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.

790 lines
23 KiB

  1. #include "pch.h"
  2. #define SOFTPCI_FILTER_SECTION L"SOFTPCI_DRV.Services"
  3. #define SOFTPCI_FILTER_SERVICE_NAME L"SoftPCI"
  4. //#define SOFTPCIDRV L"softpci"
  5. typedef enum{
  6. DriverInf = 0,
  7. DriverCat,
  8. DriverSoftPci,
  9. DriverHpSim,
  10. DriverShpc,
  11. DriverUnknown
  12. } IMAGE_TYPE;
  13. BOOL
  14. _lwritef(
  15. IN HANDLE hFile,
  16. IN PTSTR Format,
  17. ...);
  18. BOOL
  19. SoftPCI_ExpandResourceFile(
  20. IN LPTSTR DriverPath,
  21. IN LPTSTR ResName
  22. );
  23. BOOL
  24. SoftPCI_ExtractImageToDrive(
  25. IN IMAGE_TYPE ImageType
  26. );
  27. BOOL
  28. SoftPCI_InstallFilterKey(
  29. IN DEVNODE RootBus
  30. );
  31. BOOL
  32. SoftPCI_InstallDriverInf(
  33. VOID
  34. );
  35. VOID
  36. SoftPCI_LocateRootPciBusesForInstall(
  37. IN PPCI_DN Pdn,
  38. OUT PBOOL Success
  39. );
  40. BOOL
  41. SoftPCI_RebootSystem(
  42. VOID
  43. );
  44. BOOL
  45. SoftPCI_InstallDriver(VOID){
  46. BOOL success = TRUE;
  47. INT infLen = 0, reboot = IDNO;
  48. IMAGE_TYPE imageType;
  49. WCHAR winDir[MAX_PATH];
  50. WCHAR infPath[MAX_PATH];
  51. //
  52. // Spit out our images....
  53. //
  54. for (imageType = DriverInf; imageType < DriverUnknown; imageType++ ) {
  55. if (!SoftPCI_ExtractImageToDrive(imageType)){
  56. return FALSE;
  57. }
  58. }
  59. //
  60. // We need a service key
  61. //
  62. if (!SoftPCI_InstallDriverInf()) {
  63. //
  64. // Failed to install our service key
  65. //
  66. return FALSE;
  67. }
  68. //
  69. // Now we need to update each root buses reg data
  70. //
  71. SoftPCI_LocateRootPciBusesForInstall(g_PciTree->RootDevNode, &success);
  72. SoftPCI_InitializeRegistry();
  73. if (success) {
  74. reboot = MessageBox(g_SoftPCIMainWnd,
  75. L"SoftPCI Support is now installed and your system must be rebooted. OK to reboot?",
  76. L"Install Complete",
  77. MB_YESNO
  78. );
  79. if (reboot == IDYES) {
  80. return SoftPCI_RebootSystem();
  81. }
  82. }
  83. return success;
  84. }
  85. BOOL
  86. SoftPCI_ExpandResourceFile(
  87. IN LPTSTR DriverPath,
  88. IN LPTSTR ResName
  89. )
  90. /*++
  91. Routine Description:
  92. This routine was stolen from DVNT to expand our driver out of our *.exe so it can be installed.
  93. Arguments:
  94. DriverPath - count of arguments
  95. ResName - arguments from the command line
  96. Return Value:
  97. none
  98. --*/
  99. {
  100. HGLOBAL obj;
  101. HRSRC resource;
  102. LPTSTR lpStr;
  103. INT size;
  104. BOOL success = FALSE;
  105. if ((resource = FindResource(NULL, ResName, RT_RCDATA))) {
  106. if ((obj = LoadResource(NULL,resource))) {
  107. if ((lpStr = (LPTSTR)LockResource(obj)) ) {
  108. HANDLE file;
  109. DWORD written;
  110. size = SizeofResource(NULL, resource);
  111. if ((file = CreateFile(DriverPath,
  112. GENERIC_WRITE,
  113. 0,
  114. NULL,
  115. CREATE_ALWAYS,
  116. FILE_ATTRIBUTE_NORMAL,
  117. NULL
  118. )) != INVALID_HANDLE_VALUE) {
  119. if (WriteFile(file,
  120. lpStr,
  121. size,
  122. &written,
  123. NULL
  124. )) {
  125. success = TRUE ;
  126. }
  127. CloseHandle(file);
  128. }
  129. UnlockResource(obj);
  130. }
  131. }
  132. }
  133. return success;
  134. }
  135. BOOL
  136. SoftPCI_ExtractImageToDrive(
  137. IN IMAGE_TYPE ImageType
  138. )
  139. {
  140. WCHAR imagePath[MAX_PATH];
  141. WCHAR winDir[MAX_PATH];
  142. if (GetWindowsDirectory(winDir, MAX_PATH)==0) return FALSE ;
  143. wcscat(winDir, L"\\pcisim");
  144. CreateDirectory(winDir, NULL);
  145. switch (ImageType) {
  146. case DriverInf:
  147. wsprintf(imagePath, L"%s\\softpci.inf", winDir);
  148. return SoftPCI_ExpandResourceFile(imagePath, L"InfDriverResource");
  149. break;
  150. case DriverCat:
  151. wsprintf(imagePath, L"%s\\delta.cat", winDir);
  152. return SoftPCI_ExpandResourceFile(imagePath, L"CatalogDriverResource");
  153. break;
  154. case DriverSoftPci:
  155. //
  156. //
  157. // OK softpci.sys needs to be treated special as it is
  158. // not installed by normal means (as a filter). Therefore, we need
  159. // to make sure it exists in both our media source location as well
  160. // as the \system32\drivers directory.
  161. //
  162. //
  163. wsprintf(imagePath, L"%s\\softpci.sys", winDir);
  164. if (SoftPCI_ExpandResourceFile(imagePath, L"SoftPciDriverResource")) {
  165. WCHAR driverDir[MAX_PATH];
  166. ULONG i;
  167. //
  168. // Save our current media source image path
  169. //
  170. wcscpy(driverDir, imagePath);
  171. //
  172. // now remove the \\pcisim
  173. //
  174. for (i = wcslen(winDir); i > 0 && winDir[i] != '\\'; i--);
  175. winDir[i] = 0;
  176. //
  177. // Build our new image path
  178. //
  179. wsprintf(imagePath, L"%s\\system32\\drivers\\softpci.sys", winDir);
  180. return CopyFile(driverDir, imagePath, FALSE);
  181. }
  182. return FALSE;
  183. break;
  184. case DriverHpSim:
  185. wsprintf(imagePath, L"%s\\hpsim.sys", winDir);
  186. return SoftPCI_ExpandResourceFile(imagePath, L"HpSimDriverResource");
  187. break;
  188. case DriverShpc:
  189. wsprintf(imagePath, L"%s\\shpc.sys", winDir);
  190. return SoftPCI_ExpandResourceFile(imagePath, L"ShpcDriverResource");
  191. break;
  192. default:
  193. return FALSE;
  194. }
  195. }
  196. BOOL
  197. SoftPCI_InstallDriverInf(
  198. VOID
  199. )
  200. /*++
  201. Routine Description:
  202. This routine takes the INF we created and installs the Services section
  203. Arguments:
  204. InfPath - Path to the INF we created
  205. Return Value:
  206. TRUE if success
  207. --*/
  208. {
  209. HINF infHandle;
  210. UINT errorLine, i;
  211. WCHAR infPath[MAX_PATH];
  212. WCHAR winDir[MAX_PATH];
  213. if (GetWindowsDirectory(winDir, MAX_PATH)==0) return FALSE ;
  214. wcscat(winDir, L"\\pcisim");
  215. wsprintf(infPath, L"%s\\softpci.inf", winDir);
  216. infHandle = SetupOpenInfFile(infPath, NULL, INF_STYLE_WIN4, &errorLine);
  217. if (infHandle == INVALID_HANDLE_VALUE) {
  218. SoftPCI_Debug(SoftPciInstall, L"InstallDriverInf - failed open inf. Error = \"%s\"\n", SoftPCI_GetLastError());
  219. return FALSE;
  220. }
  221. if (!SetupInstallServicesFromInfSection(infHandle, SOFTPCI_FILTER_SECTION, 0)){
  222. SoftPCI_Debug(SoftPciInstall, L"InstallDriverInf - failed to install service key. Error = \"%s\"\n", SoftPCI_GetLastError());
  223. return FALSE;
  224. }
  225. SetupCloseInfFile(infHandle);
  226. return SetupCopyOEMInf(infPath,
  227. winDir,
  228. SPOST_PATH,
  229. SP_COPY_DELETESOURCE,
  230. NULL,
  231. 0,
  232. NULL,
  233. NULL
  234. );
  235. }
  236. BOOL
  237. SoftPCI_InstallFilterKey(
  238. IN DEVNODE RootBus
  239. )
  240. /*++
  241. Routine Description:
  242. This routine takes updates or adds the LowerFilters Key to the registry
  243. so that our driver is loaded each boot
  244. Arguments:
  245. RootBus - the devnode for the root bus we want to filter
  246. Return Value:
  247. TRUE if success
  248. --*/
  249. {
  250. BOOL status = FALSE;
  251. PWCHAR buffer = NULL, newBuffer, entry = NULL, entry2 = NULL;
  252. DWORD requiredSize = 0, size = ((wcslen(SOFTPCI_FILTER_SERVICE_NAME)+1) * sizeof(WCHAR));
  253. CONFIGRET cr = CR_SUCCESS;
  254. //
  255. // First call is to get required buffer size
  256. //
  257. if ((cr = CM_Get_DevNode_Registry_Property(RootBus, //Devnode
  258. CM_DRP_LOWERFILTERS, //Reg Propert
  259. NULL, //REG data type
  260. NULL, //Buffer
  261. &requiredSize, //Buffer size
  262. 0 //flags
  263. )) != CR_SUCCESS){
  264. if (cr == CR_NO_SUCH_VALUE) {
  265. //
  266. // No filter. Add ours.
  267. //
  268. if ((cr = CM_Set_DevNode_Registry_Property(RootBus,
  269. CM_DRP_LOWERFILTERS,
  270. (PVOID)SOFTPCI_FILTER_SERVICE_NAME,
  271. size,
  272. 0
  273. )) != CR_SUCCESS){
  274. return FALSE;
  275. }
  276. return TRUE;
  277. }
  278. //
  279. // If there is already a filter key, then we need to append to it
  280. //
  281. if (requiredSize) {
  282. buffer = (PWCHAR) calloc(1, requiredSize);
  283. if (buffer == NULL) {
  284. return FALSE;
  285. }
  286. //
  287. // Call again and get the current filter value
  288. //
  289. if ((CM_Get_DevNode_Registry_Property(RootBus,
  290. CM_DRP_LOWERFILTERS,
  291. NULL,
  292. buffer,
  293. &requiredSize,
  294. 0
  295. )) != CR_SUCCESS){
  296. status = FALSE;
  297. goto cleanup;
  298. }
  299. newBuffer = (PWCHAR) calloc(1, (requiredSize + size));
  300. if (newBuffer == NULL) {
  301. return FALSE;
  302. }
  303. entry2 = newBuffer;
  304. //
  305. // Run the list. If we are already present bail
  306. //
  307. for (entry = buffer; *entry; entry += (wcslen(entry)+1)) {
  308. if (wcscmp(entry, SOFTPCI_FILTER_SERVICE_NAME) == 0) {
  309. //
  310. // We are already installed
  311. //
  312. MessageBox(NULL, L"SoftPCI driver support already installed!", L"Install Error", MB_OK);
  313. status = FALSE;
  314. goto cleanup;
  315. }
  316. //
  317. // copy each entry to our new list
  318. //
  319. wcscpy(entry2, entry);
  320. entry2 += (wcslen(entry)+1);
  321. }
  322. //
  323. // Add our entry to the list
  324. //
  325. wcscpy(entry2, SOFTPCI_FILTER_SERVICE_NAME);
  326. if ((cr = CM_Set_DevNode_Registry_Property(RootBus,
  327. CM_DRP_LOWERFILTERS,
  328. newBuffer,
  329. requiredSize + size,
  330. 0
  331. )) != CR_SUCCESS){
  332. status = FALSE;
  333. goto cleanup;
  334. }
  335. status = TRUE;
  336. goto cleanup;
  337. }
  338. //
  339. // Failed to get required size
  340. //
  341. }
  342. #ifdef DEBUG
  343. else{
  344. SOFTPCI_ASSERT(FALSE);
  345. //
  346. // VERY BAD!! Should never get back success here!
  347. //
  348. }
  349. #endif
  350. cleanup:
  351. if (buffer) {
  352. free(buffer);
  353. }
  354. if (newBuffer) {
  355. free(newBuffer);
  356. }
  357. return status;
  358. }
  359. VOID
  360. SoftPCI_LocateRootPciBusesForInstall(
  361. IN PPCI_DN Pdn,
  362. OUT PBOOL Success
  363. )
  364. /*++
  365. Routine Description:
  366. This routine searches our tree for all root pci buses and then installs
  367. our filter on them
  368. Arguments:
  369. RootBus - Location to return first root bus.
  370. Return Value:
  371. TRUE if success.
  372. --*/
  373. {
  374. PPCI_DN child, sibling;
  375. if (Pdn == NULL) {
  376. *Success = FALSE;
  377. return;
  378. }
  379. child = Pdn->Child;
  380. sibling = Pdn->Sibling;
  381. if (SoftPCI_IsDevnodePCIRoot(Pdn->DevNode, FALSE)) {
  382. *Success = SoftPCI_InstallFilterKey(Pdn->DevNode);
  383. if (*Success) {
  384. SoftPCI_UpdateDeviceFriendlyName(Pdn->DevNode, SOFTPCI_BUS_DESC);
  385. }
  386. }
  387. if (*Success && child) {
  388. SoftPCI_LocateRootPciBusesForInstall(child, Success);
  389. }
  390. if (*Success && sibling) {
  391. SoftPCI_LocateRootPciBusesForInstall(sibling, Success);
  392. }
  393. }
  394. BOOL
  395. SoftPCI_RebootSystem(
  396. VOID
  397. )
  398. {
  399. HANDLE token;
  400. TOKEN_PRIVILEGES tp;
  401. LUID luid;
  402. if (!OpenProcessToken(GetCurrentProcess(),
  403. (TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY),
  404. &token)){
  405. return FALSE;
  406. }
  407. if (!LookupPrivilegeValue(NULL,
  408. SE_SHUTDOWN_NAME,
  409. &luid)) {
  410. return FALSE;
  411. }
  412. tp.PrivilegeCount = 1;
  413. tp.Privileges[0].Luid = luid;
  414. tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  415. AdjustTokenPrivileges(token,
  416. FALSE,
  417. &tp,
  418. sizeof(TOKEN_PRIVILEGES),
  419. (PTOKEN_PRIVILEGES) NULL,
  420. (PDWORD) NULL
  421. );
  422. if (GetLastError() != ERROR_SUCCESS) {
  423. return FALSE;
  424. }
  425. //
  426. // We should now be able to reboot the system.
  427. //
  428. return InitiateSystemShutdown(NULL, NULL, 0, TRUE, TRUE);
  429. }
  430. #if 0
  431. BOOL
  432. _lwritef(
  433. IN HANDLE hFile,
  434. IN PTSTR Format,
  435. ...)
  436. /*++
  437. Routine Description:
  438. This routine provides "fprintf" like functionality. (code stolen from DVNT)
  439. Arguments:
  440. hFile - Handle to INF file
  441. Format - String of data to be formatted and written
  442. Return Value:
  443. FALSE if no failures.
  444. --*/
  445. {
  446. va_list arglist;
  447. WCHAR buffer[514];
  448. INT cb;
  449. DWORD written;
  450. va_start(arglist, Format);
  451. cb = wvsprintf(buffer, Format, arglist);
  452. if (cb == -1) // handle buffer overflow
  453. {
  454. cb = sizeof(buffer) ;
  455. }
  456. else
  457. {
  458. cb+=2 ;
  459. }
  460. lstrcpy(buffer+cb-2, TEXT("\r\n")) ;
  461. return (WriteFile(hFile,
  462. buffer,
  463. cb*sizeof(WCHAR),
  464. &written,
  465. NULL
  466. ));
  467. }
  468. BOOL
  469. SoftPCI_CreateDriverINF(
  470. IN LPTSTR InfPath
  471. )
  472. /*++
  473. Routine Description:
  474. This routine build our INF file needed to install our SoftPCI devices.
  475. Arguments:
  476. InfPath = Path to INF we need to create
  477. Return Value:
  478. TRUE if successful.
  479. --*/
  480. {
  481. BOOL result = TRUE;
  482. HANDLE hFile;
  483. SYSTEMTIME systime;
  484. GetLocalTime(&systime);
  485. if ((hFile = CreateFile(InfPath,
  486. GENERIC_WRITE,
  487. 0,
  488. NULL,
  489. CREATE_ALWAYS,
  490. FILE_ATTRIBUTE_NORMAL,
  491. NULL
  492. )) == INVALID_HANDLE_VALUE) {
  493. return FALSE;
  494. }
  495. result &= _lwritef(hFile, TEXT("[Version]"));
  496. result &= _lwritef(hFile, TEXT("Signature=\"$WINDOWS NT$\""));
  497. result &= _lwritef(hFile, TEXT("Class=System"));
  498. result &= _lwritef(hFile, TEXT("ClassGuid={4D36E97D-E325-11CE-BFC1-08002BE10318}"));
  499. result &= _lwritef(hFile, TEXT("Provider=%%MSFT%%"));
  500. result &= _lwritef(hFile, TEXT("LayoutFile=layout.inf"));
  501. result &= _lwritef(hFile,
  502. TEXT("DriverVer=%02d/%02d/%04d,5.1.%d.0\r\n"),
  503. systime.wMonth,
  504. systime.wDay,
  505. systime.wYear,
  506. VER_PRODUCTBUILD);
  507. result &= _lwritef(hFile, TEXT("[DestinationDirs]"));
  508. result &= _lwritef(hFile, TEXT("DefaultDestDir = 12\r\n"));
  509. result &= _lwritef(hFile, TEXT("[Manufacturer]"));
  510. result &= _lwritef(hFile, TEXT("%%GENDEV_MFG%%=GENDEV_SYS\r\n"));
  511. result &= _lwritef(hFile, TEXT("[GENDEV_SYS]"));
  512. result &= _lwritef(hFile, TEXT("%%VEN_ABCD&DEV_DCBA.DeviceDesc%% = SOFTPCI_FDO_Install, PCI\\VEN_ABCD&DEV_DCBA&SUBSYS_DCBAABCD"));
  513. result &= _lwritef(hFile, TEXT("%%VEN_ABCD&DEV_DCBC.DeviceDesc%% = HPPCI_DRV, PCI\\VEN_ABCD&DEV_DCBC\r\n"));
  514. result &= _lwritef(hFile, TEXT(";****************************************************"));
  515. result &= _lwritef(hFile, TEXT("; SoftPci filter"));
  516. result &= _lwritef(hFile, TEXT("[%s]"), SOFTPCI_FILTER_SECTION);
  517. result &= _lwritef(hFile, TEXT("AddService = %s,0,softpci_ServiceInstallSection\r\n"), SOFTPCI_FILTER_SERVICE_NAME);
  518. result &= _lwritef(hFile, TEXT("[softpci_ServiceInstallSection]"));
  519. result &= _lwritef(hFile, TEXT("DisplayName = %%softpci_filterdesc%%"));
  520. result &= _lwritef(hFile, TEXT("ServiceType = %%SERVICE_KERNEL_DRIVER%%"));
  521. result &= _lwritef(hFile, TEXT("StartType = %%SERVICE_BOOT_START%%"));
  522. result &= _lwritef(hFile, TEXT("ErrorControl = %%SERVICE_ERROR_NORMAL%%"));
  523. result &= _lwritef(hFile, TEXT("ServiceBinary = %%12%%\\%s.sys\r\n"), SOFTPCIDRV);
  524. result &= _lwritef(hFile, TEXT(";****************************************************"));
  525. result &= _lwritef(hFile, TEXT("; SoftPci function driver"));
  526. result &= _lwritef(hFile, TEXT("[SOFTPCI_FDO_Install]"));
  527. result &= _lwritef(hFile, TEXT("CopyFiles=%s.sys\r\n"), SOFTPCIDRV);
  528. result &= _lwritef(hFile, TEXT("[SOFTPCI_FDO_Install.Services]"));
  529. result &= _lwritef(hFile, TEXT("AddService = SoftPCI_FDO,0x000001fa,SOFTPCI_FDO_ServiceInstallSection\r\n"));
  530. result &= _lwritef(hFile, TEXT("[SOFTPCI_FDO_ServiceInstallSection]"));
  531. result &= _lwritef(hFile, TEXT("DisplayName = %%softpci_fdodesc%%"));
  532. result &= _lwritef(hFile, TEXT("ServiceType = %%SERVICE_KERNEL_DRIVER%%"));
  533. result &= _lwritef(hFile, TEXT("StartType = %%SERVICE_DEMAND_START%%"));
  534. result &= _lwritef(hFile, TEXT("ErrorControl = %%SERVICE_ERROR_NORMAL%%"));
  535. result &= _lwritef(hFile, TEXT("ServiceBinary = %%12%%\\%s.sys\r\n"), SOFTPCIDRV);
  536. result &= _lwritef(hFile, TEXT(";****************************************************"));
  537. result &= _lwritef(hFile, TEXT("; Hotplug Controller simulator and driver"));
  538. result &= _lwritef(hFile, TEXT("[HPPCI_DRV]"));
  539. result &= _lwritef(hFile, TEXT("CopyFiles=HPPCI.CopyFiles\r\n"));
  540. result &= _lwritef(hFile, TEXT("[HPPCI_DRV.HW]"));
  541. result &= _lwritef(hFile, TEXT("AddReg = HPPCI_Filter_Reg\r\n"));
  542. result &= _lwritef(hFile, TEXT("[HPPCI_DRV.Services]"));
  543. result &= _lwritef(hFile, TEXT("AddService = hpsim,0,hpsim_ServiceInstallSection"));
  544. result &= _lwritef(hFile, TEXT("AddService = shpc,0,shpc_ServiceInstallSection"));
  545. result &= _lwritef(hFile, TEXT("AddService = pci, %%SPSVCINST_ASSOCSERVICE%%, pci_ServiceInstallSection\r\n"));
  546. result &= _lwritef(hFile, TEXT("[HPPCI_Filter_Reg]"));
  547. result &= _lwritef(hFile, TEXT("HKR,,\"LowerFilters\", 0x00010000,\"hpsim\""));
  548. result &= _lwritef(hFile, TEXT("HKR,,\"UpperFilters\", 0x00010000,hpsim,shpc\r\n"));
  549. result &= _lwritef(hFile, TEXT("[HPPCI.CopyFiles]"));
  550. result &= _lwritef(hFile, TEXT("hpsim.sys"));
  551. result &= _lwritef(hFile, TEXT("shpc.sys\r\n"));
  552. result &= _lwritef(hFile, TEXT("[hpsim_ServiceInstallSection]"));
  553. result &= _lwritef(hFile, TEXT("DisplayName = %%hpsim_svcdesc%%"));
  554. result &= _lwritef(hFile, TEXT("ServiceType = %%SERVICE_KERNEL_DRIVER%%"));
  555. result &= _lwritef(hFile, TEXT("StartType = %%SERVICE_DEMAND_START%%"));
  556. result &= _lwritef(hFile, TEXT("ErrorControl = %%SERVICE_ERROR_NORMAL%%"));
  557. result &= _lwritef(hFile, TEXT("ServiceBinary = %%12%%\\hpsim.sys\r\n"));
  558. result &= _lwritef(hFile, TEXT("[shpc_ServiceInstallSection]]"));
  559. result &= _lwritef(hFile, TEXT("DisplayName = %%shpc_svcdesc%%"));
  560. result &= _lwritef(hFile, TEXT("ServiceType = %%SERVICE_KERNEL_DRIVER%%"));
  561. result &= _lwritef(hFile, TEXT("StartType = %%SERVICE_DEMAND_START%%"));
  562. result &= _lwritef(hFile, TEXT("ErrorControl = %%SERVICE_ERROR_NORMAL%%"));
  563. result &= _lwritef(hFile, TEXT("ServiceBinary = %%12%%\\shpc.sys\r\n"));
  564. result &= _lwritef(hFile, TEXT(";****************************************************"));
  565. result &= _lwritef(hFile, TEXT(";Device descriptions"));
  566. result &= _lwritef(hFile, TEXT("[Strings]"));
  567. result &= _lwritef(hFile, TEXT("GENDEV_MFG = \"(Standard system devices)\""));
  568. result &= _lwritef(hFile, TEXT("SystemClassName = \"System devices\""));
  569. result &= _lwritef(hFile, TEXT("MSFT = \"Microsoft\""));
  570. result &= _lwritef(hFile, TEXT("VEN_ABCD&DEV_DCBA.DeviceDesc = \"%s\""), SOFTPCI_DEVICE_DESC);
  571. result &= _lwritef(hFile, TEXT("VEN_ABCD&DEV_DCBC.DeviceDesc = \"%s\"\r\n"), SOFTPCI_HOTPLUG_DESC);
  572. result &= _lwritef(hFile, TEXT(";****************************************************"));
  573. result &= _lwritef(hFile, TEXT(";Service descriptions"));
  574. result &= _lwritef(hFile, TEXT("softpci_fdodesc = \"Microsoft SoftPCI Device Driver\""));
  575. result &= _lwritef(hFile, TEXT("softpci_filterdesc = \"Microsoft SoftPCI Bus Filter\""));
  576. result &= _lwritef(hFile, TEXT("hpsim_svcdesc = \"Hotplug Controller Simulator Filter\""));
  577. result &= _lwritef(hFile, TEXT("shpc_svcdesc = \"Hotplug Controller Bus Filter\"\r\n"));
  578. result &= _lwritef(hFile, TEXT(";****************************************************"));
  579. result &= _lwritef(hFile, TEXT(";Handy macro substitutions (non-localizable)"));
  580. result &= _lwritef(hFile, TEXT("SPSVCINST_ASSOCSERVICE = 0x00000002"));
  581. result &= _lwritef(hFile, TEXT("SERVICE_KERNEL_DRIVER = 1"));
  582. result &= _lwritef(hFile, TEXT("SERVICE_BOOT_START = 0"));
  583. result &= _lwritef(hFile, TEXT("SERVICE_DEMAND_START = 3"));
  584. result &= _lwritef(hFile, TEXT("SERVICE_ERROR_NORMAL = 1"));
  585. result &= _lwritef(hFile, TEXT("SERVICE_ERROR_CRITICAL = 3"));
  586. CloseHandle(hFile);
  587. return result;
  588. }
  589. #endif