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.

528 lines
18 KiB

  1. /*++
  2. Copyright (c) 1994 Microsoft Corporation
  3. Module Name:
  4. fschecks.c
  5. Abstract:
  6. function to check file systems installed on local disks
  7. for C2FUNCS.DLL
  8. Author:
  9. Bob Watson (a-robw)
  10. Revision History:
  11. 23 Dec 94
  12. --*/
  13. #include <windows.h>
  14. #include <tchar.h>
  15. #include <stdio.h>
  16. #include <c2dll.h>
  17. #include <c2inc.h>
  18. #include <c2utils.h>
  19. #include "c2funcs.h"
  20. #include "c2funres.h"
  21. #define AC_NO_CHANGE 0
  22. #define AC_UPDATE_FS 1
  23. #define SECURE C2DLL_C2
  24. static
  25. BOOL
  26. IsDriveSetToConvert (
  27. IN TCHAR cDrive
  28. )
  29. /*++
  30. Routine Description:
  31. checks to see if the specified drive is set to be converted
  32. to NTFS already by checking the session manager key for
  33. an existing entry.
  34. --*/
  35. {
  36. LONG lStatus;
  37. DWORD dwDataType;
  38. DWORD dwBufferBytes;
  39. HKEY hkeySessionManager;
  40. TCHAR mszBootExecuteString[SMALL_BUFFER_SIZE];
  41. BOOL bReturn;
  42. TCHAR szThisDriveCommand[MAX_PATH];
  43. LPTSTR szThisCommand;
  44. TCHAR szDriveLetter[4];
  45. lStatus = RegOpenKeyEx (
  46. HKEY_LOCAL_MACHINE,
  47. GetStringResource (GetDllInstance(), IDS_SESSION_MANAGER_KEY),
  48. 0L,
  49. KEY_READ,
  50. &hkeySessionManager);
  51. if (lStatus == ERROR_SUCCESS) {
  52. // registry key opened successfully
  53. dwBufferBytes = sizeof(mszBootExecuteString);
  54. memset (mszBootExecuteString, 0, dwBufferBytes);
  55. lStatus = RegQueryValueEx (
  56. hkeySessionManager,
  57. (LPTSTR)GetStringResource (GetDllInstance(), IDS_BOOT_EXECUTE_VALUE),
  58. NULL,
  59. &dwDataType,
  60. (LPBYTE)mszBootExecuteString,
  61. &dwBufferBytes);
  62. if (lStatus == ERROR_SUCCESS) {
  63. // load list box with volumes that are not using NTFS
  64. // initialize the root dir string
  65. szDriveLetter[0] = cDrive;
  66. szDriveLetter[1] = 0;
  67. _stprintf (szThisDriveCommand,
  68. GetStringResource (GetDllInstance(), IDS_AUTOCONV_CMD),
  69. szDriveLetter);
  70. bReturn = FALSE; // assume false until found
  71. for (szThisCommand = mszBootExecuteString;
  72. *szThisCommand != 0;
  73. szThisCommand += lstrlen(szThisCommand) + 1) {
  74. if (lstrcmpi (szThisCommand, szThisDriveCommand) == 0) {
  75. bReturn = TRUE;
  76. break; //out of for loop
  77. }
  78. }
  79. } else {
  80. // unable to read key so assume the drive is not specified
  81. bReturn = FALSE;
  82. }
  83. RegCloseKey (hkeySessionManager);
  84. }
  85. return bReturn;
  86. }
  87. BOOL CALLBACK
  88. C2FileSysDlgProc(
  89. IN HWND hDlg, // window handle of the dialog box
  90. IN UINT message, // type of message
  91. IN WPARAM wParam,
  92. IN LPARAM lParam
  93. )
  94. /*++
  95. Routine Description:
  96. Window procedure for FileSystem List Box
  97. Arguments:
  98. Standard DlgProc arguments
  99. ReturnValue:
  100. TRUE the message was handled by this routine
  101. FALSE DefDialogProc should handle the message
  102. --*/
  103. {
  104. static LPDWORD lpdwParam;
  105. TCHAR szRootDir[4];
  106. TCHAR szVolumeName[MAX_PATH];
  107. TCHAR szFileSystemName[MAX_PATH];
  108. DWORD dwVolumeSerialNumber;
  109. DWORD dwMaxComponentLength;
  110. DWORD dwFileSystemFlags;
  111. TCHAR szItemText[MAX_PATH];
  112. ULONG ulDriveBitMask;
  113. ULONG ulDriveIndex;
  114. LONG lIndex;
  115. LONG lListBoxItems;
  116. BOOL bConvert;
  117. switch (message) {
  118. case WM_INITDIALOG:
  119. lpdwParam = (LPDWORD)lParam;
  120. // set the dialog box caption and static text
  121. SetDlgItemText (hDlg, IDC_TEXT,
  122. GetStringResource (GetDllInstance(), IDS_FS_DLG_TEXT));
  123. SetWindowText (hDlg,
  124. GetStringResource (GetDllInstance(), IDS_FS_CAPTION));
  125. // load list box with volumes that are not using NTFS
  126. // initialize the root dir string
  127. szRootDir[0] = TEXT(' ');
  128. szRootDir[1] = TEXT(':');
  129. szRootDir[2] = TEXT('\\');
  130. szRootDir[3] = 0;
  131. for (szRootDir[0] = TEXT('A');szRootDir[0] <= TEXT('Z'); szRootDir[0]++) {
  132. // check each drive in the alphabet
  133. if (GetDriveType(szRootDir) == DRIVE_FIXED) {
  134. // only check fixed disk volumes
  135. if (GetVolumeInformation(szRootDir,
  136. szVolumeName, MAX_PATH,
  137. &dwVolumeSerialNumber,
  138. &dwMaxComponentLength,
  139. &dwFileSystemFlags,
  140. szFileSystemName, MAX_PATH)) {
  141. // volume information returned so see if it's NOT NTFS..
  142. if (lstrcmpi(szFileSystemName,
  143. GetStringResource (GetDllInstance(), IDS_NTFS)) != 0) {
  144. // it's not currently NTFS, but is it set to be converted?
  145. bConvert = IsDriveSetToConvert (szRootDir[0]);
  146. _stprintf (szItemText,
  147. GetStringResource (GetDllInstance(),
  148. (bConvert ? IDS_FS_CONVERT_FORMAT : IDS_FS_LIST_TEXT_FORMAT)),
  149. szRootDir,
  150. (bConvert ? GetStringResource (GetDllInstance(), IDS_NTFS) : szFileSystemName));
  151. lIndex = SendDlgItemMessage (hDlg, IDC_LIST_BOX,
  152. LB_INSERTSTRING, (WPARAM)-1, (LPARAM)szItemText);
  153. if (lIndex != LB_ERR) {
  154. // drive added to list so store the bit
  155. // that identifies the drive
  156. ulDriveIndex = (LONG)(szRootDir[0] - TEXT('A'));
  157. ulDriveBitMask = 1 << ulDriveIndex;
  158. SendDlgItemMessage (hDlg, IDC_LIST_BOX,
  159. LB_SETITEMDATA, (WPARAM)lIndex, (LPARAM)ulDriveBitMask);
  160. // if this drive is set to be converted then select it
  161. SendDlgItemMessage (hDlg, IDC_LIST_BOX,
  162. LB_SETSEL, (WPARAM)bConvert, (LPARAM)lIndex);
  163. }
  164. }
  165. } else {
  166. _stprintf (szItemText,
  167. GetStringResource (GetDllInstance(), IDS_ERR_LIST_TEXT_FORMAT),
  168. szRootDir);
  169. SendDlgItemMessage (hDlg, IDC_LIST_BOX, LB_ADDSTRING,
  170. 0, (LPARAM)szItemText);
  171. }
  172. } else {
  173. // not a fixed drive so ignore
  174. }
  175. } // end FOR each drive in the alphabet
  176. SetFocus (GetDlgItem (hDlg, IDOK)); // set focus to OK Button
  177. return FALSE; // we don't want Windows to set the focus
  178. case WM_COMMAND:
  179. switch (LOWORD(wParam)){
  180. case IDOK:
  181. if (HIWORD(wParam) == BN_CLICKED) {
  182. // exit and return button that caused exit
  183. // build a the bitmask of selected drives
  184. ulDriveBitMask = 0L; // clear bitmap field
  185. lListBoxItems = SendDlgItemMessage (hDlg, IDC_LIST_BOX,
  186. LB_GETCOUNT, 0, 0);
  187. for (lIndex = 0; lIndex < lListBoxItems; lIndex++) {
  188. if (SendDlgItemMessage (hDlg, IDC_LIST_BOX,
  189. LB_GETSEL, (WPARAM)lIndex, 0) > 0) {
  190. // then this disk is selected so get it's id
  191. // and add it to the bit map
  192. ulDriveIndex = SendDlgItemMessage (hDlg,
  193. IDC_LIST_BOX, LB_GETITEMDATA,
  194. (WPARAM)lIndex, 0);
  195. ulDriveBitMask |= ulDriveIndex;
  196. }
  197. }
  198. *lpdwParam = (DWORD)ulDriveBitMask;
  199. EndDialog (hDlg, (int)LOWORD(wParam));
  200. return TRUE;
  201. } else {
  202. return FALSE;
  203. }
  204. case IDCANCEL:
  205. if (HIWORD(wParam) == BN_CLICKED) {
  206. *lpdwParam = 0L;
  207. EndDialog (hDlg, (int)LOWORD(wParam));
  208. return TRUE;
  209. } else {
  210. return FALSE;
  211. }
  212. case IDC_C2:
  213. if (HIWORD(wParam) == BN_CLICKED) {
  214. // select all entries in the list box
  215. SendDlgItemMessage (hDlg, IDC_LIST_BOX,
  216. LB_SETSEL, TRUE, (LPARAM)-1);
  217. return TRUE;
  218. } else {
  219. return FALSE;
  220. }
  221. case IDC_HELP:
  222. PostMessage (GetParent(hDlg), UM_SHOW_CONTEXT_HELP, 0, 0);
  223. return TRUE;
  224. default:
  225. return FALSE;
  226. }
  227. default:
  228. return (FALSE); // Didn't process the message
  229. }
  230. }
  231. LONG
  232. C2QueryFileSystems (
  233. IN LPARAM lParam
  234. )
  235. /*++
  236. Routine Description:
  237. Checks file systems installed on all local volumes.
  238. For C2 compliance, All volumes must use the NTFS file system.
  239. Arguments:
  240. pointer to C2DLL data block passed as LPARAM
  241. ReturnValue:
  242. ERROR_SUCCESS if function completes successfully
  243. WIN32 error if not
  244. This function sets the C2Compliant flag as appropriate and
  245. sets the text of the status string for this item.
  246. --*/
  247. {
  248. PC2DLL_DATA pC2Data;
  249. LONG lFatVolumeCount;
  250. TCHAR szRootDir[4];
  251. TCHAR szVolumeName[MAX_PATH];
  252. TCHAR szFileSystemName[MAX_PATH];
  253. DWORD dwVolumeSerialNumber;
  254. DWORD dwMaxComponentLength;
  255. DWORD dwFileSystemFlags;
  256. if (lParam != 0) {
  257. pC2Data = (PC2DLL_DATA)lParam;
  258. SET_WAIT_CURSOR;
  259. // initialize the FAT file system volume counter
  260. lFatVolumeCount = 0;
  261. // initialize the root dir string
  262. szRootDir[0] = TEXT(' ');
  263. szRootDir[1] = TEXT(':');
  264. szRootDir[2] = TEXT('\\');
  265. szRootDir[3] = 0;
  266. for (szRootDir[0] = TEXT('A');szRootDir[0] <= TEXT('Z'); szRootDir[0]++) {
  267. // check each drive in the alphabet
  268. if (GetDriveType(szRootDir) == DRIVE_FIXED) {
  269. // only check fixed disk volumes
  270. if (GetVolumeInformation(szRootDir,
  271. szVolumeName, MAX_PATH,
  272. &dwVolumeSerialNumber,
  273. &dwMaxComponentLength,
  274. &dwFileSystemFlags,
  275. szFileSystemName, MAX_PATH)) {
  276. // volume information returned so see if it's NOT NTFS..
  277. if (lstrcmp(szFileSystemName,
  278. GetStringResource (GetDllInstance(), IDS_NTFS)) != 0) {
  279. lFatVolumeCount++;
  280. }
  281. } else {
  282. // unable to read the volume information so assume the
  283. // worst
  284. lFatVolumeCount++;
  285. }
  286. } else {
  287. // not a fixed drive so ignore
  288. }
  289. } // end FOR each drive in the alphabet
  290. // see how things turned out
  291. if (lFatVolumeCount > 0) {
  292. pC2Data->lC2Compliance = C2DLL_NOT_SECURE;
  293. _stprintf (pC2Data->szStatusName,
  294. GetStringResource (GetDllInstance(),
  295. (lFatVolumeCount == 1 ? IDS_NOT_C2_MESSAGE_FORMAT_1 : IDS_NOT_C2_MESSAGE_FORMAT)),
  296. lFatVolumeCount);
  297. } else {
  298. pC2Data->lC2Compliance = SECURE;
  299. _stprintf (pC2Data->szStatusName,
  300. GetStringResource (GetDllInstance(), IDS_C2_MESSAGE_FORMAT));
  301. }
  302. SET_ARROW_CURSOR;
  303. } else {
  304. return ERROR_BAD_ARGUMENTS;
  305. }
  306. return ERROR_SUCCESS;
  307. }
  308. LONG
  309. C2SetFileSystems (
  310. IN LPARAM lParam
  311. )
  312. {
  313. PC2DLL_DATA pC2Data;
  314. DWORD dwDriveFlag;
  315. TCHAR szDriveLetter[4];
  316. TCHAR szNewCmdBuffer[512];
  317. LPTSTR szNewCmd;
  318. DWORD dwNewCmdSize = 0;
  319. LONG lStatus = ERROR_SUCCESS;
  320. HKEY hkeySessionManager;
  321. BOOL bUpdateRegistry = FALSE;
  322. if (lParam != 0) {
  323. pC2Data = (PC2DLL_DATA)lParam;
  324. if (pC2Data->lActionCode == AC_UPDATE_FS) {
  325. // display "last change" message
  326. if (pC2Data->lActionValue != 0) {
  327. // display warning message if 1 or more drives
  328. // are set to be converted
  329. if (DisplayDllMessageBox (pC2Data->hWnd,
  330. IDS_FS_LAST_CHANCE,
  331. IDS_FS_CAPTION,
  332. MBOKCANCEL_QUESTION) == IDOK) {
  333. bUpdateRegistry = TRUE;
  334. } else {
  335. bUpdateRegistry = FALSE;
  336. }
  337. } else {
  338. // no drives are set to be converted so the
  339. // update will be to remove the conversion commands
  340. // from the registry. Since this is reverting the
  341. // system back to it's original state, no message is
  342. // necessary.
  343. bUpdateRegistry = TRUE;
  344. }
  345. if (bUpdateRegistry) {
  346. szDriveLetter[1] = 0;
  347. memset (szNewCmdBuffer, 0, sizeof(szNewCmdBuffer));
  348. szNewCmd = szNewCmdBuffer;
  349. // initialize with prefix command
  350. lstrcpy (szNewCmd,
  351. GetStringResource (GetDllInstance(), IDS_AUTOCHEK_CMD));
  352. szNewCmd += lstrlen(szNewCmd);
  353. *szNewCmd++ = 0;
  354. // loop through all possible DOS drive Letters until
  355. // there are no more in the ActionValue mask to convert
  356. // or the end of the DOS Drive alphabet is reached.
  357. //
  358. // The drive flag bits correspond to each possible drive
  359. // letter. e.g. bit 0 (0x00000001) = A:,
  360. // bit 2 (0x00000002) = B:, etc.
  361. //
  362. for (dwDriveFlag = 1, szDriveLetter[0] = TEXT('A');
  363. ((dwDriveFlag <= (DWORD)pC2Data->lActionValue) && (szDriveLetter[0] <= TEXT('Z')));
  364. dwDriveFlag <<= 1, szDriveLetter[0]++) {
  365. if ((dwDriveFlag & pC2Data->lActionValue) == dwDriveFlag) {
  366. _stprintf (szNewCmd,
  367. GetStringResource (GetDllInstance(), IDS_AUTOCONV_CMD),
  368. szDriveLetter);
  369. // terminate string and point to next
  370. // string in MSZ buffer
  371. szNewCmd += lstrlen(szNewCmd);
  372. *szNewCmd++ = 0;
  373. }
  374. } // end for each possible Drive Letter
  375. *szNewCmd++ = 0; // terminate MSZ buffer
  376. dwNewCmdSize = (DWORD)((LPBYTE)szNewCmd) -
  377. (DWORD)((LPBYTE)&szNewCmdBuffer[0]);
  378. // write new registry value so drives will be converted
  379. // when system restarts
  380. lStatus = RegOpenKeyEx (
  381. HKEY_LOCAL_MACHINE,
  382. GetStringResource (GetDllInstance(), IDS_SESSION_MANAGER_KEY),
  383. 0L,
  384. KEY_WRITE,
  385. &hkeySessionManager);
  386. if (lStatus == ERROR_SUCCESS) {
  387. // registry key opened successfully
  388. lStatus = RegSetValueEx (
  389. hkeySessionManager,
  390. GetStringResource (GetDllInstance(), IDS_BOOT_EXECUTE_VALUE),
  391. 0L,
  392. REG_MULTI_SZ,
  393. (LPBYTE)&szNewCmdBuffer[0],
  394. dwNewCmdSize);
  395. RegCloseKey (hkeySessionManager);
  396. } // end if Session Manager Key opened
  397. } // end if user really wants to do this
  398. } // end if user has clicked "OK" on display dialog
  399. pC2Data->lActionCode = AC_NO_CHANGE;
  400. pC2Data->lActionValue = 0;
  401. } else {
  402. lStatus = ERROR_BAD_ARGUMENTS;
  403. } // end if data structure found/not found
  404. return lStatus;
  405. }
  406. LONG
  407. C2DisplayFileSystems (
  408. IN LPARAM lParam
  409. )
  410. {
  411. PC2DLL_DATA pC2Data;
  412. DWORD dwDriveBitMask;
  413. int nDlgBoxReturn;
  414. if (lParam != 0) {
  415. pC2Data = (PC2DLL_DATA)lParam;
  416. // check the C2 Compliance flag to see if the list box or
  417. // message box should be displayed
  418. if (pC2Data->lC2Compliance == SECURE) {
  419. // all volumes are OK so just pop a message box
  420. DisplayDllMessageBox (
  421. pC2Data->hWnd,
  422. IDS_C2_DISPLAY_MESSAGE,
  423. IDS_FS_CAPTION,
  424. MBOK_INFO);
  425. pC2Data->lActionCode = AC_NO_CHANGE;
  426. } else {
  427. //one or more volumes are not NTFS so display the list box
  428. // listing the ones that arent.
  429. nDlgBoxReturn = DialogBoxParam (
  430. GetDllInstance(),
  431. MAKEINTRESOURCE (IDD_LIST_DLG),
  432. pC2Data->hWnd,
  433. C2FileSysDlgProc,
  434. (LPARAM)&dwDriveBitMask);
  435. if (nDlgBoxReturn == IDOK) {
  436. pC2Data->lActionCode = AC_UPDATE_FS;
  437. pC2Data->lActionValue = dwDriveBitMask;
  438. } else {
  439. pC2Data->lActionCode = AC_NO_CHANGE;
  440. pC2Data->lActionValue = 0;
  441. }
  442. }
  443. } else {
  444. return ERROR_BAD_ARGUMENTS;
  445. }
  446. return ERROR_SUCCESS;
  447. }