Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1377 lines
42 KiB

#include "nt.h"
#include "ntrtl.h"
#include "nturtl.h"
#include <windows.h>
#include <initguid.h>
#include <devguid.h>
#include "tchar.h"
#include "string.h"
#include <setupapi.h>
#include <syssetup.h>
#include <regstr.h>
#include <setupbat.h>
#include <cfgmgr32.h>
#include "settings.h"
#include "setinc.h"
ULONG PreConfigured;
ULONG KeepEnabled;
BOOL
CALLBACK
AddPropSheetPageProc(
IN HPROPSHEETPAGE hpage,
IN LPARAM lParam
)
{
*((HPROPSHEETPAGE *)lParam) = hpage;
return TRUE;
}
DWORD
DisplayClassInstaller(
IN DI_FUNCTION InstallFunction,
IN HDEVINFO hDevInfo,
IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL
)
/*++
Routine Description:
This routine acts as the class installer for Display devices.
Arguments:
InstallFunction - Specifies the device installer function code indicating
the action being performed.
DeviceInfoSet - Supplies a handle to the device information set being
acted upon by this install action.
DeviceInfoData - Optionally, supplies the address of a device information
element being acted upon by this install action.
Return Value:
If this function successfully completed the requested action, the return
value is NO_ERROR.
If the default behavior is to be performed for the requested action, the
return value is ERROR_DI_DO_DEFAULT.
If an error occurred while attempting to perform the requested action, a
Win32 error code is returned.
--*/
{
DWORD err;
SP_DRVINFO_DATA DrvInfoData;
KdPrint(("DisplayClassInstaller function = %d\n", (DWORD) InstallFunction));
switch(InstallFunction) {
case DIF_SELECTDEVICE :
KdPrint(("DisplayClassInstaller DELECTDEVICE \n"));
if (SetupDiBuildDriverInfoList(hDevInfo, NULL, SPDIT_CLASSDRIVER))
{
if (!SetupDiEnumDriverInfo(hDevInfo,
NULL,
SPDIT_CLASSDRIVER,
0,
&DrvInfoData))
{
if (GetLastError() == ERROR_NO_MORE_ITEMS)
{
//
// This is what happens when an old inf is loaded.
// Tell the user it is an old inf.
//
FmtMessageBox(ghwndPropSheet, // BUGBUG
MB_ICONEXCLAMATION,
FALSE,
ID_DSP_TXT_INSTALL_DRIVER,
ID_DSP_TXT_BAD_INF);
return ERROR_NO_MORE_ITEMS;
}
}
}
break;
//
// we do not handle the following message because we are not
// plug-and-play yet.
//
// case DIF_INSTALLDEVICE :
default :
break;
}
//
// If we did not exit from the routine by handling the call, tell the
// setup code to handle everything the default way.
//
return ERROR_DI_DO_DEFAULT;
}
VOID
SetSelectDevParams(
HDEVINFO hDevInfo
)
/*++
Routine Description:
Sets the select device parameters by calling setup apis
Arguments:
hDevInfo : Handle to the printer class device information list
--*/
{
SP_SELECTDEVICE_PARAMS SelectDevParams;
SP_DEVINSTALL_PARAMS DeviceInstallParams;
ZeroMemory(&SelectDevParams, sizeof(SelectDevParams));
SelectDevParams.ClassInstallHeader.cbSize
= sizeof(SelectDevParams.ClassInstallHeader);
SelectDevParams.ClassInstallHeader.InstallFunction
= DIF_SELECTDEVICE;
//
// Get current SelectDevice parameters, and then set the fields
// we want to be different from default
//
SetupDiGetClassInstallParams(hDevInfo,
NULL,
&SelectDevParams.ClassInstallHeader,
sizeof(SelectDevParams),
NULL);
SelectDevParams.ClassInstallHeader.cbSize
= sizeof(SelectDevParams.ClassInstallHeader);
SelectDevParams.ClassInstallHeader.InstallFunction
= DIF_SELECTDEVICE;
//
// Set the strings to use on the select driver page .
//
LoadString(ghmod,
IDS_DISPLAYINST,
SelectDevParams.Title,
sizeof(SelectDevParams.Title));
LoadString(ghmod,
IDS_WINNTDEV_INSTRUCT,
SelectDevParams.Instructions,
sizeof(SelectDevParams.Instructions));
LoadString(ghmod,
IDS_SELECTDEV_LABEL,
SelectDevParams.ListLabel,
sizeof(SelectDevParams.ListLabel));
SetupDiSetClassInstallParams(hDevInfo,
NULL,
&SelectDevParams.ClassInstallHeader,
sizeof(SelectDevParams));
DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
SetupDiGetDeviceInstallParams(hDevInfo,
NULL,
&DeviceInstallParams);
DeviceInstallParams.Flags |= DI_USECI_SELECTSTRINGS | DI_SHOWOEM;
SetupDiSetDeviceInstallParams(hDevInfo,
NULL,
&DeviceInstallParams);
}
VOID
PreSelectDriver(
HDEVINFO hDevInfo,
LPCTSTR pszModel
)
/*++
Routine Description:
Preselect a manufacturer and model for the driver dialog
If same model is found select it, else if a match in manufacturer is
found select first driver for the manufacturer.
--*/
{
SP_DRVINFO_DATA DrvInfoData;
DWORD dwIndex = 0;
//
// If no model/manf given select first driver
//
if (pszModel && *pszModel)
{
DrvInfoData.cbSize = sizeof(DrvInfoData);
while (SetupDiEnumDriverInfo(hDevInfo,
NULL,
SPDIT_CLASSDRIVER,
dwIndex,
&DrvInfoData))
{
if (!lstrcmp(pszModel, DrvInfoData.Description))
{
//
// Found a full match. We will return.
//
SetupDiSetSelectedDriver(hDevInfo,
NULL,
&DrvInfoData);
return;
}
DrvInfoData.cbSize = sizeof(DrvInfoData);
++dwIndex;
}
//
// There a many third-party names that we would like to match if
// the third party driver disk is not available (old driver that
// was not installed.
//
// Let do the mapping of third-party names to currently provided
// names and restart the "selection".
//
// "#9 Imagine 128" = n9i128
}
return;
}
DWORD
InstallDriver(
HWND hwnd,
INSTALL_TYPE InstallType,
LPCTSTR pszModel,
LPCTSTR pszInf,
LPTSTR serviceName
)
{
HCURSOR hCursorOrg;
HCURSOR hCursor;
HDEVINFO hDevInfo;
DWORD err;
DWORD bEntryFound;
DWORD retError = NO_ERROR;
SP_DRVINFO_DATA DriverInfoData;
SP_DRVINFO_DETAIL_DATA DriverInfoDetailData;
BOOL bThirdParty = FALSE;
DWORD cbOutputSize;
HINF InfFileHandle;
PVOID Context;
INFCONTEXT infoContext;
LPTSTR pSourceLists[6];
LPTSTR *pSourceList = pSourceLists;
ULONG pSourceListCount;
TCHAR szSourceLocation[LINE_LEN];
LPTSTR InfName;
LPTSTR copyFileSection;
LPTSTR installSection;
TCHAR installSectionData[LINE_LEN];
TCHAR szServiceSection[LINE_LEN];
TCHAR szServiceName[LINE_LEN];
INFCONTEXT serviceContext;
TCHAR DeviceInst[LINE_LEN];
SP_DEVINFO_DATA DeviceInfoData;
SP_DEVINSTALL_PARAMS DeviceInstallParams;
TCHAR szSoftwareSection[LINE_LEN];
INFCONTEXT tmpContext;
ULONG maxmem;
ULONG numDev;
ULONG configFlags;
TCHAR keyName[LINE_LEN];
HKEY hkey;
DWORD disposition;
//
// instantiate setup
//
hDevInfo = SetupDiCreateDeviceInfoList((LPGUID) &GUID_DEVCLASS_DISPLAY,
hwnd);
if (hDevInfo == INVALID_HANDLE_VALUE)
return ERROR_INVALID_PARAMETER;
if (InstallType != DETECT)
{
//
// Turn on the hourglass since it will take a long time to process
// the inf file
//
hCursorOrg = GetCursor();
if (hCursor = LoadCursor(NULL, (LPCTSTR) IDC_WAIT))
{
SetCursor(hCursor);
}
//
// Build the list of drivers, and select the approrpiate entry within
// it, if possible.
// If we are preinstalling, specify the appropriate inf
//
if (InstallType == INSTALL)
{
if (!SetupDiBuildDriverInfoList(hDevInfo,
NULL,
SPDIT_CLASSDRIVER))
{
SetupDiDestroyDeviceInfoList(hDevInfo);
return ERROR_INVALID_PARAMETER;
}
}
else
{
DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
SetupDiGetDeviceInstallParams(hDevInfo,
NULL,
&DeviceInstallParams);
DeviceInstallParams.Flags |= DI_NOFILECOPY |
DI_DONOTCALLCONFIGMG |
DI_ENUMSINGLEINF;
if (SetupQuerySourceList(SRCLIST_SYSTEM,
&pSourceList,
&pSourceListCount))
{
pSourceListCount = 0;
wsprintf(DeviceInstallParams.DriverPath,
TEXT("%ws\\%ws\\%ws"),
pSourceList[0], WINNT_OEM_DISPLAY_DIR, pszInf);
SetupFreeSourceList(&pSourceList, pSourceListCount);
}
SetupDiSetDeviceInstallParams(hDevInfo,
NULL,
&DeviceInstallParams);
if (!SetupDiBuildDriverInfoList(hDevInfo,
NULL,
SPDIT_CLASSDRIVER))
{
SetupDiDestroyDeviceInfoList(hDevInfo);
return ERROR_INVALID_PARAMETER;
}
}
PreSelectDriver(hDevInfo, pszModel);
//
// Set the parameters for the window to show appriate text, buttons.
// Then tell setup to use these parameters
//
SetSelectDevParams(hDevInfo);
//
// Restore the pointer
//
if (hCursorOrg)
{
SetCursor(hCursorOrg);
}
//
// Call setup to run the window
//
reselect:
bEntryFound = FALSE;
//
// Ask the user to pick the device, unless we are preinstalling, in
// which we just use the preselection.
//
if ((InstallType == PREINSTALL) ||
SetupDiSelectDevice(hDevInfo, NULL))
{
DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
if (SetupDiGetSelectedDriver(hDevInfo,
NULL,
&DriverInfoData))
{
//
// If this is thrid party driver, put up a popup.
//
if (_tcsicmp(DriverInfoData.ProviderName, TEXT("Microsoft")))
{
bThirdParty = TRUE;
if (InstallType != PREINSTALL)
{
if (FmtMessageBox(hwnd,
MB_YESNO | MB_DEFBUTTON2 | MB_ICONQUESTION,
FALSE,
ID_DSP_TXT_THIRD_PARTY,
ID_DSP_TXT_THIRD_PARTY_DRIVER) != IDYES)
{
goto reselect;
}
}
}
DriverInfoDetailData.cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
if ((SetupDiGetDriverInfoDetail(hDevInfo,
NULL,
&DriverInfoData,
&DriverInfoDetailData,
DriverInfoDetailData.cbSize,
&cbOutputSize)) ||
(GetLastError() == ERROR_INSUFFICIENT_BUFFER))
{
bEntryFound = TRUE;
}
}
}
if (bEntryFound == FALSE)
{
retError = GetLastError();
SetupDiDestroyDriverInfoList(hDevInfo, NULL, SPDIT_CLASSDRIVER);
SetupDiDestroyDeviceInfoList(hDevInfo);
return retError;
}
}
//
// open the inf so we can run the sections in the inf, more or less
// manually.
//
if (InstallType == DETECT)
{
InfName = TEXT("display.inf");
copyFileSection = TEXT("detect");
installSection = installSectionData;
}
else
{
InfName = DriverInfoDetailData.InfFileName;
copyFileSection = DriverInfoDetailData.SectionName;
installSection = DriverInfoDetailData.SectionName;
}
//
// Open the inf so we can copy the files from it.
//
InfFileHandle = SetupOpenInfFile(InfName,
NULL,
INF_STYLE_WIN4,
NULL);
if (InfFileHandle == INVALID_HANDLE_VALUE)
{
retError = ERROR_INVALID_PARAMETER;
}
else
{
//
// For drivers we ship, the file information is lcoated in layout.inf.
// So append that file if we need it.
//
if (bThirdParty == FALSE)
{
SetupOpenAppendInfFile(NULL,
InfFileHandle,
NULL);
}
//
// Initialize the default callback so that the MsgHandler works
// properly
//
Context = SetupInitDefaultQueueCallback(hwnd);
//
// Copy all the files to the disk
//
if (InstallType == PREINSTALL)
{
pSourceListCount = 0;
if (SetupQuerySourceList(SRCLIST_SYSTEM,
&pSourceList,
&pSourceListCount))
{
wsprintf(szSourceLocation,
TEXT("%ws\\%ws"),
pSourceList[0], WINNT_OEM_DISPLAY_DIR);
SetupFreeSourceList(&pSourceList, pSourceListCount);
}
}
if (!SetupInstallFromInfSection(hwnd,
InfFileHandle,
copyFileSection,
SPINST_FILES,
NULL,
(InstallType == PREINSTALL) ?
szSourceLocation :
NULL,
0,
&SetupDefaultQueueCallback,
Context,
NULL,
NULL))
{
err = GetLastError();
DbgPrint("Install files Error %d\n", err);
//
// User cancelled. give them a chance to reselect.
//
// If they were doing a detect, just exit with the cancel message.
//
if ( (err == ERROR_CANCELLED) &&
(InstallType == INSTALL) )
{
goto reselect;
}
return err;
}
//
// If this is the detect key, then it's a list of all the sections
// we need to run. So we will have a loop.
//
if (InstallType == DETECT)
{
if (!SetupFindFirstLine(InfFileHandle,
TEXT("detect.Services"),
NULL,
&infoContext))
{
return ERROR_INVALID_PARAMETER;
}
//
// Get the next driver we have to install in a detect case
//
detect_next:
if (!SetupGetStringField(&infoContext,
0,
installSection,
sizeof(installSectionData),
NULL))
{
return ERROR_INVALID_PARAMETER;
}
}
wsprintf(szServiceSection,
TEXT("%ws.Services"),
installSection);
//
// Formulate a service install section name based on the
// install name (add .services at the end).
// Go in this section and get the name of the service that
// will be installed.
//
if (SetupFindFirstLine(InfFileHandle,
szServiceSection,
NULL,
&serviceContext))
{
SetupGetStringField(&serviceContext,
1,
szServiceName,
sizeof(szServiceName),
NULL);
}
if (serviceName)
{
wsprintf(serviceName,
TEXT("\\Registry\\Machine\\System\\CurrentControlSet\\Services\\%ws"),
szServiceName);
}
wsprintf(DeviceInst,
TEXT("Root\\LEGACY_%ws\\0000"),
szServiceName);
ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA));
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
if (SetupDiOpenDeviceInfo(hDevInfo,
DeviceInst,
hwnd,
0,
&DeviceInfoData) ||
(SetupDiCreateDeviceInfo(hDevInfo,
DeviceInst,
(LPGUID) &GUID_DEVCLASS_DISPLAY,
NULL,
hwnd,
0,
&DeviceInfoData) &&
SetupDiRegisterDeviceInfo(hDevInfo,
&DeviceInfoData,
0,
NULL,
NULL,
NULL)) )
{
//
// Set the parameters for the installation to do no
// file copies
//
ZeroMemory(&DeviceInstallParams, sizeof(SP_DEVINSTALL_PARAMS));
DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
SetupDiGetDeviceInstallParams(hDevInfo,
&DeviceInfoData,
&DeviceInstallParams);
//
// Don't copy the files since we already copied them.
//
// Don't configure device automatically otherwise the driver
// can load, and end up generating a Device0 volatile key which
// which break the next part of install.
// This can be removed when we get rid of these Device0 instance
// mechanism.
//
// We only need to enumerate the current inf.
//
DeviceInstallParams.Flags |= DI_NOFILECOPY |
DI_DONOTCALLCONFIGMG |
DI_ENUMSINGLEINF;
lstrcpy(DeviceInstallParams.DriverPath,
InfName);
SetupDiSetDeviceInstallParams(hDevInfo,
&DeviceInfoData,
&DeviceInstallParams);
if (InstallType == DETECT)
{
TCHAR DeviceInstId[LINE_LEN];
ULONG DeviceInstIdLength;
//
// Assume we get the hardware id from the detect driver node
// line in our INF
//
if (SetupGetStringField(&infoContext,
1,
DeviceInstId,
sizeof(DeviceInstId),
NULL))
{
//
// Make the DeviceInstId a MULTI_SZ.
//
DeviceInstIdLength = lstrlen(DeviceInstId);
DeviceInstId[DeviceInstIdLength] = (TCHAR) 0;
DeviceInstId[DeviceInstIdLength + 1] = (TCHAR) 0;
SetupDiSetDeviceRegistryProperty(hDevInfo,
&DeviceInfoData,
SPDRP_HARDWAREID,
(PBYTE) DeviceInstId,
(DeviceInstIdLength + 2) *
sizeof(TCHAR));
}
if (!SetupDiBuildDriverInfoList(hDevInfo,
&DeviceInfoData,
SPDIT_COMPATDRIVER))
{
err = GetLastError();
DbgPrint("SetupDiBuildDriverInfoList Detail Error %d\n", err);
return ERROR_INVALID_PARAMETER;
}
//
// Now you're guaranteed to have a non-empty list, and the first
// (i.e., most-compatible) driver node is the one you want, so
// so select it.
//
DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
if (!SetupDiEnumDriverInfo(hDevInfo,
&DeviceInfoData,
SPDIT_COMPATDRIVER,
0,
&DriverInfoData))
{
err = GetLastError();
DbgPrint("SetupDiEnumDriverInfo Detail Error %d\n", err);
return ERROR_INVALID_PARAMETER;
}
}
else
{
SetupDiBuildDriverInfoList(hDevInfo,
&DeviceInfoData,
SPDIT_CLASSDRIVER);
//
// Special feature that lets us use the original driver
// description to find the equivalent one in the new
// list.
//
DriverInfoData.Reserved = 0;
}
if (!SetupDiSetSelectedDriver(hDevInfo,
&DeviceInfoData,
&DriverInfoData))
{
return ERROR_INVALID_PARAMETER;
}
if (!SetupDiInstallDevice(hDevInfo,
&DeviceInfoData))
{
return ERROR_INVALID_PARAMETER;
}
//
// Make sure the device is enabled in case the setupapis
// diabled the device for some reason.
// See LonnyM for possible fix.
//
if (SetupDiGetDeviceRegistryProperty(hDevInfo,
&DeviceInfoData,
SPDRP_CONFIGFLAGS,
NULL,
(LPBYTE) &configFlags,
sizeof(DWORD),
NULL) &&
(configFlags & CONFIGFLAG_DISABLED))
{
configFlags &= ~CONFIGFLAG_DISABLED;
SetupDiSetDeviceRegistryProperty(hDevInfo,
&DeviceInfoData,
SPDRP_CONFIGFLAGS,
(LPBYTE) &configFlags,
sizeof(DWORD));
}
//
// Destroy these structures
//
if (InstallType == DETECT)
{
SetupDiDestroyDriverInfoList(hDevInfo,
&DeviceInfoData,
SPDIT_COMPATDRIVER);
}
else
{
SetupDiDestroyDriverInfoList(hDevInfo,
&DeviceInfoData,
SPDIT_CLASSDRIVER);
}
}
else
{
err = GetLastError();
DbgPrint("Device Install Detail Error %d\n", err);
return ERROR_INVALID_PARAMETER;
}
//
// Get any interesteing configuration data for the inf file.
//
maxmem = 4;
numDev = 1;
PreConfigured = 0;
KeepEnabled = 0;
wsprintf(szSoftwareSection,
TEXT("%ws.GeneralConfigData"),
installSection);
if (SetupFindFirstLine(InfFileHandle,
szSoftwareSection,
TEXT("MaximumNumberOfDevices"),
&tmpContext))
{
SetupGetIntField(&tmpContext,
1,
&numDev);
}
if (SetupFindFirstLine(InfFileHandle,
szSoftwareSection,
TEXT("MaximumDeviceMemoryConfiguration"),
&tmpContext))
{
SetupGetIntField(&tmpContext,
1,
&maxmem);
}
if (SetupFindFirstLine(InfFileHandle,
szSoftwareSection,
TEXT("PreConfiguredSettings"),
&tmpContext))
{
SetupGetIntField(&tmpContext,
1,
&PreConfigured);
}
if (SetupFindFirstLine(InfFileHandle,
szSoftwareSection,
TEXT("KeepExistingDriverEnabled"),
&tmpContext))
{
SetupGetIntField(&tmpContext,
1,
&KeepEnabled);
}
//
// Write the configuration information to the registry.
//
//
// Increase the number of system PTEs if we have cards that will need
// more than 10 MEG of PTEs
//
if ((maxmem = maxmem * numDev) > 10)
{
//
// we need 1K PTEs to support 1 MEG
// Then add 50% for other devices this type of machine may have.
//
// NOTE - in the future, we may want to be smarter and try
// to merge with whatever someone else put in there.
//
maxmem *= 0x400 * 3/2;
if (RegCreateKeyEx(HKEY_LOCAL_MACHINE,
TEXT("System\\CurrentControlSet\\Control\\Session Manager\\Memory Management"),
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_READ | KEY_WRITE,
NULL,
&hkey,
&disposition) == ERROR_SUCCESS)
{
RegSetValueEx(hkey,
TEXT("SystemPages"),
0,
REG_DWORD,
(LPBYTE) &maxmem,
sizeof(DWORD));
RegCloseKey(hkey);
}
}
//
// We may have to do this for multiple adapters at this point.
// So loop throught the number of devices, which has 1 as the default
// value
//
do {
numDev -= 1;
wsprintf(keyName,
TEXT("System\\CurrentControlSet\\Services\\%ws\\Device%d"),
szServiceName, numDev);
if (RegCreateKeyEx(HKEY_LOCAL_MACHINE,
keyName,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_READ | KEY_WRITE,
NULL,
&hkey,
&disposition) == ERROR_SUCCESS)
{
wsprintf(szSoftwareSection,
TEXT("%ws.SoftwareSettings"),
installSection);
if (!SetupInstallFromInfSection(hwnd,
InfFileHandle,
szSoftwareSection,
SPINST_REGISTRY,
hkey,
NULL,
0,
&SetupDefaultQueueCallback,
Context,
NULL,
NULL))
{
return ERROR_INVALID_PARAMETER;
}
//
// Write the description of the device if we are not detecting
//
if (InstallType != DETECT)
{
RegSetValueEx(hkey,
TEXT("Device Description"),
0,
REG_SZ,
(LPBYTE) DriverInfoDetailData.DrvDescription,
(lstrlen(DriverInfoDetailData.DrvDescription) + 1) *
sizeof(TCHAR) );
}
//
// Invoke the resource picker for adapters that need it.
//
{
LOG_CONF LogConfig;
RES_DES ResDes;
HMODULE hModule;
FARPROC PropSheetExtProc;
if (CM_Get_First_Log_Conf(&LogConfig,
DeviceInfoData.DevInst,
BASIC_LOG_CONF) == CR_SUCCESS)
{
//
// This device instance has a basic log config, so we want to
// give the user a resource selection dialog.
// (before we do that, go ahead and free the log config
// handle--we don't need it.)
//
CM_Free_Log_Conf_Handle(LogConfig);
if ((hModule = GetModuleHandle(TEXT("setupapi.dll"))) &&
(PropSheetExtProc = GetProcAddress(hModule,
"ExtensionPropSheetPageProc")))
{
SP_PROPSHEETPAGE_REQUEST PropSheetRequest;
HPROPSHEETPAGE hPage = {0};
PROPSHEETPAGE PropPage;
PROPSHEETHEADER PropHeader;
PropSheetRequest.cbSize = sizeof(SP_PROPSHEETPAGE_REQUEST);
PropSheetRequest.PageRequested = SPPSR_SELECT_DEVICE_RESOURCES;
PropSheetRequest.DeviceInfoSet = hDevInfo;
PropSheetRequest.DeviceInfoData = &DeviceInfoData;
//
// Try to get the property sheet extension from setupapi.
//
if (PropSheetExtProc(&PropSheetRequest,
AddPropSheetPageProc,
&hPage))
{
PropHeader.dwSize = sizeof(PROPSHEETHEADER);
PropHeader.dwFlags = PSH_NOAPPLYNOW;
PropHeader.hwndParent = hwnd;
PropHeader.hInstance = ghmod;
PropHeader.pszIcon = NULL;
PropHeader.pszCaption = TEXT(" ");
PropHeader.nPages = 1;
PropHeader.phpage = &hPage;
PropHeader.nStartPage = 0;
PropHeader.pfnCallback = NULL;
if (PropertySheet(&PropHeader) == -1)
{
if(hPage)
{
DestroyPropertySheetPage(hPage);
}
}
else
{
//
// BUGBUG can this return zero ?
//
//
// If we were successful, then we want to retrieve the user's selection.
//
CM_Get_First_Log_Conf(&LogConfig,
DeviceInfoData.DevInst,
FORCED_LOG_CONF);
ResDes = LogConfig;
// while(
if (CM_Get_Next_Res_Des(&ResDes,
ResDes,
ResType_Mem,
NULL,
0) == CR_SUCCESS)
{
MEM_RESOURCE memRes;
if (CM_Get_Res_Des_Data(ResDes,
&memRes,
sizeof(memRes),
0) == CR_SUCCESS)
{
RegSetValueEx(hkey,
TEXT("MemBase"),
0,
REG_DWORD,
(LPBYTE) &(memRes.MEM_Header.MD_Alloc_Base),
sizeof(DWORD));
}
CM_Free_Res_Des_Handle(ResDes); // resdesnext
}
}
}
}
}
}
RegCloseKey(hkey);
}
} while (numDev != 0);
//
// optinally run the OpenGl section in the inf.
// Ignore any errors at this point since this is an optional
// entry.
//
if (RegCreateKeyEx(HKEY_LOCAL_MACHINE,
TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\OpenGLDrivers"),
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_READ | KEY_WRITE,
NULL,
&hkey,
&disposition) == ERROR_SUCCESS)
{
wsprintf(szSoftwareSection,
TEXT("%ws.OpenGLSoftwareSettings"),
installSection);
SetupInstallFromInfSection(hwnd,
InfFileHandle,
szSoftwareSection,
SPINST_REGISTRY,
hkey,
NULL,
0,
&SetupDefaultQueueCallback,
Context,
NULL,
NULL);
RegCloseKey(hkey);
}
//
// Get the next line for detection if we are detecting.
//
if ((InstallType == DETECT) &&
SetupFindNextLine(&infoContext, &infoContext))
{
goto detect_next;
}
SetupCloseInfFile(InfFileHandle);
}
SetupDiDestroyDriverInfoList(hDevInfo, NULL, SPDIT_CLASSDRIVER);
SetupDiDestroyDeviceInfoList(hDevInfo);
return retError;
}
DWORD
InstallNewDriver(
HWND hwnd,
LPCTSTR pszModel,
BOOL bDetect,
PBOOL pbKeepEnabled
)
{
DWORD err;
LPTSTR keyName;
if (bDetect)
{
LPTSTR psz1;
int iRet;
psz1 = FmtSprint(ID_DSP_TXT_AUTODETECT_PROCEED);
iRet = FmtMessageBox(hwnd,
MB_YESNO | MB_DEFBUTTON2 | MB_ICONQUESTION,
FALSE,
ID_DSP_TXT_INSTALL_DRIVER,
ID_DSP_TXT_AUTODETECT,
psz1);
LocalFree(psz1);
if (iRet != IDYES)
{
return ERROR_CANCELLED;
}
}
err = InstallDriver(hwnd,
bDetect ? DETECT : INSTALL,
pszModel,
NULL,
NULL);
if (err == NO_ERROR)
{
DWORD disposition;
HKEY hkey;
*pbKeepEnabled = KeepEnabled;
//
// Tell the user the driver was installed.
//
FmtMessageBox(hwnd,
MB_ICONINFORMATION | MB_OK,
FALSE,
ID_DSP_TXT_INSTALL_DRIVER,
ID_DSP_TXT_DRIVER_INSTALLED);
if (PreConfigured == 0)
{
if (bDetect)
{
//
// Write a key to the registry to tell the display applet to
// cleanup all the drivers after the autodetect.
//
keyName = SZ_DETECT_DISPLAY;
}
else
{
//
// Create a registry key that indicates a new display was
// installed.
//
keyName = SZ_NEW_DISPLAY;
}
if (RegCreateKeyEx(HKEY_LOCAL_MACHINE,
keyName,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_READ | KEY_WRITE,
NULL,
&hkey,
&disposition) == ERROR_SUCCESS)
{
RegCloseKey(hkey);
}
}
//
// Save into the registry the fact that it will take a reboot
// for these changes to take effect
//
if (RegCreateKeyEx(HKEY_LOCAL_MACHINE,
SZ_REBOOT_NECESSARY,
0,
NULL,
REG_OPTION_VOLATILE,
KEY_READ | KEY_WRITE,
NULL,
&hkey,
&disposition) == ERROR_SUCCESS)
{
RegCloseKey(hkey);
}
//
// If everything succeeded properly, then we need to reboot the
// machine
//
// Ask the user to reboot the machine.
//
PropSheet_RestartWindows(ghwndPropSheet);
PropSheet_CancelToClose(ghwndPropSheet);
}
else if (err != ERROR_CANCELLED)
{
//
// Tell the user the driver was not installed properly.
//
FmtMessageBox(hwnd,
MB_ICONSTOP | MB_OK,
FALSE,
ID_DSP_TXT_INSTALL_DRIVER,
ID_DSP_TXT_DRIVER_INSTALLED_FAILED);
}
return err;
}
DWORD
PreInstallDriver(
HWND hwnd,
LPCTSTR pszModel,
LPCTSTR pszInf,
LPTSTR ServiceName
)
{
DWORD err;
err = InstallDriver(hwnd,
PREINSTALL,
pszModel,
pszInf,
ServiceName);
//
// Tell the user the driver was not installed properly.
//
if (err != NO_ERROR)
{
FmtMessageBox(hwnd,
MB_ICONSTOP | MB_OK,
FALSE,
ID_DSP_TXT_INSTALL_DRIVER,
ID_DSP_TXT_DRIVER_PREINSTALLED_FAILED);
}
return err;
}