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.
1555 lines
35 KiB
1555 lines
35 KiB
#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;
|
|
}
|