1 /* 2 * ReactOS New devices installation 3 * Copyright (C) 2005, 2008 ReactOS Team 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public 7 * License as published by the Free Software Foundation; either 8 * version 2.1 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public 16 * License along with this library; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 */ 19 /* 20 * PROJECT: ReactOS Add hardware control panel 21 * FILE: dll/cpl/hdwwiz/hdwwiz.c 22 * PURPOSE: ReactOS Add hardware control panel 23 * PROGRAMMER: Herv� Poussineau (hpoussin@reactos.org) 24 * Dmitry Chapyshev (dmitry@reactos.org) 25 */ 26 27 #include "resource.h" 28 #include "hdwwiz.h" 29 30 /* GLOBALS ******************************************************************/ 31 32 HINSTANCE hApplet = NULL; 33 HFONT hTitleFont; 34 SP_CLASSIMAGELIST_DATA ImageListData; 35 PWSTR pDeviceStatusText; 36 HANDLE hProcessHeap; 37 HDEVINFO hDevInfoTypes; 38 39 typedef BOOL (WINAPI *PINSTALL_NEW_DEVICE)(HWND, LPGUID, PDWORD); 40 41 42 /* STATIC FUNCTIONS *********************************************************/ 43 44 static HFONT 45 CreateTitleFont(VOID) 46 { 47 NONCLIENTMETRICS ncm; 48 LOGFONT LogFont; 49 HDC hdc; 50 INT FontSize; 51 HFONT hFont; 52 53 ncm.cbSize = sizeof(NONCLIENTMETRICS); 54 SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0); 55 56 LogFont = ncm.lfMessageFont; 57 LogFont.lfWeight = FW_BOLD; 58 wcscpy(LogFont.lfFaceName, L"MS Shell Dlg"); 59 60 hdc = GetDC(NULL); 61 FontSize = 12; 62 LogFont.lfHeight = 0 - GetDeviceCaps (hdc, LOGPIXELSY) * FontSize / 72; 63 hFont = CreateFontIndirect(&LogFont); 64 ReleaseDC(NULL, hdc); 65 66 return hFont; 67 } 68 69 static INT_PTR CALLBACK 70 StartPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 71 { 72 switch (uMsg) 73 { 74 case WM_INITDIALOG: 75 { 76 /* Set title font */ 77 SendDlgItemMessage(hwndDlg, IDC_FINISHTITLE, WM_SETFONT, (WPARAM)hTitleFont, (LPARAM)TRUE); 78 } 79 break; 80 81 case WM_NOTIFY: 82 { 83 LPNMHDR lpnm = (LPNMHDR)lParam; 84 85 switch (lpnm->code) 86 { 87 case PSN_SETACTIVE: 88 { 89 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT); 90 } 91 break; 92 } 93 } 94 break; 95 } 96 97 return FALSE; 98 } 99 100 static INT_PTR CALLBACK 101 SearchPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 102 { 103 switch (uMsg) 104 { 105 case WM_INITDIALOG: 106 { 107 /* TODO: PnP devices search */ 108 } 109 break; 110 111 case WM_NOTIFY: 112 { 113 LPNMHDR lpnm = (LPNMHDR)lParam; 114 115 switch (lpnm->code) 116 { 117 case PSN_SETACTIVE: 118 { 119 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT | PSWIZB_BACK); 120 } 121 break; 122 } 123 } 124 break; 125 } 126 127 return FALSE; 128 } 129 130 static INT_PTR CALLBACK 131 IsConnectedPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 132 { 133 switch (uMsg) 134 { 135 case WM_COMMAND: 136 { 137 if(HIWORD(wParam) == BN_CLICKED) 138 { 139 if ((SendDlgItemMessage(hwndDlg, IDC_CONNECTED, BM_GETCHECK, 0, 0) == BST_CHECKED) || 140 (SendDlgItemMessage(hwndDlg, IDC_NOTCONNECTED, BM_GETCHECK, 0, 0) == BST_CHECKED)) 141 { 142 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT | PSWIZB_BACK); 143 } 144 else 145 { 146 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK); 147 } 148 } 149 } 150 break; 151 152 case WM_NOTIFY: 153 { 154 LPNMHDR lpnm = (LPNMHDR)lParam; 155 156 switch (lpnm->code) 157 { 158 case PSN_SETACTIVE: 159 { 160 if ((SendDlgItemMessage(hwndDlg, IDC_CONNECTED, BM_GETCHECK, 0, 0) == BST_CHECKED) || 161 (SendDlgItemMessage(hwndDlg, IDC_NOTCONNECTED, BM_GETCHECK, 0, 0) == BST_CHECKED)) 162 { 163 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT | PSWIZB_BACK); 164 } 165 else 166 { 167 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK); 168 } 169 } 170 break; 171 172 case PSN_WIZNEXT: 173 { 174 if (SendDlgItemMessage(hwndDlg, IDC_NOTCONNECTED, BM_GETCHECK, 0, 0) == BST_CHECKED) 175 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_NOTCONNECTEDPAGE); 176 else 177 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_PROBELISTPAGE); 178 179 return TRUE; 180 } 181 } 182 } 183 break; 184 } 185 186 return FALSE; 187 } 188 189 static INT_PTR CALLBACK 190 FinishPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 191 { 192 switch (uMsg) 193 { 194 case WM_INITDIALOG: 195 { 196 /* Set title font */ 197 SendDlgItemMessage(hwndDlg, IDC_FINISHTITLE, WM_SETFONT, (WPARAM)hTitleFont, (LPARAM)TRUE); 198 } 199 break; 200 201 case WM_NOTIFY: 202 { 203 LPNMHDR lpnm = (LPNMHDR)lParam; 204 205 switch (lpnm->code) 206 { 207 case PSN_SETACTIVE: 208 { 209 /* Only "Finish" button */ 210 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_FINISH); 211 } 212 break; 213 } 214 } 215 break; 216 } 217 218 return FALSE; 219 } 220 221 static INT_PTR CALLBACK 222 NotConnectedPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 223 { 224 switch (uMsg) 225 { 226 case WM_INITDIALOG: 227 { 228 /* Set title font */ 229 SendDlgItemMessage(hwndDlg, IDC_FINISHTITLE, WM_SETFONT, (WPARAM)hTitleFont, (LPARAM)TRUE); 230 } 231 break; 232 233 case WM_NOTIFY: 234 { 235 LPNMHDR lpnm = (LPNMHDR)lParam; 236 237 switch (lpnm->code) 238 { 239 case PSN_SETACTIVE: 240 { 241 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_FINISH | PSWIZB_BACK); 242 } 243 break; 244 245 case PSN_WIZBACK: 246 { 247 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_ISCONNECTEDPAGE); 248 return TRUE; 249 } 250 } 251 } 252 break; 253 } 254 255 return FALSE; 256 } 257 258 static VOID 259 TrimGuidString(LPWSTR szString, LPWSTR szNewString) 260 { 261 WCHAR szBuffer[39]; 262 INT Index; 263 264 if (wcslen(szString) == 38) 265 { 266 if ((szString[0] == L'{') && (szString[37] == L'}')) 267 { 268 for (Index = 0; Index < wcslen(szString); Index++) 269 szBuffer[Index] = szString[Index + 1]; 270 271 szBuffer[36] = L'\0'; 272 wcscpy(szNewString, szBuffer); 273 return; 274 } 275 } 276 wcscpy(szNewString, L"\0"); 277 } 278 279 static VOID 280 InitProbeListPage(HWND hwndDlg) 281 { 282 LV_COLUMN Column; 283 LV_ITEM Item; 284 WCHAR szBuffer[MAX_STR_SIZE], szGuid[MAX_STR_SIZE], 285 szTrimGuid[MAX_STR_SIZE], szStatusText[MAX_STR_SIZE]; 286 HWND hList = GetDlgItem(hwndDlg, IDC_PROBELIST); 287 PWSTR pstrStatusText; 288 HDEVINFO hDevInfo; 289 SP_DEVINFO_DATA DevInfoData; 290 ULONG ulStatus, ulProblemNumber; 291 GUID ClassGuid; 292 RECT Rect; 293 DWORD Index; 294 295 if (!hList) return; 296 297 ZeroMemory(&Column, sizeof(LV_COLUMN)); 298 299 GetClientRect(hList, &Rect); 300 301 Column.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH; 302 Column.fmt = LVCFMT_LEFT; 303 Column.iSubItem = 0; 304 Column.pszText = NULL; 305 Column.cx = Rect.right - GetSystemMetrics(SM_CXVSCROLL); 306 (VOID) ListView_InsertColumn(hList, 0, &Column); 307 308 ZeroMemory(&Item, sizeof(LV_ITEM)); 309 310 LoadString(hApplet, IDS_ADDNEWDEVICE, szBuffer, sizeof(szBuffer) / sizeof(WCHAR)); 311 312 Item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE | LVIF_IMAGE; 313 Item.pszText = (LPWSTR) szBuffer; 314 Item.iItem = (INT) ListView_GetItemCount(hList); 315 Item.iImage = -1; 316 (VOID) ListView_InsertItem(hList, &Item); 317 318 hDevInfo = SetupDiGetClassDevsEx(NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT, NULL, NULL, 0); 319 320 if (hDevInfo == INVALID_HANDLE_VALUE) return; 321 322 /* Get the device image List */ 323 ImageListData.cbSize = sizeof(ImageListData); 324 SetupDiGetClassImageList(&ImageListData); 325 326 DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA); 327 for (Index = 0; TRUE; Index++) 328 { 329 szBuffer[0] = L'\0'; 330 331 if (!SetupDiEnumDeviceInfo(hDevInfo, Index, &DevInfoData)) break; 332 333 if (CM_Get_DevNode_Status_Ex(&ulStatus, &ulProblemNumber, DevInfoData.DevInst, 0, NULL) == CR_SUCCESS) 334 { 335 if (ulStatus & DN_NO_SHOW_IN_DM) continue; 336 } 337 338 /* Get the device's friendly name */ 339 if (!SetupDiGetDeviceRegistryProperty(hDevInfo, 340 &DevInfoData, 341 SPDRP_FRIENDLYNAME, 342 0, 343 (BYTE*)szBuffer, 344 MAX_STR_SIZE, 345 NULL)) 346 { 347 /* If the friendly name fails, try the description instead */ 348 SetupDiGetDeviceRegistryProperty(hDevInfo, 349 &DevInfoData, 350 SPDRP_DEVICEDESC, 351 0, 352 (BYTE*)szBuffer, 353 MAX_STR_SIZE, 354 NULL); 355 } 356 357 SetupDiGetDeviceRegistryProperty(hDevInfo, 358 &DevInfoData, 359 SPDRP_CLASSGUID, 360 0, 361 (BYTE*)szGuid, 362 MAX_STR_SIZE, 363 NULL); 364 365 TrimGuidString(szGuid, szTrimGuid); 366 UuidFromStringW(szTrimGuid, &ClassGuid); 367 368 SetupDiGetClassImageIndex(&ImageListData, 369 &ClassGuid, 370 &Item.iImage); 371 372 DeviceProblemTextW(NULL, 373 DevInfoData.DevInst, 374 ulProblemNumber, 375 szStatusText, 376 sizeof(szStatusText) / sizeof(WCHAR)); 377 378 pstrStatusText = (PWSTR)HeapAlloc(hProcessHeap, 0, sizeof(szStatusText)); 379 lstrcpy(pstrStatusText, szStatusText); 380 381 if (szBuffer[0] != L'\0') 382 { 383 /* Set device name */ 384 Item.pszText = (LPWSTR) szBuffer; 385 Item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE | LVIF_IMAGE; 386 Item.lParam = (LPARAM) pstrStatusText; 387 Item.iItem = (INT) ListView_GetItemCount(hList); 388 (VOID) ListView_InsertItem(hList, &Item); 389 } 390 391 DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA); 392 } 393 394 (VOID) ListView_SetImageList(hList, ImageListData.ImageList, LVSIL_SMALL); 395 (VOID) ListView_SetExtendedListViewStyle(hList, LVS_EX_FULLROWSELECT); 396 SetupDiDestroyDeviceInfoList(hDevInfo); 397 } 398 399 static INT_PTR CALLBACK 400 ProbeListPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 401 { 402 INT Index; 403 LVITEM Item; 404 405 switch (uMsg) 406 { 407 case WM_INITDIALOG: 408 { 409 pDeviceStatusText = (PWSTR)HeapAlloc(hProcessHeap, 0, MAX_STR_SIZE); 410 InitProbeListPage(hwndDlg); 411 } 412 break; 413 414 case WM_NOTIFY: 415 { 416 LPNMHDR lpnm = (LPNMHDR)lParam; 417 418 switch (lpnm->code) 419 { 420 case PSN_SETACTIVE: 421 { 422 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT); 423 } 424 break; 425 426 case PSN_WIZNEXT: 427 { 428 Index = (INT) SendMessage(GetDlgItem(hwndDlg, IDC_PROBELIST), LVM_GETNEXTITEM, -1, LVNI_FOCUSED); 429 if (Index == -1) Index = 0; 430 431 if (Index == 0) 432 { 433 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_SELECTWAYPAGE); 434 } 435 else 436 { 437 PWSTR pts; 438 439 ZeroMemory(&Item, sizeof(LV_ITEM)); 440 Item.mask = LVIF_PARAM; 441 Item.iItem = Index; 442 (VOID) ListView_GetItem(GetDlgItem(hwndDlg, IDC_PROBELIST), &Item); 443 pts = (PWSTR) Item.lParam; 444 wcscpy(pDeviceStatusText, pts); 445 446 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_HWSTATUSPAGE); 447 } 448 return TRUE; 449 } 450 } 451 } 452 break; 453 454 case WM_DESTROY: 455 { 456 for (Index = ListView_GetItemCount(GetDlgItem(hwndDlg, IDC_PROBELIST)); --Index > 0;) 457 { 458 ZeroMemory(&Item, sizeof(LV_ITEM)); 459 Item.mask = LVIF_PARAM; 460 Item.iItem = Index; 461 (VOID) ListView_GetItem(GetDlgItem(hwndDlg, IDC_PROBELIST), &Item); 462 HeapFree(hProcessHeap, 0, (LPVOID) Item.lParam); 463 } 464 HeapFree(hProcessHeap, 0, (LPVOID) pDeviceStatusText); 465 } 466 break; 467 } 468 469 return FALSE; 470 } 471 472 static INT_PTR CALLBACK 473 SelectWayPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 474 { 475 switch (uMsg) 476 { 477 case WM_NOTIFY: 478 { 479 LPNMHDR lpnm = (LPNMHDR)lParam; 480 481 switch (lpnm->code) 482 { 483 case PSN_SETACTIVE: 484 { 485 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT | PSWIZB_BACK); 486 if (SendDlgItemMessage(hwndDlg, IDC_AUTOINSTALL, BM_GETCHECK, 0, 0) == BST_CHECKED) 487 SendDlgItemMessage(hwndDlg, IDC_MANUALLYINST, BM_SETCHECK, 0, 0); 488 else 489 { 490 SendDlgItemMessage(hwndDlg, IDC_AUTOINSTALL, BM_SETCHECK, 1, 1); 491 SendDlgItemMessage(hwndDlg, IDC_MANUALLYINST, BM_SETCHECK, 0, 0); 492 } 493 } 494 break; 495 496 case PSN_WIZNEXT: 497 { 498 if (SendDlgItemMessage(hwndDlg, IDC_AUTOINSTALL, BM_GETCHECK, 0, 0) == BST_CHECKED) 499 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_PROGRESSPAGE); 500 else 501 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_HWTYPESPAGE); 502 503 return TRUE; 504 } 505 } 506 } 507 break; 508 } 509 510 return FALSE; 511 } 512 513 static INT_PTR CALLBACK 514 DevStatusPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 515 { 516 switch (uMsg) 517 { 518 case WM_INITDIALOG: 519 { 520 /* Set title font */ 521 SendDlgItemMessage(hwndDlg, IDC_FINISHTITLE, WM_SETFONT, (WPARAM)hTitleFont, (LPARAM)TRUE); 522 } 523 break; 524 525 case WM_NOTIFY: 526 { 527 LPNMHDR lpnm = (LPNMHDR)lParam; 528 529 switch (lpnm->code) 530 { 531 case PSN_SETACTIVE: 532 { 533 /* Set status text */ 534 SetWindowText(GetDlgItem(hwndDlg, IDC_HWSTATUSEDIT), pDeviceStatusText); 535 536 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_FINISH | PSWIZB_BACK); 537 } 538 break; 539 540 case PSN_WIZBACK: 541 { 542 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_PROBELISTPAGE); 543 return TRUE; 544 } 545 } 546 } 547 break; 548 } 549 550 return FALSE; 551 } 552 553 static INT 554 EnumDeviceClasses(INT ClassIndex, 555 LPWSTR DevClassName, 556 LPWSTR DevClassDesc, 557 BOOL *DevPresent, 558 INT *ClassImage) 559 { 560 GUID ClassGuid; 561 HKEY KeyClass; 562 WCHAR ClassName[MAX_STR_SIZE]; 563 DWORD RequiredSize = MAX_STR_SIZE; 564 UINT Ret; 565 566 *DevPresent = FALSE; 567 *DevClassName = L'\0'; 568 569 Ret = CM_Enumerate_Classes(ClassIndex, 570 &ClassGuid, 571 0); 572 if (Ret != CR_SUCCESS) 573 { 574 /* All classes enumerated */ 575 if(Ret == CR_NO_SUCH_VALUE) 576 { 577 hDevInfoTypes = NULL; 578 return -1; 579 } 580 581 if (Ret == CR_INVALID_DATA) 582 { 583 ; /* FIXME: What should we do here? */ 584 } 585 586 /* Handle other errors... */ 587 } 588 589 if (SetupDiClassNameFromGuid(&ClassGuid, 590 ClassName, 591 RequiredSize, 592 &RequiredSize)) 593 { 594 lstrcpy(DevClassName, ClassName); 595 } 596 597 if (!SetupDiGetClassImageIndex(&ImageListData, 598 &ClassGuid, 599 ClassImage)) 600 { 601 /* FIXME: Can we do this? 602 * Set the blank icon: IDI_SETUPAPI_BLANK = 41 603 * It'll be image 24 in the imagelist */ 604 *ClassImage = 24; 605 } 606 607 /* Get device info for all devices of a particular class */ 608 hDevInfoTypes = SetupDiGetClassDevs(&ClassGuid, 609 NULL, 610 NULL, 611 DIGCF_PRESENT); 612 if (hDevInfoTypes == INVALID_HANDLE_VALUE) 613 { 614 hDevInfoTypes = NULL; 615 return 0; 616 } 617 618 KeyClass = SetupDiOpenClassRegKeyEx(&ClassGuid, 619 MAXIMUM_ALLOWED, 620 DIOCR_INSTALLER, 621 NULL, 622 0); 623 if (KeyClass != INVALID_HANDLE_VALUE) 624 { 625 626 LONG dwSize = MAX_STR_SIZE; 627 628 if (RegQueryValue(KeyClass, 629 NULL, 630 DevClassDesc, 631 &dwSize) != ERROR_SUCCESS) 632 { 633 *DevClassDesc = L'\0'; 634 } 635 } 636 else 637 { 638 return -3; 639 } 640 641 *DevPresent = TRUE; 642 643 RegCloseKey(KeyClass); 644 645 return 0; 646 } 647 648 static VOID 649 InitHardWareTypesPage(HWND hwndDlg) 650 { 651 HWND hList = GetDlgItem(hwndDlg, IDC_HWTYPESLIST); 652 WCHAR DevName[MAX_STR_SIZE]; 653 WCHAR DevDesc[MAX_STR_SIZE]; 654 BOOL DevExist = FALSE; 655 INT ClassRet, DevImage, Index = 0; 656 LV_COLUMN Column; 657 LV_ITEM Item; 658 RECT Rect; 659 660 if (!hList) return; 661 662 ZeroMemory(&Column, sizeof(LV_COLUMN)); 663 664 GetClientRect(hList, &Rect); 665 666 Column.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH; 667 Column.fmt = LVCFMT_LEFT; 668 Column.iSubItem = 0; 669 Column.pszText = NULL; 670 Column.cx = Rect.right - GetSystemMetrics(SM_CXVSCROLL); 671 (VOID) ListView_InsertColumn(hList, 0, &Column); 672 673 ZeroMemory(&Item, sizeof(LV_ITEM)); 674 675 do 676 { 677 ClassRet = EnumDeviceClasses(Index, 678 DevName, 679 DevDesc, 680 &DevExist, 681 &DevImage); 682 683 if ((ClassRet != -1) && (DevExist)) 684 { 685 Item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE | LVIF_IMAGE; 686 Item.iItem = Index; 687 Item.iImage = DevImage; 688 689 if (DevDesc[0] != L'\0') 690 Item.pszText = (LPWSTR) DevDesc; 691 else 692 Item.pszText = (LPWSTR) DevName; 693 694 (VOID) ListView_InsertItem(hList, &Item); 695 696 /* Kill InfoList initialized in EnumDeviceClasses */ 697 if (hDevInfoTypes) 698 { 699 SetupDiDestroyDeviceInfoList(hDevInfoTypes); 700 hDevInfoTypes = NULL; 701 } 702 } 703 Index++; 704 } 705 while (ClassRet != -1); 706 707 (VOID) ListView_SetImageList(hList, ImageListData.ImageList, LVSIL_SMALL); 708 } 709 710 static INT_PTR CALLBACK 711 HdTypesPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 712 { 713 switch (uMsg) 714 { 715 case WM_INITDIALOG: 716 { 717 InitHardWareTypesPage(hwndDlg); 718 } 719 break; 720 721 case WM_NOTIFY: 722 { 723 LPNMHDR lpnm = (LPNMHDR)lParam; 724 725 switch (lpnm->code) 726 { 727 case PSN_SETACTIVE: 728 { 729 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK); 730 } 731 break; 732 733 case PSN_WIZBACK: 734 { 735 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_SELECTWAYPAGE); 736 return TRUE; 737 } 738 } 739 } 740 break; 741 } 742 743 return FALSE; 744 } 745 746 static INT_PTR CALLBACK 747 ProgressPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 748 { 749 switch (uMsg) 750 { 751 case WM_NOTIFY: 752 { 753 LPNMHDR lpnm = (LPNMHDR)lParam; 754 755 switch (lpnm->code) 756 { 757 case PSN_SETACTIVE: 758 { 759 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK); 760 } 761 break; 762 763 case PSN_WIZBACK: 764 { 765 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_SELECTWAYPAGE); 766 return TRUE; 767 } 768 } 769 } 770 break; 771 } 772 773 return FALSE; 774 } 775 776 static int CALLBACK 777 PropSheetProc(HWND hwndDlg, UINT uMsg, LPARAM lParam) 778 { 779 // NOTE: This callback is needed to set large icon correctly. 780 HICON hIcon; 781 switch (uMsg) 782 { 783 case PSCB_INITIALIZED: 784 { 785 hIcon = LoadIconW(hApplet, MAKEINTRESOURCEW(IDI_CPLICON)); 786 SendMessageW(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon); 787 break; 788 } 789 } 790 return 0; 791 } 792 793 static VOID 794 HardwareWizardInit(HWND hwnd) 795 { 796 HPROPSHEETPAGE ahpsp[10]; 797 PROPSHEETPAGE psp = {0}; 798 PROPSHEETHEADER psh; 799 UINT nPages = 0; 800 801 /* Create the Start page, until setup is working */ 802 psp.dwSize = sizeof(PROPSHEETPAGE); 803 psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER; 804 psp.hInstance = hApplet; 805 psp.lParam = 0; 806 psp.pfnDlgProc = StartPageDlgProc; 807 psp.pszTemplate = MAKEINTRESOURCE(IDD_STARTPAGE); 808 ahpsp[nPages++] = CreatePropertySheetPage(&psp); 809 810 /* Create search page */ 811 psp.dwSize = sizeof(PROPSHEETPAGE); 812 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE; 813 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_SEARCHTITLE); 814 psp.pszHeaderSubTitle = NULL; 815 psp.hInstance = hApplet; 816 psp.lParam = 0; 817 psp.pfnDlgProc = SearchPageDlgProc; 818 psp.pszTemplate = MAKEINTRESOURCE(IDD_SEARCHPAGE); 819 ahpsp[nPages++] = CreatePropertySheetPage(&psp); 820 821 /* Create is connected page */ 822 psp.dwSize = sizeof(PROPSHEETPAGE); 823 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE; 824 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_ISCONNECTED); 825 psp.pszHeaderSubTitle = NULL; 826 psp.hInstance = hApplet; 827 psp.lParam = 0; 828 psp.pfnDlgProc = IsConnectedPageDlgProc; 829 psp.pszTemplate = MAKEINTRESOURCE(IDD_ISCONNECTEDPAGE); 830 ahpsp[nPages++] = CreatePropertySheetPage(&psp); 831 832 /* Create probe list page */ 833 psp.dwSize = sizeof(PROPSHEETPAGE); 834 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE; 835 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_PROBELISTTITLE); 836 psp.pszHeaderSubTitle = NULL; 837 psp.hInstance = hApplet; 838 psp.lParam = 0; 839 psp.pfnDlgProc = ProbeListPageDlgProc; 840 psp.pszTemplate = MAKEINTRESOURCE(IDD_PROBELISTPAGE); 841 ahpsp[nPages++] = CreatePropertySheetPage(&psp); 842 843 /* Create select search way page */ 844 psp.dwSize = sizeof(PROPSHEETPAGE); 845 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE; 846 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_SELECTWAYTITLE); 847 psp.pszHeaderSubTitle = NULL; 848 psp.hInstance = hApplet; 849 psp.lParam = 0; 850 psp.pfnDlgProc = SelectWayPageDlgProc; 851 psp.pszTemplate = MAKEINTRESOURCE(IDD_SELECTWAYPAGE); 852 ahpsp[nPages++] = CreatePropertySheetPage(&psp); 853 854 /* Create device status page */ 855 psp.dwSize = sizeof(PROPSHEETPAGE); 856 psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER; 857 psp.hInstance = hApplet; 858 psp.lParam = 0; 859 psp.pfnDlgProc = DevStatusPageDlgProc; 860 psp.pszTemplate = MAKEINTRESOURCE(IDD_HWSTATUSPAGE); 861 ahpsp[nPages++] = CreatePropertySheetPage(&psp); 862 863 /* Create hardware types page */ 864 psp.dwSize = sizeof(PROPSHEETPAGE); 865 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE; 866 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_HDTYPESTITLE); 867 psp.pszHeaderSubTitle = NULL; 868 psp.hInstance = hApplet; 869 psp.lParam = 0; 870 psp.pfnDlgProc = HdTypesPageDlgProc; 871 psp.pszTemplate = MAKEINTRESOURCE(IDD_HWTYPESPAGE); 872 ahpsp[nPages++] = CreatePropertySheetPage(&psp); 873 874 /* Create progress page */ 875 psp.dwSize = sizeof(PROPSHEETPAGE); 876 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE; 877 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_SEARCHTITLE); 878 psp.pszHeaderSubTitle = NULL; 879 psp.hInstance = hApplet; 880 psp.lParam = 0; 881 psp.pfnDlgProc = ProgressPageDlgProc; 882 psp.pszTemplate = MAKEINTRESOURCE(IDD_PROGRESSPAGE); 883 ahpsp[nPages++] = CreatePropertySheetPage(&psp); 884 885 /* Create finish page */ 886 psp.dwSize = sizeof(PROPSHEETPAGE); 887 psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER; 888 psp.hInstance = hApplet; 889 psp.lParam = 0; 890 psp.pfnDlgProc = FinishPageDlgProc; 891 psp.pszTemplate = MAKEINTRESOURCE(IDD_FINISHPAGE); 892 ahpsp[nPages++] = CreatePropertySheetPage(&psp); 893 894 /* Create not connected page */ 895 psp.dwSize = sizeof(PROPSHEETPAGE); 896 psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER; 897 psp.hInstance = hApplet; 898 psp.lParam = 0; 899 psp.pfnDlgProc = NotConnectedPageDlgProc; 900 psp.pszTemplate = MAKEINTRESOURCE(IDD_NOTCONNECTEDPAGE); 901 ahpsp[nPages++] = CreatePropertySheetPage(&psp); 902 903 /* Create the property sheet */ 904 psh.dwSize = sizeof(PROPSHEETHEADER); 905 psh.dwFlags = PSH_WIZARD97 | PSH_WATERMARK | PSH_HEADER | PSH_USEICONID | PSH_USECALLBACK; 906 psh.hInstance = hApplet; 907 psh.pszIcon = MAKEINTRESOURCEW(IDI_CPLICON); 908 psh.hwndParent = hwnd; 909 psh.nPages = nPages; 910 psh.nStartPage = 0; 911 psh.phpage = ahpsp; 912 psh.pszbmWatermark = MAKEINTRESOURCE(IDB_WATERMARK); 913 psh.pszbmHeader = MAKEINTRESOURCE(IDB_HEADER); 914 psh.pfnCallback = PropSheetProc; 915 916 /* Create title font */ 917 hTitleFont = CreateTitleFont(); 918 919 /* Display the wizard */ 920 PropertySheet(&psh); 921 922 DeleteObject(hTitleFont); 923 } 924 925 /* FUNCTIONS ****************************************************************/ 926 927 BOOL WINAPI 928 InstallNewDevice(HWND hwndParent, LPGUID ClassGuid, PDWORD pReboot) 929 { 930 return FALSE; 931 } 932 933 VOID WINAPI 934 AddHardwareWizard(HWND hwnd, LPWSTR lpName) 935 { 936 if (lpName != NULL) 937 { 938 DPRINT1("No support of remote installation yet!\n"); 939 return; 940 } 941 942 HardwareWizardInit(hwnd); 943 } 944 945 /* Control Panel Callback */ 946 LONG CALLBACK 947 CPlApplet(HWND hwndCpl, UINT uMsg, LPARAM lParam1, LPARAM lParam2) 948 { 949 switch (uMsg) 950 { 951 case CPL_INIT: 952 return TRUE; 953 954 case CPL_GETCOUNT: 955 return 1; 956 957 case CPL_INQUIRE: 958 { 959 CPLINFO *CPlInfo = (CPLINFO*)lParam2; 960 CPlInfo->lData = 0; 961 CPlInfo->idIcon = IDI_CPLICON; 962 CPlInfo->idName = IDS_CPLNAME; 963 CPlInfo->idInfo = IDS_CPLDESCRIPTION; 964 } 965 break; 966 967 case CPL_DBLCLK: 968 AddHardwareWizard(hwndCpl, NULL); 969 break; 970 } 971 972 return FALSE; 973 } 974 975 BOOL WINAPI 976 DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpvReserved) 977 { 978 UNREFERENCED_PARAMETER(lpvReserved); 979 980 switch (dwReason) 981 { 982 case DLL_PROCESS_ATTACH: 983 hApplet = hinstDLL; 984 hProcessHeap = GetProcessHeap(); 985 DisableThreadLibraryCalls(hinstDLL); 986 break; 987 } 988 989 return TRUE; 990 } 991