Someone on this mailing list gave me a crash-course on using COM (possibly KJK, but it was a while ago so I'm not sure.)
Anyway, I'm fairly comfortable with the various macros and sort of understand how it works now.
== SOUND ARCHITECTURE ==
I've been told that Windows Vista has a new user-mode set of audio/multimedia APIs, which replace kernel-mode streaming. Evidently most of the kernel-mode components for this no longer exist in Vista. Instead, communication goes via user-mode components until PORTCLS.SYS, the only remaining kernel-streaming related component.
PORTCLS.SYS interacts with WDM audio drivers. WDMAUD.DRV interacts with the MME API (winmm.dll). So the path from the MME API to the WDM driver may be different, but older applications and drivers should see no difference there.
I think implementing the audio system used in Vista would be a good thing to do - since the kernel streaming components have been completely removed from Vista, there is no point in implementing them in ReactOS.
There should be no reason why an NT4 audio driver wouldn't work even on Vista, and XP drivers should work too. Obviously this won't be the case, though, as all drivers will probably need to be designed specifically for Vista. My point however, is that the MME API has changed slightly, but will still work with older drivers.
(As a side-note, I recall that our implementation of WINMM.DLL - as copied over from WINE - doesn't appear to deal with Plug and Play at all. This is something that will need to be remedied.)
== PORTCLS.SYS : COM IN THE KERNEL ==
This took a while for me to get my head around, and I'm at the stage now where I can happily declare a COM interface or class. But I'm having difficulty figuring out how I should actually create an instance of one in the kernel.
Apparently, there exists some kernel equivalent of CoCreateInstance.
In any case, I'd prefer to work with classes using C++, which I believe can be done with COM. So I just need to know how to implement a COM class using C++. Up until now I've guessed it as being:
class IBlahBlah_Impl : public IBlahBlah
Is this right?
I'm working on the IPort code at the moment, and am wondering how to implement this:
PORTCLASSAPI NTSTATUS NTAPI PcNewPort( OUT PPORT *OutPort, IN REFCLSID ClassId) { /* ClassId must be one of: CLSID_PortDMus (IPortDMus) defined in dmusicks.h CLSID_PortMidi (IPortMidi) CLSID_PortTopology (IPortTopology) CLSID_PortWaveCyclic (IPortWaveCyclic) CLSID_PortWavePci (IPortWavePci) */ }
Yes, it's just a commented function. From the documentation, the caller passes one of the CLSID's from the above list, and receives a pointer to an IPort.
Question is, how do I compare the parameter with one of the CLSIDs? And again, how do I create an instance of the class in kernel-mode?
If anyone can shed a little light on this, I'd appreciate it.
-Andrew