/* * 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 #include "oc.h" #include "fsconins.h" #include #include #include #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); }