Leaked source code of windows server 2003
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

  1. #include <pch.h>
  2. BOOL
  3. SoftPCI_CopyLine(
  4. OUT PWCHAR Destination,
  5. IN PWCHAR CurrentLine,
  6. IN ULONG DestinationSize
  7. );
  8. BOOL
  9. SoftPCI_GetConfigValue(
  10. IN PWCHAR CurrentDataPtr,
  11. IN PULONG DataValue,
  12. IN PULONG DataSize
  13. );
  14. BOOL
  15. SoftPCI_GetDeviceInstallCount(
  16. IN PWCHAR InstallSection,
  17. OUT PULONG DeviceCount
  18. );
  19. BOOL
  20. SoftPCI_GetDeviceInstallList(
  21. IN PWCHAR InstallSection,
  22. IN OUT PWCHAR *DeviceInstallList
  23. );
  24. BOOL
  25. SoftPCI_GetNextConfigOffset(
  26. IN OUT PWCHAR *ConfigDataPtr,
  27. OUT PUCHAR ConfigOffset
  28. );
  29. PWCHAR
  30. SoftPCI_GetNextLinePtr(
  31. PWCHAR CurrentLine
  32. );
  33. PWCHAR
  34. SoftPCI_GetNextSectionPtr(
  35. IN PWCHAR CurrentLine
  36. );
  37. VOID
  38. SoftPCI_GetCurrentParameter(
  39. OUT PWCHAR Destination,
  40. IN PWCHAR CurrentLine
  41. );
  42. PWCHAR
  43. SoftPCI_GetParameterValuePtr(
  44. IN PWCHAR CurrentLine
  45. );
  46. VOID
  47. SoftPCI_InsertEntryAtTail(
  48. IN PSINGLE_LIST_ENTRY Entry
  49. );
  50. BOOL
  51. SoftPCI_LocateSoftPCISection(
  52. VOID
  53. );
  54. PWCHAR
  55. SoftPCI_LocateFullParentPath(
  56. IN PWCHAR ParentInstallSection
  57. );
  58. HANDLE
  59. SoftPCI_OpenFile(
  60. IN PWCHAR FilePath
  61. );
  62. BOOL
  63. SoftPCI_ProcessInstallSection(
  64. VOID
  65. );
  66. BOOL
  67. SoftPCI_ProcessDeviceInstallSection(
  68. IN PWCHAR DeviceInstallSection
  69. );
  70. BOOL
  71. SoftPCI_ProcessDeviceInstallParameters(
  72. IN PWCHAR DeviceInstallSection
  73. );
  74. BOOL
  75. SoftPCI_ProcessTypeParameter(
  76. IN PWCHAR ParameterPtr,
  77. IN OUT PSOFTPCI_SCRIPT_DEVICE *InstallDevice
  78. );
  79. BOOL
  80. SoftPCI_ProcessSlotParameter(
  81. IN PWCHAR ParameterPtr,
  82. IN OUT PSOFTPCI_SCRIPT_DEVICE *InstallDevice
  83. );
  84. BOOL
  85. SoftPCI_ProcessParentPathParameter(
  86. IN PWCHAR ParameterPtr,
  87. IN OUT PSOFTPCI_SCRIPT_DEVICE *InstallDevice
  88. );
  89. BOOL
  90. SoftPCI_ProcessCfgSpaceParameter(
  91. IN PWCHAR ParameterPtr,
  92. IN OUT PSOFTPCI_SCRIPT_DEVICE *InstallDevice
  93. );
  94. BOOL
  95. SoftPCI_ProcessCfgMaskParameter(
  96. IN PWCHAR ParameterPtr,
  97. IN OUT PSOFTPCI_SCRIPT_DEVICE *InstallDevice
  98. );
  99. BOOL
  100. SoftPCI_ParseConfigSpace(
  101. IN PWCHAR ParameterPtr,
  102. IN PPCI_COMMON_CONFIG CommonConfig
  103. );
  104. BOOL
  105. SoftPCI_ParseConfigData(
  106. IN UCHAR ConfigOffset,
  107. IN PUCHAR ConfigBuffer,
  108. IN PWCHAR ConfigData
  109. );
  110. BOOL
  111. SoftPCI_ReadFile(
  112. VOID
  113. );
  114. USHORT
  115. SoftPCI_StringToUSHORT(
  116. IN PWCHAR String
  117. );
  118. BOOL
  119. SoftPCI_ValidatePciPath(
  120. IN PWCHAR PciPath
  121. );
  122. //
  123. // This is the list we fill out as we parse the ini file for
  124. // new devices to be installed
  125. //
  126. SINGLE_LIST_ENTRY g_NewDeviceList;
  127. WCHAR g_ScriptError[MAX_PATH];
  128. BOOL
  129. typedef (*PSCRIPT_PARAMETER_PARSER) (
  130. IN PWCHAR ParameterPtr,
  131. IN OUT PSOFTPCI_SCRIPT_DEVICE *InstallDevice
  132. );
  133. #define INI_SOFTPCI_SECTION L"[softpci]"
  134. #define INI_INSTALL_SECTION L"[install]"
  135. //
  136. // Currently supported parameter tags
  137. //
  138. #define TYPEPARAMTER L"type"
  139. #define SLOTPARAMTER L"slot"
  140. #define PPATHPARAMETER L"parentpath"
  141. #define CFGSPACEPARAMETER L"configspace"
  142. #define CFGMASKPARAMETER L"configspacemask"
  143. //
  144. // This is the Parameter table we use to handle
  145. // parseing for each supported parameter tag
  146. //
  147. struct {
  148. PWCHAR Parameter;
  149. PSCRIPT_PARAMETER_PARSER ParameterParser;
  150. } g_ScriptParameterTable[] = {
  151. TYPEPARAMTER, SoftPCI_ProcessTypeParameter,
  152. SLOTPARAMTER, SoftPCI_ProcessSlotParameter,
  153. PPATHPARAMETER, SoftPCI_ProcessParentPathParameter,
  154. CFGSPACEPARAMETER, SoftPCI_ProcessCfgSpaceParameter,
  155. CFGMASKPARAMETER, SoftPCI_ProcessCfgMaskParameter,
  156. NULL, NULL
  157. };
  158. //
  159. // We use this table to match up which "Type" tag to the
  160. // device type we are installing
  161. //
  162. struct {
  163. PWCHAR TypeParamter;
  164. SOFTPCI_DEV_TYPE DevType;
  165. } g_ParameterTypeTable[] = {
  166. L"device", TYPE_DEVICE,
  167. L"ppbridge", TYPE_PCI_BRIDGE,
  168. L"hpbridge", TYPE_HOTPLUG_BRIDGE,
  169. L"cbdevice", TYPE_CARDBUS_DEVICE,
  170. L"cbbridge", TYPE_CARDBUS_BRIDGE,
  171. L"private", TYPE_UNKNOWN,
  172. NULL, 0
  173. };
  174. struct {
  175. HANDLE FileHandle;
  176. ULONG FileSize;
  177. PWCHAR FileBuffer;
  178. } g_ScriptFile;
  179. #define CRLF L"\r\n"
  180. #define MAX_LINE_SIZE 100
  181. #define MAX_PARAMETER_LENGTH 50
  182. #define MAX_PARAMETER_TYPE_LENGTH 25
  183. #define IGNORE_WHITESPACE_FORWARD(x) \
  184. while ((*x == ' ') || (*x == '\t')) { \
  185. x++; \
  186. }
  187. #define IGNORE_WHITESPACE_BACKWARD(x) \
  188. while ((*x == ' ') || (*x == '\t')) { \
  189. x--; \
  190. }
  191. VOID
  192. SoftPCI_InsertEntryAtTail(
  193. IN PSINGLE_LIST_ENTRY Entry
  194. )
  195. {
  196. PSINGLE_LIST_ENTRY previousEntry;
  197. //
  198. // Find the end of the list.
  199. //
  200. previousEntry = &g_NewDeviceList;
  201. while (previousEntry->Next) {
  202. previousEntry = previousEntry->Next;
  203. }
  204. //
  205. // Append the entry.
  206. //
  207. previousEntry->Next = Entry;
  208. }
  209. BOOL
  210. SoftPCI_BuildDeviceInstallList(
  211. IN PWCHAR ScriptFile
  212. )
  213. {
  214. BOOL status = FALSE;
  215. #if 0
  216. HINF hInf;
  217. UINT errorLine;
  218. INFCONTEXT infContext;
  219. errorLine = 0;
  220. hInf = SetupOpenInfFile(
  221. ScriptFile,
  222. NULL,
  223. INF_STYLE_OLDNT,
  224. &errorLine
  225. );
  226. if (hInf == INVALID_HANDLE_VALUE) {
  227. SoftPCI_Debug(SoftPciScript, L"Failed to open handle to %s\n", ScriptFile);
  228. return FALSE;
  229. }
  230. if (SetupFindFirstLine(hInf,
  231. L"softpci",
  232. NULL,
  233. &infContext
  234. )){
  235. SoftPCI_Debug(SoftPciScript, L"found our section!\n");
  236. }
  237. SoftPCI_Debug(SoftPciScript, L"Ready to party on %s\n", ScriptFile);
  238. SetupCloseInfFile(hInf);
  239. return FALSE;
  240. #endif
  241. wcscpy(g_ScriptError, L"Unknown Error");
  242. g_ScriptFile.FileHandle = SoftPCI_OpenFile(ScriptFile);
  243. if (g_ScriptFile.FileHandle != INVALID_HANDLE_VALUE) {
  244. status = SoftPCI_ReadFile();
  245. //
  246. // We no longer need the file
  247. //
  248. CloseHandle(g_ScriptFile.FileHandle);
  249. if (!status) {
  250. return status;
  251. }
  252. //
  253. // Ensure the buffer is all lower case.
  254. //
  255. _wcslwr(g_ScriptFile.FileBuffer);
  256. //
  257. // Validate install section exits
  258. //
  259. if (!SoftPCI_LocateSoftPCISection()) {
  260. status = FALSE;
  261. goto CleanUp;
  262. }
  263. if (!SoftPCI_ProcessInstallSection()) {
  264. status = FALSE;
  265. goto CleanUp;
  266. }
  267. }
  268. #if DBG
  269. else{
  270. SoftPCI_Debug(SoftPciScript, L"Failed to open handle to %s\n", ScriptFile);
  271. }
  272. #endif
  273. CleanUp:
  274. free(g_ScriptFile.FileBuffer);
  275. return status;
  276. }
  277. BOOL
  278. SoftPCI_CopyLine(
  279. OUT PWCHAR Destination,
  280. IN PWCHAR CurrentLine,
  281. IN ULONG DestinationSize
  282. )
  283. {
  284. PWCHAR lineEnd = NULL;
  285. PWCHAR copyBuffer = Destination;
  286. PWCHAR currentLine = CurrentLine;
  287. ULONG bufferSize;
  288. ULONG lineSize;
  289. lineEnd = wcsstr(CurrentLine, CRLF);
  290. if (!lineEnd) {
  291. //
  292. // We must be at the last line
  293. //
  294. wcscpy(copyBuffer, currentLine);
  295. return TRUE;
  296. }
  297. lineSize = ((ULONG)(lineEnd - CurrentLine) * sizeof(WCHAR));
  298. //
  299. // If our destination buffer size is less than the size of
  300. // the line we only copy the size of the buffer. Otherwise
  301. // we zero the input buffer and copy just the line size.
  302. //
  303. if (DestinationSize){
  304. bufferSize = (DestinationSize * sizeof(WCHAR));
  305. RtlZeroMemory(Destination, bufferSize);
  306. if (lineSize > bufferSize) {
  307. lineSize = bufferSize - sizeof(WCHAR);
  308. }
  309. }
  310. RtlCopyMemory(Destination, CurrentLine, lineSize);
  311. return TRUE;
  312. }
  313. BOOL
  314. SoftPCI_GetDeviceInstallCount(
  315. IN PWCHAR InstallSection,
  316. OUT PULONG DeviceCount
  317. )
  318. {
  319. PWCHAR installDevice;
  320. PWCHAR installDeviceSectionStart = NULL;
  321. ULONG deviceCount = 0;
  322. installDevice = SoftPCI_GetNextLinePtr(InstallSection);
  323. installDeviceSectionStart = wcsstr(installDevice, L"[");
  324. if (!installDeviceSectionStart) {
  325. wcscpy(g_ScriptError, L"Device install section missing or invalid!");
  326. return FALSE;
  327. }
  328. while (installDevice != installDeviceSectionStart) {
  329. deviceCount++;
  330. installDevice = SoftPCI_GetNextLinePtr(installDevice);
  331. if (installDevice == NULL) {
  332. //
  333. // We reached the EOF way to early!
  334. //
  335. wcscpy(g_ScriptError, L"Unexpected EOF reached!");
  336. return FALSE;
  337. }
  338. }
  339. *DeviceCount = deviceCount;
  340. return TRUE;
  341. }
  342. BOOL
  343. SoftPCI_GetDeviceInstallList(
  344. IN PWCHAR InstallSection,
  345. IN OUT PWCHAR *DeviceInstallList
  346. )
  347. {
  348. PWCHAR *deviceInstallList;
  349. PWCHAR installDevice;
  350. PWCHAR installDeviceSectionStart;
  351. deviceInstallList = DeviceInstallList;
  352. installDevice = SoftPCI_GetNextLinePtr(InstallSection);
  353. installDeviceSectionStart = wcsstr(installDevice, L"[");
  354. if (!installDeviceSectionStart) {
  355. return FALSE;
  356. }
  357. while (installDevice != installDeviceSectionStart) {
  358. IGNORE_WHITESPACE_FORWARD(installDevice);
  359. *deviceInstallList = installDevice;
  360. installDevice = SoftPCI_GetNextLinePtr(installDevice);
  361. if (installDevice == NULL) {
  362. //
  363. // We reached the EOF way to early!
  364. //
  365. wcscpy(g_ScriptError, L"Unexpected EOF reached!");
  366. return FALSE;
  367. }
  368. deviceInstallList++;
  369. }
  370. if ((*(installDevice - 1) == '\n') && (*(installDevice - 3) == '\n')) {
  371. //
  372. // Ignore the whitespace here
  373. //
  374. deviceInstallList--;
  375. *deviceInstallList = NULL;
  376. }
  377. return TRUE;
  378. }
  379. BOOL
  380. SoftPCI_GetNextConfigOffset(
  381. IN OUT PWCHAR *ConfigDataPtr,
  382. OUT PUCHAR ConfigOffset
  383. )
  384. {
  385. PWCHAR configOffsetPtr, dummy;
  386. PWCHAR nextConfigSpace;
  387. WCHAR offset[2];
  388. ULONG i;
  389. configOffsetPtr = *ConfigDataPtr;
  390. if (configOffsetPtr == NULL) {
  391. return FALSE;
  392. }
  393. //
  394. // make sure that the next offset we find is without the current
  395. // configspace we are parsing
  396. //
  397. nextConfigSpace = wcsstr(configOffsetPtr, L"config");
  398. if (nextConfigSpace == NULL) {
  399. nextConfigSpace = configOffsetPtr + wcslen(configOffsetPtr);
  400. }
  401. configOffsetPtr = wcsstr(configOffsetPtr, L":");
  402. if ((configOffsetPtr == NULL) ||
  403. (configOffsetPtr > nextConfigSpace)) {
  404. return FALSE;
  405. }
  406. IGNORE_WHITESPACE_BACKWARD(configOffsetPtr);
  407. configOffsetPtr -= 2;
  408. for (i=0; i<2; i++) {
  409. offset[i] = *configOffsetPtr;
  410. configOffsetPtr++;
  411. }
  412. IGNORE_WHITESPACE_FORWARD(configOffsetPtr);
  413. configOffsetPtr++;
  414. IGNORE_WHITESPACE_FORWARD(configOffsetPtr);
  415. *ConfigDataPtr = configOffsetPtr;
  416. *ConfigOffset = (UCHAR) wcstoul(offset, &dummy, 16);
  417. return TRUE;
  418. }
  419. PWCHAR
  420. SoftPCI_GetNextLinePtr(
  421. IN PWCHAR CurrentLine
  422. )
  423. {
  424. PWCHAR nextLine = NULL;
  425. PWCHAR currentLine = CurrentLine;
  426. BOOL lineSkipped = FALSE;
  427. if (!CurrentLine) {
  428. return NULL;
  429. }
  430. nextLine = wcsstr(CurrentLine, CRLF);
  431. if (nextLine && *(nextLine+2) == ';'){
  432. currentLine = nextLine;
  433. }
  434. while (nextLine == currentLine) {
  435. currentLine += 2;
  436. nextLine = wcsstr(currentLine, CRLF);
  437. if (!nextLine) {
  438. nextLine = currentLine;
  439. break;
  440. }
  441. if (*currentLine == ';') {
  442. currentLine = nextLine;
  443. }
  444. lineSkipped = TRUE;
  445. }
  446. if (lineSkipped) {
  447. return ((nextLine != NULL) ? currentLine: nextLine);
  448. }
  449. if (nextLine){
  450. nextLine += 2;
  451. }
  452. return nextLine;
  453. }
  454. PWCHAR
  455. SoftPCI_GetNextSectionPtr(
  456. IN PWCHAR CurrentLine
  457. )
  458. {
  459. PWCHAR nextSection;
  460. nextSection = wcsstr(CurrentLine, L"[");
  461. if (nextSection == NULL) {
  462. nextSection = CurrentLine + wcslen(CurrentLine);
  463. }
  464. return nextSection;
  465. }
  466. VOID
  467. SoftPCI_GetCurrentParameter(
  468. OUT PWCHAR Destination,
  469. IN PWCHAR CurrentLine
  470. )
  471. {
  472. PWCHAR p = Destination;
  473. PWCHAR currentLine = CurrentLine;
  474. IGNORE_WHITESPACE_FORWARD(currentLine);
  475. SoftPCI_CopyLine(Destination, currentLine, MAX_PARAMETER_LENGTH);
  476. p = wcsstr(Destination, L"=");
  477. if (p) {
  478. p--;
  479. IGNORE_WHITESPACE_BACKWARD(p);
  480. p++;
  481. *p = 0;
  482. }
  483. }
  484. BOOL
  485. SoftPCI_GetParameterValue(
  486. OUT PWCHAR Destination,
  487. IN PWCHAR CurrentLine,
  488. IN ULONG DestinationLength
  489. )
  490. {
  491. PWCHAR valuePtr = NULL;
  492. valuePtr = wcsstr(CurrentLine, L"=");
  493. if (!valuePtr) {
  494. return FALSE;
  495. }
  496. valuePtr++;
  497. IGNORE_WHITESPACE_FORWARD(valuePtr);
  498. SoftPCI_CopyLine(Destination, valuePtr, DestinationLength);
  499. return TRUE;
  500. }
  501. PWCHAR
  502. SoftPCI_GetParameterValuePtr(
  503. IN PWCHAR CurrentLine
  504. )
  505. {
  506. PWCHAR valuePtr;
  507. PWCHAR nextSectionPtr;
  508. valuePtr = wcsstr(CurrentLine, L"=");
  509. if (!valuePtr) {
  510. return NULL;
  511. }
  512. nextSectionPtr = SoftPCI_GetNextSectionPtr(CurrentLine);
  513. if (valuePtr > nextSectionPtr) {
  514. return NULL;
  515. }
  516. valuePtr++;
  517. IGNORE_WHITESPACE_FORWARD(valuePtr);
  518. return valuePtr;
  519. }
  520. BOOL
  521. SoftPCI_LocateSoftPCISection(
  522. VOID
  523. )
  524. {
  525. PWCHAR p = NULL;
  526. p = wcsstr(g_ScriptFile.FileBuffer, INI_SOFTPCI_SECTION);
  527. return (p != NULL);
  528. }
  529. PWCHAR
  530. SoftPCI_LocateFullParentPath(
  531. IN PWCHAR ParentInstallSection
  532. )
  533. {
  534. WCHAR parentSection[MAX_PATH];
  535. PWCHAR deviceSectionPtr;
  536. PWCHAR parentPathPtr;
  537. wsprintf(parentSection, L"[%s]", ParentInstallSection);
  538. SoftPCI_Debug(SoftPciScript, L" - - Searching for %s section...\n", parentSection);
  539. deviceSectionPtr = wcsstr(g_ScriptFile.FileBuffer, parentSection);
  540. if (!deviceSectionPtr) {
  541. return NULL;
  542. }
  543. //
  544. // Now jump to the parentpath section.
  545. //
  546. parentPathPtr = wcsstr(deviceSectionPtr, PPATHPARAMETER);
  547. if (!parentPathPtr) {
  548. return NULL;
  549. }
  550. return NULL;
  551. }
  552. BOOL
  553. SoftPCI_ProcessInstallSection(
  554. VOID
  555. )
  556. {
  557. PWCHAR installSection;
  558. PWCHAR *installDeviceList;
  559. PWCHAR *installDeviceCurrent;
  560. ULONG installDeviceCount;
  561. BOOL result = TRUE;
  562. installSection = wcsstr(g_ScriptFile.FileBuffer, INI_INSTALL_SECTION);
  563. if (installSection) {
  564. //
  565. // We have our install section. Build our install list
  566. //
  567. installDeviceCount = 0;
  568. if (!SoftPCI_GetDeviceInstallCount(installSection, &installDeviceCount)){
  569. return FALSE;
  570. }
  571. //
  572. // Allocate an array of PWCHAR plus an extra NULL
  573. //
  574. installDeviceList = calloc(installDeviceCount + 1, sizeof(PWCHAR));
  575. if (!SoftPCI_GetDeviceInstallList(installSection, installDeviceList)) {
  576. free(installDeviceList);
  577. return FALSE;
  578. }
  579. //
  580. // Now we have our list. Install each device
  581. //
  582. installDeviceCurrent = installDeviceList;
  583. while(*installDeviceCurrent){
  584. //
  585. // Loop through each device to install and parse
  586. // it's InstallParamters
  587. //
  588. result = SoftPCI_ProcessDeviceInstallSection(*installDeviceCurrent);
  589. #if 0
  590. {
  591. WCHAR failedSection[MAX_PATH];
  592. SoftPCI_CopyLine(failedSection, *installDeviceCurrent, MAX_PATH);
  593. if (!result) {
  594. SoftPCI_Debug(SoftPciScript, L"Error parsing [%s] section!\n", failedSection);
  595. }else{
  596. SoftPCI_Debug(SoftPciScript, L" -- successfully parsed %s section!\n", failedSection);
  597. }
  598. }
  599. #endif
  600. installDeviceCurrent++;
  601. }
  602. }
  603. free(installDeviceList);
  604. return TRUE;
  605. }
  606. BOOL
  607. SoftPCI_ProcessDeviceInstallSection(
  608. IN PWCHAR DeviceInstallSection
  609. )
  610. {
  611. WCHAR deviceSectionString[MAX_PATH];
  612. WCHAR deviceSection[MAX_PATH];
  613. PWCHAR deviceSectionPtr;
  614. SoftPCI_CopyLine(deviceSection, DeviceInstallSection, MAX_PATH);
  615. wsprintf(deviceSectionString, L"[%s]", deviceSection);
  616. SoftPCI_Debug(SoftPciScript, L"Searching for %s section...\n", deviceSectionString);
  617. deviceSectionPtr = wcsstr(DeviceInstallSection, deviceSectionString);
  618. if (!deviceSectionPtr) {
  619. return FALSE;
  620. }
  621. SoftPCI_Debug(SoftPciScript, L" - found %s section!\n", deviceSectionString);
  622. //
  623. // We have an install section. Process InstallParamters
  624. //
  625. return SoftPCI_ProcessDeviceInstallParameters(deviceSectionPtr);
  626. }
  627. BOOL
  628. SoftPCI_ProcessDeviceInstallParameters(
  629. IN PWCHAR DeviceInstallSection
  630. )
  631. {
  632. ULONG i;
  633. BOOL result;
  634. WCHAR currentParameter[MAX_PARAMETER_LENGTH];
  635. PWCHAR currentParameterPtr;
  636. PWCHAR nextSectionPtr;
  637. PSOFTPCI_SCRIPT_DEVICE currentDevice;
  638. PSOFTPCI_SCRIPT_DEVICE installDevice;
  639. nextSectionPtr = SoftPCI_GetNextSectionPtr(DeviceInstallSection+1);
  640. if (SoftPCI_GetNextLinePtr(DeviceInstallSection) == NULL) {
  641. return FALSE;
  642. }
  643. currentParameterPtr = SoftPCI_GetNextLinePtr(DeviceInstallSection);
  644. SoftPCI_Debug(SoftPciScript, L"nextSectionPtr = %p\n", nextSectionPtr);
  645. SoftPCI_Debug(SoftPciScript, L"currentParameterPtr = %p\n", currentParameterPtr);
  646. if (!currentParameterPtr) {
  647. //
  648. // We dont have a Parameter to process
  649. //
  650. SoftPCI_Debug(SoftPciScript, L"EOF reached before parameters processed!\n");
  651. return FALSE;
  652. }
  653. result = FALSE;
  654. while (currentParameterPtr < nextSectionPtr) {
  655. //
  656. // Grab our parameters and run the respective parser
  657. //
  658. SoftPCI_GetCurrentParameter(currentParameter, currentParameterPtr);
  659. SoftPCI_Debug(SoftPciScript, L"currentParameter = %s\n", currentParameter);
  660. i = 0;
  661. while (g_ScriptParameterTable[i].Parameter) {
  662. if ((wcscmp(currentParameter, g_ScriptParameterTable[i].Parameter) == 0)) {
  663. result = g_ScriptParameterTable[i].ParameterParser(currentParameterPtr, &currentDevice);
  664. }
  665. i++;
  666. }
  667. currentParameterPtr = SoftPCI_GetNextLinePtr(currentParameterPtr);
  668. if (currentParameterPtr == NULL) {
  669. //
  670. // EOF
  671. //
  672. break;
  673. }
  674. }
  675. SoftPCI_Debug(SoftPciScript, L"currentParameterPtr = %p\n", currentParameterPtr);
  676. if (currentDevice &&
  677. currentDevice->SoftPciDevice.Config.Current.VendorID) {
  678. //
  679. // We have something so assume all is well
  680. //
  681. SoftPCI_Debug(SoftPciScript,
  682. L"New device ready to install! Ven %04x Dev %04x\n",
  683. currentDevice->SoftPciDevice.Config.Current.VendorID,
  684. currentDevice->SoftPciDevice.Config.Current.DeviceID
  685. );
  686. SoftPCI_InsertEntryAtTail(&currentDevice->ListEntry);
  687. //free(currentDevice->ParentPath);
  688. //free(currentDevice);
  689. return TRUE;
  690. }
  691. return FALSE;
  692. }
  693. BOOL
  694. SoftPCI_ProcessTypeParameter(
  695. IN PWCHAR ParameterPtr,
  696. IN OUT PSOFTPCI_SCRIPT_DEVICE *InstallDevice
  697. )
  698. {
  699. WCHAR parameterType[MAX_PARAMETER_TYPE_LENGTH];
  700. PSOFTPCI_SCRIPT_DEVICE installDevice;
  701. ULONG i;
  702. SoftPCI_Debug(SoftPciScript, L"ProcessTypeParameter called\n");
  703. if (!SoftPCI_GetParameterValue(parameterType, ParameterPtr, MAX_PARAMETER_TYPE_LENGTH)){
  704. return FALSE;
  705. }
  706. SoftPCI_Debug(SoftPciScript, L" parameterType = %s\n", parameterType);
  707. installDevice = (PSOFTPCI_SCRIPT_DEVICE) calloc(1, FIELD_OFFSET(SOFTPCI_SCRIPT_DEVICE, ParentPath));
  708. if (installDevice == NULL) {
  709. SoftPCI_Debug(SoftPciScript, L"failed to alloate memory for device!\n");
  710. return FALSE;
  711. }
  712. i = 0;
  713. while (g_ParameterTypeTable[i].TypeParamter) {
  714. if ((wcscmp(parameterType, g_ParameterTypeTable[i].TypeParamter) == 0)) {
  715. SoftPCI_InitializeDevice(&installDevice->SoftPciDevice,
  716. g_ParameterTypeTable[i].DevType);
  717. }
  718. i++;
  719. }
  720. *InstallDevice = installDevice;
  721. return TRUE;
  722. }
  723. BOOL
  724. SoftPCI_ProcessSlotParameter(
  725. IN PWCHAR ParameterPtr,
  726. IN OUT PSOFTPCI_SCRIPT_DEVICE *InstallDevice
  727. )
  728. {
  729. WCHAR slotParameter[MAX_PARAMETER_TYPE_LENGTH];
  730. SOFTPCI_SLOT deviceSlot;
  731. PSOFTPCI_SCRIPT_DEVICE installDevice;
  732. SoftPCI_Debug(SoftPciScript, L"ProcessSlotParameter called\n");
  733. installDevice = *InstallDevice;
  734. if (installDevice == NULL) {
  735. return FALSE;
  736. }
  737. if (!SoftPCI_GetParameterValue(slotParameter, ParameterPtr, MAX_PARAMETER_TYPE_LENGTH)){
  738. return FALSE;
  739. }
  740. SoftPCI_Debug(SoftPciScript, L" slotParameter = %s\n", slotParameter);
  741. deviceSlot.AsUSHORT = SoftPCI_StringToUSHORT(slotParameter);
  742. SoftPCI_Debug(SoftPciScript, L" deviceSlot = %04x\n", deviceSlot.AsUSHORT);
  743. installDevice->SoftPciDevice.Slot.AsUSHORT = deviceSlot.AsUSHORT;
  744. installDevice->SlotSpecified = TRUE;
  745. return TRUE;
  746. }
  747. BOOL
  748. SoftPCI_ProcessParentPathParameter(
  749. IN PWCHAR ParameterPtr,
  750. IN OUT PSOFTPCI_SCRIPT_DEVICE *InstallDevice
  751. )
  752. {
  753. PWCHAR parentPathPtr;
  754. PWCHAR parentPath;
  755. PWCHAR endPath;
  756. PWCHAR nextSectionPtr;
  757. ULONG parentPathLength;
  758. PSOFTPCI_SCRIPT_DEVICE installDevice;
  759. SoftPCI_Debug(SoftPciScript, L"ProcessParentPathParameter called\n");
  760. //
  761. // ParentPath could in theory be as long as (256 buses * sizeof Slot * sizeof(WCHAR))
  762. // which is 2k. Let's dynamically allocate storage needed.
  763. //
  764. installDevice = *InstallDevice;
  765. if (installDevice == NULL) {
  766. return FALSE;
  767. }
  768. parentPathPtr = SoftPCI_GetParameterValuePtr(ParameterPtr);
  769. if (!parentPathPtr) {
  770. return FALSE;
  771. }
  772. endPath = wcsstr(parentPathPtr, CRLF);
  773. parentPathLength = 0;
  774. if (endPath) {
  775. parentPathLength = (ULONG)((endPath - parentPathPtr) + 1);
  776. }else{
  777. parentPathLength = wcslen(parentPathPtr) + 1;
  778. }
  779. parentPath = (PWCHAR) calloc(sizeof(WCHAR), parentPathLength + 1);
  780. if (!parentPath) {
  781. return FALSE;
  782. }
  783. SoftPCI_CopyLine(parentPath, parentPathPtr, 0);
  784. SoftPCI_Debug(SoftPciScript, L" ParentPath - %s\n", parentPath);
  785. //
  786. // Now things get interesting. We need to parse out our parent paths
  787. // if the parent path specified here is a pointer to a previous device
  788. // instead of a actual parent path.
  789. //
  790. //
  791. // ISSUE: BrandonA - Implement this later!!!
  792. //
  793. //InstallDevice->ParentPath = SoftPCI_LocateFullParentPath(parentPath);
  794. parentPathLength *= sizeof(WCHAR);
  795. //
  796. // Now re-allocate the memory used for the installDevice with additional space for the
  797. // parentPathLength
  798. //
  799. installDevice = realloc(installDevice, sizeof(SOFTPCI_SCRIPT_DEVICE) + parentPathLength);
  800. if (installDevice) {
  801. wcscpy(installDevice->ParentPath, parentPath);
  802. installDevice->ParentPathLength = parentPathLength;
  803. *InstallDevice = installDevice;
  804. }else{
  805. *InstallDevice = NULL;
  806. return FALSE;
  807. }
  808. if (SoftPCI_ValidatePciPath(installDevice->ParentPath)){
  809. return TRUE;
  810. }
  811. free(installDevice);
  812. *InstallDevice = NULL;
  813. return FALSE;
  814. }
  815. BOOL
  816. SoftPCI_ProcessCfgSpaceParameter(
  817. IN PWCHAR ParameterPtr,
  818. IN OUT PSOFTPCI_SCRIPT_DEVICE *InstallDevice
  819. )
  820. {
  821. PSOFTPCI_SCRIPT_DEVICE installDevice;
  822. SoftPCI_Debug(SoftPciScript, L"ProcessCfgSpaceParameter called\n");
  823. installDevice = *InstallDevice;
  824. if (installDevice == NULL) {
  825. return FALSE;
  826. }
  827. return SoftPCI_ParseConfigSpace(
  828. ParameterPtr,
  829. &installDevice->SoftPciDevice.Config.Current
  830. );
  831. }
  832. BOOL
  833. SoftPCI_ProcessCfgMaskParameter(
  834. IN PWCHAR ParameterPtr,
  835. IN OUT PSOFTPCI_SCRIPT_DEVICE *InstallDevice
  836. )
  837. {
  838. PSOFTPCI_SCRIPT_DEVICE installDevice;
  839. SoftPCI_Debug(SoftPciScript, L"ProcessCfgMaskParameter called\n");
  840. installDevice = *InstallDevice;
  841. if (installDevice == NULL) {
  842. return FALSE;
  843. }
  844. return SoftPCI_ParseConfigSpace(
  845. ParameterPtr,
  846. &installDevice->SoftPciDevice.Config.Mask
  847. );
  848. }
  849. BOOL
  850. SoftPCI_ParseConfigSpace(
  851. IN PWCHAR ParameterPtr,
  852. IN PPCI_COMMON_CONFIG CommonConfig
  853. )
  854. {
  855. PWCHAR cfgSpacePtr;
  856. PWCHAR endLine, nextSection;
  857. PUCHAR configPtr;
  858. UCHAR configOffset;
  859. WCHAR lineBuffer[MAX_LINE_SIZE];
  860. cfgSpacePtr = SoftPCI_GetParameterValuePtr(ParameterPtr);
  861. if (cfgSpacePtr == NULL) {
  862. return FALSE;
  863. }
  864. if (*cfgSpacePtr == '\r') {
  865. //
  866. // Our first offset must start at the next line
  867. //
  868. cfgSpacePtr = SoftPCI_GetNextLinePtr(cfgSpacePtr);
  869. }
  870. nextSection = SoftPCI_GetNextSectionPtr(cfgSpacePtr);
  871. configPtr = (PUCHAR) CommonConfig;
  872. configOffset = 0;
  873. while (cfgSpacePtr && (cfgSpacePtr < nextSection)) {
  874. IGNORE_WHITESPACE_FORWARD(cfgSpacePtr)
  875. //
  876. // We should now be pointing to a configspace offset that we need
  877. // to parse. Validate that the line is less than our stack buffer size.
  878. //
  879. endLine = wcsstr(cfgSpacePtr, CRLF);
  880. if (endLine == NULL) {
  881. endLine = cfgSpacePtr + wcslen(cfgSpacePtr);
  882. }
  883. if ((endLine - cfgSpacePtr) > MAX_PATH) {
  884. //
  885. // Too much to parse on one line, Error out.
  886. //
  887. SoftPCI_Debug(SoftPciScript, L"ParseConfigSpace - cannot parse configspace offset!\n");
  888. return FALSE;
  889. }
  890. //
  891. // Now grab our next offset
  892. //
  893. if (!SoftPCI_GetNextConfigOffset(&cfgSpacePtr, &configOffset)) {
  894. //
  895. // We didnt find and offset, fail
  896. //
  897. return FALSE;
  898. }
  899. SoftPCI_Debug(SoftPciScript, L"ParseConfigSpace - first offset - %02x\n", configOffset);
  900. SoftPCI_CopyLine(lineBuffer, cfgSpacePtr, MAX_LINE_SIZE);
  901. SoftPCI_Debug(SoftPciScript, L"ParseConfigSpace - lineBuffer - %s\n", lineBuffer);
  902. //
  903. // Parse the specified data
  904. //
  905. SoftPCI_ParseConfigData(
  906. configOffset,
  907. configPtr + configOffset,
  908. lineBuffer
  909. );
  910. cfgSpacePtr = SoftPCI_GetNextLinePtr(cfgSpacePtr);
  911. }
  912. return TRUE;
  913. }
  914. BOOL
  915. SoftPCI_ParseConfigData(
  916. IN UCHAR ConfigOffset,
  917. IN PUCHAR ConfigBuffer,
  918. IN PWCHAR ConfigData
  919. )
  920. {
  921. USHORT configOffset;
  922. PUCHAR configBuffer;
  923. PWCHAR currentDataPtr, endLine;
  924. ULONG dataSize;
  925. ULONG dataValue;
  926. configOffset = (USHORT)ConfigOffset;
  927. currentDataPtr = ConfigData;
  928. configBuffer = ConfigBuffer;
  929. while (currentDataPtr) {
  930. SoftPCI_Debug(SoftPciScript, L"ParseConfigData - next offset - %04x\n", configOffset);
  931. if (!SoftPCI_GetConfigValue(currentDataPtr, &dataValue, &dataSize)){
  932. return FALSE;
  933. }
  934. SoftPCI_Debug(
  935. SoftPciScript,
  936. L"ParseConfigData - dataValue - %x dataSize - %x\n",
  937. dataValue,
  938. dataSize
  939. );
  940. if ((configOffset + dataSize) > sizeof(PCI_COMMON_CONFIG)){
  941. //
  942. // We cannot write more than the common config
  943. //
  944. return FALSE;
  945. }
  946. RtlCopyMemory(configBuffer, &dataValue, dataSize);
  947. currentDataPtr = wcsstr(currentDataPtr, L",");
  948. while (currentDataPtr && (*currentDataPtr == ',')) {
  949. //
  950. // For each comma encountered we increment to the next DWORD
  951. //
  952. if ((configOffset & 0x3) == 0){
  953. configOffset += sizeof(ULONG);
  954. configBuffer += sizeof(ULONG);
  955. }else{
  956. while ((configOffset & 0x3) != 0) {
  957. configOffset++;
  958. configBuffer++;
  959. }
  960. }
  961. currentDataPtr++;
  962. if (*currentDataPtr == 0) {
  963. currentDataPtr = NULL;
  964. break;
  965. }
  966. IGNORE_WHITESPACE_FORWARD(currentDataPtr)
  967. }
  968. }
  969. return TRUE;
  970. }
  971. BOOL
  972. SoftPCI_GetConfigValue(
  973. IN PWCHAR CurrentDataPtr,
  974. IN PULONG DataValue,
  975. IN PULONG DataSize
  976. )
  977. {
  978. ULONG value, size;
  979. PWCHAR endScan;
  980. *DataValue = 0;
  981. *DataSize = 0;
  982. value = 0;
  983. endScan = NULL;
  984. value = wcstoul(CurrentDataPtr, &endScan, 16);
  985. if (endScan == CurrentDataPtr) {
  986. //
  987. // no valid number was found
  988. //
  989. return FALSE;
  990. }
  991. size = (ULONG)(endScan - CurrentDataPtr);
  992. if (size % 2) {
  993. size++;
  994. }
  995. //
  996. // If we have more than 8 characters then max our size out at 8
  997. //
  998. if (size > 8) {
  999. size = 8;
  1000. }
  1001. SoftPCI_Debug(SoftPciScript, L"GetConfigValue - dataSize - %x\n", size);
  1002. //
  1003. // Now return our values. Note that size needs to be converted to bytes.
  1004. //
  1005. *DataSize = (size / 2);
  1006. *DataValue = value;
  1007. return TRUE;
  1008. }
  1009. HANDLE
  1010. SoftPCI_OpenFile(
  1011. IN PWCHAR FilePath
  1012. )
  1013. {
  1014. return CreateFile(FilePath,
  1015. GENERIC_READ,
  1016. 0,
  1017. NULL,
  1018. OPEN_EXISTING,
  1019. FILE_ATTRIBUTE_ARCHIVE,
  1020. NULL
  1021. );
  1022. }
  1023. BOOL
  1024. SoftPCI_ReadFile(
  1025. VOID
  1026. )
  1027. /*--
  1028. Routine Description:
  1029. Reads the file specified by FileHandle into a buffer and returns a pointer
  1030. to the buffer
  1031. Arguments:
  1032. none
  1033. Return Value:
  1034. TRUE on success, FALSE otherwise
  1035. --*/
  1036. {
  1037. INT sizeWritten = 0;
  1038. ULONG fileSize = 0, readSize = 0;
  1039. PUCHAR ansiFile = NULL;
  1040. //
  1041. // Obtain the File Size
  1042. //
  1043. fileSize = GetFileSize(g_ScriptFile.FileHandle, NULL);
  1044. if (fileSize == 0xFFFFFFFF) {
  1045. SoftPCI_Debug(SoftPciScript,
  1046. L"Failed to determine size of script file! Error - \"%s\"\n",
  1047. SoftPCI_GetLastError());
  1048. return FALSE;
  1049. }
  1050. //
  1051. // Allocate our buffer (with a little padding). It will be zeroed by default
  1052. //
  1053. ansiFile = (PUCHAR) calloc(1, fileSize + sizeof(ULONG));
  1054. g_ScriptFile.FileBuffer = (PWCHAR) calloc(sizeof(WCHAR), fileSize + sizeof(ULONG));
  1055. if ((g_ScriptFile.FileBuffer) && ansiFile) {
  1056. //
  1057. // Read the file
  1058. //
  1059. if (!ReadFile(g_ScriptFile.FileHandle,
  1060. ansiFile,
  1061. fileSize,
  1062. &readSize,
  1063. NULL
  1064. )){
  1065. SoftPCI_Debug(SoftPciScript,
  1066. L"Failed to read file! Error - \"%s\"\n",
  1067. SoftPCI_GetLastError());
  1068. goto CleanUp;
  1069. }
  1070. if (readSize != fileSize) {
  1071. SoftPCI_Debug(SoftPciScript,
  1072. L"Failed to read entire file! Error - \"%s\"\n",
  1073. SoftPCI_GetLastError());
  1074. goto CleanUp;
  1075. }
  1076. //
  1077. // Now convert the file to Unicode.
  1078. //
  1079. sizeWritten = MultiByteToWideChar(CP_THREAD_ACP,
  1080. MB_PRECOMPOSED,
  1081. ansiFile,
  1082. -1,
  1083. g_ScriptFile.FileBuffer,
  1084. ((fileSize * sizeof(WCHAR)) + sizeof(ULONG))
  1085. );
  1086. if (sizeWritten != (strlen(ansiFile) + 1)) {
  1087. SoftPCI_Debug(SoftPciScript,
  1088. L"Failed to convert file to unicode!\n");
  1089. goto CleanUp;
  1090. }
  1091. g_ScriptFile.FileSize = sizeWritten;
  1092. free(ansiFile);
  1093. return TRUE;
  1094. }
  1095. SoftPCI_Debug(SoftPciScript,
  1096. L"Failed to allocate required memory!");
  1097. CleanUp:
  1098. if (g_ScriptFile.FileBuffer) {
  1099. free(g_ScriptFile.FileBuffer);
  1100. }
  1101. if (ansiFile) {
  1102. free(ansiFile);
  1103. }
  1104. return FALSE;
  1105. }
  1106. USHORT
  1107. SoftPCI_StringToUSHORT(
  1108. IN PWCHAR String
  1109. )
  1110. {
  1111. WCHAR numbers[] = L"0123456789abcdef";
  1112. PWCHAR p1, p2;
  1113. USHORT convertedValue = 0;
  1114. BOOLEAN converted = FALSE;
  1115. p1 = numbers;
  1116. p2 = String;
  1117. while (*p2) {
  1118. while (*p1 && (converted == FALSE)) {
  1119. if (*p1 == *p2) {
  1120. //
  1121. // Reset our pointer
  1122. //
  1123. convertedValue <<= 4;
  1124. convertedValue |= (((UCHAR)(p1 - numbers)) & 0x0f);
  1125. converted = TRUE;
  1126. }
  1127. p1++;
  1128. }
  1129. if (converted == FALSE) {
  1130. //
  1131. // Encountered something we couldnt convert. Return what we have
  1132. //
  1133. return convertedValue;
  1134. }
  1135. p2++;
  1136. p1 = numbers;
  1137. converted = FALSE;
  1138. }
  1139. return convertedValue;
  1140. }
  1141. BOOL
  1142. SoftPCI_ValidatePciPath(
  1143. IN PWCHAR PciPath
  1144. )
  1145. {
  1146. ULONG pathLength = wcslen(PciPath);
  1147. ULONG validSize = pathLength;
  1148. PWCHAR pciPath = PciPath;
  1149. PWCHAR p1, p2;
  1150. WCHAR validChars[] = L"0123456989abcdef\\";
  1151. BOOLEAN valid = FALSE;
  1152. //
  1153. // First ignore any pre and ending "\"
  1154. //
  1155. //if (*pciPath == '\\'){
  1156. // validSize -= 1;
  1157. //}
  1158. //if (*(pciPath+pathLength) == '\\'){
  1159. // validSize -= 1;
  1160. //}
  1161. //
  1162. // Now see if everything looks good size wise.
  1163. //
  1164. if (((validSize - 4) % 5) != 0) {
  1165. SoftPCI_Debug(SoftPciScript, L" Path size invalid!\n");
  1166. return FALSE;
  1167. }
  1168. //
  1169. // Make sure all characters are legal.
  1170. //
  1171. p1 = PciPath;
  1172. while (*p1) {
  1173. p2 = validChars;
  1174. while (*p2) {
  1175. if (*p1 == *p2) {
  1176. valid = TRUE;
  1177. break;
  1178. }
  1179. p2++;
  1180. }
  1181. if (!valid) {
  1182. SoftPCI_Debug(SoftPciScript, L" Invalid character encounter in ParentPath!\n");
  1183. return FALSE;
  1184. }
  1185. p1++;
  1186. valid = FALSE;
  1187. }
  1188. return TRUE;
  1189. }