Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464/* * New device installer (newdev.dll) * * Copyright 2006 Hervé Poussineau (hpoussin@reactos.org) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
#include "newdev_private.h"
#include <wincon.h>#include <cfgmgr32.h>#include <shlobj.h>#include <shlwapi.h>
HANDLE hThread;
static VOIDCenterWindow( IN HWND hWnd){ HWND hWndParent; RECT rcParent; RECT rcWindow;
hWndParent = GetParent(hWnd); if (hWndParent == NULL) hWndParent = GetDesktopWindow();
GetWindowRect(hWndParent, &rcParent); GetWindowRect(hWnd, &rcWindow);
/* Check if the child window fits inside the parent window */ if (rcWindow.left < rcParent.left || rcWindow.top < rcParent.top || rcWindow.right > rcParent.right || rcWindow.bottom > rcParent.bottom) { return; }
SetWindowPos( hWnd, HWND_TOP, ((rcParent.right - rcParent.left) - (rcWindow.right - rcWindow.left)) / 2, ((rcParent.bottom - rcParent.top) - (rcWindow.bottom - rcWindow.top)) / 2, 0, 0, SWP_NOSIZE);}
static BOOLSetFailedInstall( IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DevInfoData OPTIONAL, IN BOOLEAN Set){ DWORD dwType, dwSize, dwFlags = 0;
dwSize = sizeof(dwFlags); if (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet, DevInfoData, SPDRP_CONFIGFLAGS, &dwType, (PBYTE)&dwFlags, dwSize, &dwSize)) { return FALSE; }
if (Set) dwFlags |= CONFIGFLAG_FAILEDINSTALL; else dwFlags &= ~CONFIGFLAG_FAILEDINSTALL;
if (!SetupDiSetDeviceRegistryProperty(DeviceInfoSet, DevInfoData, SPDRP_CONFIGFLAGS, (PBYTE)&dwFlags, dwSize)) {
return FALSE; }
if (Set) { /* Set the 'Unknown' device class */ PWSTR pszUnknown = L"Unknown"; SetupDiSetDeviceRegistryPropertyW(DeviceInfoSet, DevInfoData, SPDRP_CLASS, (PBYTE)pszUnknown, (wcslen(pszUnknown) + 1) * sizeof(WCHAR));
PWSTR pszUnknownGuid = L"{4D36E97E-E325-11CE-BFC1-08002BE10318}"; SetupDiSetDeviceRegistryPropertyW(DeviceInfoSet, DevInfoData, SPDRP_CLASSGUID, (PBYTE)pszUnknownGuid, (wcslen(pszUnknownGuid) + 1) * sizeof(WCHAR));
/* Set device problem code CM_PROB_FAILED_INSTALL */ CM_Set_DevNode_Problem(DevInfoData->DevInst, CM_PROB_FAILED_INSTALL, CM_SET_DEVNODE_PROBLEM_OVERRIDE); }
return TRUE;}
static BOOLCanDisableDevice( IN DEVINST DevInst, IN HMACHINE hMachine, OUT BOOL *CanDisable){ CONFIGRET cr; ULONG Status, ProblemNumber; BOOL Ret = FALSE;
cr = CM_Get_DevNode_Status_Ex(&Status, &ProblemNumber, DevInst, 0, hMachine); if (cr == CR_SUCCESS) { *CanDisable = ((Status & DN_DISABLEABLE) != 0); Ret = TRUE; }
return Ret;}
static BOOLIsDeviceStarted( IN DEVINST DevInst, IN HMACHINE hMachine, OUT BOOL *IsEnabled){ CONFIGRET cr; ULONG Status, ProblemNumber; BOOL Ret = FALSE;
cr = CM_Get_DevNode_Status_Ex( &Status, &ProblemNumber, DevInst, 0, hMachine); if (cr == CR_SUCCESS) { *IsEnabled = ((Status & DN_STARTED) != 0); Ret = TRUE; }
return Ret;}
static BOOLStartDevice( IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DevInfoData OPTIONAL, IN BOOL bEnable, IN DWORD HardwareProfile OPTIONAL, OUT BOOL *bNeedReboot OPTIONAL){ SP_PROPCHANGE_PARAMS pcp; SP_DEVINSTALL_PARAMS dp; DWORD LastErr; BOOL Ret = FALSE;
pcp.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER); pcp.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE; pcp.HwProfile = HardwareProfile;
if (bEnable) { /* try to enable the device on the global profile */ pcp.StateChange = DICS_ENABLE; pcp.Scope = DICS_FLAG_GLOBAL;
/* ignore errors */ LastErr = GetLastError(); if (SetupDiSetClassInstallParams( DeviceInfoSet, DevInfoData, &pcp.ClassInstallHeader, sizeof(SP_PROPCHANGE_PARAMS))) { SetupDiCallClassInstaller( DIF_PROPERTYCHANGE, DeviceInfoSet, DevInfoData); } SetLastError(LastErr); }
/* try config-specific */ pcp.StateChange = (bEnable ? DICS_ENABLE : DICS_DISABLE); pcp.Scope = DICS_FLAG_CONFIGSPECIFIC;
if (SetupDiSetClassInstallParams( DeviceInfoSet, DevInfoData, &pcp.ClassInstallHeader, sizeof(SP_PROPCHANGE_PARAMS)) && SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, DeviceInfoSet, DevInfoData)) { dp.cbSize = sizeof(SP_DEVINSTALL_PARAMS); if (SetupDiGetDeviceInstallParams( DeviceInfoSet, DevInfoData, &dp)) { if (bNeedReboot != NULL) { *bNeedReboot = ((dp.Flags & (DI_NEEDRESTART | DI_NEEDREBOOT)) != 0); }
Ret = TRUE; } } return Ret;}
static DWORD WINAPIFindDriverProc( IN LPVOID lpParam){ PDEVINSTDATA DevInstData; BOOL result = FALSE;
DevInstData = (PDEVINSTDATA)lpParam;
result = ScanFoldersForDriver(DevInstData);
if (result) { PostMessage(DevInstData->hDialog, WM_SEARCH_FINISHED, 1, 0); } else { if (!DevInstData->bUpdate) { /* Update device configuration */ SetFailedInstall(DevInstData->hDevInfo, &DevInstData->devInfoData, TRUE); } PostMessage(DevInstData->hDialog, WM_SEARCH_FINISHED, 0, 0); } return 0;}
static DWORD WINAPIInstallDriverProc( IN LPVOID lpParam){ PDEVINSTDATA DevInstData; BOOL res;
DevInstData = (PDEVINSTDATA)lpParam; res = InstallCurrentDriver(DevInstData); PostMessage(DevInstData->hDialog, WM_INSTALL_FINISHED, res ? 0 : 1, 0); return 0;}
static VOIDPopulateCustomPathCombo( IN HWND hwndCombo){ HKEY hKey = NULL; DWORD dwRegType; DWORD dwPathLength = 0; LPWSTR Buffer = NULL; LPCWSTR Path; LONG rc;
(void)ComboBox_ResetContent(hwndCombo);
/* RegGetValue would have been better... */ rc = RegOpenKeyEx( HKEY_LOCAL_MACHINE, REGSTR_PATH_SETUP REGSTR_KEY_SETUP, 0, KEY_QUERY_VALUE, &hKey); if (rc != ERROR_SUCCESS) { TRACE("RegOpenKeyEx() failed with error 0x%lx\n", rc); goto cleanup; } rc = RegQueryValueExW( hKey, L"Installation Sources", NULL, &dwRegType, NULL, &dwPathLength); if (rc != ERROR_SUCCESS || dwRegType != REG_MULTI_SZ) { TRACE("RegQueryValueEx() failed with error 0x%lx\n", rc); goto cleanup; }
/* Allocate enough space to add 2 NULL chars at the end of the string */ Buffer = HeapAlloc(GetProcessHeap(), 0, dwPathLength + 2 * sizeof(WCHAR)); if (!Buffer) { TRACE("HeapAlloc() failed\n"); goto cleanup; } rc = RegQueryValueExW( hKey, L"Installation Sources", NULL, NULL, (LPBYTE)Buffer, &dwPathLength); if (rc != ERROR_SUCCESS) { TRACE("RegQueryValueEx() failed with error 0x%lx\n", rc); goto cleanup; }
Buffer[dwPathLength / sizeof(WCHAR)] = UNICODE_NULL; Buffer[dwPathLength / sizeof(WCHAR) + 1] = UNICODE_NULL;
/* Populate combo box */ for (Path = Buffer; *Path; Path += wcslen(Path) + 1) { (void)ComboBox_AddString(hwndCombo, Path); if (Path == Buffer) (void)ComboBox_SetCurSel(hwndCombo, 0); }
cleanup: if (hKey != NULL) RegCloseKey(hKey); HeapFree(GetProcessHeap(), 0, Buffer);}
static VOIDSaveCustomPath( IN HWND hwndCombo){ LPWSTR CustomPath = NULL; DWORD CustomPathLength; LPWSTR Buffer = NULL; LPWSTR pBuffer; /* Pointer into Buffer */ int ItemsCount, Length; int i; DWORD TotalLength = 0; BOOL UseCustomPath = TRUE; HKEY hKey = NULL; LONG rc;
/* Get custom path */ Length = ComboBox_GetTextLength(hwndCombo) + 1; CustomPath = HeapAlloc(GetProcessHeap(), 0, Length * sizeof(WCHAR)); if (!CustomPath) { TRACE("HeapAlloc() failed\n"); goto cleanup; } CustomPathLength = GetWindowTextW(hwndCombo, CustomPath, Length) + 1;
/* Calculate length of the buffer */ ItemsCount = ComboBox_GetCount(hwndCombo); if (ItemsCount == CB_ERR) { TRACE("ComboBox_GetCount() failed\n"); goto cleanup; } for (i = 0; i < ItemsCount; i++) { Length = ComboBox_GetLBTextLen(hwndCombo, i); if (Length == CB_ERR) { TRACE("ComboBox_GetLBTextLen() failed\n"); goto cleanup; } TotalLength += Length + 1; } TotalLength++; /* Final NULL char */
/* Allocate buffer */ Buffer = HeapAlloc(GetProcessHeap(), 0, (CustomPathLength + TotalLength + 1) * sizeof(WCHAR)); if (!Buffer) { TRACE("HeapAlloc() failed\n"); goto cleanup; }
/* Fill the buffer */ pBuffer = &Buffer[CustomPathLength]; for (i = 0; i < ItemsCount; i++) { Length = ComboBox_GetLBText(hwndCombo, i, pBuffer); if (Length == CB_ERR) { TRACE("ComboBox_GetLBText() failed\n"); goto cleanup; } else if (UseCustomPath && _wcsicmp(CustomPath, pBuffer) == 0) UseCustomPath = FALSE; pBuffer += 1 + Length; } *pBuffer = '\0'; /* Add final NULL char */
if (!UseCustomPath) { /* Nothing to save to registry */ goto cleanup; }
TotalLength += CustomPathLength; wcscpy(Buffer, CustomPath);
/* Save the buffer */ /* RegSetKeyValue would have been better... */ rc = RegOpenKeyEx( HKEY_LOCAL_MACHINE, REGSTR_PATH_SETUP REGSTR_KEY_SETUP, 0, KEY_SET_VALUE, &hKey); if (rc != ERROR_SUCCESS) { TRACE("RegOpenKeyEx() failed with error 0x%lx\n", rc); goto cleanup; } rc = RegSetValueExW( hKey, L"Installation Sources", 0, REG_MULTI_SZ, (const BYTE*)Buffer, TotalLength * sizeof(WCHAR)); if (rc != ERROR_SUCCESS) { TRACE("RegSetValueEx() failed with error 0x%lx\n", rc); goto cleanup; }
cleanup: if (hKey != NULL) RegCloseKey(hKey); HeapFree(GetProcessHeap(), 0, CustomPath); HeapFree(GetProcessHeap(), 0, Buffer);}
static INT_PTR CALLBACKWelcomeDlgProc( IN HWND hwndDlg, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam){ PDEVINSTDATA DevInstData; UNREFERENCED_PARAMETER(wParam);
/* Retrieve pointer to the global setup data */ DevInstData = (PDEVINSTDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
switch (uMsg) { case WM_INITDIALOG: { HWND hwndControl; DWORD dwStyle;
/* Get pointer to the global setup data */ DevInstData = (PDEVINSTDATA)((LPPROPSHEETPAGE)lParam)->lParam; SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)DevInstData);
hwndControl = GetParent(hwndDlg);
/* Center the wizard window */ CenterWindow(hwndControl);
/* Hide the system menu */ dwStyle = GetWindowLongPtr(hwndControl, GWL_STYLE); SetWindowLongPtr(hwndControl, GWL_STYLE, dwStyle & ~WS_SYSMENU);
/* Set title font */ SendDlgItemMessage( hwndDlg, IDC_WELCOMETITLE, WM_SETFONT, (WPARAM)DevInstData->hTitleFont, (LPARAM)TRUE);
SendDlgItemMessage( hwndDlg, IDC_DEVICE, WM_SETTEXT, 0, (LPARAM)DevInstData->buffer);
SendDlgItemMessage( hwndDlg, IDC_RADIO_AUTO, BM_SETCHECK, (WPARAM)TRUE, (LPARAM)0);
if (!DevInstData->bUpdate) { SetFailedInstall(DevInstData->hDevInfo, &DevInstData->devInfoData, TRUE); } break; }
case WM_NOTIFY: { LPNMHDR lpnm = (LPNMHDR)lParam;
switch (lpnm->code) { case PSN_SETACTIVE: /* Enable the Next button */ PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT); break;
case PSN_WIZNEXT: /* Handle a Next button click, if necessary */ if (SendDlgItemMessage(hwndDlg, IDC_RADIO_AUTO, BM_GETCHECK, (WPARAM)0, (LPARAM)0) == BST_CHECKED) { if (PrepareFoldersToScan(DevInstData, TRUE, FALSE, NULL)) SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_SEARCHDRV); else SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_INSTALLFAILED); } return TRUE;
default: break; } break; }
default: break; }
return FALSE;}
static voidIncludePath(HWND Dlg, BOOL Enabled){ EnableWindow(GetDlgItem(Dlg, IDC_COMBO_PATH), Enabled); EnableWindow(GetDlgItem(Dlg, IDC_BROWSE), Enabled);}
static voidAutoDriver(HWND Dlg, BOOL Enabled){ EnableWindow(GetDlgItem(Dlg, IDC_CHECK_MEDIA), Enabled); EnableWindow(GetDlgItem(Dlg, IDC_CHECK_PATH), Enabled); IncludePath(Dlg, Enabled & IsDlgButtonChecked(Dlg, IDC_CHECK_PATH));}
static INT CALLBACKBrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData){ BOOL bValid = FALSE;
switch (uMsg) { case BFFM_INITIALIZED: { PCWSTR pszPath = ((PDEVINSTDATA)lpData)->CustomSearchPath;
bValid = CheckBestDriver((PDEVINSTDATA)lpData, pszPath); SendMessageW(hwnd, BFFM_SETSELECTION, TRUE, (LPARAM)pszPath); SendMessageW(hwnd, BFFM_ENABLEOK, 0, bValid); break; }
case BFFM_SELCHANGED: { WCHAR szDir[MAX_PATH];
if (SHGetPathFromIDListW((LPITEMIDLIST)lParam, szDir)) { bValid = CheckBestDriver((PDEVINSTDATA)lpData, szDir); } PostMessageW(hwnd, BFFM_ENABLEOK, 0, bValid); break; } } return 0;}
static INT_PTR CALLBACKCHSourceDlgProc( IN HWND hwndDlg, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam){ PDEVINSTDATA DevInstData;
/* Retrieve pointer to the global setup data */ DevInstData = (PDEVINSTDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
switch (uMsg) { case WM_INITDIALOG: { HWND hwndControl, hwndCombo; DWORD dwStyle; COMBOBOXINFO info = { sizeof(info) };
/* Get pointer to the global setup data */ DevInstData = (PDEVINSTDATA)((LPPROPSHEETPAGE)lParam)->lParam; SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)DevInstData);
hwndControl = GetParent(hwndDlg);
/* Center the wizard window */ CenterWindow(hwndControl);
/* Hide the system menu */ dwStyle = GetWindowLongPtr(hwndControl, GWL_STYLE); SetWindowLongPtr(hwndControl, GWL_STYLE, dwStyle & ~WS_SYSMENU);
hwndCombo = GetDlgItem(hwndDlg, IDC_COMBO_PATH); PopulateCustomPathCombo(hwndCombo);
GetComboBoxInfo(hwndCombo, &info); SHAutoComplete(info.hwndItem, SHACF_FILESYS_DIRS);
SendDlgItemMessage( hwndDlg, IDC_RADIO_SEARCHHERE, BM_SETCHECK, (WPARAM)TRUE, (LPARAM)0); AutoDriver(hwndDlg, TRUE); IncludePath(hwndDlg, FALSE);
/* Disable manual driver choice for now */ EnableWindow(GetDlgItem(hwndDlg, IDC_RADIO_CHOOSE), FALSE);
break; }
case WM_COMMAND: { switch (LOWORD(wParam)) { case IDC_RADIO_SEARCHHERE: AutoDriver(hwndDlg, TRUE); return TRUE;
case IDC_RADIO_CHOOSE: AutoDriver(hwndDlg, FALSE); return TRUE;
case IDC_CHECK_PATH: IncludePath(hwndDlg, IsDlgButtonChecked(hwndDlg, IDC_CHECK_PATH)); return TRUE;
case IDC_BROWSE: { BROWSEINFOW bi = { 0 }; LPITEMIDLIST pidl = NULL; WCHAR Title[MAX_PATH]; LoadStringW(hDllInstance, IDS_BROWSE_FOR_FOLDER_TITLE, Title, _countof(Title));
if (PrepareFoldersToScan(DevInstData, FALSE, TRUE, GetDlgItem(hwndDlg, IDC_COMBO_PATH))) { bi.hwndOwner = hwndDlg; bi.ulFlags = BIF_USENEWUI | BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT | BIF_NONEWFOLDERBUTTON; bi.lpszTitle = Title; bi.lpfn = BrowseCallbackProc; bi.lParam = (LPARAM)DevInstData; pidl = SHBrowseForFolderW(&bi); }
if (pidl) { WCHAR Directory[MAX_PATH]; IMalloc* malloc;
if (SHGetPathFromIDListW(pidl, Directory)) { /* Remove previous item selection */ SendDlgItemMessageW(hwndDlg, IDC_COMBO_PATH, CB_SETCURSEL, -1, 0);
/* Set the IDC_COMBO_PATH text */ SetWindowTextW(GetDlgItem(hwndDlg, IDC_COMBO_PATH), Directory); }
/* Free memory, if possible */ if (SUCCEEDED(SHGetMalloc(&malloc))) { IMalloc_Free(malloc, pidl); IMalloc_Release(malloc); } return TRUE; } break; } } break; }
case WM_NOTIFY: { LPNMHDR lpnm = (LPNMHDR)lParam;
switch (lpnm->code) { case PSN_SETACTIVE: /* Enable the Next and Back buttons */ PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT | PSWIZB_BACK); break;
case PSN_WIZNEXT: /* Handle a Next button click, if necessary */ if (IsDlgButtonChecked(hwndDlg, IDC_RADIO_SEARCHHERE)) { SaveCustomPath(GetDlgItem(hwndDlg, IDC_COMBO_PATH)); HeapFree(GetProcessHeap(), 0, DevInstData->CustomSearchPath); DevInstData->CustomSearchPath = NULL; if (PrepareFoldersToScan( DevInstData, IsDlgButtonChecked(hwndDlg, IDC_CHECK_MEDIA), IsDlgButtonChecked(hwndDlg, IDC_CHECK_PATH), GetDlgItem(hwndDlg, IDC_COMBO_PATH))) { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_SEARCHDRV); } else { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_INSTALLFAILED); } } else { /* FIXME */; } return TRUE;
default: break; } break; }
default: break; }
return FALSE;}
static INT_PTR CALLBACKSearchDrvDlgProc( IN HWND hwndDlg, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam){ PDEVINSTDATA DevInstData; DWORD dwThreadId;
/* Retrieve pointer to the global setup data */ DevInstData = (PDEVINSTDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
switch (uMsg) { case WM_INITDIALOG: { HWND hwndControl; DWORD dwStyle;
/* Get pointer to the global setup data */ DevInstData = (PDEVINSTDATA)((LPPROPSHEETPAGE)lParam)->lParam; SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)DevInstData);
DevInstData->hDialog = hwndDlg; hwndControl = GetParent(hwndDlg);
/* Center the wizard window */ CenterWindow(hwndControl);
SendDlgItemMessage( hwndDlg, IDC_DEVICE, WM_SETTEXT, 0, (LPARAM)DevInstData->buffer);
/* Hide the system menu */ dwStyle = GetWindowLongPtr(hwndControl, GWL_STYLE); SetWindowLongPtr(hwndControl, GWL_STYLE, dwStyle & ~WS_SYSMENU); break; }
case WM_SEARCH_FINISHED: { CloseHandle(hThread); hThread = 0; if (wParam == 0) PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_NODRIVER); else PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_INSTALLDRV); break; }
case WM_NOTIFY: { LPNMHDR lpnm = (LPNMHDR)lParam;
switch (lpnm->code) { case PSN_SETACTIVE: PropSheet_SetWizButtons(GetParent(hwndDlg), !PSWIZB_NEXT | !PSWIZB_BACK); /* Yes, we can safely ignore the problem (if any) */ SetupDiDestroyDriverInfoList( DevInstData->hDevInfo, &DevInstData->devInfoData, SPDIT_COMPATDRIVER); hThread = CreateThread(NULL, 0, FindDriverProc, DevInstData, 0, &dwThreadId); break;
case PSN_KILLACTIVE: if (hThread != 0) { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE); return TRUE; } break;
case PSN_WIZNEXT: /* Handle a Next button click, if necessary */ break;
default: break; } break; }
default: break; }
return FALSE;}
static INT_PTR CALLBACKInstallDrvDlgProc( IN HWND hwndDlg, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam){ PDEVINSTDATA DevInstData; DWORD dwThreadId;
/* Retrieve pointer to the global setup data */ DevInstData = (PDEVINSTDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
switch (uMsg) { case WM_INITDIALOG: { HWND hwndControl; DWORD dwStyle;
/* Get pointer to the global setup data */ DevInstData = (PDEVINSTDATA)((LPPROPSHEETPAGE)lParam)->lParam; SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)DevInstData);
DevInstData->hDialog = hwndDlg; hwndControl = GetParent(hwndDlg);
/* Center the wizard window */ CenterWindow(hwndControl);
SendDlgItemMessage( hwndDlg, IDC_DEVICE, WM_SETTEXT, 0, (LPARAM)DevInstData->drvInfoData.Description);
/* Hide the system menu */ dwStyle = GetWindowLongPtr(hwndControl, GWL_STYLE); SetWindowLongPtr(hwndControl, GWL_STYLE, dwStyle & ~WS_SYSMENU); break; }
case WM_INSTALL_FINISHED: { CloseHandle(hThread); hThread = 0; if (wParam == 0) { SP_DEVINSTALL_PARAMS installParams;
SetFailedInstall(DevInstData->hDevInfo, &DevInstData->devInfoData, FALSE);
/* Should we reboot? */ installParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS); if (SetupDiGetDeviceInstallParams( DevInstData->hDevInfo, &DevInstData->devInfoData, &installParams)) { if (installParams.Flags & (DI_NEEDRESTART | DI_NEEDREBOOT)) { PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_NEEDREBOOT); } else PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_FINISHPAGE); break; } } PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_INSTALLFAILED); break; }
case WM_NOTIFY: { LPNMHDR lpnm = (LPNMHDR)lParam;
switch (lpnm->code) { case PSN_SETACTIVE: PropSheet_SetWizButtons(GetParent(hwndDlg), !PSWIZB_NEXT | !PSWIZB_BACK); hThread = CreateThread(NULL, 0, InstallDriverProc, DevInstData, 0, &dwThreadId); break;
case PSN_KILLACTIVE: if (hThread != 0) { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE); return TRUE; } break;
case PSN_WIZNEXT: /* Handle a Next button click, if necessary */ break;
default: break; } break; }
default: break; }
return FALSE;}
static INT_PTR CALLBACKNoDriverDlgProc( IN HWND hwndDlg, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam){ PDEVINSTDATA DevInstData; HWND hwndControl;
UNREFERENCED_PARAMETER(wParam);
/* Get pointer to the global setup data */ DevInstData = (PDEVINSTDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
switch (uMsg) { case WM_INITDIALOG: { BOOL DisableableDevice = FALSE;
/* Get pointer to the global setup data */ DevInstData = (PDEVINSTDATA)((LPPROPSHEETPAGE)lParam)->lParam; SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)DevInstData);
/* Center the wizard window */ CenterWindow(GetParent(hwndDlg));
hwndControl = GetDlgItem(GetParent(hwndDlg), IDCANCEL); ShowWindow(hwndControl, SW_HIDE); EnableWindow(hwndControl, FALSE);
/* Set title font */ SendDlgItemMessage( hwndDlg, IDC_FINISHTITLE, WM_SETFONT, (WPARAM)DevInstData->hTitleFont, (LPARAM)TRUE);
/* disable the "do not show this dialog anymore" checkbox if the device cannot be disabled */ CanDisableDevice( DevInstData->devInfoData.DevInst, NULL, &DisableableDevice); EnableWindow( GetDlgItem(hwndDlg, IDC_DONOTSHOWDLG), DisableableDevice); break; }
case WM_NOTIFY: { LPNMHDR lpnm = (LPNMHDR)lParam;
switch (lpnm->code) { case PSN_SETACTIVE: /* Enable the correct buttons on for the active page */ PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_FINISH); break;
case PSN_WIZBACK: /* Handle a Back button click, if necessary */ hwndControl = GetDlgItem(GetParent(hwndDlg), IDCANCEL); ShowWindow(hwndControl, SW_SHOW); EnableWindow(hwndControl, TRUE); SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_CHSOURCE); return TRUE;
case PSN_WIZFINISH: { BOOL DisableableDevice = FALSE; BOOL IsStarted = FALSE;
if (CanDisableDevice(DevInstData->devInfoData.DevInst, NULL, &DisableableDevice) && DisableableDevice && IsDeviceStarted( DevInstData->devInfoData.DevInst, NULL, &IsStarted) && !IsStarted && SendDlgItemMessage( hwndDlg, IDC_DONOTSHOWDLG, BM_GETCHECK, (WPARAM)0, (LPARAM)0) == BST_CHECKED) { /* disable the device */ StartDevice( DevInstData->hDevInfo, &DevInstData->devInfoData, FALSE, 0, NULL); } else { SetFailedInstall(DevInstData->hDevInfo, &DevInstData->devInfoData, FALSE); } break; }
default: break; } break; }
default: break; }
return FALSE;}
static INT_PTR CALLBACKInstallFailedDlgProc( IN HWND hwndDlg, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam){ PDEVINSTDATA DevInstData; UNREFERENCED_PARAMETER(wParam);
/* Retrieve pointer to the global setup data */ DevInstData = (PDEVINSTDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
switch (uMsg) { case WM_INITDIALOG: { HWND hwndControl;
/* Get pointer to the global setup data */ DevInstData = (PDEVINSTDATA)((LPPROPSHEETPAGE)lParam)->lParam; SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)DevInstData);
/* Center the wizard window */ CenterWindow(GetParent(hwndDlg));
hwndControl = GetDlgItem(GetParent(hwndDlg), IDCANCEL); ShowWindow(hwndControl, SW_HIDE); EnableWindow(hwndControl, FALSE);
SendDlgItemMessage( hwndDlg, IDC_DEVICE, WM_SETTEXT, 0, (LPARAM)DevInstData->drvInfoData.Description);
/* Set title font */ SendDlgItemMessage( hwndDlg, IDC_FINISHTITLE, WM_SETFONT, (WPARAM)DevInstData->hTitleFont, (LPARAM)TRUE); break; }
case WM_NOTIFY: { LPNMHDR lpnm = (LPNMHDR)lParam;
switch (lpnm->code) { case PSN_SETACTIVE: /* Enable the correct buttons on for the active page */ PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_FINISH); break;
case PSN_WIZBACK: /* Handle a Back button click, if necessary */ break;
case PSN_WIZFINISH: /* Handle a Finish button click, if necessary */ break;
default: break; } break; }
default: break; }
return FALSE;}
static INT_PTR CALLBACKNeedRebootDlgProc( IN HWND hwndDlg, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam){ PDEVINSTDATA DevInstData; UNREFERENCED_PARAMETER(wParam);
/* Retrieve pointer to the global setup data */ DevInstData = (PDEVINSTDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
switch (uMsg) { case WM_INITDIALOG: { HWND hwndControl;
/* Get pointer to the global setup data */ DevInstData = (PDEVINSTDATA)((LPPROPSHEETPAGE)lParam)->lParam; SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)DevInstData);
/* Center the wizard window */ CenterWindow(GetParent(hwndDlg));
hwndControl = GetDlgItem(GetParent(hwndDlg), IDCANCEL); ShowWindow(hwndControl, SW_HIDE); EnableWindow(hwndControl, FALSE);
SendDlgItemMessage( hwndDlg, IDC_DEVICE, WM_SETTEXT, 0, (LPARAM)DevInstData->drvInfoData.Description);
/* Set title font */ SendDlgItemMessage( hwndDlg, IDC_FINISHTITLE, WM_SETFONT, (WPARAM)DevInstData->hTitleFont, (LPARAM)TRUE); break; }
case WM_NOTIFY: { LPNMHDR lpnm = (LPNMHDR)lParam;
switch (lpnm->code) { case PSN_SETACTIVE: /* Enable the correct buttons on for the active page */ PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_FINISH); break;
case PSN_WIZBACK: /* Handle a Back button click, if necessary */ break;
case PSN_WIZFINISH: /* Handle a Finish button click, if necessary */ break;
default: break; } break; }
default: break; }
return FALSE;}
static INT_PTR CALLBACKFinishDlgProc( IN HWND hwndDlg, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam){ PDEVINSTDATA DevInstData; UNREFERENCED_PARAMETER(wParam);
/* Retrieve pointer to the global setup data */ DevInstData = (PDEVINSTDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
switch (uMsg) { case WM_INITDIALOG: { HWND hwndControl;
/* Get pointer to the global setup data */ DevInstData = (PDEVINSTDATA)((LPPROPSHEETPAGE)lParam)->lParam; SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)DevInstData);
/* Center the wizard window */ CenterWindow(GetParent(hwndDlg));
hwndControl = GetDlgItem(GetParent(hwndDlg), IDCANCEL); ShowWindow(hwndControl, SW_HIDE); EnableWindow(hwndControl, FALSE);
SendDlgItemMessage( hwndDlg, IDC_DEVICE, WM_SETTEXT, 0, (LPARAM)DevInstData->drvInfoData.Description);
/* Set title font */ SendDlgItemMessage( hwndDlg, IDC_FINISHTITLE, WM_SETFONT, (WPARAM)DevInstData->hTitleFont, (LPARAM)TRUE); break; }
case WM_NOTIFY: { LPNMHDR lpnm = (LPNMHDR)lParam;
switch (lpnm->code) { case PSN_SETACTIVE: /* Enable the correct buttons on for the active page */ PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_FINISH); break;
case PSN_WIZBACK: /* Handle a Back button click, if necessary */ break;
case PSN_WIZFINISH: /* Handle a Finish button click, if necessary */ break;
default: break; } break; }
default: break; }
return FALSE;}
static HFONTCreateTitleFont(VOID){ NONCLIENTMETRICSW ncm; LOGFONTW LogFont; HDC hdc; INT FontSize; HFONT hFont;
ncm.cbSize = sizeof(NONCLIENTMETRICSW); SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
LogFont = ncm.lfMessageFont; LogFont.lfWeight = FW_BOLD; wcscpy(LogFont.lfFaceName, L"MS Shell Dlg");
hdc = GetDC(NULL); FontSize = 12; LogFont.lfHeight = 0 - GetDeviceCaps (hdc, LOGPIXELSY) * FontSize / 72; hFont = CreateFontIndirectW(&LogFont); ReleaseDC(NULL, hdc);
return hFont;}
BOOLDisplayWizard( IN PDEVINSTDATA DevInstData, IN HWND hwndParent, IN UINT startPage){ PROPSHEETHEADER psh = {0}; HPROPSHEETPAGE ahpsp[IDD_MAXIMUMPAGE + 1]; PROPSHEETPAGE psp = {0}; HRESULT hr = CoInitialize(NULL); /* for SHAutoComplete */
/* zero based index */ startPage -= IDD_FIRSTPAGE;
/* Create the Welcome page */ ZeroMemory(&psp, sizeof(PROPSHEETPAGE)); psp.dwSize = sizeof(PROPSHEETPAGE); psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER | PSP_USETITLE; psp.hInstance = hDllInstance; psp.lParam = (LPARAM)DevInstData; psp.pszTitle = MAKEINTRESOURCE(DevInstData->bUpdate ? IDS_UPDATEWIZARDTITLE : IDS_INSTALLWIZARDTITLE); psp.pfnDlgProc = WelcomeDlgProc; psp.pszTemplate = MAKEINTRESOURCE(IDD_WELCOMEPAGE); ahpsp[IDD_WELCOMEPAGE-IDD_FIRSTPAGE] = CreatePropertySheetPage(&psp);
/* Create the Select Source page */ psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USETITLE; psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_CHSOURCE_TITLE); psp.pfnDlgProc = CHSourceDlgProc; psp.pszTemplate = MAKEINTRESOURCE(IDD_CHSOURCE); ahpsp[IDD_CHSOURCE-IDD_FIRSTPAGE] = CreatePropertySheetPage(&psp);
/* Create the Search driver page */ psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USETITLE; psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_SEARCHDRV_TITLE); psp.pfnDlgProc = SearchDrvDlgProc; psp.pszTemplate = MAKEINTRESOURCE(IDD_SEARCHDRV); ahpsp[IDD_SEARCHDRV-IDD_FIRSTPAGE] = CreatePropertySheetPage(&psp);
/* Create the Install driver page */ psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USETITLE; psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_INSTALLDRV_TITLE); psp.pfnDlgProc = InstallDrvDlgProc; psp.pszTemplate = MAKEINTRESOURCE(IDD_INSTALLDRV); ahpsp[IDD_INSTALLDRV-IDD_FIRSTPAGE] = CreatePropertySheetPage(&psp);
/* Create the No driver page */ psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER | PSP_USETITLE; psp.pfnDlgProc = NoDriverDlgProc; psp.pszTemplate = MAKEINTRESOURCE(IDD_NODRIVER); ahpsp[IDD_NODRIVER-IDD_FIRSTPAGE] = CreatePropertySheetPage(&psp);
/* Create the Install failed page */ psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER | PSP_USETITLE; psp.pfnDlgProc = InstallFailedDlgProc; psp.pszTemplate = MAKEINTRESOURCE(IDD_INSTALLFAILED); ahpsp[IDD_INSTALLFAILED-IDD_FIRSTPAGE] = CreatePropertySheetPage(&psp);
/* Create the Need reboot page */ psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER | PSP_USETITLE; psp.pfnDlgProc = NeedRebootDlgProc; psp.pszTemplate = MAKEINTRESOURCE(IDD_NEEDREBOOT); ahpsp[IDD_NEEDREBOOT-IDD_FIRSTPAGE] = CreatePropertySheetPage(&psp);
/* Create the Finish page */ psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER | PSP_USETITLE; psp.pfnDlgProc = FinishDlgProc; psp.pszTemplate = MAKEINTRESOURCE(IDD_FINISHPAGE); ahpsp[IDD_FINISHPAGE-IDD_FIRSTPAGE] = CreatePropertySheetPage(&psp);
/* Create the property sheet */ psh.dwSize = sizeof(PROPSHEETHEADER); psh.dwFlags = PSH_WIZARD97 | PSH_WATERMARK | PSH_HEADER; psh.hInstance = hDllInstance; psh.hwndParent = hwndParent; psh.nPages = IDD_MAXIMUMPAGE + 1; psh.nStartPage = startPage; psh.phpage = ahpsp; psh.pszbmWatermark = MAKEINTRESOURCE(IDB_WATERMARK); psh.pszbmHeader = MAKEINTRESOURCE(IDB_HEADER);
/* Create title font */ DevInstData->hTitleFont = CreateTitleFont();
/* Display the wizard */ PropertySheet(&psh);
DeleteObject(DevInstData->hTitleFont);
if (SUCCEEDED(hr)) CoUninitialize(); return TRUE;}