Tuesday, March 20, 2007

How to Undisable the Use of USB Storage Devices

In a managed desktop environment, if a USB device fails to install because XP can't locate the drivers, chances are that The Man has messed with the permissions on USBStor.inf and/or USBStor.pnf

Just reverse whatever has been done from this article (requires admin privileges of course):

How to Disable the Use of USB Storage Devices.
http://support.microsoft.com/kb/823732

Wednesday, March 14, 2007

.Net CLR Performance Counters Don't Appear in Perfmon

This took a while to figure out . . . I needed to use the .Net Memory counters to watch the heap sizes and garbage collections. Unfortunately, none of them appeared in Perfmon under Performance Objects.

I looked up the old standby on "How to Manually Rebuild Performance Counter Library Values"

I wasn't quite willing to do all of the registry pecking and ripping needed to do that rebuild but I checked out the keys mentioned and tried running LODCTR \R on the .Net CLR ini file. That reported that they were already installed. :-

So I checked in on the registry entries under Services . . . HKLM\SYSTEM\CurrentControlSet\Services\.NETFramework\Performance

Imagine my surprise when I saw this value:

Disable Performance Counters = 1

Setting that to 0 brought the counters back as expected.

I blame big brother for this one, but it turns out that windows will make this setting if a counter fails some tests at load time.
Disable Performance Counters

Although you can set Perflib not to disable on fail:
Perflib Configuration Flags

Sunday, March 04, 2007

COM Interop Problem with Type Library CoClass Names Changing

Message

This was a real pain, and google was no help, so here's a post that hopefully helps someone else. 

(By the way, if you want to have some fun with VB developers who are calling your .Net Assemblies, this is hours of good, wholesome, plausibly deniable bug hunting.)   

Background:  A Visual Basic 6 project has been happily consuming a set of C# Serviced Components for some centuries.  One day, some functionality was added to the C# solution.   Suddenly the VB projects wouldn't compile.  

Basic investigation on the VB side revealed that the names of the components had changed from <BusinessObject> to <CompanyAccronym>_<FunctionalArea>_<BusinessObject>.  Basically, the new name of the object had become the namespace with dots replaced by underscores.  

We had enough experts around that we quickly narrowed it down to a naming conflict.  Ripping all the new functionality out of the solution fixed the problem, so it was obviously a conflict with a newly added object.  Renaming anything that might conflict would be the solution.  

The lingering question was exactly what circumstances cause the problem?   

To that end I've created a very simple repro in VS. 

The bottom line is that you can't have two classes with the same name in the same solution, no matter what you do with the namespaces.  As soon as you add the second (conflicting) class, you hose all of your COM clients who call your first class.  


Here's the Repro:

Create a solution. 
Add a class file:

namespace RobTest.TypeLib
{
 public class conflict
 {
  public conflict()
  {
  }
 }
}

Generate the type lib with Tlbexp:
[
  uuid(44EB15C1-7CE0-39D7-9ADB-B0086CE7F6EB),
  version(1.0),
    custom({0F21F359-AB84-41E8-9A78-36D110E6D2F9}, "RobTest.TypeLib.conflict")
]
coclass conflict {
    [default] interface _conflict;
    interface _Object;
};

Looks OK.

Now add another class in a totally different Namespace

namespace RobTest2.TypeLib2
{
 public class conflict
 {
  public conflict()
  {
  }
 }
}

Regenerate the type lib:
[
  uuid(90EDBC47-D360-3545-9786-15FF36E3AF66),
  version(1.0),
    custom({0F21F359-AB84-41E8-9A78-36D110E6D2F9}, "RobTest.TypeLib.conflict")
]
coclass RobTest_TypeLib_conflict {
    [default] interface _RobTest_TypeLib_conflict;
    interface _Object;
};
[
  uuid(A45FCAAA-AC72-31DA-A6FC-DEC2EDE2489F),
  version(1.0),
    custom({0F21F359-AB84-41E8-9A78-36D110E6D2F9}, "RobTest2.TypeLib2.TypeLibProblem2.conflict")
]
coclass RobTest2_TypeLib2_conflict {
    [default] interface _RobTest2_TypeLib2_conflict;
    interface _Object;
};

Not Good! 

The only solution is to rename the conflicting class:

namespace RobTest2.TypeLib2
{
 public class NoConflict
 {
  public NoConflict()
  {
  }
 }
}

Then everything goes happily back to the way it was.  
[
  uuid(D26D7937-EA9B-30B6-BA98-A36614BF7CCE),
  version(1.0),
    custom({0F21F359-AB84-41E8-9A78-36D110E6D2F9}, "RobTest.TypeLib.conflict")
]
coclass conflict {
    [default] interface _conflict;
    interface _Object;
};
[
  uuid(3E9830B2-B787-3FBF-A493-370273AB224F),
  version(1.0),
    custom({0F21F359-AB84-41E8-9A78-36D110E6D2F9}, "RobTest2.TypeLib2.NoConflict")
]
coclass NoConflict {
    [default] interface _NoConflict;
    interface _Object;
};