|
|
#include "pch.h"
#define SOFTPCI_FILTER_SECTION L"SOFTPCI_DRV.Services"
#define SOFTPCI_FILTER_SERVICE_NAME L"SoftPCI"
//#define SOFTPCIDRV L"softpci"
typedef enum{ DriverInf = 0, DriverCat, DriverSoftPci, DriverHpSim, DriverShpc, DriverUnknown } IMAGE_TYPE;
BOOL _lwritef( IN HANDLE hFile, IN PTSTR Format, ...);
BOOL SoftPCI_ExpandResourceFile( IN LPTSTR DriverPath, IN LPTSTR ResName );
BOOL SoftPCI_ExtractImageToDrive( IN IMAGE_TYPE ImageType );
BOOL SoftPCI_InstallFilterKey( IN DEVNODE RootBus );
BOOL SoftPCI_InstallDriverInf( VOID );
VOID SoftPCI_LocateRootPciBusesForInstall( IN PPCI_DN Pdn, OUT PBOOL Success );
BOOL SoftPCI_RebootSystem( VOID );
BOOL SoftPCI_InstallDriver(VOID){ BOOL success = TRUE; INT infLen = 0, reboot = IDNO; IMAGE_TYPE imageType; WCHAR winDir[MAX_PATH]; WCHAR infPath[MAX_PATH]; //
// Spit out our images....
//
for (imageType = DriverInf; imageType < DriverUnknown; imageType++ ) {
if (!SoftPCI_ExtractImageToDrive(imageType)){ return FALSE; } }
//
// We need a service key
//
if (!SoftPCI_InstallDriverInf()) { //
// Failed to install our service key
//
return FALSE; }
//
// Now we need to update each root buses reg data
//
SoftPCI_LocateRootPciBusesForInstall(g_PciTree->RootDevNode, &success);
SoftPCI_InitializeRegistry();
if (success) { reboot = MessageBox(g_SoftPCIMainWnd, L"SoftPCI Support is now installed and your system must be rebooted. OK to reboot?", L"Install Complete", MB_YESNO );
if (reboot == IDYES) { return SoftPCI_RebootSystem(); } } return success; }
BOOL SoftPCI_ExpandResourceFile( IN LPTSTR DriverPath, IN LPTSTR ResName ) /*++
Routine Description:
This routine was stolen from DVNT to expand our driver out of our *.exe so it can be installed. Arguments:
DriverPath - count of arguments ResName - arguments from the command line
Return Value:
none
--*/ { HGLOBAL obj; HRSRC resource; LPTSTR lpStr; INT size; BOOL success = FALSE;
if ((resource = FindResource(NULL, ResName, RT_RCDATA))) { if ((obj = LoadResource(NULL,resource))) {
if ((lpStr = (LPTSTR)LockResource(obj)) ) {
HANDLE file; DWORD written;
size = SizeofResource(NULL, resource); if ((file = CreateFile(DriverPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL )) != INVALID_HANDLE_VALUE) {
if (WriteFile(file, lpStr, size, &written, NULL )) { success = TRUE ; }
CloseHandle(file);
}
UnlockResource(obj);
} } } return success; }
BOOL SoftPCI_ExtractImageToDrive( IN IMAGE_TYPE ImageType ) {
WCHAR imagePath[MAX_PATH]; WCHAR winDir[MAX_PATH]; if (GetWindowsDirectory(winDir, MAX_PATH)==0) return FALSE ;
wcscat(winDir, L"\\pcisim"); CreateDirectory(winDir, NULL);
switch (ImageType) { case DriverInf: wsprintf(imagePath, L"%s\\softpci.inf", winDir); return SoftPCI_ExpandResourceFile(imagePath, L"InfDriverResource"); break;
case DriverCat: wsprintf(imagePath, L"%s\\delta.cat", winDir); return SoftPCI_ExpandResourceFile(imagePath, L"CatalogDriverResource"); break;
case DriverSoftPci: //
//
// OK softpci.sys needs to be treated special as it is
// not installed by normal means (as a filter). Therefore, we need
// to make sure it exists in both our media source location as well
// as the \system32\drivers directory.
//
//
wsprintf(imagePath, L"%s\\softpci.sys", winDir); if (SoftPCI_ExpandResourceFile(imagePath, L"SoftPciDriverResource")) {
WCHAR driverDir[MAX_PATH]; ULONG i; //
// Save our current media source image path
//
wcscpy(driverDir, imagePath);
//
// now remove the \\pcisim
//
for (i = wcslen(winDir); i > 0 && winDir[i] != '\\'; i--); winDir[i] = 0; //
// Build our new image path
//
wsprintf(imagePath, L"%s\\system32\\drivers\\softpci.sys", winDir);
return CopyFile(driverDir, imagePath, FALSE); } return FALSE; break;
case DriverHpSim: wsprintf(imagePath, L"%s\\hpsim.sys", winDir); return SoftPCI_ExpandResourceFile(imagePath, L"HpSimDriverResource"); break;
case DriverShpc: wsprintf(imagePath, L"%s\\shpc.sys", winDir); return SoftPCI_ExpandResourceFile(imagePath, L"ShpcDriverResource"); break; default: return FALSE; }
}
BOOL SoftPCI_InstallDriverInf( VOID ) /*++
Routine Description:
This routine takes the INF we created and installs the Services section
Arguments:
InfPath - Path to the INF we created
Return Value:
TRUE if success
--*/ {
HINF infHandle; UINT errorLine, i; WCHAR infPath[MAX_PATH]; WCHAR winDir[MAX_PATH];
if (GetWindowsDirectory(winDir, MAX_PATH)==0) return FALSE ;
wcscat(winDir, L"\\pcisim");
wsprintf(infPath, L"%s\\softpci.inf", winDir); infHandle = SetupOpenInfFile(infPath, NULL, INF_STYLE_WIN4, &errorLine); if (infHandle == INVALID_HANDLE_VALUE) { SoftPCI_Debug(SoftPciInstall, L"InstallDriverInf - failed open inf. Error = \"%s\"\n", SoftPCI_GetLastError()); return FALSE; }
if (!SetupInstallServicesFromInfSection(infHandle, SOFTPCI_FILTER_SECTION, 0)){ SoftPCI_Debug(SoftPciInstall, L"InstallDriverInf - failed to install service key. Error = \"%s\"\n", SoftPCI_GetLastError()); return FALSE; }
SetupCloseInfFile(infHandle); return SetupCopyOEMInf(infPath, winDir, SPOST_PATH, SP_COPY_DELETESOURCE, NULL, 0, NULL, NULL );
}
BOOL SoftPCI_InstallFilterKey( IN DEVNODE RootBus ) /*++
Routine Description:
This routine takes updates or adds the LowerFilters Key to the registry so that our driver is loaded each boot
Arguments:
RootBus - the devnode for the root bus we want to filter
Return Value: TRUE if success
--*/ {
BOOL status = FALSE; PWCHAR buffer = NULL, newBuffer, entry = NULL, entry2 = NULL; DWORD requiredSize = 0, size = ((wcslen(SOFTPCI_FILTER_SERVICE_NAME)+1) * sizeof(WCHAR)); CONFIGRET cr = CR_SUCCESS; //
// First call is to get required buffer size
//
if ((cr = CM_Get_DevNode_Registry_Property(RootBus, //Devnode
CM_DRP_LOWERFILTERS, //Reg Propert
NULL, //REG data type
NULL, //Buffer
&requiredSize, //Buffer size
0 //flags
)) != CR_SUCCESS){ if (cr == CR_NO_SUCH_VALUE) { //
// No filter. Add ours.
//
if ((cr = CM_Set_DevNode_Registry_Property(RootBus, CM_DRP_LOWERFILTERS, (PVOID)SOFTPCI_FILTER_SERVICE_NAME, size, 0 )) != CR_SUCCESS){ return FALSE; } return TRUE; } //
// If there is already a filter key, then we need to append to it
//
if (requiredSize) {
buffer = (PWCHAR) calloc(1, requiredSize);
if (buffer == NULL) { return FALSE; }
//
// Call again and get the current filter value
//
if ((CM_Get_DevNode_Registry_Property(RootBus, CM_DRP_LOWERFILTERS, NULL, buffer, &requiredSize, 0 )) != CR_SUCCESS){ status = FALSE; goto cleanup; }
newBuffer = (PWCHAR) calloc(1, (requiredSize + size));
if (newBuffer == NULL) { return FALSE; }
entry2 = newBuffer;
//
// Run the list. If we are already present bail
//
for (entry = buffer; *entry; entry += (wcslen(entry)+1)) { if (wcscmp(entry, SOFTPCI_FILTER_SERVICE_NAME) == 0) { //
// We are already installed
//
MessageBox(NULL, L"SoftPCI driver support already installed!", L"Install Error", MB_OK); status = FALSE; goto cleanup; }
//
// copy each entry to our new list
//
wcscpy(entry2, entry);
entry2 += (wcslen(entry)+1); } //
// Add our entry to the list
//
wcscpy(entry2, SOFTPCI_FILTER_SERVICE_NAME);
if ((cr = CM_Set_DevNode_Registry_Property(RootBus, CM_DRP_LOWERFILTERS, newBuffer, requiredSize + size, 0 )) != CR_SUCCESS){ status = FALSE; goto cleanup; }
status = TRUE; goto cleanup;
}
//
// Failed to get required size
//
} #ifdef DEBUG
else{ SOFTPCI_ASSERT(FALSE); //
// VERY BAD!! Should never get back success here!
//
} #endif
cleanup:
if (buffer) { free(buffer); }
if (newBuffer) { free(newBuffer); } return status; }
VOID SoftPCI_LocateRootPciBusesForInstall( IN PPCI_DN Pdn, OUT PBOOL Success ) /*++
Routine Description:
This routine searches our tree for all root pci buses and then installs our filter on them Arguments:
RootBus - Location to return first root bus.
Return Value:
TRUE if success.
--*/ { PPCI_DN child, sibling; if (Pdn == NULL) { *Success = FALSE; return; }
child = Pdn->Child; sibling = Pdn->Sibling; if (SoftPCI_IsDevnodePCIRoot(Pdn->DevNode, FALSE)) { *Success = SoftPCI_InstallFilterKey(Pdn->DevNode);
if (*Success) { SoftPCI_UpdateDeviceFriendlyName(Pdn->DevNode, SOFTPCI_BUS_DESC); } }
if (*Success && child) { SoftPCI_LocateRootPciBusesForInstall(child, Success); } if (*Success && sibling) { SoftPCI_LocateRootPciBusesForInstall(sibling, Success); }
}
BOOL SoftPCI_RebootSystem( VOID ) { HANDLE token; TOKEN_PRIVILEGES tp; LUID luid;
if (!OpenProcessToken(GetCurrentProcess(), (TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY), &token)){ return FALSE; } if (!LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &luid)) { return FALSE; } tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; AdjustTokenPrivileges(token, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL ); if (GetLastError() != ERROR_SUCCESS) { return FALSE; }
//
// We should now be able to reboot the system.
//
return InitiateSystemShutdown(NULL, NULL, 0, TRUE, TRUE);
}
#if 0
BOOL _lwritef( IN HANDLE hFile, IN PTSTR Format, ...) /*++
Routine Description:
This routine provides "fprintf" like functionality. (code stolen from DVNT)
Arguments:
hFile - Handle to INF file Format - String of data to be formatted and written
Return Value:
FALSE if no failures.
--*/ { va_list arglist; WCHAR buffer[514]; INT cb; DWORD written;
va_start(arglist, Format);
cb = wvsprintf(buffer, Format, arglist); if (cb == -1) // handle buffer overflow
{ cb = sizeof(buffer) ; } else { cb+=2 ; } lstrcpy(buffer+cb-2, TEXT("\r\n")) ;
return (WriteFile(hFile, buffer, cb*sizeof(WCHAR), &written, NULL ));
}
BOOL SoftPCI_CreateDriverINF( IN LPTSTR InfPath ) /*++
Routine Description:
This routine build our INF file needed to install our SoftPCI devices. Arguments: InfPath = Path to INF we need to create
Return Value:
TRUE if successful.
--*/ {
BOOL result = TRUE; HANDLE hFile; SYSTEMTIME systime;
GetLocalTime(&systime);
if ((hFile = CreateFile(InfPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL )) == INVALID_HANDLE_VALUE) {
return FALSE; }
result &= _lwritef(hFile, TEXT("[Version]")); result &= _lwritef(hFile, TEXT("Signature=\"$WINDOWS NT$\"")); result &= _lwritef(hFile, TEXT("Class=System")); result &= _lwritef(hFile, TEXT("ClassGuid={4D36E97D-E325-11CE-BFC1-08002BE10318}")); result &= _lwritef(hFile, TEXT("Provider=%%MSFT%%")); result &= _lwritef(hFile, TEXT("LayoutFile=layout.inf")); result &= _lwritef(hFile, TEXT("DriverVer=%02d/%02d/%04d,5.1.%d.0\r\n"), systime.wMonth, systime.wDay, systime.wYear, VER_PRODUCTBUILD); result &= _lwritef(hFile, TEXT("[DestinationDirs]")); result &= _lwritef(hFile, TEXT("DefaultDestDir = 12\r\n")); result &= _lwritef(hFile, TEXT("[Manufacturer]")); result &= _lwritef(hFile, TEXT("%%GENDEV_MFG%%=GENDEV_SYS\r\n"));
result &= _lwritef(hFile, TEXT("[GENDEV_SYS]")); result &= _lwritef(hFile, TEXT("%%VEN_ABCD&DEV_DCBA.DeviceDesc%% = SOFTPCI_FDO_Install, PCI\\VEN_ABCD&DEV_DCBA&SUBSYS_DCBAABCD")); result &= _lwritef(hFile, TEXT("%%VEN_ABCD&DEV_DCBC.DeviceDesc%% = HPPCI_DRV, PCI\\VEN_ABCD&DEV_DCBC\r\n")); result &= _lwritef(hFile, TEXT(";****************************************************")); result &= _lwritef(hFile, TEXT("; SoftPci filter")); result &= _lwritef(hFile, TEXT("[%s]"), SOFTPCI_FILTER_SECTION); result &= _lwritef(hFile, TEXT("AddService = %s,0,softpci_ServiceInstallSection\r\n"), SOFTPCI_FILTER_SERVICE_NAME);
result &= _lwritef(hFile, TEXT("[softpci_ServiceInstallSection]")); result &= _lwritef(hFile, TEXT("DisplayName = %%softpci_filterdesc%%")); result &= _lwritef(hFile, TEXT("ServiceType = %%SERVICE_KERNEL_DRIVER%%")); result &= _lwritef(hFile, TEXT("StartType = %%SERVICE_BOOT_START%%")); result &= _lwritef(hFile, TEXT("ErrorControl = %%SERVICE_ERROR_NORMAL%%")); result &= _lwritef(hFile, TEXT("ServiceBinary = %%12%%\\%s.sys\r\n"), SOFTPCIDRV);
result &= _lwritef(hFile, TEXT(";****************************************************")); result &= _lwritef(hFile, TEXT("; SoftPci function driver")); result &= _lwritef(hFile, TEXT("[SOFTPCI_FDO_Install]")); result &= _lwritef(hFile, TEXT("CopyFiles=%s.sys\r\n"), SOFTPCIDRV);
result &= _lwritef(hFile, TEXT("[SOFTPCI_FDO_Install.Services]")); result &= _lwritef(hFile, TEXT("AddService = SoftPCI_FDO,0x000001fa,SOFTPCI_FDO_ServiceInstallSection\r\n"));
result &= _lwritef(hFile, TEXT("[SOFTPCI_FDO_ServiceInstallSection]")); result &= _lwritef(hFile, TEXT("DisplayName = %%softpci_fdodesc%%")); result &= _lwritef(hFile, TEXT("ServiceType = %%SERVICE_KERNEL_DRIVER%%")); result &= _lwritef(hFile, TEXT("StartType = %%SERVICE_DEMAND_START%%")); result &= _lwritef(hFile, TEXT("ErrorControl = %%SERVICE_ERROR_NORMAL%%")); result &= _lwritef(hFile, TEXT("ServiceBinary = %%12%%\\%s.sys\r\n"), SOFTPCIDRV);
result &= _lwritef(hFile, TEXT(";****************************************************")); result &= _lwritef(hFile, TEXT("; Hotplug Controller simulator and driver")); result &= _lwritef(hFile, TEXT("[HPPCI_DRV]")); result &= _lwritef(hFile, TEXT("CopyFiles=HPPCI.CopyFiles\r\n")); result &= _lwritef(hFile, TEXT("[HPPCI_DRV.HW]")); result &= _lwritef(hFile, TEXT("AddReg = HPPCI_Filter_Reg\r\n"));
result &= _lwritef(hFile, TEXT("[HPPCI_DRV.Services]")); result &= _lwritef(hFile, TEXT("AddService = hpsim,0,hpsim_ServiceInstallSection")); result &= _lwritef(hFile, TEXT("AddService = shpc,0,shpc_ServiceInstallSection")); result &= _lwritef(hFile, TEXT("AddService = pci, %%SPSVCINST_ASSOCSERVICE%%, pci_ServiceInstallSection\r\n"));
result &= _lwritef(hFile, TEXT("[HPPCI_Filter_Reg]")); result &= _lwritef(hFile, TEXT("HKR,,\"LowerFilters\", 0x00010000,\"hpsim\"")); result &= _lwritef(hFile, TEXT("HKR,,\"UpperFilters\", 0x00010000,hpsim,shpc\r\n")); result &= _lwritef(hFile, TEXT("[HPPCI.CopyFiles]")); result &= _lwritef(hFile, TEXT("hpsim.sys")); result &= _lwritef(hFile, TEXT("shpc.sys\r\n"));
result &= _lwritef(hFile, TEXT("[hpsim_ServiceInstallSection]")); result &= _lwritef(hFile, TEXT("DisplayName = %%hpsim_svcdesc%%")); result &= _lwritef(hFile, TEXT("ServiceType = %%SERVICE_KERNEL_DRIVER%%")); result &= _lwritef(hFile, TEXT("StartType = %%SERVICE_DEMAND_START%%")); result &= _lwritef(hFile, TEXT("ErrorControl = %%SERVICE_ERROR_NORMAL%%")); result &= _lwritef(hFile, TEXT("ServiceBinary = %%12%%\\hpsim.sys\r\n"));
result &= _lwritef(hFile, TEXT("[shpc_ServiceInstallSection]]")); result &= _lwritef(hFile, TEXT("DisplayName = %%shpc_svcdesc%%")); result &= _lwritef(hFile, TEXT("ServiceType = %%SERVICE_KERNEL_DRIVER%%")); result &= _lwritef(hFile, TEXT("StartType = %%SERVICE_DEMAND_START%%")); result &= _lwritef(hFile, TEXT("ErrorControl = %%SERVICE_ERROR_NORMAL%%")); result &= _lwritef(hFile, TEXT("ServiceBinary = %%12%%\\shpc.sys\r\n"));
result &= _lwritef(hFile, TEXT(";****************************************************")); result &= _lwritef(hFile, TEXT(";Device descriptions")); result &= _lwritef(hFile, TEXT("[Strings]")); result &= _lwritef(hFile, TEXT("GENDEV_MFG = \"(Standard system devices)\"")); result &= _lwritef(hFile, TEXT("SystemClassName = \"System devices\"")); result &= _lwritef(hFile, TEXT("MSFT = \"Microsoft\""));
result &= _lwritef(hFile, TEXT("VEN_ABCD&DEV_DCBA.DeviceDesc = \"%s\""), SOFTPCI_DEVICE_DESC); result &= _lwritef(hFile, TEXT("VEN_ABCD&DEV_DCBC.DeviceDesc = \"%s\"\r\n"), SOFTPCI_HOTPLUG_DESC);
result &= _lwritef(hFile, TEXT(";****************************************************")); result &= _lwritef(hFile, TEXT(";Service descriptions")); result &= _lwritef(hFile, TEXT("softpci_fdodesc = \"Microsoft SoftPCI Device Driver\"")); result &= _lwritef(hFile, TEXT("softpci_filterdesc = \"Microsoft SoftPCI Bus Filter\"")); result &= _lwritef(hFile, TEXT("hpsim_svcdesc = \"Hotplug Controller Simulator Filter\"")); result &= _lwritef(hFile, TEXT("shpc_svcdesc = \"Hotplug Controller Bus Filter\"\r\n"));
result &= _lwritef(hFile, TEXT(";****************************************************")); result &= _lwritef(hFile, TEXT(";Handy macro substitutions (non-localizable)")); result &= _lwritef(hFile, TEXT("SPSVCINST_ASSOCSERVICE = 0x00000002")); result &= _lwritef(hFile, TEXT("SERVICE_KERNEL_DRIVER = 1")); result &= _lwritef(hFile, TEXT("SERVICE_BOOT_START = 0")); result &= _lwritef(hFile, TEXT("SERVICE_DEMAND_START = 3")); result &= _lwritef(hFile, TEXT("SERVICE_ERROR_NORMAL = 1")); result &= _lwritef(hFile, TEXT("SERVICE_ERROR_CRITICAL = 3"));
CloseHandle(hFile);
return result;
} #endif
|