Reactos
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at listview 193 lines 5.0 kB view raw
1/* 2 * PROJECT: ReactOS 3 * LICENSE: GPL - See COPYING in the top level directory 4 * PURPOSE: Audio Service Plug and Play 5 * COPYRIGHT: Copyright 2007 Andrew Greenwood 6 */ 7 8#include "audiosrv.h" 9 10#include <winreg.h> 11#include <winuser.h> 12#include <mmsystem.h> 13#include <setupapi.h> 14#include <ks.h> 15#include <ksmedia.h> 16 17#define NDEBUG 18#include <debug.h> 19 20static HDEVNOTIFY device_notification_handle = NULL; 21 22/* 23 Finds all devices within the KSCATEGORY_AUDIO category and puts them 24 in the shared device list. 25*/ 26 27BOOL 28ProcessExistingDevices(VOID) 29{ 30 SP_DEVICE_INTERFACE_DATA interface_data; 31 SP_DEVINFO_DATA device_data; 32 PSP_DEVICE_INTERFACE_DETAIL_DATA_W detail_data; 33 HDEVINFO dev_info; 34 DWORD length; 35 int index = 0; 36 37 const GUID category_guid = {STATIC_KSCATEGORY_AUDIO}; 38 39 dev_info = SetupDiGetClassDevsExW(&category_guid, 40 NULL, 41 NULL, 42 DIGCF_PRESENT | DIGCF_DEVICEINTERFACE, 43 NULL, 44 NULL, 45 NULL); 46 47 interface_data.cbSize = sizeof(interface_data); 48 interface_data.Reserved = 0; 49 50 /* Enumerate the devices within the category */ 51 index = 0; 52 53 length = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) 54 + (MAX_PATH * sizeof(WCHAR)); 55 56 detail_data = 57 (PSP_DEVICE_INTERFACE_DETAIL_DATA_W)HeapAlloc(GetProcessHeap(), 58 0, 59 length); 60 61 if ( ! detail_data ) 62 { 63 DPRINT("failed to allocate detail_data\n"); 64 return TRUE; 65 } 66 67 while ( 68 SetupDiEnumDeviceInterfaces(dev_info, 69 NULL, 70 &category_guid, 71 index, 72 &interface_data) ) 73 { 74 PnP_AudioDevice* list_node; 75 76 ZeroMemory(detail_data, length); 77 78 /* NOTE: We don't actually use device_data... */ 79 detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W); 80 device_data.cbSize = sizeof(device_data); 81 device_data.Reserved = 0; 82 SetupDiGetDeviceInterfaceDetailW(dev_info, 83 &interface_data, 84 detail_data, 85 length, 86 NULL, 87 &device_data); 88 89 list_node = CreateDeviceDescriptor(detail_data->DevicePath, TRUE); 90 AppendAudioDeviceToList(list_node); 91 DestroyDeviceDescriptor(list_node); 92 93 /* TODO: Cleanup the device we enumerated? */ 94 95 index ++; 96 }; 97 98 HeapFree(GetProcessHeap(), 0, detail_data); 99 100 SetupDiDestroyDeviceInfoList(dev_info); 101 102 return TRUE; 103} 104 105 106/* 107 Add new devices to the list as they arrive. 108*/ 109 110DWORD 111ProcessDeviceArrival(DEV_BROADCAST_DEVICEINTERFACE* device) 112{ 113 PnP_AudioDevice* list_node; 114 list_node = CreateDeviceDescriptor(device->dbcc_name, TRUE); 115 AppendAudioDeviceToList(list_node); 116 DestroyDeviceDescriptor(list_node); 117 118 return NO_ERROR; 119} 120 121 122/* 123 Request notification of device additions/removals. 124*/ 125 126BOOL 127RegisterForDeviceNotifications(VOID) 128{ 129 DEV_BROADCAST_DEVICEINTERFACE notification_filter; 130 131 const GUID wdmaud_guid = {STATIC_KSCATEGORY_AUDIO}; 132 133 ZeroMemory(&notification_filter, sizeof(notification_filter)); 134 notification_filter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE); 135 notification_filter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; 136 notification_filter.dbcc_classguid = wdmaud_guid; 137 138 device_notification_handle = 139 RegisterDeviceNotificationW((HANDLE) service_status_handle, 140 &notification_filter, 141 DEVICE_NOTIFY_SERVICE_HANDLE); 142 if (!device_notification_handle) 143 { 144 DPRINT("failed with error %d\n", GetLastError()); 145 } 146 147 return ( device_notification_handle != NULL ); 148} 149 150 151/* 152 When we're not interested in device notifications any more, this gets 153 called. 154*/ 155 156VOID 157UnregisterDeviceNotifications(VOID) 158{ 159 if (device_notification_handle) 160 { 161 if (UnregisterDeviceNotification(device_notification_handle)) 162 device_notification_handle = NULL; 163 } 164} 165 166 167/* 168 Device events from the main service handler get passed to this. 169*/ 170 171DWORD 172HandleDeviceEvent( 173 DWORD dwEventType, 174 LPVOID lpEventData) 175{ 176 switch (dwEventType) 177 { 178 case DBT_DEVICEARRIVAL: 179 { 180 DEV_BROADCAST_DEVICEINTERFACE* incoming_device = 181 (DEV_BROADCAST_DEVICEINTERFACE*)lpEventData; 182 183 return ProcessDeviceArrival(incoming_device); 184 } 185 186 default : 187 { 188 break; 189 } 190 } 191 192 return NO_ERROR; 193}