windows-nt/Source/XPSP1/NT/drivers/video/ms/fsvga/fsconins/fsconins.cpp
2020-09-26 16:20:57 +08:00

403 lines
11 KiB
C++

/*
* Copyright (c) 1996 Microsoft Corporation
*
* Module Name:
*
* fsconins.cpp
*
* Abstract:
*
* This file contain FsConInstall class
*
* Author:
*
* Kazuhiko Matsubara (kazum) June-16-1999
*
* Environment:
*
* User Mode
*/
#define _FSCONINS_CPP_
#include <stdlib.h>
#include "oc.h"
#include "fsconins.h"
#include <initguid.h>
#include <devguid.h>
#include <cfgmgr32.h>
#pragma hdrstop
FsConInstall::FsConInstall()
{
m_cd = NULL;
}
FsConInstall::FsConInstall(
IN PPER_COMPONENT_DATA cd
)
{
m_cd = cd;
}
BOOL
FsConInstall::GUIModeSetupInstall(
IN HWND hwndParent
)
/*++
Routine Description:
This is the single entry point for Full Screen Console Driver
GUI-mode setup install routine.
It currently simply creates and installs a dev node for FSVGA/FSNEC to interact with
PnP.
Arguments:
hwndParent Handle to parent window for GUI required by this function.
Return Value:
TRUE on success. FALSE, otherwise.
--*/
{
HINSTANCE hndl = NULL;
//
// Create the deviceinfo list.
//
HDEVINFO devInfoSet;
devInfoSet = SetupDiCreateDeviceInfoList(&GUID_DEVCLASS_DISPLAY, hwndParent);
if (devInfoSet == INVALID_HANDLE_VALUE) {
return FALSE;
}
//
// Get the "offical" display class name.
//
SP_DEVINFO_DATA deviceInfoData;
TCHAR className[MAX_CLASS_NAME_LEN];
ZeroMemory(&deviceInfoData, sizeof(SP_DEVINFO_DATA));
deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
if (! SetupDiClassNameFromGuid(&GUID_DEVCLASS_DISPLAY,
className,
sizeof(className)/sizeof(TCHAR),
NULL)) {
return FALSE;
}
//
// Create the dev node.
//
if (! SetupDiCreateDeviceInfo(devInfoSet,
TEXT("Root\\DISPLAY\\0000"),
&GUID_DEVCLASS_DISPLAY,
NULL,
hwndParent,
NULL, // No flags.
&deviceInfoData)) {
// If it already exists, then we are done ... because this was an upgrade.
if (GetLastError() == ERROR_DEVINST_ALREADY_EXISTS) {
return TRUE;
}
else {
SetupDiDestroyDeviceInfoList(devInfoSet);
return FALSE;
}
}
else if (! SetupDiSetSelectedDevice(devInfoSet,
&deviceInfoData)) {
goto InstallError;
}
//
// Add the FSVGA/FSNEC PnP ID.
//
// Create the PnP ID string.
TCHAR pnpID[256];
DWORD len;
len = GetPnPID(pnpID, sizeof(pnpID)/sizeof(TCHAR));
if (len == 0) {
goto InstallError;
}
// Add it to the registry entry for the dev node.
if (! SetupDiSetDeviceRegistryProperty(devInfoSet,
&deviceInfoData,
SPDRP_HARDWAREID,
(CONST BYTE*)pnpID,
(len + 1) * sizeof(TCHAR))) {
goto InstallError;
}
//
// Register the, as of yet, phantom dev node with PnP to turn it into a real dev node.
//
if (! SetupDiRegisterDeviceInfo(devInfoSet,
&deviceInfoData,
0,
NULL,
NULL,
NULL)) {
goto InstallError;
}
//
// Get the device instance ID.
//
TCHAR devInstanceID[MAX_PATH];
if (! SetupDiGetDeviceInstanceId(devInfoSet,
&deviceInfoData,
devInstanceID,
sizeof(devInstanceID)/sizeof(TCHAR),
NULL)) {
goto InstallError;
}
//
// Use newdev.dll to install FSVGA/FSNEC as the driver for this new dev node.
//
hndl = LoadLibrary(TEXT("newdev.dll"));
if (hndl == NULL) {
goto InstallError;
}
typedef BOOL (InstallDevInstFuncType)(
HWND hwndParent,
LPCWSTR DeviceInstanceId,
BOOL UpdateDriver,
PDWORD pReboot,
BOOL silentInstall);
InstallDevInstFuncType *pInstallDevInst;
pInstallDevInst = (InstallDevInstFuncType*)GetProcAddress(hndl, "InstallDevInstEx");
if (pInstallDevInst == NULL) {
goto InstallError;
}
if ((*pInstallDevInst)(hwndParent,
devInstanceID,
FALSE,
NULL,
TRUE)) {
// Clean up and return success!
SetupDiDestroyDeviceInfoList(devInfoSet);
FreeLibrary(hndl);
return TRUE;
}
InstallError:
SetupDiCallClassInstaller(DIF_REMOVE,
devInfoSet,
&deviceInfoData);
SetupDiDestroyDeviceInfoList(devInfoSet);
if (hndl != NULL) {
FreeLibrary(hndl);
}
return FALSE;
}
BOOL
FsConInstall::GUIModeSetupUninstall(
IN HWND hwndParent
)
/*++
Routine Description:
This is the single entry point for Full Screen Console Driver
GUI-mode setup uninstall routine.
It currently simply remove the dev node created so that FSVGA/FSNEC can interact
with PnP.
Arguments:
hwndParent Handle to parent window for GUI required by this function.
Return Value:
TRUE on success. FALSE, otherwise.
--*/
{
//
// Get the set of all devices with the FSVGA/FSNEC PnP ID.
//
HDEVINFO devInfoSet;
GUID *pGuid = (GUID*)&GUID_DEVCLASS_DISPLAY;
devInfoSet = SetupDiGetClassDevs(pGuid,
NULL,
hwndParent,
DIGCF_PRESENT);
if (devInfoSet == INVALID_HANDLE_VALUE) {
return FALSE;
}
// Get FSVGA/FSNEC PnPID
TCHAR FsConPnPID[256];
DWORD len;
len = GetPnPID(FsConPnPID, sizeof(FsConPnPID)/sizeof(TCHAR));
if (len == 0) {
return FALSE;
}
// Assume that we will be successful.
BOOL result = TRUE;
// Get the first device.
DWORD iLoop = 0;
BOOL bMoreDevices;
SP_DEVINFO_DATA deviceInfoData;
deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
//
// Get the details for all matching device interfaces.
//
while (bMoreDevices = SetupDiEnumDeviceInfo(devInfoSet,
iLoop++,
&deviceInfoData)) {
//
// Get the PnP ID for the device.
//
TCHAR pnpID[256];
if (SetupDiGetDeviceRegistryProperty(devInfoSet,
&deviceInfoData,
SPDRP_HARDWAREID,
NULL,
(BYTE*)pnpID,
sizeof(pnpID),
NULL)) {
// If the current device matchs FSVGA/FSNEC, then remove it.
if (! _tcscmp(pnpID, FsConPnPID)) {
if (! SetupDiCallClassInstaller(DIF_REMOVE,
devInfoSet,
&deviceInfoData)) {
// If we failed here, set the return status to indicate failure,
// but don't give up on any other FSVGA/FSNEC dev nodes.
result = FALSE;
}
}
}
}
// Release the device info list.
SetupDiDestroyDeviceInfoList(devInfoSet);
return result;
}
DWORD
FsConInstall::GetPnPID(
OUT LPTSTR pszPnPID,
IN DWORD dwSize
)
{
INFCONTEXT context;
if (! SetupFindFirstLine(m_cd->hinf,
TEXT("Manufacturer"), // Section
NULL, // Key
&context)) {
return 0;
}
TCHAR Manufacture[256];
DWORD nSize;
if (! SetupGetStringField(&context,
1, // Index
Manufacture,
sizeof(Manufacture)/sizeof(TCHAR),
&nSize)) {
return 0;
}
if (! SetupFindFirstLine(m_cd->hinf,
Manufacture, // Section
NULL, // Key
&context)) {
return 0;
}
if (! SetupGetStringField(&context,
2, // Index 2 is PnP-ID
pszPnPID,
dwSize,
&nSize)) {
return 0;
}
return _tcslen(pszPnPID);
}
BOOL
FsConInstall::InfSectionRegistryAndFiles(
IN LPCTSTR SubcomponentId,
IN LPCTSTR Key
)
{
INFCONTEXT context;
TCHAR section[256];
BOOL rc;
rc = SetupFindFirstLine(m_cd->hinf,
SubcomponentId,
Key,
&context);
if (rc) {
rc = SetupGetStringField(&context,
1,
section,
sizeof(section)/sizeof(TCHAR),
NULL);
if (rc) {
rc = SetupInstallFromInfSection(NULL, // hwndOwner
m_cd->hinf, // inf handle
section, //
SPINST_ALL & ~SPINST_FILES,
// operation flags
NULL, // relative key root
NULL, // source root path
0, // copy flags
NULL, // callback routine
NULL, // callback routine context
NULL, // device info set
NULL); // device info struct
}
}
return rc;
}
// loads current selection state info into "state" and
// returns whether the selection state was changed
BOOL
FsConInstall::QueryStateInfo(
LPCTSTR SubcomponentId
)
{
return m_cd->HelperRoutines.QuerySelectionState(m_cd->HelperRoutines.OcManagerContext,
SubcomponentId,
OCSELSTATETYPE_CURRENT);
}