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.

1148 lines
32 KiB

  1. /*++
  2. Copyright (c) 1994 Microsoft Corporation
  3. Module Name:
  4. OSChecks.C
  5. Abstract:
  6. functions to used to determine the Operating System(s) installed
  7. on the current system.
  8. Author:
  9. Bob Watson (a-robw)
  10. Revision History:
  11. 23 Dec 94
  12. --*/
  13. #include <nt.h>
  14. #include <ntrtl.h>
  15. #include <nturtl.h>
  16. #include <windows.h>
  17. #include <stdlib.h>
  18. #include <stdio.h>
  19. #include <c2dll.h>
  20. #include <c2inc.h>
  21. #include <c2utils.h>
  22. #include <strings.h>
  23. #include "c2funcs.h"
  24. #include "c2funres.h"
  25. // define action codes here. They are only meaningful in the
  26. // context of this module.
  27. #define AC_NO_CHANGE 0
  28. #define AC_UPDATE 1
  29. //
  30. // for the action value, these are bits in a bit-mask used to
  31. // describe the action to take in the SET procedure
  32. //
  33. #define AV_DELETE_DOS 1
  34. #define AV_SET_TIMEOUT 2
  35. #define AV_SET_DEFAULT 4
  36. #define SECURE C2DLL_C2
  37. //
  38. // define local macros
  39. //
  40. #define MALLOC(size) (PVOID)LocalAlloc(LPTR,size)
  41. #define FREE(block) {LocalFree(block); block = NULL;}
  42. //
  43. // Unicode Specific macros
  44. //
  45. #if _UNICODE
  46. #define DriveLetterToArcPath(a) DriveLetterToArcPathW(a)
  47. #else // not unicode
  48. #define DriveLetterToArcPath(a) DriveLetterToArcPathA(a)
  49. #endif
  50. //
  51. // Leave as array because some code uses sizeof(ArcNameDirectory)
  52. //
  53. WCHAR ArcNameDirectory[] = L"\\ArcName";
  54. BOOL bTargetsDefined = FALSE;
  55. PWSTR DosDeviceTargets[24];
  56. //
  57. //
  58. // Helper macro to make object attribute initialization a little cleaner.
  59. //
  60. #define INIT_OBJA(Obja,UnicodeString,UnicodeText) \
  61. \
  62. RtlInitUnicodeString((UnicodeString),(UnicodeText)); \
  63. \
  64. InitializeObjectAttributes( \
  65. (Obja), \
  66. (UnicodeString), \
  67. OBJ_CASE_INSENSITIVE, \
  68. NULL, \
  69. NULL \
  70. )
  71. static
  72. BOOL
  73. IsIntelProcessor()
  74. {
  75. SYSTEM_INFO si;
  76. memset (&si, 0, sizeof(si));
  77. GetSystemInfo(&si);
  78. if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) {
  79. return TRUE;
  80. } else {
  81. return FALSE;
  82. }
  83. }
  84. static
  85. VOID
  86. DnConcatenatePaths(
  87. IN OUT PWSTR Path1,
  88. IN PWSTR Path2,
  89. IN DWORD BufferSizeBytes
  90. )
  91. {
  92. BOOL NeedBackslash = TRUE;
  93. DWORD l = lstrlenW(Path1);
  94. DWORD BufferSizeChars;
  95. BufferSizeChars = (BufferSizeBytes >= sizeof(WCHAR))
  96. ? ((BufferSizeBytes/sizeof(WCHAR))-1) // leave room for nul
  97. : 0;
  98. //
  99. // Determine whether we need to stick a backslash
  100. // between the components.
  101. //
  102. if(l && (Path1[l-1] == L'\\')) {
  103. NeedBackslash = FALSE;
  104. }
  105. if(*Path2 == L'\\') {
  106. if(NeedBackslash) {
  107. NeedBackslash = FALSE;
  108. } else {
  109. //
  110. // Not only do we not need a backslash, but we
  111. // need to eliminate one before concatenating.
  112. //
  113. Path2++;
  114. }
  115. }
  116. //
  117. // Append backslash if necessary and if it fits.
  118. //
  119. if(NeedBackslash && (l < BufferSizeChars)) {
  120. lstrcatW(Path1,L"\\");
  121. }
  122. //
  123. // Append second part of string to first part if it fits.
  124. //
  125. if(l+lstrlenW(Path2) < BufferSizeChars) {
  126. lstrcatW(Path1,Path2);
  127. }
  128. }
  129. static
  130. PWSTR
  131. DupString(
  132. IN PWSTR String
  133. )
  134. {
  135. PWSTR p;
  136. p = MALLOC((lstrlenW(String)+1)*sizeof(WCHAR));
  137. lstrcpyW(p,String);
  138. return(p);
  139. }
  140. static
  141. VOID
  142. InitDriveNameTranslations(
  143. VOID
  144. )
  145. {
  146. WCHAR DriveName[3];
  147. WCHAR Drive;
  148. WCHAR DriveRoot[4];
  149. WCHAR Buffer[512];
  150. DriveName[1] = L':';
  151. DriveName[2] = 0;
  152. DriveRoot[0] = L' ';
  153. DriveRoot[1] = L':';
  154. DriveRoot[2] = L'\\';
  155. DriveRoot[3] = 0;
  156. //
  157. // Calculate NT names for all local hard disks C-Z.
  158. //
  159. for(Drive=L'C'; Drive<=L'Z'; Drive++) {
  160. DosDeviceTargets[Drive-L'C'] = NULL;
  161. DriveRoot[0] = Drive;
  162. if(GetDriveTypeW(DriveRoot) == DRIVE_FIXED) {
  163. DriveName[0] = Drive;
  164. // BUGBUG: this could be a mem leak...
  165. if(QueryDosDeviceW(DriveName,Buffer,(sizeof(Buffer)/sizeof(WCHAR)))) {
  166. DosDeviceTargets[Drive-L'C'] = DupString(Buffer);
  167. }
  168. }
  169. }
  170. }
  171. static
  172. PWSTR
  173. DriveLetterToArcPathW(
  174. IN WCHAR DriveLetter
  175. )
  176. {
  177. UNICODE_STRING UnicodeString;
  178. HANDLE DirectoryHandle;
  179. HANDLE ObjectHandle;
  180. OBJECT_ATTRIBUTES Obja;
  181. NTSTATUS Status;
  182. BOOL RestartScan;
  183. DWORD Context;
  184. BOOL MoreEntries;
  185. PWSTR ArcName;
  186. UCHAR Buffer[1024];
  187. POBJECT_DIRECTORY_INFORMATION DirInfo = (POBJECT_DIRECTORY_INFORMATION)Buffer;
  188. PWSTR ArcPath;
  189. PWSTR NtPath;
  190. NtPath = DosDeviceTargets[towupper(DriveLetter) - L'C'];
  191. if(!NtPath) {
  192. return(NULL);
  193. }
  194. //
  195. // Assume failure.
  196. //
  197. ArcPath = NULL;
  198. //
  199. // Open the \ArcName directory.
  200. //
  201. INIT_OBJA(&Obja,&UnicodeString,ArcNameDirectory);
  202. Status = NtOpenDirectoryObject(&DirectoryHandle,DIRECTORY_QUERY,&Obja);
  203. if(NT_SUCCESS(Status)) {
  204. RestartScan = TRUE;
  205. Context = 0;
  206. MoreEntries = TRUE;
  207. do {
  208. Status = NtQueryDirectoryObject(
  209. (HANDLE)DirectoryHandle,
  210. (PVOID)&Buffer[0],
  211. (ULONG)sizeof(Buffer),
  212. (BOOLEAN)TRUE, // return single entry
  213. (BOOLEAN)RestartScan,
  214. (PULONG)&Context,
  215. (PULONG)NULL // return length
  216. );
  217. if(NT_SUCCESS(Status)) {
  218. _wcslwr(DirInfo->Name.Buffer);
  219. //
  220. // Make sure this name is a symbolic link.
  221. //
  222. if(DirInfo->Name.Length
  223. && (DirInfo->TypeName.Length >= (sizeof(L"SymbolicLink") - sizeof(WCHAR)))
  224. && !_wcsnicmp(DirInfo->TypeName.Buffer,L"SymbolicLink",12))
  225. {
  226. ArcName = MALLOC(DirInfo->Name.Length + sizeof(ArcNameDirectory) + sizeof(WCHAR));
  227. wcscpy(ArcName,ArcNameDirectory);
  228. DnConcatenatePaths(ArcName,DirInfo->Name.Buffer,(DWORD)(-1));
  229. //
  230. // We have the entire arc name in ArcName. Now open it as a symbolic link.
  231. //
  232. INIT_OBJA(&Obja,&UnicodeString,ArcName);
  233. Status = NtOpenSymbolicLinkObject(
  234. &ObjectHandle,
  235. READ_CONTROL | SYMBOLIC_LINK_QUERY,
  236. &Obja
  237. );
  238. if(NT_SUCCESS(Status)) {
  239. //
  240. // Finally, query the object to get the link target.
  241. //
  242. UnicodeString.Buffer = (PWSTR)Buffer;
  243. UnicodeString.Length = 0;
  244. UnicodeString.MaximumLength = sizeof(Buffer);
  245. Status = NtQuerySymbolicLinkObject(
  246. ObjectHandle,
  247. &UnicodeString,
  248. NULL
  249. );
  250. if(NT_SUCCESS(Status)) {
  251. //
  252. // nul-terminate the returned string
  253. //
  254. UnicodeString.Buffer[UnicodeString.Length/sizeof(WCHAR)] = 0;
  255. if(!_wcsicmp(UnicodeString.Buffer,NtPath)) {
  256. ArcPath = ArcName
  257. + (sizeof(ArcNameDirectory)/sizeof(WCHAR));
  258. }
  259. }
  260. NtClose(ObjectHandle);
  261. }
  262. if(!ArcPath) {
  263. FREE(ArcName);
  264. }
  265. }
  266. } else {
  267. MoreEntries = FALSE;
  268. if(Status == STATUS_NO_MORE_ENTRIES) {
  269. Status = STATUS_SUCCESS;
  270. }
  271. }
  272. RestartScan = FALSE;
  273. } while(MoreEntries && !ArcPath);
  274. NtClose(DirectoryHandle);
  275. }
  276. //
  277. // ArcPath points into thje middle of a buffer.
  278. // The caller needs to be able to free it, so place it in its
  279. // own buffer here.
  280. //
  281. if(ArcPath) {
  282. ArcPath = DupString(ArcPath);
  283. FREE(ArcName);
  284. }
  285. return(ArcPath);
  286. }
  287. static
  288. WCHAR
  289. ArcPathToDriveLetter(
  290. IN PWSTR ArcPath
  291. )
  292. {
  293. NTSTATUS Status;
  294. HANDLE ObjectHandle;
  295. OBJECT_ATTRIBUTES Obja;
  296. UNICODE_STRING UnicodeString;
  297. UCHAR Buffer[1024];
  298. WCHAR DriveLetter;
  299. WCHAR drive;
  300. PWSTR arcPath;
  301. //
  302. // Assume failure
  303. //
  304. DriveLetter = 0;
  305. arcPath = MALLOC(((wcslen(ArcPath)+1)*sizeof(WCHAR)) + sizeof(ArcNameDirectory));
  306. wcscpy(arcPath,ArcNameDirectory);
  307. wcscat(arcPath,L"\\");
  308. wcscat(arcPath,ArcPath);
  309. INIT_OBJA(&Obja,&UnicodeString,arcPath);
  310. Status = NtOpenSymbolicLinkObject(
  311. &ObjectHandle,
  312. READ_CONTROL | SYMBOLIC_LINK_QUERY,
  313. &Obja
  314. );
  315. if(NT_SUCCESS(Status)) {
  316. //
  317. // Query the object to get the link target.
  318. //
  319. UnicodeString.Buffer = (PWSTR)Buffer;
  320. UnicodeString.Length = 0;
  321. UnicodeString.MaximumLength = sizeof(Buffer);
  322. Status = NtQuerySymbolicLinkObject(
  323. ObjectHandle,
  324. &UnicodeString,
  325. NULL
  326. );
  327. if(NT_SUCCESS(Status)) {
  328. UnicodeString.Buffer[UnicodeString.Length/sizeof(WCHAR)] = 0;
  329. for(drive=L'C'; drive<=L'Z'; drive++) {
  330. if(DosDeviceTargets[drive-L'C']
  331. && !_wcsicmp(UnicodeString.Buffer,DosDeviceTargets[drive-L'C']))
  332. {
  333. DriveLetter = drive;
  334. break;
  335. }
  336. }
  337. }
  338. NtClose(ObjectHandle);
  339. }
  340. FREE(arcPath);
  341. return(DriveLetter);
  342. }
  343. static
  344. BOOL
  345. IsBootIniTimeoutZero (
  346. )
  347. {
  348. TCHAR szTimeOut[MAX_PATH];
  349. LONG lRetLen;
  350. LONG lTimeOut;
  351. lRetLen = GetPrivateProfileString (
  352. GetStringResource (GetDllInstance(), IDS_BOOT_LOADER_SECTION),
  353. GetStringResource (GetDllInstance(), IDS_TIMEOUT),
  354. cmszEmptyString,
  355. szTimeOut,
  356. MAX_PATH,
  357. GetStringResource (GetDllInstance(), IDS_BOOT_INI_PATH));
  358. if (lRetLen > 0) {
  359. lTimeOut = _tcstol (szTimeOut, NULL, 10);
  360. // note that 0 is returned if the string cannot be translated!
  361. if (lTimeOut > 0) {
  362. return FALSE;
  363. } else {
  364. return TRUE;
  365. }
  366. } else {
  367. // no time out string found
  368. return FALSE;
  369. }
  370. }
  371. static
  372. LPSTR
  373. DriveLetterToArcPathA (
  374. IN CHAR DriveLetter
  375. )
  376. {
  377. WCHAR wDriveLetter;
  378. PWSTR wszArcPath;
  379. LPSTR szArcPath;
  380. int nRetLen;
  381. wDriveLetter = (WCHAR)DriveLetter;
  382. wszArcPath = DriveLetterToArcPathW(wDriveLetter);
  383. if (wszArcPath != NULL) {
  384. // convert back to ASCII
  385. nRetLen = lstrlenW(wszArcPath);
  386. szArcPath = MALLOC (nRetLen+1);
  387. if (szArcPath != NULL) {
  388. wcstombs (szArcPath, wszArcPath, nRetLen);
  389. }
  390. } else {
  391. szArcPath = NULL;
  392. }
  393. return szArcPath;
  394. }
  395. static
  396. LONG
  397. GetArcWindowsPath (
  398. OUT LPTSTR szArcPath, // buffer to write path to
  399. IN DWORD dwChars // buffer length in chars
  400. )
  401. {
  402. TCHAR szDosWindowsDir[MAX_PATH];
  403. LPTSTR szArcWindowsDrive;
  404. DWORD dwBufReqd;
  405. if (szArcPath != NULL) {
  406. if (GetWindowsDirectory(szDosWindowsDir, MAX_PATH) > 0) {
  407. // convert Dos path to Arc Path
  408. szArcWindowsDrive = DriveLetterToArcPath(szDosWindowsDir[0]);
  409. if (szArcWindowsDrive != NULL) {
  410. // make sure there's room in the buffer
  411. dwBufReqd = lstrlen(szArcWindowsDrive) +
  412. lstrlen(&szDosWindowsDir[2]);
  413. if (dwBufReqd < dwChars) {
  414. // theres room so copy and
  415. // make full path
  416. lstrcpy (szArcPath, szArcWindowsDrive);
  417. lstrcat (szArcPath, &szDosWindowsDir[2]);
  418. } else {
  419. // insufficient room so return 0
  420. dwBufReqd = 0;
  421. *szArcPath = 0;
  422. }
  423. // release memory allocated by conversion
  424. FREE (szArcWindowsDrive);
  425. } else {
  426. // unable to convert drive to arc path so return 0
  427. dwBufReqd = 0;
  428. *szArcPath = 0;
  429. }
  430. } else {
  431. // unable to get current windows dir so return 0
  432. dwBufReqd = 0;
  433. *szArcPath = 0;
  434. }
  435. } else {
  436. // empty or null buffer passed so just return 0 len
  437. dwBufReqd = 0;
  438. }
  439. return (LONG)dwBufReqd;
  440. }
  441. static
  442. BOOL
  443. IsCurrentSystemDefault (
  444. )
  445. {
  446. TCHAR szArcWindowsDir[MAX_PATH*2];
  447. TCHAR szArcDefaultDir[MAX_PATH];
  448. LONG lStatus;
  449. BOOL bReturn;
  450. if (GetArcWindowsPath(szArcWindowsDir, MAX_PATH*2) > 0) {
  451. // get boot.ini default from [Boot Loader] section
  452. lStatus = GetPrivateProfileString (
  453. GetStringResource (GetDllInstance(), IDS_BOOT_LOADER_SECTION),
  454. GetStringResource (GetDllInstance(), IDS_DEFAULT_KEY),
  455. cszEmptyString,
  456. &szArcDefaultDir[0],
  457. MAX_PATH,
  458. GetStringResource (GetDllInstance(), IDS_BOOT_INI_FILENAME));
  459. if (lStatus > 0) {
  460. if (lstrcmpi (szArcDefaultDir, szArcWindowsDir) == 0) {
  461. // default is current system
  462. bReturn = TRUE;
  463. } else {
  464. // default is not current system
  465. bReturn = FALSE;
  466. }
  467. }
  468. } else {
  469. //unable to get windows dir
  470. bReturn = FALSE;
  471. }
  472. return bReturn;
  473. }
  474. static
  475. BOOL
  476. ZeroFileByName (
  477. IN LPCTSTR szFileName
  478. )
  479. {
  480. DWORD dwOldAttrib = 0;
  481. DWORD dwNewAttrib = 0;
  482. HANDLE hFile;
  483. BOOL bReturn = FALSE;
  484. if (FileExists (szFileName)) {
  485. // save the original attributes for later
  486. dwOldAttrib = GetFileAttributes (szFileName);
  487. // set file attributes on file to allow modification
  488. SetFileAttributes (szFileName, FILE_ATTRIBUTE_NORMAL);
  489. // make sure it went OK
  490. dwNewAttrib = GetFileAttributes (szFileName);
  491. if (dwNewAttrib == FILE_ATTRIBUTE_NORMAL) {
  492. hFile = CreateFile (
  493. szFileName,
  494. GENERIC_WRITE,
  495. 0L, // no sharing while this is done
  496. NULL, // no security
  497. TRUNCATE_EXISTING,
  498. FILE_ATTRIBUTE_NORMAL,
  499. NULL);
  500. if (hFile != INVALID_HANDLE_VALUE) {
  501. CloseHandle (hFile);
  502. bReturn = TRUE;
  503. }
  504. // reset the attributes
  505. SetFileAttributes (szFileName, dwOldAttrib);
  506. }
  507. } else {
  508. // file doesn't exist so it's already 0'd
  509. bReturn = TRUE;
  510. }
  511. return bReturn;
  512. }
  513. static
  514. BOOL
  515. DeleteDosFiles (
  516. )
  517. {
  518. BOOL bReturn;
  519. bReturn = ZeroFileByName (
  520. GetStringResource(GetDllInstance(), IDS_IO_SYS));
  521. if (bReturn) {
  522. bReturn = ZeroFileByName (
  523. GetStringResource(GetDllInstance(), IDS_MSDOS_SYS));
  524. }
  525. if (bReturn) {
  526. bReturn = ZeroFileByName (
  527. GetStringResource(GetDllInstance(), IDS_PCDOS_SYS));
  528. }
  529. return bReturn;
  530. }
  531. static
  532. BOOL
  533. SetBootIniTimeoutToZero (
  534. )
  535. {
  536. BOOL bReturn = TRUE;
  537. DWORD dwNewBootIniAttrib = 0;
  538. DWORD dwOrigBootIniAttrib = 0;
  539. // save the original attributes for later
  540. dwOrigBootIniAttrib = GetFileAttributes (
  541. GetStringResource (GetDllInstance(), IDS_BOOT_INI_FILENAME));
  542. // set file attributes on Boot.INI file
  543. SetFileAttributes (
  544. GetStringResource (GetDllInstance(), IDS_BOOT_INI_FILENAME),
  545. FILE_ATTRIBUTE_NORMAL);
  546. // make sure it went OK
  547. dwNewBootIniAttrib = GetFileAttributes (
  548. GetStringResource (GetDllInstance(), IDS_BOOT_INI_FILENAME));
  549. if (dwNewBootIniAttrib == FILE_ATTRIBUTE_NORMAL) {
  550. bReturn = WritePrivateProfileString (
  551. GetStringResource (GetDllInstance(), IDS_BOOT_LOADER_SECTION),
  552. GetStringResource (GetDllInstance(), IDS_TIMEOUT),
  553. GetStringResource (GetDllInstance(), IDS_0),
  554. GetStringResource (GetDllInstance(), IDS_BOOT_INI_PATH));
  555. // reset file attributes on Boot.INI file
  556. SetFileAttributes (
  557. GetStringResource (GetDllInstance(), IDS_BOOT_INI_FILENAME),
  558. dwOrigBootIniAttrib);
  559. return bReturn;
  560. } else {
  561. return FALSE;
  562. }
  563. }
  564. static
  565. BOOL
  566. SetBootDefaultToCurrentSystem (
  567. )
  568. {
  569. TCHAR szArcSystemPath[MAX_PATH*2];
  570. BOOL bReturn = TRUE;
  571. DWORD dwNewBootIniAttrib = 0;
  572. DWORD dwOrigBootIniAttrib = 0;
  573. // save the original attributes for later
  574. dwOrigBootIniAttrib = GetFileAttributes (
  575. GetStringResource (GetDllInstance(), IDS_BOOT_INI_FILENAME));
  576. // set file attributes on Boot.INI file
  577. SetFileAttributes (
  578. GetStringResource (GetDllInstance(), IDS_BOOT_INI_FILENAME),
  579. FILE_ATTRIBUTE_NORMAL);
  580. // make sure it went OK
  581. dwNewBootIniAttrib = GetFileAttributes (
  582. GetStringResource (GetDllInstance(), IDS_BOOT_INI_FILENAME));
  583. if (dwNewBootIniAttrib == FILE_ATTRIBUTE_NORMAL) {
  584. // file set OK so continue and get new path for ini
  585. if (GetArcWindowsPath(szArcSystemPath, MAX_PATH*2) > 0) {
  586. bReturn = WritePrivateProfileString (
  587. GetStringResource (GetDllInstance(), IDS_BOOT_LOADER_SECTION),
  588. GetStringResource (GetDllInstance(), IDS_DEFAULT_KEY),
  589. szArcSystemPath,
  590. GetStringResource (GetDllInstance(), IDS_BOOT_INI_PATH));
  591. // reset file attributes on Boot.INI file
  592. SetFileAttributes (
  593. GetStringResource (GetDllInstance(), IDS_BOOT_INI_FILENAME),
  594. dwOrigBootIniAttrib);
  595. }
  596. return bReturn;
  597. } else {
  598. return FALSE;
  599. }
  600. }
  601. static
  602. BOOL
  603. IsDosOnSystem (
  604. )
  605. {
  606. BOOL bFileFound;
  607. LPCTSTR szFileToCheck;
  608. szFileToCheck = GetStringResource(GetDllInstance(), IDS_IO_SYS);
  609. bFileFound = FileExists(szFileToCheck);
  610. if (bFileFound) {
  611. // check to see if it's really there
  612. if (GetFileSizeFromPath(szFileToCheck) == 0) {
  613. // just a name so reset flag
  614. bFileFound = FALSE;
  615. }
  616. }
  617. if (!bFileFound) {
  618. szFileToCheck = GetStringResource(GetDllInstance(), IDS_MSDOS_SYS);
  619. bFileFound = FileExists(szFileToCheck);
  620. if (bFileFound) {
  621. // check to see if it's really there
  622. if (GetFileSizeFromPath(szFileToCheck) == 0) {
  623. // just a name so reset flag
  624. bFileFound = FALSE;
  625. }
  626. }
  627. }
  628. if (!bFileFound) {
  629. szFileToCheck = GetStringResource(GetDllInstance(), IDS_PCDOS_SYS);
  630. bFileFound = FileExists(szFileToCheck);
  631. if (bFileFound) {
  632. // check to see if it's really there
  633. if (GetFileSizeFromPath(szFileToCheck) == 0) {
  634. // just a name so reset flag
  635. bFileFound = FALSE;
  636. }
  637. }
  638. }
  639. return bFileFound;
  640. }
  641. BOOL CALLBACK
  642. C2OpSysDlgProc(
  643. IN HWND hDlg, // window handle of the dialog box
  644. IN UINT message, // type of message
  645. IN WPARAM wParam,
  646. IN LPARAM lParam
  647. )
  648. /*++
  649. Routine Description:
  650. Window procedure for Operating System List Box
  651. Arguments:
  652. Standard DlgProc arguments
  653. ReturnValue:
  654. TRUE the message was handled by this routine
  655. FALSE DefDialogProc should handle the message
  656. --*/
  657. {
  658. LONG lItemCount = 0;
  659. static LPDWORD lpdwActionMask;
  660. DWORD dwAction;
  661. LONG lIndex;
  662. LONG lItems;
  663. switch (message) {
  664. case WM_INITDIALOG:
  665. // bail out here if an invalid param was passed
  666. if (lParam == 0) {
  667. EndDialog (hDlg, IDCANCEL);
  668. return FALSE;
  669. }
  670. // save pointer to param
  671. lpdwActionMask = (LPDWORD)lParam;
  672. // set the dialog box caption and static text
  673. SetDlgItemText (hDlg, IDC_TEXT,
  674. GetStringResource (GetDllInstance(), IDS_OS_DLG_TEXT));
  675. SetWindowText (hDlg,
  676. GetStringResource (GetDllInstance(), IDS_OS_CAPTION));
  677. // load list box with characteristics that are not C2
  678. if (IsDosOnSystem()) {
  679. lIndex = SendDlgItemMessage (hDlg, IDC_LIST_BOX,
  680. LB_ADDSTRING, 0,
  681. (LPARAM)GetStringResource (GetDllInstance(), IDS_DOS_ON_SYSTEM));
  682. if (lIndex != LB_ERR) {
  683. lItemCount++;
  684. SendDlgItemMessage (hDlg, IDC_LIST_BOX, LB_SETITEMDATA,
  685. (WPARAM)lIndex, (LPARAM)AV_DELETE_DOS);
  686. }
  687. }
  688. if (!IsBootIniTimeoutZero()) {
  689. lIndex = SendDlgItemMessage (hDlg, IDC_LIST_BOX,
  690. LB_ADDSTRING, 0,
  691. (LPARAM)GetStringResource (GetDllInstance(), IDS_TIMEOUT_NOT_ZERO));
  692. if (lIndex != LB_ERR) {
  693. lItemCount++;
  694. SendDlgItemMessage (hDlg, IDC_LIST_BOX, LB_SETITEMDATA,
  695. (WPARAM)lIndex, (LPARAM)AV_SET_TIMEOUT);
  696. }
  697. }
  698. // check for current system defined as default
  699. if (!IsCurrentSystemDefault()) {
  700. lIndex = SendDlgItemMessage (hDlg, IDC_LIST_BOX, LB_ADDSTRING, 0,
  701. (LPARAM)GetStringResource (GetDllInstance(), IDS_CURRENT_SYS_NOT_DEFAULT));
  702. if (lIndex != LB_ERR) {
  703. lItemCount++;
  704. SendDlgItemMessage (hDlg, IDC_LIST_BOX, LB_SETITEMDATA,
  705. (WPARAM)lIndex, (LPARAM)AV_SET_DEFAULT);
  706. }
  707. }
  708. SetFocus (GetDlgItem (hDlg, IDOK)); // set focus to OK Button
  709. return FALSE; // we don't want Windows to set the focus
  710. case WM_COMMAND:
  711. switch (LOWORD(wParam)){
  712. case IDC_C2:
  713. if (HIWORD(wParam) == BN_CLICKED) {
  714. // select all entries in the list box
  715. SendDlgItemMessage (hDlg, IDC_LIST_BOX,
  716. LB_SETSEL, TRUE, (LPARAM)-1);
  717. return TRUE;
  718. } else {
  719. return FALSE;
  720. }
  721. case IDOK:
  722. dwAction = 0;
  723. // scan through list box to see which Items are to be
  724. // changed (if any)
  725. lItems = SendDlgItemMessage (hDlg, IDC_LIST_BOX, LB_GETCOUNT,
  726. 0, 0);
  727. for (lIndex = 0; lIndex < lItems; lIndex++) {
  728. // if item is selected, then "or" it's value to the mask
  729. // i.e. set it's bit
  730. if (SendDlgItemMessage (hDlg, IDC_LIST_BOX, LB_GETSEL, (WPARAM)lIndex, 0) != 0) {
  731. dwAction |= (DWORD) SendDlgItemMessage (hDlg, IDC_LIST_BOX,
  732. LB_GETITEMDATA, (WPARAM)lIndex, 0);
  733. }
  734. }
  735. // update action value with flag bits
  736. *lpdwActionMask = dwAction;
  737. // fall through to next case
  738. case IDCANCEL:
  739. if (HIWORD(wParam) == BN_CLICKED) {
  740. // exit and return button that caused exit
  741. EndDialog (hDlg, (int)LOWORD(wParam));
  742. return TRUE;
  743. } else {
  744. return FALSE;
  745. }
  746. case IDC_HELP:
  747. PostMessage (GetParent(hDlg), UM_SHOW_CONTEXT_HELP, 0, 0);
  748. return TRUE;
  749. default:
  750. return FALSE;
  751. }
  752. default:
  753. return (FALSE); // Didn't process the message
  754. }
  755. }
  756. LONG
  757. C2QueryOpSystems (
  758. IN LPARAM lParam
  759. )
  760. /*++
  761. Routine Description:
  762. Function called to find out the operating system(s) installed
  763. on the system. For C2 compliance, ONLY Windows NT is
  764. allowed on the system.
  765. Arguments:
  766. Pointer to the Dll data block passed as an LPARAM.
  767. ReturnValue:
  768. ERROR_SUCCESS if the function succeeds otherwise a
  769. WIN32 error is returned if an error occurs
  770. --*/
  771. {
  772. PC2DLL_DATA pC2Data;
  773. if (lParam != 0) {
  774. SET_WAIT_CURSOR;
  775. if (!bTargetsDefined) {
  776. InitDriveNameTranslations();
  777. bTargetsDefined = TRUE;
  778. }
  779. pC2Data = (PC2DLL_DATA)lParam;
  780. pC2Data->lC2Compliance = SECURE; // assume true for now
  781. // check for DOS files found on system
  782. if (IsDosOnSystem()) {
  783. pC2Data->lC2Compliance = C2DLL_NOT_SECURE;
  784. lstrcpy (pC2Data->szStatusName,
  785. GetStringResource (GetDllInstance(), IDS_DOS_ON_SYSTEM));
  786. }
  787. // check for boot.ini timeout > 0
  788. if (pC2Data->lC2Compliance == SECURE) {
  789. if (!IsBootIniTimeoutZero()) {
  790. pC2Data->lC2Compliance = C2DLL_NOT_SECURE;
  791. lstrcpy (pC2Data->szStatusName,
  792. GetStringResource (GetDllInstance(), IDS_TIMEOUT_NOT_ZERO));
  793. }
  794. }
  795. // check for current system defined as default
  796. if (pC2Data->lC2Compliance == SECURE) {
  797. if (!IsCurrentSystemDefault()) {
  798. pC2Data->lC2Compliance = C2DLL_NOT_SECURE;
  799. lstrcpy (pC2Data->szStatusName,
  800. GetStringResource (GetDllInstance(), IDS_CURRENT_SYS_NOT_DEFAULT));
  801. }
  802. }
  803. if (pC2Data->lC2Compliance == SECURE) {
  804. lstrcpy (pC2Data->szStatusName,
  805. GetStringResource (GetDllInstance(), IDS_OS_OK));
  806. }
  807. SET_ARROW_CURSOR;
  808. } else {
  809. return ERROR_BAD_ARGUMENTS;
  810. }
  811. return ERROR_SUCCESS;
  812. }
  813. LONG
  814. C2SetOpSystems (
  815. IN LPARAM lParam
  816. )
  817. /*++
  818. Routine Description:
  819. Function called to change the current state of this configuration
  820. item based on an action code passed in the DLL data block. If
  821. this function successfully sets the state of the configuration
  822. item, then the C2 Compliance flag and the Status string to reflect
  823. the new value of the configuration item.
  824. Arguments:
  825. Pointer to the Dll data block passed as an LPARAM.
  826. ReturnValue:
  827. ERROR_SUCCESS if the function succeeds otherwise a
  828. WIN32 error is returned if an error occurs
  829. --*/
  830. {
  831. PC2DLL_DATA pC2Data;
  832. if (lParam != 0) {
  833. pC2Data = (PC2DLL_DATA)lParam;
  834. if ((pC2Data->lActionCode == AC_UPDATE) && (pC2Data->lActionValue != 0)) {
  835. SET_WAIT_CURSOR;
  836. if (pC2Data->lActionValue & AV_DELETE_DOS) {
  837. if (DisplayDllMessageBox (
  838. pC2Data->hWnd,
  839. IDS_OS_DELETE_DOS_FILES,
  840. IDS_OS_CAPTION,
  841. MBOKCANCEL_EXCLAIM | MB_DEFBUTTON2) == IDOK) {
  842. DeleteDosFiles();
  843. }
  844. }
  845. if (pC2Data->lActionValue & AV_SET_TIMEOUT) {
  846. if (IsIntelProcessor()) {
  847. if (DisplayDllMessageBox (
  848. pC2Data->hWnd,
  849. IDS_OS_ZERO_BOOT_TIMEOUT,
  850. IDS_OS_CAPTION,
  851. MBOKCANCEL_EXCLAIM | MB_DEFBUTTON2) == IDOK) {
  852. SetBootIniTimeoutToZero();
  853. }
  854. } else {
  855. DisplayDllMessageBox (
  856. pC2Data->hWnd,
  857. IDS_OS_RISC_BOOT_TIMEOUT,
  858. IDS_OS_CAPTION,
  859. MBOK_EXCLAIM);
  860. }
  861. }
  862. if (pC2Data->lActionValue & AV_SET_DEFAULT) {
  863. SetBootDefaultToCurrentSystem ();
  864. }
  865. // now check to see what happened
  866. pC2Data->lC2Compliance = SECURE; // assume true for now
  867. // check for DOS files found on system
  868. if (IsDosOnSystem()) {
  869. pC2Data->lC2Compliance = C2DLL_NOT_SECURE;
  870. lstrcpy (pC2Data->szStatusName,
  871. GetStringResource (GetDllInstance(), IDS_DOS_ON_SYSTEM));
  872. }
  873. // check for boot.ini timeout > 0
  874. if (pC2Data->lC2Compliance == SECURE) {
  875. if (!IsBootIniTimeoutZero()) {
  876. pC2Data->lC2Compliance = C2DLL_NOT_SECURE;
  877. lstrcpy (pC2Data->szStatusName,
  878. GetStringResource (GetDllInstance(), IDS_TIMEOUT_NOT_ZERO));
  879. }
  880. }
  881. // check for current system defined as default
  882. if (pC2Data->lC2Compliance == SECURE) {
  883. if (!IsCurrentSystemDefault()) {
  884. pC2Data->lC2Compliance = C2DLL_NOT_SECURE;
  885. lstrcpy (pC2Data->szStatusName,
  886. GetStringResource (GetDllInstance(), IDS_CURRENT_SYS_NOT_DEFAULT));
  887. }
  888. }
  889. if (pC2Data->lC2Compliance == SECURE) {
  890. lstrcpy (pC2Data->szStatusName,
  891. GetStringResource (GetDllInstance(), IDS_OS_OK));
  892. }
  893. SET_ARROW_CURSOR;
  894. }
  895. pC2Data->lActionCode = 0;
  896. } else {
  897. return ERROR_BAD_ARGUMENTS;
  898. }
  899. return ERROR_SUCCESS;
  900. }
  901. LONG
  902. C2DisplayOpSystems (
  903. IN LPARAM lParam
  904. )
  905. /*++
  906. Routine Description:
  907. Function called to display more information on the configuration
  908. item and provide the user with the option to change the current
  909. setting (if appropriate). If the User "OK's" out of the UI,
  910. then the action code field in the DLL data block is set to the
  911. appropriate (and configuration item-specific) action code so the
  912. "Set" function can be called to perform the desired action. If
  913. the user Cancels out of the UI, then the Action code field is
  914. set to 0 (no action) and no action is performed.
  915. Arguments:
  916. Pointer to the Dll data block passed as an LPARAM.
  917. ReturnValue:
  918. ERROR_SUCCESS if the function succeeds otherwise a
  919. WIN32 error is returned if an error occurs
  920. --*/
  921. {
  922. PC2DLL_DATA pC2Data;
  923. INT nDlgBoxReturn;
  924. LONG lDlgBoxParam;
  925. if (lParam != 0) {
  926. pC2Data = (PC2DLL_DATA)lParam;
  927. // check the C2 Compliance flag to see if the list box or
  928. // message box should be displayed
  929. if (pC2Data->lC2Compliance == SECURE) {
  930. // all volumes are OK so just pop a message box
  931. lDlgBoxParam = 0;
  932. DisplayDllMessageBox (
  933. pC2Data->hWnd,
  934. IDS_OS_OK,
  935. IDS_OS_CAPTION,
  936. MBOK_INFO);
  937. pC2Data->lActionCode = 0;
  938. pC2Data->lActionValue = 0;
  939. } else {
  940. //one or more volumes are not NTFS so display the list box
  941. // listing the ones that arent.
  942. nDlgBoxReturn = DialogBoxParam (
  943. GetDllInstance(),
  944. MAKEINTRESOURCE (IDD_LIST_DLG),
  945. pC2Data->hWnd,
  946. C2OpSysDlgProc,
  947. (LPARAM)&lDlgBoxParam);
  948. if (nDlgBoxReturn == IDOK) {
  949. pC2Data->lActionCode = 1;
  950. pC2Data->lActionValue = lDlgBoxParam;
  951. } else {
  952. pC2Data->lActionCode = 0;
  953. pC2Data->lActionValue = 0;
  954. }
  955. }
  956. } else {
  957. return ERROR_BAD_ARGUMENTS;
  958. }
  959. return ERROR_SUCCESS;
  960. }
  961.