VOID PrintUnknownDeviceIoctlCode(__in ULONG IoctlCode) { PCHAR baseCodeStr = "unknown"; ULONG baseCode = DEVICE_TYPE_FROM_CTL_CODE(IoctlCode); ULONG functionCode = (IoctlCode & (~0xffffc003)) >> 2; DDbgPrint(" Unknown Code 0x%x\n", IoctlCode); switch (baseCode) { case IOCTL_STORAGE_BASE: baseCodeStr = "IOCTL_STORAGE_BASE"; break; case IOCTL_DISK_BASE: baseCodeStr = "IOCTL_DISK_BASE"; break; case IOCTL_VOLUME_BASE: baseCodeStr = "IOCTL_VOLUME_BASE"; break; case MOUNTDEVCONTROLTYPE: baseCodeStr = "MOUNTDEVCONTROLTYPE"; break; case MOUNTMGRCONTROLTYPE: baseCodeStr = "MOUNTMGRCONTROLTYPE"; break; default: break; } UNREFERENCED_PARAMETER(functionCode); DDbgPrint(" BaseCode: 0x%x(%s) FunctionCode 0x%x(%d)\n", baseCode, baseCodeStr, functionCode, functionCode); }
void BazisLib::DDK::DumpDeviceControlCode(const char *pszFormat, ULONG Code) { char szCode[512]; const char *pszCode = MapDeviceControlCode(Code); if (!pszCode) { sprintf(szCode, "[%08X; (devtype=%04X; code=%03X)]", Code, DEVICE_TYPE_FROM_CTL_CODE(Code), (Code >> 2) & 0x7FF); pszCode = szCode; }
/******************************************************************************* * * 函 数 名 : DispatchDeviceControl * 功能描述 : * 参数列表 : pDriverObj -- * pIrp * 说 明 : * 返回结果 : 成功返回 STATUS_SUCCESS * *******************************************************************************/ NTSTATUS DispatchDeviceControl(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp) { NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST; // STATUS_UNSUCCESSFUL PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(pIrp); ULONG uIoControlCode = 0; PVOID pIoBuffer = NULL; ULONG uInSize = 0; ULONG uOutSize = 0; PHIDE_INFO pHi = NULL ; PPROTECT_PID_INFO pPi = NULL ; PPROTECT_NAME_INFO pNi = NULL ; PDEVICE_EXTENSION pde = (PDEVICE_EXTENSION)pDevObj->DeviceExtension ; // Get the IoCtrl Code uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode; // Get the buffer info pIoBuffer = pIrp->AssociatedIrp.SystemBuffer; uInSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength; uOutSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength; KdBreakPoint() ; KeWaitForSingleObject(&pde->DeviceIoControlMutex, Executive, KernelMode, FALSE, NULL) ; switch(uIoControlCode) { // 添加要保护的进程名 case IOCTRL_ADD_PROTECT_NAME: { pNi = (PPROTECT_NAME_INFO)pIoBuffer ; if (sizeof(PROTECT_NAME_INFO) != uInSize || NULL == pNi) { break ; } // 这里可以判断一下返回值 if(AddProtectProcessName(pNi->ProcessName)) { status = STATUS_SUCCESS ; } } break ; case IOCTRL_ADD_PROTECT_PID: { pPi = (PPROTECT_PID_INFO)pIoBuffer ; if (sizeof(PROTECT_PID_INFO) != uInSize || NULL == pPi) { break ; } // 这里可以判断一下返回值 if( AddProtectProcessPID(pPi->uPID)) { status = STATUS_SUCCESS ; } } break ; // 处理隐藏进程 case IOCTRL_HIDE: { // Receive data form Application //dprintf("IOCTRL_HIDE\r\n"); // Do we have any data? // 判断传进来的参数是否正确 pHi = (PHIDE_INFO)pIoBuffer ; if (sizeof(HIDE_INFO) != uInSize || NULL == pHi) { break ; } // 这里可以判断一下返回值 if( HideProcess(pDevObj, pHi->uPID) ) { status = STATUS_SUCCESS ; } } break ; case IOCTRL_START_FILTER: { if (! pde->bIsFiltrateProcess) { pde->bIsFiltrateProcess = true ; status = STATUS_SUCCESS ; } } break ; case IOCTRL_STOP_FILTER: { if (pde->bIsFiltrateProcess) { pde->bIsFiltrateProcess = false ; status = STATUS_SUCCESS ; } } break ; // // TODO: Add execute code here. // default: { // Invalid code sent dprintf("Unknown IOCTL: 0x%X (%04X,%04X)\r\n", uIoControlCode, DEVICE_TYPE_FROM_CTL_CODE(uIoControlCode), IoGetFunctionCodeFromCtlCode(uIoControlCode)); status = STATUS_INVALID_PARAMETER; } break; } if(status == STATUS_SUCCESS) { pIrp->IoStatus.Information = uOutSize; } else { pIrp->IoStatus.Information = 0; } // Complete the I/O Request pIrp->IoStatus.Status = status; KeReleaseMutex(&pde->DeviceIoControlMutex, FALSE) ; IoCompleteRequest(pIrp, IO_NO_INCREMENT); return status; }
BOOLEAN MiniSecondary_Ioctl ( IN PSECONDARY Secondary, IN OUT PFLT_CALLBACK_DATA Data ) { NTSTATUS status; //PIO_STACK_LOCATION iopb = IoGetCurrentIrpStackLocation( Irp ); PFLT_IO_PARAMETER_BLOCK iopb = Data->Iopb; //KEVENT waitEvent; ULONG ioctlCode = iopb->Parameters.DeviceIoControl.Common.IoControlCode; ULONG devType = DEVICE_TYPE_FROM_CTL_CODE(ioctlCode); UCHAR function = (UCHAR)((ioctlCode & 0x00003FFC) >> 2); PVOID inputBuffer, outputBuffer; IO_STATUS_BLOCK ioStatusBlock; SPY_LOG_PRINT( LFS_DEBUG_SECONDARY_TRACE, ("Secondary_Ioctl: IRP_MJ_DEVICE_CONTROL Entered, deviceType = %d, function = %d IOCTL_VOLUME_BASE = %d, MOUNTDEVCONTROLTYPE = %d\n", devType, function, IOCTL_VOLUME_BASE, MOUNTDEVCONTROLTYPE) ); if (IS_WINDOWS2K() && Secondary->LfsDeviceExt->DiskDeviceObject == NULL) { NDASFS_ASSERT( LFS_BUG ); return FLT_PREOP_SUCCESS_NO_CALLBACK; } if (IS_WINDOWSXP_OR_LATER() && Secondary->LfsDeviceExt->MountVolumeDeviceObject == NULL) { NDASFS_ASSERT( LFS_BUG ); return FLT_PREOP_SUCCESS_NO_CALLBACK; } if (ioctlCode == IOCTL_VOLUME_SET_GPT_ATTRIBUTES) { Data->IoStatus.Status = STATUS_NOT_SUPPORTED; Data->IoStatus.Information = 0; return FLT_PREOP_COMPLETE; } SPY_LOG_PRINT( LFS_DEBUG_LFS_TRACE, ("Open files from secondary: LfsDeviceExt = %p, iopb->MajorFunction = %x, iopb->MinorFunction = %x\n", Secondary->LfsDeviceExt, iopb->MajorFunction, iopb->MinorFunction) ); inputBuffer = MinispyMapInputBuffer( iopb, Data->RequestorMode ); outputBuffer = MinispyMapOutputBuffer( iopb, Data->RequestorMode ); status = LfsFilterDeviceIoControl( IS_WINDOWS2K() ? Secondary->LfsDeviceExt->DiskDeviceObject : Secondary->LfsDeviceExt->MountVolumeDeviceObject, ioctlCode, inputBuffer, iopb->Parameters.DeviceIoControl.Common.InputBufferLength, outputBuffer, iopb->Parameters.DeviceIoControl.Common.OutputBufferLength, &ioStatusBlock.Information ); SPY_LOG_PRINT( LFS_DEBUG_SECONDARY_ERROR, ("%s: status = %x\n", __FUNCTION__, status) ); Data->IoStatus.Status = status; Data->IoStatus.Information = ioStatusBlock.Information; return FLT_PREOP_COMPLETE; }
NTSTATUS DokanDispatchDeviceControl(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp) /*++ Routine Description: This device control dispatcher handles IOCTLs. Arguments: DeviceObject - Context for the activity. Irp - The device control argument block. Return Value: NTSTATUS --*/ { PDokanVCB vcb; PDokanDCB dcb; PIO_STACK_LOCATION irpSp; NTSTATUS status = STATUS_NOT_IMPLEMENTED; ULONG controlCode = 0; ULONG outputLength = 0; // {DCA0E0A5-D2CA-4f0f-8416-A6414657A77A} // GUID dokanGUID = { 0xdca0e0a5, 0xd2ca, 0x4f0f, { 0x84, 0x16, 0xa6, 0x41, // 0x46, 0x57, 0xa7, 0x7a } }; __try { Irp->IoStatus.Information = 0; irpSp = IoGetCurrentIrpStackLocation(Irp); outputLength = irpSp->Parameters.DeviceIoControl.OutputBufferLength; controlCode = irpSp->Parameters.DeviceIoControl.IoControlCode; if (controlCode != IOCTL_EVENT_WAIT && controlCode != IOCTL_EVENT_INFO && controlCode != IOCTL_KEEPALIVE) { DDbgPrint("==> DokanDispatchIoControl\n"); DDbgPrint(" ProcessId %lu\n", IoGetRequestorProcessId(Irp)); } if (DeviceObject->DriverObject == NULL || DeviceObject->ReferenceCount < 0) { status = STATUS_DEVICE_DOES_NOT_EXIST; __leave; } vcb = DeviceObject->DeviceExtension; PrintIdType(vcb); if (GetIdentifierType(vcb) == DGL) { status = GlobalDeviceControl(DeviceObject, Irp); __leave; } else if (GetIdentifierType(vcb) == DCB) { status = DiskDeviceControlWithLock(DeviceObject, Irp); __leave; } else if (GetIdentifierType(vcb) != VCB) { status = STATUS_INVALID_PARAMETER; __leave; } dcb = vcb->Dcb; switch (irpSp->Parameters.DeviceIoControl.IoControlCode) { case IOCTL_EVENT_WAIT: DDbgPrint(" IOCTL_EVENT_WAIT\n"); status = DokanRegisterPendingIrpForEvent(DeviceObject, Irp); break; case IOCTL_EVENT_INFO: // DDbgPrint(" IOCTL_EVENT_INFO\n"); status = DokanCompleteIrp(DeviceObject, Irp); break; case IOCTL_EVENT_RELEASE: DDbgPrint(" IOCTL_EVENT_RELEASE\n"); status = DokanEventRelease(DeviceObject, Irp); break; case IOCTL_EVENT_WRITE: DDbgPrint(" IOCTL_EVENT_WRITE\n"); status = DokanEventWrite(DeviceObject, Irp); break; case IOCTL_KEEPALIVE: DDbgPrint(" IOCTL_KEEPALIVE\n"); if (IsFlagOn(vcb->Flags, VCB_MOUNTED)) { ExEnterCriticalRegionAndAcquireResourceExclusive(&dcb->Resource); DokanUpdateTimeout(&dcb->TickCount, DOKAN_KEEPALIVE_TIMEOUT); ExReleaseResourceAndLeaveCriticalRegion(&dcb->Resource); status = STATUS_SUCCESS; } else { DDbgPrint(" device is not mounted\n"); status = STATUS_INSUFFICIENT_RESOURCES; } break; case IOCTL_RESET_TIMEOUT: status = DokanResetPendingIrpTimeout(DeviceObject, Irp); break; case IOCTL_GET_ACCESS_TOKEN: status = DokanGetAccessToken(DeviceObject, Irp); break; default: { ULONG baseCode = DEVICE_TYPE_FROM_CTL_CODE( irpSp->Parameters.DeviceIoControl.IoControlCode); status = STATUS_NOT_IMPLEMENTED; // In case of IOCTL_STORAGE_BASE or IOCTL_DISK_BASE OR // FILE_DEVICE_NETWORK_FILE_SYSTEM or MOUNTDEVCONTROLTYPE ioctl type, pass // to DiskDeviceControl to avoid code duplication // TODO: probably not the best way to pass down Irp... if (baseCode == IOCTL_STORAGE_BASE || baseCode == IOCTL_DISK_BASE || baseCode == FILE_DEVICE_NETWORK_FILE_SYSTEM || baseCode == MOUNTDEVCONTROLTYPE) { status = DiskDeviceControlWithLock(dcb->DeviceObject, Irp); } if (status == STATUS_NOT_IMPLEMENTED) { PrintUnknownDeviceIoctlCode( irpSp->Parameters.DeviceIoControl.IoControlCode); } } break; } // switch IoControlCode } __finally { if (status != STATUS_PENDING) { if (IsDeletePending(DeviceObject)) { DDbgPrint(" DeviceObject is invalid, so prevent BSOD"); status = STATUS_DEVICE_REMOVED; } DokanCompleteIrpRequest(Irp, status, Irp->IoStatus.Information); } if (controlCode != IOCTL_EVENT_WAIT && controlCode != IOCTL_EVENT_INFO && controlCode != IOCTL_KEEPALIVE) { DokanPrintNTStatus(status); DDbgPrint("<== DokanDispatchIoControl\n"); } } return status; }
NTSTATUS FatCommonDeviceControl ( IN PIRP_CONTEXT IrpContext, IN PIRP Irp ) /*++ Routine Description: This is the common routine for doing Device control operations called by both the fsd and fsp threads Arguments: Irp - Supplies the Irp to process InFsp - Indicates if this is the fsp thread or someother thread Return Value: NTSTATUS - The return status for the operation --*/ { NTSTATUS Status; PIO_STACK_LOCATION IrpSp; KEVENT WaitEvent; PVOID CompletionContext = NULL; PVCB Vcb; PFCB Fcb; PCCB Ccb; #if __NDAS_FAT_PRIMARY__ if (IrpContext->MajorFunction == IRP_MJ_DEVICE_CONTROL && IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.IoControlCode == IOCTL_INSERT_PRIMARY_SESSION) { PVOLUME_DEVICE_OBJECT VolDo = CONTAINING_RECORD( IoGetCurrentIrpStackLocation(Irp)->DeviceObject, VOLUME_DEVICE_OBJECT, DeviceObject ); PSESSION_INFORMATION inputBuffer = (PSESSION_INFORMATION)Irp->AssociatedIrp.SystemBuffer; ULONG inputBufferLength = IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.InputBufferLength; ULONG outputBufferLength; PULONG outputBuffer; PPRIMARY_SESSION primarySession; if (inputBufferLength != sizeof(SESSION_INFORMATION)) { FatCompleteRequest( IrpContext, Irp, Status = STATUS_INVALID_PARAMETER ); return Status; } outputBufferLength = IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.OutputBufferLength; outputBuffer = (PULONG)Irp->AssociatedIrp.SystemBuffer; primarySession = PrimarySession_Create( IrpContext, VolDo, inputBuffer, Irp ); ASSERT( primarySession ); FatCompleteRequest( IrpContext, NULL, 0 ); Status = STATUS_PENDING; return Status; } #endif // // Get a pointer to the current Irp stack location // IrpSp = IoGetCurrentIrpStackLocation( Irp ); DebugTrace(+1, Dbg, "FatCommonDeviceControl\n", 0); DebugTrace( 0, Dbg, "Irp = %08lx\n", Irp); DebugTrace( 0, Dbg, "MinorFunction = %08lx\n", IrpSp->MinorFunction); // // Decode the file object, the only type of opens we accept are // user volume opens. // if (FatDecodeFileObject( IrpSp->FileObject, &Vcb, &Fcb, &Ccb ) != UserVolumeOpen) { FatCompleteRequest( IrpContext, Irp, STATUS_INVALID_PARAMETER ); DebugTrace(-1, Dbg2, "FatCommonDeviceControl -> %08lx\n", STATUS_INVALID_PARAMETER); return STATUS_INVALID_PARAMETER; } #define IOCTL_VOLUME_BASE ((ULONG) 'V') #define MOUNTDEVCONTROLTYPE ((ULONG) 'M') DebugTrace2( 0, Dbg2, ("FatCommonDeviceControl: deviceType = %d, function = %d IOCTL_VOLUME_BASE = %d, MOUNTDEVCONTROLTYPE = %d\n", DEVICE_TYPE_FROM_CTL_CODE(IrpSp->Parameters.DeviceIoControl.IoControlCode), (UCHAR)((IrpSp->Parameters.DeviceIoControl.IoControlCode & 0x00003FFC) >> 2), IOCTL_VOLUME_BASE, MOUNTDEVCONTROLTYPE) ); #if __NDAS_FAT__ if (CONTAINING_RECORD(Vcb, VOLUME_DEVICE_OBJECT, Vcb)->NetdiskEnableMode == NETDISK_SECONDARY) SetFlag( IrpContext->NdFatFlags, ND_FAT_IRP_CONTEXT_FLAG_SECONDARY_CONTEXT ); #endif // // A few IOCTLs actually require some intervention on our part // switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) { case IOCTL_VOLSNAP_FLUSH_AND_HOLD_WRITES: #if __NDAS_FAT_WIN2K_SUPPORT__ if (!IS_WINDOWSXP_OR_LATER()) { ASSERT( FALSE ); IoSkipCurrentIrpStackLocation( Irp ); break; } #endif // // This is sent by the Volume Snapshot driver (Lovelace). // We flush the volume, and hold all file resources // to make sure that nothing more gets dirty. Then we wait // for the IRP to complete or cancel. // SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT ); FatAcquireExclusiveVolume( IrpContext, Vcb ); FatFlushAndCleanVolume( IrpContext, Irp, Vcb, FlushWithoutPurge ); KeInitializeEvent( &WaitEvent, NotificationEvent, FALSE ); CompletionContext = &WaitEvent; // // Get the next stack location, and copy over the stack location // IoCopyCurrentIrpStackLocationToNext( Irp ); // // Set up the completion routine // IoSetCompletionRoutine( Irp, FatDeviceControlCompletionRoutine, CompletionContext, TRUE, TRUE, TRUE ); break; default: // // FAT doesn't need to see this on the way back, so skip ourselves. // IoSkipCurrentIrpStackLocation( Irp ); break; } // // Send the request. // Status = IoCallDriver(Vcb->TargetDeviceObject, Irp); if (Status == STATUS_PENDING && CompletionContext) { KeWaitForSingleObject( &WaitEvent, Executive, KernelMode, FALSE, NULL ); Status = Irp->IoStatus.Status; } //DebugTrace(-1, Dbg2, "FatCommonDeviceControl -> Information %08lx\n", Irp->IoStatus.Information); // // If we had a context, the IRP remains for us and we will complete it. // Handle it appropriately. // if (CompletionContext) { // // Release all the resources that we held because of a // VOLSNAP_FLUSH_AND_HOLD. // ASSERT( IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_VOLSNAP_FLUSH_AND_HOLD_WRITES ); FatReleaseVolume( IrpContext, Vcb ); // // If we had no context, the IRP will complete asynchronously. // } else { Irp = NULL; } FatCompleteRequest( IrpContext, Irp, Status ); DebugTrace(-1, Dbg2, "FatCommonDeviceControl -> %08lx\n", Status); return Status; }
NTSTATUS DispatchDeviceControl(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp) { NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST; // STATUS_UNSUCCESSFUL PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(pIrp); ULONG uIoControlCode = 0; PVOID pIoBuffer = NULL; ULONG uInSize = 0; ULONG uOutSize = 0; // Get the IoCtrl Code uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode; pIoBuffer = pIrp->AssociatedIrp.SystemBuffer; uInSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength; uOutSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength; switch(uIoControlCode) { case IOCTL_HELLO_WORLD: { dprintf("MY_CTL_CODE(0)=%d\r\n,MY_CTL_CODE"); // Return success status = STATUS_SUCCESS; } break; case IOCTRL_REC_FROM_APP: { // Receive data form Application //dprintf("IOCTRL_REC_FROM_APP\r\n"); // Do we have any data? if( uInSize > 0 ) { dprintf("Get Data from App: %ws\r\n", pIoBuffer); } // Return success status = STATUS_SUCCESS; } break; case IOCTRL_SEND_TO_APP: { // Send data to Application //dprintf("IOCTRL_SEND_TO_APP\r\n"); // If we have enough room copy the data upto the App - note copy the terminating character as well... if( uOutSize >= strlen( DATA_TO_APP ) + 1 ) { RtlCopyMemory( pIoBuffer, DATA_TO_APP, strlen( DATA_TO_APP ) + 1 ); // Update the length for the App pIrp->IoStatus.Information = strlen( DATA_TO_APP ) + 1; dprintf("Send Data to App: %s\r\n", pIoBuffer); // Return success status = STATUS_SUCCESS; } } break; // // TODO: Add execute code here. // default: { // Invalid code sent dprintf("Unknown IOCTL: 0x%X (%04X,%04X)\r\n", uIoControlCode, DEVICE_TYPE_FROM_CTL_CODE(uIoControlCode), IoGetFunctionCodeFromCtlCode(uIoControlCode)); status = STATUS_INVALID_PARAMETER; } break; } if(status == STATUS_SUCCESS) { pIrp->IoStatus.Information = uOutSize; } else { pIrp->IoStatus.Information = 0; } // Complete the I/O Request pIrp->IoStatus.Status = status; IoCompleteRequest(pIrp, IO_NO_INCREMENT); return status; }
NTSTATUS FWDispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { NTSTATUS Status = STATUS_SUCCESS; PIO_STACK_LOCATION irpStack; PDEVICE_EXTENSION deviceExtension; PVOID ioBuf; ULONG inBufLength, outBufLength; ULONG ioControlCode; ULONG_PTR num=0; irpStack = IoGetCurrentIrpStackLocation(Irp); deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; Irp->IoStatus.Information = 0; // // Get the pointer to the input/output buffer and it's length // ioBuf = Irp->AssociatedIrp.SystemBuffer; inBufLength = irpStack->Parameters.DeviceIoControl.InputBufferLength; outBufLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength; ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode; // Irp->UserBuffer; // If METHOD_NEITHER, This is Output Buffer switch (ioControlCode) { case IOCTL_SETUPFW: { // if (g_AlreadyHookTCPIP) { InterlockedExchange(&g_InterceptTCPIPRcv, 1); } else { Status= FWHookTcpipRecvHandler(); if (NT_SUCCESS(Status)) { InterlockedExchange(&g_InterceptTCPIPRcv, 1); g_AlreadyHookTCPIP = 1; } } break; } case IOCTL_UNSETFW: { // InterlockedExchange(&g_InterceptTCPIPRcv, 0); //UNHOOK的行为就放到驱动卸载时候了 break; } case IOCTL_PENDDINGCHECKPORT: { //pendding进去 IoMarkIrpPending(Irp); ExInterlockedInsertHeadList(&g_AskUserConnectListHeader, &Irp->Tail.Overlay.ListEntry, &g_AskUserConnectListLock); Status= STATUS_PENDING; Irp->IoStatus.Status = Status; return Status; break; } case IOCTL_SETONEPORTSTATUS: { Status = SetupPortStatus(ioBuf, 1); break; } case IOCTL_RESPONSEPORTASK: { Status = ResponsePortAsk((PFIREWALL_ASKUSER)ioBuf); break; } case IOCTL_ReleasePENDDINGCHECKPORT: { Status = ReleasePenddingCheckPortIrp(); break; } case IOCTL_GETPORTSTATUS: { Status = GetPortRules(ioBuf, &outBufLength); if (Status==STATUS_INFO_LENGTH_MISMATCH) { Status = STATUS_SUCCESS; } Irp->IoStatus.Information = outBufLength; break; } default: { //Status = STATUS_INVALID_PARAMETER; kprintf("[SuperCI] Unknown IOCTL: 0x%X (%04X,%04X)\n", ioControlCode, DEVICE_TYPE_FROM_CTL_CODE(ioControlCode), IoGetFunctionCodeFromCtlCode(ioControlCode)); break; } } Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; }
static VOID UsbChief_EvtIoDeviceControl(IN WDFQUEUE Queue, IN WDFREQUEST Request, IN size_t OutputBufferLength, IN size_t InputBufferLength, IN ULONG IoControlCode) { NTSTATUS Status; size_t Length = 0; PIOCTL_DATA data; PDEVICE_CONTEXT pDeviceContext; UCHAR test[4096]; UCHAR *config; WORD *version; URB Urb; WDF_USB_INTERFACE_SELECT_SETTING_PARAMS interfaceParams; ULONG i; UNREFERENCED_PARAMETER(OutputBufferLength); UNREFERENCED_PARAMETER(InputBufferLength); UNREFERENCED_PARAMETER(Queue); PAGED_CODE(); pDeviceContext = GetDeviceContext(WdfIoQueueGetDevice(Queue)); Length = 0; switch(IoControlCode) { case IOCTL_VENDOR_WRITE: if (InputBufferLength != sizeof(*data)) { UsbChief_DbgPrint(0, ("Invalid InputBuffer Size: %d/%d\n", InputBufferLength, sizeof(*data))); Status = STATUS_INVALID_DEVICE_REQUEST; goto out; } Status = WdfRequestRetrieveInputBuffer(Request, InputBufferLength, &data, &Length); if (!NT_SUCCESS(Status)) goto out; UsbChief_DbgPrint(DEBUG_IOCTL, ("EvtIoDeviceControl: IOCTL_VENDOR_WRITE %x, Index %x, Value %x, Max Length %d, Buf %p\n", data->Request, data->Index, data->Value, data->Length, data->Buffer)); if (Length != sizeof(*data)) { UsbChief_DbgPrint(0, ("Failed to retrieve buffer: %d/%d\n", Length, sizeof(*data))); Status = STATUS_INVALID_DEVICE_REQUEST; goto out; } memset(&Urb, 0, sizeof(Urb)); Urb.UrbHeader.Function = URB_FUNCTION_VENDOR_DEVICE; Urb.UrbHeader.Length = sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST); Urb.UrbControlVendorClassRequest.RequestTypeReservedBits = 0x40; Urb.UrbControlVendorClassRequest.TransferBufferLength = data->Length; Urb.UrbControlVendorClassRequest.TransferBuffer = (PVOID)data->Buffer; Urb.UrbControlVendorClassRequest.Request = data->Request; Urb.UrbControlVendorClassRequest.Value = data->Value; Urb.UrbControlVendorClassRequest.Index = data->Index; if (DebugLevel & DEBUG_IOCTL) { for(i = 0; i < data->Length; i++) DbgPrint("%02X ", ((PUCHAR)data->Buffer)[i]); DbgPrint("\n"); } Status = WdfUsbTargetDeviceSendUrbSynchronously(pDeviceContext->WdfUsbTargetDevice, NULL, NULL, &Urb); if (!NT_SUCCESS(Status)) { UsbChief_DbgPrint(0, ("WdfUsbTargetDeviceSendControlTransferSynchronously failed\n")); } break; case IOCTL_VENDOR_READ: if (InputBufferLength != sizeof(*data)) { UsbChief_DbgPrint(0, ("Invalid InputBuffer Size: %d/%d\n", InputBufferLength, sizeof(*data))); Status = STATUS_INVALID_DEVICE_REQUEST; goto out; } Status = WdfRequestRetrieveInputBuffer(Request, InputBufferLength, &data, &Length); if (!NT_SUCCESS(Status)) goto out; UsbChief_DbgPrint(DEBUG_IOCTL, ("EvtIoDeviceControl: IOCTL_VENDOR_READ %x, Index %x, Value %x, Max Length %d, Buf %p\n", data->Request, data->Index, data->Value, data->Length, data->Buffer)); if (Length != sizeof(*data)) { UsbChief_DbgPrint(0, ("Failed to retrieve buffer: %d/%d\n", Length, sizeof(*data))); Status = STATUS_INVALID_DEVICE_REQUEST; goto out; } if (data->Length > sizeof(test)) { Status = STATUS_INVALID_DEVICE_REQUEST; goto out; } memset(&Urb, 0, sizeof(Urb)); Urb.UrbHeader.Function = URB_FUNCTION_VENDOR_DEVICE; Urb.UrbHeader.Length = sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST); Urb.UrbControlVendorClassRequest.RequestTypeReservedBits = 0xc0; Urb.UrbControlVendorClassRequest.TransferFlags = USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK; Urb.UrbControlVendorClassRequest.TransferBufferLength = data->Length; Urb.UrbControlVendorClassRequest.TransferBuffer = test; Urb.UrbControlVendorClassRequest.Request = data->Request; Urb.UrbControlVendorClassRequest.Value = data->Value; Urb.UrbControlVendorClassRequest.Index = data->Index; Status = WdfUsbTargetDeviceSendUrbSynchronously(pDeviceContext->WdfUsbTargetDevice, NULL, NULL, &Urb); if (DebugLevel & DEBUG_IOCTL && NT_SUCCESS(Status)) { for(i = 0; i < Urb.UrbControlVendorClassRequest.TransferBufferLength; i++) DbgPrint("%02X ", ((PUCHAR)test)[i]); DbgPrint("\n"); } if (Urb.UrbControlVendorClassRequest.TransferBufferLength) memcpy((PVOID)data->Buffer, test, Urb.UrbControlVendorClassRequest.TransferBufferLength); Length = Urb.UrbControlVendorClassRequest.TransferBufferLength; break; case IOCTL_SELECT_CONFIGURATION: if (InputBufferLength != sizeof(*config)) { UsbChief_DbgPrint(0, ("Invalid InputBuffer Size: %d/%d\n", InputBufferLength, sizeof(*config))); Status = STATUS_INVALID_DEVICE_REQUEST; goto out; } config = 0; Status = WdfRequestRetrieveInputBuffer(Request, InputBufferLength, (PVOID)&config, &Length); if (!NT_SUCCESS(Status)) goto out; if (Length != sizeof(*config)) { UsbChief_DbgPrint(0, ("Invalid Length: %d/%d\n", Length, sizeof(*config))); Status = STATUS_INVALID_DEVICE_REQUEST; goto out; } UsbChief_DbgPrint(DEBUG_IOCTL, ("EvtDeviceControl: IOCTL_SELECT_CONFIGURATION %x\n", *config)); if (!pDeviceContext->UsbInterface) { Status = STATUS_INVALID_DEVICE_REQUEST; goto out; } WDF_USB_INTERFACE_SELECT_SETTING_PARAMS_INIT_SETTING (&interfaceParams, *config); Status = WdfUsbInterfaceSelectSetting(pDeviceContext->UsbInterface, WDF_NO_OBJECT_ATTRIBUTES, &interfaceParams); break; case IOCTL_GET_FIRMWARE_VERSION: UsbChief_DbgPrint(DEBUG_IOCTL, ("EvtDeviceControl: GET_FIRMWARE_VERSION\n")); Status = WdfRequestRetrieveOutputBuffer(Request, OutputBufferLength, &version, &Length); if (!NT_SUCCESS(Status)) goto out; if (Length != sizeof(*version)) { UsbChief_DbgPrint(0, ("Invalid Length: %d/%d\n", Length, sizeof(*version))); Status = STATUS_INVALID_DEVICE_REQUEST; goto out; } *version = pDeviceContext->UsbDeviceDescriptor.bcdDevice; break; default: UsbChief_DbgPrint(DEBUG_IOCTL, ("EvtDeviceControl %08x (Device %x, Method %x) unknown\n", IoControlCode, DEVICE_TYPE_FROM_CTL_CODE(IoControlCode), METHOD_FROM_CTL_CODE(IoControlCode))); Status = STATUS_INVALID_DEVICE_REQUEST; break; } out: UsbChief_DbgPrint(DEBUG_IOCTL, ("EvtDeviceControl: Status %08x, Length %d\n", Status, Length)); WdfRequestCompleteWithInformation(Request, Status, Length); }