Correct enumeration of Plug and Play audio devices on Windows using
authorAndrew Greenwood <silverblade@reactos.org>
Wed, 19 Sep 2007 14:42:54 +0000 (14:42 +0000)
committerAndrew Greenwood <silverblade@reactos.org>
Wed, 19 Sep 2007 14:42:54 +0000 (14:42 +0000)
KSCATEGORY_AUDIO. Also detects existing audio devices in addition to
dealing with device arrivals. Slight code tidy-up. Also added additional
GUIDs to ks.h and ksmedia.h

svn path=/trunk/; revision=29106

reactos/base/services/audiosrv/audiosrv.h [new file with mode: 0644]
reactos/base/services/audiosrv/audiosrv.rbuild
reactos/base/services/audiosrv/main.c
reactos/base/services/audiosrv/pnp.c [new file with mode: 0644]
reactos/base/services/audiosrv/pnp_list_manager.c
reactos/base/services/audiosrv/pnp_list_manager.h [deleted file]
reactos/include/psdk/ks.h
reactos/include/psdk/ksmedia.h

diff --git a/reactos/base/services/audiosrv/audiosrv.h b/reactos/base/services/audiosrv/audiosrv.h
new file mode 100644 (file)
index 0000000..ecdb2c2
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * PROJECT:          ReactOS
+ * LICENSE:          GPL - See COPYING in the top level directory
+ * FILE:             base/services/audiosrv/audiosrv.h
+ * PURPOSE:          Audio Service (private header)
+ * COPYRIGHT:        Copyright 2007 Andrew Greenwood
+ */
+
+#include <dbt.h>
+#include <audiosrv/audiosrv.h>
+
+#ifndef AUDIOSRV_PRIVATE_H
+#define AUDIOSRV_PRIVATE_H
+
+extern SERVICE_STATUS_HANDLE service_status_handle;
+
+
+/* main.c */
+
+VOID CALLBACK
+ServiceMain(DWORD argc, char** argv);
+
+DWORD WINAPI
+ServiceControlHandler(
+    DWORD dwControl,
+    DWORD dwEventType,
+    LPVOID lpEventData,
+    LPVOID lpContext);
+
+
+/* List management (pnp_list_manager.c) */
+
+VOID*
+CreateDeviceDescriptor(WCHAR* path, BOOL is_enabled);
+
+#define DestroyDeviceDescriptor(descriptor) free(descriptor)
+
+BOOL
+AppendAudioDeviceToList(PnP_AudioDevice* device);
+
+BOOL
+CreateAudioDeviceList(DWORD max_size);
+
+VOID
+DestroyAudioDeviceList();
+
+
+/* Plug and Play (pnp.c) */
+
+BOOL
+ProcessExistingDevices();
+
+DWORD
+ProcessDeviceArrival(DEV_BROADCAST_DEVICEINTERFACE* device);
+
+BOOL
+RegisterForDeviceNotifications();
+
+DWORD
+HandleDeviceEvent(
+    DWORD dwEventType,
+    LPVOID lpEventData);
+
+#endif
index 8bcc7f2..055a03c 100644 (file)
@@ -9,8 +9,10 @@ installname="audiosrv.exe" allowwarnings="true">
        <library>kernel32</library>
        <library>advapi32</library>
        <library>user32</library>
+       <library>setupapi</library>
        <file>main.c</file>
        <file>pnp_list_manager.c</file>
        <file>pnp_list_lock.c</file>
+       <file>pnp.c</file>
        <file>audiosrv.rc</file>
 </module>
index 3c42c99..591ccba 100644 (file)
@@ -7,28 +7,13 @@
  */\r
 \r
 #include <windows.h>\r
-#include <winuser.h>\r
-#include <dbt.h>\r
-#include <audiosrv/audiosrv.h>\r
-#include <pnp_list_manager.h>\r
-\r
-#include <ksmedia.h>\r
-\r
-\r
-\r
-/* Prototypes */\r
 \r
-VOID CALLBACK\r
-ServiceMain(DWORD argc, char** argv);\r
+#include <audiosrv/audiosrv.h>\r
+#include "audiosrv.h"\r
 \r
-DWORD WINAPI\r
-ServiceControlHandler(\r
-    DWORD dwControl,\r
-    DWORD dwEventType,\r
-    LPVOID lpEventData,\r
-    LPVOID lpContext);\r
 \r
 /* Service table */\r
+\r
 SERVICE_TABLE_ENTRY service_table[2] =\r
 {\r
     { L"AudioSrv", (LPSERVICE_MAIN_FUNCTION) ServiceMain },\r
@@ -37,24 +22,7 @@ SERVICE_TABLE_ENTRY service_table[2] =
 \r
 SERVICE_STATUS_HANDLE service_status_handle;\r
 SERVICE_STATUS service_status;\r
-HDEVNOTIFY device_notification_handle = NULL;\r
-\r
-/* Synchronization of access to the event list */\r
-HANDLE device_list_mutex = INVALID_HANDLE_VALUE;\r
-\r
 \r
-/* Implementation */\r
-\r
-DWORD\r
-ProcessDeviceArrival(DEV_BROADCAST_DEVICEINTERFACE* device)\r
-{\r
-    PnP_AudioDevice* list_node;\r
-    list_node = CreateDeviceDescriptor(device->dbcc_name, TRUE);\r
-    AppendAudioDeviceToList(list_node);\r
-    DestroyDeviceDescriptor(list_node);\r
-\r
-    return NO_ERROR;\r
-}\r
 \r
 DWORD WINAPI\r
 ServiceControlHandler(\r
@@ -73,12 +41,7 @@ ServiceControlHandler(
         case SERVICE_CONTROL_STOP :\r
         case SERVICE_CONTROL_SHUTDOWN :\r
         {\r
-            /* FIXME: This function doesn't exist?! */\r
-/*\r
-            UnregisterDeviceNotification(device_notification_handle);\r
-            device_notification_handle = NULL;\r
-*/\r
-\r
+            UnregisterDeviceNotifications();\r
             DestroyAudioDeviceList();\r
 \r
             service_status.dwCurrentState = SERVICE_STOP_PENDING;\r
@@ -94,23 +57,7 @@ ServiceControlHandler(
 \r
         case SERVICE_CONTROL_DEVICEEVENT :\r
         {\r
-            switch ( dwEventType )\r
-            {\r
-                case DBT_DEVICEARRIVAL :\r
-                {\r
-                    DEV_BROADCAST_DEVICEINTERFACE* incoming_device =\r
-                        (DEV_BROADCAST_DEVICEINTERFACE*) lpEventData;\r
-\r
-                    return ProcessDeviceArrival(incoming_device);\r
-                }\r
-\r
-                default :\r
-                {\r
-                    break;\r
-                }\r
-            }\r
-\r
-            return NO_ERROR;\r
+            return HandleDeviceEvent(dwEventType, lpEventData);\r
         }\r
 \r
         default :\r
@@ -120,28 +67,6 @@ ServiceControlHandler(
     /*SetServiceStatus(service_status_handle, &service_status);*/\r
 }\r
 \r
-BOOL\r
-RegisterForDeviceNotifications()\r
-{\r
-    DEV_BROADCAST_DEVICEINTERFACE notification_filter;\r
-\r
-    const GUID wdmaud_guid = {STATIC_KSCATEGORY_WDMAUD};\r
-\r
-    /* FIXME: This currently lists ALL device interfaces... */\r
-    ZeroMemory(&notification_filter, sizeof(notification_filter));\r
-    notification_filter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);\r
-    notification_filter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;\r
-    notification_filter.dbcc_classguid = wdmaud_guid;\r
-\r
-    device_notification_handle =\r
-        RegisterDeviceNotification((HANDLE) service_status_handle,\r
-                                   &notification_filter,\r
-                                   DEVICE_NOTIFY_SERVICE_HANDLE |\r
-                                   DEVICE_NOTIFY_ALL_INTERFACE_CLASSES);\r
-\r
-    return ( device_notification_handle != NULL );\r
-}\r
-\r
 VOID CALLBACK\r
 ServiceMain(DWORD argc, char** argv)\r
 {\r
@@ -181,6 +106,18 @@ ServiceMain(DWORD argc, char** argv)
         return;\r
     }\r
 \r
+    /* Now find any devices that already exist on the system */\r
+    if ( ! ProcessExistingDevices() )\r
+    {\r
+        UnregisterDeviceNotifications();\r
+        DestroyAudioDeviceList();\r
+\r
+        service_status.dwCurrentState = SERVICE_STOPPED;\r
+        service_status.dwWin32ExitCode = -1;\r
+        SetServiceStatus(service_status_handle, &service_status);\r
+        return;\r
+    }\r
+\r
     /* Tell SCM we are now running, and we may be stopped */\r
     service_status.dwCurrentState = SERVICE_RUNNING;\r
     service_status.dwControlsAccepted = SERVICE_ACCEPT_STOP;\r
diff --git a/reactos/base/services/audiosrv/pnp.c b/reactos/base/services/audiosrv/pnp.c
new file mode 100644 (file)
index 0000000..e5f99ba
--- /dev/null
@@ -0,0 +1,185 @@
+/*
+ * PROJECT:          ReactOS
+ * LICENSE:          GPL - See COPYING in the top level directory
+ * FILE:             base/services/audiosrv/pnp.c
+ * PURPOSE:          Audio Service Plug and Play
+ * COPYRIGHT:        Copyright 2007 Andrew Greenwood
+ */
+
+#include <windows.h>
+#include <winuser.h>
+#include <dbt.h>
+#include <setupapi.h>
+
+#include <ks.h>
+#include <ksmedia.h>
+
+#include <audiosrv/audiosrv.h>
+#include "audiosrv.h"
+
+static HDEVNOTIFY device_notification_handle = NULL;
+
+
+/*
+    Finds all devices within the KSCATEGORY_AUDIO category and puts them
+    in the shared device list.
+*/
+
+BOOL
+ProcessExistingDevices()
+{
+    SP_DEVICE_INTERFACE_DATA interface_data;
+    SP_DEVINFO_DATA device_data;
+    PSP_DEVICE_INTERFACE_DETAIL_DATA detail_data;
+    HDEVINFO dev_info;
+    DWORD length;
+    int index = 0;
+
+    const GUID category_guid = {STATIC_KSCATEGORY_AUDIO};
+
+    dev_info = SetupDiGetClassDevsEx(&category_guid,
+                                     NULL,
+                                     NULL,
+                                     DIGCF_PRESENT | DIGCF_DEVICEINTERFACE,
+                                     NULL,
+                                     NULL,
+                                     NULL);
+
+/*    printf("%s:\n", ClassString); */
+
+    interface_data.cbSize = sizeof(interface_data);
+    interface_data.Reserved = 0;
+
+    /* Enumerate the devices within the category */
+    index = 0;
+
+    length = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA)
+                + (MAX_PATH * sizeof(WCHAR));
+
+    detail_data =
+        (PSP_DEVICE_INTERFACE_DETAIL_DATA)HeapAlloc(GetProcessHeap(),
+                                                    0,
+                                                    length);
+
+    while ( 
+    SetupDiEnumDeviceInterfaces(dev_info,
+                                NULL,
+                                &category_guid,
+                                index,
+                                &interface_data) )
+    {
+        PnP_AudioDevice* list_node;
+
+        ZeroMemory(detail_data, length);
+
+        /* NOTE: We don't actually use device_data... */
+        detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
+        device_data.cbSize = sizeof(device_data);
+        device_data.Reserved = 0;
+        SetupDiGetDeviceInterfaceDetail(dev_info,
+                                        &interface_data,
+                                        detail_data,
+                                        length,
+                                        NULL,
+                                        &device_data);
+
+        list_node = CreateDeviceDescriptor(detail_data->DevicePath, TRUE);
+        AppendAudioDeviceToList(list_node);
+        DestroyDeviceDescriptor(list_node);
+
+        /* TODO: Cleanup the device we enumerated? */
+
+        index ++;
+    };
+
+    HeapFree(GetProcessHeap(), 0, detail_data);
+
+    SetupDiDestroyDeviceInfoList(dev_info);
+
+    return TRUE;
+}
+
+
+/*
+    Add new devices to the list as they arrive.
+*/
+
+DWORD
+ProcessDeviceArrival(DEV_BROADCAST_DEVICEINTERFACE* device)
+{
+    PnP_AudioDevice* list_node;
+    list_node = CreateDeviceDescriptor(device->dbcc_name, TRUE);
+    AppendAudioDeviceToList(list_node);
+    DestroyDeviceDescriptor(list_node);
+
+    return NO_ERROR;
+}
+
+
+/*
+    Request notification of device additions/removals.
+*/
+
+BOOL
+RegisterForDeviceNotifications()
+{
+    DEV_BROADCAST_DEVICEINTERFACE notification_filter;
+
+    const GUID wdmaud_guid = {STATIC_KSCATEGORY_AUDIO};
+
+    /* FIXME: This currently lists ALL device interfaces... */
+    ZeroMemory(&notification_filter, sizeof(notification_filter));
+    notification_filter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
+    notification_filter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
+    notification_filter.dbcc_classguid = wdmaud_guid;
+
+    device_notification_handle =
+        RegisterDeviceNotification((HANDLE) service_status_handle,
+                                   &notification_filter,
+                                   DEVICE_NOTIFY_SERVICE_HANDLE
+/* |
+                                   DEVICE_NOTIFY_ALL_INTERFACE_CLASSES*/);
+
+    return ( device_notification_handle != NULL );
+}
+
+
+/*
+    When we're not interested in device notifications any more, this gets
+    called.
+*/
+
+VOID UnregisterDeviceNotifications()
+{
+    /* TODO -- NOT IMPLEMENTED! */
+    device_notification_handle = NULL;
+}
+
+
+/*
+    Device events from the main service handler get passed to this.
+*/
+
+DWORD
+HandleDeviceEvent(
+    DWORD dwEventType,
+    LPVOID lpEventData)
+{
+    switch ( dwEventType )
+    {
+        case DBT_DEVICEARRIVAL :
+        {
+            DEV_BROADCAST_DEVICEINTERFACE* incoming_device =
+                (DEV_BROADCAST_DEVICEINTERFACE*) lpEventData;
+
+            return ProcessDeviceArrival(incoming_device);
+        }
+
+        default :
+        {
+            break;
+        }
+    }
+
+    return NO_ERROR;
+}
index 69edd54..da33c45 100644 (file)
@@ -47,6 +47,12 @@ CreateDeviceDescriptor(WCHAR* path, BOOL is_enabled)
 static HANDLE device_list_file = NULL;
 static PnP_AudioHeader* audio_device_list = NULL;
 
+
+/*
+    TODO: Detect duplicate entries and ignore them! (In case we receive
+    a PnP event for an existing device...)
+*/
+
 BOOL
 AppendAudioDeviceToList(PnP_AudioDevice* device)
 {
diff --git a/reactos/base/services/audiosrv/pnp_list_manager.h b/reactos/base/services/audiosrv/pnp_list_manager.h
deleted file mode 100644 (file)
index 43ac297..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * PROJECT:          ReactOS
- * LICENSE:          GPL - See COPYING in the top level directory
- * FILE:             base/services/audiosrv/pnp_list_manager.h
- * PURPOSE:          Audio Service List Manager
- * COPYRIGHT:        Copyright 2007 Andrew Greenwood
- */
-
-#include <assert.h>
-#include <audiosrv/audiosrv.h>
-
-#ifndef PNP_LIST_MANAGER_H
-#define PNP_LIST_MANAGER_H
-
-VOID*
-CreateDeviceDescriptor(WCHAR* path, BOOL is_enabled);
-
-#define DestroyDeviceDescriptor(descriptor) free(descriptor)
-
-BOOL
-AppendAudioDeviceToList(PnP_AudioDevice* device);
-
-BOOL
-CreateAudioDeviceList(DWORD max_size);
-
-VOID
-DestroyAudioDeviceList();
-
-#endif
index c5d42f8..5601883 100644 (file)
@@ -106,17 +106,19 @@ DEFINE_GUIDSTRUCT("00000000-0000-0000-0000-000000000000", GUID_NULL);
         METHOD_NEITHER, \
         FILE_ANY_ACCESS)
 
+// WAS 2
 #define IOCTL_KS_METHOD \
     CTL_CODE( \
         FILE_DEVICE_KS, \
-        0x002, \
+        0x003, \
         METHOD_NEITHER, \
         FILE_ANY_ACCESS)
 
+// WAS 3
 #define IOCTL_KS_PROPERTY \
     CTL_CODE( \
         FILE_DEVICE_KS, \
-        0x003, \
+        0x000, \
         METHOD_NEITHER, \
         FILE_ANY_ACCESS)
 
@@ -221,6 +223,95 @@ DEFINE_GUIDSTRUCT("97EBAACA-95BD-11D0-A3EA-00A0C9223196", KSCATEGORY_PROXY);
 DEFINE_GUIDSTRUCT("97EBAACB-95BD-11D0-A3EA-00A0C9223196", KSCATEGORY_QUALITY);
 #define KSCATEGORY_QUALITY DEFINE_GUIDNAMED(KSCATEGORY_QUALITY)
 
+/* ===============================================================
+    Common
+*/
+
+typedef struct
+{
+    GUID Set;
+    ULONG Id;
+    ULONG Flags;
+} KSIDENTIFIER, *PKSIDENTIFIER;
+
+typedef KSIDENTIFIER KSPROPERTY, *PKSPROPERTY;
+typedef KSIDENTIFIER KSMETHOD, *PKSMETHOD;
+typedef KSIDENTIFIER KSEVENT, *PKSEVENT;
+
+typedef KSIDENTIFIER KSDEGRADE, *PKSDEGRADE;
+
+typedef KSIDENTIFIER KSPIN_INTERFACE, *PKSPIN_INTERFACE;
+typedef KSIDENTIFIER KSPIN_MEDIUM, *PKSPIN_MEDIUM;
+
+typedef union
+{
+    struct {
+        ULONG   FormatSize;
+        ULONG   Flags;
+        ULONG   SampleSize;
+        ULONG   Reserved;
+        GUID    MajorFormat;
+        GUID    SubFormat;
+        GUID    Specifier;
+    };
+    LONGLONG    Alignment;
+} KSDATAFORMAT, *PKSDATAFORMAT, KSDATARANGE, *PKSDATARANGE;
+
+typedef struct
+{
+} KSATTRIBUTE, *PKSATTRIBUTE;
+
+
+
+/* ===============================================================
+    Interface Sets - TODO
+*/
+
+#if 0
+#define KSINTERFACESETID_Media
+
+#define KSINTERFACESETID_Standard
+#define KSINTERFACE_STANDARD_STREAMING
+#define KSINTERFACE_STANDARD_LOOPED_STREAMING
+#define KSINTERFACE_STANDARD_CONTROL
+#endif
+
+typedef KSIDENTIFIER KSPIN_INTERFACE, *PKSPIN_INTERFACE;
+
+#define STATIC_KSINTERFACESETID_Standard \
+    0x1A8766A0L, 0x62CE, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00
+DEFINE_GUIDSTRUCT("1A8766A0-62CE-11CF-A5D6-28DB04C10000", KSINTERFACESETID_Standard);
+#define KSINTERFACESETID_Standard DEFINE_GUIDNAMED(KSINTERFACESETID_Standard)
+
+typedef enum
+{
+    KSINTERFACE_STANDARD_STREAMING,
+    KSINTERFACE_STANDARD_LOOPED_STREAMING,
+    KSINTERFACE_STANDARD_CONTROL
+} KSINTERFACE_STANDARD;
+
+#define STATIC_KSINTERFACESETID_FileIo \
+    0x8C6F932CL, 0xE771, 0x11D0, 0xB8, 0xFF, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96
+DEFINE_GUIDSTRUCT("8C6F932C-E771-11D0-B8FF-00A0C9223196", KSINTERFACESETID_FileIo);
+#define KSINTERFACESETID_FileIo DEFINE_GUIDNAMED(KSINTERFACESETID_FileIo)
+
+
+/* ===============================================================
+    Mediums
+*/
+
+typedef enum
+{
+    KSINTERFACE_FILEIO_STREAMING
+} KSINTERFACE_FILEIO;
+
+#define KSMEDIUM_TYPE_ANYINSTANCE       0
+
+#define STATIC_KSMEDIUMSETID_Standard \
+    0x4747B320L, 0x62CE, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00
+DEFINE_GUIDSTRUCT("4747B320-62CE-11CF-A5D6-28DB04C10000", KSMEDIUMSETID_Standard);
+#define KSMEDIUMSETID_Standard DEFINE_GUIDNAMED(KSMEDIUMSETID_Standard)
+
 
 /* ===============================================================
     Clock Properties/Methods/Events
@@ -341,8 +432,10 @@ typedef enum
     Properties/Methods/Events
 */
 
-#define KSPROPSETID_Pin \
+#define STATIC_KSPROPSETID_Pin\
     0x8C134960L, 0x51AD, 0x11CF, 0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00
+DEFINE_GUIDSTRUCT("8C134960-51AD-11CF-878A-94F801C10000", KSPROPSETID_Pin);
+#define KSPROPSETID_Pin DEFINE_GUIDNAMED(KSPROPSETID_Pin)
 
 typedef enum
 {
@@ -363,6 +456,28 @@ typedef enum
     KSPROPERTY_PIN_PROPOSEDATAFORMAT
 } KSPROPERTY_PIN;
 
+typedef struct
+{
+    KSPROPERTY      Property;
+    ULONG           PinId;
+    ULONG           Reserved;
+} KSP_PIN, *PKSP_PIN;
+
+#define KSINSTANCE_INDETERMINATE    ((ULONG)-1)
+
+typedef struct
+{
+    ULONG  PossibleCount;
+    ULONG  CurrentCount;
+} KSPIN_CINSTANCES, *PKSPIN_CINSTANCES;
+
+typedef struct
+{
+    ULONG   Size;
+    ULONG   Pin;
+    WCHAR   SymbolicLinkName[1];
+} KSPIN_PHYSICALCONNECTION, *PKSPIN_PHYSICALCONNECTION;
+
 
 /* ===============================================================
     Quality
@@ -605,7 +720,7 @@ typedef enum
     KSPROPERTY_SYNTH_DLS_WAVEFORMAT
 */
 
-#define KSPROPSETID_Sysaudio
+/* #define KSPROPSETID_Sysaudio */
 /*
     KSPROPERTY_SYSAUDIO_COMPONENT_ID 
     KSPROPERTY_SYSAUDIO_CREATE_VIRTUAL_SOURCE 
@@ -629,16 +744,6 @@ typedef enum
 */
 
 
-/* ===============================================================
-    Interface Sets - TODO
-*/
-
-#define KSINTERFACESETID_Media
-
-#define KSINTERFACESETID_Standard
-#define KSINTERFACE_STANDARD_STREAMING
-#define KSINTERFACE_STANDARD_LOOPED_STREAMING
-#define KSINTERFACE_STANDARD_CONTROL
 
 
 /* ===============================================================
@@ -979,39 +1084,6 @@ typedef struct
 } KS_COMPRESSION, *PKS_COMPRESSION;
 
 
-/* ===============================================================
-    Common
-*/
-
-typedef struct
-{
-    GUID Set;
-    ULONG Id;
-    ULONG Flags;
-} KSIDENTIFIER, *PKSIDENTIFIER;
-
-typedef KSIDENTIFIER KSPROPERTY, *PKSPROPERTY;
-typedef KSIDENTIFIER KSMETHOD, *PKSMETHOD;
-typedef KSIDENTIFIER KSEVENT, *PKSEVENT;
-
-typedef KSIDENTIFIER KSDEGRADE, *PKSDEGRADE;
-
-typedef KSIDENTIFIER KSPIN_INTERFACE, *PKSPIN_INTERFACE;
-typedef KSIDENTIFIER KSPIN_MEDIUM, *PKSPIN_MEDIUM;
-
-typedef struct
-{
-} KSDATARANGE, *PKSDATARANGE;
-
-typedef struct
-{
-} KSDATAFORMAT, *PKSDATAFORMAT;
-
-typedef struct
-{
-} KSATTRIBUTE, *PKSATTRIBUTE;
-
-
 /* ===============================================================
     Priorities
 */
@@ -1053,6 +1125,12 @@ typedef struct
 
 typedef struct
 {
+    GUID    Manufacturer;
+    GUID    Product;
+    GUID    Component;
+    GUID    Name;
+    ULONG   Version;
+    ULONG   Revision;
 } KSCOMPONENTID, *PKSCOMPONENTID;
 
 typedef struct
@@ -1235,8 +1313,9 @@ typedef struct
 typedef VOID (*PFNKSITEMFREECALLBACK)(
     IN  PKSOBJECT_CREATE_ITEM CreateItem);
 
-typedef struct
-{
+typedef struct {
+    ULONG    Size;
+    ULONG    Count;
 } KSMULTIPLE_ITEM, *PKSMULTIPLE_ITEM;
 
 typedef struct
@@ -1416,14 +1495,6 @@ typedef struct
     KSPRIORITY Priority;
 } KSPIN_CONNECT, *PKSPIN_CONNECT;
 
-typedef struct
-{
-} KSP_PIN, *PKSP_PIN;
-
-typedef struct
-{
-} KSPIN_PHYSICALCONNECTION, *PKSPIN_PHYSICALCONNECTION;
-
 
 /* ===============================================================
     Topology
index 1fc999f..82954cd 100644 (file)
 
 #include <ks.h>
 
+/*
+    KS CATEGORIES
+*/
+
+
+/* Audio device (as presented by sysaudio) */
+
+#define STATIC_KSCATEGORY_AUDIO_DEVICE \
+    0xFBF6F530L, 0x07B9, 0x11D2, 0xA7, 0x1E, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88
+DEFINE_GUIDSTRUCT("FBF6F530-07B9-11D2-A71E-0000F8004788", KSCATEGORY_AUDIO_DEVICE);
+#define KSCATEGORY_AUDIO_DEVICE DEFINE_GUIDNAMED(KSCATEGORY_AUDIO_DEVICE)
+
+/* Preferred devices */
+
+#define STATIC_KSCATEGORY_PREFERRED_WAVEOUT_DEVICE \
+    0xD6C5066EL, 0x72C1, 0x11D2, 0x97, 0x55, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88
+DEFINE_GUIDSTRUCT("D6C5066E-72C1-11D2-9755-0000F8004788", KSCATEGORY_PREFERRED_WAVEOUT_DEVICE);
+#define KSCATEGORY_PREFERRED_WAVEOUT_DEVICE DEFINE_GUIDNAMED(KSCATEGORY_PREFERRED_WAVEOUT_DEVICE)
+
+#define STATIC_KSCATEGORY_PREFERRED_WAVEIN_DEVICE \
+    0xD6C50671L, 0x72C1, 0x11D2, 0x97, 0x55, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88
+DEFINE_GUIDSTRUCT("D6C50671-72C1-11D2-9755-0000F8004788", KSCATEGORY_PREFERRED_WAVEIN_DEVICE);
+#define KSCATEGORY_PREFERRED_WAVEIN_DEVICE DEFINE_GUIDNAMED(KSCATEGORY_PREFERRED_WAVEIN_DEVICE)
+
+#define STATIC_KSCATEGORY_PREFERRED_MIDIOUT_DEVICE \
+    0xD6C50674L, 0x72C1, 0x11D2, 0x97, 0x55, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88
+DEFINE_GUIDSTRUCT("D6C50674-72C1-11D2-9755-0000F8004788", KSCATEGORY_PREFERRED_MIDIOUT_DEVICE);
+#define KSCATEGORY_PREFERRED_MIDIOUT_DEVICE DEFINE_GUIDNAMED(KSCATEGORY_PREFERRED_MIDIOUT_DEVICE)
+
+
+/* Media type categories */
+
+#define STATIC_KSCATEGORY_AUDIO \
+    0x6994AD04L, 0x93EF, 0x11D0, 0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96
+DEFINE_GUIDSTRUCT("6994AD04-93EF-11D0-A3CC-00A0C9223196", KSCATEGORY_AUDIO);
+#define KSCATEGORY_AUDIO DEFINE_GUIDNAMED(KSCATEGORY_AUDIO)
+
+#define STATIC_KSCATEGORY_VIDEO \
+    0x6994AD05L, 0x93EF, 0x11D0, 0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96
+DEFINE_GUIDSTRUCT("6994AD05-93EF-11D0-A3CC-00A0C9223196", KSCATEGORY_VIDEO);
+#define KSCATEGORY_VIDEO DEFINE_GUIDNAMED(KSCATEGORY_VIDEO)
+
+#define STATIC_KSCATEGORY_TEXT \
+    0x6994AD06L, 0x93EF, 0x11D0, 0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96
+DEFINE_GUIDSTRUCT("6994AD06-93EF-11D0-A3CC-00A0C9223196", KSCATEGORY_TEXT);
+#define KSCATEGORY_TEXT DEFINE_GUIDNAMED(KSCATEGORY_TEXT)
+
+#define STATIC_KSCATEGORY_NETWORK \
+    0x67C9CC3CL, 0x69C4, 0x11D2, 0x87, 0x59, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96
+DEFINE_GUIDSTRUCT("67C9CC3C-69C4-11D2-8759-00A0C9223196", KSCATEGORY_NETWORK);
+#define KSCATEGORY_NETWORK DEFINE_GUIDNAMED(KSCATEGORY_NETWORK)
+
+#define STATIC_KSINTERFACESETID_Media \
+    0x3A13EB40L, 0x30A7, 0x11D0, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00
+DEFINE_GUIDSTRUCT("3A13EB40-30A7-11D0-A5D6-28DB04C10000", KSINTERFACESETID_Media);
+#define KSINTERFACESETID_Media DEFINE_GUIDNAMED(KSINTERFACESETID_Media)
+
+/* ... */
+
+#define STATIC_KSCATEGORY_TOPOLOGY \
+    0xDDA54A40L, 0x1E4C, 0x11D1, 0xA0, 0x50, 0x40, 0x57, 0x05, 0xC1, 0x00, 0x00
+DEFINE_GUIDSTRUCT("DDA54A40-1E4C-11D1-A050-405705C10000", KSCATEGORY_TOPOLOGY);
+#define KSCATEGORY_TOPOLOGY DEFINE_GUIDNAMED(KSCATEGORY_TOPOLOGY)
+
+#define STATIC_KSCATEGORY_VIRTUAL \
+    0x3503EAC4L, 0x1F26, 0x11D1, 0x8A, 0xB0, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96
+DEFINE_GUIDSTRUCT("3503EAC4-1F26-11D1-8AB0-00A0C9223196", KSCATEGORY_VIRTUAL);
+#define KSCATEGORY_VIRTUAL DEFINE_GUIDNAMED(KSCATEGORY_VIRTUAL)
+
+#define STATIC_KSCATEGORY_ACOUSTIC_ECHO_CANCEL \
+    0xBF963D80L, 0xC559, 0x11D0, 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1
+DEFINE_GUIDSTRUCT("BF963D80-C559-11D0-8A2B-00A0C9255AC1", KSCATEGORY_ACOUSTIC_ECHO_CANCEL);
+#define KSCATEGORY_ACOUSTIC_ECHO_CANCEL DEFINE_GUIDNAMED(KSCATEGORY_ACOUSTIC_ECHO_CANCEL)
+
+
+/* Component-specific */
+
+#define STATIC_KSCATEGORY_SYSAUDIO \
+    0xA7C7A5B1L, 0x5AF3, 0x11D1, 0x9C, 0xED, 0x00, 0xA0, 0x24, 0xBF, 0x04, 0x07
+DEFINE_GUIDSTRUCT("A7C7A5B1-5AF3-11D1-9CED-00A024BF0407", KSCATEGORY_SYSAUDIO);
+#define KSCATEGORY_SYSAUDIO DEFINE_GUIDNAMED(KSCATEGORY_SYSAUDIO)
+
 #define STATIC_KSCATEGORY_WDMAUD \
-    0x3e227e76L, 0x690d, 0x11d2, 0x81, 0x61, 0x00, 0x00, 0xf8, 0x77, 0x5b, 0xf1
+    0x3E227E76L, 0x690D, 0x11D2, 0x81, 0x61, 0x00, 0x00, 0xF8, 0x77, 0x5B, 0xF1
 DEFINE_GUIDSTRUCT("3E227E76-690D-11D2-8161-0000F8775BF1", KSCATEGORY_WDMAUD);
 #define KSCATEGORY_WDMAUD DEFINE_GUIDNAMED(KSCATEGORY_WDMAUD)
 
+#define STATIC_KSCATEGORY_AUDIO_GFX \
+    0x9BAF9572L, 0x340C, 0x11D3, 0xAB, 0xDC, 0x00, 0xA0, 0xC9, 0x0A, 0xB1, 0x6F
+DEFINE_GUIDSTRUCT("9BAF9572-340C-11D3-ABDC-00A0C90AB16F", KSCATEGORY_AUDIO_GFX);
+#define KSCATEGORY_AUDIO_GFX DEFINE_GUIDNAMED(KSCATEGORY_AUDIO_GFX)
+
+#define STATIC_KSCATEGORY_AUDIO_SPLITTER \
+    0x9EA331FAL, 0xB91B, 0x45F8, 0x92, 0x85, 0xBD, 0x2B, 0xC7, 0x7A, 0xFC, 0xDE
+DEFINE_GUIDSTRUCT("9EA331FA-B91B-45F8-9285-BD2BC77AFCDE", KSCATEGORY_AUDIO_SPLITTER);
+#define KSCATEGORY_AUDIO_SPLITTER DEFINE_GUIDNAMED(KSCATEGORY_AUDIO_SPLITTER)
+
+#define STATIC_KSCATEGORY_SYNTHESIZER STATIC_KSNODETYPE_SYNTHESIZER
+#define KSCATEGORY_SYNTHESIZER KSNODETYPE_SYNTHESIZER
+
+#define STATIC_KSCATEGORY_DRM_DESCRAMBLE STATIC_KSNODETYPE_DRM_DESCRAMBLE
+#define KSCATEGORY_DRM_DESCRAMBLE KSNODETYPE_DRM_DESCRAMBLE
+
+/*
+    Pins
+*/
+
+#define STATIC_KSCATEGORY_WDMAUD_USE_PIN_NAME \
+    0x47A4FA20L, 0xA251, 0x11D1, 0xA0, 0x50, 0x00, 0x00, 0xF8, 0x00, 0x47, 0x88
+DEFINE_GUIDSTRUCT("47A4FA20-A251-11D1-A050-0000F8004788", KSCATEGORY_WDMAUD_USE_PIN_NAME);
+#define KSCATEGORY_WDMAUD_USE_PIN_NAME DEFINE_GUIDNAMED(KSCATEGORY_WDMAUD_USE_PIN_NAME)
+
+
+/*
+    Formats
+*/
+
+// 'vids'
+#define STATIC_KSDATAFORMAT_TYPE_VIDEO \
+    0x73646976L, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71
+DEFINE_GUIDSTRUCT("73646976-0000-0010-8000-00aa00389b71", KSDATAFORMAT_TYPE_VIDEO);
+#define KSDATAFORMAT_TYPE_VIDEO DEFINE_GUIDNAMED(KSDATAFORMAT_TYPE_VIDEO)
+
+// 'auds'
+#define STATIC_KSDATAFORMAT_TYPE_AUDIO \
+    0x73647561L, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71
+DEFINE_GUIDSTRUCT("73647561-0000-0010-8000-00aa00389b71", KSDATAFORMAT_TYPE_AUDIO);
+#define KSDATAFORMAT_TYPE_AUDIO DEFINE_GUIDNAMED(KSDATAFORMAT_TYPE_AUDIO)
+
+// 'txts'
+#define STATIC_KSDATAFORMAT_TYPE_TEXT \
+    0x73747874L, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71
+DEFINE_GUIDSTRUCT("73747874-0000-0010-8000-00aa00389b71", KSDATAFORMAT_TYPE_TEXT);
+#define KSDATAFORMAT_TYPE_TEXT DEFINE_GUIDNAMED(KSDATAFORMAT_TYPE_TEXT)
+
+#define STATIC_KSDATAFORMAT_TYPE_MUSIC \
+    0xE725D360L, 0x62CC, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00
+DEFINE_GUIDSTRUCT("E725D360-62CC-11CF-A5D6-28DB04C10000", KSDATAFORMAT_TYPE_MUSIC);
+#define KSDATAFORMAT_TYPE_MUSIC DEFINE_GUIDNAMED(KSDATAFORMAT_TYPE_MUSIC)
+
+// 'mids'
+#define STATIC_KSDATAFORMAT_TYPE_MIDI \
+    0x7364696DL, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71
+DEFINE_GUIDSTRUCT("7364696D-0000-0010-8000-00aa00389b71", KSDATAFORMAT_TYPE_MIDI);
+#define KSDATAFORMAT_TYPE_MIDI DEFINE_GUIDNAMED(KSDATAFORMAT_TYPE_MIDI)
+
+#define STATIC_KSDATAFORMAT_SUBTYPE_MIDI \
+    0x1D262760L, 0xE957, 0x11CF, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00
+DEFINE_GUIDSTRUCT("1D262760-E957-11CF-A5D6-28DB04C10000", KSDATAFORMAT_SUBTYPE_MIDI);
+#define KSDATAFORMAT_SUBTYPE_MIDI DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_MIDI)
+
+
+/*
+    SysAudio Properties
+*/
+
+#define STATIC_KSPROPSETID_Sysaudio \
+    0xCBE3FAA0L, 0xCC75, 0x11D0, 0xB4, 0x65, 0x00, 0x00, 0x1A, 0x18, 0x18, 0xE6
+DEFINE_GUIDSTRUCT("CBE3FAA0-CC75-11D0-B465-00001A1818E6", KSPROPSETID_Sysaudio);
+#define KSPROPSETID_Sysaudio DEFINE_GUIDNAMED(KSPROPSETID_Sysaudio)
+
+typedef enum {
+    KSPROPERTY_SYSAUDIO_DEVICE_COUNT            = 1,
+    KSPROPERTY_SYSAUDIO_DEVICE_FRIENDLY_NAME    = 2,
+    KSPROPERTY_SYSAUDIO_DEVICE_INSTANCE         = 3,
+    KSPROPERTY_SYSAUDIO_DEVICE_INTERFACE_NAME   = 4,
+    KSPROPERTY_SYSAUDIO_SELECT_GRAPH            = 5,
+    KSPROPERTY_SYSAUDIO_CREATE_VIRTUAL_SOURCE   = 6,
+    KSPROPERTY_SYSAUDIO_DEVICE_DEFAULT          = 7,
+    KSPROPERTY_SYSAUDIO_INSTANCE_INFO           = 14,
+    KSPROPERTY_SYSAUDIO_COMPONENT_ID            = 16
+} KSPROPERTY_SYSAUDIO;
+
+typedef struct {
+    KSPROPERTY Property;
+    ULONG Flags;
+    ULONG DeviceNumber;
+} SYSAUDIO_INSTANCE_INFO, *PSYSAUDIO_INSTANCE_INFO;
+
+#define SYSAUDIO_FLAGS_DONT_COMBINE_PINS        0x00000001
+
+
 #endif