|
|
1.1.1.10 root 1: /*
2: Legal Notice: The source code contained in this file has been derived from
3: the source code of Encryption for the Masses 2.02a, which is Copyright (c)
4: Paul Le Roux and which is covered by the 'License Agreement for Encryption
5: for the Masses'. Modifications and additions to that source code contained
6: in this file are Copyright (c) TrueCrypt Foundation and are covered by the
1.1.1.11! root 7: TrueCrypt License 2.3 the full text of which is contained in the file
1.1.1.10 root 8: License.txt included in TrueCrypt binary and source code distribution
9: packages. */
10:
11: #include <stdlib.h>
12: #include <string.h>
1.1.1.6 root 13:
14: #include "Tcdefs.h"
15:
1.1.1.9 root 16: #include "Common.h"
1.1.1.6 root 17: #include "Crypto.h"
18: #include "Fat.h"
19: #include "Format.h"
1.1.1.9 root 20: #include "Random.h"
1.1.1.6 root 21: #include "Volumes.h"
1.1.1.8 root 22:
23: #ifdef _WIN32
1.1.1.6 root 24: #include "Apidrvr.h"
25: #include "Dlgcode.h"
26: #include "Language.h"
1.1.1.8 root 27: #include "Progress.h"
1.1.1.6 root 28: #include "Resource.h"
1.1.1.10 root 29: #include "../Format/FormatCom.h"
1.1.1.3 root 30:
1.1 root 31: int
1.1.1.10 root 32: FormatVolume (char *volumePath,
1.1 root 33: BOOL bDevice,
34: unsigned __int64 size,
1.1.1.4 root 35: unsigned __int64 hiddenVolHostSize,
1.1.1.6 root 36: Password *password,
1.1.1.7 root 37: int ea,
1.1 root 38: int pkcs5,
39: BOOL quickFormat,
1.1.1.8 root 40: BOOL sparseFileSwitch,
1.1.1.3 root 41: int fileSystem,
42: int clusterSize,
1.1.1.4 root 43: HWND hwndDlg,
44: BOOL hiddenVol,
1.1.1.10 root 45: int *realClusterSize,
46: BOOL uac)
1.1 root 47: {
48: int nStatus;
49: PCRYPTO_INFO cryptoInfo;
1.1.1.4 root 50: HANDLE dev = INVALID_HANDLE_VALUE;
1.1.1.10 root 51: DWORD dwError;
52: char header[HEADER_SIZE];
1.1.1.4 root 53: unsigned __int64 num_sectors, startSector;
1.1.1.3 root 54: fatparams ft;
1.1.1.4 root 55: FILETIME ftCreationTime;
56: FILETIME ftLastWriteTime;
57: FILETIME ftLastAccessTime;
58: BOOL bTimeStampValid = FALSE;
1.1.1.10 root 59: char dosDev[TC_MAX_PATH] = { 0 };
60: char devName[MAX_PATH] = { 0 };
61: int driveLetter = -1;
62: WCHAR deviceName[MAX_PATH];
63:
1.1.1.4 root 64: if (!hiddenVol)
65: size -= HEADER_SIZE;
1.1 root 66:
1.1.1.4 root 67: num_sectors = size / SECTOR_SIZE;
1.1.1.10 root 68:
69: if (bDevice)
70: {
71: strcpy ((char *)deviceName, volumePath);
72: ToUNICODE ((char *)deviceName);
73:
74: driveLetter = GetDiskDeviceDriveLetter (deviceName);
75: }
76:
1.1.1.3 root 77: VirtualLock (header, sizeof (header));
1.1 root 78:
1.1.1.3 root 79: /* Copies any header structures into header, but does not do any
1.1 root 80: disk io */
1.1.1.3 root 81: nStatus = VolumeWriteHeader (header,
1.1.1.7 root 82: ea,
83: LRW, // The only supported mode of operation when creating new volumes
1.1.1.6 root 84: password,
1.1 root 85: pkcs5,
86: 0,
87: 0,
1.1.1.4 root 88: &cryptoInfo,
1.1.1.6 root 89: hiddenVol ? size : 0,
90: FALSE);
1.1 root 91:
92: if (nStatus != 0)
1.1.1.3 root 93: {
94: burn (header, sizeof (header));
95: VirtualUnlock (header, sizeof (header));
1.1 root 96: return nStatus;
1.1.1.3 root 97: }
98:
1.1.1.6 root 99: if (bDevice)
1.1.1.3 root 100: {
1.1.1.10 root 101: /* Device-hosted volume */
1.1.1.11! root 102: DWORD dwResult;
1.1.1.10 root 103: int nPass;
104:
105: if (FakeDosNameForDevice (volumePath, dosDev, devName, FALSE) != 0)
1.1.1.4 root 106: {
1.1.1.10 root 107: handleWin32Error (hwndDlg);
108: return ERR_DONT_REPORT;
109: }
110:
111: if (IsDeviceMounted (devName))
112: {
113: if ((dev = DismountDrive (devName)) == INVALID_HANDLE_VALUE)
1.1.1.4 root 114: {
1.1.1.11! root 115: Error ("FORMAT_CANT_DISMOUNT_FILESYS");
! 116: nStatus = ERR_DONT_REPORT;
! 117: goto error;
1.1.1.10 root 118: }
119: }
120: else if (nCurrentOS == WIN_VISTA_OR_LATER && driveLetter == -1)
121: {
122: // Windows Vista doesn't allow overwriting sectors belonging to an unformatted partition
123: // to which no drive letter has been assigned under the system. This problem can be worked
124: // around by assigning a drive letter to the partition temporarily.
125:
126: char szDriveLetter[] = { 'A', ':', 0 };
127: char rootPath[] = { 'A', ':', '\\', 0 };
128: char uniqVolName[MAX_PATH+1] = { 0 };
129: int tmpDriveLetter = -1;
130: BOOL bResult = FALSE;
131:
132: tmpDriveLetter = GetFirstAvailableDrive ();
133:
134: if (tmpDriveLetter != -1)
135: {
136: rootPath[0] += tmpDriveLetter;
137: szDriveLetter[0] += tmpDriveLetter;
138:
139: if (DefineDosDevice (DDD_RAW_TARGET_PATH, szDriveLetter, volumePath))
140: {
141: bResult = GetVolumeNameForVolumeMountPoint (rootPath, uniqVolName, MAX_PATH);
142:
143: DefineDosDevice (DDD_RAW_TARGET_PATH|DDD_REMOVE_DEFINITION|DDD_EXACT_MATCH_ON_REMOVE,
144: szDriveLetter,
145: volumePath);
146:
147: if (bResult
148: && SetVolumeMountPoint (rootPath, uniqVolName))
149: {
150: // The drive letter can be removed immediately
151: DeleteVolumeMountPoint (rootPath);
152: }
153: }
154: }
155: }
156:
157: // Perform open - 'quick format' - close - open to prevent Windows from restoring NTFS boot sector backup
158: for (nPass = 0; nPass < 2; nPass++)
159: {
160: // Try exclusive access mode first
161: if (dev == INVALID_HANDLE_VALUE)
162: dev = CreateFile (devName, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
163:
164: if (dev == INVALID_HANDLE_VALUE)
165: {
166: // Retry in shared mode
167: dev = CreateFile (devName, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
168: if (dev != INVALID_HANDLE_VALUE)
169: {
170: if (IDNO == MessageBoxW (hwndDlg, GetString ("DEVICE_IN_USE_FORMAT"), lpszTitle, MB_YESNO|MB_ICONWARNING|MB_DEFBUTTON2))
171: {
172: nStatus = ERR_DONT_REPORT;
173: goto error;
174: }
175: }
176: else
177: {
178: handleWin32Error (hwndDlg);
179: nStatus = ERR_DONT_REPORT;
180: goto error;
181: }
182: }
183:
184: if (hiddenVol)
185: break; // The following "quick format" operation would damage the outer volume
186:
187: if (nPass == 0)
188: {
189: char buf[65536];
190: DWORD bw;
191:
192: // Pseudo "quick format" to prevent Windows from restoring NTFS boot sector backup
193: memset (buf, 0, sizeof (buf));
194: WriteFile (dev, buf, sizeof (buf), &bw, NULL);
195: FlushFileBuffers (dev);
196: CloseHandle (dev);
197: dev = INVALID_HANDLE_VALUE;
1.1.1.4 root 198: }
199: }
1.1.1.11! root 200:
! 201: if (DeviceIoControl (dev, FSCTL_IS_VOLUME_MOUNTED, NULL, 0, NULL, 0, &dwResult, NULL))
! 202: {
! 203: Error ("FORMAT_CANT_DISMOUNT_FILESYS");
! 204: nStatus = ERR_DONT_REPORT;
! 205: goto error;
! 206: }
1.1.1.3 root 207: }
208: else
209: {
1.1.1.10 root 210: /* File-hosted volume */
211:
1.1.1.4 root 212: // We could support FILE_ATTRIBUTE_HIDDEN as an option
213: // (Now if the container has hidden or system file attribute, the OS will not allow
214: // overwritting it; so the user will have to delete it manually).
1.1.1.10 root 215: dev = CreateFile (volumePath, GENERIC_WRITE,
1.1.1.4 root 216: hiddenVol ? (FILE_SHARE_READ | FILE_SHARE_WRITE) : 0,
217: NULL, hiddenVol ? OPEN_EXISTING : CREATE_ALWAYS, 0, NULL);
1.1.1.6 root 218:
1.1.1.8 root 219: if (dev == INVALID_HANDLE_VALUE)
220: {
221: handleWin32Error (hwndDlg);
1.1.1.10 root 222: nStatus = ERR_DONT_REPORT;
1.1.1.8 root 223: goto error;
224: }
225:
1.1.1.6 root 226: if (!hiddenVol)
227: {
228: LARGE_INTEGER volumeSize;
1.1.1.8 root 229: volumeSize.QuadPart = size + HEADER_SIZE;
1.1.1.6 root 230:
1.1.1.8 root 231: if (sparseFileSwitch && quickFormat)
232: {
233: // Create as sparse file container
234: DWORD tmp;
235: if (!DeviceIoControl (dev, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, &tmp, NULL))
236: {
237: handleWin32Error (hwndDlg);
1.1.1.10 root 238: nStatus = ERR_DONT_REPORT;
1.1.1.8 root 239: goto error;
240: }
241: }
242:
243: // Preallocate the file
1.1.1.6 root 244: if (!SetFilePointerEx (dev, volumeSize, NULL, FILE_BEGIN)
245: || !SetEndOfFile (dev)
246: || SetFilePointer (dev, 0, NULL, FILE_BEGIN) != 0)
247: {
248: handleWin32Error (hwndDlg);
1.1.1.10 root 249: nStatus = ERR_DONT_REPORT;
1.1.1.7 root 250: goto error;
1.1.1.6 root 251: }
252: }
1.1.1.3 root 253: }
254:
1.1.1.6 root 255: if (hiddenVol && !bDevice && bPreserveTimestamp)
1.1.1.4 root 256: {
257: /* Remember the container timestamp (used to reset file date and time of file-hosted
258: containers to preserve plausible deniability of hidden volume) */
259: if (GetFileTime ((HANDLE) dev, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime) == 0)
260: {
261: bTimeStampValid = FALSE;
1.1.1.6 root 262: MessageBoxW (hwndDlg, GetString ("GETFILETIME_FAILED_IMPLANT"), lpszTitle, MB_OK | MB_ICONEXCLAMATION);
1.1.1.4 root 263: }
264: else
265: bTimeStampValid = TRUE;
1.1.1.3 root 266: }
1.1 root 267:
268: KillTimer (hwndDlg, 0xff);
269:
1.1.1.6 root 270: /* Volume header */
1.1.1.4 root 271:
272: // Hidden volume setup
273: if (hiddenVol)
274: {
275: // Check hidden volume size
276: if (hiddenVolHostSize < MIN_HIDDEN_VOLUME_HOST_SIZE || hiddenVolHostSize > MAX_HIDDEN_VOLUME_HOST_SIZE)
277: {
1.1.1.7 root 278: nStatus = ERR_VOL_SIZE_WRONG;
279: goto error;
1.1.1.4 root 280: }
281:
282: // Seek to hidden volume header location
283: if (!SeekHiddenVolHeader ((HFILE) dev, hiddenVolHostSize, bDevice))
284: {
1.1.1.7 root 285: nStatus = ERR_VOL_SEEKING;
286: goto error;
1.1.1.4 root 287: }
288:
289: }
290:
291: // Write the volume header
1.1.1.8 root 292: if (_lwrite ((HFILE) dev, header, HEADER_SIZE) == HFILE_ERROR)
1.1.1.10 root 293: {
294: handleWin32Error (hwndDlg);
295: nStatus = ERR_DONT_REPORT;
296: goto error;
297: }
1.1.1.4 root 298:
1.1.1.6 root 299: /* Data area */
1.1.1.4 root 300:
1.1.1.10 root 301: startSector = HEADER_SIZE / SECTOR_SIZE; // Data area of normal volume starts right after volume header
1.1.1.4 root 302:
303: if (hiddenVol)
304: {
305: // Calculate data area position of hidden volume
306: unsigned __int64 startOffset = hiddenVolHostSize - size - HIDDEN_VOL_HEADER_OFFSET;
1.1.1.7 root 307: cryptoInfo->hiddenVolumeOffset = startOffset;
1.1.1.4 root 308:
309: // Validate the offset
310: if (startOffset % SECTOR_SIZE != 0)
311: {
1.1.1.6 root 312: nStatus = ERR_VOL_SIZE_WRONG;
313: goto error;
1.1.1.4 root 314: }
315:
316: startSector = startOffset / SECTOR_SIZE;
317: quickFormat = TRUE; // To entirely format a hidden volume would be redundant
318: }
319:
320: // Format filesystem
321:
1.1.1.3 root 322: switch (fileSystem)
323: {
324: case FILESYS_NONE:
1.1.1.10 root 325: case FILESYS_NTFS:
1.1.1.8 root 326: nStatus = FormatNoFs (startSector, num_sectors, dev, cryptoInfo, quickFormat);
1.1.1.3 root 327: break;
1.1.1.10 root 328:
1.1.1.3 root 329: case FILESYS_FAT:
1.1.1.4 root 330: if (num_sectors > 0xFFFFffff)
331: {
1.1.1.6 root 332: nStatus = ERR_VOL_SIZE_WRONG;
333: goto error;
1.1.1.4 root 334: }
335:
336: // Calculate the fats, root dir etc
337: ft.num_sectors = (unsigned int) (num_sectors);
338: ft.cluster_size = clusterSize;
1.1.1.6 root 339: memcpy (ft.volume_name, "NO NAME ", 11);
1.1.1.4 root 340: GetFatParams (&ft);
341: *realClusterSize = ft.cluster_size * SECTOR_SIZE;
342:
1.1.1.8 root 343: nStatus = FormatFat (startSector, &ft, (void *) dev, cryptoInfo, quickFormat);
1.1.1.3 root 344: break;
345: }
1.1 root 346:
1.1.1.10 root 347: error:
348: dwError = GetLastError();
1.1.1.3 root 349:
350: burn (header, sizeof (header));
351: VirtualUnlock (header, sizeof (header));
1.1 root 352:
353: crypto_close (cryptoInfo);
1.1.1.4 root 354:
1.1.1.11! root 355: if (dev != INVALID_HANDLE_VALUE)
1.1.1.4 root 356: {
1.1.1.11! root 357: if (!bDevice && !hiddenVol && nStatus != 0)
! 358: {
! 359: // Remove preallocated part before closing file handle if format failed
! 360: if (SetFilePointer (dev, 0, NULL, FILE_BEGIN) == 0)
! 361: SetEndOfFile (dev);
! 362: }
1.1.1.6 root 363:
1.1.1.11! root 364: FlushFileBuffers (dev);
1.1.1.4 root 365:
1.1.1.11! root 366: if (bTimeStampValid)
! 367: {
! 368: // Restore the container timestamp (to preserve plausible deniability of the hidden volume)
! 369: if (SetFileTime (dev, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime) == 0)
! 370: MessageBoxW (hwndDlg, GetString ("SETFILETIME_FAILED_IMPLANT"), lpszTitle, MB_OK | MB_ICONEXCLAMATION);
! 371: }
! 372:
! 373: CloseHandle (dev);
! 374: dev = INVALID_HANDLE_VALUE;
! 375: }
1.1 root 376:
1.1.1.10 root 377: if (dosDev[0])
378: RemoveFakeDosName (volumePath, dosDev);
1.1 root 379:
1.1.1.6 root 380: if (nStatus != 0)
1.1.1.3 root 381: {
1.1.1.10 root 382: SetLastError(dwError);
383: return nStatus;
384: }
1.1.1.6 root 385:
1.1.1.10 root 386: if (fileSystem == FILESYS_NTFS)
387: {
388: // Quick-format volume as NTFS
389: int driveNo = GetLastAvailableDrive ();
390: MountOptions mountOptions;
391: int retCode;
1.1.1.3 root 392:
1.1.1.10 root 393: ZeroMemory (&mountOptions, sizeof (mountOptions));
1.1.1.5 root 394:
1.1.1.10 root 395: if (driveNo == -1)
396: {
397: MessageBoxW (hwndDlg, GetString ("NO_FREE_DRIVES"), lpszTitle, ICON_HAND);
398: MessageBoxW (hwndDlg, GetString ("FORMAT_NTFS_STOP"), lpszTitle, ICON_HAND);
1.1.1.3 root 399:
1.1.1.10 root 400: return ERR_NO_FREE_DRIVES;
401: }
1.1.1.4 root 402:
1.1.1.10 root 403: mountOptions.ReadOnly = FALSE;
404: mountOptions.Removable = FALSE;
405: mountOptions.ProtectHiddenVolume = FALSE;
406: mountOptions.PreserveTimestamp = bPreserveTimestamp;
1.1.1.3 root 407:
1.1.1.10 root 408: if (MountVolume (hwndDlg, driveNo, volumePath, password, FALSE, TRUE, &mountOptions, FALSE, TRUE) < 1)
409: {
410: MessageBoxW (hwndDlg, GetString ("CANT_MOUNT_VOLUME"), lpszTitle, ICON_HAND);
411: MessageBoxW (hwndDlg, GetString ("FORMAT_NTFS_STOP"), lpszTitle, ICON_HAND);
412: return ERR_VOL_MOUNT_FAILED;
413: }
1.1.1.3 root 414:
1.1.1.10 root 415: if (!IsAdmin () && IsUacSupported ())
416: retCode = UacFormatNtfs (hwndDlg, driveNo, clusterSize);
417: else
418: retCode = FormatNtfs (driveNo, clusterSize);
1.1.1.3 root 419:
1.1.1.10 root 420: if (retCode != TRUE)
421: {
422: if (!UnmountVolume (hwndDlg, driveNo, FALSE))
423: MessageBoxW (hwndDlg, GetString ("CANT_DISMOUNT_VOLUME"), lpszTitle, ICON_HAND);
1.1.1.3 root 424:
1.1.1.10 root 425: Error ("FORMAT_NTFS_FAILED");
426: return ERR_DONT_REPORT;
1.1.1.3 root 427: }
1.1.1.10 root 428:
429: if (!UnmountVolume (hwndDlg, driveNo, FALSE))
430: MessageBoxW (hwndDlg, GetString ("CANT_DISMOUNT_VOLUME"), lpszTitle, ICON_HAND);
1.1.1.3 root 431: }
432:
1.1 root 433: return nStatus;
1.1.1.3 root 434: }
1.1 root 435:
1.1.1.8 root 436: #endif
1.1.1.3 root 437:
1.1.1.8 root 438: int FormatNoFs (unsigned __int64 startSector, __int64 num_sectors, void * dev, PCRYPTO_INFO cryptoInfo, BOOL quickFormat)
1.1.1.3 root 439: {
440: int write_buf_cnt = 0;
441: char sector[SECTOR_SIZE], *write_buf;
1.1.1.4 root 442: unsigned __int64 nSecNo = startSector;
1.1.1.6 root 443: int retVal;
1.1.1.7 root 444: char temporaryKey[DISKKEY_SIZE];
1.1.1.4 root 445:
1.1.1.8 root 446: #ifdef _WIN32
447: LARGE_INTEGER startOffset;
448: LARGE_INTEGER newOffset;
449:
1.1.1.4 root 450: // Seek to start sector
451: startOffset.QuadPart = startSector * SECTOR_SIZE;
1.1.1.6 root 452: if (!SetFilePointerEx ((HANDLE) dev, startOffset, &newOffset, FILE_BEGIN)
453: || newOffset.QuadPart != startOffset.QuadPart)
1.1.1.4 root 454: {
455: return ERR_VOL_SEEKING;
456: }
1.1.1.8 root 457: #endif
1.1.1.3 root 458:
1.1.1.8 root 459: write_buf = (char *) TCalloc (WRITE_BUF_SIZE);
1.1.1.3 root 460: memset (sector, 0, sizeof (sector));
461:
1.1.1.7 root 462: /* Fill the rest of the data area with random data */
463:
1.1.1.3 root 464: if(!quickFormat)
465: {
1.1.1.7 root 466: /* Generate a random temporary key set to be used for "dummy" encryption that will fill
467: the free disk space (data area) with random data. This is necessary for plausible
468: deniability of hidden volumes (and also reduces the amount of predictable plaintext
469: within the volume). */
1.1.1.6 root 470:
1.1.1.9 root 471: // Temporary master key
472: if (!RandgetBytes (temporaryKey, EAGetKeySize (cryptoInfo->ea), FALSE))
473: goto fail;
474: // Secondary key (LRW mode)
475: if (!RandgetBytes (cryptoInfo->iv, sizeof cryptoInfo->iv, FALSE))
476: goto fail;
1.1.1.7 root 477:
478: retVal = EAInit (cryptoInfo->ea, temporaryKey, cryptoInfo->ks);
1.1.1.6 root 479: if (retVal != 0)
1.1.1.7 root 480: {
481: burn (temporaryKey, sizeof(temporaryKey));
1.1.1.6 root 482: return retVal;
1.1.1.7 root 483: }
484: if (!EAInitMode (cryptoInfo))
485: {
486: burn (temporaryKey, sizeof(temporaryKey));
487: return ERR_MODE_INIT_FAILED;
488: }
1.1.1.4 root 489:
1.1.1.3 root 490: while (num_sectors--)
491: {
1.1.1.7 root 492: /* Generate random plaintext. Note that reused plaintext blocks are not a concern
493: here since LRW mode is designed to hide patterns. Furthermore, patterns in plaintext
494: do occur commonly on media in the "real world", so it might actually be a fatal
495: mistake to try to avoid them completely. */
1.1.1.9 root 496:
497: #if RNG_POOL_SIZE > SECTOR_SIZE
498: #error RNG_POOL_SIZE > SECTOR_SIZE
1.1.1.7 root 499: #endif
500:
1.1.1.9 root 501: #ifdef _WIN32
502: if (!RandpeekBytes (sector, RNG_POOL_SIZE)
503: || !RandpeekBytes (sector + RNG_POOL_SIZE, SECTOR_SIZE - RNG_POOL_SIZE))
504: goto fail;
505: #else
506: if ((nSecNo & 0x3fff) == 0)
507: {
508: if (!RandgetBytes (sector, RNG_POOL_SIZE, FALSE)
509: || !RandgetBytes (sector + RNG_POOL_SIZE, SECTOR_SIZE - RNG_POOL_SIZE, FALSE))
510: goto fail;
511: }
512: #endif
1.1.1.7 root 513: // Encrypt the random plaintext and write it to the disk
1.1.1.6 root 514: if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo,
1.1.1.8 root 515: cryptoInfo) == FALSE)
1.1.1.3 root 516: goto fail;
517: }
1.1.1.8 root 518: if (write_buf_cnt != 0 &&
519: #ifdef _WIN32
520: _lwrite ((HFILE)dev, write_buf, write_buf_cnt) == HFILE_ERROR)
521: #else
522: fwrite (write_buf, 1, write_buf_cnt, (FILE *)dev) != (size_t)write_buf_cnt)
523: #endif
1.1.1.3 root 524: goto fail;
525: }
526: else
527: nSecNo = num_sectors;
528:
529: UpdateProgressBar (nSecNo);
530:
531: TCfree (write_buf);
1.1.1.7 root 532: burn (temporaryKey, sizeof(temporaryKey));
1.1.1.3 root 533: return 0;
534:
535: fail:
536:
537: TCfree (write_buf);
1.1.1.7 root 538: burn (temporaryKey, sizeof(temporaryKey));
1.1.1.3 root 539: return ERR_OS_ERROR;
1.1 root 540: }
1.1.1.3 root 541:
1.1.1.8 root 542: #ifdef _WIN32
1.1.1.3 root 543:
544: volatile BOOLEAN FormatExResult;
545:
546: BOOLEAN __stdcall FormatExCallback (int command, DWORD subCommand, PVOID parameter)
547: {
548: if (command == FMIFS_DONE)
549: FormatExResult = *(BOOLEAN *) parameter;
550: return TRUE;
551: }
552:
553: BOOL FormatNtfs (int driveNo, int clusterSize)
554: {
555: WCHAR dir[8] = { driveNo + 'A', 0 };
556: PFORMATEX FormatEx;
557: HMODULE hModule = LoadLibrary ("fmifs.dll");
1.1.1.10 root 558: int i;
1.1.1.3 root 559:
560: if (hModule == NULL)
561: return FALSE;
562:
563: if (!(FormatEx = (void *) GetProcAddress (GetModuleHandle("fmifs.dll"), "FormatEx")))
564: {
565: FreeLibrary (hModule);
566: return FALSE;
567: }
568:
569: wcscat (dir, L":\\");
570:
571: FormatExResult = FALSE;
572:
1.1.1.10 root 573: // Windows sometimes fail to format a volume (hosted on a removable medium) as NTFS.
574: // It often helps to retry several times.
575: for (i = 0; i < 10 && FormatExResult != TRUE; i++)
576: {
1.1.1.11! root 577: FormatEx (dir, FMIFS_HARDDISK, L"NTFS", L"", TRUE, clusterSize * SECTOR_SIZE, FormatExCallback);
1.1.1.10 root 578: }
1.1.1.3 root 579:
580: FreeLibrary (hModule);
581: return FormatExResult;
582: }
583:
1.1.1.8 root 584: #endif
585:
1.1.1.3 root 586: BOOL
1.1.1.8 root 587: WriteSector (void *dev, char *sector,
1.1.1.3 root 588: char *write_buf, int *write_buf_cnt,
1.1.1.8 root 589: __int64 *nSecNo, PCRYPTO_INFO cryptoInfo)
1.1.1.3 root 590: {
1.1.1.8 root 591: static __int32 updateTime = 0;
1.1.1.4 root 592:
1.1.1.6 root 593: EncryptSectors ((unsigned __int32 *) sector,
1.1.1.7 root 594: (*nSecNo)++, 1, cryptoInfo);
1.1.1.4 root 595:
1.1.1.3 root 596: memcpy (write_buf + *write_buf_cnt, sector, SECTOR_SIZE);
597: (*write_buf_cnt) += SECTOR_SIZE;
598:
599: if (*write_buf_cnt == WRITE_BUF_SIZE)
600: {
1.1.1.8 root 601: if (
602: #ifdef _WIN32
603: _lwrite ((HFILE)dev, write_buf, WRITE_BUF_SIZE) == HFILE_ERROR)
604: #else
605: fwrite (write_buf, 1, WRITE_BUF_SIZE, (FILE *)dev) != WRITE_BUF_SIZE)
606: #endif
1.1.1.3 root 607: return FALSE;
608: else
609: *write_buf_cnt = 0;
610: }
1.1.1.6 root 611:
1.1.1.8 root 612: #ifdef _WIN32
1.1.1.6 root 613: if (GetTickCount () - updateTime > 25)
1.1.1.3 root 614: {
1.1.1.6 root 615: if (UpdateProgressBar (*nSecNo))
1.1.1.3 root 616: return FALSE;
1.1.1.6 root 617:
618: updateTime = GetTickCount ();
1.1.1.3 root 619: }
1.1.1.8 root 620: #else
621: UpdateProgressBar (*nSecNo);
622: #endif
1.1.1.3 root 623:
624: return TRUE;
625:
626: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.