[ros-dev] Kernel-mode COM: PORTCLS.SYS and sound

Andrew "Silver Blade" Greenwood reactos at silverblade.co.uk
Fri Jun 9 05:00:50 CEST 2006


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


More information about the Ros-dev mailing list