1 /*
2 *
3 * PROJECT: ReactOS Multimedia Control Panel
4 * FILE: dll/cpl/mmsys/mmsys.c
5 * PURPOSE: ReactOS Multimedia Control Panel
6 * PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com>
7 * Dmitry Chapyshev <dmitry@reactos.org>
8 * UPDATE HISTORY:
9 * 2005/11/23 Created
10 */
11
12 #include "mmsys.h"
13
14 #include <winsvc.h>
15 #include <shlwapi.h>
16 #include <debug.h>
17
18 #include <swenum.h>
19 #include <newdev.h>
20 #include <initguid.h>
21 #include <devguid.h>
22
23 typedef enum
24 {
25 HWPD_STANDARDLIST = 0,
26 HWPD_LARGELIST,
27 HWPD_MAX = HWPD_LARGELIST
28 } HWPAGE_DISPLAYMODE, *PHWPAGE_DISPLAYMODE;
29
30 typedef struct
31 {
32 LPWSTR LabelName;
33 LPWSTR DefaultName;
34 UINT LocalizedResId;
35 LPWSTR FileName;
36 } EVENT_LABEL_ITEM;
37
38 typedef struct
39 {
40 LPWSTR LabelName;
41 LPWSTR DefaultName;
42 UINT IconId;
43 } SYSTEM_SCHEME_ITEM;
44
45 static EVENT_LABEL_ITEM EventLabels[] =
46 {
47 {
48 L"WindowsLogon",
49 L"ReactOS Logon",
50 IDS_REACTOS_LOGON,
51 L"ReactOS_Logon.wav"
52 },
53 {
54 L"WindowsLogoff",
55 L"ReactOS Logoff",
56 IDS_REACTOS_LOGOFF,
57 L"ReactOS_Logoff.wav"
58 },
59 {
60 NULL,
61 NULL,
62 0,
63 NULL
64 }
65 };
66
67 static SYSTEM_SCHEME_ITEM SystemSchemes[] =
68 {
69 {
70 L".Default",
71 L"ReactOS Standard",
72 IDS_REACTOS_DEFAULT_SCHEME
73 },
74 {
75 L".None",
76 L"No Sounds",
77 -1
78 },
79 {
80 NULL,
81 NULL
82 }
83 };
84
85
86 HWND WINAPI
87 DeviceCreateHardwarePageEx(HWND hWndParent,
88 LPGUID lpGuids,
89 UINT uNumberOfGuids,
90 HWPAGE_DISPLAYMODE DisplayMode);
91
92 typedef BOOL (WINAPI *UpdateDriverForPlugAndPlayDevicesProto)(
93 _In_opt_ HWND hwndParent,
94 _In_ LPCWSTR HardwareId,
95 _In_ LPCWSTR FullInfPath,
96 _In_ DWORD InstallFlags,
97 _Out_opt_ PBOOL bRebootRequired);
98
99 #define UPDATEDRIVERFORPLUGANDPLAYDEVICES "UpdateDriverForPlugAndPlayDevicesW"
100 #define NUM_APPLETS (1)
101
102
103 HINSTANCE hApplet = 0;
104
105 /* Applets */
106 const APPLET Applets[NUM_APPLETS] =
107 {
108 {IDI_CPLICON, IDS_CPLNAME, IDS_CPLDESCRIPTION, MmSysApplet},
109 };
110
111
112 HRESULT WINAPI
DllCanUnloadNow(VOID)113 DllCanUnloadNow(VOID)
114 {
115 DPRINT1("DllCanUnloadNow() stubs\n");
116 return S_OK;
117 }
118
119 HRESULT WINAPI
DllGetClassObject(REFCLSID rclsid,REFIID riid,LPVOID * ppv)120 DllGetClassObject(REFCLSID rclsid,
121 REFIID riid,
122 LPVOID *ppv)
123 {
124 DPRINT1("DllGetClassObject() stubs\n");
125 return S_OK;
126 }
127
128
129 VOID WINAPI
ShowDriverSettingsAfterForkW(HWND hwnd,HINSTANCE hInstance,LPWSTR lpszCmd,int nCmdShow)130 ShowDriverSettingsAfterForkW(HWND hwnd,
131 HINSTANCE hInstance,
132 LPWSTR lpszCmd,
133 int nCmdShow)
134 {
135 DPRINT1("ShowDriverSettingsAfterForkW() stubs\n");
136 }
137
138 VOID WINAPI
ShowDriverSettingsAfterForkA(HWND hwnd,HINSTANCE hInstance,LPSTR lpszCmd,int nCmdShow)139 ShowDriverSettingsAfterForkA(HWND hwnd,
140 HINSTANCE hInstance,
141 LPSTR lpszCmd,
142 int nCmdShow)
143 {
144 DPRINT1("ShowDriverSettingsAfterForkA() stubs\n");
145 }
146
147 VOID WINAPI
ShowDriverSettingsAfterFork(HWND hwnd,HINSTANCE hInstance,LPSTR lpszCmd,int nCmdShow)148 ShowDriverSettingsAfterFork(HWND hwnd,
149 HINSTANCE hInstance,
150 LPSTR lpszCmd,
151 int nCmdShow)
152 {
153 DPRINT1("ShowDriverSettingsAfterFork() stubs\n");
154 }
155
156 BOOL WINAPI
ShowMMCPLPropertySheet(HWND hwnd,LPCSTR pszPropSheet,LPSTR pszName,LPSTR pszCaption)157 ShowMMCPLPropertySheet(HWND hwnd,
158 LPCSTR pszPropSheet,
159 LPSTR pszName,
160 LPSTR pszCaption)
161 {
162 DPRINT1("ShowMMCPLPropertySheet() stubs\n");
163 return TRUE;
164 }
165
166 VOID WINAPI
mmseRunOnceW(HWND hwnd,HINSTANCE hInstance,LPWSTR lpszCmd,int nCmdShow)167 mmseRunOnceW(HWND hwnd,
168 HINSTANCE hInstance,
169 LPWSTR lpszCmd,
170 int nCmdShow)
171 {
172 DPRINT1("mmseRunOnceW() stubs\n");
173 }
174
175 VOID WINAPI
mmseRunOnceA(HWND hwnd,HINSTANCE hInstance,LPSTR lpszCmd,int nCmdShow)176 mmseRunOnceA(HWND hwnd,
177 HINSTANCE hInstance,
178 LPSTR lpszCmd,
179 int nCmdShow)
180 {
181 DPRINT1("mmseRunOnceA() stubs\n");
182 }
183
184 VOID WINAPI
mmseRunOnce(HWND hwnd,HINSTANCE hInstance,LPSTR lpszCmd,int nCmdShow)185 mmseRunOnce(HWND hwnd,
186 HINSTANCE hInstance,
187 LPSTR lpszCmd,
188 int nCmdShow)
189 {
190 DPRINT1("mmseRunOnce() stubs\n");
191 }
192
193 BOOL WINAPI
MediaPropPageProvider(LPVOID Info,LPFNADDPROPSHEETPAGE PropSheetPage,LPARAM lParam)194 MediaPropPageProvider(LPVOID Info,
195 LPFNADDPROPSHEETPAGE PropSheetPage,
196 LPARAM lParam)
197 {
198 DPRINT1("MediaPropPageProvider() stubs\n");
199 return TRUE;
200 }
201
202 VOID
InstallSystemSoundLabels(HKEY hKey)203 InstallSystemSoundLabels(HKEY hKey)
204 {
205 UINT i = 0;
206 HKEY hSubKey;
207 WCHAR Buffer[40];
208
209 do
210 {
211 if (RegCreateKeyExW(hKey, EventLabels[i].LabelName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hSubKey, NULL) == ERROR_SUCCESS)
212 {
213 RegSetValueExW(hSubKey, NULL, 0, REG_SZ, (LPBYTE)EventLabels[i].DefaultName, (wcslen(EventLabels[i].DefaultName) + 1) * sizeof(WCHAR));
214 StringCchPrintfW(Buffer, _countof(Buffer), L"@mmsys.cpl,-%u", EventLabels[i].LocalizedResId);
215 RegSetValueExW(hSubKey, L"DispFileName", 0, REG_SZ, (LPBYTE)Buffer, (wcslen(Buffer) + 1) * sizeof(WCHAR));
216
217 RegCloseKey(hSubKey);
218 }
219 i++;
220 } while (EventLabels[i].LabelName);
221 }
222
223 VOID
InstallSystemSoundSchemeNames(HKEY hKey)224 InstallSystemSoundSchemeNames(HKEY hKey)
225 {
226 UINT i = 0;
227 HKEY hSubKey;
228
229 do
230 {
231 if (RegCreateKeyExW(hKey, SystemSchemes[i].LabelName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hSubKey, NULL) == ERROR_SUCCESS)
232 {
233 RegSetValueExW(hSubKey, NULL, 0, REG_SZ, (LPBYTE)SystemSchemes[i].DefaultName, (wcslen(SystemSchemes[i].DefaultName) + 1) * sizeof(WCHAR));
234 RegCloseKey(hSubKey);
235 }
236 i++;
237 } while (SystemSchemes[i].LabelName);
238 }
239
240 VOID
InstallDefaultSystemSoundScheme(HKEY hRootKey)241 InstallDefaultSystemSoundScheme(HKEY hRootKey)
242 {
243 HKEY hKey, hSubKey;
244 WCHAR Path[MAX_PATH];
245 UINT i = 0;
246
247 if (RegCreateKeyExW(hRootKey, L".Default", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL) != ERROR_SUCCESS)
248 return;
249
250 RegSetValueExW(hKey, NULL, 0, REG_SZ, (LPBYTE)SystemSchemes[0].DefaultName, (wcslen(SystemSchemes[0].DefaultName) + 1) * sizeof(WCHAR));
251 StringCchPrintfW(Path, _countof(Path), L"@mmsys.cpl,-%u", SystemSchemes[0].IconId);
252 RegSetValueExW(hKey, L"DispFileName", 0, REG_SZ, (LPBYTE)Path, (wcslen(Path) + 1) * sizeof(WCHAR));
253
254 do
255 {
256 if (RegCreateKeyExW(hKey, EventLabels[i].LabelName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hSubKey, NULL) == ERROR_SUCCESS)
257 {
258 HKEY hScheme;
259
260 StringCchPrintfW(Path, _countof(Path), L"%%SystemRoot%%\\media\\%s", EventLabels[i].FileName);
261 if (RegCreateKeyExW(hSubKey, L".Current", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hScheme, NULL) == ERROR_SUCCESS)
262 {
263 RegSetValueExW(hScheme, NULL, 0, REG_EXPAND_SZ, (LPBYTE)Path, (wcslen(Path) + 1) * sizeof(WCHAR));
264 RegCloseKey(hScheme);
265 }
266
267 if (RegCreateKeyExW(hSubKey, L".Default", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hScheme, NULL) == ERROR_SUCCESS)
268 {
269 RegSetValueExW(hScheme, NULL, 0, REG_EXPAND_SZ, (LPBYTE)Path, (wcslen(Path) + 1) * sizeof(WCHAR));
270 RegCloseKey(hScheme);
271 }
272 RegCloseKey(hSubKey);
273 }
274 i++;
275 } while (EventLabels[i].LabelName);
276
277 RegCloseKey(hKey);
278 }
279
280
281 VOID
InstallSystemSoundScheme(VOID)282 InstallSystemSoundScheme(VOID)
283 {
284 HKEY hKey, hSubKey;
285 DWORD dwDisposition;
286
287 if (RegCreateKeyExW(HKEY_CURRENT_USER, L"AppEvents", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL) != ERROR_SUCCESS)
288 return;
289
290 if (RegCreateKeyExW(hKey, L"EventLabels", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hSubKey, NULL) == ERROR_SUCCESS)
291 {
292 InstallSystemSoundLabels(hSubKey);
293 RegCloseKey(hSubKey);
294 }
295
296 if (RegCreateKeyExW(hKey, L"Schemes", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hSubKey, &dwDisposition) == ERROR_SUCCESS)
297 {
298 HKEY hNames;
299
300 if (RegCreateKeyExW(hSubKey, L"Names", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hNames, NULL) == ERROR_SUCCESS)
301 {
302 InstallSystemSoundSchemeNames(hNames);
303 RegCloseKey(hNames);
304 }
305
306 if (RegCreateKeyExW(hSubKey, L"Apps", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hNames, NULL) == ERROR_SUCCESS)
307 {
308 InstallDefaultSystemSoundScheme(hNames);
309 RegCloseKey(hNames);
310 if (dwDisposition & REG_CREATED_NEW_KEY)
311 {
312 // FIXME
313 RegSetValueExW(hSubKey, NULL, 0, REG_SZ, (LPBYTE)L".Default", sizeof(L".Default"));
314 }
315 }
316
317 RegCloseKey(hSubKey);
318 }
319
320 RegCloseKey(hKey);
321 }
322
323 BOOL
IsSoftwareBusPnpEnumeratorInstalled()324 IsSoftwareBusPnpEnumeratorInstalled()
325 {
326 HDEVINFO hDevInfo;
327 SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;
328 GUID SWBusGuid = {STATIC_BUSID_SoftwareDeviceEnumerator};
329 PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData;
330
331 hDevInfo = SetupDiGetClassDevsW(&SWBusGuid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
332 if (!hDevInfo)
333 {
334 // failed
335 return FALSE;
336 }
337
338 DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
339 if (!SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &SWBusGuid, 0, &DeviceInterfaceData))
340 {
341 // failed
342 SetupDiDestroyDeviceInfoList(hDevInfo);
343 return FALSE;
344 }
345
346 DeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA_W)HeapAlloc(GetProcessHeap(), 0, (MAX_PATH * sizeof(WCHAR)) + sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W));
347 if (!DeviceInterfaceDetailData)
348 {
349 // failed
350 SetupDiDestroyDeviceInfoList(hDevInfo);
351 return FALSE;
352 }
353
354 DeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W);
355 if (!SetupDiGetDeviceInterfaceDetailW(hDevInfo, &DeviceInterfaceData, DeviceInterfaceDetailData, (MAX_PATH * sizeof(WCHAR)) + sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W), NULL, NULL))
356 {
357 // failed
358 HeapFree(GetProcessHeap(), 0, DeviceInterfaceDetailData);
359 SetupDiDestroyDeviceInfoList(hDevInfo);
360 return FALSE;
361 }
362 HeapFree(GetProcessHeap(), 0, DeviceInterfaceDetailData);
363 SetupDiDestroyDeviceInfoList(hDevInfo);
364 return TRUE;
365 }
366
367 DWORD
InstallSoftwareBusPnpEnumerator(LPCWSTR InfPath,LPCWSTR HardwareIdList)368 InstallSoftwareBusPnpEnumerator(LPCWSTR InfPath, LPCWSTR HardwareIdList)
369 {
370 HDEVINFO DeviceInfoSet = INVALID_HANDLE_VALUE;
371 SP_DEVINFO_DATA DeviceInfoData;
372 GUID ClassGUID;
373 WCHAR ClassName[50];
374 int Result = 0;
375 HMODULE hModule = NULL;
376 UpdateDriverForPlugAndPlayDevicesProto UpdateProc;
377 BOOL reboot = FALSE;
378 DWORD flags = 0;
379
380 if (!SetupDiGetINFClassW(InfPath, &ClassGUID, ClassName, _countof(ClassName), NULL))
381 {
382 return -1;
383 }
384
385 DeviceInfoSet = SetupDiCreateDeviceInfoList(&ClassGUID, NULL);
386 if (DeviceInfoSet == INVALID_HANDLE_VALUE)
387 {
388 return -1;
389 }
390
391 DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
392 if (!SetupDiCreateDeviceInfoW(DeviceInfoSet, ClassName, &ClassGUID, NULL, NULL, DICD_GENERATE_ID, &DeviceInfoData))
393 {
394 SetupDiDestroyDeviceInfoList(DeviceInfoSet);
395 return -1;
396 }
397
398 if (!SetupDiSetDeviceRegistryPropertyW(DeviceInfoSet, &DeviceInfoData, SPDRP_HARDWAREID, (LPBYTE)HardwareIdList, (wcslen(HardwareIdList) + 1 + 1) * sizeof(WCHAR)))
399 {
400 SetupDiDestroyDeviceInfoList(DeviceInfoSet);
401 return -1;
402 }
403
404 if (!SetupDiCallClassInstaller(DIF_REGISTERDEVICE, DeviceInfoSet, &DeviceInfoData))
405 {
406 SetupDiDestroyDeviceInfoList(DeviceInfoSet);
407 return -1;
408 }
409
410 if (GetFileAttributesW(InfPath) == INVALID_FILE_ATTRIBUTES)
411 {
412 SetupDiDestroyDeviceInfoList(DeviceInfoSet);
413 return -1;
414 }
415
416 flags |= INSTALLFLAG_FORCE;
417 hModule = LoadLibraryW(L"newdev.dll");
418 if (!hModule)
419 {
420 SetupDiDestroyDeviceInfoList(DeviceInfoSet);
421 return -1;
422 }
423
424 UpdateProc = (UpdateDriverForPlugAndPlayDevicesProto)GetProcAddress(hModule, UPDATEDRIVERFORPLUGANDPLAYDEVICES);
425 if (!UpdateProc)
426 {
427 SetupDiDestroyDeviceInfoList(DeviceInfoSet);
428 FreeLibrary(hModule);
429 return -1;
430 }
431
432 if (!UpdateProc(NULL, HardwareIdList, InfPath, flags, &reboot))
433 {
434 SetupDiDestroyDeviceInfoList(DeviceInfoSet);
435 FreeLibrary(hModule);
436 return -1;
437 }
438
439 FreeLibrary(hModule);
440 SetupDiDestroyDeviceInfoList(DeviceInfoSet);
441 return Result;
442 }
443
444 DWORD
MMSYS_InstallDevice(HDEVINFO hDevInfo,PSP_DEVINFO_DATA pspDevInfoData)445 MMSYS_InstallDevice(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pspDevInfoData)
446 {
447 UINT Length;
448 WCHAR szBuffer[MAX_PATH];
449 HINF hInf;
450 PVOID Context;
451 BOOL Result;
452 SC_HANDLE hSCManager, hService;
453 WCHAR WaveName[20];
454 HKEY hKey;
455 DWORD BufferSize;
456 ULONG Index;
457
458 if (!IsEqualIID(&pspDevInfoData->ClassGuid, &GUID_DEVCLASS_SOUND) &&
459 !IsEqualIID(&pspDevInfoData->ClassGuid, &GUID_DEVCLASS_MEDIA))
460 return ERROR_DI_DO_DEFAULT;
461
462 Length = GetWindowsDirectoryW(szBuffer, _countof(szBuffer));
463 if (!Length || Length >= _countof(szBuffer) - CONST_STR_LEN(L"\\inf\\audio.inf"))
464 {
465 return ERROR_GEN_FAILURE;
466 }
467
468 //PathCchAppend(szBuffer, _countof(szBuffer), L"inf\\audio.inf");
469 StringCchCatW(szBuffer, _countof(szBuffer), L"\\inf\\audio.inf");
470
471 hInf = SetupOpenInfFileW(szBuffer,
472 NULL,
473 INF_STYLE_WIN4,
474 NULL);
475
476 if (hInf == INVALID_HANDLE_VALUE)
477 {
478 return ERROR_GEN_FAILURE;
479 }
480
481 Context = SetupInitDefaultQueueCallback(NULL);
482 if (Context == NULL)
483 {
484 SetupCloseInfFile(hInf);
485 return ERROR_GEN_FAILURE;
486 }
487
488 Result = SetupInstallFromInfSectionW(NULL,
489 hInf,
490 L"AUDIO_Inst.NT",
491 SPINST_ALL,
492 NULL,
493 NULL,
494 SP_COPY_NEWER,
495 SetupDefaultQueueCallbackW,
496 Context,
497 NULL,
498 NULL);
499
500 if (Result)
501 {
502 Result = SetupInstallServicesFromInfSectionW(hInf,
503 L"Audio_Inst.NT.Services",
504 0);
505 }
506
507 SetupTermDefaultQueueCallback(Context);
508 SetupCloseInfFile(hInf);
509
510 if (!IsSoftwareBusPnpEnumeratorInstalled())
511 {
512 Length = GetWindowsDirectoryW(szBuffer, _countof(szBuffer));
513 if (!Length || Length >= _countof(szBuffer) - CONST_STR_LEN(L"\\inf\\machine.inf"))
514 {
515 return ERROR_GEN_FAILURE;
516 }
517
518 //PathCchAppend(szBuffer, _countof(szBuffer), L"inf\\machine.inf");
519 StringCchCatW(szBuffer, _countof(szBuffer), L"\\inf\\machine.inf");
520
521 InstallSoftwareBusPnpEnumerator(szBuffer, L"ROOT\\SWENUM\0");
522 }
523
524 hSCManager = OpenSCManagerW(NULL, NULL, SC_MANAGER_CONNECT);
525 if (!hSCManager)
526 {
527 return ERROR_DI_DO_DEFAULT;
528 }
529
530 hService = OpenServiceW(hSCManager, L"AudioSrv", SERVICE_ALL_ACCESS);
531 if (hService)
532 {
533 /* Make AudioSrv start automatically */
534 ChangeServiceConfigW(hService, SERVICE_NO_CHANGE, SERVICE_AUTO_START, SERVICE_NO_CHANGE, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
535
536 StartServiceW(hService, 0, NULL);
537 CloseServiceHandle(hService);
538 }
539 CloseServiceHandle(hSCManager);
540
541 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Drivers32", 0, KEY_READ | KEY_WRITE, &hKey) == ERROR_SUCCESS)
542 {
543 Length = GetSystemDirectoryW(szBuffer, _countof(szBuffer));
544 if (!Length || Length >= _countof(szBuffer) - CONST_STR_LEN(L"\\wdmaud.drv"))
545 {
546 RegCloseKey(hKey);
547 return ERROR_DI_DO_DEFAULT;
548 }
549
550 //PathCchAppend(szBuffer, _countof(szBuffer), L"wdmaud.drv");
551 StringCchCatW(szBuffer, _countof(szBuffer), L"\\wdmaud.drv");
552
553 for (Index = 1; Index <= 4; Index++)
554 {
555 StringCchPrintfW(WaveName, _countof(WaveName), L"wave%u", Index);
556 if (RegQueryValueExW(hKey, WaveName, 0, NULL, NULL, &BufferSize) != ERROR_MORE_DATA)
557 {
558 /* Store new audio driver entry */
559 RegSetValueExW(hKey, WaveName, 0, REG_SZ, (LPBYTE)szBuffer, (wcslen(szBuffer) + 1) * sizeof(WCHAR));
560 break;
561 }
562 else
563 {
564 WCHAR Buffer[MAX_PATH];
565 BufferSize = sizeof(Buffer);
566
567 if (RegQueryValueExW(hKey, WaveName, 0, NULL, (LPBYTE)Buffer, &BufferSize) == ERROR_SUCCESS)
568 {
569 /* Make sure the buffer is zero terminated */
570 Buffer[_countof(Buffer) - 1] = UNICODE_NULL;
571
572 if (!_wcsicmp(Buffer, szBuffer))
573 {
574 /* An entry already exists */
575 break;
576 }
577 }
578 }
579 }
580 RegCloseKey(hKey);
581 }
582 InstallSystemSoundScheme();
583
584 return ERROR_DI_DO_DEFAULT;
585
586 }
587
588 DWORD
MMSYS_RemoveDevice(HDEVINFO hDevInfo,PSP_DEVINFO_DATA pspDevInfoData)589 MMSYS_RemoveDevice(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pspDevInfoData)
590 {
591 return ERROR_DI_DO_DEFAULT;
592 }
593
594 DWORD
MMSYS_AllowInstallDevice(HDEVINFO hDevInfo,PSP_DEVINFO_DATA pspDevInfoData)595 MMSYS_AllowInstallDevice(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pspDevInfoData)
596 {
597 return ERROR_DI_DO_DEFAULT;
598 }
599
600 DWORD
MMSYS_SelectDevice(HDEVINFO hDevInfo,PSP_DEVINFO_DATA pspDevInfoData)601 MMSYS_SelectDevice(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pspDevInfoData)
602 {
603 return ERROR_DI_DO_DEFAULT;
604 }
605
606 DWORD
MMSYS_DetectDevice(HDEVINFO hDevInfo,PSP_DEVINFO_DATA pspDevInfoData)607 MMSYS_DetectDevice(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pspDevInfoData)
608 {
609 return ERROR_DI_DO_DEFAULT;
610 }
611
612 DWORD
MMSYS_SelectBestCompatDRV(HDEVINFO hDevInfo,PSP_DEVINFO_DATA pspDevInfoData)613 MMSYS_SelectBestCompatDRV(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pspDevInfoData)
614 {
615 return ERROR_DI_DO_DEFAULT;
616 }
617
618 DWORD WINAPI
MediaClassInstaller(IN DI_FUNCTION diFunction,IN HDEVINFO hDevInfo,IN PSP_DEVINFO_DATA pspDevInfoData OPTIONAL)619 MediaClassInstaller(IN DI_FUNCTION diFunction,
620 IN HDEVINFO hDevInfo,
621 IN PSP_DEVINFO_DATA pspDevInfoData OPTIONAL)
622 {
623 switch (diFunction)
624 {
625 case DIF_INSTALLDEVICE:
626 return MMSYS_InstallDevice(hDevInfo, pspDevInfoData);
627 case DIF_REMOVE:
628 return MMSYS_RemoveDevice(hDevInfo, pspDevInfoData);
629 case DIF_ALLOW_INSTALL:
630 return MMSYS_AllowInstallDevice(hDevInfo, pspDevInfoData);
631 case DIF_SELECTDEVICE:
632 return MMSYS_SelectDevice(hDevInfo, pspDevInfoData);
633 case DIF_DETECT:
634 return MMSYS_DetectDevice(hDevInfo, pspDevInfoData);
635 case DIF_SELECTBESTCOMPATDRV:
636 return MMSYS_SelectBestCompatDRV(hDevInfo, pspDevInfoData);
637 default:
638 return ERROR_DI_DO_DEFAULT;
639 }
640 }
641
642
643 /* Hardware property page dialog callback */
644 static INT_PTR CALLBACK
HardwareDlgProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)645 HardwareDlgProc(HWND hwndDlg,
646 UINT uMsg,
647 WPARAM wParam,
648 LPARAM lParam)
649 {
650 UNREFERENCED_PARAMETER(lParam);
651 UNREFERENCED_PARAMETER(wParam);
652 switch (uMsg)
653 {
654 case WM_INITDIALOG:
655 {
656 GUID Guids[2];
657 Guids[0] = GUID_DEVCLASS_CDROM;
658 Guids[1] = GUID_DEVCLASS_MEDIA;
659
660 /* Create the hardware page */
661 DeviceCreateHardwarePageEx(hwndDlg,
662 Guids,
663 _countof(Guids),
664 HWPD_LARGELIST);
665 break;
666 }
667 }
668
669 return FALSE;
670 }
671
672 static int CALLBACK
PropSheetProc(HWND hwndDlg,UINT uMsg,LPARAM lParam)673 PropSheetProc(HWND hwndDlg, UINT uMsg, LPARAM lParam)
674 {
675 // NOTE: This callback is needed to set large icon correctly.
676 HICON hIcon;
677 switch (uMsg)
678 {
679 case PSCB_INITIALIZED:
680 {
681 hIcon = LoadIconW(hApplet, MAKEINTRESOURCEW(IDI_CPLICON));
682 SendMessageW(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
683 break;
684 }
685 }
686 return 0;
687 }
688
689 LONG APIENTRY
MmSysApplet(HWND hwnd,UINT uMsg,LPARAM wParam,LPARAM lParam)690 MmSysApplet(HWND hwnd,
691 UINT uMsg,
692 LPARAM wParam,
693 LPARAM lParam)
694 {
695 PROPSHEETPAGEW psp[5];
696 PROPSHEETHEADERW psh; // = { 0 };
697 INT nPage = 0;
698
699 UNREFERENCED_PARAMETER(wParam);
700
701 if (uMsg == CPL_STARTWPARMSW && lParam != 0)
702 nPage = _wtoi((PWSTR)lParam);
703
704 psh.dwSize = sizeof(PROPSHEETHEADERW);
705 psh.dwFlags = PSH_PROPSHEETPAGE | PSH_PROPTITLE | PSH_USEICONID | PSH_USECALLBACK;
706 psh.hwndParent = hwnd;
707 psh.hInstance = hApplet;
708 psh.pszIcon = MAKEINTRESOURCEW(IDI_CPLICON);
709 psh.pszCaption = MAKEINTRESOURCEW(IDS_CPLNAME);
710 psh.nPages = _countof(psp);
711 psh.nStartPage = 0;
712 psh.ppsp = psp;
713 psh.pfnCallback = PropSheetProc;
714
715 InitPropSheetPage(&psp[0], IDD_VOLUME, VolumeDlgProc);
716 InitPropSheetPage(&psp[1], IDD_SOUNDS, SoundsDlgProc);
717 InitPropSheetPage(&psp[2], IDD_AUDIO, AudioDlgProc);
718 InitPropSheetPage(&psp[3], IDD_VOICE, VoiceDlgProc);
719 InitPropSheetPage(&psp[4], IDD_HARDWARE, HardwareDlgProc);
720
721 if (nPage != 0 && nPage <= psh.nPages)
722 psh.nStartPage = nPage;
723
724 return (LONG)(PropertySheetW(&psh) != -1);
725 }
726
727 VOID
InitPropSheetPage(PROPSHEETPAGEW * psp,WORD idDlg,DLGPROC DlgProc)728 InitPropSheetPage(PROPSHEETPAGEW *psp,
729 WORD idDlg,
730 DLGPROC DlgProc)
731 {
732 ZeroMemory(psp, sizeof(PROPSHEETPAGEW));
733 psp->dwSize = sizeof(PROPSHEETPAGEW);
734 psp->dwFlags = PSP_DEFAULT;
735 psp->hInstance = hApplet;
736 psp->pszTemplate = MAKEINTRESOURCEW(idDlg);
737 psp->pfnDlgProc = DlgProc;
738 }
739
740
741 /* Control Panel Callback */
742 LONG CALLBACK
CPlApplet(HWND hwndCpl,UINT uMsg,LPARAM lParam1,LPARAM lParam2)743 CPlApplet(HWND hwndCpl,
744 UINT uMsg,
745 LPARAM lParam1,
746 LPARAM lParam2)
747 {
748 UINT i = (UINT)lParam1;
749
750 switch (uMsg)
751 {
752 case CPL_INIT:
753 return TRUE;
754
755 case CPL_GETCOUNT:
756 return NUM_APPLETS;
757
758 case CPL_INQUIRE:
759 if (i < NUM_APPLETS)
760 {
761 CPLINFO *CPlInfo = (CPLINFO*)lParam2;
762 CPlInfo->lData = 0;
763 CPlInfo->idIcon = Applets[i].idIcon;
764 CPlInfo->idName = Applets[i].idName;
765 CPlInfo->idInfo = Applets[i].idDescription;
766 }
767 else
768 {
769 return TRUE;
770 }
771 break;
772
773 case CPL_DBLCLK:
774 if (i < NUM_APPLETS)
775 Applets[i].AppletProc(hwndCpl, uMsg, lParam1, lParam2);
776 else
777 return TRUE;
778 break;
779
780 case CPL_STARTWPARMSW:
781 if (i < NUM_APPLETS)
782 return Applets[i].AppletProc(hwndCpl, uMsg, lParam1, lParam2);
783 break;
784 }
785
786 return FALSE;
787 }
788
789 VOID WINAPI
ShowAudioPropertySheet(HWND hwnd,HINSTANCE hInstance,LPWSTR lpszCmd,int nCmdShow)790 ShowAudioPropertySheet(HWND hwnd,
791 HINSTANCE hInstance,
792 LPWSTR lpszCmd,
793 int nCmdShow)
794 {
795 PROPSHEETPAGEW psp[1];
796 PROPSHEETHEADERW psh;
797
798 DPRINT("ShowAudioPropertySheet()\n");
799
800 psh.dwSize = sizeof(PROPSHEETHEADERW);
801 psh.dwFlags = PSH_PROPSHEETPAGE | PSH_PROPTITLE | PSH_USEICONID | PSH_USECALLBACK;
802 psh.hwndParent = hwnd;
803 psh.hInstance = hInstance;
804 psh.pszIcon = MAKEINTRESOURCEW(IDI_CPLICON);
805 psh.pszCaption = MAKEINTRESOURCEW(IDS_CPLNAME);
806 psh.nPages = _countof(psp);
807 psh.nStartPage = 0;
808 psh.ppsp = psp;
809 psh.pfnCallback = PropSheetProc;
810
811 InitPropSheetPage(&psp[0], IDD_AUDIO,AudioDlgProc);
812
813 PropertySheetW(&psh);
814 }
815
816 VOID WINAPI
ShowFullControlPanel(HWND hwnd,HINSTANCE hInstance,LPSTR lpszCmd,int nCmdShow)817 ShowFullControlPanel(HWND hwnd,
818 HINSTANCE hInstance,
819 LPSTR lpszCmd,
820 int nCmdShow)
821 {
822 PROPSHEETPAGEW psp[5];
823 PROPSHEETHEADERW psh;
824
825 DPRINT("ShowFullControlPanel()\n");
826
827 psh.dwSize = sizeof(PROPSHEETHEADERW);
828 psh.dwFlags = PSH_PROPSHEETPAGE | PSH_PROPTITLE | PSH_USEICONID | PSH_USECALLBACK;
829 psh.hwndParent = hwnd;
830 psh.hInstance = hInstance;
831 psh.pszIcon = MAKEINTRESOURCEW(IDI_CPLICON);
832 psh.pszCaption = MAKEINTRESOURCEW(IDS_CPLNAME);
833 psh.nPages = _countof(psp);
834 psh.nStartPage = 0;
835 psh.ppsp = psp;
836 psh.pfnCallback = PropSheetProc;
837
838 InitPropSheetPage(&psp[0], IDD_VOLUME, VolumeDlgProc);
839 InitPropSheetPage(&psp[1], IDD_SOUNDS, SoundsDlgProc);
840 InitPropSheetPage(&psp[2], IDD_AUDIO, AudioDlgProc);
841 InitPropSheetPage(&psp[3], IDD_VOICE, VoiceDlgProc);
842 InitPropSheetPage(&psp[4], IDD_HARDWARE, HardwareDlgProc);
843
844 PropertySheetW(&psh);
845 }
846
847 BOOL WINAPI
DllMain(HINSTANCE hinstDLL,DWORD dwReason,LPVOID lpReserved)848 DllMain(HINSTANCE hinstDLL,
849 DWORD dwReason,
850 LPVOID lpReserved)
851 {
852 UNREFERENCED_PARAMETER(lpReserved);
853 switch (dwReason)
854 {
855 case DLL_PROCESS_ATTACH:
856 hApplet = hinstDLL;
857 DisableThreadLibraryCalls(hinstDLL);
858 break;
859 }
860
861 return TRUE;
862 }
863