Программирование драйверов Windows


Исполняемый код драйвера - часть 13


таблицу 8.9): ULONG xferSize = pIrpStack-&#62Parameters.DeviceIoControl.InputBufferLength; if( xferSize &#60 1 ) { // Нет данных для отправки в порт: #if DBG==1 DbgPrint("LPTPORT: DeviceControlRoutine: IOCTL_SEND_TO_PORT,\n", " no bytes to transfer.\n"); #endif // Завершение без переноса данных клиенту: return CompleteIrp( pIrp, STATUS_SUCCESS, 0 ); } // if( xferSize &#62 MAX_BUFFER_SIZE ) ? Но размер входящих данных // уже не актуален, поскольку будет использоваться буфер, // поступивший от клиента (точнее, от Диспетчера ввода/вывода). // // Теперь мы ничего не копируем, а просто инициируем процесс // программируемого вывода, откладывая пакет в очередь // необработанных IRP пакетов (не забываем сообщить адрес // процедуры CancelRoutine, которая должна получить управление, // если клиент решит отозвать свой запрос): #if DBG==1 DbgPrint("LPTPORT: DeviceControlRoutine: IOCTL_SEND_TO_PORT,\n" " xfer size is %d Irp is pending.\n", xferSize ); #endif IoMarkIrpPending( pIrp ); IoStartPacket( pDevObj, pIrp, 0, CancelRoutine); return STATUS_PENDING; } case IOCTL_SEND_TO_USER: { // Размер данных, ожидаемых пользователем pDevExt-&#62xferSize = pIrpStack-&#62Parameters.DeviceIoControl.OutputBufferLength; if( pDevExt-&#62xferSize&#62 0 ) { // Согласно таблице 8.9, адрес клиентского буфера при // методе METHOD_BUFFERED в IOCTL запросе находится там // же, что и при обработке обычного запроса Read (см. // первый вариант драйвера, функцию DispatchRead): pDevExt-&#62pUserBuffer = (PUCHAR)pIrp-&#62AssociatedIrp.SystemBuffer; // Пытаемся безопасно перенести данные: KeSynchronizeExecution( pDevExt-&#62pIntObj, TransferToUserSafely, pDevExt ); } // Завершаем обработку IRP пакета: #if DBG==1 DbgPrint("LPTPORT: DeviceControlRoutine: IOCTL_SEND_TO_USER,\n" " %d bytes transferred to user.\n", pDevExt-&#62xferSize); #endif return CompleteIrp( pIrp, STATUS_SUCCESS, pDevExt-&#62xferSize); } case IOCTL_TAKE_EVENT: { // Размер данных, поступивших от клиента драйвера ULONG xferFromDriverSize = pIrpStack-&#62Parameters.DeviceIoControl.OutputBufferLength; if( xferFromDriverSize &#60 sizeof(HANDLE)) { #if DBG==1 DbgPrint("LPTPORT: DeviceControlRoutine: IOCTL_TAKE_EVENT,\n " "event info can not be transferred due to 0 buffer size.\n"); #endif status = STATUS_INVALID_PARAMETER; // Завершение без переноса данных клиенту: return CompleteIrp( pIrp, status, 0 ); // 0 - Нет переноса } if(pDevExt-&#62pEvent==NULL) // Объект события еще не был создан { // для данного клиента. // Создаем объект события типа // SynchronizationEvent, с автоматическим переходом в // несигнальное состояние: #define EVENT_NAME L"\\BaseNamedObjects\\LPTPORT_EVENT" UNICODE_STRING eventName; RtlInitUnicodeString( &eventName, EVENT_NAME );




Начало  Назад  Вперед