Source code of Windows XP (NT5)
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.

1124 lines
22 KiB

  1. #include "precomp.h"
  2. #pragma hdrstop
  3. /*++
  4. Copyright (c) 1990 Microsoft Corporation
  5. Module Name:
  6. detect1.c
  7. Abstract:
  8. Detect module for Win32 PDK Setup.
  9. This module has no external dependencies and is not statically linked
  10. to any part of Setup.
  11. Author:
  12. Ted Miller (tedm) June 1991
  13. --*/
  14. #define PROCESSOR_NONE ""
  15. #define PROCESSOR_I386 "I386"
  16. #define PROCESSOR_I486 "I486"
  17. #define PROCESSOR_I586 "I586"
  18. #define PROCESSOR_R4000 "R4000"
  19. #define PROCESSOR_ALPHA "Alpha_AXP"
  20. #define PROCESSOR_PPC601 "PPC601"
  21. #define PROCESSOR_PPC603 "PPC603"
  22. #define PROCESSOR_PPC604 "PPC604"
  23. #define PROCESSOR_PPC620 "PPC620"
  24. #define PLATFORM_NONE ""
  25. #define PLATFORM_I386 "I386"
  26. #define PLATFORM_MIPS "Mips"
  27. #define PLATFORM_ALPHA "Alpha"
  28. #define PLATFORM_PPC "ppc"
  29. //
  30. // Local prototypes
  31. //
  32. BOOL MatchNtPathToDosPath( PUNICODE_STRING, PUNICODE_STRING, SZ, SZ, CB );
  33. VOID ConvertUnicodeToAnsi( PUNICODE_STRING, SZ );
  34. /*
  35. oemcp as a string
  36. */
  37. CB
  38. GetOemCodepage(
  39. IN RGSZ Args,
  40. IN USHORT cArgs,
  41. OUT SZ ReturnBuffer,
  42. IN CB cbReturnBuffer
  43. )
  44. {
  45. UINT cp;
  46. Unused(Args);
  47. Unused(cArgs);
  48. Unused(cbReturnBuffer);
  49. cp = GetOEMCP();
  50. wsprintf(ReturnBuffer,"%u",cp);
  51. return(lstrlen(ReturnBuffer)+1);
  52. }
  53. /*
  54. ansicp as a string
  55. */
  56. CB
  57. GetAnsiCodepage(
  58. IN RGSZ Args,
  59. IN USHORT cArgs,
  60. OUT SZ ReturnBuffer,
  61. IN CB cbReturnBuffer
  62. )
  63. {
  64. UINT cp;
  65. Unused(Args);
  66. Unused(cArgs);
  67. Unused(cbReturnBuffer);
  68. cp = GetACP();
  69. wsprintf(ReturnBuffer,"%u",cp);
  70. return(lstrlen(ReturnBuffer)+1);
  71. }
  72. /*
  73. langauge type as a string
  74. */
  75. CB
  76. GetLanguage(
  77. IN RGSZ Args,
  78. IN USHORT cArgs,
  79. OUT SZ ReturnBuffer,
  80. IN CB cbReturnBuffer
  81. )
  82. {
  83. //
  84. // bugbug ramonsa - enable when GetQualifiedLocale returns something
  85. // meaningful
  86. #ifdef LOCALE_STUFF
  87. LCID LcId = {0,0,0};
  88. LCSTRINGS LcStrings;
  89. Unused(Args);
  90. Unused(cArgs);
  91. Unused(cbReturnBuffer);
  92. ReturnBuffer[0] = '\0';
  93. if ( GetQualifiedLocale( QF_LCID,
  94. &LcId,
  95. NULL,
  96. &LcStrings ) ) {
  97. lstrcpy(ReturnBuffer,LcStrings.szLanguage);
  98. return(lstrlen(ReturnBuffer)+1);
  99. }
  100. return 0;
  101. #else
  102. #define TEMP_LANGUAGE "ENG"
  103. Unused(Args);
  104. Unused(cArgs);
  105. Unused(cbReturnBuffer);
  106. lstrcpy(ReturnBuffer,TEMP_LANGUAGE);
  107. return(lstrlen(ReturnBuffer)+1);
  108. #endif
  109. }
  110. /*
  111. * GetSystemDate - returns a list of date information in the following
  112. * order:
  113. * sec after 1-1-1970, year, month, day, hour, minute, second, millisecond
  114. *
  115. */
  116. CB
  117. GetSystemDate(
  118. IN RGSZ Args,
  119. IN USHORT cArgs,
  120. OUT SZ ReturnBuffer,
  121. IN CB cbReturnBuffer
  122. )
  123. {
  124. SYSTEMTIME systime;
  125. time_t timet;
  126. Unused( Args );
  127. Unused( cArgs );
  128. Unused( cbReturnBuffer );
  129. GetSystemTime( &systime );
  130. time( &timet );
  131. wsprintf(ReturnBuffer, "{\"%d\",\"%d\",\"%d\",\"%d\",\"%d\",\"%d\",\"%d\",\"%d\"}",
  132. timet,
  133. systime.wYear,
  134. systime.wMonth,
  135. systime.wDay,
  136. systime.wHour,
  137. systime.wMinute,
  138. systime.wSecond,
  139. systime.wMilliseconds
  140. );
  141. return(lstrlen(ReturnBuffer)+1);
  142. }
  143. /*
  144. Country type as a string
  145. */
  146. CB
  147. GetCountry(
  148. IN RGSZ Args,
  149. IN USHORT cArgs,
  150. OUT SZ ReturnBuffer,
  151. IN CB cbReturnBuffer
  152. )
  153. {
  154. //
  155. // bugbug ramonsa - enable when GetQualifiedLocale returns something
  156. // meaningful
  157. #ifdef LOCALE_STUFF
  158. LCID LcId = {0,0,0};
  159. LCSTRINGS LcStrings;
  160. Unused(Args);
  161. Unused(cArgs);
  162. Unused(cbReturnBuffer);
  163. ReturnBuffer[0] = '\0';
  164. if ( GetQualifiedLocale( QF_LCID,
  165. &LcId,
  166. NULL,
  167. &LcStrings ) ) {
  168. lstrcpy(ReturnBuffer,LcStrings.szCountry);
  169. return(lstrlen(ReturnBuffer)+1);
  170. }
  171. return 0;
  172. #else
  173. #define TEMP_COUNTRY "US"
  174. Unused(Args);
  175. Unused(cArgs);
  176. Unused(cbReturnBuffer);
  177. lstrcpy(ReturnBuffer,TEMP_COUNTRY);
  178. return(lstrlen(ReturnBuffer)+1);
  179. #endif
  180. }
  181. CB
  182. GetProcessor(
  183. IN RGSZ Args,
  184. IN USHORT cArgs,
  185. OUT SZ ReturnBuffer,
  186. IN CB cbReturnBuffer
  187. )
  188. {
  189. SYSTEM_INFO SystemInfo;
  190. SZ szProcessor;
  191. Unused(Args);
  192. Unused(cArgs);
  193. Unused(cbReturnBuffer);
  194. GetSystemInfo( &SystemInfo );
  195. switch ( SystemInfo.wProcessorArchitecture ) {
  196. case PROCESSOR_ARCHITECTURE_INTEL:
  197. if (SystemInfo.wProcessorLevel == 3) {
  198. szProcessor = PROCESSOR_I386;
  199. } else
  200. if (SystemInfo.wProcessorLevel == 4) {
  201. szProcessor = PROCESSOR_I486;
  202. } else {
  203. szProcessor = PROCESSOR_I586;
  204. }
  205. break;
  206. case PROCESSOR_ARCHITECTURE_MIPS:
  207. szProcessor = PROCESSOR_R4000;
  208. break;
  209. case PROCESSOR_ARCHITECTURE_ALPHA:
  210. szProcessor = PROCESSOR_ALPHA;
  211. break;
  212. case PROCESSOR_ARCHITECTURE_PPC:
  213. if (SystemInfo.wProcessorLevel == 1) {
  214. szProcessor = PROCESSOR_PPC601;
  215. } else
  216. if (SystemInfo.wProcessorLevel == 3) {
  217. szProcessor = PROCESSOR_PPC603;
  218. } else
  219. if (SystemInfo.wProcessorLevel == 4) {
  220. szProcessor = PROCESSOR_PPC604;
  221. } else
  222. if (SystemInfo.wProcessorLevel == 6) {
  223. szProcessor = PROCESSOR_PPC603;
  224. } else
  225. if (SystemInfo.wProcessorLevel == 7) {
  226. szProcessor = PROCESSOR_PPC603;
  227. } else
  228. if (SystemInfo.wProcessorLevel == 9) {
  229. szProcessor = PROCESSOR_PPC604;
  230. } else
  231. if (SystemInfo.wProcessorLevel == 20) {
  232. szProcessor = PROCESSOR_PPC620;
  233. }
  234. else {
  235. szProcessor = PROCESSOR_PPC601;
  236. }
  237. break;
  238. default:
  239. //
  240. // There could be processors we don't know about.
  241. // Try to make sure we'll at least set up on them
  242. // by defaulting to a known processor. This also eliminates
  243. // the need to keep updating the INFs to know about all the
  244. // processors we support.
  245. //
  246. szProcessor = PROCESSOR_NONE;
  247. #ifdef _X86_
  248. //
  249. // Probably a P6 or greater.
  250. //
  251. szProcessor = PROCESSOR_I586;
  252. #endif
  253. #ifdef _MIPS_
  254. //
  255. // Probably something that came after the R4000.
  256. // Assume R4000 to be safe.
  257. //
  258. szProcessor = PROCESSOR_R4000;
  259. #endif
  260. #ifdef _ALPHA_
  261. //
  262. // Just recognize that it's an Alpha.
  263. //
  264. szProcessor = PROCESSOR_ALPHA;
  265. #endif
  266. #ifdef _PPC_
  267. //
  268. // Just call it a 601, which is assumed to be
  269. // the lowest common denominator.
  270. //
  271. szProcessor = PROCESSOR_PPC601;
  272. #endif
  273. break;
  274. }
  275. lstrcpy( ReturnBuffer, szProcessor );
  276. return lstrlen( ReturnBuffer)+1;
  277. }
  278. CB
  279. GetPlatform(
  280. IN RGSZ Args,
  281. IN USHORT cArgs,
  282. OUT SZ ReturnBuffer,
  283. IN CB cbReturnBuffer
  284. )
  285. {
  286. SYSTEM_INFO SystemInfo;
  287. SZ szPlatform;
  288. Unused(Args);
  289. Unused(cArgs);
  290. Unused(cbReturnBuffer);
  291. GetSystemInfo( &SystemInfo );
  292. switch ( SystemInfo.wProcessorArchitecture ) {
  293. case PROCESSOR_ARCHITECTURE_INTEL:
  294. szPlatform = PLATFORM_I386;
  295. break;
  296. case PROCESSOR_ARCHITECTURE_MIPS:
  297. szPlatform = PLATFORM_MIPS;
  298. break;
  299. case PROCESSOR_ARCHITECTURE_ALPHA:
  300. szPlatform = PLATFORM_ALPHA;
  301. break;
  302. case PROCESSOR_ARCHITECTURE_PPC:
  303. szPlatform = PLATFORM_PPC;
  304. break;
  305. default:
  306. szPlatform = PLATFORM_NONE;
  307. //
  308. // Try really hard to return a reasonable value by
  309. // assuming that the code is running on a machine of the
  310. // platform for which the it was compiled.
  311. // This lets us run on processors we haven't invented yet
  312. // and whose ids are thus not accounted for in the aboce
  313. // cases.
  314. //
  315. #ifdef _X86_
  316. szPlatform = PLATFORM_I386;
  317. #endif
  318. #ifdef _MIPS_
  319. szPlatform = PLATFORM_MIPS;
  320. #endif
  321. #ifdef _ALPHA_
  322. szPlatform = PLATFORM_ALPHA;
  323. #endif
  324. #ifdef _PPC_
  325. szPlatform = PLATFORM_PPC;
  326. #endif
  327. break;
  328. }
  329. lstrcpy( ReturnBuffer, szPlatform );
  330. return lstrlen( ReturnBuffer)+1;
  331. }
  332. /*
  333. Memory size as an ASCII string (Kb)
  334. */
  335. CB
  336. GetMemorySize(
  337. IN RGSZ Args,
  338. IN USHORT cArgs,
  339. OUT SZ ReturnBuffer,
  340. IN CB cbReturnBuffer
  341. )
  342. {
  343. MEMORYSTATUS MemoryStatus;
  344. Unused(Args);
  345. Unused(cArgs);
  346. Unused(cbReturnBuffer);
  347. GlobalMemoryStatus(&MemoryStatus);
  348. _ultoa((ULONG)(MemoryStatus.dwTotalPhys/1024),ReturnBuffer,10);
  349. return(lstrlen(ReturnBuffer)+1);
  350. }
  351. /*
  352. Minimum pagefile size necessary for crash dump support (MB)
  353. */
  354. CB
  355. GetCrashDumpSize(
  356. IN RGSZ Args,
  357. IN USHORT cArgs,
  358. OUT SZ ReturnBuffer,
  359. IN CB cbReturnBuffer
  360. )
  361. {
  362. MEMORYSTATUS ms;
  363. SYSTEM_INFO si;
  364. Unused(Args);
  365. Unused(cArgs);
  366. Unused(cbReturnBuffer);
  367. GlobalMemoryStatus(&ms);
  368. GetSystemInfo(&si);
  369. //
  370. // We need a pagefile as large as physical memory + 1 page.
  371. //
  372. _ultoa(
  373. (ULONG)((ms.dwTotalPhys + si.dwPageSize + 0xFFFFF) >> 20),
  374. ReturnBuffer,
  375. 10);
  376. return(lstrlen(ReturnBuffer)+1);
  377. }
  378. /*
  379. list of paths on which a given file appears.
  380. */
  381. CB
  382. FindFileInstances(
  383. IN RGSZ Args,
  384. IN USHORT cArgs,
  385. OUT SZ ReturnBuffer,
  386. IN CB cbReturnBuffer
  387. )
  388. {
  389. CB rc = 0;
  390. SZ sz;
  391. RGSZ rgszFiles;
  392. HANDLE hff;
  393. WIN32_FIND_DATA FindFileData;
  394. Unused(cbReturnBuffer);
  395. //
  396. // If no file specified then return 0
  397. //
  398. if (cArgs != 1) {
  399. return rc;
  400. }
  401. //
  402. // If invalid filename then return 0
  403. if ((lstrlen(Args[0]) + 1) > MAX_PATH) {
  404. return rc;
  405. }
  406. //
  407. // Allocate just the NULL terminator for the rgsz structure
  408. //
  409. rgszFiles = RgszAlloc(1);
  410. if (!rgszFiles) {
  411. return rc;
  412. }
  413. //
  414. // Do find first, find next adding files found to the rgsz structure
  415. //
  416. if ((hff = FindFirstFile( Args[0], &FindFileData )) != (HANDLE)-1) {
  417. do {
  418. if (!RgszAdd( &rgszFiles, SzDup( (SZ)FindFileData.cFileName ) )) {
  419. FindClose( hff );
  420. return rc;
  421. }
  422. }
  423. while (FindNextFile(hff, &FindFileData));
  424. FindClose( hff );
  425. }
  426. //
  427. // Convert the rgsz structure to a sz list value and copy this over
  428. // to the return buffer.
  429. //
  430. sz = SzListValueFromRgsz( rgszFiles );
  431. if ( sz ) {
  432. lstrcpy( ReturnBuffer, sz );
  433. rc = lstrlen(sz) + 1;
  434. SFree( sz );
  435. }
  436. RgszFree( rgszFiles );
  437. return ( rc );
  438. }
  439. //
  440. // Get Windows version
  441. //
  442. CB
  443. GetWindowsNtVersion(
  444. IN RGSZ Args,
  445. IN USHORT cArgs,
  446. OUT SZ ReturnBuffer,
  447. IN CB cbReturnBuffer
  448. )
  449. {
  450. DWORD Version;
  451. DWORD WinMaj;
  452. DWORD WinMin;
  453. DWORD OsMaj;
  454. DWORD OsMin;
  455. Unused(Args);
  456. Unused(cArgs);
  457. Unused(cbReturnBuffer);
  458. Version = GetVersion();
  459. WinMaj = FIRSTBYTE(Version);
  460. WinMin = SECONDBYTE(Version);
  461. OsMin = THIRDBYTE(Version);
  462. OsMaj = FOURTHBYTE(Version);
  463. sprintf(ReturnBuffer, "{%lu,%lu,%lu,%lu}", WinMaj, WinMin, OsMaj, OsMin );
  464. return(lstrlen(ReturnBuffer)+1);
  465. }
  466. //
  467. // Get Windows directory
  468. //
  469. CB
  470. GetWindowsNtDir(
  471. IN RGSZ Args,
  472. IN USHORT cArgs,
  473. OUT SZ ReturnBuffer,
  474. IN CB cbReturnBuffer
  475. )
  476. {
  477. DWORD cbRet;
  478. Unused(Args);
  479. Unused(cArgs);
  480. cbRet = GetWindowsDirectory( ReturnBuffer, cbReturnBuffer );
  481. if ( (cbRet == 0) || (cbRet > cbReturnBuffer) ) {
  482. ReturnBuffer[0] = '\0';
  483. return 0;
  484. }
  485. return cbRet + 1;
  486. }
  487. //
  488. // Get Windows system directory
  489. //
  490. CB
  491. GetWindowsNtSysDir(
  492. IN RGSZ Args,
  493. IN USHORT cArgs,
  494. OUT SZ ReturnBuffer,
  495. IN CB cbReturnBuffer
  496. )
  497. {
  498. DWORD cbRet;
  499. Unused(Args);
  500. Unused(cArgs);
  501. cbRet = GetSystemDirectory( ReturnBuffer, cbReturnBuffer );
  502. if ( (cbRet == 0) || (cbRet > cbReturnBuffer) ) {
  503. ReturnBuffer[0] = '\0';
  504. return 0;
  505. }
  506. return cbRet + 1;
  507. }
  508. //
  509. // Get NT directory
  510. //
  511. CB
  512. GetNtDir(
  513. IN RGSZ Args,
  514. IN USHORT cArgs,
  515. OUT SZ ReturnBuffer,
  516. IN CB cbReturnBuffer
  517. )
  518. {
  519. #define SYSTEMROOT "\\SystemRoot"
  520. #define DRIVEROOT "\\DosDevices\\?:"
  521. #define LINKBUFFERSIZE (MAXIMUM_FILENAME_LENGTH * sizeof(WCHAR))
  522. ANSI_STRING SystemRoot;
  523. ANSI_STRING DriveRoot;
  524. WCHAR SysLinkBuffer[LINKBUFFERSIZE];
  525. WCHAR DrvLinkBuffer[LINKBUFFERSIZE];
  526. WCHAR DriveLetter;
  527. CHAR DriveBuffer[] = DRIVEROOT;
  528. NTSTATUS Status;
  529. UNICODE_STRING SystemRootU;
  530. UNICODE_STRING SystemRootLinkU;
  531. UNICODE_STRING DriveRootU;
  532. UNICODE_STRING DriveRootLinkU;
  533. Unused(Args);
  534. Unused(cArgs);
  535. Unused(cbReturnBuffer);
  536. ReturnBuffer[0] = '\0';
  537. SystemRootLinkU.Length = 0;
  538. SystemRootLinkU.MaximumLength = LINKBUFFERSIZE;
  539. SystemRootLinkU.Buffer = SysLinkBuffer;
  540. DriveRootLinkU.Length = 0;
  541. DriveRootLinkU.MaximumLength = LINKBUFFERSIZE;
  542. DriveRootLinkU.Buffer = DrvLinkBuffer;
  543. RtlInitAnsiString(&SystemRoot, SYSTEMROOT);
  544. Status = RtlAnsiStringToUnicodeString(
  545. &SystemRootU,
  546. &SystemRoot,
  547. TRUE
  548. );
  549. //
  550. // Get the value of the "SystemRoot" symbolic link.
  551. //
  552. if ( GetSymbolicLinkTarget( &SystemRootU, &SystemRootLinkU ) ) {
  553. for ( DriveLetter = (WCHAR)'A';
  554. DriveLetter <= (WCHAR)'Z';
  555. DriveLetter++ ) {
  556. DriveBuffer[12] = (CHAR)DriveLetter;
  557. RtlInitAnsiString(&DriveRoot, DriveBuffer);
  558. Status = RtlAnsiStringToUnicodeString(
  559. &DriveRootU,
  560. &DriveRoot,
  561. TRUE
  562. );
  563. //
  564. // If there is a symbolic link for the drive, see if it
  565. // matches the symbolic link of "SystemRoot"
  566. //
  567. if ( GetSymbolicLinkTarget( &DriveRootU, &DriveRootLinkU ) ) {
  568. if ( MatchNtPathToDosPath( &SystemRootLinkU,
  569. &DriveRootLinkU,
  570. &DriveBuffer[12],
  571. ReturnBuffer,
  572. cbReturnBuffer ) ) {
  573. return lstrlen(ReturnBuffer)+1;
  574. }
  575. }
  576. RtlFreeUnicodeString(&DriveRootU);
  577. }
  578. }
  579. RtlFreeUnicodeString(&SystemRootU);
  580. return 0;
  581. }
  582. //
  583. // Convert an NT path to a DOS path
  584. //
  585. BOOL
  586. MatchNtPathToDosPath(
  587. IN PUNICODE_STRING NtPathU,
  588. IN PUNICODE_STRING DosLinkU,
  589. IN SZ DosPath,
  590. OUT SZ ReturnBuffer,
  591. IN CB cbBuffer
  592. )
  593. {
  594. CHAR NtPath[MAX_PATH];
  595. CHAR DosLink[MAX_PATH];
  596. SZ p;
  597. Unused( cbBuffer );
  598. ConvertUnicodeToAnsi( NtPathU, NtPath );
  599. ConvertUnicodeToAnsi( DosLinkU, DosLink );
  600. //
  601. // If DosLink is a substring of NtPath, then subsitute that substring by
  602. // the given DosPath.
  603. //
  604. p = strstr( NtPath, DosLink );
  605. if ( p == NtPath ) {
  606. strcpy( ReturnBuffer, DosPath );
  607. p = NtPath + strlen(DosLink);
  608. strcat( ReturnBuffer, p );
  609. return fTrue;
  610. }
  611. return fFalse;
  612. }
  613. //
  614. // Convert Unicode string to ansi string
  615. //
  616. VOID
  617. ConvertUnicodeToAnsi(
  618. IN PUNICODE_STRING UnicodeString,
  619. OUT SZ AnsiString
  620. )
  621. {
  622. WCHAR *pw;
  623. SZ pa;
  624. pw = UnicodeString->Buffer;
  625. pa = AnsiString;
  626. while ( *pw != (WCHAR)0 ) {
  627. *pa++ = (CHAR)(*pw++);
  628. }
  629. *pa = '\0';
  630. }
  631. //
  632. // Get NT drive
  633. //
  634. CB
  635. GetNtDrive(
  636. IN RGSZ Args,
  637. IN USHORT cArgs,
  638. OUT SZ ReturnBuffer,
  639. IN CB cbReturnBuffer
  640. )
  641. {
  642. if ( GetNtDir( Args, cArgs, ReturnBuffer, cbReturnBuffer ) > 0 ) {
  643. ReturnBuffer[2] = '\0';
  644. return 3;
  645. }
  646. return 0;
  647. }
  648. #if i386
  649. //
  650. // Get NT Boot Info - I386 version
  651. //
  652. CB
  653. GetNtBootInfo(
  654. IN RGSZ Args,
  655. IN USHORT cArgs,
  656. OUT SZ ReturnBuffer,
  657. IN CB cbReturnBuffer
  658. )
  659. {
  660. #define BOOT_INI "C:\\BOOT.INI"
  661. #define MULTIBOOT_SCT "multiboot"
  662. #define FLEXBOOT_SCT "flexboot"
  663. #define OS_SCT "operating systems"
  664. #define TIMEOUT "timeout"
  665. #define DEFAULT "default"
  666. PTAGGEDFILE pBootTxt;
  667. PTFSECTION pSection;
  668. PTFKEYWORD pTimeout;
  669. PTFKEYWORD pDefault;
  670. PTFKEYWORD pKey;
  671. BOOL fOkay = fFalse;
  672. RGSZ rgszInfo;
  673. RGSZ rgszTmp;
  674. SZ sz;
  675. INT cCount = 3;
  676. Unused( Args );
  677. Unused( cArgs );
  678. Unused( cbReturnBuffer );
  679. rgszInfo = RgszAlloc(cCount);
  680. rgszTmp = RgszAlloc(3);
  681. if ( rgszInfo && rgszTmp ) {
  682. //
  683. // Get Boot.txt
  684. //
  685. if ( pBootTxt = GetTaggedFile( BOOT_INI ) ) {
  686. //
  687. // Get multiboot section
  688. //
  689. if ( ( pSection = GetSection( pBootTxt, MULTIBOOT_SCT )) ||
  690. ( pSection = GetSection( pBootTxt, FLEXBOOT_SCT ))
  691. ) {
  692. //
  693. // Get timeout and default
  694. //
  695. pTimeout = GetKeyword( pSection, TIMEOUT );
  696. pDefault = GetKeyword( pSection, DEFAULT );
  697. if ( pTimeout && pDefault ) {
  698. //
  699. // Get Operating systems section
  700. //
  701. if ( pSection = GetSection( pBootTxt, OS_SCT ) ) {
  702. rgszInfo[0] = SzDup( pTimeout->szValue );
  703. rgszInfo[1] = SzDup( pDefault->szValue );
  704. rgszInfo[2] = NULL;
  705. if ( rgszInfo[0] && rgszInfo[1] ) {
  706. fOkay = fTrue;
  707. pKey = NULL;
  708. while ( pKey = GetNextKeyword( pSection, pKey )) {
  709. rgszTmp[0] = pKey->szName;
  710. rgszTmp[1] = pKey->szValue;
  711. rgszTmp[2] = NULL;
  712. sz = SzListValueFromRgsz( rgszTmp );
  713. if ( !sz ||
  714. !RgszAdd( &rgszInfo, sz ) ) {
  715. fOkay = fFalse;
  716. if ( sz ) {
  717. SFree( sz );
  718. }
  719. break;
  720. }
  721. }
  722. }
  723. }
  724. }
  725. }
  726. CloseTaggedFile( pBootTxt );
  727. }
  728. }
  729. if ( fOkay ) {
  730. sz = SzListValueFromRgsz( rgszInfo );
  731. if ( sz ) {
  732. strcpy( ReturnBuffer, sz );
  733. SFree( sz );
  734. } else {
  735. fOkay = fFalse;
  736. }
  737. }
  738. if ( rgszTmp ) {
  739. rgszTmp[0] = NULL;
  740. RgszFree( rgszTmp );
  741. }
  742. if ( rgszInfo ) {
  743. RgszFreeCount( rgszInfo, cCount );
  744. }
  745. if ( fOkay ) {
  746. return lstrlen(ReturnBuffer)+1;
  747. } else {
  748. return 0;
  749. }
  750. }
  751. #else // if i386
  752. //
  753. // Get NT Boot Info - MIPS version
  754. //
  755. CB
  756. GetNtBootInfo(
  757. IN RGSZ Args,
  758. IN USHORT cArgs,
  759. OUT SZ ReturnBuffer,
  760. IN CB cbReturnBuffer
  761. )
  762. {
  763. //
  764. // BUGBUG ramonsa - For MIPS currently we fail
  765. //
  766. Unused( Args );
  767. Unused( cArgs );
  768. Unused( ReturnBuffer );
  769. Unused( cbReturnBuffer );
  770. return 0;
  771. }
  772. #endif // if i386
  773. //
  774. // Get value of an environment variable. Returns the value in list form. If the
  775. // value is a path (semicolon-separated components) each component is an element
  776. // of the list.
  777. //
  778. CB
  779. GetLoadedEnvVar(
  780. IN RGSZ Args,
  781. IN USHORT cArgs,
  782. OUT SZ ReturnBuffer,
  783. IN CB cbReturnBuffer
  784. )
  785. {
  786. CHAR EnvValue[ MAX_PATH ];
  787. SZ sz;
  788. Unused( cbReturnBuffer );
  789. ReturnBuffer[0] = '\0';
  790. if (cArgs > 0) {
  791. if ( GetEnvironmentVariable( Args[0], EnvValue, MAX_PATH ) == 0 ) {
  792. //
  793. // Env. Variable not defined, return empty list
  794. //
  795. #define UNDEF_VAR_VALUE "{}"
  796. lstrcpy( ReturnBuffer, UNDEF_VAR_VALUE );
  797. return lstrlen( ReturnBuffer )+1;
  798. } else if ( sz = SzListValueFromPath( EnvValue ) ) {
  799. lstrcpy( ReturnBuffer, sz );
  800. SFree( sz );
  801. return lstrlen( ReturnBuffer)+1;
  802. }
  803. }
  804. return 0;
  805. }
  806. CB
  807. IsUniprocessorSystem(
  808. IN RGSZ Args,
  809. IN USHORT cArgs,
  810. OUT SZ ReturnBuffer,
  811. IN CB cbReturnBuffer
  812. )
  813. {
  814. CHAR Value[256];
  815. HKEY hkey;
  816. LONG l;
  817. DWORD size;
  818. BOOL IsUp;
  819. SYSTEM_INFO SysInfo;
  820. Unused(Args);
  821. Unused(cArgs);
  822. Unused(cbReturnBuffer);
  823. ReturnBuffer[0] = 0;
  824. //
  825. // Look in the registry.
  826. //
  827. l = RegOpenKeyEx(
  828. HKEY_LOCAL_MACHINE,
  829. "Software\\Microsoft\\Windows NT\\CurrentVersion",
  830. 0,
  831. KEY_QUERY_VALUE,
  832. &hkey
  833. );
  834. if(l == NO_ERROR) {
  835. size = sizeof(Value);
  836. l = RegQueryValueEx(
  837. hkey,
  838. "CurrentType",
  839. NULL,
  840. NULL,
  841. Value,
  842. &size
  843. );
  844. RegCloseKey(hkey);
  845. }
  846. if(l == NO_ERROR) {
  847. //
  848. // It's UP if the string starts with Uni
  849. // and not Multi
  850. //
  851. IsUp = (Value[0] == 'U');
  852. } else {
  853. //
  854. // Registry didn't tell us for some reason; fall back on
  855. // the # of processors.
  856. //
  857. GetSystemInfo(&SysInfo);
  858. IsUp = (SysInfo.dwNumberOfProcessors == 1);
  859. }
  860. lstrcpy(ReturnBuffer,IsUp ? "YES" : "NO");
  861. return lstrlen(ReturnBuffer)+1;
  862. }