Yesterday I talked about CoGetMalloc. One thing I didn't include was why the ability to specify an allocator was removed from the system. If you've read Raymond's blog, the answer should be obvious. I suspected it, but wasn't sure, but after I submitted yesterday's post, I got an email internally.
The ability to specify an allocator was a feature added back in the days when applications were trusted not to screw up.
Unfortunately, whenever applications are given the ability to screw up, they did. They provided their own IMalloc implementations, many of which didn't correctly implement the IMalloc contract. Now this isn't necessarily a big deal - the application just stomped on itself, right, so it's the application's fault, right? Well yeah, but sometimes these 3rd party allocators took out windows components as well. All in all, it wasn't very pretty.
When the 32bit version COM was implemented (for NT 3.5), the decision was made to deprecate the first parameter to CoInitialize/CoInitializeEx. The IMallocSpy API was added to allow applications the abiity to track leaks and monitor memory. The COM guys were able to get away with this breaking change because all 32 bit applications were new applications, thus no existing applications would be broken by the change.
I was doing some shell32 interop in C# and ran into SHGetMalloc but in the end it was never needed that I use it, all API calls suggested alternatives.
My search for what I saw turned up this link and it didn't really surprise me it is to the old new thing. :)
So, when the CoInitialize parameter was deprecated, why wasn't CoGetMalloc removed as well? There's no reason to call it since we can get the same functionality more directly via CoTaskMemX, and any 32-bit COM code was being rewritten anyway, right?
I had always wondered what those reserved parameters were for in CoInitialize and CoInitializeEx. I always thought they were reserved for *future* use. It never occurred to me that they were left over from past use. Although I wrote programs for 16-bit Windows, COM and OLE were way over my head at the time, so I never had occasion to call those functions before. Thanks for explaining the mystery.
Rob, I'm not sure why it wasn't removed - most likely it was as an aid to help in porting apps from Win16 to Win32 - not providing a param is easy - if someone saved a copy of the allocator away and used it offline, it might be harder to port.
Pretty interesting. I never even though about why that parameter was there.
"able to get away with this breaking change because all 32 bit applications were new applications"
I wish Win64 took this approach. It seems like there are a lot of ugly and confusing hacks, like storing 64-bit binaries in System32 and 32-bit binaries in SystemWOW64, which as far as I can see were only added to make it very slightly easier to recompile 32-bit apps without having to change as much. (Also, 32-bit binaries in the dir ending "64" and 64-bit binaries in the dir ending "32", WTF? I take it when we move to 128-bit the 64-bit binaries will be in a dir ending "128".)
It's not like you really can just recompile and your 64-bit port is done. If you use any of the GUI stuff -- and many other things -- then you'll have to inspect the code for problems where pointers are smuggled through 32-bit DWORDs etc., so why not make people also fix errors where they've hardcoded the system32 path (etc.) as well? It's hardly a massive effort and the program benefits from doing things the right way afterwards (assuming the programmer changes it to use an API to get the system folder, rather than hardcoding it to the new value). No existing programs would have been broken because there were no existing 64-bit programs, just as there were no 32-bit programs when 32-bit COM was created.
Instead we will forever have to see and live with a number of ugly and confusing hacks in the OS which will be there forever just to save people a tiny bit of time now.