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 } 800