Files
reactos/reactos/lib/newdev/newdev.c
Thomas Bluemel 2dbda08b7e Add a stub for ClientSideInstallW. umpnpmgr is supposed to run rundll32 in the context of the currently logged on user like this:
"rundll32.exe newdev.dll,ClientSideInstall \\.\pipe\PNP_Device_Install_Pipe_0.{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}"

svn path=/trunk/; revision=19342
2005-11-19 13:27:27 +00:00

1066 lines
28 KiB
C

/*
* 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)
* PROGRAMMERS: Christoph von Wittich (Christoph@ActiveVB.de)
*/
//#define NDEBUG
#include <debug.h>
#include "newdev.h"
static BOOL SearchDriver ( PDEVINSTDATA DevInstData, LPCTSTR Path );
static BOOL InstallDriver ( PDEVINSTDATA DevInstData );
static DWORD WINAPI FindDriverProc( LPVOID lpParam );
static BOOL FindDriver ( PDEVINSTDATA DevInstData );
static DEVINSTDATA DevInstData;
HINSTANCE hDllInstance;
HANDLE hThread;
/*
* @unimplemented
*/
BOOL WINAPI
UpdateDriverForPlugAndPlayDevicesW(
IN HWND hwndParent,
IN LPCWSTR HardwareId,
IN LPCWSTR FullInfPath,
IN DWORD InstallFlags,
OUT PBOOL bRebootRequired OPTIONAL)
{
UNIMPLEMENTED;
SetLastError(ERROR_GEN_FAILURE);
return FALSE;
}
/*
* @implemented
*/
BOOL WINAPI
UpdateDriverForPlugAndPlayDevicesA(
IN HWND hwndParent,
IN LPCSTR HardwareId,
IN LPCSTR FullInfPath,
IN DWORD InstallFlags,
OUT PBOOL bRebootRequired OPTIONAL)
{
BOOL Result;
LPWSTR HardwareIdW = NULL;
LPWSTR FullInfPathW = NULL;
int len = MultiByteToWideChar(CP_ACP, 0, HardwareId, -1, NULL, 0);
HardwareIdW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
if (!HardwareIdW)
{
SetLastError(ERROR_GEN_FAILURE);
return FALSE;
}
MultiByteToWideChar(CP_ACP, 0, HardwareId, -1, HardwareIdW, len);
len = MultiByteToWideChar(CP_ACP, 0, FullInfPath, -1, NULL, 0);
FullInfPathW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
if (!FullInfPathW)
{
HeapFree(GetProcessHeap(), 0, HardwareIdW);
SetLastError(ERROR_GEN_FAILURE);
return FALSE;
}
MultiByteToWideChar(CP_ACP, 0, FullInfPath, -1, FullInfPathW, len);
Result = UpdateDriverForPlugAndPlayDevicesW(hwndParent,
HardwareIdW,
FullInfPathW,
InstallFlags,
bRebootRequired);
HeapFree(GetProcessHeap(), 0, HardwareIdW);
HeapFree(GetProcessHeap(), 0, FullInfPathW);
return Result;
}
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);
}
static INT_PTR CALLBACK
WelcomeDlgProc(
IN HWND hwndDlg,
IN UINT uMsg,
IN WPARAM wParam,
IN LPARAM lParam)
{
PDEVINSTDATA DevInstData;
/* Retrieve pointer to the global setup data */
DevInstData = (PDEVINSTDATA)GetWindowLongPtr (hwndDlg, 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;
}
static INT_PTR CALLBACK
CHSourceDlgProc(
IN HWND hwndDlg,
IN UINT uMsg,
IN WPARAM wParam,
IN LPARAM lParam)
{
PDEVINSTDATA DevInstData;
/* Retrieve pointer to the global setup data */
DevInstData = (PDEVINSTDATA)GetWindowLongPtr (hwndDlg, 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;
}
static INT_PTR CALLBACK
SearchDrvDlgProc(
IN HWND hwndDlg,
IN UINT uMsg,
IN WPARAM wParam,
IN LPARAM lParam)
{
PDEVINSTDATA DevInstData;
DWORD dwThreadId;
/* Retrieve pointer to the global setup data */
DevInstData = (PDEVINSTDATA)GetWindowLongPtr (hwndDlg, 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;
}
static DWORD WINAPI
FindDriverProc(
IN 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))
//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;
}
static INT_PTR CALLBACK
FinishDlgProc(
IN HWND hwndDlg,
IN UINT uMsg,
IN WPARAM wParam,
IN LPARAM lParam)
{
PDEVINSTDATA DevInstData;
/* Retrieve pointer to the global setup data */
DevInstData = (PDEVINSTDATA)GetWindowLongPtr (hwndDlg, 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->drvInfoData.Description);
/* Set title font */
SendDlgItemMessage(hwndDlg,
IDC_FINISHTITLE,
WM_SETFONT,
(WPARAM)DevInstData->hTitleFont,
(LPARAM)TRUE);
}
break;
case WM_NOTIFY:
{
LPNMHDR lpnm = (LPNMHDR)lParam;
switch (lpnm->code)
{
case PSN_SETACTIVE:
/* Enable the correct buttons on for the active page */
PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_FINISH);
break;
case PSN_WIZBACK:
/* Handle a Back button click, if necessary */
break;
case PSN_WIZFINISH:
/* Handle a Finish button click, if necessary */
break;
default:
break;
}
}
break;
default:
break;
}
return FALSE;
}
static INT_PTR CALLBACK
InstFailDlgProc(
IN HWND hwndDlg,
IN UINT uMsg,
IN WPARAM wParam,
IN 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;
}
static BOOL
FindDriver(
IN 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;
}
static BOOL
IsDots(IN LPCTSTR str)
{
if(_tcscmp(str, _T(".")) && _tcscmp(str, _T(".."))) return FALSE;
return TRUE;
}
static LPTSTR
GetFileExt(IN LPTSTR 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("");
}
static BOOL
SearchDriver(
IN PDEVINSTDATA DevInstData,
IN LPCTSTR 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
{
LPCTSTR 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;
}
static BOOL
InstallDriver(
IN 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;
}
static 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)
{
PROPSHEETHEADER psh;
HPROPSHEETPAGE ahpsp[5];
PROPSHEETPAGE psp;
BOOL ret;
DWORD config_flags;
/*TCHAR buf[128];*/
if (!IsUserAdmin())
{
/* XP kills the process... */
ExitProcess(ERROR_ACCESS_DENIED);
}
/* Clear devinst data */
ZeroMemory(&DevInstData, sizeof(DEVINSTDATA));
DevInstData.devInfoData.cbSize = 0; /* Tell if the devInfoData is valid */
DevInstData.hDevInfo = SetupDiCreateDeviceInfoListExW(NULL, NULL, NULL, NULL);
if (DevInstData.hDevInfo == INVALID_HANDLE_VALUE)
{
DPRINT("SetupDiCreateDeviceInfoListExW() failed with error 0x%lx\n", GetLastError());
CleanUp();
return FALSE;
}
DevInstData.devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
ret = SetupDiOpenDeviceInfoW(
DevInstData.hDevInfo,
InstanceId,
NULL,
0, /* Open flags */
&DevInstData.devInfoData);
if (!ret)
{
DPRINT("SetupDiOpenDeviceInfoW() failed with error 0x%lx (InstanceId %S)\n", GetLastError(), InstanceId);
DevInstData.devInfoData.cbSize = 0;
CleanUp();
return FALSE;
}
SetLastError(ERROR_GEN_FAILURE);
ret = SetupDiGetDeviceRegistryProperty(
DevInstData.hDevInfo,
&DevInstData.devInfoData,
SPDRP_DEVICEDESC,
&DevInstData.regDataType,
NULL, 0,
&DevInstData.requiredSize);
if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER && DevInstData.regDataType == REG_SZ)
{
DevInstData.buffer = HeapAlloc(GetProcessHeap(), 0, DevInstData.requiredSize);
if (!DevInstData.buffer)
{
DPRINT("HeapAlloc() failed\n");
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
}
else
{
ret = SetupDiGetDeviceRegistryProperty(
DevInstData.hDevInfo,
&DevInstData.devInfoData,
SPDRP_DEVICEDESC,
&DevInstData.regDataType,
DevInstData.buffer, DevInstData.requiredSize,
&DevInstData.requiredSize);
}
}
if (!ret)
{
DPRINT("SetupDiGetDeviceRegistryProperty() failed with error 0x%lx (InstanceId %S)\n", GetLastError(), InstanceId);
CleanUp();
return FALSE;
}
if(SetupDiGetDeviceRegistryProperty(DevInstData.hDevInfo,
&DevInstData.devInfoData,
SPDRP_CONFIGFLAGS,
NULL,
(BYTE *)&config_flags,
sizeof(config_flags),
NULL))
{
if (config_flags & CONFIGFLAG_FAILEDINSTALL)
{
CleanUp();
return TRUE;
}
}
/*
else
{
swprintf(buf, _T("%ld"), GetLastError());
MessageBox(0,buf,buf,0);
}
*/
DPRINT("Installing %S (%S)\n", DevInstData.buffer, InstanceId);
if ((!FindDriver(&DevInstData)) && (Show != SW_HIDE))
{
/* 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 );
}
CleanUp();
return TRUE;
}
BOOL WINAPI
ClientSideInstallW(IN HWND hWndOwner,
IN DWORD dwUnknownFlags,
IN LPWSTR lpNamedPipeName)
{
/* NOTE: pNamedPipeName is in the format:
* "\\.\pipe\PNP_Device_Install_Pipe_0.{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}"
*/
return FALSE;
}
BOOL WINAPI
DllMain(
IN HINSTANCE hInstance,
IN DWORD dwReason,
IN LPVOID lpReserved)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
INITCOMMONCONTROLSEX InitControls;
DisableThreadLibraryCalls(hInstance);
InitControls.dwSize = sizeof(INITCOMMONCONTROLSEX);
InitControls.dwICC = ICC_PROGRESS_CLASS;
InitCommonControlsEx(&InitControls);
hDllInstance = hInstance;
}
return TRUE;
}