//-------------------- // Функция обработки запроса информации о файле // NTSTATUS DispatchQueryInformation(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp) { NTSTATUS status = STATUS_SUCCESS; PIO_STACK_LOCATION pIrpStack; ULONG info = 0; FILE_BASIC_INFORMATION *fbi; FILE_STANDARD_INFORMATION *fsi; pIrpStack = IoGetCurrentIrpStackLocation(pIrp); switch (pIrpStack->Parameters.QueryFile.FileInformationClass) { case FileStandardInformation: info = sizeof(FILE_STANDARD_INFORMATION); if (info > pIrpStack->Parameters.QueryFile.Length) { info = 0; break; } fsi = (FILE_STANDARD_INFORMATION*)pIrp->AssociatedIrp.SystemBuffer; fsi->AllocationSize.QuadPart = 0; fsi->EndOfFile.QuadPart = 1000; // размер файла fsi->NumberOfLinks = 1; // количество жёстких ссылок fsi->Directory = FALSE; fsi->DeletePending = FALSE; break; } return CompleteIrp(pIrp, status, info); }
// // Функция обработки запроса на чтение. // NTSTATUS DispatchRead(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp) { NTSTATUS status = STATUS_SUCCESS; PIO_STACK_LOCATION pIrpStack; ULONG info = 0; char *inputBuffer; PLIST_ENTRY link; pIrpStack = IoGetCurrentIrpStackLocation(pIrp); if (pDeviceObject->Flags & DO_BUFFERED_IO) { inputBuffer = (char*)pIrp->AssociatedIrp.SystemBuffer; } else { inputBuffer = (char*)pIrp->UserBuffer; } for (link = glOpenFiles.Flink; link != &glOpenFiles; link = link->Flink) { OpenFileEntry *entry = CONTAINING_RECORD(link, OpenFileEntry, link); if (info + entry->fileName.Length + 1 <= pIrpStack->Parameters.Read.Length) { RtlCopyMemory(inputBuffer + info, entry->fileName.Buffer, entry->fileName.Length); info += entry->fileName.Length; inputBuffer[info++] = '\n'; } else { break; } } return CompleteIrp(pIrp, status, info); // Завершение IRP }
NTSTATUS SecLabReceivePacket(PADAPT pAdapt,IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp) { // 某一时刻只有一个读IRP被允许存放在队列中 NdisAcquireSpinLock(&ReadIrpLock); if(ReadIrp!=NULL /*&& ReadCount!=0*/) { NdisReleaseSpinLock(&ReadIrpLock); return CompleteIrp(Irp,STATUS_UNSUCCESSFUL,0); } // 看是否成功取出封包数据 if( PickPacketFromList(pAdapt,Irp)) { ReadCount=0; ReadIrp=NULL; NdisReleaseSpinLock(&ReadIrpLock); return STATUS_SUCCESS; } // 如果队列中没有封包数据,就将此IRP排队 ReadIrp = Irp; ReadCount=1; // Mark Irp as pending and set Cancel routine Irp->IoStatus.Information = 0; Irp->IoStatus.Status = STATUS_PENDING; IoMarkIrpPending(Irp); IoSetCancelRoutine(Irp,SecLabCancelIrp); NdisReleaseSpinLock(&ReadIrpLock); return STATUS_PENDING; }
NTSTATUS PnpQueryCapabilitiesHandler( IN PDEVICE_EXTENSION pdx, IN PIRP Irp) { NTSTATUS status = ForwardAndWait( pdx, Irp); if( NT_SUCCESS(status)) { PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp); PDEVICE_CAPABILITIES deviceCapabilities; deviceCapabilities = IrpStack->Parameters.DeviceCapabilities.Capabilities; for(int ds=PowerSystemWorking;ds<PowerSystemMaximum;ds++) KdPrint(("Capabilities from bus: DeviceState[%d]=%d", ds, deviceCapabilities->DeviceState[ds])); DEVICE_POWER_STATE dps; SetMostPoweredState( PowerSystemWorking, PowerDeviceD0); SetMostPoweredState( PowerSystemSleeping1, PowerDeviceD3); SetMostPoweredState( PowerSystemSleeping2, PowerDeviceD3); SetMostPoweredState( PowerSystemSleeping3, PowerDeviceD3); SetMostPoweredState( PowerSystemHibernate, PowerDeviceD3); SetMostPoweredState( PowerSystemShutdown, PowerDeviceD3); //重点就是这句话了 deviceCapabilities->Removable=TRUE; for(ds=PowerSystemWorking;ds<PowerSystemMaximum;ds++) KdPrint(("Capabilities now: DeviceState[%d]=%d", ds, deviceCapabilities->DeviceState[ds])); } return CompleteIrp( Irp, status, Irp->IoStatus.Information); }
NTSTATUS Wdm1Close(IN PDEVICE_OBJECT fdo, IN PIRP Irp) { DebugPrintMsg("Close"); // Complete successfully return CompleteIrp(Irp, STATUS_SUCCESS, 0); }
NTSTATUS Wdm1Write(IN PDEVICE_OBJECT fdo, IN PIRP Irp) { PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp); NTSTATUS status = STATUS_SUCCESS; LONG BytesTxd = 0; // Get call parameters LONGLONG FilePointer = IrpStack->Parameters.Write.ByteOffset.QuadPart; ULONG WriteLen = IrpStack->Parameters.Write.Length; DebugPrint("Write %d bytes from file pointer %d", (int)WriteLen, (int)FilePointer); if (FilePointer < 0) status = STATUS_INVALID_PARAMETER; else { // Get access to the shared buffer KIRQL irql; KeAcquireSpinLock(&BufferLock, &irql); BytesTxd = WriteLen; // (Re)allocate buffer if necessary if (((ULONG)FilePointer) + WriteLen > BufferSize) { ULONG NewBufferSize = ((ULONG)FilePointer) + WriteLen; PVOID NewBuffer = ExAllocatePool(NonPagedPool, NewBufferSize); if (NewBuffer == NULL) { BytesTxd = BufferSize - (ULONG)FilePointer; if (BytesTxd < 0) BytesTxd = 0; } else { RtlZeroMemory(NewBuffer, NewBufferSize); if (Buffer != NULL) { RtlCopyMemory(NewBuffer, Buffer, BufferSize); ExFreePool(Buffer); } Buffer = (PUCHAR)NewBuffer; BufferSize = NewBufferSize; } } // Write to shared memory if (BytesTxd>0 && Buffer != NULL) RtlCopyMemory(Buffer + FilePointer, Irp->AssociatedIrp.SystemBuffer, BytesTxd); // Release shared buffer KeReleaseSpinLock(&BufferLock, irql); } DebugPrint("Write: %d bytes written", (int)BytesTxd); // Complete IRP return CompleteIrp(Irp, status, BytesTxd); }
NTSTATUS Wdm1Create(IN PDEVICE_OBJECT fdo, IN PIRP Irp) { PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp); DebugPrint("Create File is %T", &(IrpStack->FileObject->FileName)); Stack_Init(&s); // Complete successfully return CompleteIrp(Irp, STATUS_SUCCESS, 0); }
VOID CancelQueue(PC0C_IRP_QUEUE pQueue, PLIST_ENTRY pQueueToComplete) { while (pQueue->pCurrent) { PIRP pIrp; pIrp = pQueue->pCurrent; ShiftQueue(pQueue); CompleteIrp(pIrp, STATUS_CANCELLED, pQueueToComplete); } }
// // Функция обработки запроса на открытие устройства драйвера. // NTSTATUS DispatchCreate(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp) { NTSTATUS status = STATUS_SUCCESS; // статус завершения операции ввода/вывода PIO_STACK_LOCATION pIrpStack; // указатель на текущий элемент стека IRP-пакета ULONG info = 0; // количество возвращённых байт pIrpStack = IoGetCurrentIrpStackLocation(pIrp); KdPrint(("Open file %wZ\n", &pIrpStack->FileObject->FileName)); return CompleteIrp(pIrp, status, info); // Завершение IRP }
// // Функция обработки запроса на закрытие устройства драйвера. // NTSTATUS DispatchClose(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp) { NTSTATUS status = STATUS_SUCCESS; PIO_STACK_LOCATION pIrpStack; ULONG info = 0; pIrpStack = IoGetCurrentIrpStackLocation(pIrp); return CompleteIrp(pIrp, status, info); }
VOID SecLabCancelIrp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { IoReleaseCancelSpinLock(Irp->CancelIrql); // If this is our queued read, then unqueue it NdisAcquireSpinLock(&ReadIrpLock); if( Irp==ReadIrp) { ReadIrp = NULL; ReadCount=0; } NdisReleaseSpinLock(&ReadIrpLock); // Whatever Irp it is, just cancel it CompleteIrp(Irp,STATUS_CANCELLED,0); }
NTSTATUS Wdm1Read(IN PDEVICE_OBJECT fdo, IN PIRP Irp) { PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp); NTSTATUS status = STATUS_SUCCESS; LONG BytesTxd = 0; // Get call parameters LONGLONG FilePointer = IrpStack->Parameters.Read.ByteOffset.QuadPart; ULONG ReadLen = IrpStack->Parameters.Read.Length; DebugPrint("Read %d bytes from file pointer %d", (int)ReadLen, (int)FilePointer); // Get access to the shared buffer KIRQL irql; KeAcquireSpinLock(&BufferLock, &irql); // Check file pointer if (FilePointer < 0) status = STATUS_INVALID_PARAMETER; if (FilePointer >= (LONGLONG)BufferSize) status = STATUS_END_OF_FILE; if (status == STATUS_SUCCESS) { // Get transfer count if (((ULONG)FilePointer) + ReadLen > BufferSize) { BytesTxd = BufferSize - (ULONG)FilePointer; if (BytesTxd < 0) BytesTxd = 0; } else BytesTxd = ReadLen; // Read from shared buffer if (BytesTxd>0 && Buffer != NULL) RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, Buffer + FilePointer, BytesTxd); } // Release shared buffer KeReleaseSpinLock(&BufferLock, irql); DebugPrint("Read: %d bytes returned", (int)BytesTxd); // Complete IRP return CompleteIrp(Irp, status, BytesTxd); }
NTSTATUS DriverIrpHandler(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { NTSTATUS Status; BOOLEAN bHandled = FALSE; PIO_STACK_LOCATION currentIrpStack = IoGetCurrentIrpStackLocation(Irp); KLOG(LInfo, "DevObj %p Major %x Minor %x", DeviceObject, currentIrpStack->MajorFunction, currentIrpStack->MinorFunction); Status = KbdDispatchGeneral(&MonitorGetInstance()->Kbd, DeviceObject, Irp, &bHandled); if (bHandled) return Status; if (currentIrpStack->MajorFunction == IRP_MJ_DEVICE_CONTROL) { return DriverDeviceControlHandler(DeviceObject, Irp); } else { return CompleteIrp(Irp, STATUS_SUCCESS, 0); } }
NTSTATUS UsbKbdCreate( IN PDEVICE_OBJECT fdo, IN PIRP Irp) { PUSBKBD_DEVICE_EXTENSION dx = (PUSBKBD_DEVICE_EXTENSION)fdo->DeviceExtension; PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp); DebugPrint( "Create File is %T", &(IrpStack->FileObject->FileName)); if( dx->IODisabled) return CompleteIrp( Irp, STATUS_DEVICE_NOT_CONNECTED, 0); InterlockedIncrement(&dx->OpenHandleCount); // Display USB host controller driver info USBD_VERSION_INFORMATION vi; USBD_GetUSBDIVersion(&vi); DebugPrint("USBDI version %x Supported version %x", vi.USBDI_Version, vi.Supported_USB_Version); // Reset device and select HID keyboard configuration UsbResetDevice(dx); UsbSelectConfiguration(dx); // DebugPrint USB info UsbGetUsbInfo(dx); // DebugPrint string lang ids ULONG StringsLen = 50; PVOID pvstrings; NTSTATUS status = UsbGetSpecifiedDescriptor( dx, pvstrings, USB_STRING_DESCRIPTOR_TYPE, StringsLen); if( NT_SUCCESS(status)) if( StringsLen>0) { PUSB_STRING_DESCRIPTOR strings = (PUSB_STRING_DESCRIPTOR)pvstrings; ULONG LangIds = (strings->bLength - FIELD_OFFSET( USB_STRING_DESCRIPTOR, bString[0]))>>1; DebugPrint("StringsLen %d LangIds %d",StringsLen,LangIds); if( LangIds>0) for( ULONG LangIdNo=0; LangIdNo<LangIds; LangIdNo++) DebugPrint("LangId[%d]=%4x",LangIdNo,strings->bString[LangIdNo]); }
NTSTATUS DriverDeviceControlHandler( IN PDEVICE_OBJECT fdo, IN PIRP Irp ) { NTSTATUS Status = STATUS_SUCCESS; PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp); ULONG ControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode; ULONG method = ControlCode & 0x3; ULONG ResultLength = 0; ULONG InputLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength; ULONG OutputLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength; PVOID Buffer = Irp->AssociatedIrp.SystemBuffer; KeEnterGuardedRegion(); KLOG(LInfo, "IoControl fdo %p, ioctl %x", fdo, ControlCode); if (OutputLength < InputLength) { KLog(LError, "invalid outputlen=%x vs inputlen=%x", OutputLength, InputLength); Status = STATUS_INVALID_PARAMETER; goto complete; } ResultLength = InputLength; switch( ControlCode) { case IOCTL_KMON_INIT: { PKMON_INIT initData = (PKMON_INIT)Buffer; if (InputLength < sizeof(KMON_INIT)) { Status = STATUS_BUFFER_TOO_SMALL; goto complete; } KLog(LInfo, "IOCTL_KMON_INIT"); Status = MonitorStart(initData); break; } case IOCTL_KMON_RELEASE: { PKMON_RELEASE releaseData = (PKMON_RELEASE)Buffer; if (InputLength < sizeof(KMON_RELEASE)) { Status = STATUS_BUFFER_TOO_SMALL; goto complete; } KLog(LInfo, "IOCTL_KMON_RELEASE"); Status = MonitorStop(releaseData); break; } case IOCTL_KMON_OPEN_WINSTA: { POPEN_WINSTA openWinsta = (POPEN_WINSTA)Buffer; if (InputLength < sizeof(OPEN_WINSTA)) { Status = STATUS_BUFFER_TOO_SMALL; goto complete; } Status = MonitorOpenWinsta(openWinsta); break; } case IOCTL_KMON_OPEN_DESKTOP: { POPEN_DESKTOP openDeskop = (POPEN_DESKTOP)Buffer; if (InputLength < sizeof(OPEN_DESKTOP)) { Status = STATUS_BUFFER_TOO_SMALL; goto complete; } Status = MonitorOpenDesktop(openDeskop); break; } case IOCTL_KMON_SCREENSHOT: { PKMON_SCREENSHOT screenShot = (PKMON_SCREENSHOT)Buffer; if (InputLength < sizeof(KMON_SCREENSHOT)) { Status = STATUS_BUFFER_TOO_SMALL; goto complete; } Status = MonitorScreenshot(screenShot); break; } default: Status = STATUS_INVALID_DEVICE_REQUEST; } complete: KeLeaveGuardedRegion(); KLog(LInfo, "dev=%p IoControl: %x bytes: %x, Status=%x", fdo, ControlCode, ResultLength, Status); return CompleteIrp(Irp, Status, ResultLength); }
NTSTATUS FdoPortStartIrp( IN PC0C_IO_PORT pIoPort, IN PIRP pIrp, IN UCHAR iQueue, IN PC0C_FDOPORT_START_ROUTINE pStartRoutine) { NTSTATUS status; LIST_ENTRY queueToComplete; KIRQL oldIrql; PC0C_IRP_QUEUE pQueue; PC0C_IRP_STATE pState; InitializeListHead(&queueToComplete); pState = GetIrpState(pIrp); HALT_UNLESS(pState); pState->flags = 0; pState->iQueue = iQueue; pQueue = &pIoPort->irpQueues[iQueue]; KeAcquireSpinLock(pIoPort->pIoLock, &oldIrql); #pragma warning(push, 3) IoSetCancelRoutine(pIrp, CancelRoutine); #pragma warning(pop) if (pIrp->Cancel) { status = NoPending(pIrp, STATUS_CANCELLED); } else { if (!pQueue->pCurrent) { status = StartIrp(pIoPort, pIrp, pState, pQueue, &queueToComplete, pStartRoutine); } else { PIO_STACK_LOCATION pIrpStack; PIO_STACK_LOCATION pCurrentStack; pIrpStack = IoGetCurrentIrpStackLocation(pIrp); pCurrentStack = IoGetCurrentIrpStackLocation(pQueue->pCurrent); if (pIrpStack->MajorFunction == IRP_MJ_DEVICE_CONTROL && pIrpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SERIAL_WAIT_ON_MASK) { status = NoPending(pIrp, STATUS_INVALID_PARAMETER); } else if (pIrpStack->MajorFunction == IRP_MJ_DEVICE_CONTROL && pIrpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SERIAL_IMMEDIATE_CHAR) { if (pCurrentStack->MajorFunction == IRP_MJ_DEVICE_CONTROL && pCurrentStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SERIAL_IMMEDIATE_CHAR) { status = NoPending(pIrp, STATUS_INVALID_PARAMETER); } else { PC0C_IRP_STATE pCurrentState; pCurrentState = GetIrpState(pQueue->pCurrent); HALT_UNLESS(pCurrentState); pCurrentState->flags &= ~C0C_IRP_FLAG_IS_CURRENT; InsertHeadList(&pQueue->queue, &pQueue->pCurrent->Tail.Overlay.ListEntry); pCurrentState->flags |= C0C_IRP_FLAG_IN_QUEUE; status = StartIrp(pIoPort, pIrp, pState, pQueue, &queueToComplete, pStartRoutine); } } else { InsertTailList(&pQueue->queue, &pIrp->Tail.Overlay.ListEntry); pState->flags |= C0C_IRP_FLAG_IN_QUEUE; if (pState->iQueue == C0C_QUEUE_WRITE) { pIoPort->amountInWriteQueue += GetWriteLength(pIrp); } if (pCurrentStack->MajorFunction == IRP_MJ_DEVICE_CONTROL && pCurrentStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SERIAL_XOFF_COUNTER && pQueue->pCurrent->IoStatus.Information) { if (pIrpStack->MajorFunction == IRP_MJ_FLUSH_BUFFERS) { RemoveEntryList(&pIrp->Tail.Overlay.ListEntry); pState->flags &= ~C0C_IRP_FLAG_IN_QUEUE; status = NoPending(pIrp, STATUS_SUCCESS); } else { PIRP pIrpXoffCounter = pQueue->pCurrent; ShiftQueue(pQueue); CompleteIrp(pIrpXoffCounter, STATUS_SERIAL_MORE_WRITES, &queueToComplete); status = StartIrp(pIoPort, pIrp, pState, pQueue, &queueToComplete, pStartRoutine); } } else { pIrp->IoStatus.Status = STATUS_PENDING; IoMarkIrpPending(pIrp); status = STATUS_PENDING; } } } } KeReleaseSpinLock(pIoPort->pIoLock, oldIrql); FdoPortCompleteQueue(&queueToComplete); return status; }
NTSTATUS Wdm1DeviceControl(IN PDEVICE_OBJECT fdo, IN PIRP Irp) { PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp); NTSTATUS status = STATUS_SUCCESS; ULONG BytesTxd = 0; ULONG ControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode; ULONG InputLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength; ULONG OutputLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength; DebugPrint("DeviceIoControl: Control code %x InputLength %d OutputLength %d", ControlCode, InputLength, OutputLength); // Get access to the shared buffer KIRQL irql; KeAcquireSpinLock(&BufferLock, &irql); switch (ControlCode) { /////// Zero Buffer case IOCTL_WDM1_ZERO_BUFFER: // Zero the buffer if (Buffer != NULL && BufferSize > 0) RtlZeroMemory(Buffer, BufferSize); break; /////// Remove Buffer case IOCTL_WDM1_REMOVE_BUFFER: if (Buffer != NULL) { ExFreePool(Buffer); Buffer = NULL; BufferSize = 0; } break; /////// Get Buffer Size as ULONG case IOCTL_WDM1_GET_BUFFER_SIZE: if (OutputLength < sizeof(ULONG)) status = STATUS_INVALID_PARAMETER; else { BytesTxd = sizeof(ULONG); RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, &BufferSize, sizeof(ULONG)); } break; /////// Get Buffer case IOCTL_WDM1_GET_BUFFER: if (OutputLength > BufferSize) status = STATUS_INVALID_PARAMETER; else { BytesTxd = OutputLength; RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, Buffer, BytesTxd); } break; /////// Get DateTime case IOCTL_WDM1_GET_BUILDTIME: { if (OutputLength < dateTimeSize){ status = STATUS_INVALID_PARAMETER; } else { memset(dateTimeBuffer, 0, dateTimeSize); strcpy(dateTimeBuffer, __DATE__); strcat(dateTimeBuffer, " "); strcat(dateTimeBuffer, __TIME__); DebugPrint("DateTime: %s", dateTimeBuffer); BytesTxd = dateTimeSize; RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, dateTimeBuffer, dateTimeSize); } } break; /////// ------------- RPN STACK -------------------- case IOCTL_WDM1_RPN_PUSH: { int value = 0; RtlCopyMemory(&value, Irp->AssociatedIrp.SystemBuffer, 4); // 4 byte = 32bit BytesTxd = 4; if (!Stack_Push(&s, value)){ status = STATUS_UNSUCCESSFUL; BytesTxd = 0; } DebugPrintStack(); } break; case IOCTL_WDM1_RPN_POP: { if (OutputLength < 4) { status = STATUS_INVALID_PARAMETER; } else { int value = 0; if (Stack_Pop(&s, value)){ BytesTxd = 4; RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, &value, BytesTxd); } else { BytesTxd = 0; status = STATUS_UNSUCCESSFUL; } } } break; case IOCTL_WDM1_RPN_ADD: if (!RpnCalculator_Add(&s)){ BytesTxd = 0; status = STATUS_UNSUCCESSFUL; } break; case IOCTL_WDM1_RPN_SUB: if (!RpnCalculator_Substract(&s)){ BytesTxd = 0; status = STATUS_UNSUCCESSFUL; } break; case IOCTL_WDM1_RPN_MULT: if (!RpnCalculator_Multiply(&s)){ BytesTxd = 0; status = STATUS_UNSUCCESSFUL; } break; case IOCTL_WDM1_RPN_DIV: if (!RpnCalculator_Divide(&s)){ BytesTxd = 0; status = STATUS_UNSUCCESSFUL; } break; case IOCTL_WDM1_RPN_GETDIVREST: if (!RpnCalculator_Modulo(&s)){ BytesTxd = 0; status = STATUS_UNSUCCESSFUL; } break; case IOCTL_WDM1_RPN_DUPLI: if (!Stack_Dup(&s)){ BytesTxd = 0; status = STATUS_UNSUCCESSFUL; } DebugPrintStack(); break; /////// Invalid request default: status = STATUS_INVALID_DEVICE_REQUEST; } // Release shared buffer KeReleaseSpinLock(&BufferLock, irql); DebugPrint("DeviceIoControl: %d bytes written", (int)BytesTxd); // Complete IRP return CompleteIrp(Irp, status, BytesTxd); }
// // Функция обработки запроса на запись. // NTSTATUS DispatchWrite(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp) { NTSTATUS status = STATUS_SUCCESS; PIO_STACK_LOCATION pIrpStack; ULONG info = 0; OpenFileEntry *entry; char* str; char* str1; PLIST_ENTRY link; int len; ANSI_STRING f; BOOLEAN FileNonExist = TRUE; int l; char *inputBuffer; int i; pIrpStack = IoGetCurrentIrpStackLocation(pIrp); if (pDeviceObject->Flags & DO_BUFFERED_IO) { // если для устройства определён буферизованный ввод/вывод, // то записываем данные в системный буфер inputBuffer = (char*)pIrp->AssociatedIrp.SystemBuffer; } else { // иначе непосредственно в пользовательский буфер inputBuffer = (char*)pIrp->UserBuffer; } // выделяем память для нового элемента и вставляем его в конец списка entry = (OpenFileEntry*)ExAllocateFromPagedLookasideList(&glPagedList); InsertTailList(&glOpenFiles, &entry->link); // копируем имя файла в созданный элемент RtlUnicodeStringToAnsiString(&entry->fileName, &pIrpStack->FileObject->FileName, TRUE); len = strlen(entry->fileName.Buffer) + 1; do str = ExAllocatePool(NonPagedPool, len); while (str == NULL); strcpy(str, entry->fileName.Buffer); if (strstr(str, "??") != NULL){ do str1 = ExAllocatePool(NonPagedPool, len - 4); while (str1 == NULL); strcpy(str1, &str[4]); do entry->fullName.Buffer = AnsiToUnicode(str1); while (entry->fullName.Buffer == NULL); ExFreePool(str1); } else entry->fullName.Buffer = AnsiToUnicode(str); //если ввели "ddd" отчищаем весь список хукнутых файлов if (strstr(str, "ddd") != NULL){ while (!IsListEmpty(&glOpenFiles)) { PLIST_ENTRY pLink = RemoveHeadList(&glOpenFiles); entry = CONTAINING_RECORD(pLink, OpenFileEntry, link); RtlFreeAnsiString(&entry->fileName); RtlFreeUnicodeString(&entry->fullName); ExFreeToPagedLookasideList(&glPagedList, entry); } } ExFreePool(str); return CompleteIrp(pIrp, status, info); }
NTSTATUS DriverPassthroughHandler (__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp) { UNREFERENCED_PARAMETER(DeviceObject); return CompleteIrp (Irp, 0, STATUS_NOT_SUPPORTED); }
BOOLEAN PickPacketFromList(PADAPT pAdapt,PIRP Irp) { PIO_STACK_LOCATION IrpStack; ULONG PacketLenTotal=0; PNDIS_PACKET pRcvPacket; PLIST_ENTRY pRcvPacketEntry; PUCHAR pSrc, pDst; PUCHAR pDstFormer; ULONG BytesRemaining; // at pDst PNDIS_BUFFER pNdisBuffer; ULONG BytesAvailable; ULONG BytesToCopy; NdisAcquireSpinLock(&PacketListLock); if(!IsListEmpty(&PacketList)) { // // Get the first queued receive packet // pRcvPacketEntry = PacketList.Flink; RemoveEntryList(pRcvPacketEntry); PacketCount--; NdisReleaseSpinLock(&PacketListLock); pRcvPacket = SECLAB_LIST_ENTRY_TO_RCV_PKT(pRcvPacketEntry); // // Copy as much data as possible from the receive packet to // the IRP MDL. // pDst = (PUCHAR)ExAllocatePool(NonPagedPool,MY_MTU); if(pDst==NULL) { DbgPrint("Can not allocate enough pool"); DbgBreakPoint(); } pDstFormer=pDst; IrpStack = IoGetCurrentIrpStackLocation(Irp); BytesRemaining = IrpStack->Parameters.DeviceIoControl.OutputBufferLength; pNdisBuffer = pRcvPacket->Private.Head; while (BytesRemaining && (pNdisBuffer != NULL)) { NdisQueryBufferSafe(pNdisBuffer, &pSrc, &BytesAvailable, NormalPagePriority); if (pSrc == NULL) { DbgPrint("PickPacketFromList: QueryBuffer failed for buffer"); break; } if (BytesAvailable) { BytesToCopy = MIN(BytesAvailable, BytesRemaining); NdisMoveMemory(pDstFormer, pSrc, BytesToCopy); BytesRemaining -= BytesToCopy; pDstFormer += BytesToCopy; PacketLenTotal += BytesToCopy; } NdisGetNextBuffer(pNdisBuffer, &pNdisBuffer); } // // Complete the IRP. // RtlCopyMemory( Irp->AssociatedIrp.SystemBuffer, pDst, PacketLenTotal); IoSetCancelRoutine(Irp,NULL); CompleteIrp(Irp,STATUS_SUCCESS,PacketLenTotal); ExFreePool(pDst); // // Free up the receive packet - back to the miniport if it // belongs to it, else reclaim it (local copy). // if (NdisGetPoolFromPacket(pRcvPacket) != pAdapt->RecvPacketPoolHandle) { NdisReturnPackets(&pRcvPacket, 1); } else { SecLabFreeReceivePacket(pAdapt, pRcvPacket); } } else { NdisReleaseSpinLock(&PacketListLock); return FALSE; } return TRUE; }