« Back to home

The hidden danger of forgetting to specify %SystemRoot% in a custom environment block

When spawning a process using CreateProcess and friends, the child process usually inherits the environment (i.e. all environment variables) of the spawning process. Of course, this behavior can be overridden by creating a custom environment block and passing it to the lpEnvironment parameter of CreateProcess. While the MSDN documentation on CreateProcess does contain a remark saying that current directory information (=C: and friends) should be included in such a custom environment block, it does not mention the importance of SystemRoot.

Read more »

RCW Reference Counting Rules != COM Reference Counting Rules

Posted on

Avoiding COM object leaks in managed applications that make use of COM Interop can be a daunting task. While diligent tracking of COM object references and appropriate usage of Marshal.ReleaseComObject usually works fine, COM Interop is always good for surprises. Recently having been tracking down a COM object leak in a COM/.Net-Interop-centric application, I noticed that the CLR did not quite manage the reference count on my COM object as I expected it to do – more precisely, it incremented the referece count of a COM object when it was passed (from COM) as a method parameter to a callback implemented in .

Read more »

Working Around TlbImp's Cleverness

TlbImp, the .Net tool to create Interop assemblies from COM type libraries, contains an optimization that presumably aims at making the consumption of the Interop assembly easier, but ultimately is a nuisance. Consider the following IDL code: import "oaidl.idl"; import "ocidl.idl"; [ uuid( a657ef35-fea1-40ad-86d8-bb7b6085a0a3 ), version( 1.0 ) ] library Test { [ object, uuid( 84b2f017-b8fe-4c2c-87b8-0587b4bf5507 ), version( 1.0 ), oleautomation ] interface IFoo : IUnknown { HRESULT Foo(); } [ object, uuid( 13d950d6-beb3-4dd3-957b-88b0e5eb5e3f ), version( 1.

Read more »

Error Codes: Win32 vs. HRESULT vs. NTSTATUS

Posted on

There are three common error code formats used throughout Windows. In the kernel and native part, NTSTATUS is used exclusively. The Win32 API uses its own error codes (they do not really have a name, so I will refer to them as Win32 error codes) and COM uses HRESULTs – though the separation is not always so sharp, e.g. the safe string functions (StringCch* and friends) also return HRESULTs although they do not belong to COM.

Read more »

Determining the apartment of a thread

Posted on

There are situations in which it would be convenient to list which apartment the threads of a process belong to. In case of managed debugging, the !threads command provided by SOS gives this info: PreEmptive GC Alloc Lock ID ThreadOBJ State GC Context Domain Count APT Exception 0 688 00149528 6020 Enabled 00000000:00000000 00159e68 0 STA 1 f70 00165548 b220 Enabled 00000000:00000000 00159e68 0 MTA (Finalizer) In case of unmanaged debugging, however, no such command exists (at least to my knowledge).

Read more »