NTSTATUS Acpi_EnumChildren ( _In_ PACPI_CONTEXT AcpiCtx, _Out_ WDFMEMORY* EnumChildrenOutput ) { NTSTATUS status; WDFDEVICE device; WDFMEMORY inputMem; PACPI_ENUM_CHILDREN_INPUT_BUFFER inputBuf; size_t inputBufSize; WDF_MEMORY_DESCRIPTOR inputMemDesc; WDFMEMORY outputMem; PACPI_ENUM_CHILDREN_OUTPUT_BUFFER outputBuf; size_t outputBufSize; WDF_MEMORY_DESCRIPTOR outputMemDesc; WDF_OBJECT_ATTRIBUTES attributes; PAGED_CODE(); TRACE_FUNC_ENTRY(TRACE_FLAG_ACPI); device = Context_GetWdfDevice(AcpiCtx); inputMem = WDF_NO_HANDLE; outputMem = WDF_NO_HANDLE; WDF_OBJECT_ATTRIBUTES_INIT(&attributes); attributes.ParentObject = device; inputBufSize = sizeof(*inputBuf); status = WdfMemoryCreate(&attributes, NonPagedPoolNx, 0, inputBufSize, &inputMem, (PVOID*) &inputBuf); if (!NT_SUCCESS(status)) { TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] WdfMemoryCreate for %Iu bytes failed", device, inputBufSize); goto Exit; } RtlZeroMemory(inputBuf, inputBufSize); inputBuf->Signature = ACPI_ENUM_CHILDREN_INPUT_BUFFER_SIGNATURE; inputBuf->Flags = ENUM_CHILDREN_IMMEDIATE_ONLY; WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(&inputMemDesc, inputMem, nullptr); outputBufSize = sizeof(*outputBuf); do { WDF_OBJECT_ATTRIBUTES_INIT(&attributes); attributes.ParentObject = device; status = WdfMemoryCreate(&attributes, NonPagedPoolNx, 0, outputBufSize, &outputMem, (PVOID*) &outputBuf); if (!NT_SUCCESS(status)) { TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] WdfMemoryCreate for %Iu bytes failed", device, outputBufSize); goto Exit; } WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(&outputMemDesc, outputMem, nullptr); status = WdfIoTargetSendIoctlSynchronously(WdfDeviceGetIoTarget(device), NULL, IOCTL_ACPI_ENUM_CHILDREN, &inputMemDesc, &outputMemDesc, nullptr, nullptr); if (NT_SUCCESS(status)) { if (outputBuf->Signature != ACPI_ENUM_CHILDREN_OUTPUT_BUFFER_SIGNATURE) { status = STATUS_ACPI_INVALID_DATA; TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] Invalid data in ACPI_ENUM_CHILDREN_OUTPUT_BUFFER", device); goto Exit; } // // There must be atleast one, because this device is included in the list. // if (outputBuf->NumberOfChildren < 1) { status = STATUS_ACPI_INVALID_DATA; TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] No child devices in ACPI_ENUM_CHILDREN_OUTPUT_BUFFER", device); goto Exit; } break; } if (status != STATUS_BUFFER_OVERFLOW) { TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] IOCTL_ACPI_ENUM_CHILDREN failed - %!STATUS!", device, status); goto Exit; } if (outputBuf->Signature != ACPI_ENUM_CHILDREN_OUTPUT_BUFFER_SIGNATURE) { status = STATUS_ACPI_INVALID_DATA; TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] Invalid data in ACPI_ENUM_CHILDREN_OUTPUT_BUFFER", device); goto Exit; } outputBufSize = outputBuf->NumberOfChildren; WdfObjectDelete(outputMem); outputMem = WDF_NO_HANDLE; #pragma warning(suppress:4127) } while (true); *EnumChildrenOutput = outputMem; Exit: if (inputMem != WDF_NO_HANDLE) { WdfObjectDelete(inputMem); } if (!NT_SUCCESS(status) && (outputMem != WDF_NO_HANDLE)) { WdfObjectDelete(outputMem); } TRACE_FUNC_EXIT(TRACE_FLAG_ACPI); return status; }
// Pass down Idle notification request to lower driver // NTSTATUS HidFx2SendIdleNotification(_In_ WDFREQUEST hRequest) { NTSTATUS status = STATUS_SUCCESS; WDF_REQUEST_SEND_OPTIONS options; WDFIOTARGET hNextLowerDriver; WDFDEVICE hDevice; PIO_STACK_LOCATION pCurrentIrpStack = NULL; IO_STACK_LOCATION nextIrpStack; TraceVerbose(DBG_IOCTL, "(%!FUNC!) Entry\n"); hDevice = WdfIoQueueGetDevice(WdfRequestGetIoQueue(hRequest)); pCurrentIrpStack = IoGetCurrentIrpStackLocation(WdfRequestWdmGetIrp(hRequest)); // Convert the request to corresponding USB Idle notification request if (pCurrentIrpStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(HID_SUBMIT_IDLE_NOTIFICATION_CALLBACK_INFO)) { ASSERT(sizeof(HID_SUBMIT_IDLE_NOTIFICATION_CALLBACK_INFO) == sizeof(USB_IDLE_CALLBACK_INFO)); #pragma warning(suppress :4127) // conditional expression is constant warning if (sizeof(HID_SUBMIT_IDLE_NOTIFICATION_CALLBACK_INFO) == sizeof(USB_IDLE_CALLBACK_INFO)) { // prepare next stack location RtlZeroMemory(&nextIrpStack, sizeof(IO_STACK_LOCATION)); nextIrpStack.MajorFunction = pCurrentIrpStack->MajorFunction; nextIrpStack.Parameters.DeviceIoControl.InputBufferLength = pCurrentIrpStack->Parameters.DeviceIoControl.InputBufferLength; nextIrpStack.Parameters.DeviceIoControl.Type3InputBuffer = pCurrentIrpStack->Parameters.DeviceIoControl.Type3InputBuffer; nextIrpStack.Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION; nextIrpStack.DeviceObject = WdfIoTargetWdmGetTargetDeviceObject(WdfDeviceGetIoTarget(hDevice)); // Format the I/O request for the driver's local I/O target by using the contents of the specified WDM I/O stack location structure. WdfRequestWdmFormatUsingStackLocation(hRequest, &nextIrpStack); // Send the request down using Fire and forget option. WDF_REQUEST_SEND_OPTIONS_INIT(&options, WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET); hNextLowerDriver = WdfDeviceGetIoTarget(hDevice); if (WdfRequestSend(hRequest, hNextLowerDriver, &options) == FALSE) { status = STATUS_UNSUCCESSFUL; } } else // Incorrect DeviceIoControl.InputBufferLength { status = STATUS_INFO_LENGTH_MISMATCH; TraceErr(DBG_IOCTL, "(%!FUNC!) Incorrect DeviceIoControl.InputBufferLength, %!STATUS!\n", status); return status; } } else // DeviceIoControl.InputBufferLength too small { status = STATUS_BUFFER_TOO_SMALL; TraceErr(DBG_IOCTL, "(%!FUNC!) DeviceIoControl.InputBufferLength too small, %!STATUS!\n", status); return status; } TraceVerbose(DBG_IOCTL, "(%!FUNC!) Exit = %!STATUS!\n", status); return status; }
NDIS_STATUS VenetGetInterface(NDIS_HANDLE handle, PADAPTER a) { WDF_OBJECT_ATTRIBUTES attr; int rc; NTSTATUS nrc; /* Get my interface from Vbus... */ NdisMGetDeviceProperty(handle, &a->pdo, &a->fdo, &a->next, NULL, NULL); WDF_OBJECT_ATTRIBUTES_INIT(&attr); nrc = WdfDeviceMiniportCreate(WdfGetDriver(), &attr, a->fdo, a->next, a->pdo, &a->wdf_device); if (!NT_SUCCESS(nrc)) return NDIS_STATUS_FAILURE; nrc = WdfIoTargetQueryForInterface(WdfDeviceGetIoTarget(a->wdf_device), &VBUS_INTERFACE_GUID, (PINTERFACE) &a->vif, VBUS_IF_SIZE, VBUS_IF_VERSION, NULL); if (!NT_SUCCESS(nrc)) return NDIS_STATUS_FAILURE; rc = a->vif.open(a->pdo, VENET_VERSION, &a->bus_handle, VenetEventHandler); if (rc) return NDIS_STATUS_FAILURE; return NDIS_STATUS_SUCCESS; }
void MouseTrapEvtIoInternalDeviceControl(WDFQUEUE queue, WDFREQUEST request, size_t outputBufferLength, size_t inputBufferLength, ULONG ioControlCode) { UNREFERENCED_PARAMETER(outputBufferLength); UNREFERENCED_PARAMETER(inputBufferLength); NTSTATUS status = STATUS_SUCCESS; PAGED_CODE(); // Ensure paging is allowed in current IRQL // Get extension data WDFDEVICE hDevice = WdfIoQueueGetDevice(queue); PDEVICE_CONTEXT context = DeviceGetContext(hDevice); if(ioControlCode == IOCTL_INTERNAL_MOUSE_CONNECT) { // Only allow one connection. if(context->UpperConnectData.ClassService == NULL) { // Copy the connection parameters to the device extension. PCONNECT_DATA connectData; size_t length; status = WdfRequestRetrieveInputBuffer(request, sizeof(CONNECT_DATA), &connectData, &length); if(NT_SUCCESS(status)) { // Hook into the report chain (I am not sure this is correct) context->UpperConnectData = *connectData; connectData->ClassDeviceObject = WdfDeviceWdmGetDeviceObject(hDevice); #pragma warning(push) #pragma warning(disable:4152) connectData->ClassService = MouseTrapServiceCallback; #pragma warning(pop) } else { DebugPrint(("[MouseTrap] WdfRequestRetrieveInputBuffer failed %x\n", status)); } } else { status = STATUS_SHARING_VIOLATION; } } else if(ioControlCode == IOCTL_INTERNAL_MOUSE_DISCONNECT) { status = STATUS_NOT_IMPLEMENTED; } // Complete on error if(!NT_SUCCESS(status)) { WdfRequestComplete(request, status); return; } // Dispatch to higher level driver WDF_REQUEST_SEND_OPTIONS options; WDF_REQUEST_SEND_OPTIONS_INIT(&options, WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET); if(WdfRequestSend(request, WdfDeviceGetIoTarget(hDevice), &options) == FALSE) { NTSTATUS status = WdfRequestGetStatus(request); DebugPrint(("[MouseTrap] WdfRequestSend failed: 0x%x\n", status)); WdfRequestComplete(request, status); } }
NTSTATUS BthEchoSharedDeviceContextHeaderInit( PBTHECHOSAMPLE_DEVICE_CONTEXT_HEADER Header, WDFDEVICE Device ) /*++ Description: Initializes the common context header between server and client Arguments: Header - Contex header Device - Framework device object Return Value: NTSTATUS Status code. --*/ { NTSTATUS status; WDF_OBJECT_ATTRIBUTES attributes; Header->Device = Device; Header->IoTarget = WdfDeviceGetIoTarget(Device); // // Initialize request object // WDF_OBJECT_ATTRIBUTES_INIT(&attributes); attributes.ParentObject = Device; status = WdfRequestCreate( &attributes, Header->IoTarget, &Header->Request ); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, "Failed to pre-allocate request in device context, Status code %!STATUS!\n", status); goto exit; } exit: return status; }
VOID SimSensorIoInternalDeviceControl ( WDFQUEUE Queue, WDFREQUEST Request, size_t OutputBufferLength, size_t InputBufferLength, ULONG IoControlCode) /*++ Description: The system uses IoInternalDeviceControl requests to communicate with the ACPI driver on the device stack. For proper operation of thermal zones, these requests must be forwarded unless the driver knows how to handle them. --*/ { WDF_REQUEST_SEND_OPTIONS RequestSendOptions; BOOLEAN Return; NTSTATUS Status; UNREFERENCED_PARAMETER(OutputBufferLength); UNREFERENCED_PARAMETER(InputBufferLength); UNREFERENCED_PARAMETER(IoControlCode); DebugEnter(); WdfRequestFormatRequestUsingCurrentType(Request); WDF_REQUEST_SEND_OPTIONS_INIT( &RequestSendOptions, WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET); Return = WdfRequestSend( Request, WdfDeviceGetIoTarget(WdfIoQueueGetDevice(Queue)), &RequestSendOptions); if (Return == FALSE) { Status = WdfRequestGetStatus(Request); DebugPrint(SIMSENSOR_WARN, "WdfRequestSend() Failed. Request Status=0x%x\n", Status); WdfRequestComplete(Request, Status); } DebugExit(); }
/////////////////////////////////////////////////////////////////////////////// // SmplFilterEvtIoDefault /////////////////////////////////////////////////////////////////////////////// VOID SmplFilterEvtIoDefault( __in WDFQUEUE Queue, __in WDFREQUEST Request ) { WDF_REQUEST_PARAMETERS RequestParameters; BOOLEAN bResult; WDF_REQUEST_PARAMETERS_INIT(&RequestParameters); WdfRequestGetParameters(Request, &RequestParameters); if(WdfRequestTypeRead == RequestParameters.Type) { DbgPrintEx( DPFLTR_IHVDRIVER_ID, 1234, "SmplFilterEvtIoDefault WdfRequestTypeRead\n"); WdfRequestFormatRequestUsingCurrentType(Request); WdfRequestSetCompletionRoutine(Request, SmplFilterCompletionRoutineRead, NULL); bResult = WdfRequestSend(Request, WdfDeviceGetIoTarget(WdfIoQueueGetDevice(Queue)), NULL); } else { WDF_REQUEST_SEND_OPTIONS Options; WDF_REQUEST_SEND_OPTIONS_INIT(&Options, WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET); DbgPrintEx( DPFLTR_IHVDRIVER_ID, 1234, "SmplFilterEvtIoDefault other Request type\n"); bResult = WdfRequestSend(Request, WdfDeviceGetIoTarget(WdfIoQueueGetDevice(Queue)), &Options); } if(FALSE == bResult) { DbgPrintEx( DPFLTR_IHVDRIVER_ID, 1234, "WdfRequestSend failed!\n"); WdfRequestComplete(Request, WdfRequestGetStatus(Request)); } } // end SmplFilterEvtIoDefault
VOID ForwardRequestToIoTarget( _In_ WDFQUEUE queue, _In_ WDFREQUEST request, _In_ size_t length) { TraceEntry(); Trace(TRACE_LEVEL_INFORMATION, "%!FUNC! - Queue 0x%p, Request 0x%p Length %Iu", queue, request, length); auto device = WdfIoQueueGetDevice(queue); auto context = GetDeviceContext(device); if (length > context->MaxLengthInBytesForRWTransfers) { TraceError("%!FUNC! - Buffer Length to big %Iu, Max is %Iu. Status - %!STATUS!", length, context->MaxLengthInBytesForRWTransfers, STATUS_BUFFER_OVERFLOW); WdfRequestCompleteWithInformation(request, STATUS_BUFFER_OVERFLOW, NULL); return; } auto targetDevice = WdfDeviceGetIoTarget(device); WdfRequestFormatRequestUsingCurrentType(request); WDF_REQUEST_SEND_OPTIONS options; WDF_REQUEST_SEND_OPTIONS_INIT( &options, WDF_REQUEST_SEND_OPTION_SYNCHRONOUS | WDF_REQUEST_SEND_OPTION_TIMEOUT); WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&options, WDF_ABS_TIMEOUT_IN_SEC(10)); auto sendSuccess = WdfRequestSend(request, targetDevice, &options); auto status = WdfRequestGetStatus(request); if (!sendSuccess || !NT_SUCCESS(status)) { TraceError("%!FUNC! - WdfRequestSend returned %d with status: %!STATUS!", sendSuccess, status); WdfRequestCompleteWithInformation(request, status, NULL); return; } WdfRequestComplete(request, status); }
VOID FilterEvtIoDeviceControl( IN WDFQUEUE Queue, IN WDFREQUEST Request, IN size_t OutputBufferLength, IN size_t InputBufferLength, IN ULONG IoControlCode ) /*++ Routine Description: This routine is the dispatch routine for internal device control requests. Arguments: Queue - Handle to the framework queue object that is associated with the I/O request. Request - Handle to a framework request object. OutputBufferLength - length of the request's output buffer, if an output buffer is available. InputBufferLength - length of the request's input buffer, if an input buffer is available. IoControlCode - the driver-defined or system-defined I/O control code (IOCTL) that is associated with the request. Return Value: VOID --*/ { PFILTER_EXTENSION filterExt; NTSTATUS status = STATUS_SUCCESS; WDFDEVICE device; UNREFERENCED_PARAMETER(OutputBufferLength); UNREFERENCED_PARAMETER(InputBufferLength); KdPrint(("Entered FilterEvtIoDeviceControl\n")); device = WdfIoQueueGetDevice(Queue); filterExt = FilterGetData(device); switch (IoControlCode) { // // Put your cases for handling IOCTLs here // default: status = STATUS_SUCCESS; } if (!NT_SUCCESS(status)) { WdfRequestComplete(Request, status); return; } // // Forward the request down. WdfDeviceGetIoTarget returns // the default target, which represents the device attached to us below in // the stack. // #if FORWARD_REQUEST_WITH_COMPLETION // // Use this routine to forward a request if you are interested in post // processing the IRP. // FilterForwardRequestWithCompletionRoutine(Request, WdfDeviceGetIoTarget(device)); #else FilterForwardRequest(Request, WdfDeviceGetIoTarget(device)); #endif return; }
NTSTATUS kmdf1394_EvtDeviceAdd ( IN WDFDRIVER Driver, IN PWDFDEVICE_INIT DeviceInit) /*++ Routine Description: EvtDeviceAdd is called by the framework in response to AddDevice call from the PnP manager. Arguments: Driver - Handle to a framework driver object created in DriverEntry DeviceInit - Pointer to a framework-allocated WDFDEVICE_INIT structure. Return Value: NTSTATUS --*/ { NTSTATUS ntStatus = STATUS_SUCCESS; PDEVICE_EXTENSION deviceExtension; WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks; WDF_OBJECT_ATTRIBUTES fdoAttributes,lockAttributes; WDFDEVICE device; WDF_DEVICE_PNP_CAPABILITIES pnpCaps; WDF_IO_QUEUE_CONFIG ioQueueConfig; UNREFERENCED_PARAMETER (Driver); PAGED_CODE(); Enter(); // // Zero out the PnpPowerCallbacks structure. // WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks); // // Set Callbacks for any of the functions we are interested in. // If no callback is set, Framework will take the default action // by itself. // // These two callbacks set up and tear down hardware state, // specifically that which only has to be done once. // pnpPowerCallbacks.EvtDevicePrepareHardware = kmdf1394_EvtPrepareHardware; pnpPowerCallbacks.EvtDeviceReleaseHardware = kmdf1394_EvtReleaseHardware; pnpPowerCallbacks.EvtDeviceSelfManagedIoCleanup = \ kmdf1394_EvtDeviceSelfManagedIoCleanup; pnpPowerCallbacks.EvtDeviceD0Entry = kmdf1394_EvtDeviceD0Entry; pnpPowerCallbacks.EvtDeviceD0Exit = kmdf1394_EvtDeviceD0Exit; // // Register the PnP and power callbacks. Power policy related callbacks // will be registered// later in SotwareInit. // WdfDeviceInitSetPnpPowerEventCallbacks (DeviceInit, &pnpPowerCallbacks); if (!NT_SUCCESS (ntStatus)) { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_PNP, "WdfDeviceInitSetPnpPowerEventCallbacks failed %!STATUS!\n", ntStatus); return ntStatus; } // // We'll allow multiple handles to be opened to this device driver // so we'll set exclusivity to FALSE. // WdfDeviceInitSetExclusive (DeviceInit, FALSE); // // Specify the size and type of device context. // WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE (&fdoAttributes, DEVICE_EXTENSION); ntStatus = WdfDeviceCreate (&DeviceInit, &fdoAttributes, &device); if (!NT_SUCCESS (ntStatus)) { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_PNP, "WdfDeviceInitialize failed %!STATUS!\n", ntStatus); return ntStatus; } deviceExtension = GetDeviceContext (device); deviceExtension->WdfDevice = device; DoTraceLevelMessage(TRACE_LEVEL_INFORMATION, TRACE_FLAG_PNP, "PDO(0x%p) FDO(0x%p), Lower(0x%p) DevExt (0x%p)\n", WdfDeviceWdmGetPhysicalDevice (device), WdfDeviceWdmGetDeviceObject (device), WdfDeviceWdmGetAttachedDevice(device), deviceExtension); // // Tell the Framework that this device will need an interface so that // application can interact with it. // ntStatus = WdfDeviceCreateDeviceInterface ( device, (LPGUID) &GUID_KMDF_VDEV, NULL); if (!NT_SUCCESS (ntStatus)) { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_PNP, "WdfDeviceCreateDeviceInterface failed %!STATUS!\n", ntStatus); return ntStatus; } // // Tell the framework to set the SurpriseRemovalOK in the DeviceCaps so // that you don't get the popup in usermode (on Win2K) when you surprise // remove the device. // WDF_DEVICE_PNP_CAPABILITIES_INIT (&pnpCaps); pnpCaps.SurpriseRemovalOK = WdfTrue; WdfDeviceSetPnpCapabilities (device, &pnpCaps); // // save the device object we created as our physical device object // deviceExtension->PhysicalDeviceObject = \ WdfDeviceWdmGetPhysicalDevice (device); if (NULL == deviceExtension->PhysicalDeviceObject) { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_PNP, "WdfDeviceWdmGetPhysicalDevice: NULL DeviceObject\n"); return STATUS_UNSUCCESSFUL; } // // This is our default IoTarget representing the deviceobject // we are attached to. // deviceExtension->StackIoTarget = WdfDeviceGetIoTarget(device); deviceExtension->StackDeviceObject = WdfDeviceWdmGetAttachedDevice(device); if (NULL == deviceExtension->StackDeviceObject) { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_PNP, "WdfDeviceWdmGetAttachedDevice: NULL DeviceObject\n"); return STATUS_UNSUCCESSFUL; } // // Create a automanaged queue for dispatching ioctl requests. // All other requests are automatically failed by the framework. // By creating an automanaged queue we don't have to worry about // PNP/Power synchronization. // A default queue gets all the requests that are not // configure-fowarded using WdfDeviceConfigureRequestDispatching. // WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE ( &ioQueueConfig, WdfIoQueueDispatchParallel); ioQueueConfig.EvtIoDeviceControl = kmdf1394_EvtIoDeviceControl; __analysis_assume(ioQueueConfig.EvtIoStop != 0); ntStatus = WdfIoQueueCreate ( deviceExtension->WdfDevice, &ioQueueConfig, WDF_NO_OBJECT_ATTRIBUTES, &deviceExtension->IoctlQueue); __analysis_assume(ioQueueConfig.EvtIoStop == 0); if (!NT_SUCCESS (ntStatus)) { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_PNP, "WdfIoQueueCreate failed %!STATUS!\n", ntStatus); return ntStatus; } // // Create an additional queue to hold bus reset requests. // WDF_IO_QUEUE_CONFIG_INIT (&ioQueueConfig, WdfIoQueueDispatchManual); __analysis_assume(ioQueueConfig.EvtIoStop != 0); ntStatus = WdfIoQueueCreate ( deviceExtension->WdfDevice, &ioQueueConfig, WDF_NO_OBJECT_ATTRIBUTES, &deviceExtension->BusResetRequestsQueue); __analysis_assume(ioQueueConfig.EvtIoStop == 0); if(!NT_SUCCESS (ntStatus)) { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_PNP, "Error Creating Reset Request Queue %!STATUS!\n", ntStatus); return ntStatus; } WDF_OBJECT_ATTRIBUTES_INIT (&lockAttributes); lockAttributes.ParentObject = device; ntStatus = WdfSpinLockCreate (&lockAttributes,&deviceExtension->CromSpinLock); if(!NT_SUCCESS (ntStatus)) { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_PNP, "WdfSpinLockCreate CromSpinLock failed %!STATUS!\n", ntStatus); return ntStatus; } WDF_OBJECT_ATTRIBUTES_INIT (&lockAttributes); lockAttributes.ParentObject = device; ntStatus = WdfSpinLockCreate ( &lockAttributes, &deviceExtension->AsyncSpinLock); if(!NT_SUCCESS (ntStatus)) { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_PNP, "WdfSpinLockCreate AsyncSpinLock failed %!STATUS!\n", ntStatus); return ntStatus; } WDF_OBJECT_ATTRIBUTES_INIT (&lockAttributes); lockAttributes.ParentObject = device; ntStatus = WdfSpinLockCreate ( &lockAttributes, &deviceExtension->IsochSpinLock ); if(!NT_SUCCESS (ntStatus)) { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_PNP, "WdfSpinLockCreate IsochSpinLock failed %!STATUS!\n", ntStatus); return ntStatus; } WDF_OBJECT_ATTRIBUTES_INIT (&lockAttributes); lockAttributes.ParentObject = device; ntStatus = WdfSpinLockCreate ( &lockAttributes, &deviceExtension->IsochResourceSpinLock); if(!NT_SUCCESS (ntStatus)) { DoTraceLevelMessage(TRACE_LEVEL_ERROR, TRACE_FLAG_PNP, "WdfSpinLockCreate IsochResourceSpinLock failed %!STATUS!\n", ntStatus); return ntStatus; } InitializeListHead (&deviceExtension->CromData); InitializeListHead (&deviceExtension->AsyncAddressData); InitializeListHead (&deviceExtension->IsochDetachData); InitializeListHead (&deviceExtension->IsochResourceData); ExitS(ntStatus); return(ntStatus); } // kmdf1394_PnpAddDevice
/////////////////////////////////////////////////////////////////////////////// // // CDFilterEvtDeviceAdd // // This routine is called by the framework when a device of // the type we filter is found in the system. // // INPUTS: // // DriverObject - Our WDFDRIVER object // // DeviceInit - The device iniitalization structure we'll // be using to create our WDFDEVICE // // OUTPUTS: // // None. // // RETURNS: // // STATUS_SUCCESS, otherwise an error indicating why the driver could not // load. // // IRQL: // // This routine is called at IRQL == PASSIVE_LEVEL. // // NOTES: // // /////////////////////////////////////////////////////////////////////////////// NTSTATUS CDFilterEvtDeviceAdd(WDFDRIVER Driver, PWDFDEVICE_INIT DeviceInit) { NTSTATUS status; WDF_OBJECT_ATTRIBUTES wdfObjectAttr; WDFDEVICE wdfDevice; PFILTER_DEVICE_CONTEXT devContext; WDF_IO_QUEUE_CONFIG ioQueueConfig; #if DBG DbgPrint("CDFilterEvtDeviceAdd: Adding device...\n"); #endif UNREFERENCED_PARAMETER(Driver); // // Indicate that we're creating a FILTER device. This will cause // KMDF to attach us correctly to the device stack and auto-forward // any requests we don't explicitly handle. // WdfFdoInitSetFilter(DeviceInit); // // Setup our device attributes to have our context type // WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&wdfObjectAttr, FILTER_DEVICE_CONTEXT); // // And create our WDF device. This does a multitude of things, // including: // // 1) Creating a WDM device object // 2) Attaching the device object to the filtered device object // 3) Propogates all of the flags and characteristics of the // target device to our filter device. So, for example, if // the target device is setup for direct I/O our filter // device will also be setup for direct I/O // status = WdfDeviceCreate(&DeviceInit, &wdfObjectAttr, &wdfDevice); if (!NT_SUCCESS(status)) { #if DBG DbgPrint("WdfDeviceCreate failed - 0x%x\n", status); #endif return status; } // // Get our filter context // devContext = CDFilterGetDeviceContext(wdfDevice); // // Get our local (aka "in-stack") I/O Target. This is the device // to which we'll be forwarding requests that we intercept (and // hence aren't automagically forwarded). // devContext->TargetToSendRequestsTo = WdfDeviceGetIoTarget(wdfDevice); // // Now that that's over with, we can create our default queue. // This queue will allow us to pick off any I/O requests // that we may be interested in before they are forwarded // to the target device. // WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&ioQueueConfig, WdfIoQueueDispatchParallel); // // For this exercise we'll intercept READ requests // ioQueueConfig.EvtIoRead = CDFilterEvtRead; // // Create the queue... // status = WdfIoQueueCreate(wdfDevice, &ioQueueConfig, WDF_NO_OBJECT_ATTRIBUTES, NULL); if (!NT_SUCCESS(status)) { #if DBG DbgPrint("WdfIoQueueCreate failed - 0x%x\n", status); #endif return status; } // // Success! // return STATUS_SUCCESS; }
VOID Rio500_EvtIoDeviceControl( _In_ WDFQUEUE Queue, _In_ WDFREQUEST Request, _In_ size_t OutputBufferLength, _In_ size_t InputBufferLength, _In_ ULONG IoControlCode ) /*++ Routine Description: This event is called when the framework receives IRP_MJ_DEVICE_CONTROL requests from the system. Arguments: Queue - Handle to the framework queue object that is associated with the I/O request. Request - Handle to a framework request object. OutputBufferLength - length of the request's output buffer, if an output buffer is available. InputBufferLength - length of the request's input buffer, if an input buffer is available. IoControlCode - the driver-defined or system-defined I/O control code (IOCTL) that is associated with the request. Return Value: VOID --*/ { WDFDEVICE device; PVOID ioBuffer; PRIO_IOCTL_BLOCK ioBufferRio; size_t bufLength; NTSTATUS status; PDEVICE_CONTEXT pDevContext; ULONG length = 0; URB urb; PMDL pMdl = NULL; WDF_MEMORY_DESCRIPTOR memoryDesc; #ifdef _WIN64 BOOLEAN isWowRequest = FALSE; #endif // _WIN64 UNREFERENCED_PARAMETER(OutputBufferLength); UNREFERENCED_PARAMETER(InputBufferLength); Rio500_DbgPrint(3, ("Entered Rio500_DispatchDevCtrl\n")); PAGED_CODE(); // // initialize variables // device = WdfIoQueueGetDevice(Queue); pDevContext = GetDeviceContext(device); switch(IoControlCode) { case IOCTL_RIO500_RESET_PIPE: status = ResetPipe(pDevContext->ReadPipe); if (NT_SUCCESS(status)) { status = ResetPipe(pDevContext->WritePipe); } break; case IOCTL_RIO500_GET_CONFIG_DESCRIPTOR: if (pDevContext->UsbConfigurationDescriptor) { length = pDevContext->UsbConfigurationDescriptor->wTotalLength; status = WdfRequestRetrieveOutputBuffer(Request, length, &ioBuffer, &bufLength); if (!NT_SUCCESS(status)) { Rio500_DbgPrint(1, ("WdfRequestRetrieveInputBuffer failed\n")); break; } RtlCopyMemory(ioBuffer, pDevContext->UsbConfigurationDescriptor, length); status = STATUS_SUCCESS; } else { status = STATUS_INVALID_DEVICE_STATE; } break; case IOCTL_RIO500_RESET_DEVICE: status = ResetDevice(device); break; case IOCTL_RIO500_RIO_COMMAND: #ifdef _WIN64 if (IoIs32bitProcess(NULL)) { bufLength = sizeof(RIO_IOCTL_BLOCK) - sizeof(DWORD32); isWowRequest = TRUE; } else #endif // _WIN64 { bufLength = sizeof(RIO_IOCTL_BLOCK); } status = WdfRequestRetrieveInputBuffer( Request, bufLength, &ioBufferRio, NULL ); if (NT_SUCCESS(status)) { #ifdef _WIN64 if (isWowRequest) { ioBuffer = (PVOID)ioBufferRio->MsgData.DataWow; } else #endif // _WIN64 { ioBuffer = ioBufferRio->MsgData.Data; } if (ioBufferRio->MsgLength != 0 && ioBuffer != NULL) { pMdl = IoAllocateMdl( ioBuffer, ioBufferRio->MsgLength, FALSE, FALSE, NULL ); MmProbeAndLockPages(pMdl, (KPROCESSOR_MODE)KernelMode, IoModifyAccess); } memset(&urb, 0, sizeof(urb)); urb.UrbControlVendorClassRequest.Hdr.Length = sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST); urb.UrbControlVendorClassRequest.Hdr.Function = URB_FUNCTION_VENDOR_DEVICE; urb.UrbControlVendorClassRequest.TransferBuffer = NULL; urb.UrbControlVendorClassRequest.RequestTypeReservedBits = 0x00; urb.UrbControlVendorClassRequest.TransferBufferLength = ioBufferRio->MsgLength; urb.UrbControlVendorClassRequest.TransferBufferMDL = pMdl; urb.UrbControlVendorClassRequest.Request = ioBufferRio->RequestCode; urb.UrbControlVendorClassRequest.Value = ioBufferRio->MsgValue; urb.UrbControlVendorClassRequest.Index = ioBufferRio->MsgIndex; urb.UrbControlVendorClassRequest.TransferFlags = USBD_SHORT_TRANSFER_OK; if (ioBufferRio->RequestType & 0x80) { urb.UrbControlVendorClassRequest.TransferFlags |= USBD_TRANSFER_DIRECTION_IN; } urb.UrbControlVendorClassRequest.UrbLink = NULL; WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memoryDesc, &urb, sizeof(urb)); status = WdfIoTargetSendInternalIoctlOthersSynchronously( WdfDeviceGetIoTarget(device), Request, IOCTL_INTERNAL_USB_SUBMIT_URB, &memoryDesc, NULL, NULL, NULL, NULL ); if (pMdl != NULL) { MmUnlockPages(pMdl); IoFreeMdl(pMdl); } } break; default: status = STATUS_INVALID_DEVICE_REQUEST; break; } WdfRequestCompleteWithInformation(Request, status, length); Rio500_DbgPrint(3, ("Exit Rio500_DispatchDevCtrl\n")); }
static NTSTATUS XenVbd_EvtDeviceAdd(WDFDRIVER driver, PWDFDEVICE_INIT device_init) { PXENVBD_FILTER_DATA xvfd; NTSTATUS status; WDFDEVICE device; WDF_OBJECT_ATTRIBUTES device_attributes; WDF_PNPPOWER_EVENT_CALLBACKS pnp_power_callbacks; WDF_DPC_CONFIG dpc_config; WDF_OBJECT_ATTRIBUTES oa; UCHAR pnp_minor_functions[] = { IRP_MN_START_DEVICE }; UCHAR power_minor_functions[] = { IRP_MN_SET_POWER }; UNREFERENCED_PARAMETER(driver); FUNCTION_ENTER(); WdfDeviceInitSetDeviceType(device_init, FILE_DEVICE_UNKNOWN); WdfFdoInitSetFilter(device_init); WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnp_power_callbacks); pnp_power_callbacks.EvtDeviceD0Entry = XenVbd_EvtDeviceD0Entry; pnp_power_callbacks.EvtDeviceD0Exit = XenVbd_EvtDeviceD0Exit; WdfDeviceInitSetPnpPowerEventCallbacks(device_init, &pnp_power_callbacks); status = WdfDeviceInitAssignWdmIrpPreprocessCallback(device_init, XenVbd_EvtDeviceWdmIrpPreprocess_START_DEVICE, IRP_MJ_PNP, pnp_minor_functions, ARRAY_SIZE(pnp_minor_functions)); if (!NT_SUCCESS(status)) { return status; } status = WdfDeviceInitAssignWdmIrpPreprocessCallback(device_init, XenVbd_EvtDeviceWdmIrpPreprocess_SET_POWER, IRP_MJ_POWER, power_minor_functions, ARRAY_SIZE(power_minor_functions)); if (!NT_SUCCESS(status)) { return status; } WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&device_attributes, XENVBD_FILTER_DATA); status = WdfDeviceCreate(&device_init, &device_attributes, &device); if (!NT_SUCCESS(status)) { FUNCTION_MSG("Error creating device 0x%x\n", status); return status; } xvfd = GetXvfd(device); xvfd->wdf_device = device; xvfd->wdf_target = WdfDeviceGetIoTarget(device); xvfd->xvdd.xvfd = xvfd; xvfd->xvdd.pdo = WdfDeviceWdmGetPhysicalDevice(device); xvfd->xvdd.grant_tag = XENVBD_POOL_TAG; KeInitializeEvent(&xvfd->xvdd.backend_event, SynchronizationEvent, FALSE); WDF_DPC_CONFIG_INIT(&dpc_config, XenVbd_EvtDpcEvent); WDF_OBJECT_ATTRIBUTES_INIT(&oa); oa.ParentObject = device; status = WdfDpcCreate(&dpc_config, &oa, &xvfd->dpc); WdfDeviceSetSpecialFileSupport(device, WdfSpecialFilePaging, TRUE); WdfDeviceSetSpecialFileSupport(device, WdfSpecialFileHibernation, TRUE); WdfDeviceSetSpecialFileSupport(device, WdfSpecialFileDump, TRUE); FUNCTION_EXIT(); return status; }
VOID SimSensorIoDeviceControl( WDFQUEUE Queue, WDFREQUEST Request, size_t OutputBufferLength, size_t InputBufferLength, ULONG IoControlCode ) /*++ Routine Description: Handles requests to read or write the simulated device state. Arguments: Queue - Supplies a handle to the framework queue object that is associated with the I/O request. Request - Supplies a handle to a framework request object. This one represents the IRP_MJ_DEVICE_CONTROL IRP received by the framework. OutputBufferLength - Supplies the length, in bytes, of the request's output buffer, if an output buffer is available. InputBufferLength - Supplies the length, in bytes, of the request's input buffer, if an input buffer is available. IoControlCode - Supplies the Driver-defined or system-defined I/O control code (IOCtl) that is associated with the request. Return Value: VOID --*/ { ULONG BytesReturned; WDFDEVICE Device; BOOLEAN Result; WDF_REQUEST_SEND_OPTIONS RequestSendOptions; NTSTATUS Status; UNREFERENCED_PARAMETER(InputBufferLength); UNREFERENCED_PARAMETER(OutputBufferLength); PAGED_CODE(); Device = WdfIoQueueGetDevice(Queue); DebugPrint(SIMSENSOR_NOTE, "SimSensorIoDeviceControl: 0x%p\n", Device); BytesReturned = 0; switch(IoControlCode) { case IOCTL_THERMAL_READ_TEMPERATURE: // // This call will either complete the request or put it in the pending // queue. // SimSensorAddReadRequest(Device, Request); break; default: // // Unrecognized IOCtls must be forwarded down the stack. // WDF_REQUEST_SEND_OPTIONS_INIT( &RequestSendOptions, WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET); WdfRequestFormatRequestUsingCurrentType(Request); Result = WdfRequestSend( Request, WdfDeviceGetIoTarget(Device), &RequestSendOptions); if (Result == FALSE) { Status = WdfRequestGetStatus(Request); DebugPrint(SIMSENSOR_WARN, "WdfRequestSend() Failed. Request Status = 0x%x\n", Status); WdfRequestComplete(Request, Status); } break; } }
NTSTATUS t1394_EvtDeviceAdd( /*IN*/WDFDRIVER Driver, /*IN*/PWDFDEVICE_INIT DeviceInit ) /*++ Routine Description: EvtDeviceAdd is called by the framework in response to AddDevice call from the PnP manager. Arguments: Driver - Handle to a framework driver object created in DriverEntry DeviceInit - Pointer to a framework-allocated WDFDEVICE_INIT structure. Return Value: NTSTATUS --*/ { NTSTATUS status = STATUS_SUCCESS; PDEVICE_EXTENSION deviceExtension; PNODE_DEVICE_EXTENSION pNodeExt; WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks; WDF_OBJECT_ATTRIBUTES fdoAttributes,lockAttributes; WDFDEVICE device; WDF_DEVICE_PNP_CAPABILITIES pnpCaps; WDF_IO_QUEUE_CONFIG ioQueueConfig; WDF_IO_TARGET_OPEN_PARAMS openParams; //UNREFERENCED_PARAMETER(Driver); //ENTER("t1394_PnpAddDevice"); // // Zero out the PnpPowerCallbacks structure. // WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks); // // Set Callbacks for any of the functions we are interested in. // If no callback is set, Framework will take the default action // by itself. // // These two callbacks set up and tear down hardware state, // specifically that which only has to be done once. // pnpPowerCallbacks.EvtDevicePrepareHardware = t1394_EvtPrepareHardware; pnpPowerCallbacks.EvtDeviceReleaseHardware = t1394_EvtReleaseHardware; pnpPowerCallbacks.EvtDeviceSelfManagedIoCleanup = t1394_EvtDeviceSelfManagedIoCleanup; pnpPowerCallbacks.EvtDeviceD0Entry = t1394_EvtDeviceD0Entry; pnpPowerCallbacks.EvtDeviceD0Exit = t1394_EvtDeviceD0Exit; // // Register the PnP and power callbacks. Power policy related callbacks // will be registered// later in SotwareInit. // WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks); if ( !NT_SUCCESS(status)) { //TRACE(TL_ERROR, ("WdfDeviceInitSetPnpPowerEventCallbacks failed %x\n", // status)); return status; } WdfDeviceInitSetExclusive(DeviceInit, FALSE); // // Specify the size and type of device context. // WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&fdoAttributes, DEVICE_EXTENSION); status = WdfDeviceCreate(&DeviceInit, &fdoAttributes, &device); if ( !NT_SUCCESS(status)) { //TRACE(TL_ERROR, ("WdfDeviceInitialize failed %x\n", status)); return status; } deviceExtension = GetDeviceContext (device); deviceExtension->WdfDevice = device; //TRACE(TL_TRACE, ("PDO(0x%p) FDO(0x%p), Lower(0x%p) DevExt (0x%p)\n", // WdfDeviceWdmGetPhysicalDevice (device), // WdfDeviceWdmGetDeviceObject (device), // WdfDeviceWdmGetAttachedDevice(device), // deviceExtension)); // // Tell the Framework that this device will need an interface so that // application can interact with it. // status = WdfDeviceCreateDeviceInterface( device, #if defined(_1394VDEV_DRIVER_) (LPGUID) &GUID_1394VDEV, #else (LPGUID) &GUID_1394DIAG, #endif NULL ); if (!NT_SUCCESS (status)) { //TRACE(TL_ERROR, ("WdfDeviceCreateDeviceInterface failed %x\n", status)); return status; } // // Tell the framework to set the SurpriseRemovalOK in the DeviceCaps so // that you don't get the popup in usermode (on Win2K) when you surprise // remove the device. // WDF_DEVICE_PNP_CAPABILITIES_INIT(&pnpCaps); pnpCaps.SurpriseRemovalOK = WdfTrue; WdfDeviceSetPnpCapabilities(device, &pnpCaps); // save the device object we created as our physical device object deviceExtension->PhysicalDeviceObject = WdfDeviceWdmGetPhysicalDevice (device); if (deviceExtension->PhysicalDeviceObject == NULL) { //TRACE(TL_ERROR, ("WdfDeviceWdmGetPhysicalDevice: NULL DeviceObject\n")); return STATUS_UNSUCCESSFUL; } // // This is our default IoTarget representing the deviceobject // we are attached to. // deviceExtension->StackIoTarget = WdfDeviceGetIoTarget(device); deviceExtension->StackDeviceObject = WdfDeviceWdmGetAttachedDevice(device); if (deviceExtension->StackDeviceObject == NULL) { //TRACE(TL_ERROR, ("WdfDeviceWdmGetAttachedDevice: NULL DeviceObject\n")); return STATUS_UNSUCCESSFUL; } // Patch: this code is not in DDK 7600.16385.1 { // // Get the port device object from the passed in PhysicalDeviceObject // created by the 1394 stack for us. // Note: we can't use the top of the stack and get its device extension // in case there is a filter driver between us and our PDO. // //pNodeExt = WdfDeviceWdmGetPhysicalDevice(device)->DeviceExtension; //deviceExtension->PortDeviceObject = pNodeExt->PortDeviceObject; // Patch: this code is not in DDK 7600.16385.1 } //TRACE(TL_TRACE, ("PortDeviceObject = 0x%x\n", // deviceExtension->PortDeviceObject)); // // Create a automanaged queue for dispatching ioctl requests. // All other requests are automatically failed by the framework. // By creating an automanaged queue we don't have to worry about // PNP/Power synchronization. // A default queue gets all the requests that are not // configure-fowarded using WdfDeviceConfigureRequestDispatching. // WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE( &ioQueueConfig, WdfIoQueueDispatchParallel ); ioQueueConfig.EvtIoDeviceControl = t1394_EvtIoDeviceControl; status = WdfIoQueueCreate( deviceExtension->WdfDevice, &ioQueueConfig, WDF_NO_OBJECT_ATTRIBUTES, &deviceExtension->IoctlQueue // queue handle ); if (!NT_SUCCESS (status)) { //TRACE(TL_ERROR, ("WdfIoQueueCreate failed 0x%x\n", status)); return status; } // // Create an additional queue to hold bus reset requests. // WDF_IO_QUEUE_CONFIG_INIT( &ioQueueConfig, WdfIoQueueDispatchManual ); status = WdfIoQueueCreate ( deviceExtension->WdfDevice, &ioQueueConfig, WDF_NO_OBJECT_ATTRIBUTES, &deviceExtension->BusResetRequestsQueue ); if(!NT_SUCCESS (status)){ //TRACE(TL_ERROR, ("Error Creating Reset Request Queue 0x%x\n", // status)); return status; } // // Create another IoTarget representing PortDeviceObject so that // we can send async requests in rawmode directly to the port device. // WDF_IO_TARGET_OPEN_PARAMS_INIT_EXISTING_DEVICE(&openParams, pNodeExt->PortDeviceObject); status = WdfIoTargetCreate(device, WDF_NO_OBJECT_ATTRIBUTES, &deviceExtension->PortDeviceIoTarget); if (!NT_SUCCESS (status)) { //TRACE(TL_ERROR, ("WdfIoTargetCreate failed 0x%x\n", status)); return status; } status = WdfIoTargetOpen(deviceExtension->PortDeviceIoTarget, &openParams); if (!NT_SUCCESS (status)) { //TRACE(TL_ERROR, ("WdfIoTargetCreate failed 0x%x\n", status)); return status; } WDF_OBJECT_ATTRIBUTES_INIT(&lockAttributes); lockAttributes.ParentObject = device; // initialize the spinlock/list to store the bus reset irps... status = WdfSpinLockCreate(&lockAttributes,&deviceExtension->CromSpinLock ); if(!NT_SUCCESS(status)){ //TRACE(TL_ERROR, ("WdfSpinLockCreate CromSpinLock " // "failed 0x%x\n", status)); return status; } WDF_OBJECT_ATTRIBUTES_INIT(&lockAttributes); lockAttributes.ParentObject = device; status = WdfSpinLockCreate(&lockAttributes, &deviceExtension->AsyncSpinLock ); if(!NT_SUCCESS(status)){ //TRACE(TL_ERROR, ("WdfSpinLockCreate AsyncSpinLock " // "failed 0x%x\n", status)); return status; } WDF_OBJECT_ATTRIBUTES_INIT(&lockAttributes); lockAttributes.ParentObject = device; status = WdfSpinLockCreate(&lockAttributes, &deviceExtension->IsochSpinLock ); if(!NT_SUCCESS(status)){ //TRACE(TL_ERROR, ("WdfSpinLockCreate IsochSpinLock " // "failed 0x%x\n", status)); return status; } WDF_OBJECT_ATTRIBUTES_INIT(&lockAttributes); lockAttributes.ParentObject = device; status = WdfSpinLockCreate(&lockAttributes, &deviceExtension->IsochResourceSpinLock ); if(!NT_SUCCESS(status)){ //TRACE(TL_ERROR, ("WdfSpinLockCreate IsochResourceSpinLock " // "failed 0x%x\n", status)); return status; } InitializeListHead(&deviceExtension->CromData); InitializeListHead(&deviceExtension->AsyncAddressData); InitializeListHead(&deviceExtension->IsochDetachData); InitializeListHead(&deviceExtension->IsochResourceData); //EXIT("t1394_PnpAddDevice", status); return(status); } // t1394_PnpAddDevice
NTSTATUS Acpi_EvaluateUcsiDsm ( _In_ PACPI_CONTEXT AcpiCtx, _In_ ULONG FunctionIndex, _Outptr_opt_ PACPI_EVAL_OUTPUT_BUFFER* Output ) /*++ N.B. Caller is expected to free the Output buffer. --*/ { NTSTATUS status; WDFDEVICE device; WDFMEMORY inputMemory; WDF_MEMORY_DESCRIPTOR inputMemDesc; PACPI_EVAL_INPUT_BUFFER_COMPLEX inputBuffer; size_t inputBufferSize; size_t inputArgumentBufferSize; PACPI_METHOD_ARGUMENT argument; WDF_MEMORY_DESCRIPTOR outputMemDesc; PACPI_EVAL_OUTPUT_BUFFER outputBuffer; size_t outputBufferSize; size_t outputArgumentBufferSize; WDF_OBJECT_ATTRIBUTES attributes; WDF_REQUEST_SEND_OPTIONS sendOptions; PAGED_CODE(); TRACE_FUNC_ENTRY(TRACE_FLAG_ACPI); device = Context_GetWdfDevice(AcpiCtx); inputMemory = WDF_NO_HANDLE; outputBuffer = nullptr; inputArgumentBufferSize = ACPI_METHOD_ARGUMENT_LENGTH(sizeof(GUID)) + ACPI_METHOD_ARGUMENT_LENGTH(sizeof(ULONG)) + ACPI_METHOD_ARGUMENT_LENGTH(sizeof(ULONG)) + ACPI_METHOD_ARGUMENT_LENGTH(0); inputBufferSize = FIELD_OFFSET(ACPI_EVAL_INPUT_BUFFER_COMPLEX, Argument) + inputArgumentBufferSize; WDF_OBJECT_ATTRIBUTES_INIT(&attributes); attributes.ParentObject = device; status = WdfMemoryCreate(&attributes, NonPagedPoolNx, 0, inputBufferSize, &inputMemory, (PVOID*) &inputBuffer); if (!NT_SUCCESS(status)) { TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] WdfMemoryCreate failed for %Iu bytes - %!STATUS!", device, inputBufferSize, status); goto Exit; } RtlZeroMemory(inputBuffer, inputBufferSize); inputBuffer->Signature = ACPI_EVAL_INPUT_BUFFER_COMPLEX_SIGNATURE; inputBuffer->Size = (ULONG) inputArgumentBufferSize; inputBuffer->ArgumentCount = 4; inputBuffer->MethodNameAsUlong = (ULONG) 'MSD_'; argument = &(inputBuffer->Argument[0]); ACPI_METHOD_SET_ARGUMENT_BUFFER(argument, &GUID_UCSI_DSM, sizeof(GUID_UCSI_DSM)); argument = ACPI_METHOD_NEXT_ARGUMENT(argument); ACPI_METHOD_SET_ARGUMENT_INTEGER(argument, UCSI_DSM_REVISION); argument = ACPI_METHOD_NEXT_ARGUMENT(argument); ACPI_METHOD_SET_ARGUMENT_INTEGER(argument, FunctionIndex); argument = ACPI_METHOD_NEXT_ARGUMENT(argument); argument->Type = ACPI_METHOD_ARGUMENT_PACKAGE_EX; argument->DataLength = 0; outputArgumentBufferSize = ACPI_METHOD_ARGUMENT_LENGTH(sizeof(ULONG)); outputBufferSize = FIELD_OFFSET(ACPI_EVAL_OUTPUT_BUFFER, Argument) + outputArgumentBufferSize; outputBuffer = (PACPI_EVAL_OUTPUT_BUFFER) ExAllocatePoolWithTag(NonPagedPoolNx, outputBufferSize, TAG_UCSI); if (outputBuffer == nullptr) { status = STATUS_INSUFFICIENT_RESOURCES; TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] ExAllocatePoolWithTag failed for %Iu bytes", device, outputBufferSize); goto Exit; } RtlZeroMemory(outputBuffer, outputBufferSize); WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(&inputMemDesc, inputMemory, NULL); WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&outputMemDesc, outputBuffer, (ULONG) outputBufferSize); WDF_REQUEST_SEND_OPTIONS_INIT(&sendOptions, WDF_REQUEST_SEND_OPTION_SYNCHRONOUS); WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&sendOptions, WDF_REL_TIMEOUT_IN_MS(UCSI_DSM_EXECUTION_TIMEOUT_IN_MS)); status = WdfIoTargetSendInternalIoctlSynchronously( WdfDeviceGetIoTarget(device), NULL, IOCTL_ACPI_EVAL_METHOD, &inputMemDesc, &outputMemDesc, &sendOptions, NULL); if (!NT_SUCCESS(status)) { TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] IOCTL_ACPI_EVAL_METHOD for _DSM failed - %!STATUS!", device, status); goto Exit; } if (outputBuffer->Signature != ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE) { TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] ACPI_EVAL_OUTPUT_BUFFER signature is incorrect", device); status = STATUS_ACPI_INVALID_DATA; goto Exit; } Exit: if (inputMemory != WDF_NO_HANDLE) { WdfObjectDelete(inputMemory); } if (!NT_SUCCESS(status) || (Output == nullptr)) { if (outputBuffer) { ExFreePoolWithTag(outputBuffer, TAG_UCSI); } } else { *Output = outputBuffer; } TRACE_FUNC_EXIT(TRACE_FLAG_ACPI); return status; }
NTSTATUS Acpi_EvaluatePld ( _In_ PACPI_CONTEXT AcpiCtx, _In_ LPCSTR DeviceName, _Out_ PACPI_PLD_BUFFER PldBuffer ) { NTSTATUS status; WDFDEVICE device; WDF_MEMORY_DESCRIPTOR inputMemDesc; ACPI_EVAL_INPUT_BUFFER_EX inputBuffer; size_t inputBufferSize; WDFMEMORY outputMemory; WDF_MEMORY_DESCRIPTOR outputMemDesc; PACPI_EVAL_OUTPUT_BUFFER outputBuffer; size_t outputBufferSize; size_t outputArgumentBufferSize; WDF_OBJECT_ATTRIBUTES attributes; PAGED_CODE(); TRACE_FUNC_ENTRY(TRACE_FLAG_ACPI); device = Context_GetWdfDevice(AcpiCtx); outputMemory = WDF_NO_HANDLE; inputBufferSize = sizeof(inputBuffer); RtlZeroMemory(&inputBuffer, inputBufferSize); inputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE_EX; status = RtlStringCchPrintfA(inputBuffer.MethodName, sizeof(inputBuffer.MethodName), "%s._PLD", DeviceName); if (!NT_SUCCESS(status)) { TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] RtlStringCchPrintfA for creating method name failed - %!STATUS!", device, status); goto Exit; } outputArgumentBufferSize = 1024; outputBufferSize = FIELD_OFFSET(ACPI_EVAL_OUTPUT_BUFFER, Argument) + outputArgumentBufferSize; WDF_OBJECT_ATTRIBUTES_INIT(&attributes); attributes.ParentObject = device; status = WdfMemoryCreate(&attributes, NonPagedPoolNx, 0, outputBufferSize, &outputMemory, (PVOID*) &outputBuffer); if (!NT_SUCCESS(status)) { TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] WdfMemoryCreate failed for %Iu bytes - %!STATUS!", device, outputBufferSize, status); goto Exit; } RtlZeroMemory(outputBuffer, outputBufferSize); WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&inputMemDesc, &inputBuffer, (ULONG) inputBufferSize); WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(&outputMemDesc, outputMemory, NULL); status = WdfIoTargetSendInternalIoctlSynchronously( WdfDeviceGetIoTarget(device), NULL, IOCTL_ACPI_EVAL_METHOD_EX, &inputMemDesc, &outputMemDesc, NULL, NULL); if (!NT_SUCCESS(status)) { TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] IOCTL_ACPI_EVAL_METHOD_EX for %s failed - %!STATUS!", device, inputBuffer.MethodName, status); goto Exit; } if (outputBuffer->Signature != ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE) { status = STATUS_ACPI_INVALID_DATA; TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] ACPI_EVAL_OUTPUT_BUFFER signature is incorrect", device); goto Exit; } if (outputBuffer->Count < 1) { status = STATUS_ACPI_INVALID_DATA; TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] _PLD for %s didn't return anything", device, inputBuffer.MethodName); goto Exit; } if (outputBuffer->Argument[0].Type != ACPI_METHOD_ARGUMENT_BUFFER) { status = STATUS_ACPI_INVALID_DATA; TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] _PLD for %s returned an unexpected argument of type %d", device, inputBuffer.MethodName, outputBuffer->Argument[0].Type); goto Exit; } if (outputBuffer->Argument[0].DataLength < sizeof(*PldBuffer)) { status = STATUS_ACPI_INVALID_DATA; TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] Unexpected _PLD buffer size for %s. Expected %Iu bytes, got %Iu bytes", device, inputBuffer.MethodName, sizeof(*PldBuffer), outputBuffer->Argument[0].DataLength); goto Exit; } *PldBuffer = *((PACPI_PLD_BUFFER) outputBuffer->Argument[0].Data); Exit: if (outputMemory != WDF_NO_HANDLE) { WdfObjectDelete(outputMemory); } TRACE_FUNC_EXIT(TRACE_FLAG_ACPI); return status; }
VOID KbFilter_EvtIoInternalDeviceControl( IN WDFQUEUE Queue, IN WDFREQUEST Request, IN size_t OutputBufferLength, IN size_t InputBufferLength, IN ULONG IoControlCode ) /*++ Routine Description: This routine is the dispatch routine for internal device control requests. There are two specific control codes that are of interest: IOCTL_INTERNAL_KEYBOARD_CONNECT: Store the old context and function pointer and replace it with our own. This makes life much simpler than intercepting IRPs sent by the RIT and modifying them on the way back up. IOCTL_INTERNAL_I8042_HOOK_KEYBOARD: Add in the necessary function pointers and context values so that we can alter how the ps/2 keyboard is initialized. NOTE: Handling IOCTL_INTERNAL_I8042_HOOK_KEYBOARD is *NOT* necessary if all you want to do is filter KEYBOARD_INPUT_DATAs. You can remove the handling code and all related device extension fields and functions to conserve space. Arguments: Queue - Handle to the framework queue object that is associated with the I/O request. Request - Handle to a framework request object. OutputBufferLength - length of the request's output buffer, if an output buffer is available. InputBufferLength - length of the request's input buffer, if an input buffer is available. IoControlCode - the driver-defined or system-defined I/O control code (IOCTL) that is associated with the request. Return Value: VOID --*/ { PDEVICE_EXTENSION devExt; PINTERNAL_I8042_HOOK_KEYBOARD hookKeyboard = NULL; PCONNECT_DATA connectData = NULL; NTSTATUS status = STATUS_SUCCESS; size_t length; WDFDEVICE hDevice; BOOLEAN forwardWithCompletionRoutine = FALSE; BOOLEAN ret = TRUE; WDFCONTEXT completionContext = WDF_NO_CONTEXT; WDF_REQUEST_SEND_OPTIONS options; WDFMEMORY outputMemory; UNREFERENCED_PARAMETER(OutputBufferLength); UNREFERENCED_PARAMETER(InputBufferLength); PAGED_CODE(); DebugPrint(("Entered KbFilter_EvtIoInternalDeviceControl\n")); hDevice = WdfIoQueueGetDevice(Queue); devExt = FilterGetData(hDevice); switch (IoControlCode) { // // Connect a keyboard class device driver to the port driver. // case IOCTL_INTERNAL_KEYBOARD_CONNECT: // // Only allow one connection. // if (devExt->UpperConnectData.ClassService != NULL) { status = STATUS_SHARING_VIOLATION; break; } // // Get the input buffer from the request // (Parameters.DeviceIoControl.Type3InputBuffer). // status = WdfRequestRetrieveInputBuffer(Request, sizeof(CONNECT_DATA), &connectData, &length); if(!NT_SUCCESS(status)){ DebugPrint(("WdfRequestRetrieveInputBuffer failed %x\n", status)); break; } NT_ASSERT(length == InputBufferLength); devExt->UpperConnectData = *connectData; // // Hook into the report chain. Everytime a keyboard packet is reported // to the system, KbFilter_ServiceCallback will be called // connectData->ClassDeviceObject = WdfDeviceWdmGetDeviceObject(hDevice); #pragma warning(disable:4152) //nonstandard extension, function/data pointer conversion connectData->ClassService = KbFilter_ServiceCallback; #pragma warning(default:4152) break; // // Disconnect a keyboard class device driver from the port driver. // case IOCTL_INTERNAL_KEYBOARD_DISCONNECT: // // Clear the connection parameters in the device extension. // // devExt->UpperConnectData.ClassDeviceObject = NULL; // devExt->UpperConnectData.ClassService = NULL; status = STATUS_NOT_IMPLEMENTED; break; // // Attach this driver to the initialization and byte processing of the // i8042 (ie PS/2) keyboard. This is only necessary if you want to do PS/2 // specific functions, otherwise hooking the CONNECT_DATA is sufficient // case IOCTL_INTERNAL_I8042_HOOK_KEYBOARD: DebugPrint(("hook keyboard received!\n")); // // Get the input buffer from the request // (Parameters.DeviceIoControl.Type3InputBuffer) // status = WdfRequestRetrieveInputBuffer(Request, sizeof(INTERNAL_I8042_HOOK_KEYBOARD), &hookKeyboard, &length); if(!NT_SUCCESS(status)){ DebugPrint(("WdfRequestRetrieveInputBuffer failed %x\n", status)); break; } NT_ASSERT(length == InputBufferLength); // // Enter our own initialization routine and record any Init routine // that may be above us. Repeat for the isr hook // devExt->UpperContext = hookKeyboard->Context; // // replace old Context with our own // hookKeyboard->Context = (PVOID) devExt; if (hookKeyboard->InitializationRoutine) { devExt->UpperInitializationRoutine = hookKeyboard->InitializationRoutine; } hookKeyboard->InitializationRoutine = (PI8042_KEYBOARD_INITIALIZATION_ROUTINE) KbFilter_InitializationRoutine; if (hookKeyboard->IsrRoutine) { devExt->UpperIsrHook = hookKeyboard->IsrRoutine; } hookKeyboard->IsrRoutine = (PI8042_KEYBOARD_ISR) KbFilter_IsrHook; // // Store all of the other important stuff // devExt->IsrWritePort = hookKeyboard->IsrWritePort; devExt->QueueKeyboardPacket = hookKeyboard->QueueKeyboardPacket; devExt->CallContext = hookKeyboard->CallContext; status = STATUS_SUCCESS; break; case IOCTL_KEYBOARD_QUERY_ATTRIBUTES: forwardWithCompletionRoutine = TRUE; completionContext = devExt; break; // // Might want to capture these in the future. For now, then pass them down // the stack. These queries must be successful for the RIT to communicate // with the keyboard. // case IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION: case IOCTL_KEYBOARD_QUERY_INDICATORS: case IOCTL_KEYBOARD_SET_INDICATORS: case IOCTL_KEYBOARD_QUERY_TYPEMATIC: case IOCTL_KEYBOARD_SET_TYPEMATIC: break; } if (!NT_SUCCESS(status)) { WdfRequestComplete(Request, status); return; } // // Forward the request down. WdfDeviceGetIoTarget returns // the default target, which represents the device attached to us below in // the stack. // if (forwardWithCompletionRoutine) { // // Format the request with the output memory so the completion routine // can access the return data in order to cache it into the context area // status = WdfRequestRetrieveOutputMemory(Request, &outputMemory); if (!NT_SUCCESS(status)) { DebugPrint(("WdfRequestRetrieveOutputMemory failed: 0x%x\n", status)); WdfRequestComplete(Request, status); return; } status = WdfIoTargetFormatRequestForInternalIoctl(WdfDeviceGetIoTarget(hDevice), Request, IoControlCode, NULL, NULL, outputMemory, NULL); if (!NT_SUCCESS(status)) { DebugPrint(("WdfIoTargetFormatRequestForInternalIoctl failed: 0x%x\n", status)); WdfRequestComplete(Request, status); return; } // // Set our completion routine with a context area that we will save // the output data into // WdfRequestSetCompletionRoutine(Request, KbFilterRequestCompletionRoutine, completionContext); ret = WdfRequestSend(Request, WdfDeviceGetIoTarget(hDevice), WDF_NO_SEND_OPTIONS); if (ret == FALSE) { status = WdfRequestGetStatus (Request); DebugPrint( ("WdfRequestSend failed: 0x%x\n", status)); WdfRequestComplete(Request, status); } } else { // // We are not interested in post processing the IRP so // fire and forget. // WDF_REQUEST_SEND_OPTIONS_INIT(&options, WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET); ret = WdfRequestSend(Request, WdfDeviceGetIoTarget(hDevice), &options); if (ret == FALSE) { status = WdfRequestGetStatus (Request); DebugPrint(("WdfRequestSend failed: 0x%x\n", status)); WdfRequestComplete(Request, status); } } return; }
VOID MouFilter_EvtIoInternalDeviceControl( IN WDFQUEUE Queue, IN WDFREQUEST Request, IN size_t OutputBufferLength, IN size_t InputBufferLength, IN ULONG IoControlCode ) /*++ Routine Description: This routine is the dispatch routine for internal device control requests. There are two specific control codes that are of interest: IOCTL_INTERNAL_MOUSE_CONNECT: Store the old context and function pointer and replace it with our own. This makes life much simpler than intercepting IRPs sent by the RIT and modifying them on the way back up. IOCTL_INTERNAL_I8042_HOOK_MOUSE: Add in the necessary function pointers and context values so that we can alter how the ps/2 mouse is initialized. NOTE: Handling IOCTL_INTERNAL_I8042_HOOK_MOUSE is *NOT* necessary if all you want to do is filter MOUSE_INPUT_DATAs. You can remove the handling code and all related device extension fields and functions to conserve space. --*/ { PDEVICE_EXTENSION devExt; PCONNECT_DATA connectData; PINTERNAL_I8042_HOOK_MOUSE hookMouse; NTSTATUS status = STATUS_SUCCESS; WDFDEVICE hDevice; size_t length; UNREFERENCED_PARAMETER(OutputBufferLength); UNREFERENCED_PARAMETER(InputBufferLength); PAGED_CODE(); hDevice = WdfIoQueueGetDevice(Queue); devExt = FilterGetData(hDevice); switch (IoControlCode) { // // Connect a mouse class device driver to the port driver. // case IOCTL_INTERNAL_MOUSE_CONNECT: // // Only allow one connection. // if (devExt->UpperConnectData.ClassService != NULL) { status = STATUS_SHARING_VIOLATION; break; } // // Copy the connection parameters to the device extension. // status = WdfRequestRetrieveInputBuffer(Request, sizeof(CONNECT_DATA), &connectData, &length); if(!NT_SUCCESS(status)) { DebugPrint(("WdfRequestRetrieveInputBuffer failed %x\n", status)); break; } devExt->UpperConnectData = *connectData; // // Hook into the report chain. Everytime a mouse packet is reported to // the system, MouFilter_ServiceCallback will be called // connectData->ClassDeviceObject = WdfDeviceWdmGetDeviceObject(hDevice); connectData->ClassService = MouFilter_ServiceCallback; break; // // Disconnect a mouse class device driver from the port driver. // case IOCTL_INTERNAL_MOUSE_DISCONNECT: // // Clear the connection parameters in the device extension. // // devExt->UpperConnectData.ClassDeviceObject = NULL; // devExt->UpperConnectData.ClassService = NULL; status = STATUS_NOT_IMPLEMENTED; break; // // Attach this driver to the initialization and byte processing of the // i8042 (ie PS/2) mouse. This is only necessary if you want to do PS/2 // specific functions, otherwise hooking the CONNECT_DATA is sufficient // case IOCTL_INTERNAL_I8042_HOOK_MOUSE: DebugPrint(("hook mouse received!\n")); // Get the input buffer from the request // (Parameters.DeviceIoControl.Type3InputBuffer) // status = WdfRequestRetrieveInputBuffer(Request, sizeof(INTERNAL_I8042_HOOK_MOUSE), &hookMouse, &length); if(!NT_SUCCESS(status)) { DebugPrint(("WdfRequestRetrieveInputBuffer failed %x\n", status)); break; } // // Set isr routine and context and record any values from above this driver // devExt->UpperContext = hookMouse->Context; hookMouse->Context = (PVOID) devExt; if (hookMouse->IsrRoutine) { devExt->UpperIsrHook = hookMouse->IsrRoutine; } hookMouse->IsrRoutine = (PI8042_MOUSE_ISR) MouFilter_IsrHook; // // Store all of the other functions we might need in the future // devExt->IsrWritePort = hookMouse->IsrWritePort; devExt->CallContext = hookMouse->CallContext; devExt->QueueMousePacket = hookMouse->QueueMousePacket; status = STATUS_SUCCESS; break; // // Might want to capture this in the future. For now, then pass it down // the stack. These queries must be successful for the RIT to communicate // with the mouse. // case IOCTL_MOUSE_QUERY_ATTRIBUTES: default: break; } if (!NT_SUCCESS(status)) { WdfRequestComplete(Request, status); return ; } MouFilter_DispatchPassThrough(Request,WdfDeviceGetIoTarget(hDevice)); }