ReactOS 0.4.15-dev-7924-g5949c20
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
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,
53 &DevicesKey) == ERROR_SUCCESS )
54 {
55 /* Find out how much memory is needed for the key name */
56 if ( RegQueryInfoKey(DevicesKey,
58 &MaxNameLength,
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,
95 &ValueNameLength,
96 NULL,
97 &ValueType,
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
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*/
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}
unsigned char BOOLEAN
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
static VOID FreeMemory(PCREATE_DATA Data)
Definition: create.c:134
static WCHAR ServiceName[]
Definition: browser.c:19
#define RegCloseKey(hKey)
Definition: registry.h:49
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define CloseHandle
Definition: compat.h:739
unsigned long DWORD
Definition: ntddk_ex.h:95
_Inout_ PUSB_DEVICE_HANDLE DeviceHandle
Definition: hubbusif.h:121
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:312
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
DeviceType
Definition: mmdrv.h:42
MMRESULT OpenKernelSoundDeviceByName(IN PWSTR DevicePath, IN BOOLEAN ReadOnly, OUT PHANDLE Handle)
Definition: kernel.c:23
#define VALIDATE_MMSYS_PARAMETER(parameter_condition)
Definition: mmebuddy.h:71
#define AllocateWideString(string_length)
Definition: mmebuddy.h:33
UCHAR MMDEVICE_TYPE
Definition: mmebuddy.h:88
UINT GetDigitCount(IN UINT Number)
Definition: utility.c:68
#define IsValidSoundDeviceType
Definition: mmebuddy.h:69
#define ZeroWideString(string)
Definition: mmebuddy.h:36
#define SND_TRACE(...)
#define SND_ERR(...)
#define SND_WARN(...)
MMRESULT OpenSoundDeviceRegKey(IN LPWSTR ServiceName, IN DWORD DeviceIndex, OUT PHKEY KeyHandle)
Definition: registry.c:73
BOOLEAN(* SOUND_DEVICE_DETECTED_PROC)(UCHAR DeviceType, PWSTR DevicePath)
Definition: mment4.h:24
#define MMSYSERR_NOMEM
Definition: mmsystem.h:103
UINT MMRESULT
Definition: mmsystem.h:962
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
#define MMSYSERR_ERROR
Definition: mmsystem.h:97
#define KEY_READ
Definition: nt_native.h:1023
#define DWORD
Definition: nt_native.h:44
#define REG_NONE
Definition: nt_native.h:1492
#define L(x)
Definition: ntvdm.h:50
#define REG_DWORD
Definition: sdbapi.c:596
MMRESULT DetectNt4SoundDevices(IN MMDEVICE_TYPE DeviceType, IN PWSTR BaseDeviceName, IN SOUND_DEVICE_DETECTED_PROC SoundDeviceDetectedProc)
Definition: detect.c:151
MMRESULT EnumerateNt4ServiceSoundDevices(IN LPWSTR ServiceName, IN MMDEVICE_TYPE DeviceType, IN SOUND_DEVICE_DETECTED_PROC SoundDeviceDetectedProc)
Definition: detect.c:26
#define REG_DEVICES_KEY_NAME_U
Definition: sndnames.h:78
uint16_t * PWSTR
Definition: typedefs.h:56
unsigned char * LPBYTE
Definition: typedefs.h:53
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3275
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG _Out_opt_ PULONG _Out_opt_ PULONG ValueType
Definition: wdfregistry.h:282
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243
#define ZeroMemory
Definition: winbase.h:1712
#define RegOpenKeyEx
Definition: winreg.h:520
#define RegEnumValue
Definition: winreg.h:511
#define RegQueryInfoKey
Definition: winreg.h:521
#define wsprintf
Definition: winuser.h:5865
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184