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 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 swprintf(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 swprintf(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 swprintf(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() 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", (wcslen(L".Default")+1) * sizeof(WCHAR)); 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 TCHAR ClassName[50]; 374 int Result = 0; 375 HMODULE hModule = NULL; 376 UpdateDriverForPlugAndPlayDevicesProto UpdateProc; 377 BOOL reboot = FALSE; 378 DWORD flags = 0; 379 380 if (!SetupDiGetINFClass(InfPath,&ClassGUID,ClassName,sizeof(ClassName)/sizeof(ClassName[0]),0)) 381 { 382 return -1; 383 } 384 385 DeviceInfoSet = SetupDiCreateDeviceInfoList(&ClassGUID,0); 386 if(DeviceInfoSet == INVALID_HANDLE_VALUE) 387 { 388 return -1; 389 } 390 391 DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); 392 if (!SetupDiCreateDeviceInfo(DeviceInfoSet, ClassName, &ClassGUID, NULL, 0, DICD_GENERATE_ID, &DeviceInfoData)) 393 { 394 SetupDiDestroyDeviceInfoList(DeviceInfoSet); 395 return -1; 396 } 397 398 if(!SetupDiSetDeviceRegistryProperty(DeviceInfoSet, &DeviceInfoData, SPDRP_HARDWAREID, (LPBYTE)HardwareIdList, (lstrlen(HardwareIdList)+1+1)*sizeof(TCHAR))) 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(GetFileAttributes(InfPath)==(DWORD)(-1)) { 411 SetupDiDestroyDeviceInfoList(DeviceInfoSet); 412 return -1; 413 } 414 415 flags |= INSTALLFLAG_FORCE; 416 hModule = LoadLibraryW(L"newdev.dll"); 417 if(!hModule) { 418 SetupDiDestroyDeviceInfoList(DeviceInfoSet); 419 return -1; 420 } 421 422 UpdateProc = (UpdateDriverForPlugAndPlayDevicesProto)GetProcAddress(hModule,UPDATEDRIVERFORPLUGANDPLAYDEVICES); 423 if(!UpdateProc) 424 { 425 SetupDiDestroyDeviceInfoList(DeviceInfoSet); 426 FreeLibrary(hModule); 427 return -1; 428 } 429 430 if(!UpdateProc(NULL, HardwareIdList, InfPath, flags, &reboot)) 431 { 432 SetupDiDestroyDeviceInfoList(DeviceInfoSet); 433 FreeLibrary(hModule); 434 return -1; 435 } 436 437 FreeLibrary(hModule); 438 SetupDiDestroyDeviceInfoList(DeviceInfoSet); 439 return Result; 440 } 441 442 DWORD 443 MMSYS_InstallDevice(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pspDevInfoData) 444 { 445 UINT Length; 446 LPWSTR pBuffer; 447 WCHAR szBuffer[MAX_PATH]; 448 HINF hInf; 449 PVOID Context; 450 BOOL Result; 451 SC_HANDLE hSCManager, hService; 452 WCHAR WaveName[20]; 453 HKEY hKey; 454 DWORD BufferSize; 455 ULONG Index; 456 457 if (!IsEqualIID(&pspDevInfoData->ClassGuid, &GUID_DEVCLASS_SOUND) && 458 !IsEqualIID(&pspDevInfoData->ClassGuid, &GUID_DEVCLASS_MEDIA)) 459 return ERROR_DI_DO_DEFAULT; 460 461 Length = GetWindowsDirectoryW(szBuffer, MAX_PATH); 462 if (!Length || Length >= MAX_PATH - 14) 463 { 464 return ERROR_GEN_FAILURE; 465 } 466 467 pBuffer = PathAddBackslashW(szBuffer); 468 if (!pBuffer) 469 { 470 return ERROR_GEN_FAILURE; 471 } 472 473 wcscpy(pBuffer, L"inf\\audio.inf"); 474 475 hInf = SetupOpenInfFileW(szBuffer, 476 NULL, 477 INF_STYLE_WIN4, 478 NULL); 479 480 if (hInf == INVALID_HANDLE_VALUE) 481 { 482 return ERROR_GEN_FAILURE; 483 } 484 485 Context = SetupInitDefaultQueueCallback(NULL); 486 if (Context == NULL) 487 { 488 SetupCloseInfFile(hInf); 489 return ERROR_GEN_FAILURE; 490 } 491 492 Result = SetupInstallFromInfSectionW(NULL, 493 hInf, 494 L"AUDIO_Inst.NT", 495 SPINST_ALL, 496 NULL, 497 NULL, 498 SP_COPY_NEWER, 499 SetupDefaultQueueCallbackW, 500 Context, 501 NULL, 502 NULL); 503 504 if (Result) 505 { 506 Result = SetupInstallServicesFromInfSectionW(hInf, 507 L"Audio_Inst.NT.Services", 508 0); 509 } 510 511 SetupTermDefaultQueueCallback(Context); 512 SetupCloseInfFile(hInf); 513 514 if (!IsSoftwareBusPnpEnumeratorInstalled()) 515 { 516 Length = GetWindowsDirectoryW(szBuffer, MAX_PATH); 517 if (!Length || Length >= MAX_PATH - 14) 518 { 519 return ERROR_GEN_FAILURE; 520 } 521 522 pBuffer = PathAddBackslashW(szBuffer); 523 if (!pBuffer) 524 { 525 return ERROR_GEN_FAILURE; 526 } 527 528 wcscpy(pBuffer, L"inf\\machine.inf"); 529 InstallSoftwareBusPnpEnumerator(szBuffer, L"ROOT\\SWENUM\0"); 530 } 531 532 hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); 533 if (!hSCManager) 534 { 535 return ERROR_DI_DO_DEFAULT; 536 } 537 538 hService = OpenService(hSCManager, L"AudioSrv", SERVICE_ALL_ACCESS); 539 if (hService) 540 { 541 /* Make AudioSrv start automatically */ 542 ChangeServiceConfig(hService, SERVICE_NO_CHANGE, SERVICE_AUTO_START, SERVICE_NO_CHANGE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); 543 544 StartService(hService, 0, NULL); 545 CloseServiceHandle(hService); 546 } 547 CloseServiceHandle(hSCManager); 548 549 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Drivers32", 0, GENERIC_READ | GENERIC_WRITE, &hKey) == ERROR_SUCCESS) 550 { 551 szBuffer[Length] = '\0'; 552 pBuffer = PathAddBackslashW(szBuffer); 553 wcscpy(pBuffer, L"system32\\wdmaud.drv"); 554 555 for(Index = 1; Index <= 4; Index++) 556 { 557 swprintf(WaveName, L"wave%u", Index); 558 if (RegQueryValueExW(hKey, WaveName, 0, NULL, NULL, &BufferSize) != ERROR_MORE_DATA) 559 { 560 /* Store new audio driver entry */ 561 RegSetValueExW(hKey, WaveName, 0, REG_SZ, (LPBYTE)szBuffer, (wcslen(szBuffer)+1) * sizeof(WCHAR)); 562 break; 563 } 564 else 565 { 566 WCHAR Buffer[MAX_PATH]; 567 BufferSize = sizeof(Buffer); 568 569 if (RegQueryValueExW(hKey, WaveName, 0, NULL, (LPBYTE)Buffer, &BufferSize) == ERROR_SUCCESS) 570 { 571 /* Make sure the buffer is zero terminated */ 572 Buffer[MAX_PATH-1] = L'\0'; 573 574 if (!wcsicmp(Buffer, szBuffer)) 575 { 576 /* An entry already exists */ 577 break; 578 } 579 } 580 } 581 } 582 RegCloseKey(hKey); 583 } 584 InstallSystemSoundScheme(); 585 586 return ERROR_DI_DO_DEFAULT; 587 588 } 589 590 DWORD 591 MMSYS_RemoveDevice(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pspDevInfoData) 592 { 593 return ERROR_DI_DO_DEFAULT; 594 } 595 596 DWORD 597 MMSYS_AllowInstallDevice(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pspDevInfoData) 598 { 599 return ERROR_DI_DO_DEFAULT; 600 } 601 602 DWORD 603 MMSYS_SelectDevice(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pspDevInfoData) 604 { 605 return ERROR_DI_DO_DEFAULT; 606 } 607 608 DWORD 609 MMSYS_DetectDevice(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pspDevInfoData) 610 { 611 return ERROR_DI_DO_DEFAULT; 612 } 613 614 DWORD 615 MMSYS_SelectBestCompatDRV(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pspDevInfoData) 616 { 617 return ERROR_DI_DO_DEFAULT; 618 } 619 620 DWORD WINAPI 621 MediaClassInstaller(IN DI_FUNCTION diFunction, 622 IN HDEVINFO hDevInfo, 623 IN PSP_DEVINFO_DATA pspDevInfoData OPTIONAL) 624 { 625 switch (diFunction) 626 { 627 case DIF_INSTALLDEVICE: 628 return MMSYS_InstallDevice(hDevInfo, pspDevInfoData); 629 case DIF_REMOVE: 630 return MMSYS_RemoveDevice(hDevInfo, pspDevInfoData); 631 case DIF_ALLOW_INSTALL: 632 return MMSYS_AllowInstallDevice(hDevInfo, pspDevInfoData); 633 case DIF_SELECTDEVICE: 634 return MMSYS_SelectDevice(hDevInfo, pspDevInfoData); 635 case DIF_DETECT: 636 return MMSYS_DetectDevice(hDevInfo, pspDevInfoData); 637 case DIF_SELECTBESTCOMPATDRV: 638 return MMSYS_SelectBestCompatDRV(hDevInfo, pspDevInfoData); 639 default: 640 return ERROR_DI_DO_DEFAULT; 641 } 642 } 643 644 645 /* Hardware property page dialog callback */ 646 static INT_PTR CALLBACK 647 HardwareDlgProc(HWND hwndDlg, 648 UINT uMsg, 649 WPARAM wParam, 650 LPARAM lParam) 651 { 652 UNREFERENCED_PARAMETER(lParam); 653 UNREFERENCED_PARAMETER(wParam); 654 switch(uMsg) 655 { 656 case WM_INITDIALOG: 657 { 658 GUID Guids[2]; 659 Guids[0] = GUID_DEVCLASS_CDROM; 660 Guids[1] = GUID_DEVCLASS_MEDIA; 661 662 /* Create the hardware page */ 663 DeviceCreateHardwarePageEx(hwndDlg, 664 Guids, 665 sizeof(Guids) / sizeof(Guids[0]), 666 HWPD_LARGELIST); 667 break; 668 } 669 } 670 671 return FALSE; 672 } 673 674 static int CALLBACK 675 PropSheetProc(HWND hwndDlg, UINT uMsg, LPARAM lParam) 676 { 677 // NOTE: This callback is needed to set large icon correctly. 678 HICON hIcon; 679 switch (uMsg) 680 { 681 case PSCB_INITIALIZED: 682 { 683 hIcon = LoadIconW(hApplet, MAKEINTRESOURCEW(IDI_CPLICON)); 684 SendMessageW(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon); 685 break; 686 } 687 } 688 return 0; 689 } 690 691 LONG APIENTRY 692 MmSysApplet(HWND hwnd, 693 UINT uMsg, 694 LPARAM wParam, 695 LPARAM lParam) 696 { 697 PROPSHEETPAGE psp[5]; 698 PROPSHEETHEADER psh; // = { 0 }; 699 TCHAR Caption[256]; 700 INT nPage = 0; 701 702 UNREFERENCED_PARAMETER(lParam); 703 UNREFERENCED_PARAMETER(wParam); 704 UNREFERENCED_PARAMETER(uMsg); 705 706 if (uMsg == CPL_STARTWPARMSW && lParam != 0) 707 nPage = _wtoi((PWSTR)lParam); 708 709 LoadString(hApplet, IDS_CPLNAME, Caption, _countof(Caption)); 710 711 psh.dwSize = sizeof(PROPSHEETHEADER); 712 psh.dwFlags = PSH_PROPSHEETPAGE | PSH_PROPTITLE | PSH_USEICONID | PSH_USECALLBACK; 713 psh.hwndParent = hwnd; 714 psh.hInstance = hApplet; 715 psh.pszIcon = MAKEINTRESOURCEW(IDI_CPLICON); 716 psh.pszCaption = Caption; 717 psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE); 718 psh.nStartPage = 0; 719 psh.ppsp = psp; 720 psh.pfnCallback = PropSheetProc; 721 722 InitPropSheetPage(&psp[0], IDD_VOLUME,VolumeDlgProc); 723 InitPropSheetPage(&psp[1], IDD_SOUNDS,SoundsDlgProc); 724 InitPropSheetPage(&psp[2], IDD_AUDIO,AudioDlgProc); 725 InitPropSheetPage(&psp[3], IDD_VOICE,VoiceDlgProc); 726 InitPropSheetPage(&psp[4], IDD_HARDWARE,HardwareDlgProc); 727 728 if (nPage != 0 && nPage <= psh.nPages) 729 psh.nStartPage = nPage; 730 731 return (LONG)(PropertySheet(&psh) != -1); 732 } 733 734 VOID 735 InitPropSheetPage(PROPSHEETPAGE *psp, 736 WORD idDlg, 737 DLGPROC DlgProc) 738 { 739 ZeroMemory(psp, sizeof(PROPSHEETPAGE)); 740 psp->dwSize = sizeof(PROPSHEETPAGE); 741 psp->dwFlags = PSP_DEFAULT; 742 psp->hInstance = hApplet; 743 psp->pszTemplate = MAKEINTRESOURCE(idDlg); 744 psp->pfnDlgProc = DlgProc; 745 } 746 747 748 /* Control Panel Callback */ 749 LONG CALLBACK 750 CPlApplet(HWND hwndCpl, 751 UINT uMsg, 752 LPARAM lParam1, 753 LPARAM lParam2) 754 { 755 switch(uMsg) 756 { 757 case CPL_INIT: 758 return TRUE; 759 760 case CPL_GETCOUNT: 761 return NUM_APPLETS; 762 763 case CPL_INQUIRE: 764 { 765 CPLINFO *CPlInfo = (CPLINFO*)lParam2; 766 UINT uAppIndex = (UINT)lParam1; 767 768 CPlInfo->lData = 0; 769 CPlInfo->idIcon = Applets[uAppIndex].idIcon; 770 CPlInfo->idName = Applets[uAppIndex].idName; 771 CPlInfo->idInfo = Applets[uAppIndex].idDescription; 772 break; 773 } 774 775 case CPL_DBLCLK: 776 { 777 UINT uAppIndex = (UINT)lParam1; 778 Applets[uAppIndex].AppletProc(hwndCpl, 779 uMsg, 780 lParam1, 781 lParam2); 782 break; 783 } 784 785 case CPL_STARTWPARMSW: 786 return Applets[(UINT)lParam1].AppletProc(hwndCpl, uMsg, lParam1, lParam2); 787 } 788 789 return FALSE; 790 } 791 792 VOID WINAPI 793 ShowAudioPropertySheet(HWND hwnd, 794 HINSTANCE hInstance, 795 LPTSTR lpszCmd, 796 int nCmdShow) 797 { 798 PROPSHEETPAGE psp[1]; 799 PROPSHEETHEADER psh; 800 TCHAR Caption[256]; 801 802 DPRINT("ShowAudioPropertySheet()\n"); 803 804 LoadString(hApplet, IDS_CPLNAME, Caption, _countof(Caption)); 805 806 psh.dwSize = sizeof(PROPSHEETHEADER); 807 psh.dwFlags = PSH_PROPSHEETPAGE | PSH_PROPTITLE | PSH_USEICONID | PSH_USECALLBACK; 808 psh.hwndParent = hwnd; 809 psh.hInstance = hInstance; 810 psh.pszIcon = MAKEINTRESOURCEW(IDI_CPLICON); 811 psh.pszCaption = Caption; 812 psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE); 813 psh.nStartPage = 0; 814 psh.ppsp = psp; 815 psh.pfnCallback = PropSheetProc; 816 817 InitPropSheetPage(&psp[0], IDD_AUDIO,AudioDlgProc); 818 819 PropertySheet(&psh); 820 } 821 822 VOID WINAPI 823 ShowFullControlPanel(HWND hwnd, 824 HINSTANCE hInstance, 825 LPSTR lpszCmd, 826 int nCmdShow) 827 { 828 PROPSHEETPAGE psp[5]; 829 PROPSHEETHEADER psh; 830 TCHAR Caption[256]; 831 832 DPRINT("ShowFullControlPanel()\n"); 833 834 LoadString(hApplet, IDS_CPLNAME, Caption, _countof(Caption)); 835 836 psh.dwSize = sizeof(PROPSHEETHEADER); 837 psh.dwFlags = PSH_PROPSHEETPAGE | PSH_PROPTITLE | PSH_USEICONID | PSH_USECALLBACK; 838 psh.hwndParent = hwnd; 839 psh.hInstance = hInstance; 840 psh.pszIcon = MAKEINTRESOURCEW(IDI_CPLICON); 841 psh.pszCaption = Caption; 842 psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE); 843 psh.nStartPage = 0; 844 psh.ppsp = psp; 845 psh.pfnCallback = PropSheetProc; 846 847 InitPropSheetPage(&psp[0], IDD_VOLUME,VolumeDlgProc); 848 InitPropSheetPage(&psp[1], IDD_SOUNDS,SoundsDlgProc); 849 InitPropSheetPage(&psp[2], IDD_AUDIO,AudioDlgProc); 850 InitPropSheetPage(&psp[3], IDD_VOICE,VoiceDlgProc); 851 InitPropSheetPage(&psp[4], IDD_HARDWARE,HardwareDlgProc); 852 853 PropertySheet(&psh); 854 } 855 856 BOOL WINAPI 857 DllMain(HINSTANCE hinstDLL, 858 DWORD dwReason, 859 LPVOID lpReserved) 860 { 861 UNREFERENCED_PARAMETER(lpReserved); 862 switch(dwReason) 863 { 864 case DLL_PROCESS_ATTACH: 865 hApplet = hinstDLL; 866 DisableThreadLibraryCalls(hinstDLL); 867 break; 868 } 869 870 return TRUE; 871 } 872