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 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 mmseRunOnceW(HWND hwnd, 168 HINSTANCE hInstance, 169 LPWSTR lpszCmd, 170 int nCmdShow) 171 { 172 DPRINT1("mmseRunOnceW() stubs\n"); 173 } 174 175 VOID WINAPI 176 mmseRunOnceA(HWND hwnd, 177 HINSTANCE hInstance, 178 LPSTR lpszCmd, 179 int nCmdShow) 180 { 181 DPRINT1("mmseRunOnceA() stubs\n"); 182 } 183 184 VOID WINAPI 185 mmseRunOnce(HWND hwnd, 186 HINSTANCE hInstance, 187 LPSTR lpszCmd, 188 int nCmdShow) 189 { 190 DPRINT1("mmseRunOnce() stubs\n"); 191 } 192 193 BOOL WINAPI 194 MediaPropPageProvider(LPVOID Info, 195 LPFNADDPROPSHEETPAGE PropSheetPage, 196 LPARAM lParam) 197 { 198 DPRINT1("MediaPropPageProvider() stubs\n"); 199 return TRUE; 200 } 201 202 VOID 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 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 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 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 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 368 InstallSoftwareBusPnpEnumerator(LPWSTR 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 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 589 MMSYS_RemoveDevice(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pspDevInfoData) 590 { 591 return ERROR_DI_DO_DEFAULT; 592 } 593 594 DWORD 595 MMSYS_AllowInstallDevice(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pspDevInfoData) 596 { 597 return ERROR_DI_DO_DEFAULT; 598 } 599 600 DWORD 601 MMSYS_SelectDevice(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pspDevInfoData) 602 { 603 return ERROR_DI_DO_DEFAULT; 604 } 605 606 DWORD 607 MMSYS_DetectDevice(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pspDevInfoData) 608 { 609 return ERROR_DI_DO_DEFAULT; 610 } 611 612 DWORD 613 MMSYS_SelectBestCompatDRV(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pspDevInfoData) 614 { 615 return ERROR_DI_DO_DEFAULT; 616 } 617 618 DWORD WINAPI 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 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 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 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 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 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 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 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 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