ReactOS  0.4.15-dev-2765-g10e48fa
detect.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Sound System "MME Buddy" NT4 Library
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: lib/drivers/sound/mment4/detect.c
5  *
6  * PURPOSE: Assists in locating Windows NT4 compatible sound devices,
7  * which mostly use the same device naming convention and/or
8  * store their created device names within their service key
9  * within the registry.
10  *
11  * PROGRAMMERS: Andrew Greenwood (silverblade@reactos.org)
12 */
13 
14 #include "precomp.h"
15 
16 #include <mment4.h>
17 #include <mmebuddy_debug.h>
18 
19 /*
20  This is the "nice" way to discover audio devices in NT4 - go into the
21  service registry key and enumerate the Parameters\Device*\Devices
22  values. The value names represent the device name, whereas the data
23  assigned to them identifies the type of device.
24 */
29  IN SOUND_DEVICE_DETECTED_PROC SoundDeviceDetectedProc)
30 {
31  HKEY Key;
32  DWORD KeyIndex = 0;
33 
35 
36  /* Device type zero means "all" */
38  DeviceType == 0 );
39 
40  while ( OpenSoundDeviceRegKey(ServiceName, KeyIndex, &Key) == MMSYSERR_NOERROR )
41  {
42  HKEY DevicesKey;
43  DWORD ValueType = REG_NONE, ValueIndex = 0;
44  DWORD MaxNameLength = 0, ValueNameLength = 0;
45  PWSTR DevicePath = NULL, ValueName = NULL;
46  DWORD ValueDataLength = sizeof(DWORD);
48 
49  if ( RegOpenKeyEx(Key,
51  0,
52  KEY_READ,
53  &DevicesKey) == ERROR_SUCCESS )
54  {
55  /* Find out how much memory is needed for the key name */
56  if ( RegQueryInfoKey(DevicesKey,
57  NULL, NULL, NULL, NULL, NULL, NULL, NULL,
58  &MaxNameLength,
59  NULL, NULL, NULL) != ERROR_SUCCESS )
60  {
61  SND_ERR(L"Failed to query registry key information\n");
62  RegCloseKey(DevicesKey);
64 
65  return MMSYSERR_ERROR;
66  }
67 
68  DevicePath = AllocateWideString(MaxNameLength +
69  strlen("\\\\.\\"));
70 
71  /* Check that the memory allocation was successful */
72  if ( ! DevicePath )
73  {
74  /* There's no point in going further */
75  RegCloseKey(DevicesKey);
77 
78  return MMSYSERR_NOMEM;
79  }
80 
81  /* Insert the device path prefix */
82  wsprintf(DevicePath, L"\\\\.\\");
83 
84  /* The offset of the string following this prefix */
85  ValueName = DevicePath + strlen("\\\\.\\");
86 
87  /* Copy this so that it may be overwritten - include NULL */
88  ValueNameLength = MaxNameLength + sizeof(WCHAR);
89 
90  SND_TRACE(L"Interested in devices beginning with %wS\n", DevicePath);
91 
92  while ( RegEnumValue(DevicesKey,
93  ValueIndex,
94  ValueName,
95  &ValueNameLength,
96  NULL,
97  &ValueType,
98  (LPBYTE) &ValueData,
99  &ValueDataLength) == ERROR_SUCCESS )
100  {
101  /* Device types are stored as DWORDs */
102  if ( ( ValueType == REG_DWORD ) &&
103  ( ValueDataLength == sizeof(DWORD) ) )
104  {
105  if ( ( DeviceType == 0 ) ||
106  ( DeviceType == ValueData ) )
107  {
108  SND_TRACE(L"Found device: %wS\n", DevicePath);
109  SoundDeviceDetectedProc(ValueData, DevicePath);
110  }
111  }
112 
113  /* Reset variables for the next iteration */
114  ValueNameLength = MaxNameLength + sizeof(WCHAR);
115  ZeroMemory(ValueName, (MaxNameLength+1)*sizeof(WCHAR));
116  /*ZeroWideString(ValueName);*/
117  ValueDataLength = sizeof(DWORD);
118  ValueData = 0;
120 
121  ++ ValueIndex;
122  }
123 
124  FreeMemory(DevicePath);
125 
126  RegCloseKey(DevicesKey);
127  }
128  else
129  {
130  SND_WARN(L"Unable to open the Devices key!\n");
131  }
132 
133  ++ KeyIndex;
134 
135  RegCloseKey(Key);
136  }
137 
138  return MMSYSERR_NOERROR;
139 }
140 
141 /*
142  Brute-force device detection, using a base device name (eg: \\.\WaveOut).
143 
144  This will add the device number as a suffix to the end of the string and
145  attempt to open the device based on that name. On success, it will
146  increment the device number and repeat this process.
147 
148  When it runs out of devices, it will give up.
149 */
150 MMRESULT
153  IN PWSTR BaseDeviceName,
154  IN SOUND_DEVICE_DETECTED_PROC SoundDeviceDetectedProc)
155 {
156  SIZE_T DeviceNameLength = 0;
158  ULONG Index = 0;
160  BOOLEAN DoSearch = TRUE;
161 
163 
164  DeviceNameLength = wcslen(BaseDeviceName);
165  /* Consider the length of the number */
166  DeviceNameLength += GetDigitCount(Index);
167 
168  DeviceName = AllocateWideString(DeviceNameLength);
169 
170  if ( ! DeviceName )
171  {
172  return MMSYSERR_NOMEM;
173  }
174 
175  while ( DoSearch )
176  {
177  /* Nothing like a nice clean device name */
179  wsprintf(DeviceName, L"%ls%d", BaseDeviceName, Index);
180 
182  TRUE,
184  {
185  /* Notify the callback function */
186  SND_TRACE(L"Found device: %wS\n", DeviceName);
187  SoundDeviceDetectedProc(DeviceType, DeviceName);
188 
190 
191  ++ Index;
192  }
193  else
194  {
195  DoSearch = FALSE;
196  }
197  }
198 
200 
201  return MMSYSERR_NOERROR;
202 }
#define IN
Definition: typedefs.h:39
static VOID FreeMemory(PCREATE_DATA Data)
Definition: create.c:134
#define CloseHandle
Definition: compat.h:598
_Inout_ PUSB_DEVICE_HANDLE DeviceHandle
Definition: hubbusif.h:121
#define RegQueryInfoKey
Definition: winreg.h:521
#define ERROR_SUCCESS
Definition: deptool.c:10
UINT GetDigitCount(IN UINT Number)
Definition: utility.c:68
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
MMRESULT DetectNt4SoundDevices(IN MMDEVICE_TYPE DeviceType, IN PWSTR BaseDeviceName, IN SOUND_DEVICE_DETECTED_PROC SoundDeviceDetectedProc)
Definition: detect.c:151
#define KEY_READ
Definition: nt_native.h:1023
#define TRUE
Definition: types.h:120
uint16_t * PWSTR
Definition: typedefs.h:56
#define ZeroMemory
Definition: winbase.h:1664
UINT MMRESULT
Definition: mmsystem.h:962
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG _Out_opt_ PULONG _Out_opt_ PULONG ValueType
Definition: wdfregistry.h:279
#define DWORD
Definition: nt_native.h:44
#define VALIDATE_MMSYS_PARAMETER(parameter_condition)
Definition: mmebuddy.h:71
#define ZeroWideString(string)
Definition: mmebuddy.h:36
UCHAR MMDEVICE_TYPE
Definition: mmebuddy.h:88
#define MMSYSERR_NOMEM
Definition: mmsystem.h:103
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3272
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
unsigned char * LPBYTE
Definition: typedefs.h:53
MMRESULT OpenKernelSoundDeviceByName(IN PWSTR DevicePath, IN BOOLEAN ReadOnly, OUT PHANDLE Handle)
Definition: kernel.c:23
#define FALSE
Definition: types.h:117
#define IsValidSoundDeviceType
Definition: mmebuddy.h:69
#define AllocateWideString(string_length)
Definition: mmebuddy.h:33
unsigned char BOOLEAN
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFKEY * Key
Definition: wdfdevice.h:2654
DeviceType
Definition: mmdrv.h:41
MMRESULT OpenSoundDeviceRegKey(IN LPWSTR ServiceName, IN DWORD DeviceIndex, OUT PHKEY KeyHandle)
Definition: registry.c:73
MMRESULT EnumerateNt4ServiceSoundDevices(IN LPWSTR ServiceName, IN MMDEVICE_TYPE DeviceType, IN SOUND_DEVICE_DETECTED_PROC SoundDeviceDetectedProc)
Definition: detect.c:26
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
LPTSTR ServiceName
Definition: ServiceMain.c:15
#define MMSYSERR_ERROR
Definition: mmsystem.h:97
__wchar_t WCHAR
Definition: xmlstorage.h:180
_In_ WDFCOLLECTION _In_ ULONG Index
#define SND_ERR(...)
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:311
unsigned long DWORD
Definition: ntddk_ex.h:95
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:240
static const WCHAR L[]
Definition: oid.c:1250
BOOLEAN(* SOUND_DEVICE_DETECTED_PROC)(UCHAR DeviceType, PWSTR DevicePath)
Definition: mment4.h:24
#define SND_WARN(...)
#define REG_DEVICES_KEY_NAME_U
Definition: sndnames.h:78
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RegOpenKeyEx
Definition: winreg.h:520
#define NULL
Definition: types.h:112
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
unsigned int ULONG
Definition: retypes.h:1
#define REG_NONE
Definition: nt_native.h:1492
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define wsprintf
Definition: winuser.h:5840
#define REG_DWORD
Definition: sdbapi.c:596
#define RegEnumValue
Definition: winreg.h:511
#define SND_TRACE(...)