1c2c66affSColin Finck /* 2c2c66affSColin Finck * New device installer (newdev.dll) 3c2c66affSColin Finck * 4c2c66affSColin Finck * Copyright 2006 Herv� Poussineau (hpoussin@reactos.org) 5c2c66affSColin Finck * 6c2c66affSColin Finck * This library is free software; you can redistribute it and/or 7c2c66affSColin Finck * modify it under the terms of the GNU Lesser General Public 8c2c66affSColin Finck * License as published by the Free Software Foundation; either 9c2c66affSColin Finck * version 2.1 of the License, or (at your option) any later version. 10c2c66affSColin Finck * 11c2c66affSColin Finck * This library is distributed in the hope that it will be useful, 12c2c66affSColin Finck * but WITHOUT ANY WARRANTY; without even the implied warranty of 13c2c66affSColin Finck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14c2c66affSColin Finck * Lesser General Public License for more details. 15c2c66affSColin Finck * 16c2c66affSColin Finck * You should have received a copy of the GNU Lesser General Public 17c2c66affSColin Finck * License along with this library; if not, write to the Free Software 18c2c66affSColin Finck * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19c2c66affSColin Finck */ 20c2c66affSColin Finck 21c2c66affSColin Finck #include "newdev_private.h" 22c2c66affSColin Finck 23c2c66affSColin Finck #include <wincon.h> 24c2c66affSColin Finck #include <cfgmgr32.h> 25c2c66affSColin Finck #include <shlobj.h> 2662b13979SKatayama Hirofumi MZ #include <shlwapi.h> 27c2c66affSColin Finck 28c2c66affSColin Finck HANDLE hThread; 29c2c66affSColin Finck 30c2c66affSColin Finck static VOID 31c2c66affSColin Finck CenterWindow( 32c2c66affSColin Finck IN HWND hWnd) 33c2c66affSColin Finck { 34c2c66affSColin Finck HWND hWndParent; 35c2c66affSColin Finck RECT rcParent; 36c2c66affSColin Finck RECT rcWindow; 37c2c66affSColin Finck 38c2c66affSColin Finck hWndParent = GetParent(hWnd); 39c2c66affSColin Finck if (hWndParent == NULL) 40c2c66affSColin Finck hWndParent = GetDesktopWindow(); 41c2c66affSColin Finck 42c2c66affSColin Finck GetWindowRect(hWndParent, &rcParent); 43c2c66affSColin Finck GetWindowRect(hWnd, &rcWindow); 44c2c66affSColin Finck 45c2c66affSColin Finck SetWindowPos( 46c2c66affSColin Finck hWnd, 47c2c66affSColin Finck HWND_TOP, 48c2c66affSColin Finck ((rcParent.right - rcParent.left) - (rcWindow.right - rcWindow.left)) / 2, 49c2c66affSColin Finck ((rcParent.bottom - rcParent.top) - (rcWindow.bottom - rcWindow.top)) / 2, 50c2c66affSColin Finck 0, 51c2c66affSColin Finck 0, 52c2c66affSColin Finck SWP_NOSIZE); 53c2c66affSColin Finck } 54c2c66affSColin Finck 55c2c66affSColin Finck static BOOL 56c2c66affSColin Finck SetFailedInstall( 57c2c66affSColin Finck IN HDEVINFO DeviceInfoSet, 58c2c66affSColin Finck IN PSP_DEVINFO_DATA DevInfoData OPTIONAL, 59c2c66affSColin Finck IN BOOLEAN Set) 60c2c66affSColin Finck { 61c2c66affSColin Finck DWORD dwType, dwSize, dwFlags = 0; 62c2c66affSColin Finck 63c2c66affSColin Finck dwSize = sizeof(dwFlags); 64c2c66affSColin Finck if (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet, 65c2c66affSColin Finck DevInfoData, 66c2c66affSColin Finck SPDRP_CONFIGFLAGS, 67c2c66affSColin Finck &dwType, 68c2c66affSColin Finck (PBYTE)&dwFlags, 69c2c66affSColin Finck dwSize, 70c2c66affSColin Finck &dwSize)) 71c2c66affSColin Finck { 72c2c66affSColin Finck return FALSE; 73c2c66affSColin Finck } 74c2c66affSColin Finck 75c2c66affSColin Finck if (Set) 76c2c66affSColin Finck dwFlags |= CONFIGFLAG_FAILEDINSTALL; 77c2c66affSColin Finck else 78c2c66affSColin Finck dwFlags &= ~CONFIGFLAG_FAILEDINSTALL; 79c2c66affSColin Finck 80c2c66affSColin Finck if (!SetupDiSetDeviceRegistryProperty(DeviceInfoSet, 81c2c66affSColin Finck DevInfoData, 82c2c66affSColin Finck SPDRP_CONFIGFLAGS, 83c2c66affSColin Finck (PBYTE)&dwFlags, 84c2c66affSColin Finck dwSize)) 85c2c66affSColin Finck { 86c2c66affSColin Finck 87c2c66affSColin Finck return FALSE; 88c2c66affSColin Finck } 89c2c66affSColin Finck 903fa57b8fSEric Kohl if (Set) 913fa57b8fSEric Kohl { 923fa57b8fSEric Kohl /* Set the 'Unknown' device class */ 933fa57b8fSEric Kohl PWSTR pszUnknown = L"Unknown"; 943fa57b8fSEric Kohl SetupDiSetDeviceRegistryPropertyW(DeviceInfoSet, 953fa57b8fSEric Kohl DevInfoData, 963fa57b8fSEric Kohl SPDRP_CLASS, 973fa57b8fSEric Kohl (PBYTE)pszUnknown, 983fa57b8fSEric Kohl (wcslen(pszUnknown) + 1) * sizeof(WCHAR)); 993fa57b8fSEric Kohl 1003fa57b8fSEric Kohl PWSTR pszUnknownGuid = L"{4D36E97E-E325-11CE-BFC1-08002BE10318}"; 1013fa57b8fSEric Kohl SetupDiSetDeviceRegistryPropertyW(DeviceInfoSet, 1023fa57b8fSEric Kohl DevInfoData, 1033fa57b8fSEric Kohl SPDRP_CLASSGUID, 1043fa57b8fSEric Kohl (PBYTE)pszUnknownGuid, 1053fa57b8fSEric Kohl (wcslen(pszUnknownGuid) + 1) * sizeof(WCHAR)); 1063fa57b8fSEric Kohl 107*32428a39SEric Kohl /* Set device problem code CM_PROB_FAILED_INSTALL */ 108*32428a39SEric Kohl CM_Set_DevNode_Problem(DevInfoData->DevInst, 109*32428a39SEric Kohl CM_PROB_FAILED_INSTALL, 110*32428a39SEric Kohl CM_SET_DEVNODE_PROBLEM_OVERRIDE); 1113fa57b8fSEric Kohl } 1123fa57b8fSEric Kohl 113c2c66affSColin Finck return TRUE; 114c2c66affSColin Finck } 115c2c66affSColin Finck 116c2c66affSColin Finck static BOOL 117c2c66affSColin Finck CanDisableDevice( 118c2c66affSColin Finck IN DEVINST DevInst, 119c2c66affSColin Finck IN HMACHINE hMachine, 120c2c66affSColin Finck OUT BOOL *CanDisable) 121c2c66affSColin Finck { 122c2c66affSColin Finck CONFIGRET cr; 123c2c66affSColin Finck ULONG Status, ProblemNumber; 124c2c66affSColin Finck BOOL Ret = FALSE; 125c2c66affSColin Finck 126c2c66affSColin Finck cr = CM_Get_DevNode_Status_Ex(&Status, 127c2c66affSColin Finck &ProblemNumber, 128c2c66affSColin Finck DevInst, 129c2c66affSColin Finck 0, 130c2c66affSColin Finck hMachine); 131c2c66affSColin Finck if (cr == CR_SUCCESS) 132c2c66affSColin Finck { 133c2c66affSColin Finck *CanDisable = ((Status & DN_DISABLEABLE) != 0); 134c2c66affSColin Finck Ret = TRUE; 135c2c66affSColin Finck } 136c2c66affSColin Finck 137c2c66affSColin Finck return Ret; 138c2c66affSColin Finck } 139c2c66affSColin Finck 140c2c66affSColin Finck static BOOL 141c2c66affSColin Finck IsDeviceStarted( 142c2c66affSColin Finck IN DEVINST DevInst, 143c2c66affSColin Finck IN HMACHINE hMachine, 144c2c66affSColin Finck OUT BOOL *IsEnabled) 145c2c66affSColin Finck { 146c2c66affSColin Finck CONFIGRET cr; 147c2c66affSColin Finck ULONG Status, ProblemNumber; 148c2c66affSColin Finck BOOL Ret = FALSE; 149c2c66affSColin Finck 150c2c66affSColin Finck cr = CM_Get_DevNode_Status_Ex( 151c2c66affSColin Finck &Status, 152c2c66affSColin Finck &ProblemNumber, 153c2c66affSColin Finck DevInst, 154c2c66affSColin Finck 0, 155c2c66affSColin Finck hMachine); 156c2c66affSColin Finck if (cr == CR_SUCCESS) 157c2c66affSColin Finck { 158c2c66affSColin Finck *IsEnabled = ((Status & DN_STARTED) != 0); 159c2c66affSColin Finck Ret = TRUE; 160c2c66affSColin Finck } 161c2c66affSColin Finck 162c2c66affSColin Finck return Ret; 163c2c66affSColin Finck } 164c2c66affSColin Finck 165c2c66affSColin Finck static BOOL 166c2c66affSColin Finck StartDevice( 167c2c66affSColin Finck IN HDEVINFO DeviceInfoSet, 168c2c66affSColin Finck IN PSP_DEVINFO_DATA DevInfoData OPTIONAL, 169c2c66affSColin Finck IN BOOL bEnable, 170c2c66affSColin Finck IN DWORD HardwareProfile OPTIONAL, 171c2c66affSColin Finck OUT BOOL *bNeedReboot OPTIONAL) 172c2c66affSColin Finck { 173c2c66affSColin Finck SP_PROPCHANGE_PARAMS pcp; 174c2c66affSColin Finck SP_DEVINSTALL_PARAMS dp; 175c2c66affSColin Finck DWORD LastErr; 176c2c66affSColin Finck BOOL Ret = FALSE; 177c2c66affSColin Finck 178c2c66affSColin Finck pcp.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER); 179c2c66affSColin Finck pcp.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE; 180c2c66affSColin Finck pcp.HwProfile = HardwareProfile; 181c2c66affSColin Finck 182c2c66affSColin Finck if (bEnable) 183c2c66affSColin Finck { 184c2c66affSColin Finck /* try to enable the device on the global profile */ 185c2c66affSColin Finck pcp.StateChange = DICS_ENABLE; 186c2c66affSColin Finck pcp.Scope = DICS_FLAG_GLOBAL; 187c2c66affSColin Finck 188c2c66affSColin Finck /* ignore errors */ 189c2c66affSColin Finck LastErr = GetLastError(); 190c2c66affSColin Finck if (SetupDiSetClassInstallParams( 191c2c66affSColin Finck DeviceInfoSet, 192c2c66affSColin Finck DevInfoData, 193c2c66affSColin Finck &pcp.ClassInstallHeader, 194c2c66affSColin Finck sizeof(SP_PROPCHANGE_PARAMS))) 195c2c66affSColin Finck { 196c2c66affSColin Finck SetupDiCallClassInstaller( 197c2c66affSColin Finck DIF_PROPERTYCHANGE, 198c2c66affSColin Finck DeviceInfoSet, 199c2c66affSColin Finck DevInfoData); 200c2c66affSColin Finck } 201c2c66affSColin Finck SetLastError(LastErr); 202c2c66affSColin Finck } 203c2c66affSColin Finck 204c2c66affSColin Finck /* try config-specific */ 205c2c66affSColin Finck pcp.StateChange = (bEnable ? DICS_ENABLE : DICS_DISABLE); 206c2c66affSColin Finck pcp.Scope = DICS_FLAG_CONFIGSPECIFIC; 207c2c66affSColin Finck 208c2c66affSColin Finck if (SetupDiSetClassInstallParams( 209c2c66affSColin Finck DeviceInfoSet, 210c2c66affSColin Finck DevInfoData, 211c2c66affSColin Finck &pcp.ClassInstallHeader, 212c2c66affSColin Finck sizeof(SP_PROPCHANGE_PARAMS)) && 213c2c66affSColin Finck SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, 214c2c66affSColin Finck DeviceInfoSet, 215c2c66affSColin Finck DevInfoData)) 216c2c66affSColin Finck { 217c2c66affSColin Finck dp.cbSize = sizeof(SP_DEVINSTALL_PARAMS); 218c2c66affSColin Finck if (SetupDiGetDeviceInstallParams( 219c2c66affSColin Finck DeviceInfoSet, 220c2c66affSColin Finck DevInfoData, 221c2c66affSColin Finck &dp)) 222c2c66affSColin Finck { 223c2c66affSColin Finck if (bNeedReboot != NULL) 224c2c66affSColin Finck { 225c2c66affSColin Finck *bNeedReboot = ((dp.Flags & (DI_NEEDRESTART | DI_NEEDREBOOT)) != 0); 226c2c66affSColin Finck } 227c2c66affSColin Finck 228c2c66affSColin Finck Ret = TRUE; 229c2c66affSColin Finck } 230c2c66affSColin Finck } 231c2c66affSColin Finck return Ret; 232c2c66affSColin Finck } 233c2c66affSColin Finck 234c2c66affSColin Finck static DWORD WINAPI 235c2c66affSColin Finck FindDriverProc( 236c2c66affSColin Finck IN LPVOID lpParam) 237c2c66affSColin Finck { 238c2c66affSColin Finck PDEVINSTDATA DevInstData; 239c2c66affSColin Finck BOOL result = FALSE; 240c2c66affSColin Finck 241c2c66affSColin Finck DevInstData = (PDEVINSTDATA)lpParam; 242c2c66affSColin Finck 243c2c66affSColin Finck result = ScanFoldersForDriver(DevInstData); 244c2c66affSColin Finck 245c2c66affSColin Finck if (result) 246c2c66affSColin Finck { 247c2c66affSColin Finck PostMessage(DevInstData->hDialog, WM_SEARCH_FINISHED, 1, 0); 248c2c66affSColin Finck } 249c2c66affSColin Finck else 250c2c66affSColin Finck { 251c2c66affSColin Finck /* Update device configuration */ 2523fa57b8fSEric Kohl SetFailedInstall(DevInstData->hDevInfo, 253c2c66affSColin Finck &DevInstData->devInfoData, 2543fa57b8fSEric Kohl TRUE); 255c2c66affSColin Finck 256c2c66affSColin Finck PostMessage(DevInstData->hDialog, WM_SEARCH_FINISHED, 0, 0); 257c2c66affSColin Finck } 258c2c66affSColin Finck return 0; 259c2c66affSColin Finck } 260c2c66affSColin Finck 261c2c66affSColin Finck static DWORD WINAPI 262c2c66affSColin Finck InstallDriverProc( 263c2c66affSColin Finck IN LPVOID lpParam) 264c2c66affSColin Finck { 265c2c66affSColin Finck PDEVINSTDATA DevInstData; 266c2c66affSColin Finck BOOL res; 267c2c66affSColin Finck 268c2c66affSColin Finck DevInstData = (PDEVINSTDATA)lpParam; 269c2c66affSColin Finck res = InstallCurrentDriver(DevInstData); 270c2c66affSColin Finck PostMessage(DevInstData->hDialog, WM_INSTALL_FINISHED, res ? 0 : 1, 0); 271c2c66affSColin Finck return 0; 272c2c66affSColin Finck } 273c2c66affSColin Finck 274c2c66affSColin Finck static VOID 275c2c66affSColin Finck PopulateCustomPathCombo( 276c2c66affSColin Finck IN HWND hwndCombo) 277c2c66affSColin Finck { 278c2c66affSColin Finck HKEY hKey = NULL; 279c2c66affSColin Finck DWORD dwRegType; 280c2c66affSColin Finck DWORD dwPathLength = 0; 281c2c66affSColin Finck LPWSTR Buffer = NULL; 282c2c66affSColin Finck LPCWSTR Path; 283c2c66affSColin Finck LONG rc; 284c2c66affSColin Finck 285c2c66affSColin Finck (void)ComboBox_ResetContent(hwndCombo); 286c2c66affSColin Finck 287c2c66affSColin Finck /* RegGetValue would have been better... */ 288c2c66affSColin Finck rc = RegOpenKeyEx( 289c2c66affSColin Finck HKEY_LOCAL_MACHINE, 290c2c66affSColin Finck REGSTR_PATH_SETUP REGSTR_KEY_SETUP, 291c2c66affSColin Finck 0, 292c2c66affSColin Finck KEY_QUERY_VALUE, 293c2c66affSColin Finck &hKey); 294c2c66affSColin Finck if (rc != ERROR_SUCCESS) 295c2c66affSColin Finck { 296c2c66affSColin Finck TRACE("RegOpenKeyEx() failed with error 0x%lx\n", rc); 297c2c66affSColin Finck goto cleanup; 298c2c66affSColin Finck } 299c2c66affSColin Finck rc = RegQueryValueExW( 300c2c66affSColin Finck hKey, 301c2c66affSColin Finck L"Installation Sources", 302c2c66affSColin Finck NULL, 303c2c66affSColin Finck &dwRegType, 304c2c66affSColin Finck NULL, 305c2c66affSColin Finck &dwPathLength); 306c2c66affSColin Finck if (rc != ERROR_SUCCESS || dwRegType != REG_MULTI_SZ) 307c2c66affSColin Finck { 308c2c66affSColin Finck TRACE("RegQueryValueEx() failed with error 0x%lx\n", rc); 309c2c66affSColin Finck goto cleanup; 310c2c66affSColin Finck } 311c2c66affSColin Finck 312c2c66affSColin Finck /* Allocate enough space to add 2 NULL chars at the end of the string */ 313c2c66affSColin Finck Buffer = HeapAlloc(GetProcessHeap(), 0, dwPathLength + 2 * sizeof(WCHAR)); 314c2c66affSColin Finck if (!Buffer) 315c2c66affSColin Finck { 316c2c66affSColin Finck TRACE("HeapAlloc() failed\n"); 317c2c66affSColin Finck goto cleanup; 318c2c66affSColin Finck } 319c2c66affSColin Finck rc = RegQueryValueExW( 320c2c66affSColin Finck hKey, 321c2c66affSColin Finck L"Installation Sources", 322c2c66affSColin Finck NULL, 323c2c66affSColin Finck NULL, 324c2c66affSColin Finck (LPBYTE)Buffer, 325c2c66affSColin Finck &dwPathLength); 326c2c66affSColin Finck if (rc != ERROR_SUCCESS) 327c2c66affSColin Finck { 328c2c66affSColin Finck TRACE("RegQueryValueEx() failed with error 0x%lx\n", rc); 329c2c66affSColin Finck goto cleanup; 330c2c66affSColin Finck } 331c2c66affSColin Finck 332c2c66affSColin Finck Buffer[dwPathLength / sizeof(WCHAR)] = UNICODE_NULL; 333c2c66affSColin Finck Buffer[dwPathLength / sizeof(WCHAR) + 1] = UNICODE_NULL; 334c2c66affSColin Finck 335c2c66affSColin Finck /* Populate combo box */ 336c2c66affSColin Finck for (Path = Buffer; *Path; Path += wcslen(Path) + 1) 337c2c66affSColin Finck { 338c2c66affSColin Finck (void)ComboBox_AddString(hwndCombo, Path); 339c2c66affSColin Finck if (Path == Buffer) 340c2c66affSColin Finck (void)ComboBox_SetCurSel(hwndCombo, 0); 341c2c66affSColin Finck } 342c2c66affSColin Finck 343c2c66affSColin Finck cleanup: 344c2c66affSColin Finck if (hKey != NULL) 345c2c66affSColin Finck RegCloseKey(hKey); 346c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, Buffer); 347c2c66affSColin Finck } 348c2c66affSColin Finck 349c2c66affSColin Finck static VOID 350c2c66affSColin Finck SaveCustomPath( 351c2c66affSColin Finck IN HWND hwndCombo) 352c2c66affSColin Finck { 353c2c66affSColin Finck LPWSTR CustomPath = NULL; 354c2c66affSColin Finck DWORD CustomPathLength; 355c2c66affSColin Finck LPWSTR Buffer = NULL; 356c2c66affSColin Finck LPWSTR pBuffer; /* Pointer into Buffer */ 357c2c66affSColin Finck int ItemsCount, Length; 358c2c66affSColin Finck int i; 359c2c66affSColin Finck DWORD TotalLength = 0; 360c2c66affSColin Finck BOOL UseCustomPath = TRUE; 361c2c66affSColin Finck HKEY hKey = NULL; 362c2c66affSColin Finck LONG rc; 363c2c66affSColin Finck 364c2c66affSColin Finck /* Get custom path */ 365c2c66affSColin Finck Length = ComboBox_GetTextLength(hwndCombo) + 1; 366c2c66affSColin Finck CustomPath = HeapAlloc(GetProcessHeap(), 0, Length * sizeof(WCHAR)); 367c2c66affSColin Finck if (!CustomPath) 368c2c66affSColin Finck { 369c2c66affSColin Finck TRACE("HeapAlloc() failed\n"); 370c2c66affSColin Finck goto cleanup; 371c2c66affSColin Finck } 372c2c66affSColin Finck CustomPathLength = GetWindowTextW(hwndCombo, CustomPath, Length) + 1; 373c2c66affSColin Finck 374c2c66affSColin Finck /* Calculate length of the buffer */ 375c2c66affSColin Finck ItemsCount = ComboBox_GetCount(hwndCombo); 376c2c66affSColin Finck if (ItemsCount == CB_ERR) 377c2c66affSColin Finck { 378c2c66affSColin Finck TRACE("ComboBox_GetCount() failed\n"); 379c2c66affSColin Finck goto cleanup; 380c2c66affSColin Finck } 381c2c66affSColin Finck for (i = 0; i < ItemsCount; i++) 382c2c66affSColin Finck { 383c2c66affSColin Finck Length = ComboBox_GetLBTextLen(hwndCombo, i); 384c2c66affSColin Finck if (Length == CB_ERR) 385c2c66affSColin Finck { 386c2c66affSColin Finck TRACE("ComboBox_GetLBTextLen() failed\n"); 387c2c66affSColin Finck goto cleanup; 388c2c66affSColin Finck } 389c2c66affSColin Finck TotalLength += Length + 1; 390c2c66affSColin Finck } 391c2c66affSColin Finck TotalLength++; /* Final NULL char */ 392c2c66affSColin Finck 393c2c66affSColin Finck /* Allocate buffer */ 394c2c66affSColin Finck Buffer = HeapAlloc(GetProcessHeap(), 0, (CustomPathLength + TotalLength + 1) * sizeof(WCHAR)); 395c2c66affSColin Finck if (!Buffer) 396c2c66affSColin Finck { 397c2c66affSColin Finck TRACE("HeapAlloc() failed\n"); 398c2c66affSColin Finck goto cleanup; 399c2c66affSColin Finck } 400c2c66affSColin Finck 401c2c66affSColin Finck /* Fill the buffer */ 402c2c66affSColin Finck pBuffer = &Buffer[CustomPathLength]; 403c2c66affSColin Finck for (i = 0; i < ItemsCount; i++) 404c2c66affSColin Finck { 405c2c66affSColin Finck Length = ComboBox_GetLBText(hwndCombo, i, pBuffer); 406c2c66affSColin Finck if (Length == CB_ERR) 407c2c66affSColin Finck { 408c2c66affSColin Finck TRACE("ComboBox_GetLBText() failed\n"); 409c2c66affSColin Finck goto cleanup; 410c2c66affSColin Finck } 411c2c66affSColin Finck else if (UseCustomPath && _wcsicmp(CustomPath, pBuffer) == 0) 412c2c66affSColin Finck UseCustomPath = FALSE; 413c2c66affSColin Finck pBuffer += 1 + Length; 414c2c66affSColin Finck } 415c2c66affSColin Finck *pBuffer = '\0'; /* Add final NULL char */ 416c2c66affSColin Finck 417c2c66affSColin Finck if (!UseCustomPath) 418c2c66affSColin Finck { 419c2c66affSColin Finck /* Nothing to save to registry */ 420c2c66affSColin Finck goto cleanup; 421c2c66affSColin Finck } 422c2c66affSColin Finck 423c2c66affSColin Finck TotalLength += CustomPathLength; 424c2c66affSColin Finck wcscpy(Buffer, CustomPath); 425c2c66affSColin Finck 426c2c66affSColin Finck /* Save the buffer */ 427c2c66affSColin Finck /* RegSetKeyValue would have been better... */ 428c2c66affSColin Finck rc = RegOpenKeyEx( 429c2c66affSColin Finck HKEY_LOCAL_MACHINE, 430c2c66affSColin Finck REGSTR_PATH_SETUP REGSTR_KEY_SETUP, 431c2c66affSColin Finck 0, 432c2c66affSColin Finck KEY_SET_VALUE, 433c2c66affSColin Finck &hKey); 434c2c66affSColin Finck if (rc != ERROR_SUCCESS) 435c2c66affSColin Finck { 436c2c66affSColin Finck TRACE("RegOpenKeyEx() failed with error 0x%lx\n", rc); 437c2c66affSColin Finck goto cleanup; 438c2c66affSColin Finck } 439c2c66affSColin Finck rc = RegSetValueExW( 440c2c66affSColin Finck hKey, 441c2c66affSColin Finck L"Installation Sources", 442c2c66affSColin Finck 0, 443c2c66affSColin Finck REG_MULTI_SZ, 444c2c66affSColin Finck (const BYTE*)Buffer, 445c2c66affSColin Finck TotalLength * sizeof(WCHAR)); 446c2c66affSColin Finck if (rc != ERROR_SUCCESS) 447c2c66affSColin Finck { 448c2c66affSColin Finck TRACE("RegSetValueEx() failed with error 0x%lx\n", rc); 449c2c66affSColin Finck goto cleanup; 450c2c66affSColin Finck } 451c2c66affSColin Finck 452c2c66affSColin Finck cleanup: 453c2c66affSColin Finck if (hKey != NULL) 454c2c66affSColin Finck RegCloseKey(hKey); 455c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, CustomPath); 456c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, Buffer); 457c2c66affSColin Finck } 458c2c66affSColin Finck 459c2c66affSColin Finck static INT_PTR CALLBACK 460c2c66affSColin Finck WelcomeDlgProc( 461c2c66affSColin Finck IN HWND hwndDlg, 462c2c66affSColin Finck IN UINT uMsg, 463c2c66affSColin Finck IN WPARAM wParam, 464c2c66affSColin Finck IN LPARAM lParam) 465c2c66affSColin Finck { 466c2c66affSColin Finck PDEVINSTDATA DevInstData; 467c2c66affSColin Finck UNREFERENCED_PARAMETER(wParam); 468c2c66affSColin Finck 469c2c66affSColin Finck /* Retrieve pointer to the global setup data */ 470d281d14fSTimo Kreuzer DevInstData = (PDEVINSTDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); 471c2c66affSColin Finck 472c2c66affSColin Finck switch (uMsg) 473c2c66affSColin Finck { 474c2c66affSColin Finck case WM_INITDIALOG: 475c2c66affSColin Finck { 476c2c66affSColin Finck HWND hwndControl; 477c2c66affSColin Finck DWORD dwStyle; 478c2c66affSColin Finck 479c2c66affSColin Finck /* Get pointer to the global setup data */ 480c2c66affSColin Finck DevInstData = (PDEVINSTDATA)((LPPROPSHEETPAGE)lParam)->lParam; 481d281d14fSTimo Kreuzer SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)DevInstData); 482c2c66affSColin Finck 483c2c66affSColin Finck hwndControl = GetParent(hwndDlg); 484c2c66affSColin Finck 485c2c66affSColin Finck /* Center the wizard window */ 486c2c66affSColin Finck CenterWindow(hwndControl); 487c2c66affSColin Finck 488c2c66affSColin Finck /* Hide the system menu */ 489c2c66affSColin Finck dwStyle = GetWindowLongPtr(hwndControl, GWL_STYLE); 490c2c66affSColin Finck SetWindowLongPtr(hwndControl, GWL_STYLE, dwStyle & ~WS_SYSMENU); 491c2c66affSColin Finck 492c2c66affSColin Finck /* Set title font */ 493c2c66affSColin Finck SendDlgItemMessage( 494c2c66affSColin Finck hwndDlg, 495c2c66affSColin Finck IDC_WELCOMETITLE, 496c2c66affSColin Finck WM_SETFONT, 497c2c66affSColin Finck (WPARAM)DevInstData->hTitleFont, 498c2c66affSColin Finck (LPARAM)TRUE); 499c2c66affSColin Finck 500c2c66affSColin Finck SendDlgItemMessage( 501c2c66affSColin Finck hwndDlg, 502c2c66affSColin Finck IDC_DEVICE, 503c2c66affSColin Finck WM_SETTEXT, 504c2c66affSColin Finck 0, 505c2c66affSColin Finck (LPARAM)DevInstData->buffer); 506c2c66affSColin Finck 507c2c66affSColin Finck SendDlgItemMessage( 508c2c66affSColin Finck hwndDlg, 509c2c66affSColin Finck IDC_RADIO_AUTO, 510c2c66affSColin Finck BM_SETCHECK, 511c2c66affSColin Finck (WPARAM)TRUE, 512c2c66affSColin Finck (LPARAM)0); 513c2c66affSColin Finck 514c2c66affSColin Finck SetFailedInstall(DevInstData->hDevInfo, 515c2c66affSColin Finck &DevInstData->devInfoData, 516c2c66affSColin Finck TRUE); 517c2c66affSColin Finck break; 518c2c66affSColin Finck } 519c2c66affSColin Finck 520c2c66affSColin Finck case WM_NOTIFY: 521c2c66affSColin Finck { 522c2c66affSColin Finck LPNMHDR lpnm = (LPNMHDR)lParam; 523c2c66affSColin Finck 524c2c66affSColin Finck switch (lpnm->code) 525c2c66affSColin Finck { 526c2c66affSColin Finck case PSN_SETACTIVE: 527c2c66affSColin Finck /* Enable the Next button */ 528c2c66affSColin Finck PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT); 529c2c66affSColin Finck break; 530c2c66affSColin Finck 531c2c66affSColin Finck case PSN_WIZNEXT: 532c2c66affSColin Finck /* Handle a Next button click, if necessary */ 533c2c66affSColin Finck if (SendDlgItemMessage(hwndDlg, IDC_RADIO_AUTO, BM_GETCHECK, (WPARAM)0, (LPARAM)0) == BST_CHECKED) 534c2c66affSColin Finck { 535c2c66affSColin Finck if (PrepareFoldersToScan(DevInstData, TRUE, FALSE, NULL)) 536c2c66affSColin Finck PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_SEARCHDRV); 537c2c66affSColin Finck else 538c2c66affSColin Finck PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_INSTALLFAILED); 539c2c66affSColin Finck } 540c2c66affSColin Finck return TRUE; 541c2c66affSColin Finck 542c2c66affSColin Finck default: 543c2c66affSColin Finck break; 544c2c66affSColin Finck } 545c2c66affSColin Finck break; 546c2c66affSColin Finck } 547c2c66affSColin Finck 548c2c66affSColin Finck default: 549c2c66affSColin Finck break; 550c2c66affSColin Finck } 551c2c66affSColin Finck 552c2c66affSColin Finck return FALSE; 553c2c66affSColin Finck } 554c2c66affSColin Finck 555c2c66affSColin Finck static void 556c2c66affSColin Finck IncludePath(HWND Dlg, BOOL Enabled) 557c2c66affSColin Finck { 558c2c66affSColin Finck EnableWindow(GetDlgItem(Dlg, IDC_COMBO_PATH), Enabled); 559c2c66affSColin Finck EnableWindow(GetDlgItem(Dlg, IDC_BROWSE), Enabled); 560c2c66affSColin Finck } 561c2c66affSColin Finck 562c2c66affSColin Finck static void 563c2c66affSColin Finck AutoDriver(HWND Dlg, BOOL Enabled) 564c2c66affSColin Finck { 565c2c66affSColin Finck EnableWindow(GetDlgItem(Dlg, IDC_CHECK_MEDIA), Enabled); 566c2c66affSColin Finck EnableWindow(GetDlgItem(Dlg, IDC_CHECK_PATH), Enabled); 567c2c66affSColin Finck IncludePath(Dlg, Enabled & IsDlgButtonChecked(Dlg, IDC_CHECK_PATH)); 568c2c66affSColin Finck } 569c2c66affSColin Finck 570c2c66affSColin Finck static INT_PTR CALLBACK 571c2c66affSColin Finck CHSourceDlgProc( 572c2c66affSColin Finck IN HWND hwndDlg, 573c2c66affSColin Finck IN UINT uMsg, 574c2c66affSColin Finck IN WPARAM wParam, 575c2c66affSColin Finck IN LPARAM lParam) 576c2c66affSColin Finck { 577c2c66affSColin Finck PDEVINSTDATA DevInstData; 578c2c66affSColin Finck 579c2c66affSColin Finck /* Retrieve pointer to the global setup data */ 580d281d14fSTimo Kreuzer DevInstData = (PDEVINSTDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); 581c2c66affSColin Finck 582c2c66affSColin Finck switch (uMsg) 583c2c66affSColin Finck { 584c2c66affSColin Finck case WM_INITDIALOG: 585c2c66affSColin Finck { 58662b13979SKatayama Hirofumi MZ HWND hwndControl, hwndCombo; 587c2c66affSColin Finck DWORD dwStyle; 58862b13979SKatayama Hirofumi MZ COMBOBOXINFO info = { sizeof(info) }; 589c2c66affSColin Finck 590c2c66affSColin Finck /* Get pointer to the global setup data */ 591c2c66affSColin Finck DevInstData = (PDEVINSTDATA)((LPPROPSHEETPAGE)lParam)->lParam; 592d281d14fSTimo Kreuzer SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)DevInstData); 593c2c66affSColin Finck 594c2c66affSColin Finck hwndControl = GetParent(hwndDlg); 595c2c66affSColin Finck 596c2c66affSColin Finck /* Center the wizard window */ 597c2c66affSColin Finck CenterWindow(hwndControl); 598c2c66affSColin Finck 599c2c66affSColin Finck /* Hide the system menu */ 600c2c66affSColin Finck dwStyle = GetWindowLongPtr(hwndControl, GWL_STYLE); 601c2c66affSColin Finck SetWindowLongPtr(hwndControl, GWL_STYLE, dwStyle & ~WS_SYSMENU); 602c2c66affSColin Finck 60362b13979SKatayama Hirofumi MZ hwndCombo = GetDlgItem(hwndDlg, IDC_COMBO_PATH); 60462b13979SKatayama Hirofumi MZ PopulateCustomPathCombo(hwndCombo); 60562b13979SKatayama Hirofumi MZ 60662b13979SKatayama Hirofumi MZ GetComboBoxInfo(hwndCombo, &info); 60762b13979SKatayama Hirofumi MZ SHAutoComplete(info.hwndItem, SHACF_FILESYS_DIRS); 608c2c66affSColin Finck 609c2c66affSColin Finck SendDlgItemMessage( 610c2c66affSColin Finck hwndDlg, 611c2c66affSColin Finck IDC_RADIO_SEARCHHERE, 612c2c66affSColin Finck BM_SETCHECK, 613c2c66affSColin Finck (WPARAM)TRUE, 614c2c66affSColin Finck (LPARAM)0); 615c2c66affSColin Finck AutoDriver(hwndDlg, TRUE); 616c2c66affSColin Finck IncludePath(hwndDlg, FALSE); 617c2c66affSColin Finck 618c2c66affSColin Finck /* Disable manual driver choice for now */ 619c2c66affSColin Finck EnableWindow(GetDlgItem(hwndDlg, IDC_RADIO_CHOOSE), FALSE); 620c2c66affSColin Finck 621c2c66affSColin Finck break; 622c2c66affSColin Finck } 623c2c66affSColin Finck 624c2c66affSColin Finck case WM_COMMAND: 625c2c66affSColin Finck { 626c2c66affSColin Finck switch (LOWORD(wParam)) 627c2c66affSColin Finck { 628c2c66affSColin Finck case IDC_RADIO_SEARCHHERE: 629c2c66affSColin Finck AutoDriver(hwndDlg, TRUE); 630c2c66affSColin Finck return TRUE; 631c2c66affSColin Finck 632c2c66affSColin Finck case IDC_RADIO_CHOOSE: 633c2c66affSColin Finck AutoDriver(hwndDlg, FALSE); 634c2c66affSColin Finck return TRUE; 635c2c66affSColin Finck 636c2c66affSColin Finck case IDC_CHECK_PATH: 637c2c66affSColin Finck IncludePath(hwndDlg, IsDlgButtonChecked(hwndDlg, IDC_CHECK_PATH)); 638c2c66affSColin Finck return TRUE; 639c2c66affSColin Finck 640c2c66affSColin Finck case IDC_BROWSE: 641c2c66affSColin Finck { 642c2c66affSColin Finck BROWSEINFO bi = { 0 }; 643c2c66affSColin Finck LPITEMIDLIST pidl; 644c2c66affSColin Finck 645c2c66affSColin Finck bi.hwndOwner = hwndDlg; 646b591bd33SKatayama Hirofumi MZ bi.ulFlags = BIF_USENEWUI | BIF_RETURNONLYFSDIRS; 647c2c66affSColin Finck pidl = SHBrowseForFolder(&bi); 648c2c66affSColin Finck if (pidl) 649c2c66affSColin Finck { 650c2c66affSColin Finck WCHAR Directory[MAX_PATH]; 651c2c66affSColin Finck IMalloc* malloc; 652c2c66affSColin Finck 653c2c66affSColin Finck if (SHGetPathFromIDListW(pidl, Directory)) 654c2c66affSColin Finck { 655c2c66affSColin Finck /* Set the IDC_COMBO_PATH text */ 656c2c66affSColin Finck SetWindowTextW(GetDlgItem(hwndDlg, IDC_COMBO_PATH), Directory); 657c2c66affSColin Finck } 658c2c66affSColin Finck 659c2c66affSColin Finck /* Free memory, if possible */ 660c2c66affSColin Finck if (SUCCEEDED(SHGetMalloc(&malloc))) 661c2c66affSColin Finck { 662c2c66affSColin Finck IMalloc_Free(malloc, pidl); 663c2c66affSColin Finck IMalloc_Release(malloc); 664c2c66affSColin Finck } 665c2c66affSColin Finck return TRUE; 666c2c66affSColin Finck } 667c2c66affSColin Finck break; 668c2c66affSColin Finck } 669c2c66affSColin Finck } 670c2c66affSColin Finck break; 671c2c66affSColin Finck } 672c2c66affSColin Finck 673c2c66affSColin Finck case WM_NOTIFY: 674c2c66affSColin Finck { 675c2c66affSColin Finck LPNMHDR lpnm = (LPNMHDR)lParam; 676c2c66affSColin Finck 677c2c66affSColin Finck switch (lpnm->code) 678c2c66affSColin Finck { 679c2c66affSColin Finck case PSN_SETACTIVE: 680c2c66affSColin Finck /* Enable the Next and Back buttons */ 681c2c66affSColin Finck PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT | PSWIZB_BACK); 682c2c66affSColin Finck break; 683c2c66affSColin Finck 684c2c66affSColin Finck case PSN_WIZNEXT: 685c2c66affSColin Finck /* Handle a Next button click, if necessary */ 686c2c66affSColin Finck if (IsDlgButtonChecked(hwndDlg, IDC_RADIO_SEARCHHERE)) 687c2c66affSColin Finck { 688c2c66affSColin Finck SaveCustomPath(GetDlgItem(hwndDlg, IDC_COMBO_PATH)); 689c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, DevInstData->CustomSearchPath); 690c2c66affSColin Finck DevInstData->CustomSearchPath = NULL; 691c2c66affSColin Finck if (PrepareFoldersToScan( 692c2c66affSColin Finck DevInstData, 693c2c66affSColin Finck IsDlgButtonChecked(hwndDlg, IDC_CHECK_MEDIA), 694c2c66affSColin Finck IsDlgButtonChecked(hwndDlg, IDC_CHECK_PATH), 695c2c66affSColin Finck GetDlgItem(hwndDlg, IDC_COMBO_PATH))) 696c2c66affSColin Finck { 697c2c66affSColin Finck PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_SEARCHDRV); 698c2c66affSColin Finck } 699c2c66affSColin Finck else 700c2c66affSColin Finck { 701c2c66affSColin Finck PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_INSTALLFAILED); 702c2c66affSColin Finck } 703c2c66affSColin Finck } 704c2c66affSColin Finck else 705c2c66affSColin Finck { 706c2c66affSColin Finck /* FIXME */; 707c2c66affSColin Finck } 708c2c66affSColin Finck return TRUE; 709c2c66affSColin Finck 710c2c66affSColin Finck default: 711c2c66affSColin Finck break; 712c2c66affSColin Finck } 713c2c66affSColin Finck break; 714c2c66affSColin Finck } 715c2c66affSColin Finck 716c2c66affSColin Finck default: 717c2c66affSColin Finck break; 718c2c66affSColin Finck } 719c2c66affSColin Finck 720c2c66affSColin Finck return FALSE; 721c2c66affSColin Finck } 722c2c66affSColin Finck 723c2c66affSColin Finck static INT_PTR CALLBACK 724c2c66affSColin Finck SearchDrvDlgProc( 725c2c66affSColin Finck IN HWND hwndDlg, 726c2c66affSColin Finck IN UINT uMsg, 727c2c66affSColin Finck IN WPARAM wParam, 728c2c66affSColin Finck IN LPARAM lParam) 729c2c66affSColin Finck { 730c2c66affSColin Finck PDEVINSTDATA DevInstData; 731c2c66affSColin Finck DWORD dwThreadId; 732c2c66affSColin Finck 733c2c66affSColin Finck /* Retrieve pointer to the global setup data */ 734d281d14fSTimo Kreuzer DevInstData = (PDEVINSTDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); 735c2c66affSColin Finck 736c2c66affSColin Finck switch (uMsg) 737c2c66affSColin Finck { 738c2c66affSColin Finck case WM_INITDIALOG: 739c2c66affSColin Finck { 740c2c66affSColin Finck HWND hwndControl; 741c2c66affSColin Finck DWORD dwStyle; 742c2c66affSColin Finck 743c2c66affSColin Finck /* Get pointer to the global setup data */ 744c2c66affSColin Finck DevInstData = (PDEVINSTDATA)((LPPROPSHEETPAGE)lParam)->lParam; 745d281d14fSTimo Kreuzer SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)DevInstData); 746c2c66affSColin Finck 747c2c66affSColin Finck DevInstData->hDialog = hwndDlg; 748c2c66affSColin Finck hwndControl = GetParent(hwndDlg); 749c2c66affSColin Finck 750c2c66affSColin Finck /* Center the wizard window */ 751c2c66affSColin Finck CenterWindow(hwndControl); 752c2c66affSColin Finck 753c2c66affSColin Finck SendDlgItemMessage( 754c2c66affSColin Finck hwndDlg, 755c2c66affSColin Finck IDC_DEVICE, 756c2c66affSColin Finck WM_SETTEXT, 757c2c66affSColin Finck 0, 758c2c66affSColin Finck (LPARAM)DevInstData->buffer); 759c2c66affSColin Finck 760c2c66affSColin Finck /* Hide the system menu */ 761c2c66affSColin Finck dwStyle = GetWindowLongPtr(hwndControl, GWL_STYLE); 762c2c66affSColin Finck SetWindowLongPtr(hwndControl, GWL_STYLE, dwStyle & ~WS_SYSMENU); 763c2c66affSColin Finck break; 764c2c66affSColin Finck } 765c2c66affSColin Finck 766c2c66affSColin Finck case WM_SEARCH_FINISHED: 767c2c66affSColin Finck { 768c2c66affSColin Finck CloseHandle(hThread); 769c2c66affSColin Finck hThread = 0; 770c2c66affSColin Finck if (wParam == 0) 771c2c66affSColin Finck PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_NODRIVER); 772c2c66affSColin Finck else 773c2c66affSColin Finck PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_INSTALLDRV); 774c2c66affSColin Finck break; 775c2c66affSColin Finck } 776c2c66affSColin Finck 777c2c66affSColin Finck case WM_NOTIFY: 778c2c66affSColin Finck { 779c2c66affSColin Finck LPNMHDR lpnm = (LPNMHDR)lParam; 780c2c66affSColin Finck 781c2c66affSColin Finck switch (lpnm->code) 782c2c66affSColin Finck { 783c2c66affSColin Finck case PSN_SETACTIVE: 784c2c66affSColin Finck PropSheet_SetWizButtons(GetParent(hwndDlg), !PSWIZB_NEXT | !PSWIZB_BACK); 785c2c66affSColin Finck /* Yes, we can safely ignore the problem (if any) */ 786c2c66affSColin Finck SetupDiDestroyDriverInfoList( 787c2c66affSColin Finck DevInstData->hDevInfo, 788c2c66affSColin Finck &DevInstData->devInfoData, 789c2c66affSColin Finck SPDIT_COMPATDRIVER); 790c2c66affSColin Finck hThread = CreateThread(NULL, 0, FindDriverProc, DevInstData, 0, &dwThreadId); 791c2c66affSColin Finck break; 792c2c66affSColin Finck 793c2c66affSColin Finck case PSN_KILLACTIVE: 794c2c66affSColin Finck if (hThread != 0) 795c2c66affSColin Finck { 7960182dcd7STimo Kreuzer SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE); 797c2c66affSColin Finck return TRUE; 798c2c66affSColin Finck } 799c2c66affSColin Finck break; 800c2c66affSColin Finck 801c2c66affSColin Finck case PSN_WIZNEXT: 802c2c66affSColin Finck /* Handle a Next button click, if necessary */ 803c2c66affSColin Finck break; 804c2c66affSColin Finck 805c2c66affSColin Finck default: 806c2c66affSColin Finck break; 807c2c66affSColin Finck } 808c2c66affSColin Finck break; 809c2c66affSColin Finck } 810c2c66affSColin Finck 811c2c66affSColin Finck default: 812c2c66affSColin Finck break; 813c2c66affSColin Finck } 814c2c66affSColin Finck 815c2c66affSColin Finck return FALSE; 816c2c66affSColin Finck } 817c2c66affSColin Finck 818c2c66affSColin Finck static INT_PTR CALLBACK 819c2c66affSColin Finck InstallDrvDlgProc( 820c2c66affSColin Finck IN HWND hwndDlg, 821c2c66affSColin Finck IN UINT uMsg, 822c2c66affSColin Finck IN WPARAM wParam, 823c2c66affSColin Finck IN LPARAM lParam) 824c2c66affSColin Finck { 825c2c66affSColin Finck PDEVINSTDATA DevInstData; 826c2c66affSColin Finck DWORD dwThreadId; 827c2c66affSColin Finck 828c2c66affSColin Finck /* Retrieve pointer to the global setup data */ 829d281d14fSTimo Kreuzer DevInstData = (PDEVINSTDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); 830c2c66affSColin Finck 831c2c66affSColin Finck switch (uMsg) 832c2c66affSColin Finck { 833c2c66affSColin Finck case WM_INITDIALOG: 834c2c66affSColin Finck { 835c2c66affSColin Finck HWND hwndControl; 836c2c66affSColin Finck DWORD dwStyle; 837c2c66affSColin Finck 838c2c66affSColin Finck /* Get pointer to the global setup data */ 839c2c66affSColin Finck DevInstData = (PDEVINSTDATA)((LPPROPSHEETPAGE)lParam)->lParam; 840d281d14fSTimo Kreuzer SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)DevInstData); 841c2c66affSColin Finck 842c2c66affSColin Finck DevInstData->hDialog = hwndDlg; 843c2c66affSColin Finck hwndControl = GetParent(hwndDlg); 844c2c66affSColin Finck 845c2c66affSColin Finck /* Center the wizard window */ 846c2c66affSColin Finck CenterWindow(hwndControl); 847c2c66affSColin Finck 848c2c66affSColin Finck SendDlgItemMessage( 849c2c66affSColin Finck hwndDlg, 850c2c66affSColin Finck IDC_DEVICE, 851c2c66affSColin Finck WM_SETTEXT, 852c2c66affSColin Finck 0, 853c2c66affSColin Finck (LPARAM)DevInstData->drvInfoData.Description); 854c2c66affSColin Finck 855c2c66affSColin Finck /* Hide the system menu */ 856c2c66affSColin Finck dwStyle = GetWindowLongPtr(hwndControl, GWL_STYLE); 857c2c66affSColin Finck SetWindowLongPtr(hwndControl, GWL_STYLE, dwStyle & ~WS_SYSMENU); 858c2c66affSColin Finck break; 859c2c66affSColin Finck } 860c2c66affSColin Finck 861c2c66affSColin Finck case WM_INSTALL_FINISHED: 862c2c66affSColin Finck { 863c2c66affSColin Finck CloseHandle(hThread); 864c2c66affSColin Finck hThread = 0; 865c2c66affSColin Finck if (wParam == 0) 866c2c66affSColin Finck { 867c2c66affSColin Finck SP_DEVINSTALL_PARAMS installParams; 868c2c66affSColin Finck 869c2c66affSColin Finck SetFailedInstall(DevInstData->hDevInfo, 870c2c66affSColin Finck &DevInstData->devInfoData, 871c2c66affSColin Finck FALSE); 872c2c66affSColin Finck 873c2c66affSColin Finck /* Should we reboot? */ 874c2c66affSColin Finck installParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS); 875c2c66affSColin Finck if (SetupDiGetDeviceInstallParams( 876c2c66affSColin Finck DevInstData->hDevInfo, 877c2c66affSColin Finck &DevInstData->devInfoData, 878c2c66affSColin Finck &installParams)) 879c2c66affSColin Finck { 880c2c66affSColin Finck if (installParams.Flags & (DI_NEEDRESTART | DI_NEEDREBOOT)) 881c2c66affSColin Finck { 882c2c66affSColin Finck PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_NEEDREBOOT); 883c2c66affSColin Finck } 884c2c66affSColin Finck else 885c2c66affSColin Finck PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_FINISHPAGE); 886c2c66affSColin Finck break; 887c2c66affSColin Finck } 888c2c66affSColin Finck } 889c2c66affSColin Finck PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_INSTALLFAILED); 890c2c66affSColin Finck break; 891c2c66affSColin Finck } 892c2c66affSColin Finck 893c2c66affSColin Finck case WM_NOTIFY: 894c2c66affSColin Finck { 895c2c66affSColin Finck LPNMHDR lpnm = (LPNMHDR)lParam; 896c2c66affSColin Finck 897c2c66affSColin Finck switch (lpnm->code) 898c2c66affSColin Finck { 899c2c66affSColin Finck case PSN_SETACTIVE: 900c2c66affSColin Finck PropSheet_SetWizButtons(GetParent(hwndDlg), !PSWIZB_NEXT | !PSWIZB_BACK); 901c2c66affSColin Finck hThread = CreateThread(NULL, 0, InstallDriverProc, DevInstData, 0, &dwThreadId); 902c2c66affSColin Finck break; 903c2c66affSColin Finck 904c2c66affSColin Finck case PSN_KILLACTIVE: 905c2c66affSColin Finck if (hThread != 0) 906c2c66affSColin Finck { 9070182dcd7STimo Kreuzer SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE); 908c2c66affSColin Finck return TRUE; 909c2c66affSColin Finck } 910c2c66affSColin Finck break; 911c2c66affSColin Finck 912c2c66affSColin Finck case PSN_WIZNEXT: 913c2c66affSColin Finck /* Handle a Next button click, if necessary */ 914c2c66affSColin Finck break; 915c2c66affSColin Finck 916c2c66affSColin Finck default: 917c2c66affSColin Finck break; 918c2c66affSColin Finck } 919c2c66affSColin Finck break; 920c2c66affSColin Finck } 921c2c66affSColin Finck 922c2c66affSColin Finck default: 923c2c66affSColin Finck break; 924c2c66affSColin Finck } 925c2c66affSColin Finck 926c2c66affSColin Finck return FALSE; 927c2c66affSColin Finck } 928c2c66affSColin Finck 929c2c66affSColin Finck static INT_PTR CALLBACK 930c2c66affSColin Finck NoDriverDlgProc( 931c2c66affSColin Finck IN HWND hwndDlg, 932c2c66affSColin Finck IN UINT uMsg, 933c2c66affSColin Finck IN WPARAM wParam, 934c2c66affSColin Finck IN LPARAM lParam) 935c2c66affSColin Finck { 936c2c66affSColin Finck PDEVINSTDATA DevInstData; 937c2c66affSColin Finck HWND hwndControl; 938c2c66affSColin Finck 939c2c66affSColin Finck UNREFERENCED_PARAMETER(wParam); 940c2c66affSColin Finck 941c2c66affSColin Finck /* Get pointer to the global setup data */ 942d281d14fSTimo Kreuzer DevInstData = (PDEVINSTDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); 943c2c66affSColin Finck 944c2c66affSColin Finck switch (uMsg) 945c2c66affSColin Finck { 946c2c66affSColin Finck case WM_INITDIALOG: 947c2c66affSColin Finck { 948c2c66affSColin Finck BOOL DisableableDevice = FALSE; 949c2c66affSColin Finck 950c2c66affSColin Finck /* Get pointer to the global setup data */ 951c2c66affSColin Finck DevInstData = (PDEVINSTDATA)((LPPROPSHEETPAGE)lParam)->lParam; 952d281d14fSTimo Kreuzer SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)DevInstData); 953c2c66affSColin Finck 954c2c66affSColin Finck /* Center the wizard window */ 955c2c66affSColin Finck CenterWindow(GetParent(hwndDlg)); 956c2c66affSColin Finck 957c2c66affSColin Finck hwndControl = GetDlgItem(GetParent(hwndDlg), IDCANCEL); 958c2c66affSColin Finck ShowWindow(hwndControl, SW_HIDE); 959c2c66affSColin Finck EnableWindow(hwndControl, FALSE); 960c2c66affSColin Finck 961c2c66affSColin Finck /* Set title font */ 962c2c66affSColin Finck SendDlgItemMessage( 963c2c66affSColin Finck hwndDlg, 964c2c66affSColin Finck IDC_FINISHTITLE, 965c2c66affSColin Finck WM_SETFONT, 966c2c66affSColin Finck (WPARAM)DevInstData->hTitleFont, 967c2c66affSColin Finck (LPARAM)TRUE); 968c2c66affSColin Finck 969c2c66affSColin Finck /* disable the "do not show this dialog anymore" checkbox 970c2c66affSColin Finck if the device cannot be disabled */ 971c2c66affSColin Finck CanDisableDevice( 972c2c66affSColin Finck DevInstData->devInfoData.DevInst, 973c2c66affSColin Finck NULL, 974c2c66affSColin Finck &DisableableDevice); 975c2c66affSColin Finck EnableWindow( 976c2c66affSColin Finck GetDlgItem(hwndDlg, IDC_DONOTSHOWDLG), 977c2c66affSColin Finck DisableableDevice); 978c2c66affSColin Finck break; 979c2c66affSColin Finck } 980c2c66affSColin Finck 981c2c66affSColin Finck case WM_NOTIFY: 982c2c66affSColin Finck { 983c2c66affSColin Finck LPNMHDR lpnm = (LPNMHDR)lParam; 984c2c66affSColin Finck 985c2c66affSColin Finck switch (lpnm->code) 986c2c66affSColin Finck { 987c2c66affSColin Finck case PSN_SETACTIVE: 988c2c66affSColin Finck /* Enable the correct buttons on for the active page */ 989c2c66affSColin Finck PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_FINISH); 990c2c66affSColin Finck break; 991c2c66affSColin Finck 992c2c66affSColin Finck case PSN_WIZBACK: 993c2c66affSColin Finck /* Handle a Back button click, if necessary */ 994c2c66affSColin Finck hwndControl = GetDlgItem(GetParent(hwndDlg), IDCANCEL); 995c2c66affSColin Finck ShowWindow(hwndControl, SW_SHOW); 996c2c66affSColin Finck EnableWindow(hwndControl, TRUE); 997c2c66affSColin Finck PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_CHSOURCE); 998c2c66affSColin Finck return TRUE; 999c2c66affSColin Finck 1000c2c66affSColin Finck case PSN_WIZFINISH: 1001c2c66affSColin Finck { 1002c2c66affSColin Finck BOOL DisableableDevice = FALSE; 1003c2c66affSColin Finck BOOL IsStarted = FALSE; 1004c2c66affSColin Finck 1005c2c66affSColin Finck if (CanDisableDevice(DevInstData->devInfoData.DevInst, 1006c2c66affSColin Finck NULL, 1007c2c66affSColin Finck &DisableableDevice) && 1008c2c66affSColin Finck DisableableDevice && 1009c2c66affSColin Finck IsDeviceStarted( 1010c2c66affSColin Finck DevInstData->devInfoData.DevInst, 1011c2c66affSColin Finck NULL, 1012c2c66affSColin Finck &IsStarted) && 1013c2c66affSColin Finck !IsStarted && 1014c2c66affSColin Finck SendDlgItemMessage( 1015c2c66affSColin Finck hwndDlg, 1016c2c66affSColin Finck IDC_DONOTSHOWDLG, 1017c2c66affSColin Finck BM_GETCHECK, 1018c2c66affSColin Finck (WPARAM)0, (LPARAM)0) == BST_CHECKED) 1019c2c66affSColin Finck { 1020c2c66affSColin Finck /* disable the device */ 1021c2c66affSColin Finck StartDevice( 1022c2c66affSColin Finck DevInstData->hDevInfo, 1023c2c66affSColin Finck &DevInstData->devInfoData, 1024c2c66affSColin Finck FALSE, 1025c2c66affSColin Finck 0, 1026c2c66affSColin Finck NULL); 1027c2c66affSColin Finck } 1028c2c66affSColin Finck else 1029c2c66affSColin Finck { 1030c2c66affSColin Finck SetFailedInstall(DevInstData->hDevInfo, 1031c2c66affSColin Finck &DevInstData->devInfoData, 1032c2c66affSColin Finck FALSE); 1033c2c66affSColin Finck } 1034c2c66affSColin Finck break; 1035c2c66affSColin Finck } 1036c2c66affSColin Finck 1037c2c66affSColin Finck default: 1038c2c66affSColin Finck break; 1039c2c66affSColin Finck } 1040c2c66affSColin Finck break; 1041c2c66affSColin Finck } 1042c2c66affSColin Finck 1043c2c66affSColin Finck default: 1044c2c66affSColin Finck break; 1045c2c66affSColin Finck } 1046c2c66affSColin Finck 1047c2c66affSColin Finck return FALSE; 1048c2c66affSColin Finck } 1049c2c66affSColin Finck 1050c2c66affSColin Finck static INT_PTR CALLBACK 1051c2c66affSColin Finck InstallFailedDlgProc( 1052c2c66affSColin Finck IN HWND hwndDlg, 1053c2c66affSColin Finck IN UINT uMsg, 1054c2c66affSColin Finck IN WPARAM wParam, 1055c2c66affSColin Finck IN LPARAM lParam) 1056c2c66affSColin Finck { 1057c2c66affSColin Finck PDEVINSTDATA DevInstData; 1058c2c66affSColin Finck UNREFERENCED_PARAMETER(wParam); 1059c2c66affSColin Finck 1060c2c66affSColin Finck /* Retrieve pointer to the global setup data */ 1061d281d14fSTimo Kreuzer DevInstData = (PDEVINSTDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); 1062c2c66affSColin Finck 1063c2c66affSColin Finck switch (uMsg) 1064c2c66affSColin Finck { 1065c2c66affSColin Finck case WM_INITDIALOG: 1066c2c66affSColin Finck { 1067c2c66affSColin Finck HWND hwndControl; 1068c2c66affSColin Finck 1069c2c66affSColin Finck /* Get pointer to the global setup data */ 1070c2c66affSColin Finck DevInstData = (PDEVINSTDATA)((LPPROPSHEETPAGE)lParam)->lParam; 1071d281d14fSTimo Kreuzer SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)DevInstData); 1072c2c66affSColin Finck 1073c2c66affSColin Finck /* Center the wizard window */ 1074c2c66affSColin Finck CenterWindow(GetParent(hwndDlg)); 1075c2c66affSColin Finck 1076c2c66affSColin Finck hwndControl = GetDlgItem(GetParent(hwndDlg), IDCANCEL); 1077c2c66affSColin Finck ShowWindow(hwndControl, SW_HIDE); 1078c2c66affSColin Finck EnableWindow(hwndControl, FALSE); 1079c2c66affSColin Finck 1080c2c66affSColin Finck SendDlgItemMessage( 1081c2c66affSColin Finck hwndDlg, 1082c2c66affSColin Finck IDC_DEVICE, 1083c2c66affSColin Finck WM_SETTEXT, 1084c2c66affSColin Finck 0, 1085c2c66affSColin Finck (LPARAM)DevInstData->drvInfoData.Description); 1086c2c66affSColin Finck 1087c2c66affSColin Finck /* Set title font */ 1088c2c66affSColin Finck SendDlgItemMessage( 1089c2c66affSColin Finck hwndDlg, 1090c2c66affSColin Finck IDC_FINISHTITLE, 1091c2c66affSColin Finck WM_SETFONT, 1092c2c66affSColin Finck (WPARAM)DevInstData->hTitleFont, 1093c2c66affSColin Finck (LPARAM)TRUE); 1094c2c66affSColin Finck break; 1095c2c66affSColin Finck } 1096c2c66affSColin Finck 1097c2c66affSColin Finck case WM_NOTIFY: 1098c2c66affSColin Finck { 1099c2c66affSColin Finck LPNMHDR lpnm = (LPNMHDR)lParam; 1100c2c66affSColin Finck 1101c2c66affSColin Finck switch (lpnm->code) 1102c2c66affSColin Finck { 1103c2c66affSColin Finck case PSN_SETACTIVE: 1104c2c66affSColin Finck /* Enable the correct buttons on for the active page */ 1105c2c66affSColin Finck PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_FINISH); 1106c2c66affSColin Finck break; 1107c2c66affSColin Finck 1108c2c66affSColin Finck case PSN_WIZBACK: 1109c2c66affSColin Finck /* Handle a Back button click, if necessary */ 1110c2c66affSColin Finck break; 1111c2c66affSColin Finck 1112c2c66affSColin Finck case PSN_WIZFINISH: 1113c2c66affSColin Finck /* Handle a Finish button click, if necessary */ 1114c2c66affSColin Finck break; 1115c2c66affSColin Finck 1116c2c66affSColin Finck default: 1117c2c66affSColin Finck break; 1118c2c66affSColin Finck } 1119c2c66affSColin Finck break; 1120c2c66affSColin Finck } 1121c2c66affSColin Finck 1122c2c66affSColin Finck default: 1123c2c66affSColin Finck break; 1124c2c66affSColin Finck } 1125c2c66affSColin Finck 1126c2c66affSColin Finck return FALSE; 1127c2c66affSColin Finck } 1128c2c66affSColin Finck 1129c2c66affSColin Finck static INT_PTR CALLBACK 1130c2c66affSColin Finck NeedRebootDlgProc( 1131c2c66affSColin Finck IN HWND hwndDlg, 1132c2c66affSColin Finck IN UINT uMsg, 1133c2c66affSColin Finck IN WPARAM wParam, 1134c2c66affSColin Finck IN LPARAM lParam) 1135c2c66affSColin Finck { 1136c2c66affSColin Finck PDEVINSTDATA DevInstData; 1137c2c66affSColin Finck UNREFERENCED_PARAMETER(wParam); 1138c2c66affSColin Finck 1139c2c66affSColin Finck /* Retrieve pointer to the global setup data */ 1140d281d14fSTimo Kreuzer DevInstData = (PDEVINSTDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); 1141c2c66affSColin Finck 1142c2c66affSColin Finck switch (uMsg) 1143c2c66affSColin Finck { 1144c2c66affSColin Finck case WM_INITDIALOG: 1145c2c66affSColin Finck { 1146c2c66affSColin Finck HWND hwndControl; 1147c2c66affSColin Finck 1148c2c66affSColin Finck /* Get pointer to the global setup data */ 1149c2c66affSColin Finck DevInstData = (PDEVINSTDATA)((LPPROPSHEETPAGE)lParam)->lParam; 1150d281d14fSTimo Kreuzer SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)DevInstData); 1151c2c66affSColin Finck 1152c2c66affSColin Finck /* Center the wizard window */ 1153c2c66affSColin Finck CenterWindow(GetParent(hwndDlg)); 1154c2c66affSColin Finck 1155c2c66affSColin Finck hwndControl = GetDlgItem(GetParent(hwndDlg), IDCANCEL); 1156c2c66affSColin Finck ShowWindow(hwndControl, SW_HIDE); 1157c2c66affSColin Finck EnableWindow(hwndControl, FALSE); 1158c2c66affSColin Finck 1159c2c66affSColin Finck SendDlgItemMessage( 1160c2c66affSColin Finck hwndDlg, 1161c2c66affSColin Finck IDC_DEVICE, 1162c2c66affSColin Finck WM_SETTEXT, 1163c2c66affSColin Finck 0, 1164c2c66affSColin Finck (LPARAM)DevInstData->drvInfoData.Description); 1165c2c66affSColin Finck 1166c2c66affSColin Finck /* Set title font */ 1167c2c66affSColin Finck SendDlgItemMessage( 1168c2c66affSColin Finck hwndDlg, 1169c2c66affSColin Finck IDC_FINISHTITLE, 1170c2c66affSColin Finck WM_SETFONT, 1171c2c66affSColin Finck (WPARAM)DevInstData->hTitleFont, 1172c2c66affSColin Finck (LPARAM)TRUE); 1173c2c66affSColin Finck break; 1174c2c66affSColin Finck } 1175c2c66affSColin Finck 1176c2c66affSColin Finck case WM_NOTIFY: 1177c2c66affSColin Finck { 1178c2c66affSColin Finck LPNMHDR lpnm = (LPNMHDR)lParam; 1179c2c66affSColin Finck 1180c2c66affSColin Finck switch (lpnm->code) 1181c2c66affSColin Finck { 1182c2c66affSColin Finck case PSN_SETACTIVE: 1183c2c66affSColin Finck /* Enable the correct buttons on for the active page */ 1184c2c66affSColin Finck PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_FINISH); 1185c2c66affSColin Finck break; 1186c2c66affSColin Finck 1187c2c66affSColin Finck case PSN_WIZBACK: 1188c2c66affSColin Finck /* Handle a Back button click, if necessary */ 1189c2c66affSColin Finck break; 1190c2c66affSColin Finck 1191c2c66affSColin Finck case PSN_WIZFINISH: 1192c2c66affSColin Finck /* Handle a Finish button click, if necessary */ 1193c2c66affSColin Finck break; 1194c2c66affSColin Finck 1195c2c66affSColin Finck default: 1196c2c66affSColin Finck break; 1197c2c66affSColin Finck } 1198c2c66affSColin Finck break; 1199c2c66affSColin Finck } 1200c2c66affSColin Finck 1201c2c66affSColin Finck default: 1202c2c66affSColin Finck break; 1203c2c66affSColin Finck } 1204c2c66affSColin Finck 1205c2c66affSColin Finck return FALSE; 1206c2c66affSColin Finck } 1207c2c66affSColin Finck 1208c2c66affSColin Finck static INT_PTR CALLBACK 1209c2c66affSColin Finck FinishDlgProc( 1210c2c66affSColin Finck IN HWND hwndDlg, 1211c2c66affSColin Finck IN UINT uMsg, 1212c2c66affSColin Finck IN WPARAM wParam, 1213c2c66affSColin Finck IN LPARAM lParam) 1214c2c66affSColin Finck { 1215c2c66affSColin Finck PDEVINSTDATA DevInstData; 1216c2c66affSColin Finck UNREFERENCED_PARAMETER(wParam); 1217c2c66affSColin Finck 1218c2c66affSColin Finck /* Retrieve pointer to the global setup data */ 1219d281d14fSTimo Kreuzer DevInstData = (PDEVINSTDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); 1220c2c66affSColin Finck 1221c2c66affSColin Finck switch (uMsg) 1222c2c66affSColin Finck { 1223c2c66affSColin Finck case WM_INITDIALOG: 1224c2c66affSColin Finck { 1225c2c66affSColin Finck HWND hwndControl; 1226c2c66affSColin Finck 1227c2c66affSColin Finck /* Get pointer to the global setup data */ 1228c2c66affSColin Finck DevInstData = (PDEVINSTDATA)((LPPROPSHEETPAGE)lParam)->lParam; 1229d281d14fSTimo Kreuzer SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)DevInstData); 1230c2c66affSColin Finck 1231c2c66affSColin Finck /* Center the wizard window */ 1232c2c66affSColin Finck CenterWindow(GetParent(hwndDlg)); 1233c2c66affSColin Finck 1234c2c66affSColin Finck hwndControl = GetDlgItem(GetParent(hwndDlg), IDCANCEL); 1235c2c66affSColin Finck ShowWindow(hwndControl, SW_HIDE); 1236c2c66affSColin Finck EnableWindow(hwndControl, FALSE); 1237c2c66affSColin Finck 1238c2c66affSColin Finck SendDlgItemMessage( 1239c2c66affSColin Finck hwndDlg, 1240c2c66affSColin Finck IDC_DEVICE, 1241c2c66affSColin Finck WM_SETTEXT, 1242c2c66affSColin Finck 0, 1243c2c66affSColin Finck (LPARAM)DevInstData->drvInfoData.Description); 1244c2c66affSColin Finck 1245c2c66affSColin Finck /* Set title font */ 1246c2c66affSColin Finck SendDlgItemMessage( 1247c2c66affSColin Finck hwndDlg, 1248c2c66affSColin Finck IDC_FINISHTITLE, 1249c2c66affSColin Finck WM_SETFONT, 1250c2c66affSColin Finck (WPARAM)DevInstData->hTitleFont, 1251c2c66affSColin Finck (LPARAM)TRUE); 1252c2c66affSColin Finck break; 1253c2c66affSColin Finck } 1254c2c66affSColin Finck 1255c2c66affSColin Finck case WM_NOTIFY: 1256c2c66affSColin Finck { 1257c2c66affSColin Finck LPNMHDR lpnm = (LPNMHDR)lParam; 1258c2c66affSColin Finck 1259c2c66affSColin Finck switch (lpnm->code) 1260c2c66affSColin Finck { 1261c2c66affSColin Finck case PSN_SETACTIVE: 1262c2c66affSColin Finck /* Enable the correct buttons on for the active page */ 1263c2c66affSColin Finck PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_FINISH); 1264c2c66affSColin Finck break; 1265c2c66affSColin Finck 1266c2c66affSColin Finck case PSN_WIZBACK: 1267c2c66affSColin Finck /* Handle a Back button click, if necessary */ 1268c2c66affSColin Finck break; 1269c2c66affSColin Finck 1270c2c66affSColin Finck case PSN_WIZFINISH: 1271c2c66affSColin Finck /* Handle a Finish button click, if necessary */ 1272c2c66affSColin Finck break; 1273c2c66affSColin Finck 1274c2c66affSColin Finck default: 1275c2c66affSColin Finck break; 1276c2c66affSColin Finck } 1277c2c66affSColin Finck break; 1278c2c66affSColin Finck } 1279c2c66affSColin Finck 1280c2c66affSColin Finck default: 1281c2c66affSColin Finck break; 1282c2c66affSColin Finck } 1283c2c66affSColin Finck 1284c2c66affSColin Finck return FALSE; 1285c2c66affSColin Finck } 1286c2c66affSColin Finck 1287c2c66affSColin Finck static HFONT 1288c2c66affSColin Finck CreateTitleFont(VOID) 1289c2c66affSColin Finck { 1290c2c66affSColin Finck NONCLIENTMETRICSW ncm; 1291c2c66affSColin Finck LOGFONTW LogFont; 1292c2c66affSColin Finck HDC hdc; 1293c2c66affSColin Finck INT FontSize; 1294c2c66affSColin Finck HFONT hFont; 1295c2c66affSColin Finck 1296c2c66affSColin Finck ncm.cbSize = sizeof(NONCLIENTMETRICSW); 1297c2c66affSColin Finck SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0); 1298c2c66affSColin Finck 1299c2c66affSColin Finck LogFont = ncm.lfMessageFont; 1300c2c66affSColin Finck LogFont.lfWeight = FW_BOLD; 1301c2c66affSColin Finck wcscpy(LogFont.lfFaceName, L"MS Shell Dlg"); 1302c2c66affSColin Finck 1303c2c66affSColin Finck hdc = GetDC(NULL); 1304c2c66affSColin Finck FontSize = 12; 1305c2c66affSColin Finck LogFont.lfHeight = 0 - GetDeviceCaps (hdc, LOGPIXELSY) * FontSize / 72; 1306c2c66affSColin Finck hFont = CreateFontIndirectW(&LogFont); 1307c2c66affSColin Finck ReleaseDC(NULL, hdc); 1308c2c66affSColin Finck 1309c2c66affSColin Finck return hFont; 1310c2c66affSColin Finck } 1311c2c66affSColin Finck 1312c2c66affSColin Finck BOOL 1313c2c66affSColin Finck DisplayWizard( 1314c2c66affSColin Finck IN PDEVINSTDATA DevInstData, 1315c2c66affSColin Finck IN HWND hwndParent, 1316c2c66affSColin Finck IN UINT startPage) 1317c2c66affSColin Finck { 1318097355dbSMark Jansen PROPSHEETHEADER psh = {0}; 1319c2c66affSColin Finck HPROPSHEETPAGE ahpsp[IDD_MAXIMUMPAGE + 1]; 1320097355dbSMark Jansen PROPSHEETPAGE psp = {0}; 132162b13979SKatayama Hirofumi MZ HRESULT hr = CoInitialize(NULL); /* for SHAutoComplete */ 1322c2c66affSColin Finck 1323c2c66affSColin Finck /* zero based index */ 1324c2c66affSColin Finck startPage -= IDD_FIRSTPAGE; 1325c2c66affSColin Finck 1326c2c66affSColin Finck /* Create the Welcome page */ 1327c2c66affSColin Finck ZeroMemory(&psp, sizeof(PROPSHEETPAGE)); 1328c2c66affSColin Finck psp.dwSize = sizeof(PROPSHEETPAGE); 1329c2c66affSColin Finck psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER | PSP_USETITLE; 1330c2c66affSColin Finck psp.hInstance = hDllInstance; 1331c2c66affSColin Finck psp.lParam = (LPARAM)DevInstData; 1332c2c66affSColin Finck psp.pszTitle = MAKEINTRESOURCE(DevInstData->bUpdate ? IDS_UPDATEWIZARDTITLE : IDS_INSTALLWIZARDTITLE); 1333c2c66affSColin Finck psp.pfnDlgProc = WelcomeDlgProc; 1334c2c66affSColin Finck psp.pszTemplate = MAKEINTRESOURCE(IDD_WELCOMEPAGE); 1335c2c66affSColin Finck ahpsp[IDD_WELCOMEPAGE-IDD_FIRSTPAGE] = CreatePropertySheetPage(&psp); 1336c2c66affSColin Finck 1337c2c66affSColin Finck /* Create the Select Source page */ 1338c2c66affSColin Finck psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USETITLE; 1339c2c66affSColin Finck psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_CHSOURCE_TITLE); 1340c2c66affSColin Finck psp.pfnDlgProc = CHSourceDlgProc; 1341c2c66affSColin Finck psp.pszTemplate = MAKEINTRESOURCE(IDD_CHSOURCE); 1342c2c66affSColin Finck ahpsp[IDD_CHSOURCE-IDD_FIRSTPAGE] = CreatePropertySheetPage(&psp); 1343c2c66affSColin Finck 1344c2c66affSColin Finck /* Create the Search driver page */ 1345c2c66affSColin Finck psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USETITLE; 1346c2c66affSColin Finck psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_SEARCHDRV_TITLE); 1347c2c66affSColin Finck psp.pfnDlgProc = SearchDrvDlgProc; 1348c2c66affSColin Finck psp.pszTemplate = MAKEINTRESOURCE(IDD_SEARCHDRV); 1349c2c66affSColin Finck ahpsp[IDD_SEARCHDRV-IDD_FIRSTPAGE] = CreatePropertySheetPage(&psp); 1350c2c66affSColin Finck 1351c2c66affSColin Finck /* Create the Install driver page */ 1352c2c66affSColin Finck psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USETITLE; 1353c2c66affSColin Finck psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_INSTALLDRV_TITLE); 1354c2c66affSColin Finck psp.pfnDlgProc = InstallDrvDlgProc; 1355c2c66affSColin Finck psp.pszTemplate = MAKEINTRESOURCE(IDD_INSTALLDRV); 1356c2c66affSColin Finck ahpsp[IDD_INSTALLDRV-IDD_FIRSTPAGE] = CreatePropertySheetPage(&psp); 1357c2c66affSColin Finck 1358c2c66affSColin Finck /* Create the No driver page */ 1359c2c66affSColin Finck psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER | PSP_USETITLE; 1360c2c66affSColin Finck psp.pfnDlgProc = NoDriverDlgProc; 1361c2c66affSColin Finck psp.pszTemplate = MAKEINTRESOURCE(IDD_NODRIVER); 1362c2c66affSColin Finck ahpsp[IDD_NODRIVER-IDD_FIRSTPAGE] = CreatePropertySheetPage(&psp); 1363c2c66affSColin Finck 1364c2c66affSColin Finck /* Create the Install failed page */ 1365c2c66affSColin Finck psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER | PSP_USETITLE; 1366c2c66affSColin Finck psp.pfnDlgProc = InstallFailedDlgProc; 1367c2c66affSColin Finck psp.pszTemplate = MAKEINTRESOURCE(IDD_INSTALLFAILED); 1368c2c66affSColin Finck ahpsp[IDD_INSTALLFAILED-IDD_FIRSTPAGE] = CreatePropertySheetPage(&psp); 1369c2c66affSColin Finck 1370c2c66affSColin Finck /* Create the Need reboot page */ 1371c2c66affSColin Finck psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER | PSP_USETITLE; 1372c2c66affSColin Finck psp.pfnDlgProc = NeedRebootDlgProc; 1373c2c66affSColin Finck psp.pszTemplate = MAKEINTRESOURCE(IDD_NEEDREBOOT); 1374c2c66affSColin Finck ahpsp[IDD_NEEDREBOOT-IDD_FIRSTPAGE] = CreatePropertySheetPage(&psp); 1375c2c66affSColin Finck 1376c2c66affSColin Finck /* Create the Finish page */ 1377c2c66affSColin Finck psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER | PSP_USETITLE; 1378c2c66affSColin Finck psp.pfnDlgProc = FinishDlgProc; 1379c2c66affSColin Finck psp.pszTemplate = MAKEINTRESOURCE(IDD_FINISHPAGE); 1380c2c66affSColin Finck ahpsp[IDD_FINISHPAGE-IDD_FIRSTPAGE] = CreatePropertySheetPage(&psp); 1381c2c66affSColin Finck 1382c2c66affSColin Finck /* Create the property sheet */ 1383c2c66affSColin Finck psh.dwSize = sizeof(PROPSHEETHEADER); 1384c2c66affSColin Finck psh.dwFlags = PSH_WIZARD97 | PSH_WATERMARK | PSH_HEADER; 1385c2c66affSColin Finck psh.hInstance = hDllInstance; 1386c2c66affSColin Finck psh.hwndParent = hwndParent; 1387c2c66affSColin Finck psh.nPages = IDD_MAXIMUMPAGE + 1; 1388c2c66affSColin Finck psh.nStartPage = startPage; 1389c2c66affSColin Finck psh.phpage = ahpsp; 1390c2c66affSColin Finck psh.pszbmWatermark = MAKEINTRESOURCE(IDB_WATERMARK); 1391c2c66affSColin Finck psh.pszbmHeader = MAKEINTRESOURCE(IDB_HEADER); 1392c2c66affSColin Finck 1393c2c66affSColin Finck /* Create title font */ 1394c2c66affSColin Finck DevInstData->hTitleFont = CreateTitleFont(); 1395c2c66affSColin Finck 1396c2c66affSColin Finck /* Display the wizard */ 1397c2c66affSColin Finck PropertySheet(&psh); 1398c2c66affSColin Finck 1399c2c66affSColin Finck DeleteObject(DevInstData->hTitleFont); 1400c2c66affSColin Finck 140162b13979SKatayama Hirofumi MZ if (SUCCEEDED(hr)) 140262b13979SKatayama Hirofumi MZ CoUninitialize(); 1403c2c66affSColin Finck return TRUE; 1404c2c66affSColin Finck } 1405