📄 ntdriver.c
字号:
{
DriverMutexWait ();
unmount->nReturnCode = UnmountDevice (ListDevice, unmount->ignoreOpenFiles);
DriverMutexRelease ();
break;
}
}
Irp->IoStatus.Information = sizeof (UNMOUNT_STRUCT);
Irp->IoStatus.Status = STATUS_SUCCESS;
}
break;
case UNMOUNT_ALL:
if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (UNMOUNT_STRUCT))
{
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
}
else
{
UNMOUNT_STRUCT *unmount = (UNMOUNT_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
unmount->nReturnCode = UnmountAllDevices (DeviceObject, unmount->ignoreOpenFiles);
Irp->IoStatus.Information = sizeof (UNMOUNT_STRUCT);
Irp->IoStatus.Status = STATUS_SUCCESS;
}
break;
}
/* Finish the I/O operation by simply completing the packet and
returning the same NTSTATUS as in the packet itself. */
ntStatus = COMPLETE_IRP (DeviceObject, Irp, Irp->IoStatus.Status, Irp->IoStatus.Information);
Dump ("TCDeviceControl NTSTATUS = 0x%08x END\n", ntStatus);
return ntStatus;
}
NTSTATUS
TCStartThread (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension, MOUNT_STRUCT * mount)
{
PTHREAD_BLOCK pThreadBlock = TCalloc (sizeof (THREAD_BLOCK));
HANDLE hThread;
NTSTATUS ntStatus;
Dump ("Starting thread...\n");
if (pThreadBlock == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
else
{
pThreadBlock->DeviceObject = DeviceObject;
pThreadBlock->mount = mount;
}
Extension->bThreadShouldQuit = FALSE;
ntStatus = PsCreateSystemThread (&hThread,
THREAD_ALL_ACCESS,
NULL,
NULL,
NULL,
TCThreadIRP,
pThreadBlock);
if (!NT_SUCCESS (ntStatus))
{
Dump ("PsCreateSystemThread Failed END\n");
TCfree (pThreadBlock);
return ntStatus;
}
ObReferenceObjectByHandle (hThread,
THREAD_ALL_ACCESS,
NULL,
KernelMode,
&Extension->peThread,
NULL);
ZwClose (hThread);
Dump ("Waiting for thread to initialize...\n");
KeWaitForSingleObject (&Extension->keCreateEvent,
UserRequest,
UserMode,
FALSE,
NULL);
Dump ("Waiting completed! Thread returns 0x%08x\n", pThreadBlock->ntCreateStatus);
ntStatus = pThreadBlock->ntCreateStatus;
TCfree (pThreadBlock);
return ntStatus;
}
void
TCStopThread (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,
UserRequest,
UserMode,
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;
duetime.QuadPart = (__int64) milliSeconds * -10000;
KeInitializeTimerEx(timer, NotificationTimer);
KeSetTimerEx(timer, duetime, 0, NULL);
KeWaitForSingleObject (timer, UserRequest, UserMode, FALSE, NULL);
TCfree (timer);
}
/* TCThreadIRP does all the work of processing IRP's, and dispatching them
to either the ReadWrite function or the DeviceControl function */
VOID
TCThreadIRP (PVOID Context)
{
PTHREAD_BLOCK pThreadBlock = (PTHREAD_BLOCK) Context;
PDEVICE_OBJECT DeviceObject = pThreadBlock->DeviceObject;
PDRIVER_OBJECT DriverObject = DeviceObject->DriverObject;
PEXTENSION Extension = (PEXTENSION) DeviceObject->DeviceExtension;
LARGE_INTEGER queueWait;
BOOL bDevice;
/* Set thread priority to lowest realtime level. */
KeSetPriorityThread (KeGetCurrentThread (), LOW_REALTIME_PRIORITY);
queueWait.QuadPart = -WAIT_SECONDS (1);
Dump ("Mount THREAD OPENING VOLUME BEGIN\n");
#ifdef USE_KERNEL_MUTEX
KeWaitForMutexObject (&Extension->KernelMutex, Executive, KernelMode,
FALSE, NULL);
#endif
if (memcmp (pThreadBlock->mount->wszVolume, WIDE ("\\Device"), 14) != 0)
{
wcscpy (pThreadBlock->wszMountVolume, WIDE ("\\??\\"));
wcscat (pThreadBlock->wszMountVolume, pThreadBlock->mount->wszVolume);
bDevice = FALSE;
}
else
{
wcscpy (pThreadBlock->wszMountVolume, pThreadBlock->mount->wszVolume);
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);
#ifdef USE_KERNEL_MUTEX
KeReleaseMutex (&Extension->KernelMutex, FALSE);
#endif
if (!NT_SUCCESS (pThreadBlock->ntCreateStatus) || pThreadBlock->mount->nReturnCode != 0)
{
KeSetEvent (&Extension->keCreateEvent, 0, FALSE);
PsTerminateSystemThread (STATUS_SUCCESS);
}
else
{
KeSetEvent (&Extension->keCreateEvent, 0, FALSE);
/* From this point on pThreadBlock cannot be used as it will
have been released! */
pThreadBlock = NULL;
}
for (;;)
{
NTSTATUS ntStatus;
ASSERT (KeGetCurrentIrql ()== PASSIVE_LEVEL);
/* Wait for a request from the dispatch routines. */
ntStatus = KeWaitForSingleObject ((PVOID) & Extension->RequestSemaphore,
Executive, KernelMode, FALSE, &queueWait);
if (ntStatus != STATUS_TIMEOUT)
{
#ifdef USE_KERNEL_MUTEX
KeWaitForMutexObject (&Extension->KernelMutex, Executive, KernelMode,
FALSE, NULL);
#endif
// Dump ("DRIVER THREAD PROCESSING DEVICEOBJECT 0x%08x \n", DeviceObject);
for (;;)
{
PIO_STACK_LOCATION irpSp;
PLIST_ENTRY request;
PIRP Irp;
request = ExInterlockedRemoveHeadList (&Extension->ListEntry,
&Extension->ListSpinLock);
if (request == NULL)
break;
ASSERT (KeGetCurrentIrql ()== PASSIVE_LEVEL);
Irp = CONTAINING_RECORD (request, IRP, Tail.Overlay.ListEntry);
irpSp = IoGetCurrentIrpStackLocation (Irp);
switch (irpSp->MajorFunction)
{
case IRP_MJ_READ:
case IRP_MJ_WRITE:
TCReadWrite (DeviceObject, Extension, Irp);
break;
case IRP_MJ_FLUSH_BUFFERS:
if (Extension->bRawDevice == FALSE)
TCSendIRP_FileDevice (DeviceObject, Extension, NULL, Irp->Flags, IRP_MJ_FLUSH_BUFFERS, Irp);
else
{
COMPLETE_IRP (DeviceObject, Irp, STATUS_SUCCESS, 0);
}
break;
case IRP_MJ_SHUTDOWN:
COMPLETE_IRP (DeviceObject, Irp, STATUS_SUCCESS, 0);
break;
case IRP_MJ_DEVICE_CONTROL:
if (irpSp->Parameters.DeviceIoControl.IoControlCode != IOCTL_DISK_CHECK_VERIFY)
TCDeviceControl (DeviceObject, Extension, Irp);
else
{
if (Extension->bRawDevice == TRUE)
TCSendIRP_RawDevice (DeviceObject, Extension, NULL, 0, IRP_MJ_DEVICE_CONTROL, Irp);
else
TCDeviceControl (DeviceObject, Extension, Irp);
}
break;
} /* end of switch on
irpSp->MajorFunction */
} /* for any remaining IRP's for this device */
#ifdef USE_KERNEL_MUTEX
KeReleaseMutex (&Extension->KernelMutex, FALSE);
#endif
if (Extension->bThreadShouldQuit)
{
// Dump ("END PROCESSING DEVICEOBJECT THREAD ENDING 0x%08x Number = %d\n",
// DeviceObject, Extension->nDosDriveNo);
Dump ("Closing volume along with Thread!\n");
TCCloseVolume (DeviceObject, Extension);
PsTerminateSystemThread (STATUS_SUCCESS);
}
//else
//{
// Dump ("END PROCESSING DEVICEOBJECT 0x%08x Number = %d\n",
// DeviceObject, Extension->nDosDriveNo);
//}
}
} /* outermost for */
}
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)
{
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 if (ulCode == MOUNT)
return (LPWSTR) _T ("MOUNT");
else if (ulCode == UNMOUNT)
return (LPWSTR) _T ("UNMOUNT");
else if (ulCode == UNMOUNT_ALL)
return (LPWSTR) _T ("UNMOUNT_ALL");
else if (ulCode == MOUNT_LIST)
return (LPWSTR) _T ("MOUNT_LIST");
else if (ulCode == OPEN_TEST)
return (LPWSTR) _T ("OPEN_TEST");
else if (ulCode == VOLUME_PROPERTIES)
return (LPWSTR) _T ("VOLUME_PROPERTIES");
else if (ulCode == DRIVER_VERSION)
return (LPWSTR) _T ("DRIVER_VERSION");
else if (ulCode == CACHE_STATUS)
return (LPWSTR) _T ("CACHE_STATUS");
else if (ulCode == WIPE_CACHE)
return (LPWSTR) _T ("WIPE_CACHE");
else if (ulCode == RESOLVE_SYMLINK)
return (LPWSTR) _T ("RESOLVE_SYMLINK");
else
{
Dump("Unknown IOCTL recieved: DeviceType = 0x%x Function = 0x%x\n", (int)(ulCode>>16), (int)((ulCode&0x1FFF)>>2));
return (LPWSTR) _T ("UNKNOWN");
}
}
#endif
PDEVICE_OBJECT
TCDeleteDeviceObject (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension)
{
PDEVICE_OBJECT OldDeviceObject = DeviceObject;
UNICODE_STRING Win32NameString;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -