00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00020 #include <wdm.h>
00021 #include "cbm_driver.h"
00022
00034 NTSTATUS
00035 cbm_start_thread(IN PDEVICE_EXTENSION Pdx)
00036 {
00037 NTSTATUS ntStatus;
00038 PDEVICE_OBJECT fdo;
00039
00040 FUNC_ENTER();
00041
00042 DBG_ASSERT(Pdx != NULL);
00043
00044
00045
00046 fdo = Pdx->Fdo;
00047
00048 DBG_ASSERT(fdo != NULL);
00049
00050
00051
00052
00053 DBG_ASSERT(Pdx->ThreadHandle == 0);
00054 DBG_ASSERT(Pdx->Thread == 0);
00055
00056 PERF_EVENT_THREAD_START_SCHED();
00057
00058
00060
00061 Pdx->QuitThread = FALSE;
00062
00063
00064
00065 DBG_IRQL( == PASSIVE_LEVEL);
00066 ntStatus = PsCreateSystemThread(&Pdx->ThreadHandle,
00067 THREAD_ALL_ACCESS,
00068 NULL,
00069 NULL,
00070 NULL,
00071 cbm_thread,
00072 Pdx);
00073
00074 if (!NT_SUCCESS(ntStatus))
00075 {
00076
00077
00078 DBG_ERROR((DBG_PREFIX "Creation of system thread FAILED, deleting device"));
00079 LogErrorString(fdo, CBM_START_FAILED, L"creation of the system thread.", NULL);
00080 }
00081 else
00082 {
00083
00084
00085
00086
00087
00088 DBG_IRQL( == PASSIVE_LEVEL);
00089 ObReferenceObjectByHandle(Pdx->ThreadHandle,
00090 THREAD_ALL_ACCESS, NULL, KernelMode, &Pdx->Thread, NULL);
00091
00092 DBG_ASSERT(Pdx->Thread);
00093
00094 if (Pdx->Thread)
00095 {
00096
00097
00098 DBG_IRQL( == PASSIVE_LEVEL);
00099 KeSetPriorityThread(Pdx->Thread, LOW_REALTIME_PRIORITY);
00100 }
00101 }
00102
00103 FUNC_LEAVE_NTSTATUS(ntStatus);
00104 }
00105
00117 VOID
00118 cbm_stop_thread(IN PDEVICE_EXTENSION Pdx)
00119 {
00120 FUNC_ENTER();
00121
00122 DBG_ASSERT(Pdx != NULL);
00123 DBG_ASSERT(Pdx->QuitThread == FALSE);
00124 DBG_ASSERT(Pdx->ThreadHandle != 0);
00125 DBG_ASSERT(Pdx->Thread != 0);
00126
00127 if ((Pdx->ThreadHandle != 0) && (Pdx->Thread != 0))
00128 {
00129 PERF_EVENT_THREAD_STOP_SCHED();
00130
00131
00132
00133 Pdx->QuitThread = TRUE;
00134
00135
00136
00137 QueueSignal(&Pdx->IrpQueue);
00138
00139
00140
00141 KeWaitForSingleObject(Pdx->Thread, Executive, KernelMode, FALSE, NULL);
00142
00143
00144
00145 ObDereferenceObject(Pdx->Thread);
00146 ZwClose(Pdx->ThreadHandle);
00147
00148
00149
00150 Pdx->Thread = NULL;
00151 Pdx->ThreadHandle = 0;
00152 }
00153
00154 FUNC_LEAVE();
00155 }
00156
00165 VOID
00166 cbm_thread(IN PVOID Context)
00167 {
00168 PDEVICE_EXTENSION pdx;
00169 NTSTATUS ntStatus;
00170
00171 FUNC_ENTER();
00172
00173 PERF_EVENT_THREAD_START_EXEC();
00174
00175
00176
00177 pdx = Context;
00178
00179
00180
00181 ntStatus = STATUS_SUCCESS;
00182
00183
00184
00185 while (!pdx->QuitThread)
00186 {
00187 PERF_EVENT_THREAD_POLL();
00188
00189
00190
00191 ntStatus = QueuePoll(&pdx->IrpQueue, pdx->Fdo);
00192 }
00193
00194 PERF_EVENT_THREAD_STOP_EXEC();
00195
00196
00197
00198 DBG_IRQL( == PASSIVE_LEVEL);
00199 PsTerminateSystemThread(ntStatus);
00200
00201 FUNC_LEAVE();
00202 }