📄 ntdriver.c
字号:
pThreadBlock->wszMountVolume, pThreadBlock->mount->nDosDriveNo, bDevice);
pThreadBlock->ntCreateStatus = TCOpenVolume (DeviceObject,
Extension,
pThreadBlock->mount,
pThreadBlock->wszMountVolume,
bDevice);
if (!NT_SUCCESS (pThreadBlock->ntCreateStatus) || pThreadBlock->mount->nReturnCode != 0)
{
KeSetEvent (&Extension->keCreateEvent, 0, FALSE);
PsTerminateSystemThread (STATUS_SUCCESS);
}
// Start IO queue
Extension->Queue.IsFilterDevice = FALSE;
Extension->Queue.DeviceObject = DeviceObject;
Extension->Queue.CryptoInfo = Extension->cryptoInfo;
Extension->Queue.HostFileHandle = Extension->hDeviceFile;
Extension->Queue.VirtualDeviceLength = Extension->DiskLength;
pThreadBlock->ntCreateStatus = EncryptedIoQueueStart (&Extension->Queue, pThreadBlock->mount->bUserContext ? IoGetCurrentProcess() : NULL);
if (!NT_SUCCESS (pThreadBlock->ntCreateStatus))
{
TCCloseVolume (DeviceObject, Extension);
pThreadBlock->mount->nReturnCode = ERR_OS_ERROR;
KeSetEvent (&Extension->keCreateEvent, 0, FALSE);
PsTerminateSystemThread (STATUS_SUCCESS);
}
KeSetEvent (&Extension->keCreateEvent, 0, FALSE);
/* From this point on pThreadBlock cannot be used as it will have been released! */
pThreadBlock = NULL;
for (;;)
{
/* Wait for a request from the dispatch routines. */
KeWaitForSingleObject ((PVOID) & Extension->RequestSemaphore, Executive, KernelMode, FALSE, NULL);
for (;;)
{
PIO_STACK_LOCATION irpSp;
PLIST_ENTRY request;
PIRP irp;
request = ExInterlockedRemoveHeadList (&Extension->ListEntry, &Extension->ListSpinLock);
if (request == NULL)
break;
irp = CONTAINING_RECORD (request, IRP, Tail.Overlay.ListEntry);
irpSp = IoGetCurrentIrpStackLocation (irp);
if (irpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL)
ProcessVolumeDeviceControlIrp (DeviceObject, Extension, irp);
else
ASSERT (FALSE);
}
if (Extension->bThreadShouldQuit)
{
Dump ("Closing volume\n");
EncryptedIoQueueStop (&Extension->Queue);
TCCloseVolume (DeviceObject, Extension);
PsTerminateSystemThread (STATUS_SUCCESS);
}
}
}
void
TCGetNTNameFromNumber (LPWSTR ntname, int nDriveNo)
{
WCHAR tmp[3] =
{0, ':', 0};
int j = nDriveNo + (WCHAR) 'A';
tmp[0] = (short) j;
wcscpy (ntname, (LPWSTR) NT_MOUNT_PREFIX);
wcsncat (ntname, tmp, 1);
}
void
TCGetDosNameFromNumber (LPWSTR dosname, int nDriveNo)
{
WCHAR tmp[3] =
{0, ':', 0};
int j = nDriveNo + (WCHAR) 'A';
tmp[0] = (short) j;
wcscpy (dosname, (LPWSTR) DOS_MOUNT_PREFIX);
wcscat (dosname, tmp);
}
#ifdef _DEBUG
LPWSTR
TCTranslateCode (ULONG ulCode)
{
switch (ulCode)
{
#define TC_CASE_RET_NAME(CODE) case CODE : return L###CODE
TC_CASE_RET_NAME (TC_IOCTL_ABORT_BOOT_ENCRYPTION_SETUP);
TC_CASE_RET_NAME (TC_IOCTL_BOOT_ENCRYPTION_SETUP);
TC_CASE_RET_NAME (TC_IOCTL_DISMOUNT_ALL_VOLUMES);
TC_CASE_RET_NAME (TC_IOCTL_DISMOUNT_VOLUME);
TC_CASE_RET_NAME (TC_IOCTL_GET_BOOT_DRIVE_VOLUME_PROPERTIES);
TC_CASE_RET_NAME (TC_IOCTL_GET_BOOT_ENCRYPTION_ALGORITHM_NAME);
TC_CASE_RET_NAME (TC_IOCTL_GET_BOOT_ENCRYPTION_SETUP_RESULT);
TC_CASE_RET_NAME (TC_IOCTL_GET_BOOT_ENCRYPTION_STATUS);
TC_CASE_RET_NAME (TC_IOCTL_GET_BOOT_LOADER_VERSION);
TC_CASE_RET_NAME (TC_IOCTL_GET_DEVICE_REFCOUNT);
TC_CASE_RET_NAME (TC_IOCTL_GET_DRIVE_GEOMETRY);
TC_CASE_RET_NAME (TC_IOCTL_GET_DRIVE_PARTITION_INFO);
TC_CASE_RET_NAME (TC_IOCTL_GET_DRIVER_VERSION);
TC_CASE_RET_NAME (TC_IOCTL_GET_MOUNTED_VOLUMES);
TC_CASE_RET_NAME (TC_IOCTL_GET_PASSWORD_CACHE_STATUS);
TC_CASE_RET_NAME (TC_IOCTL_GET_SYSTEM_DRIVE_CONFIG);
TC_CASE_RET_NAME (TC_IOCTL_GET_TRAVELER_MODE_STATUS);
TC_CASE_RET_NAME (TC_IOCTL_SET_TRAVELER_MODE_STATUS);
TC_CASE_RET_NAME (TC_IOCTL_GET_RESOLVED_SYMLINK);
TC_CASE_RET_NAME (TC_IOCTL_GET_VOLUME_PROPERTIES);
TC_CASE_RET_NAME (TC_IOCTL_DISK_IS_WRITABLE);
TC_CASE_RET_NAME (TC_IOCTL_IS_ANY_VOLUME_MOUNTED);
TC_CASE_RET_NAME (TC_IOCTL_IS_HIDDEN_SYSTEM_RUNNING);
TC_CASE_RET_NAME (TC_IOCTL_MOUNT_VOLUME);
TC_CASE_RET_NAME (TC_IOCTL_OPEN_TEST);
TC_CASE_RET_NAME (TC_IOCTL_PROBE_REAL_DRIVE_SIZE);
TC_CASE_RET_NAME (TC_IOCTL_REOPEN_BOOT_VOLUME_HEADER);
TC_CASE_RET_NAME (TC_IOCTL_WAS_REFERENCED_DEVICE_DELETED);
TC_CASE_RET_NAME (TC_IOCTL_WIPE_PASSWORD_CACHE);
TC_CASE_RET_NAME (IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS);
#undef TC_CASE_RET_NAME
}
if (ulCode == IOCTL_DISK_GET_DRIVE_GEOMETRY)
return (LPWSTR) _T ("IOCTL_DISK_GET_DRIVE_GEOMETRY");
else if (ulCode == IOCTL_DISK_GET_DRIVE_GEOMETRY_EX)
return (LPWSTR) _T ("IOCTL_DISK_GET_DRIVE_GEOMETRY_EX");
else if (ulCode == IOCTL_MOUNTDEV_QUERY_DEVICE_NAME)
return (LPWSTR) _T ("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME");
else if (ulCode == IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME)
return (LPWSTR) _T ("IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME");
else if (ulCode == IOCTL_MOUNTDEV_QUERY_UNIQUE_ID)
return (LPWSTR) _T ("IOCTL_MOUNTDEV_QUERY_UNIQUE_ID");
else if (ulCode == IOCTL_MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY)
return (LPWSTR) _T ("IOCTL_MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY");
else if (ulCode == IOCTL_VOLUME_ONLINE)
return (LPWSTR) _T ("IOCTL_VOLUME_ONLINE");
else if (ulCode == IOCTL_MOUNTDEV_LINK_CREATED)
return (LPWSTR) _T ("IOCTL_MOUNTDEV_LINK_CREATED");
else if (ulCode == IOCTL_MOUNTDEV_LINK_DELETED)
return (LPWSTR) _T ("IOCTL_MOUNTDEV_LINK_DELETED");
else if (ulCode == IOCTL_MOUNTMGR_QUERY_POINTS)
return (LPWSTR) _T ("IOCTL_MOUNTMGR_QUERY_POINTS");
else if (ulCode == IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_CREATED)
return (LPWSTR) _T ("IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_CREATED");
else if (ulCode == IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_DELETED)
return (LPWSTR) _T ("IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_DELETED");
else if (ulCode == IOCTL_DISK_GET_LENGTH_INFO)
return (LPWSTR) _T ("IOCTL_DISK_GET_LENGTH_INFO");
else if (ulCode == IOCTL_STORAGE_GET_DEVICE_NUMBER)
return (LPWSTR) _T ("IOCTL_STORAGE_GET_DEVICE_NUMBER");
else if (ulCode == IOCTL_DISK_GET_PARTITION_INFO)
return (LPWSTR) _T ("IOCTL_DISK_GET_PARTITION_INFO");
else if (ulCode == IOCTL_DISK_GET_PARTITION_INFO_EX)
return (LPWSTR) _T ("IOCTL_DISK_GET_PARTITION_INFO_EX");
else if (ulCode == IOCTL_DISK_SET_PARTITION_INFO)
return (LPWSTR) _T ("IOCTL_DISK_SET_PARTITION_INFO");
else if (ulCode == IOCTL_DISK_GET_DRIVE_LAYOUT)
return (LPWSTR) _T ("IOCTL_DISK_GET_DRIVE_LAYOUT");
else if (ulCode == IOCTL_DISK_SET_DRIVE_LAYOUT_EX)
return (LPWSTR) _T ("IOCTL_DISK_SET_DRIVE_LAYOUT_EX");
else if (ulCode == IOCTL_DISK_VERIFY)
return (LPWSTR) _T ("IOCTL_DISK_VERIFY");
else if (ulCode == IOCTL_DISK_FORMAT_TRACKS)
return (LPWSTR) _T ("IOCTL_DISK_FORMAT_TRACKS");
else if (ulCode == IOCTL_DISK_REASSIGN_BLOCKS)
return (LPWSTR) _T ("IOCTL_DISK_REASSIGN_BLOCKS");
else if (ulCode == IOCTL_DISK_PERFORMANCE)
return (LPWSTR) _T ("IOCTL_DISK_PERFORMANCE");
else if (ulCode == IOCTL_DISK_IS_WRITABLE)
return (LPWSTR) _T ("IOCTL_DISK_IS_WRITABLE");
else if (ulCode == IOCTL_DISK_LOGGING)
return (LPWSTR) _T ("IOCTL_DISK_LOGGING");
else if (ulCode == IOCTL_DISK_FORMAT_TRACKS_EX)
return (LPWSTR) _T ("IOCTL_DISK_FORMAT_TRACKS_EX");
else if (ulCode == IOCTL_DISK_HISTOGRAM_STRUCTURE)
return (LPWSTR) _T ("IOCTL_DISK_HISTOGRAM_STRUCTURE");
else if (ulCode == IOCTL_DISK_HISTOGRAM_DATA)
return (LPWSTR) _T ("IOCTL_DISK_HISTOGRAM_DATA");
else if (ulCode == IOCTL_DISK_HISTOGRAM_RESET)
return (LPWSTR) _T ("IOCTL_DISK_HISTOGRAM_RESET");
else if (ulCode == IOCTL_DISK_REQUEST_STRUCTURE)
return (LPWSTR) _T ("IOCTL_DISK_REQUEST_STRUCTURE");
else if (ulCode == IOCTL_DISK_REQUEST_DATA)
return (LPWSTR) _T ("IOCTL_DISK_REQUEST_DATA");
else if (ulCode == IOCTL_DISK_CONTROLLER_NUMBER)
return (LPWSTR) _T ("IOCTL_DISK_CONTROLLER_NUMBER");
else if (ulCode == SMART_GET_VERSION)
return (LPWSTR) _T ("SMART_GET_VERSION");
else if (ulCode == SMART_SEND_DRIVE_COMMAND)
return (LPWSTR) _T ("SMART_SEND_DRIVE_COMMAND");
else if (ulCode == SMART_RCV_DRIVE_DATA)
return (LPWSTR) _T ("SMART_RCV_DRIVE_DATA");
else if (ulCode == IOCTL_DISK_INTERNAL_SET_VERIFY)
return (LPWSTR) _T ("IOCTL_DISK_INTERNAL_SET_VERIFY");
else if (ulCode == IOCTL_DISK_INTERNAL_CLEAR_VERIFY)
return (LPWSTR) _T ("IOCTL_DISK_INTERNAL_CLEAR_VERIFY");
else if (ulCode == IOCTL_DISK_CHECK_VERIFY)
return (LPWSTR) _T ("IOCTL_DISK_CHECK_VERIFY");
else if (ulCode == IOCTL_DISK_MEDIA_REMOVAL)
return (LPWSTR) _T ("IOCTL_DISK_MEDIA_REMOVAL");
else if (ulCode == IOCTL_DISK_EJECT_MEDIA)
return (LPWSTR) _T ("IOCTL_DISK_EJECT_MEDIA");
else if (ulCode == IOCTL_DISK_LOAD_MEDIA)
return (LPWSTR) _T ("IOCTL_DISK_LOAD_MEDIA");
else if (ulCode == IOCTL_DISK_RESERVE)
return (LPWSTR) _T ("IOCTL_DISK_RESERVE");
else if (ulCode == IOCTL_DISK_RELEASE)
return (LPWSTR) _T ("IOCTL_DISK_RELEASE");
else if (ulCode == IOCTL_DISK_FIND_NEW_DEVICES)
return (LPWSTR) _T ("IOCTL_DISK_FIND_NEW_DEVICES");
else if (ulCode == IOCTL_DISK_GET_MEDIA_TYPES)
return (LPWSTR) _T ("IOCTL_DISK_GET_MEDIA_TYPES");
else if (ulCode == IOCTL_STORAGE_SET_HOTPLUG_INFO)
return (LPWSTR) _T ("IOCTL_STORAGE_SET_HOTPLUG_INFO");
else if (ulCode == IRP_MJ_READ)
return (LPWSTR) _T ("IRP_MJ_READ");
else if (ulCode == IRP_MJ_WRITE)
return (LPWSTR) _T ("IRP_MJ_WRITE");
else if (ulCode == IRP_MJ_CREATE)
return (LPWSTR) _T ("IRP_MJ_CREATE");
else if (ulCode == IRP_MJ_CLOSE)
return (LPWSTR) _T ("IRP_MJ_CLOSE");
else if (ulCode == IRP_MJ_CLEANUP)
return (LPWSTR) _T ("IRP_MJ_CLEANUP");
else if (ulCode == IRP_MJ_FLUSH_BUFFERS)
return (LPWSTR) _T ("IRP_MJ_FLUSH_BUFFERS");
else if (ulCode == IRP_MJ_SHUTDOWN)
return (LPWSTR) _T ("IRP_MJ_SHUTDOWN");
else if (ulCode == IRP_MJ_DEVICE_CONTROL)
return (LPWSTR) _T ("IRP_MJ_DEVICE_CONTROL");
else
{
return (LPWSTR) _T ("IOCTL");
}
}
#endif
PDEVICE_OBJECT
TCDeleteDeviceObject (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension)
{
PDEVICE_OBJECT OldDeviceObject = DeviceObject;
UNICODE_STRING Win32NameString;
NTSTATUS ntStatus;
Dump ("TCDeleteDeviceObject BEGIN\n");
if (Extension->bRootDevice)
{
RtlInitUnicodeString (&Win32NameString, (LPWSTR) DOS_ROOT_PREFIX);
ntStatus = IoDeleteSymbolicLink (&Win32NameString);
if (!NT_SUCCESS (ntStatus))
Dump ("IoDeleteSymbolicLink failed ntStatus = 0x%08x\n", ntStatus);
}
else
{
if (Extension->peThread != NULL)
TCStopVolumeThread (DeviceObject, Extension);
if (DeviceObject->ReferenceCount > 0)
ReferencedDeviceDeleted = TRUE;
// Forced dismount does not set reference count to zero even if all open handles are closed
Dump ("Deleting device with ref count %ld\n", DeviceObject->ReferenceCount);
DeviceObject->ReferenceCount = 0;
}
if (DeviceObject != NULL)
DeviceObject = DeviceObject->NextDevice;
IoDeleteDevice (OldDeviceObject);
Dump ("TCDeleteDeviceObject END\n");
return DeviceObject;
}
VOID
TCUnloadDriver (PDRIVER_OBJECT DriverObject)
{
PDEVICE_OBJECT DeviceObject = DriverObject->DeviceObject;
Dump ("TCUnloadDriver BEGIN\n");
UnmountAllDevices (NULL, DeviceObject, TRUE);
/* Now walk the list of driver objects and get rid of them */
while (DeviceObject != (PDEVICE_OBJECT) NULL)
{
DeviceObject = TCDeleteDeviceObject (DeviceObject,
(PEXTENSION) DeviceObject->DeviceExtension);
}
WipeCache ();
if (IsBootDriveMounted())
TC_BUG_CHECK (STATUS_INVALID_DEVICE_STATE);
EncryptionThreadPoolStop();
Dump ("TCUnloadDriver END\n");
}
NTSTATUS
TCDeviceIoControl (PWSTR deviceName, ULONG IoControlCode,
void *InputBuffer, int InputBufferSize, void *OutputBuffer, int OutputBufferSize)
{
IO_STATUS_BLOCK ioStatusBlock;
NTSTATUS ntStatus;
PIRP irp;
PFILE_OBJECT fileObject;
PDEVICE_OBJECT deviceObject;
KEVENT event;
UNICODE_STRING name;
RtlInitUnicodeString(&name, deviceName);
ntStatus = IoGetDeviceObjectPointer (&name, FILE_READ_ATTRIBUTES, &fileObject, &deviceObject);
if (ntStatus != STATUS_SUCCESS)
return ntStatus;
KeInitializeEvent(&event, NotificationEvent, FALSE);
irp = IoBuildDeviceIoControlRequest (IoControlCode,
deviceObject,
InputBuffer, InputBufferSize,
OutputBuffer, OutputBufferSize,
FALSE,
&event,
&ioStatusBlock);
if (irp == NULL)
{
Dump ("IRP allocation failed\n");
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
goto ret;
}
ntStatus = IoCallDriver (deviceObject, irp);
if (ntStatus == STATUS_PENDING)
{
KeWaitForSingleObject (&event, Executive, KernelMode, FALSE, NULL);
ntStatus = ioStatusBlock.Status;
}
ret:
ObDereferenceObject (fileObject);
return ntStatus;
}
NTSTATUS SendDeviceIoControlRequest (PDEVICE_OBJECT deviceObject, ULONG ioControlCode, void *inputBuffer, int inputBufferSize, void *outputBuffer, int outputBufferSize)
{
IO_STATUS_BLOCK ioStatusBlock;
NTSTATUS status;
PIRP irp;
KEVENT event;
ASSERT(KeGetCurrentIrql() <= APC_LEVEL);
KeInitializeEvent (&event, NotificationEvent, FALSE);
irp = IoBuildDeviceIoControlRequest (ioControlCode, deviceObject, inputBuffer, inputBufferSize,
outputBuffer, outputBufferSize, FALSE, &event, &ioStatusBlock);
if (!irp)
return STATUS_INSUFFICIENT_RESOURCES;
ObReferenceObject (deviceObject);
status = IoCallDriver (deviceObject, irp);
if (status == STATUS_PENDING)
{
KeWaitForSingleObject (&event, Executive, KernelMode, FALSE, NULL);
status = ioStatusBlock.Status;
}
ObDereferenceObject (deviceObject);
return status;
}
NTSTATUS ProbeRealDriveSize (PDEVICE_OBJECT driveDeviceObject, LARGE_INTEGER *driveSize)
{
NTSTATUS status;
LARGE_INTEGER sysLength;
LARGE_INTEGER offset;
byte *sectorBuffer;
ULONGLONG startTime;
if (!UserCanAccessDriveDevice())
return STATUS_ACCESS_DENIED;
sectorBuffer = TCalloc (SECTOR_SIZE);
if (!sectorBuffer)
return STATUS_INSUFFICIENT_RESOURCES;
status = SendDeviceIoControlRequest (driveDeviceObject, IOCTL_DISK_GET_LENGTH_INFO,
NULL, 0, &sysLength, sizeof (sysLength));
if (!NT_SUCCESS (status))
{
Dump ("Failed to get drive size - error %x\n",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -