📄 ntdriver.c
字号:
ObDereferenceObject (fileObject);
if (status == STATUS_TIMEOUT)
{
request->TimeOut = TRUE;
Irp->IoStatus.Information = sizeof (ProbeRealDriveSizeRequest);
Irp->IoStatus.Status = STATUS_SUCCESS;
}
else if (!NT_SUCCESS (status))
{
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = status;
}
else
{
request->TimeOut = FALSE;
Irp->IoStatus.Information = sizeof (ProbeRealDriveSizeRequest);
Irp->IoStatus.Status = status;
}
}
break;
case TC_IOCTL_MOUNT_VOLUME:
if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (MOUNT_STRUCT))
{
Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
Irp->IoStatus.Information = 0;
}
else
{
MOUNT_STRUCT *mount = (MOUNT_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
if (mount->VolumePassword.Length > MAX_PASSWORD)
{
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
break;
}
EnsureNullTerminatedString (mount->wszVolume, sizeof (mount->wszVolume));
DriverMutexWait ();
Irp->IoStatus.Information = sizeof (MOUNT_STRUCT);
Irp->IoStatus.Status = MountDevice (DeviceObject, mount);
DriverMutexRelease ();
burn (&mount->VolumePassword, sizeof (mount->VolumePassword));
burn (&mount->ProtectedHidVolPassword, sizeof (mount->ProtectedHidVolPassword));
}
break;
case TC_IOCTL_DISMOUNT_VOLUME:
if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (UNMOUNT_STRUCT)
|| !DeviceObject || !DeviceObject->DriverObject)
{
Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
Irp->IoStatus.Information = 0;
}
else
{
UNMOUNT_STRUCT *unmount = (UNMOUNT_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
PDEVICE_OBJECT ListDevice;
unmount->nReturnCode = ERR_DRIVE_NOT_FOUND;
for (ListDevice = DeviceObject->DriverObject->DeviceObject;
ListDevice != (PDEVICE_OBJECT) NULL;
ListDevice = ListDevice->NextDevice)
{
PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension;
if (!ListExtension->bRootDevice
&& ListExtension->IsVolumeDevice
&& !ListExtension->bShuttingDown
&& unmount->nDosDriveNo == ListExtension->nDosDriveNo)
{
DriverMutexWait ();
unmount->nReturnCode = UnmountDevice (unmount, ListDevice, unmount->ignoreOpenFiles);
DriverMutexRelease ();
break;
}
}
Irp->IoStatus.Information = sizeof (UNMOUNT_STRUCT);
Irp->IoStatus.Status = STATUS_SUCCESS;
}
break;
case TC_IOCTL_DISMOUNT_ALL_VOLUMES:
if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (UNMOUNT_STRUCT))
{
Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
Irp->IoStatus.Information = 0;
}
else
{
UNMOUNT_STRUCT *unmount = (UNMOUNT_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
unmount->nReturnCode = UnmountAllDevices (unmount, DeviceObject, unmount->ignoreOpenFiles);
Irp->IoStatus.Information = sizeof (UNMOUNT_STRUCT);
Irp->IoStatus.Status = STATUS_SUCCESS;
}
break;
case TC_IOCTL_BOOT_ENCRYPTION_SETUP:
DriverMutexWait ();
Irp->IoStatus.Status = StartBootEncryptionSetup (DeviceObject, Irp, irpSp);
Irp->IoStatus.Information = 0;
DriverMutexRelease ();
break;
case TC_IOCTL_ABORT_BOOT_ENCRYPTION_SETUP:
DriverMutexWait ();
Irp->IoStatus.Status = AbortBootEncryptionSetup();
Irp->IoStatus.Information = 0;
DriverMutexRelease ();
break;
case TC_IOCTL_GET_BOOT_ENCRYPTION_STATUS:
DriverMutexWait ();
GetBootEncryptionStatus (Irp, irpSp);
DriverMutexRelease ();
break;
case TC_IOCTL_GET_BOOT_ENCRYPTION_SETUP_RESULT:
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = GetSetupResult();
break;
case TC_IOCTL_GET_BOOT_DRIVE_VOLUME_PROPERTIES:
DriverMutexWait ();
GetBootDriveVolumeProperties (Irp, irpSp);
DriverMutexRelease ();
break;
case TC_IOCTL_GET_BOOT_LOADER_VERSION:
DriverMutexWait ();
GetBootLoaderVersion (Irp, irpSp);
DriverMutexRelease ();
break;
case TC_IOCTL_REOPEN_BOOT_VOLUME_HEADER:
DriverMutexWait ();
ReopenBootVolumeHeader (Irp, irpSp);
DriverMutexRelease ();
break;
case TC_IOCTL_GET_BOOT_ENCRYPTION_ALGORITHM_NAME:
DriverMutexWait ();
GetBootEncryptionAlgorithmName (Irp, irpSp);
DriverMutexRelease ();
break;
case TC_IOCTL_IS_HIDDEN_SYSTEM_RUNNING:
if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (int))
{
Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
Irp->IoStatus.Information = 0;
}
else
{
*(int *) Irp->AssociatedIrp.SystemBuffer = IsHiddenSystemRunning() ? 1 : 0;
Irp->IoStatus.Information = sizeof (int);
Irp->IoStatus.Status = STATUS_SUCCESS;
}
break;
default:
return TCCompleteIrp (Irp, STATUS_INVALID_DEVICE_REQUEST, 0);
}
#ifdef DEBUG
if (!NT_SUCCESS (Irp->IoStatus.Status))
{
switch (irpSp->Parameters.DeviceIoControl.IoControlCode)
{
case TC_IOCTL_GET_MOUNTED_VOLUMES:
case TC_IOCTL_GET_PASSWORD_CACHE_STATUS:
case TC_IOCTL_GET_TRAVELER_MODE_STATUS:
case TC_IOCTL_SET_TRAVELER_MODE_STATUS:
case TC_IOCTL_OPEN_TEST:
case TC_IOCTL_GET_RESOLVED_SYMLINK:
case TC_IOCTL_GET_DRIVE_PARTITION_INFO:
case TC_IOCTL_GET_BOOT_DRIVE_VOLUME_PROPERTIES:
case TC_IOCTL_GET_BOOT_ENCRYPTION_STATUS:
case TC_IOCTL_IS_HIDDEN_SYSTEM_RUNNING:
break;
default:
Dump ("IOCTL error 0x%08x\n", Irp->IoStatus.Status);
}
}
#endif
return TCCompleteIrp (Irp, Irp->IoStatus.Status, Irp->IoStatus.Information);
}
NTSTATUS TCStartThread (PKSTART_ROUTINE threadProc, PVOID threadArg, PKTHREAD *kThread)
{
return TCStartThreadInProcess (threadProc, threadArg, kThread, NULL);
}
NTSTATUS TCStartThreadInProcess (PKSTART_ROUTINE threadProc, PVOID threadArg, PKTHREAD *kThread, PEPROCESS process)
{
NTSTATUS status;
HANDLE threadHandle;
HANDLE processHandle = NULL;
OBJECT_ATTRIBUTES threadObjAttributes;
if (process)
{
status = ObOpenObjectByPointer (process, OBJ_KERNEL_HANDLE, NULL, 0, NULL, KernelMode, &processHandle);
if (!NT_SUCCESS (status))
return status;
}
InitializeObjectAttributes (&threadObjAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
status = PsCreateSystemThread (&threadHandle, THREAD_ALL_ACCESS, &threadObjAttributes, processHandle, NULL, threadProc, threadArg);
if (!NT_SUCCESS (status))
return status;
status = ObReferenceObjectByHandle (threadHandle, THREAD_ALL_ACCESS, NULL, KernelMode, (PVOID *) kThread, NULL);
if (!NT_SUCCESS (status))
{
ZwClose (threadHandle);
*kThread = NULL;
return status;
}
if (processHandle)
ZwClose (processHandle);
ZwClose (threadHandle);
return STATUS_SUCCESS;
}
void TCStopThread (PKTHREAD kThread, PKEVENT wakeUpEvent)
{
if (wakeUpEvent)
KeSetEvent (wakeUpEvent, 0, FALSE);
KeWaitForSingleObject (kThread, Executive, KernelMode, FALSE, NULL);
ObDereferenceObject (kThread);
}
NTSTATUS
TCStartVolumeThread (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension, MOUNT_STRUCT * mount)
{
PTHREAD_BLOCK pThreadBlock = TCalloc (sizeof (THREAD_BLOCK));
HANDLE hThread;
NTSTATUS ntStatus;
HANDLE process;
OBJECT_ATTRIBUTES threadObjAttributes;
Dump ("Starting thread...\n");
if (pThreadBlock == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
else
{
pThreadBlock->DeviceObject = DeviceObject;
pThreadBlock->mount = mount;
}
if (mount->bUserContext)
{
ntStatus = ObOpenObjectByPointer (IoGetCurrentProcess (), OBJ_KERNEL_HANDLE, NULL, 0, NULL, KernelMode, &process);
if (!NT_SUCCESS (ntStatus))
{
Dump ("ObOpenObjectByPointer Failed\n");
goto ret;
}
}
else
process = NULL;
Extension->bThreadShouldQuit = FALSE;
InitializeObjectAttributes (&threadObjAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
ntStatus = PsCreateSystemThread (&hThread,
THREAD_ALL_ACCESS,
&threadObjAttributes,
process,
NULL,
VolumeThreadProc,
pThreadBlock);
if (process)
ZwClose (process);
if (!NT_SUCCESS (ntStatus))
{
Dump ("PsCreateSystemThread Failed END\n");
goto ret;
}
ntStatus = ObReferenceObjectByHandle (hThread,
THREAD_ALL_ACCESS,
NULL,
KernelMode,
&Extension->peThread,
NULL);
ZwClose (hThread);
if (!NT_SUCCESS (ntStatus))
goto ret;
Dump ("Waiting for thread to initialize...\n");
KeWaitForSingleObject (&Extension->keCreateEvent,
Executive,
KernelMode,
FALSE,
NULL);
Dump ("Waiting completed! Thread returns 0x%08x\n", pThreadBlock->ntCreateStatus);
ntStatus = pThreadBlock->ntCreateStatus;
ret:
TCfree (pThreadBlock);
return ntStatus;
}
void
TCStopVolumeThread (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension)
{
NTSTATUS ntStatus;
if (DeviceObject); /* Remove compiler warning */
Dump ("Signalling thread to quit...\n");
Extension->bThreadShouldQuit = TRUE;
KeReleaseSemaphore (&Extension->RequestSemaphore,
0,
1,
TRUE);
ntStatus = KeWaitForSingleObject (Extension->peThread,
Executive,
KernelMode,
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",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -