e2e21bc8dd93360c680b1dd003f7bd01b4cedfc5
[reactos.git] / dll / cpl / mmsys / mmsys.c
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)(IN OPTIONAL HWND hwndParent,
93 IN LPCTSTR HardwareId,
94 IN LPCTSTR FullInfPath,
95 IN DWORD InstallFlags,
96 OUT OPTIONAL PBOOL bRebootRequired
97 );
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
113 DllCanUnloadNow(VOID)
114 {
115 DPRINT1("DllCanUnloadNow() stubs\n");
116 return S_OK;
117 }
118
119 HRESULT WINAPI
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
130 ShowDriverSettingsAfterForkW(HWND hwnd,
131 HINSTANCE hInstance,
132 LPWSTR lpszCmd,
133 int nCmdShow)
134 {
135 DPRINT1("ShowDriverSettingsAfterForkW() stubs\n");
136 }
137
138 VOID WINAPI
139 ShowDriverSettingsAfterForkA(HWND hwnd,
140 HINSTANCE hInstance,
141 LPSTR lpszCmd,
142 int nCmdShow)
143 {
144 DPRINT1("ShowDriverSettingsAfterForkA() stubs\n");
145 }
146
147 VOID WINAPI
148 ShowDriverSettingsAfterFork(HWND hwnd,
149 HINSTANCE hInstance,
150 LPSTR lpszCmd,
151 int nCmdShow)
152 {
153 DPRINT1("ShowDriverSettingsAfterFork() stubs\n");
154 }
155
156 BOOL WINAPI
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
167 ShowAudioPropertySheet(HWND hwnd,
168 HINSTANCE hInstance,
169 LPTSTR lpszCmd,
170 int nCmdShow)
171 {
172 DPRINT1("ShowAudioPropertySheet() stubs\n");
173 }
174
175 VOID WINAPI
176 mmseRunOnceW(HWND hwnd,
177 HINSTANCE hInstance,
178 LPWSTR lpszCmd,
179 int nCmdShow)
180 {
181 DPRINT1("mmseRunOnceW() stubs\n");
182 }
183
184 VOID WINAPI
185 mmseRunOnceA(HWND hwnd,
186 HINSTANCE hInstance,
187 LPSTR lpszCmd,
188 int nCmdShow)
189 {
190 DPRINT1("mmseRunOnceA() stubs\n");
191 }
192
193 VOID WINAPI
194 mmseRunOnce(HWND hwnd,
195 HINSTANCE hInstance,
196 LPSTR lpszCmd,
197 int nCmdShow)
198 {
199 DPRINT1("mmseRunOnce() stubs\n");
200 }
201
202 BOOL WINAPI
203 MediaPropPageProvider(LPVOID Info,
204 LPFNADDPROPSHEETPAGE PropSheetPage,
205 LPARAM lParam)
206 {
207 DPRINT1("MediaPropPageProvider() stubs\n");
208 return TRUE;
209 }
210
211 VOID WINAPI
212 ShowFullControlPanel(HWND hwnd,
213 HINSTANCE hInstance,
214 LPSTR lpszCmd,
215 int nCmdShow)
216 {
217 DPRINT1("ShowFullControlPanel() stubs\n");
218 }
219
220 VOID
221 InstallSystemSoundLabels(HKEY hKey)
222 {
223 UINT i = 0;
224 HKEY hSubKey;
225 WCHAR Buffer[40];
226
227 do
228 {
229 if (RegCreateKeyExW(hKey, EventLabels[i].LabelName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hSubKey, NULL) == ERROR_SUCCESS)
230 {
231 RegSetValueExW(hSubKey, NULL, 0, REG_SZ, (LPBYTE)EventLabels[i].DefaultName, (wcslen(EventLabels[i].DefaultName)+1) * sizeof(WCHAR));
232 swprintf(Buffer, L"@mmsys.cpl,-%u", EventLabels[i].LocalizedResId);
233 RegSetValueExW(hSubKey, L"DispFileName", 0, REG_SZ, (LPBYTE)Buffer, (wcslen(Buffer)+1) * sizeof(WCHAR));
234
235 RegCloseKey(hSubKey);
236 }
237 i++;
238 }while(EventLabels[i].LabelName);
239 }
240
241 VOID
242 InstallSystemSoundSchemeNames(HKEY hKey)
243 {
244 UINT i = 0;
245 HKEY hSubKey;
246
247 do
248 {
249 if (RegCreateKeyExW(hKey, SystemSchemes[i].LabelName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hSubKey, NULL) == ERROR_SUCCESS)
250 {
251 RegSetValueExW(hSubKey, NULL, 0, REG_SZ, (LPBYTE)SystemSchemes[i].DefaultName, (wcslen(SystemSchemes[i].DefaultName)+1) * sizeof(WCHAR));
252 RegCloseKey(hSubKey);
253 }
254 i++;
255 }while(SystemSchemes[i].LabelName);
256 }
257
258 VOID
259 InstallDefaultSystemSoundScheme(HKEY hRootKey)
260 {
261 HKEY hKey, hSubKey;
262 WCHAR Path[MAX_PATH];
263 UINT i = 0;
264
265 if (RegCreateKeyExW(hRootKey, L".Default", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL) != ERROR_SUCCESS)
266 return;
267
268 RegSetValueExW(hKey, NULL, 0, REG_SZ, (LPBYTE)SystemSchemes[0].DefaultName, (wcslen(SystemSchemes[0].DefaultName)+1) * sizeof(WCHAR));
269 swprintf(Path, L"@mmsys.cpl,-%u", SystemSchemes[0].IconId);
270 RegSetValueExW(hKey, L"DispFileName", 0, REG_SZ, (LPBYTE)Path, (wcslen(Path)+1) * sizeof(WCHAR));
271
272 do
273 {
274 if (RegCreateKeyExW(hKey, EventLabels[i].LabelName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hSubKey, NULL) == ERROR_SUCCESS)
275 {
276 HKEY hScheme;
277
278 swprintf(Path, L"%%SystemRoot%%\\media\\%s", EventLabels[i].FileName);
279 if (RegCreateKeyExW(hSubKey, L".Current", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hScheme, NULL) == ERROR_SUCCESS)
280 {
281 RegSetValueExW(hScheme, NULL, 0, REG_EXPAND_SZ, (LPBYTE)Path, (wcslen(Path)+1) * sizeof(WCHAR));
282 RegCloseKey(hScheme);
283 }
284
285 if (RegCreateKeyExW(hSubKey, L".Default", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hScheme, NULL) == ERROR_SUCCESS)
286 {
287 RegSetValueExW(hScheme, NULL, 0, REG_EXPAND_SZ, (LPBYTE)Path, (wcslen(Path)+1) * sizeof(WCHAR));
288 RegCloseKey(hScheme);
289 }
290 RegCloseKey(hSubKey);
291 }
292 i++;
293 }while(EventLabels[i].LabelName);
294
295 RegCloseKey(hKey);
296 }
297
298
299 VOID
300 InstallSystemSoundScheme()
301 {
302 HKEY hKey, hSubKey;
303 DWORD dwDisposition;
304
305 if (RegCreateKeyExW(HKEY_CURRENT_USER, L"AppEvents", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL) != ERROR_SUCCESS)
306 return;
307
308 if (RegCreateKeyExW(hKey, L"EventLabels", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hSubKey, NULL) == ERROR_SUCCESS)
309 {
310 InstallSystemSoundLabels(hSubKey);
311 RegCloseKey(hSubKey);
312 }
313
314 if (RegCreateKeyExW(hKey, L"Schemes", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hSubKey, &dwDisposition) == ERROR_SUCCESS)
315 {
316 HKEY hNames;
317
318 if (RegCreateKeyExW(hSubKey, L"Names", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hNames, NULL) == ERROR_SUCCESS)
319 {
320 InstallSystemSoundSchemeNames(hNames);
321 RegCloseKey(hNames);
322 }
323
324 if (RegCreateKeyExW(hSubKey, L"Apps", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hNames, NULL) == ERROR_SUCCESS)
325 {
326 InstallDefaultSystemSoundScheme(hNames);
327 RegCloseKey(hNames);
328 if (dwDisposition & REG_CREATED_NEW_KEY)
329 {
330 // FIXME
331 RegSetValueExW(hSubKey, NULL, 0, REG_SZ, (LPBYTE)L".Default", (wcslen(L".Default")+1) * sizeof(WCHAR));
332 }
333 }
334
335 RegCloseKey(hSubKey);
336 }
337
338 RegCloseKey(hKey);
339 }
340
341 BOOL
342 IsSoftwareBusPnpEnumeratorInstalled()
343 {
344 HDEVINFO hDevInfo;
345 SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;
346 GUID SWBusGuid = {STATIC_BUSID_SoftwareDeviceEnumerator};
347 PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData;
348
349 hDevInfo = SetupDiGetClassDevsW(&SWBusGuid, NULL, NULL, DIGCF_DEVICEINTERFACE| DIGCF_PRESENT);
350 if (!hDevInfo)
351 {
352 // failed
353 return FALSE;
354 }
355
356 DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
357 if (!SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &SWBusGuid, 0, &DeviceInterfaceData))
358 {
359 // failed
360 SetupDiDestroyDeviceInfoList(hDevInfo);
361 return FALSE;
362 }
363
364 DeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA_W)HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR) + sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W));
365 if (!DeviceInterfaceDetailData)
366 {
367 // failed
368 SetupDiDestroyDeviceInfoList(hDevInfo);
369 return FALSE;
370 }
371
372 DeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W);
373 if (!SetupDiGetDeviceInterfaceDetailW(hDevInfo, &DeviceInterfaceData, DeviceInterfaceDetailData,MAX_PATH * sizeof(WCHAR) + sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W), NULL, NULL))
374 {
375 // failed
376 HeapFree(GetProcessHeap(), 0, DeviceInterfaceDetailData);
377 SetupDiDestroyDeviceInfoList(hDevInfo);
378 return FALSE;
379 }
380 HeapFree(GetProcessHeap(), 0, DeviceInterfaceDetailData);
381 SetupDiDestroyDeviceInfoList(hDevInfo);
382 return TRUE;
383 }
384
385 DWORD
386 InstallSoftwareBusPnpEnumerator(LPWSTR InfPath, LPCWSTR HardwareIdList)
387 {
388 HDEVINFO DeviceInfoSet = INVALID_HANDLE_VALUE;
389 SP_DEVINFO_DATA DeviceInfoData;
390 GUID ClassGUID;
391 TCHAR ClassName[50];
392 int Result = 0;
393 HMODULE hModule = NULL;
394 UpdateDriverForPlugAndPlayDevicesProto UpdateProc;
395 BOOL reboot = FALSE;
396 DWORD flags = 0;
397
398 if (!SetupDiGetINFClass(InfPath,&ClassGUID,ClassName,sizeof(ClassName)/sizeof(ClassName[0]),0))
399 {
400 return -1;
401 }
402
403 DeviceInfoSet = SetupDiCreateDeviceInfoList(&ClassGUID,0);
404 if(DeviceInfoSet == INVALID_HANDLE_VALUE)
405 {
406 return -1;
407 }
408
409 DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
410 if (!SetupDiCreateDeviceInfo(DeviceInfoSet, ClassName, &ClassGUID, NULL, 0, DICD_GENERATE_ID, &DeviceInfoData))
411 {
412 SetupDiDestroyDeviceInfoList(DeviceInfoSet);
413 return -1;
414 }
415
416 if(!SetupDiSetDeviceRegistryProperty(DeviceInfoSet, &DeviceInfoData, SPDRP_HARDWAREID, (LPBYTE)HardwareIdList, (lstrlen(HardwareIdList)+1+1)*sizeof(TCHAR)))
417 {
418 SetupDiDestroyDeviceInfoList(DeviceInfoSet);
419 return -1;
420 }
421
422 if (!SetupDiCallClassInstaller(DIF_REGISTERDEVICE, DeviceInfoSet, &DeviceInfoData))
423 {
424 SetupDiDestroyDeviceInfoList(DeviceInfoSet);
425 return -1;
426 }
427
428 if(GetFileAttributes(InfPath)==(DWORD)(-1)) {
429 SetupDiDestroyDeviceInfoList(DeviceInfoSet);
430 return -1;
431 }
432
433 flags |= INSTALLFLAG_FORCE;
434 hModule = LoadLibraryW(L"newdev.dll");
435 if(!hModule) {
436 SetupDiDestroyDeviceInfoList(DeviceInfoSet);
437 return -1;
438 }
439
440 UpdateProc = (UpdateDriverForPlugAndPlayDevicesProto)GetProcAddress(hModule,UPDATEDRIVERFORPLUGANDPLAYDEVICES);
441 if(!UpdateProc)
442 {
443 SetupDiDestroyDeviceInfoList(DeviceInfoSet);
444 FreeLibrary(hModule);
445 return -1;
446 }
447
448 if(!UpdateProc(NULL, HardwareIdList, InfPath, flags, &reboot))
449 {
450 SetupDiDestroyDeviceInfoList(DeviceInfoSet);
451 FreeLibrary(hModule);
452 return -1;
453 }
454
455 FreeLibrary(hModule);
456 SetupDiDestroyDeviceInfoList(DeviceInfoSet);
457 return Result;
458 }
459
460 DWORD
461 MMSYS_InstallDevice(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pspDevInfoData)
462 {
463 UINT Length;
464 LPWSTR pBuffer;
465 WCHAR szBuffer[MAX_PATH];
466 HINF hInf;
467 PVOID Context;
468 BOOL Result;
469 SC_HANDLE hSCManager, hService;
470 WCHAR WaveName[20];
471 HKEY hKey;
472 DWORD BufferSize;
473 ULONG Index;
474
475 if (!IsEqualIID(&pspDevInfoData->ClassGuid, &GUID_DEVCLASS_SOUND) &&
476 !IsEqualIID(&pspDevInfoData->ClassGuid, &GUID_DEVCLASS_MEDIA))
477 return ERROR_DI_DO_DEFAULT;
478
479 Length = GetWindowsDirectoryW(szBuffer, MAX_PATH);
480 if (!Length || Length >= MAX_PATH - 14)
481 {
482 return ERROR_GEN_FAILURE;
483 }
484
485 pBuffer = PathAddBackslashW(szBuffer);
486 if (!pBuffer)
487 {
488 return ERROR_GEN_FAILURE;
489 }
490
491 wcscpy(pBuffer, L"inf\\audio.inf");
492
493 hInf = SetupOpenInfFileW(szBuffer,
494 NULL,
495 INF_STYLE_WIN4,
496 NULL);
497
498 if (hInf == INVALID_HANDLE_VALUE)
499 {
500 return ERROR_GEN_FAILURE;
501 }
502
503 Context = SetupInitDefaultQueueCallback(NULL);
504 if (Context == NULL)
505 {
506 SetupCloseInfFile(hInf);
507 return ERROR_GEN_FAILURE;
508 }
509
510 Result = SetupInstallFromInfSectionW(NULL,
511 hInf,
512 L"AUDIO_Inst.NT",
513 SPINST_ALL,
514 NULL,
515 NULL,
516 SP_COPY_NEWER,
517 SetupDefaultQueueCallbackW,
518 Context,
519 NULL,
520 NULL);
521
522 if (Result)
523 {
524 Result = SetupInstallServicesFromInfSectionW(hInf,
525 L"Audio_Inst.NT.Services",
526 0);
527 }
528
529 SetupTermDefaultQueueCallback(Context);
530 SetupCloseInfFile(hInf);
531
532 if (!IsSoftwareBusPnpEnumeratorInstalled())
533 {
534 Length = GetWindowsDirectoryW(szBuffer, MAX_PATH);
535 if (!Length || Length >= MAX_PATH - 14)
536 {
537 return ERROR_GEN_FAILURE;
538 }
539
540 pBuffer = PathAddBackslashW(szBuffer);
541 if (!pBuffer)
542 {
543 return ERROR_GEN_FAILURE;
544 }
545
546 wcscpy(pBuffer, L"inf\\machine.inf");
547 InstallSoftwareBusPnpEnumerator(szBuffer, L"ROOT\\SWENUM\0");
548 }
549
550 hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
551 if (!hSCManager)
552 {
553 return ERROR_DI_DO_DEFAULT;
554 }
555
556 hService = OpenService(hSCManager, L"RosAudioSrv", SERVICE_ALL_ACCESS);
557 if (hService)
558 {
559 /* Make RosAudioSrv start automatically */
560 ChangeServiceConfig(hService, SERVICE_NO_CHANGE, SERVICE_AUTO_START, SERVICE_NO_CHANGE, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
561
562 StartService(hService, 0, NULL);
563 CloseServiceHandle(hService);
564 }
565 CloseServiceHandle(hSCManager);
566
567 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Drivers32", 0, GENERIC_READ | GENERIC_WRITE, &hKey) == ERROR_SUCCESS)
568 {
569 szBuffer[Length] = '\0';
570 pBuffer = PathAddBackslashW(szBuffer);
571 wcscpy(pBuffer, L"system32\\wdmaud.drv");
572
573 for(Index = 1; Index <= 4; Index++)
574 {
575 swprintf(WaveName, L"wave%u", Index);
576 if (RegQueryValueExW(hKey, WaveName, 0, NULL, NULL, &BufferSize) != ERROR_MORE_DATA)
577 {
578 /* Store new audio driver entry */
579 RegSetValueExW(hKey, WaveName, 0, REG_SZ, (LPBYTE)szBuffer, (wcslen(szBuffer)+1) * sizeof(WCHAR));
580 break;
581 }
582 else
583 {
584 WCHAR Buffer[MAX_PATH];
585 BufferSize = sizeof(Buffer);
586
587 if (RegQueryValueExW(hKey, WaveName, 0, NULL, (LPBYTE)Buffer, &BufferSize) == ERROR_SUCCESS)
588 {
589 /* Make sure the buffer is zero terminated */
590 Buffer[MAX_PATH-1] = L'\0';
591
592 if (!wcsicmp(Buffer, szBuffer))
593 {
594 /* An entry already exists */
595 break;
596 }
597 }
598 }
599 }
600 RegCloseKey(hKey);
601 }
602 InstallSystemSoundScheme();
603
604 return ERROR_DI_DO_DEFAULT;
605
606 }
607
608 DWORD
609 MMSYS_RemoveDevice(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pspDevInfoData)
610 {
611 return ERROR_DI_DO_DEFAULT;
612 }
613
614 DWORD
615 MMSYS_AllowInstallDevice(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pspDevInfoData)
616 {
617 return ERROR_DI_DO_DEFAULT;
618 }
619
620 DWORD
621 MMSYS_SelectDevice(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pspDevInfoData)
622 {
623 return ERROR_DI_DO_DEFAULT;
624 }
625
626 DWORD
627 MMSYS_DetectDevice(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pspDevInfoData)
628 {
629 return ERROR_DI_DO_DEFAULT;
630 }
631
632 DWORD
633 MMSYS_SelectBestCompatDRV(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pspDevInfoData)
634 {
635 return ERROR_DI_DO_DEFAULT;
636 }
637
638 DWORD WINAPI
639 MediaClassInstaller(IN DI_FUNCTION diFunction,
640 IN HDEVINFO hDevInfo,
641 IN PSP_DEVINFO_DATA pspDevInfoData OPTIONAL)
642 {
643 switch (diFunction)
644 {
645 case DIF_INSTALLDEVICE:
646 return MMSYS_InstallDevice(hDevInfo, pspDevInfoData);
647 case DIF_REMOVE:
648 return MMSYS_RemoveDevice(hDevInfo, pspDevInfoData);
649 case DIF_ALLOW_INSTALL:
650 return MMSYS_AllowInstallDevice(hDevInfo, pspDevInfoData);
651 case DIF_SELECTDEVICE:
652 return MMSYS_SelectDevice(hDevInfo, pspDevInfoData);
653 case DIF_DETECT:
654 return MMSYS_DetectDevice(hDevInfo, pspDevInfoData);
655 case DIF_SELECTBESTCOMPATDRV:
656 return MMSYS_SelectBestCompatDRV(hDevInfo, pspDevInfoData);
657 default:
658 return ERROR_DI_DO_DEFAULT;
659 }
660 }
661
662
663 /* Hardware property page dialog callback */
664 static INT_PTR CALLBACK
665 HardwareDlgProc(HWND hwndDlg,
666 UINT uMsg,
667 WPARAM wParam,
668 LPARAM lParam)
669 {
670 UNREFERENCED_PARAMETER(lParam);
671 UNREFERENCED_PARAMETER(wParam);
672 switch(uMsg)
673 {
674 case WM_INITDIALOG:
675 {
676 GUID Guids[2];
677 Guids[0] = GUID_DEVCLASS_CDROM;
678 Guids[1] = GUID_DEVCLASS_MEDIA;
679
680 /* Create the hardware page */
681 DeviceCreateHardwarePageEx(hwndDlg,
682 Guids,
683 sizeof(Guids) / sizeof(Guids[0]),
684 HWPD_LARGELIST);
685 break;
686 }
687 }
688
689 return FALSE;
690 }
691
692 LONG APIENTRY
693 MmSysApplet(HWND hwnd,
694 UINT uMsg,
695 LPARAM wParam,
696 LPARAM lParam)
697 {
698 PROPSHEETPAGE psp[5];
699 PROPSHEETHEADER psh; // = { 0 };
700 TCHAR Caption[256];
701
702 UNREFERENCED_PARAMETER(lParam);
703 UNREFERENCED_PARAMETER(wParam);
704 UNREFERENCED_PARAMETER(uMsg);
705
706 LoadString(hApplet, IDS_CPLNAME, Caption, _countof(Caption));
707
708 psh.dwSize = sizeof(PROPSHEETHEADER);
709 psh.dwFlags = PSH_PROPSHEETPAGE | PSH_PROPTITLE;
710 psh.hwndParent = hwnd;
711 psh.hInstance = hApplet;
712 psh.hIcon = LoadIcon(hApplet,
713 MAKEINTRESOURCE(IDI_CPLICON));
714 psh.pszCaption = Caption;
715 psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE);
716 psh.nStartPage = 0;
717 psh.ppsp = psp;
718
719 InitPropSheetPage(&psp[0], IDD_VOLUME,VolumeDlgProc);
720 InitPropSheetPage(&psp[1], IDD_SOUNDS,SoundsDlgProc);
721 InitPropSheetPage(&psp[2], IDD_AUDIO,AudioDlgProc);
722 InitPropSheetPage(&psp[3], IDD_VOICE,VoiceDlgProc);
723 InitPropSheetPage(&psp[4], IDD_HARDWARE,HardwareDlgProc);
724
725 return (LONG)(PropertySheet(&psh) != -1);
726 }
727
728 VOID
729 InitPropSheetPage(PROPSHEETPAGE *psp,
730 WORD idDlg,
731 DLGPROC DlgProc)
732 {
733 ZeroMemory(psp, sizeof(PROPSHEETPAGE));
734 psp->dwSize = sizeof(PROPSHEETPAGE);
735 psp->dwFlags = PSP_DEFAULT;
736 psp->hInstance = hApplet;
737 psp->pszTemplate = MAKEINTRESOURCE(idDlg);
738 psp->pfnDlgProc = DlgProc;
739 }
740
741
742 /* Control Panel Callback */
743 LONG CALLBACK
744 CPlApplet(HWND hwndCpl,
745 UINT uMsg,
746 LPARAM lParam1,
747 LPARAM lParam2)
748 {
749 switch(uMsg)
750 {
751 case CPL_INIT:
752 return TRUE;
753
754 case CPL_GETCOUNT:
755 return NUM_APPLETS;
756
757 case CPL_INQUIRE:
758 {
759 CPLINFO *CPlInfo = (CPLINFO*)lParam2;
760 UINT uAppIndex = (UINT)lParam1;
761
762 CPlInfo->lData = 0;
763 CPlInfo->idIcon = Applets[uAppIndex].idIcon;
764 CPlInfo->idName = Applets[uAppIndex].idName;
765 CPlInfo->idInfo = Applets[uAppIndex].idDescription;
766 break;
767 }
768
769 case CPL_DBLCLK:
770 {
771 UINT uAppIndex = (UINT)lParam1;
772 Applets[uAppIndex].AppletProc(hwndCpl,
773 uMsg,
774 lParam1,
775 lParam2);
776 break;
777 }
778 }
779
780 return FALSE;
781 }
782
783
784 BOOL WINAPI
785 DllMain(HINSTANCE hinstDLL,
786 DWORD dwReason,
787 LPVOID lpReserved)
788 {
789 UNREFERENCED_PARAMETER(lpReserved);
790 switch(dwReason)
791 {
792 case DLL_PROCESS_ATTACH:
793 hApplet = hinstDLL;
794 DisableThreadLibraryCalls(hinstDLL);
795 break;
796 }
797
798 return TRUE;
799 }