📄 ntdriver.c
字号:
FALSE,
NULL);
if (ntStatus != STATUS_SUCCESS)
Dump ("Failed waiting for crypto thread to quit: 0x%08x...\n",
ntStatus);
ObDereferenceObject (Extension->peThread);
Extension->peThread = NULL;
Dump ("Thread exited\n");
}
// Suspend current thread for a number of milliseconds
void TCSleep (int milliSeconds)
{
PKTIMER timer = (PKTIMER) TCalloc (sizeof (KTIMER));
LARGE_INTEGER duetime;
if (!timer)
return;
duetime.QuadPart = (__int64) milliSeconds * -10000;
KeInitializeTimerEx(timer, NotificationTimer);
KeSetTimerEx(timer, duetime, 0, NULL);
KeWaitForSingleObject (timer, Executive, KernelMode, FALSE, NULL);
TCfree (timer);
}
/* VolumeThreadProc does all the work of processing IRP's, and dispatching them
to either the ReadWrite function or the DeviceControl function */
VOID VolumeThreadProc (PVOID Context)
{
PTHREAD_BLOCK pThreadBlock = (PTHREAD_BLOCK) Context;
PDEVICE_OBJECT DeviceObject = pThreadBlock->DeviceObject;
PEXTENSION Extension = (PEXTENSION) DeviceObject->DeviceExtension;
BOOL bDevice;
/* Set thread priority to lowest realtime level. */
KeSetPriorityThread (KeGetCurrentThread (), LOW_REALTIME_PRIORITY);
Dump ("Mount THREAD OPENING VOLUME BEGIN\n");
if (memcmp (pThreadBlock->mount->wszVolume, WIDE ("\\Device"), 14) != 0)
{
wcscpy (pThreadBlock->wszMountVolume, WIDE ("\\??\\"));
wcsncat (pThreadBlock->wszMountVolume, pThreadBlock->mount->wszVolume,
sizeof (pThreadBlock->wszMountVolume) / 2 - 5);
bDevice = FALSE;
}
else
{
pThreadBlock->wszMountVolume[0] = 0;
wcsncat (pThreadBlock->wszMountVolume, pThreadBlock->mount->wszVolume,
sizeof (pThreadBlock->wszMountVolume) / 2 - 1);
bDevice = TRUE;
}
Dump ("Mount THREAD request for File %ls DriveNumber %d Device = %d\n",
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;
if (Extension->SecurityClientContextValid)
Extension->Queue.SecurityClientContext = &Extension->SecurityClientContext;
else
Extension->Queue.SecurityClientContext = NULL;
pThreadBlock->ntCreateStatus = EncryptedIoQueueStart (&Extension->Queue);
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_ABORT_DECOY_SYSTEM_WIPE);
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_DECOY_SYSTEM_WIPE_RESULT);
TC_CASE_RET_NAME (TC_IOCTL_GET_DECOY_SYSTEM_WIPE_STATUS);
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_START_DECOY_SYSTEM_WIPE);
TC_CASE_RET_NAME (TC_IOCTL_WAS_REFERENCED_DEVICE_DELETED);
TC_CASE_RET_NAME (TC_IOCTL_WIPE_PASSWORD_CACHE);
TC_CASE_RET_NAME (TC_IOCTL_WRITE_BOOT_DRIVE_SECTOR);
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 (Extension->UserSid)
TCfree (Extension->UserSid);
if (Extension->SecurityClientContextValid)
{
if (OsMajorVersion == 5 && OsMinorVersion == 0)
{
ObDereferenceObject (Extension->SecurityClientContext.ClientToken);
}
else
{
// Windows 2000 does not support PsDereferenceImpersonationToken() used by SeDeleteClientSecurity().
// TODO: Use only SeDeleteClientSecurity() once support for Windows 2000 is dropped.
VOID (*PsDereferenceImpersonationTokenD) (PACCESS_TOKEN ImpersonationToken);
UNICODE_STRING name;
RtlInitUnicodeString (&name, L"PsDereferenceImpersonationToken");
PsDereferenceImpersonationTokenD = MmGetSystemRoutineAddress (&name);
if (!PsDereferenceImpersonationTokenD)
TC_BUG_CHECK (STATUS_NOT_IMPLEMENTED);
# define PsDereferencePrimaryToken
# define PsDereferenceImpersonationToken PsDereferenceImpersonationTokenD
SeDeleteClientSecurity (&Extension->SecurityClientContext);
# undef PsDereferencePrimaryToken
# undef PsDereferenceImpersonationToken
}
}
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 (
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -