Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenwizard.c
Go to the documentation of this file.
00001 /* 00002 * New device installer (newdev.dll) 00003 * 00004 * Copyright 2006 Hervé Poussineau (hpoussin@reactos.org) 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00019 */ 00020 00021 #include "newdev_private.h" 00022 00023 WINE_DEFAULT_DEBUG_CHANNEL(newdev); 00024 00025 HANDLE hThread; 00026 00027 static VOID 00028 CenterWindow( 00029 IN HWND hWnd) 00030 { 00031 HWND hWndParent; 00032 RECT rcParent; 00033 RECT rcWindow; 00034 00035 hWndParent = GetParent(hWnd); 00036 if (hWndParent == NULL) 00037 hWndParent = GetDesktopWindow(); 00038 00039 GetWindowRect(hWndParent, &rcParent); 00040 GetWindowRect(hWnd, &rcWindow); 00041 00042 SetWindowPos( 00043 hWnd, 00044 HWND_TOP, 00045 ((rcParent.right - rcParent.left) - (rcWindow.right - rcWindow.left)) / 2, 00046 ((rcParent.bottom - rcParent.top) - (rcWindow.bottom - rcWindow.top)) / 2, 00047 0, 00048 0, 00049 SWP_NOSIZE); 00050 } 00051 00052 static BOOL 00053 CanDisableDevice( 00054 IN DEVINST DevInst, 00055 IN HMACHINE hMachine, 00056 OUT BOOL *CanDisable) 00057 { 00058 CONFIGRET cr; 00059 ULONG Status, ProblemNumber; 00060 BOOL Ret = FALSE; 00061 00062 cr = CM_Get_DevNode_Status_Ex(&Status, 00063 &ProblemNumber, 00064 DevInst, 00065 0, 00066 hMachine); 00067 if (cr == CR_SUCCESS) 00068 { 00069 *CanDisable = ((Status & DN_DISABLEABLE) != 0); 00070 Ret = TRUE; 00071 } 00072 00073 return Ret; 00074 } 00075 00076 static BOOL 00077 IsDeviceStarted( 00078 IN DEVINST DevInst, 00079 IN HMACHINE hMachine, 00080 OUT BOOL *IsEnabled) 00081 { 00082 CONFIGRET cr; 00083 ULONG Status, ProblemNumber; 00084 BOOL Ret = FALSE; 00085 00086 cr = CM_Get_DevNode_Status_Ex( 00087 &Status, 00088 &ProblemNumber, 00089 DevInst, 00090 0, 00091 hMachine); 00092 if (cr == CR_SUCCESS) 00093 { 00094 *IsEnabled = ((Status & DN_STARTED) != 0); 00095 Ret = TRUE; 00096 } 00097 00098 return Ret; 00099 } 00100 00101 static BOOL 00102 StartDevice( 00103 IN HDEVINFO DeviceInfoSet, 00104 IN PSP_DEVINFO_DATA DevInfoData OPTIONAL, 00105 IN BOOL bEnable, 00106 IN DWORD HardwareProfile OPTIONAL, 00107 OUT BOOL *bNeedReboot OPTIONAL) 00108 { 00109 SP_PROPCHANGE_PARAMS pcp; 00110 SP_DEVINSTALL_PARAMS dp; 00111 DWORD LastErr; 00112 BOOL Ret = FALSE; 00113 00114 pcp.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER); 00115 pcp.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE; 00116 pcp.HwProfile = HardwareProfile; 00117 00118 if (bEnable) 00119 { 00120 /* try to enable the device on the global profile */ 00121 pcp.StateChange = DICS_ENABLE; 00122 pcp.Scope = DICS_FLAG_GLOBAL; 00123 00124 /* ignore errors */ 00125 LastErr = GetLastError(); 00126 if (SetupDiSetClassInstallParams( 00127 DeviceInfoSet, 00128 DevInfoData, 00129 &pcp.ClassInstallHeader, 00130 sizeof(SP_PROPCHANGE_PARAMS))) 00131 { 00132 SetupDiCallClassInstaller( 00133 DIF_PROPERTYCHANGE, 00134 DeviceInfoSet, 00135 DevInfoData); 00136 } 00137 SetLastError(LastErr); 00138 } 00139 00140 /* try config-specific */ 00141 pcp.StateChange = (bEnable ? DICS_ENABLE : DICS_DISABLE); 00142 pcp.Scope = DICS_FLAG_CONFIGSPECIFIC; 00143 00144 if (SetupDiSetClassInstallParams( 00145 DeviceInfoSet, 00146 DevInfoData, 00147 &pcp.ClassInstallHeader, 00148 sizeof(SP_PROPCHANGE_PARAMS)) && 00149 SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, 00150 DeviceInfoSet, 00151 DevInfoData)) 00152 { 00153 dp.cbSize = sizeof(SP_DEVINSTALL_PARAMS); 00154 if (SetupDiGetDeviceInstallParams( 00155 DeviceInfoSet, 00156 DevInfoData, 00157 &dp)) 00158 { 00159 if (bNeedReboot != NULL) 00160 { 00161 *bNeedReboot = ((dp.Flags & (DI_NEEDRESTART | DI_NEEDREBOOT)) != 0); 00162 } 00163 00164 Ret = TRUE; 00165 } 00166 } 00167 return Ret; 00168 } 00169 00170 static DWORD WINAPI 00171 FindDriverProc( 00172 IN LPVOID lpParam) 00173 { 00174 PDEVINSTDATA DevInstData; 00175 DWORD config_flags; 00176 BOOL result = FALSE; 00177 00178 DevInstData = (PDEVINSTDATA)lpParam; 00179 00180 result = ScanFoldersForDriver(DevInstData); 00181 00182 if (result) 00183 { 00184 PostMessage(DevInstData->hDialog, WM_SEARCH_FINISHED, 1, 0); 00185 } 00186 else 00187 { 00188 /* Update device configuration */ 00189 if (SetupDiGetDeviceRegistryProperty( 00190 DevInstData->hDevInfo, 00191 &DevInstData->devInfoData, 00192 SPDRP_CONFIGFLAGS, 00193 NULL, 00194 (BYTE *)&config_flags, 00195 sizeof(config_flags), 00196 NULL)) 00197 { 00198 config_flags |= CONFIGFLAG_FAILEDINSTALL; 00199 SetupDiSetDeviceRegistryPropertyW( 00200 DevInstData->hDevInfo, 00201 &DevInstData->devInfoData, 00202 SPDRP_CONFIGFLAGS, 00203 (BYTE *)&config_flags, sizeof(config_flags)); 00204 } 00205 00206 PostMessage(DevInstData->hDialog, WM_SEARCH_FINISHED, 0, 0); 00207 } 00208 return 0; 00209 } 00210 00211 static DWORD WINAPI 00212 InstallDriverProc( 00213 IN LPVOID lpParam) 00214 { 00215 PDEVINSTDATA DevInstData; 00216 BOOL res; 00217 00218 DevInstData = (PDEVINSTDATA)lpParam; 00219 res = InstallCurrentDriver(DevInstData); 00220 PostMessage(DevInstData->hDialog, WM_INSTALL_FINISHED, res ? 0 : 1, 0); 00221 return 0; 00222 } 00223 00224 static VOID 00225 PopulateCustomPathCombo( 00226 IN HWND hwndCombo) 00227 { 00228 HKEY hKey = NULL; 00229 DWORD dwRegType; 00230 DWORD dwPathLength = 0; 00231 LPWSTR Buffer = NULL; 00232 LPCWSTR Path; 00233 LONG rc; 00234 00235 (void)ComboBox_ResetContent(hwndCombo); 00236 00237 /* RegGetValue would have been better... */ 00238 rc = RegOpenKeyEx( 00239 HKEY_LOCAL_MACHINE, 00240 REGSTR_PATH_SETUP REGSTR_KEY_SETUP, 00241 0, 00242 KEY_QUERY_VALUE, 00243 &hKey); 00244 if (rc != ERROR_SUCCESS) 00245 { 00246 TRACE("RegOpenKeyEx() failed with error 0x%lx\n", rc); 00247 goto cleanup; 00248 } 00249 rc = RegQueryValueExW( 00250 hKey, 00251 L"Installation Sources", 00252 NULL, 00253 &dwRegType, 00254 NULL, 00255 &dwPathLength); 00256 if (rc != ERROR_SUCCESS || dwRegType != REG_MULTI_SZ) 00257 { 00258 TRACE("RegQueryValueEx() failed with error 0x%lx\n", rc); 00259 goto cleanup; 00260 } 00261 00262 /* Allocate enough space to add 2 NULL chars at the end of the string */ 00263 Buffer = HeapAlloc(GetProcessHeap(), 0, dwPathLength + 2 * sizeof(WCHAR)); 00264 if (!Buffer) 00265 { 00266 TRACE("HeapAlloc() failed\n"); 00267 goto cleanup; 00268 } 00269 rc = RegQueryValueExW( 00270 hKey, 00271 L"Installation Sources", 00272 NULL, 00273 NULL, 00274 (LPBYTE)Buffer, 00275 &dwPathLength); 00276 if (rc != ERROR_SUCCESS) 00277 { 00278 TRACE("RegQueryValueEx() failed with error 0x%lx\n", rc); 00279 goto cleanup; 00280 } 00281 Buffer[dwPathLength] = Buffer[dwPathLength + 1] = '\0'; 00282 00283 /* Populate combo box */ 00284 for (Path = Buffer; *Path; Path += wcslen(Path) + 1) 00285 { 00286 (void)ComboBox_AddString(hwndCombo, Path); 00287 if (Path == Buffer) 00288 (void)ComboBox_SetCurSel(hwndCombo, 0); 00289 } 00290 00291 cleanup: 00292 if (hKey != NULL) 00293 RegCloseKey(hKey); 00294 HeapFree(GetProcessHeap(), 0, Buffer); 00295 } 00296 00297 static VOID 00298 SaveCustomPath( 00299 IN HWND hwndCombo) 00300 { 00301 LPWSTR CustomPath = NULL; 00302 DWORD CustomPathLength; 00303 LPWSTR Buffer = NULL; 00304 LPWSTR pBuffer; /* Pointer into Buffer */ 00305 int ItemsCount, Length; 00306 DWORD i; 00307 DWORD TotalLength = 0; 00308 BOOL UseCustomPath = TRUE; 00309 HKEY hKey = NULL; 00310 LONG rc; 00311 00312 /* Get custom path */ 00313 Length = ComboBox_GetTextLength(hwndCombo) + 1; 00314 CustomPath = HeapAlloc(GetProcessHeap(), 0, Length * sizeof(WCHAR)); 00315 if (!CustomPath) 00316 { 00317 TRACE("HeapAlloc() failed\n"); 00318 goto cleanup; 00319 } 00320 CustomPathLength = GetWindowTextW(hwndCombo, CustomPath, Length) + 1; 00321 00322 /* Calculate length of the buffer */ 00323 ItemsCount = ComboBox_GetCount(hwndCombo); 00324 if (ItemsCount == CB_ERR) 00325 { 00326 TRACE("ComboBox_GetCount() failed\n"); 00327 goto cleanup; 00328 } 00329 for (i = 0; i < ItemsCount; i++) 00330 { 00331 Length = ComboBox_GetLBTextLen(hwndCombo, i); 00332 if (Length == CB_ERR) 00333 { 00334 TRACE("ComboBox_GetLBTextLen() failed\n"); 00335 goto cleanup; 00336 } 00337 TotalLength += Length + 1; 00338 } 00339 TotalLength++; /* Final NULL char */ 00340 00341 /* Allocate buffer */ 00342 Buffer = HeapAlloc(GetProcessHeap(), 0, (CustomPathLength + TotalLength + 1) * sizeof(WCHAR)); 00343 if (!Buffer) 00344 { 00345 TRACE("HeapAlloc() failed\n"); 00346 goto cleanup; 00347 } 00348 00349 /* Fill the buffer */ 00350 pBuffer = &Buffer[CustomPathLength]; 00351 for (i = 0; i < ItemsCount; i++) 00352 { 00353 Length = ComboBox_GetLBText(hwndCombo, i, pBuffer); 00354 if (Length == CB_ERR) 00355 { 00356 TRACE("ComboBox_GetLBText() failed\n"); 00357 goto cleanup; 00358 } 00359 else if (UseCustomPath && _wcsicmp(CustomPath, pBuffer) == 0) 00360 UseCustomPath = FALSE; 00361 pBuffer += 1 + Length; 00362 } 00363 *pBuffer = '\0'; /* Add final NULL char */ 00364 00365 if (!UseCustomPath) 00366 { 00367 /* Nothing to save to registry */ 00368 goto cleanup; 00369 } 00370 00371 TotalLength += CustomPathLength; 00372 wcscpy(Buffer, CustomPath); 00373 00374 /* Save the buffer */ 00375 /* RegSetKeyValue would have been better... */ 00376 rc = RegOpenKeyEx( 00377 HKEY_LOCAL_MACHINE, 00378 REGSTR_PATH_SETUP REGSTR_KEY_SETUP, 00379 0, 00380 KEY_SET_VALUE, 00381 &hKey); 00382 if (rc != ERROR_SUCCESS) 00383 { 00384 TRACE("RegOpenKeyEx() failed with error 0x%lx\n", rc); 00385 goto cleanup; 00386 } 00387 rc = RegSetValueExW( 00388 hKey, 00389 L"Installation Sources", 00390 0, 00391 REG_MULTI_SZ, 00392 (const BYTE*)Buffer, 00393 TotalLength * sizeof(WCHAR)); 00394 if (rc != ERROR_SUCCESS) 00395 { 00396 TRACE("RegSetValueEx() failed with error 0x%lx\n", rc); 00397 goto cleanup; 00398 } 00399 00400 cleanup: 00401 if (hKey != NULL) 00402 RegCloseKey(hKey); 00403 HeapFree(GetProcessHeap(), 0, CustomPath); 00404 HeapFree(GetProcessHeap(), 0, Buffer); 00405 } 00406 00407 static INT_PTR CALLBACK 00408 WelcomeDlgProc( 00409 IN HWND hwndDlg, 00410 IN UINT uMsg, 00411 IN WPARAM wParam, 00412 IN LPARAM lParam) 00413 { 00414 PDEVINSTDATA DevInstData; 00415 UNREFERENCED_PARAMETER(wParam); 00416 00417 /* Retrieve pointer to the global setup data */ 00418 DevInstData = (PDEVINSTDATA)GetWindowLongPtr(hwndDlg, GWL_USERDATA); 00419 00420 switch (uMsg) 00421 { 00422 case WM_INITDIALOG: 00423 { 00424 HWND hwndControl; 00425 DWORD dwStyle; 00426 00427 /* Get pointer to the global setup data */ 00428 DevInstData = (PDEVINSTDATA)((LPPROPSHEETPAGE)lParam)->lParam; 00429 SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)DevInstData); 00430 00431 hwndControl = GetParent(hwndDlg); 00432 00433 /* Center the wizard window */ 00434 CenterWindow(hwndControl); 00435 00436 /* Hide the system menu */ 00437 dwStyle = GetWindowLongPtr(hwndControl, GWL_STYLE); 00438 SetWindowLongPtr(hwndControl, GWL_STYLE, dwStyle & ~WS_SYSMENU); 00439 00440 /* Set title font */ 00441 SendDlgItemMessage( 00442 hwndDlg, 00443 IDC_WELCOMETITLE, 00444 WM_SETFONT, 00445 (WPARAM)DevInstData->hTitleFont, 00446 (LPARAM)TRUE); 00447 00448 SendDlgItemMessage( 00449 hwndDlg, 00450 IDC_DEVICE, 00451 WM_SETTEXT, 00452 0, 00453 (LPARAM)DevInstData->buffer); 00454 00455 SendDlgItemMessage( 00456 hwndDlg, 00457 IDC_RADIO_AUTO, 00458 BM_SETCHECK, 00459 (WPARAM)TRUE, 00460 (LPARAM)0); 00461 break; 00462 } 00463 00464 case WM_NOTIFY: 00465 { 00466 LPNMHDR lpnm = (LPNMHDR)lParam; 00467 00468 switch (lpnm->code) 00469 { 00470 case PSN_SETACTIVE: 00471 /* Enable the Next button */ 00472 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT); 00473 break; 00474 00475 case PSN_WIZNEXT: 00476 /* Handle a Next button click, if necessary */ 00477 if (SendDlgItemMessage(hwndDlg, IDC_RADIO_AUTO, BM_GETCHECK, (WPARAM)0, (LPARAM)0) == BST_CHECKED) 00478 { 00479 if (PrepareFoldersToScan(DevInstData, TRUE, FALSE, NULL)) 00480 PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_SEARCHDRV); 00481 else 00482 PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_INSTALLFAILED); 00483 } 00484 return TRUE; 00485 00486 default: 00487 break; 00488 } 00489 break; 00490 } 00491 00492 default: 00493 break; 00494 } 00495 00496 return DefWindowProc(hwndDlg, uMsg, wParam, lParam); 00497 } 00498 00499 static void 00500 IncludePath(HWND Dlg, BOOL Enabled) 00501 { 00502 EnableWindow(GetDlgItem(Dlg, IDC_COMBO_PATH), Enabled); 00503 EnableWindow(GetDlgItem(Dlg, IDC_BROWSE), Enabled); 00504 } 00505 00506 static void 00507 AutoDriver(HWND Dlg, BOOL Enabled) 00508 { 00509 EnableWindow(GetDlgItem(Dlg, IDC_CHECK_MEDIA), Enabled); 00510 EnableWindow(GetDlgItem(Dlg, IDC_CHECK_PATH), Enabled); 00511 IncludePath(Dlg, Enabled & IsDlgButtonChecked(Dlg, IDC_CHECK_PATH)); 00512 } 00513 00514 static INT_PTR CALLBACK 00515 CHSourceDlgProc( 00516 IN HWND hwndDlg, 00517 IN UINT uMsg, 00518 IN WPARAM wParam, 00519 IN LPARAM lParam) 00520 { 00521 PDEVINSTDATA DevInstData; 00522 00523 /* Retrieve pointer to the global setup data */ 00524 DevInstData = (PDEVINSTDATA)GetWindowLongPtr(hwndDlg, GWL_USERDATA); 00525 00526 switch (uMsg) 00527 { 00528 case WM_INITDIALOG: 00529 { 00530 HWND hwndControl; 00531 DWORD dwStyle; 00532 00533 /* Get pointer to the global setup data */ 00534 DevInstData = (PDEVINSTDATA)((LPPROPSHEETPAGE)lParam)->lParam; 00535 SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)DevInstData); 00536 00537 hwndControl = GetParent(hwndDlg); 00538 00539 /* Center the wizard window */ 00540 CenterWindow(hwndControl); 00541 00542 /* Hide the system menu */ 00543 dwStyle = GetWindowLongPtr(hwndControl, GWL_STYLE); 00544 SetWindowLongPtr(hwndControl, GWL_STYLE, dwStyle & ~WS_SYSMENU); 00545 00546 PopulateCustomPathCombo(GetDlgItem(hwndDlg, IDC_COMBO_PATH)); 00547 00548 SendDlgItemMessage( 00549 hwndDlg, 00550 IDC_RADIO_SEARCHHERE, 00551 BM_SETCHECK, 00552 (WPARAM)TRUE, 00553 (LPARAM)0); 00554 AutoDriver(hwndDlg, TRUE); 00555 IncludePath(hwndDlg, FALSE); 00556 00557 /* Disable manual driver choice for now */ 00558 EnableWindow(GetDlgItem(hwndDlg, IDC_RADIO_CHOOSE), FALSE); 00559 00560 break; 00561 } 00562 00563 case WM_COMMAND: 00564 { 00565 switch (LOWORD(wParam)) 00566 { 00567 case IDC_RADIO_SEARCHHERE: 00568 AutoDriver(hwndDlg, TRUE); 00569 return TRUE; 00570 00571 case IDC_RADIO_CHOOSE: 00572 AutoDriver(hwndDlg, FALSE); 00573 return TRUE; 00574 00575 case IDC_CHECK_PATH: 00576 IncludePath(hwndDlg, IsDlgButtonChecked(hwndDlg, IDC_CHECK_PATH)); 00577 return TRUE; 00578 00579 case IDC_BROWSE: 00580 { 00581 BROWSEINFO bi = { 0 }; 00582 LPITEMIDLIST pidl; 00583 00584 bi.hwndOwner = hwndDlg; 00585 bi.ulFlags = BIF_RETURNONLYFSDIRS; 00586 pidl = SHBrowseForFolder(&bi); 00587 if (pidl) 00588 { 00589 WCHAR Directory[MAX_PATH]; 00590 IMalloc* malloc; 00591 00592 if (SHGetPathFromIDListW(pidl, Directory)) 00593 { 00594 /* Set the IDC_COMBO_PATH text */ 00595 SetWindowTextW(GetDlgItem(hwndDlg, IDC_COMBO_PATH), Directory); 00596 } 00597 00598 /* Free memory, if possible */ 00599 if (SUCCEEDED(SHGetMalloc(&malloc))) 00600 { 00601 IMalloc_Free(malloc, pidl); 00602 IMalloc_Release(malloc); 00603 } 00604 return TRUE; 00605 } 00606 break; 00607 } 00608 } 00609 break; 00610 } 00611 00612 case WM_NOTIFY: 00613 { 00614 LPNMHDR lpnm = (LPNMHDR)lParam; 00615 00616 switch (lpnm->code) 00617 { 00618 case PSN_SETACTIVE: 00619 /* Enable the Next and Back buttons */ 00620 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT | PSWIZB_BACK); 00621 break; 00622 00623 case PSN_WIZNEXT: 00624 /* Handle a Next button click, if necessary */ 00625 if (IsDlgButtonChecked(hwndDlg, IDC_RADIO_SEARCHHERE)) 00626 { 00627 SaveCustomPath(GetDlgItem(hwndDlg, IDC_COMBO_PATH)); 00628 HeapFree(GetProcessHeap(), 0, DevInstData->CustomSearchPath); 00629 DevInstData->CustomSearchPath = NULL; 00630 if (PrepareFoldersToScan( 00631 DevInstData, 00632 IsDlgButtonChecked(hwndDlg, IDC_CHECK_MEDIA), 00633 IsDlgButtonChecked(hwndDlg, IDC_CHECK_PATH), 00634 GetDlgItem(hwndDlg, IDC_COMBO_PATH))) 00635 { 00636 PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_SEARCHDRV); 00637 } 00638 else 00639 { 00640 PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_INSTALLFAILED); 00641 } 00642 } 00643 else 00644 { 00645 /* FIXME */; 00646 } 00647 return TRUE; 00648 00649 default: 00650 break; 00651 } 00652 break; 00653 } 00654 00655 default: 00656 break; 00657 } 00658 00659 return DefWindowProc(hwndDlg, uMsg, wParam, lParam); 00660 } 00661 00662 static INT_PTR CALLBACK 00663 SearchDrvDlgProc( 00664 IN HWND hwndDlg, 00665 IN UINT uMsg, 00666 IN WPARAM wParam, 00667 IN LPARAM lParam) 00668 { 00669 PDEVINSTDATA DevInstData; 00670 DWORD dwThreadId; 00671 00672 /* Retrieve pointer to the global setup data */ 00673 DevInstData = (PDEVINSTDATA)GetWindowLongPtr(hwndDlg, GWL_USERDATA); 00674 00675 switch (uMsg) 00676 { 00677 case WM_INITDIALOG: 00678 { 00679 HWND hwndControl; 00680 DWORD dwStyle; 00681 00682 /* Get pointer to the global setup data */ 00683 DevInstData = (PDEVINSTDATA)((LPPROPSHEETPAGE)lParam)->lParam; 00684 SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)DevInstData); 00685 00686 DevInstData->hDialog = hwndDlg; 00687 hwndControl = GetParent(hwndDlg); 00688 00689 /* Center the wizard window */ 00690 CenterWindow(hwndControl); 00691 00692 SendDlgItemMessage( 00693 hwndDlg, 00694 IDC_DEVICE, 00695 WM_SETTEXT, 00696 0, 00697 (LPARAM)DevInstData->buffer); 00698 00699 /* Hide the system menu */ 00700 dwStyle = GetWindowLongPtr(hwndControl, GWL_STYLE); 00701 SetWindowLongPtr(hwndControl, GWL_STYLE, dwStyle & ~WS_SYSMENU); 00702 break; 00703 } 00704 00705 case WM_SEARCH_FINISHED: 00706 { 00707 CloseHandle(hThread); 00708 hThread = 0; 00709 if (wParam == 0) 00710 PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_NODRIVER); 00711 else 00712 PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_INSTALLDRV); 00713 break; 00714 } 00715 00716 case WM_NOTIFY: 00717 { 00718 LPNMHDR lpnm = (LPNMHDR)lParam; 00719 00720 switch (lpnm->code) 00721 { 00722 case PSN_SETACTIVE: 00723 PropSheet_SetWizButtons(GetParent(hwndDlg), !PSWIZB_NEXT | !PSWIZB_BACK); 00724 /* Yes, we can safely ignore the problem (if any) */ 00725 SetupDiDestroyDriverInfoList( 00726 DevInstData->hDevInfo, 00727 &DevInstData->devInfoData, 00728 SPDIT_COMPATDRIVER); 00729 hThread = CreateThread(NULL, 0, FindDriverProc, DevInstData, 0, &dwThreadId); 00730 break; 00731 00732 case PSN_KILLACTIVE: 00733 if (hThread != 0) 00734 { 00735 SetWindowLongPtr(hwndDlg, DWL_MSGRESULT, TRUE); 00736 return TRUE; 00737 } 00738 break; 00739 00740 case PSN_WIZNEXT: 00741 /* Handle a Next button click, if necessary */ 00742 break; 00743 00744 default: 00745 break; 00746 } 00747 break; 00748 } 00749 00750 default: 00751 break; 00752 } 00753 00754 return DefWindowProc(hwndDlg, uMsg, wParam, lParam); 00755 } 00756 00757 static INT_PTR CALLBACK 00758 InstallDrvDlgProc( 00759 IN HWND hwndDlg, 00760 IN UINT uMsg, 00761 IN WPARAM wParam, 00762 IN LPARAM lParam) 00763 { 00764 PDEVINSTDATA DevInstData; 00765 DWORD dwThreadId; 00766 00767 /* Retrieve pointer to the global setup data */ 00768 DevInstData = (PDEVINSTDATA)GetWindowLongPtr(hwndDlg, GWL_USERDATA); 00769 00770 switch (uMsg) 00771 { 00772 case WM_INITDIALOG: 00773 { 00774 HWND hwndControl; 00775 DWORD dwStyle; 00776 00777 /* Get pointer to the global setup data */ 00778 DevInstData = (PDEVINSTDATA)((LPPROPSHEETPAGE)lParam)->lParam; 00779 SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)DevInstData); 00780 00781 DevInstData->hDialog = hwndDlg; 00782 hwndControl = GetParent(hwndDlg); 00783 00784 /* Center the wizard window */ 00785 CenterWindow(hwndControl); 00786 00787 SendDlgItemMessage( 00788 hwndDlg, 00789 IDC_DEVICE, 00790 WM_SETTEXT, 00791 0, 00792 (LPARAM)DevInstData->drvInfoData.Description); 00793 00794 /* Hide the system menu */ 00795 dwStyle = GetWindowLongPtr(hwndControl, GWL_STYLE); 00796 SetWindowLongPtr(hwndControl, GWL_STYLE, dwStyle & ~WS_SYSMENU); 00797 break; 00798 } 00799 00800 case WM_INSTALL_FINISHED: 00801 { 00802 CloseHandle(hThread); 00803 hThread = 0; 00804 if (wParam == 0) 00805 { 00806 /* Should we reboot? */ 00807 SP_DEVINSTALL_PARAMS installParams; 00808 installParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS); 00809 if (SetupDiGetDeviceInstallParams( 00810 DevInstData->hDevInfo, 00811 &DevInstData->devInfoData, 00812 &installParams)) 00813 { 00814 if (installParams.Flags & (DI_NEEDRESTART | DI_NEEDREBOOT)) 00815 { 00816 PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_NEEDREBOOT); 00817 } 00818 else 00819 PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_FINISHPAGE); 00820 break; 00821 } 00822 } 00823 PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_INSTALLFAILED); 00824 break; 00825 } 00826 00827 case WM_NOTIFY: 00828 { 00829 LPNMHDR lpnm = (LPNMHDR)lParam; 00830 00831 switch (lpnm->code) 00832 { 00833 case PSN_SETACTIVE: 00834 PropSheet_SetWizButtons(GetParent(hwndDlg), !PSWIZB_NEXT | !PSWIZB_BACK); 00835 hThread = CreateThread(NULL, 0, InstallDriverProc, DevInstData, 0, &dwThreadId); 00836 break; 00837 00838 case PSN_KILLACTIVE: 00839 if (hThread != 0) 00840 { 00841 SetWindowLongPtr(hwndDlg, DWL_MSGRESULT, TRUE); 00842 return TRUE; 00843 } 00844 break; 00845 00846 case PSN_WIZNEXT: 00847 /* Handle a Next button click, if necessary */ 00848 break; 00849 00850 default: 00851 break; 00852 } 00853 break; 00854 } 00855 00856 default: 00857 break; 00858 } 00859 00860 return DefWindowProc(hwndDlg, uMsg, wParam, lParam); 00861 } 00862 00863 static INT_PTR CALLBACK 00864 NoDriverDlgProc( 00865 IN HWND hwndDlg, 00866 IN UINT uMsg, 00867 IN WPARAM wParam, 00868 IN LPARAM lParam) 00869 { 00870 PDEVINSTDATA DevInstData; 00871 HWND hwndControl; 00872 00873 UNREFERENCED_PARAMETER(wParam); 00874 00875 /* Get pointer to the global setup data */ 00876 DevInstData = (PDEVINSTDATA)GetWindowLongPtr(hwndDlg, GWL_USERDATA); 00877 00878 switch (uMsg) 00879 { 00880 case WM_INITDIALOG: 00881 { 00882 BOOL DisableableDevice = FALSE; 00883 00884 /* Get pointer to the global setup data */ 00885 DevInstData = (PDEVINSTDATA)((LPPROPSHEETPAGE)lParam)->lParam; 00886 SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)DevInstData); 00887 00888 /* Center the wizard window */ 00889 CenterWindow(GetParent(hwndDlg)); 00890 00891 hwndControl = GetDlgItem(GetParent(hwndDlg), IDCANCEL); 00892 ShowWindow(hwndControl, SW_HIDE); 00893 EnableWindow(hwndControl, FALSE); 00894 00895 /* Set title font */ 00896 SendDlgItemMessage( 00897 hwndDlg, 00898 IDC_FINISHTITLE, 00899 WM_SETFONT, 00900 (WPARAM)DevInstData->hTitleFont, 00901 (LPARAM)TRUE); 00902 00903 /* disable the "do not show this dialog anymore" checkbox 00904 if the device cannot be disabled */ 00905 CanDisableDevice( 00906 DevInstData->devInfoData.DevInst, 00907 NULL, 00908 &DisableableDevice); 00909 EnableWindow( 00910 GetDlgItem(hwndDlg, IDC_DONOTSHOWDLG), 00911 DisableableDevice); 00912 break; 00913 } 00914 00915 case WM_NOTIFY: 00916 { 00917 LPNMHDR lpnm = (LPNMHDR)lParam; 00918 00919 switch (lpnm->code) 00920 { 00921 case PSN_SETACTIVE: 00922 /* Enable the correct buttons on for the active page */ 00923 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_FINISH); 00924 break; 00925 00926 case PSN_WIZBACK: 00927 /* Handle a Back button click, if necessary */ 00928 hwndControl = GetDlgItem(GetParent(hwndDlg), IDCANCEL); 00929 ShowWindow(hwndControl, SW_SHOW); 00930 EnableWindow(hwndControl, TRUE); 00931 PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_CHSOURCE); 00932 return TRUE; 00933 00934 case PSN_WIZFINISH: 00935 { 00936 BOOL DisableableDevice = FALSE; 00937 BOOL IsStarted = FALSE; 00938 00939 if (CanDisableDevice(DevInstData->devInfoData.DevInst, 00940 NULL, 00941 &DisableableDevice) && 00942 DisableableDevice && 00943 IsDeviceStarted( 00944 DevInstData->devInfoData.DevInst, 00945 NULL, 00946 &IsStarted) && 00947 !IsStarted && 00948 SendDlgItemMessage( 00949 hwndDlg, 00950 IDC_DONOTSHOWDLG, 00951 BM_GETCHECK, 00952 (WPARAM)0, (LPARAM)0) == BST_CHECKED) 00953 { 00954 /* disable the device */ 00955 StartDevice( 00956 DevInstData->hDevInfo, 00957 &DevInstData->devInfoData, 00958 FALSE, 00959 0, 00960 NULL); 00961 } 00962 break; 00963 } 00964 00965 default: 00966 break; 00967 } 00968 break; 00969 } 00970 00971 default: 00972 break; 00973 } 00974 00975 return DefWindowProc(hwndDlg, uMsg, wParam, lParam); 00976 } 00977 00978 static INT_PTR CALLBACK 00979 InstallFailedDlgProc( 00980 IN HWND hwndDlg, 00981 IN UINT uMsg, 00982 IN WPARAM wParam, 00983 IN LPARAM lParam) 00984 { 00985 PDEVINSTDATA DevInstData; 00986 UNREFERENCED_PARAMETER(wParam); 00987 00988 /* Retrieve pointer to the global setup data */ 00989 DevInstData = (PDEVINSTDATA)GetWindowLongPtr(hwndDlg, GWL_USERDATA); 00990 00991 switch (uMsg) 00992 { 00993 case WM_INITDIALOG: 00994 { 00995 HWND hwndControl; 00996 00997 /* Get pointer to the global setup data */ 00998 DevInstData = (PDEVINSTDATA)((LPPROPSHEETPAGE)lParam)->lParam; 00999 SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)DevInstData); 01000 01001 /* Center the wizard window */ 01002 CenterWindow(GetParent(hwndDlg)); 01003 01004 hwndControl = GetDlgItem(GetParent(hwndDlg), IDCANCEL); 01005 ShowWindow(hwndControl, SW_HIDE); 01006 EnableWindow(hwndControl, FALSE); 01007 01008 SendDlgItemMessage( 01009 hwndDlg, 01010 IDC_DEVICE, 01011 WM_SETTEXT, 01012 0, 01013 (LPARAM)DevInstData->drvInfoData.Description); 01014 01015 /* Set title font */ 01016 SendDlgItemMessage( 01017 hwndDlg, 01018 IDC_FINISHTITLE, 01019 WM_SETFONT, 01020 (WPARAM)DevInstData->hTitleFont, 01021 (LPARAM)TRUE); 01022 break; 01023 } 01024 01025 case WM_NOTIFY: 01026 { 01027 LPNMHDR lpnm = (LPNMHDR)lParam; 01028 01029 switch (lpnm->code) 01030 { 01031 case PSN_SETACTIVE: 01032 /* Enable the correct buttons on for the active page */ 01033 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_FINISH); 01034 break; 01035 01036 case PSN_WIZBACK: 01037 /* Handle a Back button click, if necessary */ 01038 break; 01039 01040 case PSN_WIZFINISH: 01041 /* Handle a Finish button click, if necessary */ 01042 break; 01043 01044 default: 01045 break; 01046 } 01047 break; 01048 } 01049 01050 default: 01051 break; 01052 } 01053 01054 return DefWindowProc(hwndDlg, uMsg, wParam, lParam); 01055 } 01056 01057 static INT_PTR CALLBACK 01058 NeedRebootDlgProc( 01059 IN HWND hwndDlg, 01060 IN UINT uMsg, 01061 IN WPARAM wParam, 01062 IN LPARAM lParam) 01063 { 01064 PDEVINSTDATA DevInstData; 01065 UNREFERENCED_PARAMETER(wParam); 01066 01067 /* Retrieve pointer to the global setup data */ 01068 DevInstData = (PDEVINSTDATA)GetWindowLongPtr(hwndDlg, GWL_USERDATA); 01069 01070 switch (uMsg) 01071 { 01072 case WM_INITDIALOG: 01073 { 01074 HWND hwndControl; 01075 01076 /* Get pointer to the global setup data */ 01077 DevInstData = (PDEVINSTDATA)((LPPROPSHEETPAGE)lParam)->lParam; 01078 SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)DevInstData); 01079 01080 /* Center the wizard window */ 01081 CenterWindow(GetParent(hwndDlg)); 01082 01083 hwndControl = GetDlgItem(GetParent(hwndDlg), IDCANCEL); 01084 ShowWindow(hwndControl, SW_HIDE); 01085 EnableWindow(hwndControl, FALSE); 01086 01087 SendDlgItemMessage( 01088 hwndDlg, 01089 IDC_DEVICE, 01090 WM_SETTEXT, 01091 0, 01092 (LPARAM)DevInstData->drvInfoData.Description); 01093 01094 /* Set title font */ 01095 SendDlgItemMessage( 01096 hwndDlg, 01097 IDC_FINISHTITLE, 01098 WM_SETFONT, 01099 (WPARAM)DevInstData->hTitleFont, 01100 (LPARAM)TRUE); 01101 break; 01102 } 01103 01104 case WM_NOTIFY: 01105 { 01106 LPNMHDR lpnm = (LPNMHDR)lParam; 01107 01108 switch (lpnm->code) 01109 { 01110 case PSN_SETACTIVE: 01111 /* Enable the correct buttons on for the active page */ 01112 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_FINISH); 01113 break; 01114 01115 case PSN_WIZBACK: 01116 /* Handle a Back button click, if necessary */ 01117 break; 01118 01119 case PSN_WIZFINISH: 01120 /* Handle a Finish button click, if necessary */ 01121 break; 01122 01123 default: 01124 break; 01125 } 01126 break; 01127 } 01128 01129 default: 01130 break; 01131 } 01132 01133 return DefWindowProc(hwndDlg, uMsg, wParam, lParam); 01134 } 01135 01136 static INT_PTR CALLBACK 01137 FinishDlgProc( 01138 IN HWND hwndDlg, 01139 IN UINT uMsg, 01140 IN WPARAM wParam, 01141 IN LPARAM lParam) 01142 { 01143 PDEVINSTDATA DevInstData; 01144 UNREFERENCED_PARAMETER(wParam); 01145 01146 /* Retrieve pointer to the global setup data */ 01147 DevInstData = (PDEVINSTDATA)GetWindowLongPtr(hwndDlg, GWL_USERDATA); 01148 01149 switch (uMsg) 01150 { 01151 case WM_INITDIALOG: 01152 { 01153 HWND hwndControl; 01154 01155 /* Get pointer to the global setup data */ 01156 DevInstData = (PDEVINSTDATA)((LPPROPSHEETPAGE)lParam)->lParam; 01157 SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)DevInstData); 01158 01159 /* Center the wizard window */ 01160 CenterWindow(GetParent(hwndDlg)); 01161 01162 hwndControl = GetDlgItem(GetParent(hwndDlg), IDCANCEL); 01163 ShowWindow(hwndControl, SW_HIDE); 01164 EnableWindow(hwndControl, FALSE); 01165 01166 SendDlgItemMessage( 01167 hwndDlg, 01168 IDC_DEVICE, 01169 WM_SETTEXT, 01170 0, 01171 (LPARAM)DevInstData->drvInfoData.Description); 01172 01173 /* Set title font */ 01174 SendDlgItemMessage( 01175 hwndDlg, 01176 IDC_FINISHTITLE, 01177 WM_SETFONT, 01178 (WPARAM)DevInstData->hTitleFont, 01179 (LPARAM)TRUE); 01180 break; 01181 } 01182 01183 case WM_NOTIFY: 01184 { 01185 LPNMHDR lpnm = (LPNMHDR)lParam; 01186 01187 switch (lpnm->code) 01188 { 01189 case PSN_SETACTIVE: 01190 /* Enable the correct buttons on for the active page */ 01191 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_FINISH); 01192 break; 01193 01194 case PSN_WIZBACK: 01195 /* Handle a Back button click, if necessary */ 01196 break; 01197 01198 case PSN_WIZFINISH: 01199 /* Handle a Finish button click, if necessary */ 01200 break; 01201 01202 default: 01203 break; 01204 } 01205 break; 01206 } 01207 01208 default: 01209 break; 01210 } 01211 01212 return DefWindowProc(hwndDlg, uMsg, wParam, lParam); 01213 } 01214 01215 static HFONT 01216 CreateTitleFont(VOID) 01217 { 01218 NONCLIENTMETRICSW ncm; 01219 LOGFONTW LogFont; 01220 HDC hdc; 01221 INT FontSize; 01222 HFONT hFont; 01223 01224 ncm.cbSize = sizeof(NONCLIENTMETRICSW); 01225 SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0); 01226 01227 LogFont = ncm.lfMessageFont; 01228 LogFont.lfWeight = FW_BOLD; 01229 wcscpy(LogFont.lfFaceName, L"MS Shell Dlg"); 01230 01231 hdc = GetDC(NULL); 01232 FontSize = 12; 01233 LogFont.lfHeight = 0 - GetDeviceCaps (hdc, LOGPIXELSY) * FontSize / 72; 01234 hFont = CreateFontIndirectW(&LogFont); 01235 ReleaseDC(NULL, hdc); 01236 01237 return hFont; 01238 } 01239 01240 BOOL 01241 DisplayWizard( 01242 IN PDEVINSTDATA DevInstData, 01243 IN HWND hwndParent, 01244 IN UINT startPage) 01245 { 01246 PROPSHEETHEADER psh; 01247 HPROPSHEETPAGE ahpsp[IDD_MAXIMUMPAGE + 1]; 01248 PROPSHEETPAGE psp; 01249 01250 /* Create the Welcome page */ 01251 ZeroMemory(&psp, sizeof(PROPSHEETPAGE)); 01252 psp.dwSize = sizeof(PROPSHEETPAGE); 01253 psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER; 01254 psp.hInstance = hDllInstance; 01255 psp.lParam = (LPARAM)DevInstData; 01256 psp.pfnDlgProc = (DLGPROC) WelcomeDlgProc; 01257 psp.pszTemplate = MAKEINTRESOURCE(IDD_WELCOMEPAGE); 01258 ahpsp[IDD_WELCOMEPAGE] = CreatePropertySheetPage(&psp); 01259 01260 /* Create the Select Source page */ 01261 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE; 01262 psp.pfnDlgProc = (DLGPROC) CHSourceDlgProc; 01263 psp.pszTemplate = MAKEINTRESOURCE(IDD_CHSOURCE); 01264 ahpsp[IDD_CHSOURCE] = CreatePropertySheetPage(&psp); 01265 01266 /* Create the Search driver page */ 01267 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE; 01268 psp.pfnDlgProc = (DLGPROC) SearchDrvDlgProc; 01269 psp.pszTemplate = MAKEINTRESOURCE(IDD_SEARCHDRV); 01270 ahpsp[IDD_SEARCHDRV] = CreatePropertySheetPage(&psp); 01271 01272 /* Create the Install driver page */ 01273 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE; 01274 psp.pfnDlgProc = (DLGPROC) InstallDrvDlgProc; 01275 psp.pszTemplate = MAKEINTRESOURCE(IDD_INSTALLDRV); 01276 ahpsp[IDD_INSTALLDRV] = CreatePropertySheetPage(&psp); 01277 01278 /* Create the No driver page */ 01279 psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER; 01280 psp.pfnDlgProc = (DLGPROC) NoDriverDlgProc; 01281 psp.pszTemplate = MAKEINTRESOURCE(IDD_NODRIVER); 01282 ahpsp[IDD_NODRIVER] = CreatePropertySheetPage(&psp); 01283 01284 /* Create the Install failed page */ 01285 psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER; 01286 psp.pfnDlgProc = (DLGPROC) InstallFailedDlgProc; 01287 psp.pszTemplate = MAKEINTRESOURCE(IDD_INSTALLFAILED); 01288 ahpsp[IDD_INSTALLFAILED] = CreatePropertySheetPage(&psp); 01289 01290 /* Create the Need reboot page */ 01291 psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER; 01292 psp.pfnDlgProc = (DLGPROC) NeedRebootDlgProc; 01293 psp.pszTemplate = MAKEINTRESOURCE(IDD_NEEDREBOOT); 01294 ahpsp[IDD_NEEDREBOOT] = CreatePropertySheetPage(&psp); 01295 01296 /* Create the Finish page */ 01297 psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER; 01298 psp.pfnDlgProc = (DLGPROC) FinishDlgProc; 01299 psp.pszTemplate = MAKEINTRESOURCE(IDD_FINISHPAGE); 01300 ahpsp[IDD_FINISHPAGE] = CreatePropertySheetPage(&psp); 01301 01302 /* Create the property sheet */ 01303 psh.dwSize = sizeof(PROPSHEETHEADER); 01304 psh.dwFlags = PSH_WIZARD97 | PSH_WATERMARK | PSH_HEADER; 01305 psh.hInstance = hDllInstance; 01306 psh.hwndParent = hwndParent; 01307 psh.nPages = IDD_MAXIMUMPAGE + 1; 01308 psh.nStartPage = startPage; 01309 psh.phpage = ahpsp; 01310 psh.pszbmWatermark = MAKEINTRESOURCE(IDB_WATERMARK); 01311 psh.pszbmHeader = MAKEINTRESOURCE(IDB_HEADER); 01312 01313 /* Create title font */ 01314 DevInstData->hTitleFont = CreateTitleFont(); 01315 01316 /* Display the wizard */ 01317 PropertySheet(&psh); 01318 01319 DeleteObject(DevInstData->hTitleFont); 01320 01321 return TRUE; 01322 } Generated on Sat May 26 2012 04:24:02 for ReactOS by
1.7.6.1
|