查看文章 |
3.创建一个线程处理卷的挂载 ntStatus = TCStartVolumeThread (NewDeviceObject, NewExtension, mount); //创建一个卷处理线程
TSTATUS TCStartVolumeThread (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension, MOUNT_STRUCT * mount) { PTHREAD_BLOCK pThreadBlock = TCalloc (sizeof (THREAD_BLOCK)); HANDLE hThread; NTSTATUS ntStatus; OBJECT_ATTRIBUTES threadObjAttributes; SECURITY_QUALITY_OF_SERVICE qos;
Dump ("Starting thread...\n");
if (pThreadBlock == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } else { pThreadBlock->DeviceObject = DeviceObject; pThreadBlock->mount = mount; }
qos.Length = sizeof (qos); qos.ContextTrackingMode = SECURITY_STATIC_TRACKING; qos.EffectiveOnly = TRUE; qos.ImpersonationLevel = SecurityImpersonation;
ntStatus = SeCreateClientSecurity (PsGetCurrentThread(), &qos, FALSE, &Extension->SecurityClientContext); if (!NT_SUCCESS (ntStatus)) goto ret;
Extension->SecurityClientContextValid = TRUE;
Extension->bThreadShouldQuit = FALSE;
InitializeObjectAttributes (&threadObjAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
ntStatus = PsCreateSystemThread (&hThread, THREAD_ALL_ACCESS, &threadObjAttributes, NULL, NULL, VolumeThreadProc, pThreadBlock); //创建线程
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); //等待一个创建完成的事件 调用完EncryptedIoQueueStart后设置
Dump ("Waiting completed! Thread returns 0x%08x\n", pThreadBlock->ntCreateStatus); ntStatus = pThreadBlock->ntCreateStatus;
ret: TCfree (pThreadBlock); return ntStatus; }
看看这个线程都干了什么:
VolumeThreadProc做所有IRP的处理工作,并派遣他们无论是读写功能或DeviceControl功能 /* 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); //设备对象名字 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); //打开这个对象,这里比较复杂自己看下源代码 /* NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension, MOUNT_STRUCT *mount, PWSTR pwszMountVolume, BOOL bRawDevice) */ if (!NT_SUCCESS (pThreadBlock->ntCreateStatus) || pThreadBlock->mount->nReturnCode != 0) { KeSetEvent (&Extension->keCreateEvent, 0, FALSE); PsTerminateSystemThread (STATUS_SUCCESS); } //失败的操作
// Start IO queue 保持设备上记录的信息,比如cryptoInfo Extension->Queue.IsFilterDevice = FALSE; Extension->Queue.DeviceObject = DeviceObject; Extension->Queue.CryptoInfo = Extension->cryptoInfo; Extension->Queue.HostFileHandle = Extension->hDeviceFile; Extension->Queue.VirtualDeviceLength = Extension->DiskLength; Extension->Queue.MaxReadAheadOffset.QuadPart = Extension->HostLength;
if (Extension->SecurityClientContextValid) Extension->Queue.SecurityClientContext = &Extension->SecurityClientContext; else Extension->Queue.SecurityClientContext = NULL; //注意下这里创建了3个事务线程 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); //等待到收到一个IRP_MJ_DEVICE_CONTROL 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);
ASSERT (irpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL);
ProcessVolumeDeviceControlIrp (DeviceObject, Extension, irp); IoReleaseRemoveLock (&Extension->Queue.RemoveLock, irp); }
if (Extension->bThreadShouldQuit) { Dump ("Closing volume\n"); EncryptedIoQueueStop (&Extension->Queue);
TCCloseVolume (DeviceObject, Extension); PsTerminateSystemThread (STATUS_SUCCESS); } } } |

