|
|
1.1.1.3 ! root 1: /* The source code contained in this file has been derived from the source code ! 2: of Encryption for the Masses 2.02a by Paul Le Roux. Modifications and ! 3: additions to that source code contained in this file are Copyright (c) 2004 ! 4: TrueCrypt Team and Copyright (c) 2004 TrueCrypt Foundation. Unmodified ! 5: parts are Copyright (c) 1998-99 Paul Le Roux. This is a TrueCrypt Foundation ! 6: release. Please see the file license.txt for full license details. */ 1.1 root 7: 8: #include "TCdefs.h" 9: 10: #include "crypto.h" 11: #include "fat.h" 12: #include "format.h" 13: #include "volumes.h" 14: #include "progress.h" 15: #include "apidrvr.h" 16: #include "dlgcode.h" 17: 1.1.1.3 ! root 18: ! 19: static int GetAvailableDrive () ! 20: { ! 21: DWORD dwUsedDrives = GetLogicalDrives(); ! 22: int i; ! 23: ! 24: for (i = 25; i > 2; i--) ! 25: { ! 26: if (!(dwUsedDrives & 1 << i)) ! 27: return i; ! 28: } ! 29: ! 30: return -1; ! 31: } ! 32: ! 33: static BOOL MountVolume (HWND hwndDlg, int driveNo, char *volumePath, char *szPassword) ! 34: { ! 35: extern HANDLE hDriver; ! 36: ! 37: MOUNT_STRUCT driver; ! 38: DWORD dwResult; ! 39: BOOL bResult, bDevice; ! 40: ! 41: VirtualLock (&driver, sizeof (driver)); ! 42: ! 43: driver.nDosDriveNo = driveNo; ! 44: driver.bCache = 0; ! 45: driver.time = 0; ! 46: driver.nPasswordLen = strlen (szPassword); ! 47: strcpy (driver.szPassword, szPassword); ! 48: ! 49: CreateFullVolumePath ((char *) driver.wszVolume, volumePath, &bDevice); ! 50: ToUNICODE ((char *) driver.wszVolume); ! 51: ! 52: bResult = DeviceIoControl (hDriver, MOUNT, &driver, ! 53: sizeof (driver), &driver, sizeof (driver), &dwResult, NULL); ! 54: ! 55: burn (&driver.szPassword, sizeof (driver.szPassword)); ! 56: ! 57: VirtualUnlock (&driver, sizeof (driver)); ! 58: ! 59: if (bResult == FALSE) ! 60: { ! 61: handleWin32Error (hwndDlg); ! 62: return FALSE; ! 63: } ! 64: else ! 65: { ! 66: if (driver.nReturnCode == 0) ! 67: { ! 68: if (nCurrentOS == WIN_NT) ! 69: { ! 70: char *lpszPipeName = "\\\\.\\pipe\\truecryptservice"; ! 71: DWORD bytesRead; ! 72: char inbuf[80]; ! 73: char outbuf[80]; ! 74: ! 75: sprintf (outbuf, "mount %d", driver.nDosDriveNo); ! 76: ! 77: bResult = CallNamedPipe (lpszPipeName, ! 78: outbuf, sizeof (outbuf), ! 79: inbuf, sizeof (inbuf), ! 80: &bytesRead, NMPWAIT_WAIT_FOREVER); ! 81: ! 82: if (bResult == FALSE) ! 83: { ! 84: handleWin32Error (hwndDlg); ! 85: } ! 86: else ! 87: { ! 88: DWORD os_err = 0; ! 89: int err = 0; ! 90: ! 91: sscanf (inbuf, "%s %d %lu", outbuf, &err, &os_err); ! 92: ! 93: if (*inbuf == '-') ! 94: { ! 95: if (err == ERR_OS_ERROR) ! 96: { ! 97: SetLastError (os_err); ! 98: handleWin32Error (hwndDlg); ! 99: } ! 100: else ! 101: { ! 102: handleError (hwndDlg, err); ! 103: } ! 104: ! 105: bResult = FALSE; ! 106: } ! 107: } ! 108: return bResult; ! 109: } ! 110: } ! 111: else ! 112: { ! 113: handleError (hwndDlg, driver.nReturnCode); ! 114: return FALSE; ! 115: } ! 116: } ! 117: ! 118: return TRUE; ! 119: } ! 120: 1.1 root 121: int 122: FormatVolume (char *lpszFilename, 123: BOOL bDevice, 1.1.1.3 ! root 124: char *volumePath, 1.1 root 125: unsigned __int64 size, 126: char *lpszPassword, 127: int cipher, 128: int pkcs5, 129: BOOL quickFormat, 1.1.1.3 ! root 130: int fileSystem, ! 131: int clusterSize, ! 132: char * summaryMsg, 1.1 root 133: HWND hwndDlg) 134: { 135: int nStatus; 136: PCRYPTO_INFO cryptoInfo; 137: void *dev = INVALID_HANDLE_VALUE; 138: OPEN_TEST_STRUCT driver; 139: DISKIO_STRUCT win9x_r0; 1.1.1.3 ! root 140: DWORD dwError, dwThen, dwNow; 1.1 root 141: diskio_f write; 1.1.1.3 ! root 142: char header[SECTOR_SIZE]; ! 143: __int64 num_sectors; ! 144: fatparams ft; ! 145: ! 146: size -= SECTOR_SIZE; // less the first TC sector ! 147: num_sectors = size / SECTOR_SIZE; 1.1 root 148: 1.1.1.3 ! root 149: if (fileSystem == FILESYS_FAT) 1.1 root 150: { 1.1.1.3 ! root 151: if (num_sectors > 0xFFFFffff) ! 152: return ERR_VOL_SIZE_WRONG; 1.1 root 153: 1.1.1.3 ! root 154: ft.num_sectors = (unsigned int) (num_sectors); ! 155: ft.cluster_size = clusterSize; ! 156: memcpy (ft.volume_name, " ", 11); ! 157: /* Calculate the fats, root dir etc, and update ft */ ! 158: GetFatParams (&ft); 1.1 root 159: } 160: 1.1.1.3 ! root 161: VirtualLock (header, sizeof (header)); 1.1 root 162: 1.1.1.3 ! root 163: /* Copies any header structures into header, but does not do any 1.1 root 164: disk io */ 1.1.1.3 ! root 165: nStatus = VolumeWriteHeader (header, 1.1 root 166: cipher, 167: lpszPassword, 168: pkcs5, 169: 0, 170: 0, 171: &cryptoInfo); 172: 173: if (nStatus != 0) 1.1.1.3 ! root 174: { ! 175: burn (header, sizeof (header)); ! 176: VirtualUnlock (header, sizeof (header)); 1.1 root 177: return nStatus; 1.1.1.3 ! root 178: } ! 179: ! 180: write = (diskio_f) _lwrite; ! 181: ! 182: if (bDevice == TRUE) ! 183: { ! 184: dev = CreateFile (lpszFilename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); ! 185: } ! 186: else ! 187: { ! 188: /* We could support FILE_ATTRIBUTE_HIDDEN as an ! 189: option! */ ! 190: dev = CreateFile (lpszFilename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); ! 191: } ! 192: ! 193: if (dev == INVALID_HANDLE_VALUE) ! 194: { ! 195: return ERR_OS_ERROR; ! 196: } 1.1 root 197: 198: KillTimer (hwndDlg, 0xff); 199: 1.1.1.3 ! root 200: InitProgressBar (num_sectors); ! 201: dwThen = GetTickCount (); 1.1.1.2 root 202: 1.1.1.3 ! root 203: switch (fileSystem) ! 204: { ! 205: case FILESYS_NONE: ! 206: case FILESYS_NTFS: ! 207: nStatus = FormatNoFs (num_sectors, header, (HFILE) dev, cryptoInfo, 1000, write, bDevice==TRUE ? quickFormat:FALSE); ! 208: break; ! 209: ! 210: case FILESYS_FAT: ! 211: /* This does the disk io, both copying out the header, init the ! 212: sectors, and writing the FAT tables etc */ ! 213: nStatus = FormatFat (&ft, header, (HFILE) dev, cryptoInfo, 1000, write, bDevice==TRUE ? quickFormat:FALSE); ! 214: break; ! 215: } 1.1 root 216: 1.1.1.3 ! root 217: dwNow = GetTickCount (); ! 218: ! 219: burn (header, sizeof (header)); ! 220: VirtualUnlock (header, sizeof (header)); 1.1 root 221: 222: crypto_close (cryptoInfo); 1.1.1.3 ! root 223: CloseHandle (dev); 1.1 root 224: 1.1.1.3 ! root 225: dwError = GetLastError(); 1.1 root 226: 227: if (nStatus!=0) 228: SetLastError(dwError); 1.1.1.3 ! root 229: else ! 230: { ! 231: switch (fileSystem) ! 232: { ! 233: case FILESYS_NONE: ! 234: sprintf (summaryMsg, "Volume size:\t\t%I64d sectors (%I64d MB)\nFile system:\t\tNone" ! 235: "\n\nFormatting took %lu seconds." ! 236: , num_sectors, num_sectors*512/1024/1024 ! 237: , (dwNow - dwThen)/1000); ! 238: break; ! 239: ! 240: case FILESYS_FAT: ! 241: sprintf (summaryMsg, ! 242: "Volume size:\t\t%d sectors (%I64d MB)\nFile system:\t\tFAT%d\n" ! 243: "FAT size:\t\t%d bytes\nCluster size:\t\t%d bytes\nClusters available:\t%d" ! 244: "\n\nFormatting took %lu seconds." ! 245: , ft.num_sectors, ((__int64) ft.num_sectors*512)/1024/1024, ft.size_fat ! 246: , (int) (512*ft.fats*ft.fat_length), ! 247: (int) (512*ft.cluster_size), ft.cluster_count, ! 248: (dwNow - dwThen)/1000); ! 249: break; ! 250: ! 251: case FILESYS_NTFS: ! 252: { ! 253: int driveNo = GetAvailableDrive (); ! 254: DWORD os_error; ! 255: int err; ! 256: ! 257: if (driveNo == -1) ! 258: { ! 259: MessageBox (hwndDlg, "No free drives available. NTFS formatting cannot continue.", lpszTitle, ICON_HAND); ! 260: return ERR_NO_FREE_DRIVES; ! 261: } ! 262: ! 263: if (!MountVolume (hwndDlg, driveNo, volumePath, lpszPassword)) ! 264: { ! 265: MessageBox (hwndDlg, "Cannot mount volume. NTFS formatting cannot continue.", lpszTitle, ICON_HAND); ! 266: return ERR_VOL_MOUNT_FAILED; ! 267: } ! 268: ! 269: if (!FormatNtfs (driveNo, clusterSize)) ! 270: { ! 271: MessageBox (hwndDlg, "NTFS formatting failed. Try using FAT filesystem.", lpszTitle, MB_ICONERROR); ! 272: UnmountVolume (driveNo, &os_error, &err); ! 273: return ERR_VOL_FORMAT_BAD; ! 274: } ! 275: ! 276: UnmountVolume (driveNo, &os_error, &err); ! 277: ! 278: dwNow = GetTickCount (); ! 279: ! 280: sprintf (summaryMsg, "Volume size:\t\t%I64d sectors (%I64d MB)\nFile system:\t\tNTFS" ! 281: "\n\nFormatting took %lu seconds." ! 282: , num_sectors, num_sectors*512/1024/1024 ! 283: , (dwNow - dwThen)/1000); ! 284: ! 285: break; ! 286: } ! 287: } ! 288: } ! 289: ! 290: NormalCursor (); ! 291: 1.1 root 292: return nStatus; 1.1.1.3 ! root 293: } 1.1 root 294: 1.1.1.3 ! root 295: ! 296: int FormatNoFs (__int64 num_sectors, char *header, HFILE dev, PCRYPTO_INFO cryptoInfo, int nFrequency, diskio_f write, BOOL quickFormat) ! 297: { ! 298: int write_buf_cnt = 0; ! 299: char sector[SECTOR_SIZE], *write_buf; ! 300: int progress = 0; ! 301: unsigned __int64 nSecNo = 1; ! 302: ! 303: if ((*write) (dev, header, SECTOR_SIZE) == HFILE_ERROR) ! 304: return ERR_OS_ERROR; ! 305: ! 306: write_buf = TCalloc (WRITE_BUF_SIZE); ! 307: ! 308: memset (sector, 0, sizeof (sector)); ! 309: ! 310: /* write data area */ ! 311: if(!quickFormat) ! 312: { ! 313: while (num_sectors--) ! 314: { ! 315: if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo, &progress, ! 316: cryptoInfo, nFrequency, write) == FALSE) ! 317: goto fail; ! 318: } ! 319: if (write_buf_cnt != 0 && (*write) (dev, write_buf, write_buf_cnt) == HFILE_ERROR) ! 320: goto fail; ! 321: } ! 322: else ! 323: nSecNo = num_sectors; ! 324: ! 325: UpdateProgressBar (nSecNo); ! 326: ! 327: TCfree (write_buf); ! 328: return 0; ! 329: ! 330: fail: ! 331: ! 332: TCfree (write_buf); ! 333: return ERR_OS_ERROR; 1.1 root 334: } 1.1.1.3 ! root 335: ! 336: ! 337: volatile BOOLEAN FormatExResult; ! 338: ! 339: BOOLEAN __stdcall FormatExCallback (int command, DWORD subCommand, PVOID parameter) ! 340: { ! 341: if (command == FMIFS_DONE) ! 342: FormatExResult = *(BOOLEAN *) parameter; ! 343: return TRUE; ! 344: } ! 345: ! 346: BOOL FormatNtfs (int driveNo, int clusterSize) ! 347: { ! 348: WCHAR dir[8] = { driveNo + 'A', 0 }; ! 349: PFORMATEX FormatEx; ! 350: HMODULE hModule = LoadLibrary ("fmifs.dll"); ! 351: ! 352: if (hModule == NULL) ! 353: return FALSE; ! 354: ! 355: if (!(FormatEx = (void *) GetProcAddress (GetModuleHandle("fmifs.dll"), "FormatEx"))) ! 356: { ! 357: FreeLibrary (hModule); ! 358: return FALSE; ! 359: } ! 360: ! 361: wcscat (dir, L":\\"); ! 362: ! 363: FormatExResult = FALSE; ! 364: ! 365: if (*(char *)dir > 'C' && *(char *)dir <= 'Z') ! 366: FormatEx (dir, FMIFS_HARDDISK, L"NTFS", L"", TRUE, clusterSize * 512, FormatExCallback); ! 367: ! 368: FreeLibrary (hModule); ! 369: return FormatExResult; ! 370: } ! 371: ! 372: BOOL ! 373: WriteSector (HFILE dev, char *sector, ! 374: char *write_buf, int *write_buf_cnt, ! 375: __int64 *nSecNo, int *progress, PCRYPTO_INFO cryptoInfo, ! 376: int nFrequency, diskio_f write) ! 377: { ! 378: (*cryptoInfo->encrypt_sector) ((unsigned long *) sector, ! 379: (*nSecNo)++, 1, cryptoInfo->ks, cryptoInfo->iv, cryptoInfo->cipher); ! 380: memcpy (write_buf + *write_buf_cnt, sector, SECTOR_SIZE); ! 381: (*write_buf_cnt) += SECTOR_SIZE; ! 382: ! 383: ! 384: if (*write_buf_cnt == WRITE_BUF_SIZE) ! 385: { ! 386: if ((*write) (dev, write_buf, WRITE_BUF_SIZE) == HFILE_ERROR) ! 387: return FALSE; ! 388: else ! 389: *write_buf_cnt = 0; ! 390: } ! 391: ! 392: if (++(*progress) == nFrequency) ! 393: { ! 394: if (UpdateProgressBar (*nSecNo) == TRUE) ! 395: return FALSE; ! 396: *progress = 0; ! 397: } ! 398: ! 399: return TRUE; ! 400: ! 401: } ! 402: ! 403: ! 404:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.