ISAPI and COM
Working with Component Object Model (COM) interfaces under the ISAPI requires understanding of the IIS thread pool architecture.
IIS maintains a pool of I/O threads that call an ISAPI extension's callback functions. The possibility exists that the thread that calls initialization code in DllMain or GetExtensionVersion is not the same thread that calls HttpExtensionProc. Also, different threads might call HttpExtensionProc from one request to another.
Because COM initialization affects the thread in which it is called, COM should never be initialized within CoInitialize or CoInitializeEx unless it is uninitialized before the callback function returns.
This architecture provides three design options for using COM from ISAPI:
Create a pool of threads and initialize them when the ISAPI extension is loaded.
For each request, do all initialization and uninitialization from within HttpExtensionProc.
Avoid initializing COM. This allows the ISAPI filter or extension to run in a multithreaded apartment, because IIS initializes one of its threads at start time.
Because the first option forces initialization on each request, and leaves your code vulnerable to other ISAPI extensions that may have initialized COM on the IIS thread, the last option is recommended.