From 775e2dbd070abe62b04c244db1ee82bc4d4aac77 Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Tue, 8 Nov 2005 22:25:29 +0000 Subject: [PATCH] started implementation of device driver installation wizard svn path=/trunk/; revision=19070 --- reactos/lib/newdev/De.rc | 28 +- reactos/lib/newdev/En.rc | 28 +- reactos/lib/newdev/newdev.c | 1051 +++++++++++++++++++++++++++------ reactos/lib/newdev/newdev.h | 18 + reactos/lib/newdev/newdev.xml | 2 + reactos/lib/newdev/resource.h | 18 +- 6 files changed, 930 insertions(+), 215 deletions(-) diff --git a/reactos/lib/newdev/De.rc b/reactos/lib/newdev/De.rc index 4ffcfd61c87..143c4b862ba 100644 --- a/reactos/lib/newdev/De.rc +++ b/reactos/lib/newdev/De.rc @@ -6,15 +6,15 @@ STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | CAPTION "Hardwareinstallation" FONT 8, "MS Shell Dlg" BEGIN - LTEXT "Willkommen",IDC_WELCOMETITLE,115,8,195,24 + LTEXT "Willkommen",IDC_WELCOMETITLE,120,8,195,24 LTEXT "Dieser Assistent installiert einen neuen Gerätetreiber für:", - IDC_STATIC,115,40,195,16 - LTEXT "Klicken Sie auf Weiter um fortzufahren.",IDC_STATIC,115,169,195,17 - LTEXT "UNKNOWN DEVICE",IDC_DEVICE,129,55,164,11 + IDC_STATIC,120,40,195,16 + LTEXT "Klicken Sie auf Weiter um fortzufahren.",IDC_STATIC,120,169,195,17 + LTEXT "UNKNOWN DEVICE",IDC_DEVICE,134,55,164,11 CONTROL "Treiber automatisch installieren",IDC_RADIO_AUTO,"Button", - BS_AUTORADIOBUTTON,115,112,178,13 + BS_AUTORADIOBUTTON,120,112,178,13 CONTROL "Treiber von einer bestimmten Position installieren",IDC_RADIO_MANUAL, - "Button",BS_AUTORADIOBUTTON,115,133,164,14 + "Button",BS_AUTORADIOBUTTON,120,133,164,14 END IDD_NODRIVER DIALOG DISCARDABLE 0, 0, 317, 193 @@ -23,13 +23,13 @@ STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | CAPTION "Hardwareinstallation" FONT 8, "MS Shell Dlg" BEGIN - LTEXT "Installation fehlgeschlagen",IDC_FINISHTITLE,115,8,195,24 + LTEXT "Installation fehlgeschlagen",IDC_FINISHTITLE,120,8,195,24 LTEXT "Der Gerät konnte nicht installiert werden, da kein passender Treiber gefunden werden konnte.", - IDC_STATIC,115,40,195,19 + IDC_STATIC,120,40,195,19 LTEXT "Klicken Sie auf Zurück, wenn Sie eine Treiber CD oder Diskette haben oder den Pfad zum Treiber kennen.", - IDC_STATIC,113,98,181,24 + IDC_STATIC,120,98,181,24 CONTROL "Diesen Dialog nicht mehr anzeigen",IDC_DONOTSHOWDLG,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,114,170,180,11 + BS_AUTOCHECKBOX | WS_TABSTOP,120,170,180,11 END IDD_CHSOURCE DIALOG DISCARDABLE 0, 0, 317, 143 @@ -45,7 +45,7 @@ BEGIN BS_AUTOCHECKBOX | WS_TABSTOP,47,33,163,9 CONTROL "Diesen Pfad ebenfalls durchsuchen",IDC_CHECK_PATH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,50,54,162,10 - PUSHBUTTON "Durchsuchen",IDC_BROWSE,248,69,45,14 + PUSHBUTTON "Durchsuchen",IDC_BROWSE,248,69,50,14 COMBOBOX IDC_COMBO_PATH,64,71,176,12,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP END @@ -64,10 +64,10 @@ STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | CAPTION "Hardwareinstallation" FONT 8, "MS Shell Dlg" BEGIN - LTEXT "Installation abgeschlossen",IDC_FINISHTITLE,115,8,195,11 + LTEXT "Installation abgeschlossen",IDC_FINISHTITLE,120,8,195,11 LTEXT "Der Assistent hat die Installation erfolgreich abgeschlossen.", - IDC_STATIC,115,32,195,19 - LTEXT "Klicken Sie zum Beenden der Installation auf Fertigstellen.",IDC_STATIC,115,174, + IDC_STATIC,120,32,195,19 + LTEXT "Klicken Sie zum Beenden der Installation auf Fertigstellen.",IDC_STATIC,120,174, 190,11 LTEXT "UNKNOWN DEVICE",IDC_DEVICE,148,53,147,12 END diff --git a/reactos/lib/newdev/En.rc b/reactos/lib/newdev/En.rc index 3db088b9f73..13839dbb21f 100644 --- a/reactos/lib/newdev/En.rc +++ b/reactos/lib/newdev/En.rc @@ -6,15 +6,15 @@ STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | CAPTION "Device installation" FONT 8, "MS Shell Dlg" BEGIN - LTEXT "Welcome",IDC_WELCOMETITLE,115,8,195,24 + LTEXT "Welcome",IDC_WELCOMETITLE,120,8,195,24 LTEXT "This wizard installs a new device driver for:", - IDC_STATIC,115,40,195,16 - LTEXT "Click Next to continue.",IDC_STATIC,115,169,195,17 - LTEXT "UNKNOWN DEVICE",IDC_DEVICE,129,55,164,11 + IDC_STATIC,120,40,195,16 + LTEXT "Click Next to continue.",IDC_STATIC,120,169,195,17 + LTEXT "UNKNOWN DEVICE",IDC_DEVICE,134,55,164,11 CONTROL "Install driver automatically",IDC_RADIO_AUTO,"Button", - BS_AUTORADIOBUTTON,115,112,178,13 + BS_AUTORADIOBUTTON,120,112,178,13 CONTROL "Install driver from specific location",IDC_RADIO_MANUAL, - "Button",BS_AUTORADIOBUTTON,115,133,164,14 + "Button",BS_AUTORADIOBUTTON,120,133,164,14 END IDD_NODRIVER DIALOG DISCARDABLE 0, 0, 317, 193 @@ -23,13 +23,13 @@ STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | CAPTION "Device installation" FONT 8, "MS Shell Dlg" BEGIN - LTEXT "Installation failed",IDC_FINISHTITLE,115,8,195,24 + LTEXT "Installation failed",IDC_FINISHTITLE,120,8,195,24 LTEXT "The device could not be installed because the driver could not be found.", - IDC_STATIC,115,40,195,19 + IDC_STATIC,120,40,195,19 LTEXT "Click on Back if you have a driver disk or know the path to the driver.", - IDC_STATIC,113,98,181,24 + IDC_STATIC,120,98,181,24 CONTROL "Do not show this dialog anymore",IDC_DONOTSHOWDLG,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,114,170,180,11 + BS_AUTOCHECKBOX | WS_TABSTOP,120,170,180,11 END IDD_CHSOURCE DIALOG DISCARDABLE 0, 0, 317, 143 @@ -45,7 +45,7 @@ BEGIN BS_AUTOCHECKBOX | WS_TABSTOP,47,33,163,9 CONTROL "Include this path",IDC_CHECK_PATH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,47,54,162,10 - PUSHBUTTON "Browse",IDC_BROWSE,248,69,45,14 + PUSHBUTTON "Browse",IDC_BROWSE,248,69,50,14 COMBOBOX IDC_COMBO_PATH,61,71,176,12,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP END @@ -64,10 +64,10 @@ STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | CAPTION "Device installation" FONT 8, "MS Shell Dlg" BEGIN - LTEXT "Installation complete",IDC_FINISHTITLE,115,8,195,11 + LTEXT "Installation complete",IDC_FINISHTITLE,120,8,195,11 LTEXT "The wizard has finished installing the driver for:", - IDC_STATIC,115,32,195,19 - LTEXT "Click Finish to close the wizard.",IDC_STATIC,115,174, + IDC_STATIC,120,32,195,19 + LTEXT "Click Finish to close the wizard.",IDC_STATIC,120,174, 179,11 LTEXT "UNKNOWN DEVICE",IDC_DEVICE,148,53,147,12 END diff --git a/reactos/lib/newdev/newdev.c b/reactos/lib/newdev/newdev.c index 2bd47ebb80d..9be1285e6d3 100644 --- a/reactos/lib/newdev/newdev.c +++ b/reactos/lib/newdev/newdev.c @@ -1,68 +1,820 @@ /* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS New devices installation - * FILE: lib/newdev/newdev.c - * PURPOSE: New devices installation - * - * PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org) - */ +* COPYRIGHT: See COPYING in the top level directory +* PROJECT: ReactOS New devices installation +* FILE: lib/newdev/newdev.c +* PURPOSE: New devices installation +* +* PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org) +*/ -#define NDEBUG + +//#define NDEBUG #include +#include +#include +#include +#include + +#include #include "newdev.h" +#include "resource.h" + +static DEVINSTDATA DevInstData; +HINSTANCE hDllInstance; +HANDLE hThread; + +static HFONT +CreateTitleFont(VOID) +{ + NONCLIENTMETRICS ncm; + LOGFONT LogFont; + HDC hdc; + INT FontSize; + HFONT hFont; + + ncm.cbSize = sizeof(NONCLIENTMETRICS); + SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0); + + LogFont = ncm.lfMessageFont; + LogFont.lfWeight = FW_BOLD; + _tcscpy(LogFont.lfFaceName, _T("MS Shell Dlg")); + + hdc = GetDC(NULL); + FontSize = 12; + LogFont.lfHeight = 0 - GetDeviceCaps (hdc, LOGPIXELSY) * FontSize / 72; + hFont = CreateFontIndirect(&LogFont); + ReleaseDC(NULL, hdc); + + return hFont; +} + +static VOID +CenterWindow(HWND hWnd) +{ + HWND hWndParent; + RECT rcParent; + RECT rcWindow; + + hWndParent = GetParent(hWnd); + if (hWndParent == NULL) + hWndParent = GetDesktopWindow(); + + GetWindowRect(hWndParent, &rcParent); + GetWindowRect(hWnd, &rcWindow); + + 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); +} + +INT_PTR CALLBACK +WelcomeDlgProc(HWND hwndDlg, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + + PDEVINSTDATA DevInstData; + + /* Retrieve pointer to the global setup data */ + DevInstData = (PDEVINSTDATA)GetWindowLongPtr (hwndDlg, GWL_USERDATA); + + switch (uMsg) + { + case WM_INITDIALOG: + { + HWND hwndControl; + DWORD dwStyle; + + /* Get pointer to the global setup data */ + DevInstData = (PDEVINSTDATA)((LPPROPSHEETPAGE)lParam)->lParam; + SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)DevInstData); + + hwndControl = GetParent(hwndDlg); + + /* Center the wizard window */ + CenterWindow (hwndControl); + + /* Hide the system menu */ + dwStyle = GetWindowLong(hwndControl, GWL_STYLE); + SetWindowLong(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); + + + } + 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) + PropSheet_SetCurSel(GetParent(hwndDlg), 0, IDD_SEARCHDRV); + + break; + + default: + break; + } + } + break; + + default: + break; + } + + return FALSE; +} + +INT_PTR CALLBACK +CHSourceDlgProc(HWND hwndDlg, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + + PDEVINSTDATA DevInstData; + + /* Retrieve pointer to the global setup data */ + DevInstData = (PDEVINSTDATA)GetWindowLongPtr (hwndDlg, GWL_USERDATA); + + switch (uMsg) + { + case WM_INITDIALOG: + { + HWND hwndControl; + DWORD dwStyle; + + /* Get pointer to the global setup data */ + DevInstData = (PDEVINSTDATA)((LPPROPSHEETPAGE)lParam)->lParam; + SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)DevInstData); + + hwndControl = GetParent(hwndDlg); + + /* Center the wizard window */ + CenterWindow (hwndControl); + + /* Hide the system menu */ + dwStyle = GetWindowLong(hwndControl, GWL_STYLE); + SetWindowLong(hwndControl, GWL_STYLE, dwStyle & ~WS_SYSMENU); + + SendDlgItemMessage(hwndDlg, + IDC_RADIO_SEARCHHERE, + BM_SETCHECK, + (WPARAM) TRUE, + (LPARAM) 0); + + + } + 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 */ + PropSheet_SetCurSel(GetParent(hwndDlg), 0, 4); + break; + + default: + break; + } + } + break; + + default: + break; + } + + return FALSE; +} + +INT_PTR CALLBACK +SearchDrvDlgProc(HWND hwndDlg, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + + PDEVINSTDATA DevInstData; + DWORD dwThreadId; + + /* Retrieve pointer to the global setup data */ + DevInstData = (PDEVINSTDATA)GetWindowLongPtr (hwndDlg, GWL_USERDATA); + + switch (uMsg) + { + case WM_INITDIALOG: + { + HWND hwndControl; + DWORD dwStyle; + + /* Get pointer to the global setup data */ + DevInstData = (PDEVINSTDATA)((LPPROPSHEETPAGE)lParam)->lParam; + SetWindowLongPtr(hwndDlg, GWL_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 = GetWindowLong(hwndControl, GWL_STYLE); + SetWindowLong(hwndControl, GWL_STYLE, dwStyle & ~WS_SYSMENU); + } + break; + + case WM_SEARCH_FINISHED: + { + CloseHandle(hThread); + hThread = 0; + if (wParam == 0) + PropSheet_SetCurSel(GetParent(hwndDlg), 0, IDD_NODRIVER); + else + PropSheet_SetCurSel(GetParent(hwndDlg), 0, IDD_FINISHPAGE); + 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, FindDriverProc, DevInstData, 0, &dwThreadId); + break; + + case PSN_KILLACTIVE: + if (hThread != 0) { + SetWindowLong ( hwndDlg, DWL_MSGRESULT, TRUE); + return TRUE; + } + break; + case PSN_WIZNEXT: + /* Handle a Next button click, if necessary */ + break; + + default: + break; + } + } + break; + + default: + break; + } + + return FALSE; +} + +DWORD WINAPI FindDriverProc( LPVOID lpParam ) +{ + TCHAR drive[] = {'?',':',0}; + size_t nType; + DWORD dwDrives; + PDEVINSTDATA DevInstData; + UINT i = 1; + + DevInstData = (PDEVINSTDATA)lpParam; + + dwDrives = GetLogicalDrives(); + for (drive[0] = 'A'; drive[0] <= 'Z'; drive[0]++) { + if (dwDrives & i) { + nType = GetDriveType( drive ); + if ((nType == DRIVE_CDROM) || (nType == DRIVE_FIXED)) { + /* search for inf file */ + if (SearchDriver ( DevInstData, drive )) { + /* if we found a valid driver inf... */ + if (FindDriver ( DevInstData )) { + InstallDriver ( DevInstData ); + PostMessage(DevInstData->hDialog, WM_SEARCH_FINISHED, 1, 0); + return 0; + } + } + } + } + i <<= 1; + } + + PostMessage(DevInstData->hDialog, WM_SEARCH_FINISHED, 0, 0); + return 0; +} + +INT_PTR CALLBACK +FinishDlgProc(HWND hwndDlg, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + + PDEVINSTDATA DevInstData; + + /* Retrieve pointer to the global setup data */ + DevInstData = (PDEVINSTDATA)GetWindowLongPtr (hwndDlg, GWL_USERDATA); + + switch (uMsg) + { + case WM_INITDIALOG: + { + HWND hwndControl; + + /* Get pointer to the global setup data */ + DevInstData = (PDEVINSTDATA)((LPPROPSHEETPAGE)lParam)->lParam; + SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)DevInstData); + + hwndControl = GetDlgItem(GetParent(hwndDlg), IDCANCEL); + ShowWindow (hwndControl, SW_HIDE); + EnableWindow (hwndControl, FALSE); + + SendDlgItemMessage(hwndDlg, + IDC_DEVICE, + WM_SETTEXT, + 0, + (LPARAM) DevInstData->buffer); + + /* 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; +} + +INT_PTR CALLBACK +InstFailDlgProc(HWND hwndDlg, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + + PDEVINSTDATA DevInstData; + + /* Get pointer to the global setup data */ + DevInstData = (PDEVINSTDATA)GetWindowLongPtr (hwndDlg, GWL_USERDATA); + + switch (uMsg) + { + case WM_INITDIALOG: + { + HWND hwndControl; + + DevInstData = (PDEVINSTDATA)((LPPROPSHEETPAGE)lParam)->lParam; + SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)DevInstData); + + 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); + } + break; + + case WM_NOTIFY: + { + LPNMHDR lpnm = (LPNMHDR)lParam; + DWORD config_flags; + BOOL ret; + + 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: + PropSheet_SetCurSel(GetParent(hwndDlg), 0, IDD_WELCOMEPAGE); + /* Handle a Back button click, if necessary */ + break; + + case PSN_WIZFINISH: + /* Handle a Finish button click, if necessary */ + if (SendDlgItemMessage(hwndDlg, IDC_DONOTSHOWDLG, BM_GETCHECK, (WPARAM) 0, (LPARAM) 0) == BST_CHECKED) { + + if(SetupDiGetDeviceRegistryProperty(DevInstData->hDevInfo, + &DevInstData->devInfoData, + SPDRP_CONFIGFLAGS, + NULL, + (BYTE *)&config_flags, + sizeof(config_flags), + NULL)) + { + config_flags |= CONFIGFLAG_FAILEDINSTALL; + ret = SetupDiSetDeviceRegistryProperty( + DevInstData->hDevInfo, + &DevInstData->devInfoData, + SPDRP_CONFIGFLAGS, + NULL, 0 ); + } + + } + break; + + default: + break; + } + } + break; + + default: + break; + } + + return FALSE; +} + + +BOOL FindDriver ( PDEVINSTDATA DevInstData ) { + BOOL ret; + + ret = SetupDiBuildDriverInfoList(DevInstData->hDevInfo, &DevInstData->devInfoData, SPDIT_COMPATDRIVER); + if (!ret) + { + DPRINT("SetupDiBuildDriverInfoList() failed with error 0x%lx\n", GetLastError()); + return FALSE; + } + + DevInstData->drvInfoData.cbSize = sizeof(SP_DRVINFO_DATA); + ret = SetupDiEnumDriverInfo( + DevInstData->hDevInfo, + &DevInstData->devInfoData, + SPDIT_COMPATDRIVER, + 0, + &DevInstData->drvInfoData); + if (!ret) + { + if (GetLastError() == ERROR_NO_MORE_ITEMS) + return FALSE; + DPRINT("SetupDiEnumDriverInfo() failed with error 0x%lx\n", GetLastError()); + return FALSE; + } + DPRINT("Installing driver %S: %S\n", DevInstData->drvInfoData.MfgName, DevInstData->drvInfoData.Description); + + return TRUE; +} + + +BOOL IsDots(const TCHAR* str) { + if(_tcscmp(str, _T(".")) && _tcscmp(str, _T(".."))) return FALSE; + return TRUE; +} + +TCHAR* GetFileExt(TCHAR* FileName) +{ + if (FileName == 0) + return _T(""); + + int i = _tcsclen(FileName); + while ((i >= 0) && (FileName[i] != _T('.'))) + i--; + + FileName = _tcslwr(FileName); + + if (i >= 0) + return &FileName[i]; + else + return _T(""); +} + +BOOL SearchDriver ( PDEVINSTDATA DevInstData, const TCHAR* Path ) { + WIN32_FIND_DATA wfd; + SP_DEVINSTALL_PARAMS DevInstallParams; + TCHAR DirPath[MAX_PATH]; + TCHAR FileName[MAX_PATH]; + TCHAR FullPath[MAX_PATH]; + TCHAR LastDirPath[MAX_PATH] = _T(""); + TCHAR PathWithPattern[MAX_PATH]; + BOOL ok = TRUE; + BOOL ret; + HANDLE hFindFile; + + _tcscpy(DirPath, Path); + + if (DirPath[_tcsclen(DirPath) - 1] != '\\') + _tcscat(DirPath, _T("\\")); + + _tcscpy(PathWithPattern, DirPath); + _tcscat(PathWithPattern, _T("\\*")); + + for (hFindFile = FindFirstFile(PathWithPattern, &wfd); ((hFindFile != INVALID_HANDLE_VALUE) && ok); ok = FindNextFile(hFindFile, &wfd)) + { + + _tcscpy(FileName, wfd.cFileName); + if(IsDots(FileName)) continue; + + if((wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { + _tcscpy(FullPath, DirPath); + _tcscat(FullPath, FileName); + if(SearchDriver(DevInstData, FullPath)) + break; + } + else { + TCHAR* pszExtension = GetFileExt(FileName); + + if ((_tcscmp(pszExtension, _T(".inf")) == 0) && (_tcscmp(LastDirPath, DirPath) != 0)){ + _tcscpy(LastDirPath, DirPath); + ZeroMemory (&DevInstallParams, sizeof(SP_DEVINSTALL_PARAMS)); + DevInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS); + + ret = SetupDiGetDeviceInstallParams( + DevInstData->hDevInfo, + &DevInstData->devInfoData, + &DevInstallParams); + + if (_tcsclen(DirPath) <= MAX_PATH) { + memcpy(DevInstallParams.DriverPath, DirPath, (_tcsclen(DirPath) + 1) * sizeof(TCHAR)); + } + + ret = SetupDiSetDeviceInstallParams( + DevInstData->hDevInfo, + &DevInstData->devInfoData, + &DevInstallParams); + + if ( FindDriver ( DevInstData ) ) { + if (hFindFile != INVALID_HANDLE_VALUE) + FindClose(hFindFile); + return TRUE; + } + + } + } + } + + if (hFindFile != INVALID_HANDLE_VALUE) + FindClose(hFindFile); + + return FALSE; +} + +BOOL InstallDriver ( PDEVINSTDATA DevInstData ) { + BOOL ret; + + ret = SetupDiCallClassInstaller( + DIF_SELECTBESTCOMPATDRV, + DevInstData->hDevInfo, + &DevInstData->devInfoData); + if (!ret) + { + DPRINT("SetupDiCallClassInstaller(DIF_SELECTBESTCOMPATDRV) failed with error 0x%lx\n", GetLastError()); + return FALSE; + } + + ret = SetupDiCallClassInstaller( + DIF_ALLOW_INSTALL, + DevInstData->hDevInfo, + &DevInstData->devInfoData); + if (!ret) + { + DPRINT("SetupDiCallClassInstaller(DIF_ALLOW_INSTALL) failed with error 0x%lx\n", GetLastError()); + return FALSE; + } + + ret = SetupDiCallClassInstaller( + DIF_NEWDEVICEWIZARD_PREANALYZE, + DevInstData->hDevInfo, + &DevInstData->devInfoData); + if (!ret) + { + DPRINT("SetupDiCallClassInstaller(DIF_NEWDEVICEWIZARD_PREANALYZE) failed with error 0x%lx\n", GetLastError()); + return FALSE; + } + + ret = SetupDiCallClassInstaller( + DIF_NEWDEVICEWIZARD_POSTANALYZE, + DevInstData->hDevInfo, + &DevInstData->devInfoData); + if (!ret) + { + DPRINT("SetupDiCallClassInstaller(DIF_NEWDEVICEWIZARD_POSTANALYZE) failed with error 0x%lx\n", GetLastError()); + return FALSE; + } + + ret = SetupDiCallClassInstaller( + DIF_INSTALLDEVICEFILES, + DevInstData->hDevInfo, + &DevInstData->devInfoData); + if (!ret) + { + DPRINT("SetupDiCallClassInstaller(DIF_INSTALLDEVICEFILES) failed with error 0x%lx\n", GetLastError()); + return FALSE; + } + + ret = SetupDiCallClassInstaller( + DIF_REGISTER_COINSTALLERS, + DevInstData->hDevInfo, + &DevInstData->devInfoData); + if (!ret) + { + DPRINT("SetupDiCallClassInstaller(DIF_REGISTER_COINSTALLERS) failed with error 0x%lx\n", GetLastError()); + return FALSE; + } + + ret = SetupDiCallClassInstaller( + DIF_INSTALLINTERFACES, + DevInstData->hDevInfo, + &DevInstData->devInfoData); + if (!ret) + { + DPRINT("SetupDiCallClassInstaller(DIF_INSTALLINTERFACES) failed with error 0x%lx\n", GetLastError()); + return FALSE; + } + + ret = SetupDiCallClassInstaller( + DIF_INSTALLDEVICE, + DevInstData->hDevInfo, + &DevInstData->devInfoData); + if (!ret) + { + DPRINT("SetupDiCallClassInstaller(DIF_INSTALLDEVICE) failed with error 0x%lx\n", GetLastError()); + return FALSE; + } + + ret = SetupDiCallClassInstaller( + DIF_NEWDEVICEWIZARD_FINISHINSTALL, + DevInstData->hDevInfo, + &DevInstData->devInfoData); + if (!ret) + { + DPRINT("SetupDiCallClassInstaller(DIF_NEWDEVICEWIZARD_FINISHINSTALL) failed with error 0x%lx\n", GetLastError()); + return FALSE; + } + + ret = SetupDiCallClassInstaller( + DIF_DESTROYPRIVATEDATA, + DevInstData->hDevInfo, + &DevInstData->devInfoData); + if (!ret) + { + DPRINT("SetupDiCallClassInstaller(DIF_DESTROYPRIVATEDATA) failed with error 0x%lx\n", GetLastError()); + return FALSE; + } + + return TRUE; + +} + +void CleanUp ( void ) { + + if (DevInstData.devInfoData.cbSize != 0) + { + if (!SetupDiDestroyDriverInfoList(DevInstData.hDevInfo, &DevInstData.devInfoData, SPDIT_COMPATDRIVER)) + DPRINT("SetupDiDestroyDriverInfoList() failed with error 0x%lx\n", GetLastError()); + } + + if (DevInstData.hDevInfo != INVALID_HANDLE_VALUE) + { + if (!SetupDiDestroyDeviceInfoList(DevInstData.hDevInfo)) + DPRINT("SetupDiDestroyDeviceInfoList() failed with error 0x%lx\n", GetLastError()); + } + + if (DevInstData.buffer) + HeapFree(GetProcessHeap(), 0, DevInstData.buffer); + +} BOOL WINAPI DevInstallW( - IN HWND hWndParent, - IN HINSTANCE hInstance, - IN LPCWSTR InstanceId, - IN INT Show) + IN HWND hWndParent, + IN HINSTANCE hInstance, + IN LPCWSTR InstanceId, + IN INT Show) { - HDEVINFO hDevInfo; - SP_DEVINFO_DATA devInfoData; - DWORD requiredSize; - DWORD regDataType; - PBYTE buffer = NULL; - SP_DRVINFO_DATA drvInfoData; + + PROPSHEETHEADER psh; + HPROPSHEETPAGE ahpsp[5]; + PROPSHEETPAGE psp; BOOL ret; - devInfoData.cbSize = 0; /* Tell if the devInfoData is valid */ + /* Clear devinst data */ + ZeroMemory(&DevInstData, sizeof(DEVINSTDATA)); + DevInstData.devInfoData.cbSize = 0; /* Tell if the devInfoData is valid */ - hDevInfo = SetupDiCreateDeviceInfoListExW(NULL, NULL, NULL, NULL); - if (hDevInfo == INVALID_HANDLE_VALUE) + + DevInstData.hDevInfo = SetupDiCreateDeviceInfoListExW(NULL, NULL, NULL, NULL); + if (DevInstData.hDevInfo == INVALID_HANDLE_VALUE) { DPRINT("SetupDiCreateDeviceInfoListExW() failed with error 0x%lx\n", GetLastError()); - ret = FALSE; - goto cleanup; + CleanUp(); + return FALSE; } - devInfoData.cbSize = sizeof(SP_DEVINFO_DATA); + DevInstData.devInfoData.cbSize = sizeof(SP_DEVINFO_DATA); ret = SetupDiOpenDeviceInfoW( - hDevInfo, + DevInstData.hDevInfo, InstanceId, NULL, 0, /* Open flags */ - &devInfoData); + &DevInstData.devInfoData); if (!ret) { DPRINT("SetupDiOpenDeviceInfoW() failed with error 0x%lx\n", GetLastError()); - devInfoData.cbSize = 0; - goto cleanup; + DevInstData.devInfoData.cbSize = 0; + CleanUp(); + return FALSE; } SetLastError(ERROR_GEN_FAILURE); ret = SetupDiGetDeviceRegistryProperty( - hDevInfo, - &devInfoData, + DevInstData.hDevInfo, + &DevInstData.devInfoData, SPDRP_DEVICEDESC, - ®DataType, + &DevInstData.regDataType, NULL, 0, - &requiredSize); - if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER && regDataType == REG_SZ) + &DevInstData.requiredSize); + + if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER && DevInstData.regDataType == REG_SZ) { - buffer = HeapAlloc(GetProcessHeap(), 0, requiredSize); - if (!buffer) + DevInstData.buffer = HeapAlloc(GetProcessHeap(), 0, DevInstData.requiredSize); + if (!DevInstData.buffer) { DPRINT("HeapAlloc() failed\n"); SetLastError(ERROR_NOT_ENOUGH_MEMORY); @@ -70,158 +822,101 @@ DevInstallW( else { ret = SetupDiGetDeviceRegistryProperty( - hDevInfo, - &devInfoData, + DevInstData.hDevInfo, + &DevInstData.devInfoData, SPDRP_DEVICEDESC, - ®DataType, - buffer, requiredSize, - &requiredSize); + &DevInstData.regDataType, + DevInstData.buffer, DevInstData.requiredSize, + &DevInstData.requiredSize); } } if (!ret) { DPRINT("SetupDiGetDeviceRegistryProperty() failed with error 0x%lx\n", GetLastError()); - goto cleanup; + CleanUp(); + return FALSE; } - DPRINT("Installing %s (%S)\n", buffer, InstanceId); + DPRINT("Installing %S (%S)\n", DevInstData.buffer, InstanceId); - ret = SetupDiBuildDriverInfoList(hDevInfo, &devInfoData, SPDIT_COMPATDRIVER); - if (!ret) - { - DPRINT("SetupDiBuildDriverInfoList() failed with error 0x%lx\n", GetLastError()); - goto cleanup; + if ((Show =! SW_HIDE) && (!FindDriver(&DevInstData))) { + + /* Create the Welcome page */ + ZeroMemory (&psp, sizeof(PROPSHEETPAGE)); + psp.dwSize = sizeof(PROPSHEETPAGE); + psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER; + psp.hInstance = hDllInstance; + psp.lParam = (LPARAM)&DevInstData; + psp.pfnDlgProc = WelcomeDlgProc; + psp.pszTemplate = MAKEINTRESOURCE(IDD_WELCOMEPAGE); + ahpsp[IDD_WELCOMEPAGE] = CreatePropertySheetPage(&psp); + + /* Create the Select Source page */ + psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE; + psp.pfnDlgProc = CHSourceDlgProc; + psp.pszTemplate = MAKEINTRESOURCE(IDD_CHSOURCE); + ahpsp[IDD_CHSOURCE] = CreatePropertySheetPage(&psp); + + /* Create the Search driver page */ + psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE; + psp.pfnDlgProc = SearchDrvDlgProc; + psp.pszTemplate = MAKEINTRESOURCE(IDD_SEARCHDRV); + ahpsp[IDD_SEARCHDRV] = CreatePropertySheetPage(&psp); + + /* Create the Finish page */ + psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER; + psp.pfnDlgProc = FinishDlgProc; + psp.pszTemplate = MAKEINTRESOURCE(IDD_FINISHPAGE); + ahpsp[IDD_FINISHPAGE] = CreatePropertySheetPage(&psp); + + /* Create the Install failed page */ + psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER; + psp.pfnDlgProc = InstFailDlgProc; + psp.pszTemplate = MAKEINTRESOURCE(IDD_NODRIVER); + ahpsp[IDD_NODRIVER] = CreatePropertySheetPage(&psp); + + /* Create the property sheet */ + psh.dwSize = sizeof(PROPSHEETHEADER); + psh.dwFlags = PSH_WIZARD97 | PSH_WATERMARK | PSH_HEADER; + psh.hInstance = hDllInstance; + psh.hwndParent = NULL; + psh.nPages = 5; + psh.nStartPage = 0; + 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); + + } + else { + InstallDriver ( &DevInstData ); } - drvInfoData.cbSize = sizeof(SP_DRVINFO_DATA); - ret = SetupDiEnumDriverInfo( - hDevInfo, - &devInfoData, - SPDIT_COMPATDRIVER, - 0, - &drvInfoData); - if (!ret) - { - DPRINT("SetupDiEnumDriverInfo() failed with error 0x%lx\n", GetLastError()); - goto cleanup; - } - DPRINT("Installing driver %s: %s\n", drvInfoData.MfgName, drvInfoData.Description); - - ret = SetupDiCallClassInstaller( - DIF_SELECTBESTCOMPATDRV, - hDevInfo, - &devInfoData); - if (!ret) - { - DPRINT("SetupDiCallClassInstaller(DIF_SELECTBESTCOMPATDRV) failed with error 0x%lx\n", GetLastError()); - goto cleanup; - } - - ret = SetupDiCallClassInstaller( - DIF_ALLOW_INSTALL, - hDevInfo, - &devInfoData); - if (!ret) - { - DPRINT("SetupDiCallClassInstaller(DIF_ALLOW_INSTALL) failed with error 0x%lx\n", GetLastError()); - goto cleanup; - } - - ret = SetupDiCallClassInstaller( - DIF_NEWDEVICEWIZARD_PREANALYZE, - hDevInfo, - &devInfoData); - if (!ret) - { - DPRINT("SetupDiCallClassInstaller(DIF_NEWDEVICEWIZARD_PREANALYZE) failed with error 0x%lx\n", GetLastError()); - goto cleanup; - } - - ret = SetupDiCallClassInstaller( - DIF_NEWDEVICEWIZARD_POSTANALYZE, - hDevInfo, - &devInfoData); - if (!ret) - { - DPRINT("SetupDiCallClassInstaller(DIF_NEWDEVICEWIZARD_POSTANALYZE) failed with error 0x%lx\n", GetLastError()); - goto cleanup; - } - - ret = SetupDiCallClassInstaller( - DIF_INSTALLDEVICEFILES, - hDevInfo, - &devInfoData); - if (!ret) - { - DPRINT("SetupDiCallClassInstaller(DIF_INSTALLDEVICEFILES) failed with error 0x%lx\n", GetLastError()); - goto cleanup; - } - - ret = SetupDiCallClassInstaller( - DIF_REGISTER_COINSTALLERS, - hDevInfo, - &devInfoData); - if (!ret) - { - DPRINT("SetupDiCallClassInstaller(DIF_REGISTER_COINSTALLERS) failed with error 0x%lx\n", GetLastError()); - goto cleanup; - } - - ret = SetupDiCallClassInstaller( - DIF_INSTALLINTERFACES, - hDevInfo, - &devInfoData); - if (!ret) - { - DPRINT("SetupDiCallClassInstaller(DIF_INSTALLINTERFACES) failed with error 0x%lx\n", GetLastError()); - goto cleanup; - } - - ret = SetupDiCallClassInstaller( - DIF_INSTALLDEVICE, - hDevInfo, - &devInfoData); - if (!ret) - { - DPRINT("SetupDiCallClassInstaller(DIF_INSTALLDEVICE) failed with error 0x%lx\n", GetLastError()); - goto cleanup; - } - - ret = SetupDiCallClassInstaller( - DIF_NEWDEVICEWIZARD_FINISHINSTALL, - hDevInfo, - &devInfoData); - if (!ret) - { - DPRINT("SetupDiCallClassInstaller(DIF_NEWDEVICEWIZARD_FINISHINSTALL) failed with error 0x%lx\n", GetLastError()); - goto cleanup; - } - - ret = SetupDiCallClassInstaller( - DIF_DESTROYPRIVATEDATA, - hDevInfo, - &devInfoData); - if (!ret) - { - DPRINT("SetupDiCallClassInstaller(DIF_DESTROYPRIVATEDATA) failed with error 0x%lx\n", GetLastError()); - goto cleanup; - } - -cleanup: - if (devInfoData.cbSize != 0) - { - if (!SetupDiDestroyDriverInfoList(hDevInfo, &devInfoData, SPDIT_COMPATDRIVER)) - DPRINT("SetupDiDestroyDriverInfoList() failed with error 0x%lx\n", GetLastError()); - } - - if (hDevInfo != INVALID_HANDLE_VALUE) - { - if (!SetupDiDestroyDeviceInfoList(hDevInfo)) - DPRINT("SetupDiDestroyDeviceInfoList() failed with error 0x%lx\n", GetLastError()); - } - - if (buffer) - HeapFree(GetProcessHeap(), 0, buffer); - - return ret; + CleanUp(); + return TRUE; +} + +BOOL STDCALL +DllMain (HINSTANCE hInstance, + DWORD dwReason, + LPVOID lpReserved) +{ + if (dwReason == DLL_PROCESS_ATTACH) + { + INITCOMMONCONTROLSEX InitControls; + + InitControls.dwSize = sizeof(INITCOMMONCONTROLSEX); + InitControls.dwICC = ICC_PROGRESS_CLASS; + InitCommonControlsEx(&InitControls); + hDllInstance = hInstance; + } + + return TRUE; } diff --git a/reactos/lib/newdev/newdev.h b/reactos/lib/newdev/newdev.h index 518182042ca..cdbd8265b09 100644 --- a/reactos/lib/newdev/newdev.h +++ b/reactos/lib/newdev/newdev.h @@ -3,3 +3,21 @@ ULONG DbgPrint(PCH Format,...); +typedef struct _DEVINSTDATA +{ + HFONT hTitleFont; + PBYTE buffer; + DWORD requiredSize; + DWORD regDataType; + HWND hDialog; + HDEVINFO hDevInfo; + SP_DEVINFO_DATA devInfoData; + SP_DRVINFO_DATA drvInfoData; +} DEVINSTDATA, *PDEVINSTDATA; + +BOOL SearchDriver ( PDEVINSTDATA DevInstData, const TCHAR* Path ); +BOOL InstallDriver ( PDEVINSTDATA DevInstData ); +DWORD WINAPI FindDriverProc( LPVOID lpParam ); +BOOL FindDriver ( PDEVINSTDATA DevInstData ); + +#define WM_SEARCH_FINISHED (WM_USER + 10) diff --git a/reactos/lib/newdev/newdev.xml b/reactos/lib/newdev/newdev.xml index 79e54400bec..ebf81e78fda 100644 --- a/reactos/lib/newdev/newdev.xml +++ b/reactos/lib/newdev/newdev.xml @@ -1,5 +1,7 @@ . + + 0x0600 0x0501 diff --git a/reactos/lib/newdev/resource.h b/reactos/lib/newdev/resource.h index 0547827c0e3..fad5d93a7ec 100644 --- a/reactos/lib/newdev/resource.h +++ b/reactos/lib/newdev/resource.h @@ -1,10 +1,10 @@ #ifndef RESOURCE_H #define RESOURCE_H -#define IDB_WATERMARK 100 -#define IDB_HEADER 101 +#define IDB_WATERMARK 100 +#define IDB_HEADER 101 -#define IDC_STATIC -1 +#define IDC_STATIC -1 #define IDC_DEVICE 2000 #define IDC_RADIO_AUTO 2001 @@ -14,15 +14,15 @@ #define IDC_RADIO_CHOOSE 2005 #define IDC_CHECK_MEDIA 2006 #define IDC_CHECK_PATH 2007 -#define IDC_WELCOMETITLE 2008 +#define IDC_WELCOMETITLE 2008 #define IDC_BROWSE 2009 #define IDC_COMBO_PATH 2010 #define IDC_FINISHTITLE 2011 -#define IDD_WELCOMEPAGE 1000 -#define IDD_NODRIVER 1001 -#define IDD_CHSOURCE 1002 -#define IDD_SEARCHDRV 1003 -#define IDD_FINISHPAGE 1004 +#define IDD_WELCOMEPAGE 0 +#define IDD_CHSOURCE 1 +#define IDD_SEARCHDRV 2 +#define IDD_FINISHPAGE 3 +#define IDD_NODRIVER 4 #endif /* RESOURCE_H */