| SlavaI 
								Главный специалист    Offline | 
								|  | « Ответ #1 : 24-09-2003 07:37 »  |  | 
 
 Да все просто. Если нужна абсолютная независимость чтения/записи(то есть дуплекс) то делай два потока(если один поток то будет полудуплекс), каждый из котрых ждет на событии, в драйвере помещаешь IRP в очередь, для чего можешь сделать простенькую структурку
 struct Irp_Container
 {
 LIST_ENTRY ListEntry;
 PIRP Irp;
 };
 
 создаешь два события
 
 KEVENT                  global_ReadEvent;
 KEVENT                  global_WriteEvent;
 
 инициализируешь их до первого использования
 
 KeInitializeEvent(&global_ReadEvent,SynchronizationEvent,FALSE);
 KeInitializeEvent(&global_WriteEvent,SynchronizationEvent,FALSE);
 
 создаешь заголовки двух очередей
 
 LIST_ENTRY              global_read_list;
 LIST_ENTRY              global_write_list;
 
 также инициализируешь до первого использования
 
 InitializeListHead(&global_read_list);
 InitializeListHead(&global_write_list);
 
 создаешь спин блокировки для блокирования доступа к спискам
 
 KSPIN_LOCK  global_SpinLockRead;
 KSPIN_LOCK  global_SpinLockWrite;
 
 также инициализируешь до первого использования
 
 KeInitializeSpinLock(&global_SpinLockRead);
 KeInitializeSpinLock(&global_SpinLockWrite);
 
 Делаешь ф-ции потоков(показываю только одну)
 
 VOID ReadIrpThread (IN PVOID Context)
 {
 PLIST_ENTRY                  request;
 PIRP                              pIrp;
 Irp_Container*               pReadIrp ;
 
 KeSetPriorityThread(KeGetCurrentThread(),LOW_REALTIME_PRIORITY);
 
 while (TRUE)
 {
 KeWaitForSingleObject(&global_ReadEvent,Executive,KernelMode,FALSE,NULL);
 
 while (request = ExInterlockedRemoveHeadList(&global_read_list,&global_SpinLockRead))
 {
 pReadIrp= CONTAINING_RECORD(request,Irp_Container,ListEntry);
 pIrp = pReadIrp->Irp;
 ...................................................
 тут обрабатываешь Irp
 }
 if (InterlockedCompareExchange(&global_TerminateReadThread,0,0))
 {
 dprintf("Terminating Thread\n");
 PsTerminateSystemThread(STATUS_SUCCESS);
 }
 
 }
 
 }
 
 в драйвере  помещаешь IRP в очередь и савишь event в сигнальное состояние, поток проснется и вынет его из очереди и обработает. Память под структуру Irp_Container выделяй из неподкачиваемого пула и не забывай освобождать после того как из очереди в потоке обработки вынешь. Вот как помещать в очередь
 
 Irp_Container* pIrpContainer;
 pIrpContainer = ExAllocatePool(NonPagedPool,....);
 pIrpContainer->Irp=Irp;
 
 ExInterlockedInsertTailList(&global_read_list,&pIrpContainer->ListEntry,&global_SpinLockRead);
 
 // Sending Event to ReadIrpThread
 KeSetEvent(&g_AccessThreadEvent,(KPRIORITY)0,FALSE);
 
 Для остановки потока ставишь переменную  global_TerminateReadThread в и 1 переводишь событие в сигнальное состояние.
 Потоки создаешь при помощи PsCreateSystemThread.
 Продумай, что ты будешь делать после откладывания IRP на обработку- возваращать STATUS_PENDING или блокировать и ждать обработки этого IRP.
 Есть еще системные очереди, но я их не использую.
 И подумай насколько тебе нужны очереди, может и без них можно?
 |