Truecrypt代码Format分析(2)---核心函数TcFormatVolume( )详解(下)

// 这是if..else 的下半部分.

else
 {
  /* File-hosted volume */
  // 根据volParams->volumePath,创建文件
  dev = CreateFile (volParams->volumePath, GENERIC_READ | GENERIC_WRITE,
   (volParams->hiddenVol || bInstantRetryOtherFilesys) ? (FILE_SHARE_READ | FILE_SHARE_WRITE) : 0,
   NULL, (volParams->hiddenVol || bInstantRetryOtherFilesys) ? OPEN_EXISTING : CREATE_ALWAYS, 0, NULL);

  if (dev == INVALID_HANDLE_VALUE)
  {
   nStatus = ERR_OS_ERROR;
   goto error;
  }
  // DisableFileCompression()函数内部调用DeviceIoControl(),
  // 发送IOCTL_CODE,FSCTL_GET_COMPRESSION和FSCTL_SET_COMPRESSION
  // 来设置dev的COMPRESSION信息.和稀疏文件的压缩性相关? 可以参见驱动分析...
  
  DisableFileCompression (dev);

  // 如果为非hiddenVol则...
  
  if (!volParams->hiddenVol && !bInstantRetryOtherFilesys)
  {
   LARGE_INTEGER volumeSize;
   volumeSize.QuadPart = dataAreaSize + TC_VOLUME_HEADER_GROUP_SIZE;
  
   if (volParams->sparseFileSwitch && volParams->quickFormat)
   {
    // Create as sparse file container
    // 创建一个 稀疏(sparse) file container..
    // 在这里解释下 sparse file指的是文件中出现大量的0数据,这些数据对我们用处不大,但是却占用我们的空间
    // 因此自从Windows 3.51对此进行了优化,那些无用的0字节被用一定的算法压缩起来,使得这些0字节不再占用那么多空间
    // 在你声明一个很大的文件为稀疏文件的时候(如 100GB),这个文件实际并不需要占用那么大空间,因为里面大多是无用的0数据
    // 那么,NTFS对稀疏文件的压缩算法可以释放这些无用的0字节算是对磁盘空间效率的优化,但是FAT32并不支持稀疏文件.
    DWORD tmp;
    if (!DeviceIoControl (dev, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, &tmp, NULL))
    {
     nStatus = ERR_OS_ERROR;
     goto error;
    }
   }

   // Preallocate the file
   // 预分配文件大小...
   if (!SetFilePointerEx (dev, volumeSize, NULL, FILE_BEGIN)
    || !SetEndOfFile (dev)
    || SetFilePointer (dev, 0, NULL, FILE_BEGIN) != 0)
   {
    nStatus = ERR_OS_ERROR;
    goto error;
   }
  }
 }// File-hosted volume *end

 // 如果是 hiddenVol并且非 Device的话,获得与FileTime相关的信息
 if (volParams->hiddenVol && !volParams->bDevice && bPreserveTimestamp)
 {
  if (GetFileTime ((HANDLE) dev, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime) == 0)
   bTimeStampValid = FALSE;
  else
   bTimeStampValid = TRUE;
 }

 /* Volume header */

 // Hidden volume setup
 // Hidden Volume 的安装和设置
 if(volParams->hiddenVol)
 {
  LARGE_INTEGER headerOffset;

  // Check hidden volume size
  // 检查 hidden volume的大小
  if (volParams->hiddenVolHostSize < TC_MIN_HIDDEN_VOLUME_HOST_SIZE || volParams->hiddenVolHostSize > TC_MAX_HIDDEN_VOLUME_HOST_SIZE)
  {  
   nStatus = ERR_VOL_SIZE_WRONG;
   goto error;
  }

  // Seek to hidden volume header location
  // 用SetFilePointerEx()定位 hidden volume header的位置
  
  headerOffset.QuadPart = TC_HIDDEN_VOLUME_HEADER_OFFSET;

  if (!SetFilePointerEx ((HANDLE) dev, headerOffset, NULL, FILE_BEGIN))
  {
   nStatus = ERR_OS_ERROR;
   goto error;
  }
 }

 // 如果没有尝试其他的Filesystem则...
 if (!bInstantRetryOtherFilesys)
 {
  // Write the volume header
  // 往volume中写如header信息,该header是在前面调用CreateVolumeHeaderInMemory()函数,初始化好的.

  if (!WriteEffectiveVolumeHeader (volParams->bDevice, dev, (byte *)header))
  {
   nStatus = ERR_OS_ERROR;
   goto error;
  }

  // To prevent fragmentation, write zeroes to reserved header sectors which are going to be filled with random data
  // 为了防止磁盘的碎片化,往剩余的header sectors 中填0.
  if (!volParams->bDevice && !volParams->hiddenVol)
  {
   byte buf[TC_VOLUME_HEADER_GROUP_SIZE - TC_VOLUME_HEADER_EFFECTIVE_SIZE];
   DWORD bytesWritten;
   ZeroMemory (buf, sizeof (buf));

   if (!WriteFile (dev, buf, sizeof (buf), &bytesWritten, NULL))
   {
    nStatus = ERR_OS_ERROR;
    goto error;
   }

   if (bytesWritten != sizeof (buf))
   {
    nStatus = ERR_PARAMETER_INCORRECT;
    goto error;
   }
  }
 }

 // 如果是 hidden Volume
 if (volParams->hiddenVol)
 {
  // Calculate data area position of hidden volume
  // 计算获得 数据区 在 hidden volume的 位置
  cryptoInfo->hiddenVolumeOffset = dataOffset;

  // Validate the offset
  // 检测这offset 是否有效
  if (dataOffset % FormatSectorSize != 0)
  {
   nStatus = ERR_VOL_SIZE_WRONG;
   goto error;
  }

  volParams->quickFormat = TRUE;  // To entirely format a hidden volume would be redundant
 }

 /* Data area */
 // 获得数据区的起始扇区,即startSector.
 startSector = dataOffset / FormatSectorSize;

 // Format filesystem
 // 格式化成相应的文件系统,NONE/NTFS/FAT

 switch (volParams->fileSystem)
 {
 case FILESYS_NONE:
 case FILESYS_NTFS:
  
 // StartFormatWriteThread()函数内部另外创建了一个线程,然后调用线程函数FormatWriteThreadProc()
 // FormatWriteThreadProc()设置当前的线程的优先级为HIGHEST,然后尝试往该dev中写入数据,即WriteThreadBuffer,\
 // 而WriteThreadBuffer = (byte *) TCalloc (FormatWriteBufferSize);
  if (volParams->bDevice && !StartFormatWriteThread())
  {
   nStatus = ERR_OS_ERROR;
   goto error;
  }
 
 // FormatNoFs()这个函数看的我有点吐血了,里面有很多关于加密算法的初始化操作,分析不过来
 // 不过主要的格式化操作,由内部的WriteSector()和FlushFormatWriteBuffer()完成.
  nStatus = FormatNoFs (startSector, num_sectors, dev, cryptoInfo, volParams->quickFormat);

  if (volParams->bDevice)
   StopFormatWriteThread();

  break;
  
 case FILESYS_FAT:
  if (num_sectors > 0xFFFFffff)
  {
   nStatus = ERR_VOL_SIZE_WRONG;
   goto error;
  }

  // Calculate the fats, root dir etc
/*
  typedef struct fatparams_t
{
 char volume_name[11];
 byte volume_id[4];
 unsigned int num_sectors; // total number of sectors
 int cluster_count; // number of clusters
 int size_root_dir; // size of the root directory in bytes
 int size_fat;  // size of FAT
 int fats;
 int media;
 int cluster_size;
 int fat_length;
 uint16 dir_entries;
 uint16 sector_size;
 int hidden;
 __int16 reserved;
 uint16 sectors;
 unsigned int total_sect;

 uint16 heads;
 uint16 secs_track;

} fatparams;
*/

 // 上面的结构体 与 FAT相关,下面的操作就是初始化fat结构的成员变量.
 ft.num_sectors = (unsigned int) (num_sectors);

#if TC_MAX_VOLUME_SECTOR_SIZE > 0xFFFF
#error TC_MAX_VOLUME_SECTOR_SIZE > 0xFFFF
#endif

  ft.sector_size = (uint16) FormatSectorSize;
  ft.cluster_size = volParams->clusterSize;
  memcpy (ft.volume_name, "NO NAME    ", 11);
  GetFatParams (&ft);
  *(volParams->realClusterSize) = ft.cluster_size * FormatSectorSize;

  if (volParams->bDevice && !StartFormatWriteThread())
  {
   nStatus = ERR_OS_ERROR;
   goto error;
  }

 // 执行FormatFat()函数,进行FS的格式化操作.
  nStatus = FormatFat (startSector, &ft, (void *) dev, cryptoInfo, volParams->quickFormat);

  if (volParams->bDevice)
   StopFormatWriteThread();

  break;

 default:
  nStatus = ERR_PARAMETER_INCORRECT;
  goto error;
 }

 // Write header backup
 // 写入header的备份
 offset.QuadPart = volParams->hiddenVol ? volParams->hiddenVolHostSize - TC_HIDDEN_VOLUME_HEADER_OFFSET : dataAreaSize + TC_VOLUME_HEADER_GROUP_SIZE;

 if (!SetFilePointerEx ((HANDLE) dev, offset, NULL, FILE_BEGIN))
 {
  nStatus = ERR_OS_ERROR;
  goto error;
 }

 nStatus = CreateVolumeHeaderInMemory (FALSE,
  header,
  volParams->ea,
  FIRST_MODE_OF_OPERATION_ID,
  volParams->password,
  volParams->pkcs5,
  (char *)cryptoInfo->master_keydata,
  &cryptoInfo,
  dataAreaSize,
  volParams->hiddenVol ? dataAreaSize : 0,
  dataOffset,
  dataAreaSize,
  0,
  volParams->headerFlags,
  FormatSectorSize,
  FALSE);

 if (!WriteEffectiveVolumeHeader (volParams->bDevice, dev, (byte *)header))
 {
  nStatus = ERR_OS_ERROR;
  goto error;
 }

 // Fill reserved header sectors (including the backup header area) with random data
 // 用随机数据填充剩余的header sectors

 if (!volParams->hiddenVol)
 {
  nStatus = WriteRandomDataToReservedHeaderAreas (dev, cryptoInfo, dataAreaSize, FALSE, FALSE);

  if (nStatus != ERR_SUCCESS)
   goto error;
 }

#ifndef DEBUG
 if (volParams->quickFormat && volParams->fileSystem != FILESYS_NTFS)
  Sleep (500); // User-friendly GUI
#endif

// 这部分有点懒了...凑合着看吧...
error:
 dwError = GetLastError();

 burn (header, sizeof (header));
 VirtualUnlock (header, sizeof (header));
 
 // 如果dev不为无效的HANDLE
 if (dev != INVALID_HANDLE_VALUE)
 {
  // 如果不是Device或者也不是hidden Volume 那么就移除 先前预先分配的 磁盘空间
  if (!volParams->bDevice && !volParams->hiddenVol && nStatus != 0)
  {
   // Remove preallocated part before closing file handle if format failed
   // 如果格式化失败了...
   if (SetFilePointer (dev, 0, NULL, FILE_BEGIN) == 0)
    SetEndOfFile (dev);
  }

  FlushFileBuffers (dev);

  if (bTimeStampValid)
   SetFileTime (dev, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime);

  CloseHandle (dev);
  dev = INVALID_HANDLE_VALUE;
 }

 if (nStatus != 0)
 {
  SetLastError(dwError);
  goto fv_end;
 }

 // 如果要求被格式化成 NTFS
 if (volParams->fileSystem == FILESYS_NTFS)
 {
  // Quick-format volume as NTFS
  int driveNo = GetLastAvailableDrive ();
  MountOptions mountOptions;
  int retCode;

  ZeroMemory (&mountOptions, sizeof (mountOptions));

  if (driveNo == -1)
  {
   MessageBoxW (volParams->hwndDlg, GetString ("NO_FREE_DRIVES"), lpszTitle, ICON_HAND);
   MessageBoxW (volParams->hwndDlg, GetString ("FORMAT_NTFS_STOP"), lpszTitle, ICON_HAND);

   nStatus = ERR_NO_FREE_DRIVES;
   goto fv_end;
  }

  mountOptions.ReadOnly = FALSE;
  mountOptions.Removable = FALSE;
  mountOptions.ProtectHiddenVolume = FALSE;
  mountOptions.PreserveTimestamp = bPreserveTimestamp;
  mountOptions.PartitionInInactiveSysEncScope = FALSE;
  mountOptions.UseBackupHeader = FALSE;

  if (MountVolume (volParams->hwndDlg, driveNo, volParams->volumePath, volParams->password, FALSE, TRUE, &mountOptions, FALSE, TRUE) < 1)
  {
   MessageBoxW (volParams->hwndDlg, GetString ("CANT_MOUNT_VOLUME"), lpszTitle, ICON_HAND);
   MessageBoxW (volParams->hwndDlg, GetString ("FORMAT_NTFS_STOP"), lpszTitle, ICON_HAND);
   nStatus = ERR_VOL_MOUNT_FAILED;
   goto fv_end;
  }

  if (!IsAdmin () && IsUacSupported ())
   retCode = UacFormatNtfs (volParams->hwndDlg, driveNo, volParams->clusterSize);
  else
   retCode = FormatNtfs (driveNo, volParams->clusterSize);

  if (retCode != TRUE)
  {
   if (!UnmountVolume (volParams->hwndDlg, driveNo, FALSE))
    MessageBoxW (volParams->hwndDlg, GetString ("CANT_DISMOUNT_VOLUME"), lpszTitle, ICON_HAND);

   if (dataAreaSize <= TC_MAX_FAT_SECTOR_COUNT * FormatSectorSize)
   {
    if (AskErrYesNo ("FORMAT_NTFS_FAILED_ASK_FAT") == IDYES)
    {
     // NTFS format failed and the user wants to try FAT format immediately
     volParams->fileSystem = FILESYS_FAT;
     bInstantRetryOtherFilesys = TRUE;
     volParams->quickFormat = TRUE;  // Volume has already been successfully TC-formatted
     volParams->clusterSize = 0;  // Default cluster size
     goto begin_format;
    }
   }
   else
    Error ("FORMAT_NTFS_FAILED");

   nStatus = ERR_DONT_REPORT;
   goto fv_end;
  }

  if (!UnmountVolume (volParams->hwndDlg, driveNo, FALSE))
   MessageBoxW (volParams->hwndDlg, GetString ("CANT_DISMOUNT_VOLUME"), lpszTitle, ICON_HAND);
 }

fv_end:
 dwError = GetLastError();

 if (dosDev[0])
  RemoveFakeDosName (volParams->volumePath, dosDev);

 crypto_close (cryptoInfo);

 SetLastError (dwError);
 return nStatus;

}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值