📄 freeotfe4pda.c
字号:
{
devContext->FileAttributes = GetFileAttributes(devContext->zzFilename);
devContext->FileAttributesStored = (devContext->FileAttributes !=
FAILED_GETFILEATTRIBUTES);
}
// Volume file handle...
if (allOK)
{
desiredAccess = GENERIC_READ;
if (!(DIOCBuffer->ReadOnly))
{
desiredAccess |= GENERIC_WRITE;
}
// Note: FILE_ATTRIBUTE_NORMAL only valid if used *alone*
//fileFlags = FILE_ATTRIBUTE_NORMAL;
fileFlags = FILE_FLAG_WRITE_THROUGH;
if (DIOCBuffer->ReadOnly)
{
fileFlags |= FILE_ATTRIBUTE_READONLY;
}
devContext->FileHandle = CreateFile(
devContext->zzFilename,
desiredAccess,
(FILE_SHARE_READ | FILE_SHARE_WRITE),
NULL,
OPEN_EXISTING,
fileFlags,
NULL
);
if (devContext->FileHandle == INVALID_HANDLE_VALUE)
{
DEBUGOUTMAINDRV(DEBUGLEV_ERROR, (TEXT("Unable to open volume file\n")));
allOK = FALSE;
}
}
// Get file timestamps...
// Note: File attributes obtained before opening file, file timestamps
// obtained after opening file
if (allOK)
{
devContext->FileTimestampsStored = GetFileTime(
devContext->FileHandle,
&(devContext->CreationTime),
&(devContext->LastAccessTime),
&(devContext->LastWriteTime)
);
}
// Volume file size and starting offset...
if (allOK)
{
devContext->DataOffset = DIOCBuffer->DataStart;
// Store the size of the file/partition for later use...
if (devContext->MountSource == MNTSRC_PARTITION)
{
allOK = GetMaxSizePartition(
devContext->zzFilename,
&determinedMaxSize
);
}
else
{
allOK = GetMaxSizeFile(
devContext->FileHandle,
&determinedMaxSize
);
}
if (!(allOK))
{
DEBUGOUTMAINDRV(DEBUGLEV_ERROR, (TEXT("Unable to determine max possible size.\n")));
}
DEBUGOUTMAINDRV(DEBUGLEV_INFO, (TEXT("Size of actual file/partition: %lld bytes\n"), determinedMaxSize.QuadPart));
DEBUGOUTMAINDRV(DEBUGLEV_INFO, (TEXT("Starting offset: %lld bytes\n"), devContext->DataOffset.QuadPart));
// Encrypted data start/end offsets
dataEnd = DIOCBuffer->DataEnd;
if (dataEnd.QuadPart == 0)
{
dataEnd = determinedMaxSize;
}
// Sanity check...
if (
(devContext->DataOffset.QuadPart >= dataEnd.QuadPart) ||
(dataEnd.QuadPart > determinedMaxSize.QuadPart)
)
{
DEBUGOUTMAINDRV(DEBUGLEV_ERROR, (TEXT("Invalid value passed as encrypted data start/end.\n")));
allOK = FALSE;
}
// The size of the partition
devContext->PartitionSize.QuadPart = (dataEnd.QuadPart -
devContext->DataOffset.QuadPart);
}
// Setup DiskGeometry member...
if (allOK)
{
// Note: When WinCE formats the volume, it loses:
//
// (di_sectors * di_heads) + di_sectors
//
// sectors as overheads. This is the same with the CF and SD cards
// I tested.
tmpLargeInt.QuadPart = devContext->PartitionSize.QuadPart / BYTES_PER_SECTOR;
devContext->DiskGeometry.di_total_sectors = tmpLargeInt.LowPart;
devContext->DiskGeometry.di_bytes_per_sect = BYTES_PER_SECTOR;
devContext->DiskGeometry.di_sectors = SECTORS_PER_TRACK;
devContext->DiskGeometry.di_heads = TRACKS_PER_CYLINDER;
tmpLargeInt.QuadPart =
(
// Encrypted partition size...
devContext->PartitionSize.QuadPart
) / (
devContext->DiskGeometry.di_heads *
devContext->DiskGeometry.di_sectors *
devContext->DiskGeometry.di_bytes_per_sect
);
devContext->DiskGeometry.di_cylinders = tmpLargeInt.LowPart;
// DISK_INFO_FLAG_PAGEABLE can be enabled; see:
// http://support.microsoft.com/default.aspx?scid=kb;en-us;Q260874
// BUT! It shouldn't be enabled as from the MSDN, this would require
// read and write requests to be synchronous and do not involve
// memory manager calls, loader operations, or thread switches.
// We could set DISK_INFO_FLAG_CHS_UNCERTAIN, since it's only a simulation,
// but since we can supply reasonable values...
// DISK_INFO_FLAG_MBR - not strictly needed(?), but the SD cards and CF cards
// I tested have it set, and since that's what we're emulating...
devContext->DiskGeometry.di_flags = (
// DISK_INFO_FLAG_CHS_UNCERTAIN |
DISK_INFO_FLAG_MBR |
DISK_INFO_FLAG_PAGEABLE
);
DEBUGOUTMAINDRV(DEBUGLEV_INFO, (TEXT("Simulated disk geometry:\n")));
DEBUGOUTMAINDRV(
DEBUGLEV_INFO,
(TEXT(" di_total_sectors : %d\n"),
devContext->DiskGeometry.di_total_sectors)
);
DEBUGOUTMAINDRV(
DEBUGLEV_INFO,
(TEXT(" di_total_sectors : %d\n"),
devContext->DiskGeometry.di_total_sectors)
);
DEBUGOUTMAINDRV(
DEBUGLEV_INFO,
(TEXT(" di_bytes_per_sect: %d\n"),
devContext->DiskGeometry.di_bytes_per_sect)
);
DEBUGOUTMAINDRV(
DEBUGLEV_INFO,
(TEXT(" di_cylinders : %d\n"),
devContext->DiskGeometry.di_cylinders)
);
DEBUGOUTMAINDRV(
DEBUGLEV_INFO,
(TEXT(" di_heads : %d\n"),
devContext->DiskGeometry.di_heads)
);
DEBUGOUTMAINDRV(
DEBUGLEV_INFO,
(TEXT(" di_sectors : %d\n"),
devContext->DiskGeometry.di_sectors)
);
DEBUGOUTMAINDRV(
DEBUGLEV_INFO,
(TEXT(" di_flags : %d\n"),
devContext->DiskGeometry.di_flags)
);
}
if (allOK)
{
// The size of the disk (i.e. including hidden sectors)
devContext->DiskSize.QuadPart =
devContext->DiskGeometry.di_cylinders *
devContext->DiskGeometry.di_heads *
devContext->DiskGeometry.di_sectors *
devContext->DiskGeometry.di_bytes_per_sect;
}
// Initialize various simple members...
if (allOK)
{
// From the DISK_INFO struct definition, WinCE block devices are only
// allowed to have a block size of 512 bytes
// THIS COULD CAUSE PROBLEMS IN FUTURE? For example, a CDROM drive needs
// this set to 2048 - assuming it's to match the PC version of FreeOTFE...
devContext->FileSectorSize = MAND_BYTES_PER_SECTOR;
DEBUGOUTMAINDRV(DEBUGLEV_INFO, (TEXT("Using file sector size: %d\n"), devContext->FileSectorSize));
tmpLargeInt.QuadPart = (devContext->DataOffset.QuadPart % devContext->DiskGeometry.di_bytes_per_sect);
devContext->DataOffsetModVirtualSectorSize = tmpLargeInt.LowPart;
DEBUGOUTMAINDRV(DEBUGLEV_INFO, (TEXT("DataOffsetModVirtualSectorSize: %d\n"), devContext->DataOffsetModVirtualSectorSize));
devContext->ReadOnly = DIOCBuffer->ReadOnly;
devContext->EncryptionBlockSize = ENCRYPTION_BLOCK_SIZE;
}
// Start setting up StrageDeviceInfo member...
if (allOK)
{
DEBUGOUTMAINDRV(DEBUGLEV_INFO, (TEXT("Setting up StrageDeviceInfo member...\n")));
devContext->StorageDeviceInfo.cbSize = sizeof(devContext->StorageDeviceInfo);
// Default storage profile in case none set on builtin registry profile
// entry...
wcscpy(devContext->StorageDeviceInfo.szProfile, DEFAULT_PROFILE);
// From the Active registry key, get the "Builtin" registry key entries
DEBUGOUTMAINDRV(
DEBUGLEV_INFO,
(TEXT("Registry key (Builtin) : %ls\n"),
devContext->RegdetailsActive.Key)
);
if (RegDetailsGetBuiltinByKey(
devContext->RegdetailsActive.Key,
®detailsBuiltin
))
{
DEBUGOUTMAINDRV(DEBUGLEV_INFO, (TEXT("Got Builtin registry entries.\n")));
if (
(wcslen(regdetailsBuiltin.Profile) *
sizeof(devContext->StorageDeviceInfo.szProfile[0])) >
sizeof(devContext->StorageDeviceInfo.szProfile)
)
{
DEBUGOUTMAINDRV(DEBUGLEV_ERROR, (TEXT("Builtin registry entry identifying profile too long.\n")));
DEBUGOUTMAINDRV(
DEBUGLEV_ERROR,
(TEXT("Max allowed by struct: %d\n"),
sizeof(devContext->StorageDeviceInfo.szProfile))
);
DEBUGOUTMAINDRV(
DEBUGLEV_ERROR,
(TEXT("Builtin entry length : %d\n"),
(wcslen(regdetailsBuiltin.Profile) *
sizeof(devContext->StorageDeviceInfo.szProfile[0])))
);
allOK = FALSE;
}
else
{
profileStrLen = wcslen(regdetailsBuiltin.Profile);
wcsncpy(
devContext->StorageDeviceInfo.szProfile,
regdetailsBuiltin.Profile,
min(
(sizeof(devContext->StorageDeviceInfo.szProfile) /
sizeof(devContext->StorageDeviceInfo.szProfile[0])),
profileStrLen
)
);
}
}
RegDetailsFree(®detailsBuiltin, NULL, NULL);
DEBUGOUTMAINDRV(DEBUGLEV_INFO, (TEXT("Set storage profile name as: %ls\n"), devContext->StorageDeviceInfo.szProfile));
devContext->StorageDeviceInfo.dwDeviceClass = STORAGE_DEVICE_CLASS_BLOCK;
devContext->StorageDeviceInfo.dwDeviceType = DIOCBuffer->DeviceType;
if (DIOCBuffer->ReadOnly)
{
devContext->StorageDeviceInfo.dwDeviceFlags = STORAGE_DEVICE_FLAG_READONLY;
}
else
{
devContext->StorageDeviceInfo.dwDeviceFlags = STORAGE_DEVICE_FLAG_READWRITE;
}
}
// Debug dump simulated storage device details...
if (allOK)
{
DEBUGOUTMAINDRV(DEBUGLEV_INFO, (TEXT("Simulated storage device:\n")));
DEBUGOUTMAINDRV(
DEBUGLEV_INFO,
(TEXT(" cbSize : %d\n"),
devContext->StorageDeviceInfo.cbSize)
);
DEBUGOUTMAINDRV(
DEBUGLEV_INFO,
(TEXT(" szProfile : %ls\n"),
devContext->StorageDeviceInfo.szProfile)
);
DEBUGOUTMAINDRV(
DEBUGLEV_INFO,
(TEXT(" dwDeviceClass: %d\n"),
devContext->StorageDeviceInfo.dwDeviceClass)
);
DEBUGOUTMAINDRV(
DEBUGLEV_INFO,
(TEXT(" dwDeviceType : %d\n"),
devContext->StorageDeviceInfo.dwDeviceType)
);
DEBUGOUTMAINDRV(
DEBUGLEV_INFO,
(TEXT(" dwDeviceFlags: %d\n"),
devContext->StorageDeviceInfo.dwDeviceFlags)
);
}
// Initialize various simple members...
if (allOK)
{
devContext->PreventMediaRemoval = TRUE;
devContext->SectorIVGenMethod = DIOCBuffer->SectorIVGenMethod;
}
// --- OBTAIN THE HASH DRIVER ---
// Blank, in case an IV hash driver wasn't passed in
if (allOK)
{
// If an IV hash algorithm *was* passed in, get it's details and store them
if (
(DIOCBuffer->IVHashDeviceName[0] != 0) &&
(!(IsEqualGUID(&(DIOCBuffer->IVHashGUID), &FREEOTFE_NULL_GUID)))
)
{
devContext->IVHash.HashGUID = DIOCBuffer->IVHashGUID;
allOK = GetDeviceDetailsHash(
(WCHAR*)&DIOCBuffer->IVHashDeviceName,
&DIOCBuffer->IVHashGUID,
&(devContext->IVHash)
);
if (!(allOK))
{
DEBUGOUTMAINDRV(DEBUGLEV_ERROR, (TEXT("Unable to get IV hash device\n")));
}
}
else
{
DEBUGOUTMAINDRV(DEBUGLEV_INFO, (TEXT("No IV hash algorithm specified.\n")));
}
}
// --- OBTAIN THE IV CYPHER DRIVER ---
if (allOK)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -