|
|
#include <pch.h>
BOOL SoftPCI_CopyLine( OUT PWCHAR Destination, IN PWCHAR CurrentLine, IN ULONG DestinationSize );
BOOL SoftPCI_GetConfigValue( IN PWCHAR CurrentDataPtr, IN PULONG DataValue, IN PULONG DataSize );
BOOL SoftPCI_GetDeviceInstallCount( IN PWCHAR InstallSection, OUT PULONG DeviceCount );
BOOL SoftPCI_GetDeviceInstallList( IN PWCHAR InstallSection, IN OUT PWCHAR *DeviceInstallList );
BOOL SoftPCI_GetNextConfigOffset( IN OUT PWCHAR *ConfigDataPtr, OUT PUCHAR ConfigOffset );
PWCHAR SoftPCI_GetNextLinePtr( PWCHAR CurrentLine );
PWCHAR SoftPCI_GetNextSectionPtr( IN PWCHAR CurrentLine );
VOID SoftPCI_GetCurrentParameter( OUT PWCHAR Destination, IN PWCHAR CurrentLine );
PWCHAR SoftPCI_GetParameterValuePtr( IN PWCHAR CurrentLine );
VOID SoftPCI_InsertEntryAtTail( IN PSINGLE_LIST_ENTRY Entry );
BOOL SoftPCI_LocateSoftPCISection( VOID );
PWCHAR SoftPCI_LocateFullParentPath( IN PWCHAR ParentInstallSection );
HANDLE SoftPCI_OpenFile( IN PWCHAR FilePath );
BOOL SoftPCI_ProcessInstallSection( VOID );
BOOL SoftPCI_ProcessDeviceInstallSection( IN PWCHAR DeviceInstallSection );
BOOL SoftPCI_ProcessDeviceInstallParameters( IN PWCHAR DeviceInstallSection );
BOOL SoftPCI_ProcessTypeParameter( IN PWCHAR ParameterPtr, IN OUT PSOFTPCI_SCRIPT_DEVICE *InstallDevice );
BOOL SoftPCI_ProcessSlotParameter( IN PWCHAR ParameterPtr, IN OUT PSOFTPCI_SCRIPT_DEVICE *InstallDevice );
BOOL SoftPCI_ProcessParentPathParameter( IN PWCHAR ParameterPtr, IN OUT PSOFTPCI_SCRIPT_DEVICE *InstallDevice );
BOOL SoftPCI_ProcessCfgSpaceParameter( IN PWCHAR ParameterPtr, IN OUT PSOFTPCI_SCRIPT_DEVICE *InstallDevice );
BOOL SoftPCI_ProcessCfgMaskParameter( IN PWCHAR ParameterPtr, IN OUT PSOFTPCI_SCRIPT_DEVICE *InstallDevice );
BOOL SoftPCI_ParseConfigSpace( IN PWCHAR ParameterPtr, IN PPCI_COMMON_CONFIG CommonConfig );
BOOL SoftPCI_ParseConfigData( IN UCHAR ConfigOffset, IN PUCHAR ConfigBuffer, IN PWCHAR ConfigData );
BOOL SoftPCI_ReadFile( VOID );
USHORT SoftPCI_StringToUSHORT( IN PWCHAR String );
BOOL SoftPCI_ValidatePciPath( IN PWCHAR PciPath );
//
// This is the list we fill out as we parse the ini file for
// new devices to be installed
//
SINGLE_LIST_ENTRY g_NewDeviceList;
WCHAR g_ScriptError[MAX_PATH];
BOOL typedef (*PSCRIPT_PARAMETER_PARSER) ( IN PWCHAR ParameterPtr, IN OUT PSOFTPCI_SCRIPT_DEVICE *InstallDevice );
#define INI_SOFTPCI_SECTION L"[softpci]"
#define INI_INSTALL_SECTION L"[install]"
//
// Currently supported parameter tags
//
#define TYPEPARAMTER L"type"
#define SLOTPARAMTER L"slot"
#define PPATHPARAMETER L"parentpath"
#define CFGSPACEPARAMETER L"configspace"
#define CFGMASKPARAMETER L"configspacemask"
//
// This is the Parameter table we use to handle
// parseing for each supported parameter tag
//
struct { PWCHAR Parameter; PSCRIPT_PARAMETER_PARSER ParameterParser;
} g_ScriptParameterTable[] = { TYPEPARAMTER, SoftPCI_ProcessTypeParameter, SLOTPARAMTER, SoftPCI_ProcessSlotParameter, PPATHPARAMETER, SoftPCI_ProcessParentPathParameter, CFGSPACEPARAMETER, SoftPCI_ProcessCfgSpaceParameter, CFGMASKPARAMETER, SoftPCI_ProcessCfgMaskParameter, NULL, NULL };
//
// We use this table to match up which "Type" tag to the
// device type we are installing
//
struct { PWCHAR TypeParamter; SOFTPCI_DEV_TYPE DevType;
} g_ParameterTypeTable[] = { L"device", TYPE_DEVICE, L"ppbridge", TYPE_PCI_BRIDGE, L"hpbridge", TYPE_HOTPLUG_BRIDGE, L"cbdevice", TYPE_CARDBUS_DEVICE, L"cbbridge", TYPE_CARDBUS_BRIDGE, L"private", TYPE_UNKNOWN, NULL, 0 };
struct { HANDLE FileHandle; ULONG FileSize; PWCHAR FileBuffer; } g_ScriptFile;
#define CRLF L"\r\n"
#define MAX_LINE_SIZE 100
#define MAX_PARAMETER_LENGTH 50
#define MAX_PARAMETER_TYPE_LENGTH 25
#define IGNORE_WHITESPACE_FORWARD(x) \
while ((*x == ' ') || (*x == '\t')) { \ x++; \ } #define IGNORE_WHITESPACE_BACKWARD(x) \
while ((*x == ' ') || (*x == '\t')) { \ x--; \ }
VOID SoftPCI_InsertEntryAtTail( IN PSINGLE_LIST_ENTRY Entry ) { PSINGLE_LIST_ENTRY previousEntry;
//
// Find the end of the list.
//
previousEntry = &g_NewDeviceList;
while (previousEntry->Next) { previousEntry = previousEntry->Next; }
//
// Append the entry.
//
previousEntry->Next = Entry; }
BOOL SoftPCI_BuildDeviceInstallList( IN PWCHAR ScriptFile ) {
BOOL status = FALSE; #if 0
HINF hInf; UINT errorLine; INFCONTEXT infContext;
errorLine = 0; hInf = SetupOpenInfFile( ScriptFile, NULL, INF_STYLE_OLDNT, &errorLine );
if (hInf == INVALID_HANDLE_VALUE) {
SoftPCI_Debug(SoftPciScript, L"Failed to open handle to %s\n", ScriptFile); return FALSE; }
if (SetupFindFirstLine(hInf, L"softpci", NULL, &infContext )){
SoftPCI_Debug(SoftPciScript, L"found our section!\n"); } SoftPCI_Debug(SoftPciScript, L"Ready to party on %s\n", ScriptFile); SetupCloseInfFile(hInf); return FALSE; #endif
wcscpy(g_ScriptError, L"Unknown Error"); g_ScriptFile.FileHandle = SoftPCI_OpenFile(ScriptFile); if (g_ScriptFile.FileHandle != INVALID_HANDLE_VALUE) {
status = SoftPCI_ReadFile();
//
// We no longer need the file
//
CloseHandle(g_ScriptFile.FileHandle);
if (!status) { return status; }
//
// Ensure the buffer is all lower case.
//
_wcslwr(g_ScriptFile.FileBuffer);
//
// Validate install section exits
//
if (!SoftPCI_LocateSoftPCISection()) { status = FALSE; goto CleanUp; }
if (!SoftPCI_ProcessInstallSection()) { status = FALSE; goto CleanUp; }
}
#if DBG
else{ SoftPCI_Debug(SoftPciScript, L"Failed to open handle to %s\n", ScriptFile); } #endif
CleanUp:
free(g_ScriptFile.FileBuffer); return status; }
BOOL SoftPCI_CopyLine( OUT PWCHAR Destination, IN PWCHAR CurrentLine, IN ULONG DestinationSize ) {
PWCHAR lineEnd = NULL; PWCHAR copyBuffer = Destination; PWCHAR currentLine = CurrentLine; ULONG bufferSize; ULONG lineSize; lineEnd = wcsstr(CurrentLine, CRLF); if (!lineEnd) { //
// We must be at the last line
//
wcscpy(copyBuffer, currentLine); return TRUE; }
lineSize = ((ULONG)(lineEnd - CurrentLine) * sizeof(WCHAR));
//
// If our destination buffer size is less than the size of
// the line we only copy the size of the buffer. Otherwise
// we zero the input buffer and copy just the line size.
//
if (DestinationSize){
bufferSize = (DestinationSize * sizeof(WCHAR)); RtlZeroMemory(Destination, bufferSize);
if (lineSize > bufferSize) { lineSize = bufferSize - sizeof(WCHAR); } } RtlCopyMemory(Destination, CurrentLine, lineSize); return TRUE; }
BOOL SoftPCI_GetDeviceInstallCount( IN PWCHAR InstallSection, OUT PULONG DeviceCount ) {
PWCHAR installDevice; PWCHAR installDeviceSectionStart = NULL; ULONG deviceCount = 0;
installDevice = SoftPCI_GetNextLinePtr(InstallSection); installDeviceSectionStart = wcsstr(installDevice, L"["); if (!installDeviceSectionStart) { wcscpy(g_ScriptError, L"Device install section missing or invalid!"); return FALSE; }
while (installDevice != installDeviceSectionStart) {
deviceCount++; installDevice = SoftPCI_GetNextLinePtr(installDevice);
if (installDevice == NULL) { //
// We reached the EOF way to early!
//
wcscpy(g_ScriptError, L"Unexpected EOF reached!"); return FALSE; } } *DeviceCount = deviceCount;
return TRUE; }
BOOL SoftPCI_GetDeviceInstallList( IN PWCHAR InstallSection, IN OUT PWCHAR *DeviceInstallList ) {
PWCHAR *deviceInstallList; PWCHAR installDevice; PWCHAR installDeviceSectionStart;
deviceInstallList = DeviceInstallList; installDevice = SoftPCI_GetNextLinePtr(InstallSection); installDeviceSectionStart = wcsstr(installDevice, L"["); if (!installDeviceSectionStart) { return FALSE; }
while (installDevice != installDeviceSectionStart) {
IGNORE_WHITESPACE_FORWARD(installDevice);
*deviceInstallList = installDevice;
installDevice = SoftPCI_GetNextLinePtr(installDevice);
if (installDevice == NULL) { //
// We reached the EOF way to early!
//
wcscpy(g_ScriptError, L"Unexpected EOF reached!"); return FALSE; } deviceInstallList++; }
if ((*(installDevice - 1) == '\n') && (*(installDevice - 3) == '\n')) { //
// Ignore the whitespace here
//
deviceInstallList--; *deviceInstallList = NULL; }
return TRUE;
}
BOOL SoftPCI_GetNextConfigOffset( IN OUT PWCHAR *ConfigDataPtr, OUT PUCHAR ConfigOffset ) {
PWCHAR configOffsetPtr, dummy; PWCHAR nextConfigSpace; WCHAR offset[2]; ULONG i;
configOffsetPtr = *ConfigDataPtr; if (configOffsetPtr == NULL) { return FALSE; }
//
// make sure that the next offset we find is without the current
// configspace we are parsing
//
nextConfigSpace = wcsstr(configOffsetPtr, L"config"); if (nextConfigSpace == NULL) { nextConfigSpace = configOffsetPtr + wcslen(configOffsetPtr); } configOffsetPtr = wcsstr(configOffsetPtr, L":"); if ((configOffsetPtr == NULL) || (configOffsetPtr > nextConfigSpace)) { return FALSE; }
IGNORE_WHITESPACE_BACKWARD(configOffsetPtr); configOffsetPtr -= 2;
for (i=0; i<2; i++) { offset[i] = *configOffsetPtr; configOffsetPtr++; } IGNORE_WHITESPACE_FORWARD(configOffsetPtr); configOffsetPtr++; IGNORE_WHITESPACE_FORWARD(configOffsetPtr); *ConfigDataPtr = configOffsetPtr;
*ConfigOffset = (UCHAR) wcstoul(offset, &dummy, 16);
return TRUE; }
PWCHAR SoftPCI_GetNextLinePtr( IN PWCHAR CurrentLine )
{ PWCHAR nextLine = NULL; PWCHAR currentLine = CurrentLine; BOOL lineSkipped = FALSE; if (!CurrentLine) { return NULL; } nextLine = wcsstr(CurrentLine, CRLF);
if (nextLine && *(nextLine+2) == ';'){ currentLine = nextLine; }
while (nextLine == currentLine) { currentLine += 2; nextLine = wcsstr(currentLine, CRLF); if (!nextLine) { nextLine = currentLine; break; } if (*currentLine == ';') { currentLine = nextLine; } lineSkipped = TRUE; }
if (lineSkipped) { return ((nextLine != NULL) ? currentLine: nextLine); } if (nextLine){ nextLine += 2; }
return nextLine; }
PWCHAR SoftPCI_GetNextSectionPtr( IN PWCHAR CurrentLine ) {
PWCHAR nextSection;
nextSection = wcsstr(CurrentLine, L"["); if (nextSection == NULL) { nextSection = CurrentLine + wcslen(CurrentLine); }
return nextSection;
}
VOID SoftPCI_GetCurrentParameter( OUT PWCHAR Destination, IN PWCHAR CurrentLine ) { PWCHAR p = Destination; PWCHAR currentLine = CurrentLine;
IGNORE_WHITESPACE_FORWARD(currentLine);
SoftPCI_CopyLine(Destination, currentLine, MAX_PARAMETER_LENGTH);
p = wcsstr(Destination, L"=");
if (p) { p--; IGNORE_WHITESPACE_BACKWARD(p); p++; *p = 0; } }
BOOL SoftPCI_GetParameterValue( OUT PWCHAR Destination, IN PWCHAR CurrentLine, IN ULONG DestinationLength ) { PWCHAR valuePtr = NULL; valuePtr = wcsstr(CurrentLine, L"=");
if (!valuePtr) { return FALSE; } valuePtr++;
IGNORE_WHITESPACE_FORWARD(valuePtr); SoftPCI_CopyLine(Destination, valuePtr, DestinationLength);
return TRUE; }
PWCHAR SoftPCI_GetParameterValuePtr( IN PWCHAR CurrentLine ) {
PWCHAR valuePtr; PWCHAR nextSectionPtr; valuePtr = wcsstr(CurrentLine, L"="); if (!valuePtr) { return NULL; }
nextSectionPtr = SoftPCI_GetNextSectionPtr(CurrentLine);
if (valuePtr > nextSectionPtr) { return NULL; } valuePtr++;
IGNORE_WHITESPACE_FORWARD(valuePtr);
return valuePtr; }
BOOL SoftPCI_LocateSoftPCISection( VOID ) { PWCHAR p = NULL;
p = wcsstr(g_ScriptFile.FileBuffer, INI_SOFTPCI_SECTION);
return (p != NULL); }
PWCHAR SoftPCI_LocateFullParentPath( IN PWCHAR ParentInstallSection ) { WCHAR parentSection[MAX_PATH]; PWCHAR deviceSectionPtr; PWCHAR parentPathPtr;
wsprintf(parentSection, L"[%s]", ParentInstallSection);
SoftPCI_Debug(SoftPciScript, L" - - Searching for %s section...\n", parentSection);
deviceSectionPtr = wcsstr(g_ScriptFile.FileBuffer, parentSection);
if (!deviceSectionPtr) { return NULL; }
//
// Now jump to the parentpath section.
//
parentPathPtr = wcsstr(deviceSectionPtr, PPATHPARAMETER);
if (!parentPathPtr) { return NULL; }
return NULL; }
BOOL SoftPCI_ProcessInstallSection( VOID ) { PWCHAR installSection; PWCHAR *installDeviceList; PWCHAR *installDeviceCurrent; ULONG installDeviceCount; BOOL result = TRUE;
installSection = wcsstr(g_ScriptFile.FileBuffer, INI_INSTALL_SECTION);
if (installSection) { //
// We have our install section. Build our install list
//
installDeviceCount = 0; if (!SoftPCI_GetDeviceInstallCount(installSection, &installDeviceCount)){ return FALSE; }
//
// Allocate an array of PWCHAR plus an extra NULL
//
installDeviceList = calloc(installDeviceCount + 1, sizeof(PWCHAR));
if (!SoftPCI_GetDeviceInstallList(installSection, installDeviceList)) { free(installDeviceList); return FALSE; }
//
// Now we have our list. Install each device
//
installDeviceCurrent = installDeviceList;
while(*installDeviceCurrent){ //
// Loop through each device to install and parse
// it's InstallParamters
//
result = SoftPCI_ProcessDeviceInstallSection(*installDeviceCurrent);
#if 0
{
WCHAR failedSection[MAX_PATH];
SoftPCI_CopyLine(failedSection, *installDeviceCurrent, MAX_PATH);
if (!result) {
SoftPCI_Debug(SoftPciScript, L"Error parsing [%s] section!\n", failedSection);
}else{
SoftPCI_Debug(SoftPciScript, L" -- successfully parsed %s section!\n", failedSection); } } #endif
installDeviceCurrent++; } }
free(installDeviceList);
return TRUE; }
BOOL SoftPCI_ProcessDeviceInstallSection( IN PWCHAR DeviceInstallSection ) { WCHAR deviceSectionString[MAX_PATH]; WCHAR deviceSection[MAX_PATH]; PWCHAR deviceSectionPtr;
SoftPCI_CopyLine(deviceSection, DeviceInstallSection, MAX_PATH);
wsprintf(deviceSectionString, L"[%s]", deviceSection);
SoftPCI_Debug(SoftPciScript, L"Searching for %s section...\n", deviceSectionString);
deviceSectionPtr = wcsstr(DeviceInstallSection, deviceSectionString);
if (!deviceSectionPtr) { return FALSE; }
SoftPCI_Debug(SoftPciScript, L" - found %s section!\n", deviceSectionString);
//
// We have an install section. Process InstallParamters
//
return SoftPCI_ProcessDeviceInstallParameters(deviceSectionPtr); }
BOOL SoftPCI_ProcessDeviceInstallParameters( IN PWCHAR DeviceInstallSection ) { ULONG i; BOOL result; WCHAR currentParameter[MAX_PARAMETER_LENGTH]; PWCHAR currentParameterPtr; PWCHAR nextSectionPtr; PSOFTPCI_SCRIPT_DEVICE currentDevice; PSOFTPCI_SCRIPT_DEVICE installDevice;
nextSectionPtr = SoftPCI_GetNextSectionPtr(DeviceInstallSection+1);
if (SoftPCI_GetNextLinePtr(DeviceInstallSection) == NULL) { return FALSE; }
currentParameterPtr = SoftPCI_GetNextLinePtr(DeviceInstallSection); SoftPCI_Debug(SoftPciScript, L"nextSectionPtr = %p\n", nextSectionPtr); SoftPCI_Debug(SoftPciScript, L"currentParameterPtr = %p\n", currentParameterPtr);
if (!currentParameterPtr) { //
// We dont have a Parameter to process
//
SoftPCI_Debug(SoftPciScript, L"EOF reached before parameters processed!\n"); return FALSE; } result = FALSE; while (currentParameterPtr < nextSectionPtr) { //
// Grab our parameters and run the respective parser
//
SoftPCI_GetCurrentParameter(currentParameter, currentParameterPtr);
SoftPCI_Debug(SoftPciScript, L"currentParameter = %s\n", currentParameter);
i = 0; while (g_ScriptParameterTable[i].Parameter) {
if ((wcscmp(currentParameter, g_ScriptParameterTable[i].Parameter) == 0)) {
result = g_ScriptParameterTable[i].ParameterParser(currentParameterPtr, ¤tDevice); } i++; }
currentParameterPtr = SoftPCI_GetNextLinePtr(currentParameterPtr);
if (currentParameterPtr == NULL) { //
// EOF
//
break; } }
SoftPCI_Debug(SoftPciScript, L"currentParameterPtr = %p\n", currentParameterPtr); if (currentDevice && currentDevice->SoftPciDevice.Config.Current.VendorID) { //
// We have something so assume all is well
//
SoftPCI_Debug(SoftPciScript, L"New device ready to install! Ven %04x Dev %04x\n", currentDevice->SoftPciDevice.Config.Current.VendorID, currentDevice->SoftPciDevice.Config.Current.DeviceID );
SoftPCI_InsertEntryAtTail(¤tDevice->ListEntry); //free(currentDevice->ParentPath);
//free(currentDevice);
return TRUE; }
return FALSE;
}
BOOL SoftPCI_ProcessTypeParameter( IN PWCHAR ParameterPtr, IN OUT PSOFTPCI_SCRIPT_DEVICE *InstallDevice ) { WCHAR parameterType[MAX_PARAMETER_TYPE_LENGTH]; PSOFTPCI_SCRIPT_DEVICE installDevice; ULONG i;
SoftPCI_Debug(SoftPciScript, L"ProcessTypeParameter called\n");
if (!SoftPCI_GetParameterValue(parameterType, ParameterPtr, MAX_PARAMETER_TYPE_LENGTH)){ return FALSE; }
SoftPCI_Debug(SoftPciScript, L" parameterType = %s\n", parameterType);
installDevice = (PSOFTPCI_SCRIPT_DEVICE) calloc(1, FIELD_OFFSET(SOFTPCI_SCRIPT_DEVICE, ParentPath));
if (installDevice == NULL) { SoftPCI_Debug(SoftPciScript, L"failed to alloate memory for device!\n"); return FALSE; } i = 0; while (g_ParameterTypeTable[i].TypeParamter) {
if ((wcscmp(parameterType, g_ParameterTypeTable[i].TypeParamter) == 0)) {
SoftPCI_InitializeDevice(&installDevice->SoftPciDevice, g_ParameterTypeTable[i].DevType); } i++; }
*InstallDevice = installDevice;
return TRUE; }
BOOL SoftPCI_ProcessSlotParameter( IN PWCHAR ParameterPtr, IN OUT PSOFTPCI_SCRIPT_DEVICE *InstallDevice ) { WCHAR slotParameter[MAX_PARAMETER_TYPE_LENGTH]; SOFTPCI_SLOT deviceSlot; PSOFTPCI_SCRIPT_DEVICE installDevice;
SoftPCI_Debug(SoftPciScript, L"ProcessSlotParameter called\n");
installDevice = *InstallDevice; if (installDevice == NULL) { return FALSE; }
if (!SoftPCI_GetParameterValue(slotParameter, ParameterPtr, MAX_PARAMETER_TYPE_LENGTH)){ return FALSE; }
SoftPCI_Debug(SoftPciScript, L" slotParameter = %s\n", slotParameter);
deviceSlot.AsUSHORT = SoftPCI_StringToUSHORT(slotParameter); SoftPCI_Debug(SoftPciScript, L" deviceSlot = %04x\n", deviceSlot.AsUSHORT);
installDevice->SoftPciDevice.Slot.AsUSHORT = deviceSlot.AsUSHORT; installDevice->SlotSpecified = TRUE;
return TRUE; }
BOOL SoftPCI_ProcessParentPathParameter( IN PWCHAR ParameterPtr, IN OUT PSOFTPCI_SCRIPT_DEVICE *InstallDevice ) { PWCHAR parentPathPtr; PWCHAR parentPath; PWCHAR endPath; PWCHAR nextSectionPtr; ULONG parentPathLength; PSOFTPCI_SCRIPT_DEVICE installDevice; SoftPCI_Debug(SoftPciScript, L"ProcessParentPathParameter called\n"); //
// ParentPath could in theory be as long as (256 buses * sizeof Slot * sizeof(WCHAR))
// which is 2k. Let's dynamically allocate storage needed.
//
installDevice = *InstallDevice; if (installDevice == NULL) { return FALSE; }
parentPathPtr = SoftPCI_GetParameterValuePtr(ParameterPtr); if (!parentPathPtr) { return FALSE; }
endPath = wcsstr(parentPathPtr, CRLF); parentPathLength = 0; if (endPath) { parentPathLength = (ULONG)((endPath - parentPathPtr) + 1); }else{ parentPathLength = wcslen(parentPathPtr) + 1; }
parentPath = (PWCHAR) calloc(sizeof(WCHAR), parentPathLength + 1);
if (!parentPath) { return FALSE; }
SoftPCI_CopyLine(parentPath, parentPathPtr, 0);
SoftPCI_Debug(SoftPciScript, L" ParentPath - %s\n", parentPath);
//
// Now things get interesting. We need to parse out our parent paths
// if the parent path specified here is a pointer to a previous device
// instead of a actual parent path.
//
//
// ISSUE: BrandonA - Implement this later!!!
//
//InstallDevice->ParentPath = SoftPCI_LocateFullParentPath(parentPath);
parentPathLength *= sizeof(WCHAR);
//
// Now re-allocate the memory used for the installDevice with additional space for the
// parentPathLength
//
installDevice = realloc(installDevice, sizeof(SOFTPCI_SCRIPT_DEVICE) + parentPathLength); if (installDevice) { wcscpy(installDevice->ParentPath, parentPath); installDevice->ParentPathLength = parentPathLength; *InstallDevice = installDevice; }else{ *InstallDevice = NULL; return FALSE; } if (SoftPCI_ValidatePciPath(installDevice->ParentPath)){ return TRUE; } free(installDevice); *InstallDevice = NULL;
return FALSE; }
BOOL SoftPCI_ProcessCfgSpaceParameter( IN PWCHAR ParameterPtr, IN OUT PSOFTPCI_SCRIPT_DEVICE *InstallDevice ) { PSOFTPCI_SCRIPT_DEVICE installDevice; SoftPCI_Debug(SoftPciScript, L"ProcessCfgSpaceParameter called\n"); installDevice = *InstallDevice; if (installDevice == NULL) { return FALSE; }
return SoftPCI_ParseConfigSpace( ParameterPtr, &installDevice->SoftPciDevice.Config.Current );
}
BOOL SoftPCI_ProcessCfgMaskParameter( IN PWCHAR ParameterPtr, IN OUT PSOFTPCI_SCRIPT_DEVICE *InstallDevice ) { PSOFTPCI_SCRIPT_DEVICE installDevice;
SoftPCI_Debug(SoftPciScript, L"ProcessCfgMaskParameter called\n"); installDevice = *InstallDevice; if (installDevice == NULL) { return FALSE; }
return SoftPCI_ParseConfigSpace( ParameterPtr, &installDevice->SoftPciDevice.Config.Mask ); }
BOOL SoftPCI_ParseConfigSpace( IN PWCHAR ParameterPtr, IN PPCI_COMMON_CONFIG CommonConfig ) {
PWCHAR cfgSpacePtr; PWCHAR endLine, nextSection; PUCHAR configPtr; UCHAR configOffset; WCHAR lineBuffer[MAX_LINE_SIZE];
cfgSpacePtr = SoftPCI_GetParameterValuePtr(ParameterPtr);
if (cfgSpacePtr == NULL) { return FALSE; }
if (*cfgSpacePtr == '\r') { //
// Our first offset must start at the next line
//
cfgSpacePtr = SoftPCI_GetNextLinePtr(cfgSpacePtr); } nextSection = SoftPCI_GetNextSectionPtr(cfgSpacePtr);
configPtr = (PUCHAR) CommonConfig; configOffset = 0; while (cfgSpacePtr && (cfgSpacePtr < nextSection)) {
IGNORE_WHITESPACE_FORWARD(cfgSpacePtr)
//
// We should now be pointing to a configspace offset that we need
// to parse. Validate that the line is less than our stack buffer size.
//
endLine = wcsstr(cfgSpacePtr, CRLF);
if (endLine == NULL) { endLine = cfgSpacePtr + wcslen(cfgSpacePtr); }
if ((endLine - cfgSpacePtr) > MAX_PATH) { //
// Too much to parse on one line, Error out.
//
SoftPCI_Debug(SoftPciScript, L"ParseConfigSpace - cannot parse configspace offset!\n"); return FALSE; } //
// Now grab our next offset
//
if (!SoftPCI_GetNextConfigOffset(&cfgSpacePtr, &configOffset)) { //
// We didnt find and offset, fail
//
return FALSE; }
SoftPCI_Debug(SoftPciScript, L"ParseConfigSpace - first offset - %02x\n", configOffset);
SoftPCI_CopyLine(lineBuffer, cfgSpacePtr, MAX_LINE_SIZE); SoftPCI_Debug(SoftPciScript, L"ParseConfigSpace - lineBuffer - %s\n", lineBuffer);
//
// Parse the specified data
//
SoftPCI_ParseConfigData( configOffset, configPtr + configOffset, lineBuffer );
cfgSpacePtr = SoftPCI_GetNextLinePtr(cfgSpacePtr); }
return TRUE;
}
BOOL SoftPCI_ParseConfigData( IN UCHAR ConfigOffset, IN PUCHAR ConfigBuffer, IN PWCHAR ConfigData ) { USHORT configOffset; PUCHAR configBuffer; PWCHAR currentDataPtr, endLine; ULONG dataSize; ULONG dataValue;
configOffset = (USHORT)ConfigOffset; currentDataPtr = ConfigData; configBuffer = ConfigBuffer; while (currentDataPtr) {
SoftPCI_Debug(SoftPciScript, L"ParseConfigData - next offset - %04x\n", configOffset); if (!SoftPCI_GetConfigValue(currentDataPtr, &dataValue, &dataSize)){ return FALSE; } SoftPCI_Debug( SoftPciScript, L"ParseConfigData - dataValue - %x dataSize - %x\n", dataValue, dataSize );
if ((configOffset + dataSize) > sizeof(PCI_COMMON_CONFIG)){ //
// We cannot write more than the common config
//
return FALSE; } RtlCopyMemory(configBuffer, &dataValue, dataSize); currentDataPtr = wcsstr(currentDataPtr, L","); while (currentDataPtr && (*currentDataPtr == ',')) { //
// For each comma encountered we increment to the next DWORD
//
if ((configOffset & 0x3) == 0){ configOffset += sizeof(ULONG); configBuffer += sizeof(ULONG); }else{
while ((configOffset & 0x3) != 0) { configOffset++; configBuffer++; } } currentDataPtr++; if (*currentDataPtr == 0) { currentDataPtr = NULL; break; }
IGNORE_WHITESPACE_FORWARD(currentDataPtr) } } return TRUE; }
BOOL SoftPCI_GetConfigValue( IN PWCHAR CurrentDataPtr, IN PULONG DataValue, IN PULONG DataSize ) {
ULONG value, size; PWCHAR endScan;
*DataValue = 0; *DataSize = 0; value = 0;
endScan = NULL;
value = wcstoul(CurrentDataPtr, &endScan, 16);
if (endScan == CurrentDataPtr) { //
// no valid number was found
//
return FALSE; }
size = (ULONG)(endScan - CurrentDataPtr); if (size % 2) { size++; }
//
// If we have more than 8 characters then max our size out at 8
//
if (size > 8) { size = 8; } SoftPCI_Debug(SoftPciScript, L"GetConfigValue - dataSize - %x\n", size);
//
// Now return our values. Note that size needs to be converted to bytes.
//
*DataSize = (size / 2); *DataValue = value;
return TRUE; }
HANDLE SoftPCI_OpenFile( IN PWCHAR FilePath ) { return CreateFile(FilePath, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, NULL ); }
BOOL SoftPCI_ReadFile( VOID ) /*--
Routine Description:
Reads the file specified by FileHandle into a buffer and returns a pointer to the buffer
Arguments:
none
Return Value:
TRUE on success, FALSE otherwise --*/ {
INT sizeWritten = 0; ULONG fileSize = 0, readSize = 0; PUCHAR ansiFile = NULL; //
// Obtain the File Size
//
fileSize = GetFileSize(g_ScriptFile.FileHandle, NULL); if (fileSize == 0xFFFFFFFF) { SoftPCI_Debug(SoftPciScript, L"Failed to determine size of script file! Error - \"%s\"\n", SoftPCI_GetLastError()); return FALSE; }
//
// Allocate our buffer (with a little padding). It will be zeroed by default
//
ansiFile = (PUCHAR) calloc(1, fileSize + sizeof(ULONG)); g_ScriptFile.FileBuffer = (PWCHAR) calloc(sizeof(WCHAR), fileSize + sizeof(ULONG)); if ((g_ScriptFile.FileBuffer) && ansiFile) {
//
// Read the file
//
if (!ReadFile(g_ScriptFile.FileHandle, ansiFile, fileSize, &readSize, NULL )){
SoftPCI_Debug(SoftPciScript, L"Failed to read file! Error - \"%s\"\n", SoftPCI_GetLastError()); goto CleanUp; }
if (readSize != fileSize) {
SoftPCI_Debug(SoftPciScript, L"Failed to read entire file! Error - \"%s\"\n", SoftPCI_GetLastError()); goto CleanUp; }
//
// Now convert the file to Unicode.
//
sizeWritten = MultiByteToWideChar(CP_THREAD_ACP, MB_PRECOMPOSED, ansiFile, -1, g_ScriptFile.FileBuffer, ((fileSize * sizeof(WCHAR)) + sizeof(ULONG)) );
if (sizeWritten != (strlen(ansiFile) + 1)) {
SoftPCI_Debug(SoftPciScript, L"Failed to convert file to unicode!\n"); goto CleanUp;
}
g_ScriptFile.FileSize = sizeWritten;
free(ansiFile); return TRUE; }
SoftPCI_Debug(SoftPciScript, L"Failed to allocate required memory!");
CleanUp:
if (g_ScriptFile.FileBuffer) { free(g_ScriptFile.FileBuffer); }
if (ansiFile) { free(ansiFile); }
return FALSE; }
USHORT SoftPCI_StringToUSHORT( IN PWCHAR String ) {
WCHAR numbers[] = L"0123456789abcdef"; PWCHAR p1, p2; USHORT convertedValue = 0; BOOLEAN converted = FALSE; p1 = numbers; p2 = String;
while (*p2) {
while (*p1 && (converted == FALSE)) {
if (*p1 == *p2) { //
// Reset our pointer
//
convertedValue <<= 4; convertedValue |= (((UCHAR)(p1 - numbers)) & 0x0f);
converted = TRUE; } p1++; }
if (converted == FALSE) { //
// Encountered something we couldnt convert. Return what we have
//
return convertedValue; }
p2++; p1 = numbers; converted = FALSE; }
return convertedValue; }
BOOL SoftPCI_ValidatePciPath( IN PWCHAR PciPath ) {
ULONG pathLength = wcslen(PciPath); ULONG validSize = pathLength; PWCHAR pciPath = PciPath; PWCHAR p1, p2; WCHAR validChars[] = L"0123456989abcdef\\"; BOOLEAN valid = FALSE; //
// First ignore any pre and ending "\"
//
//if (*pciPath == '\\'){
// validSize -= 1;
//}
//if (*(pciPath+pathLength) == '\\'){
// validSize -= 1;
//}
//
// Now see if everything looks good size wise.
//
if (((validSize - 4) % 5) != 0) { SoftPCI_Debug(SoftPciScript, L" Path size invalid!\n"); return FALSE; } //
// Make sure all characters are legal.
//
p1 = PciPath; while (*p1) {
p2 = validChars; while (*p2) {
if (*p1 == *p2) { valid = TRUE; break; } p2++; }
if (!valid) { SoftPCI_Debug(SoftPciScript, L" Invalid character encounter in ParentPath!\n"); return FALSE; } p1++; valid = FALSE; }
return TRUE; }
|