diff options
| author | karlf <[email protected]> | 2016-08-11 13:28:13 -0700 |
|---|---|---|
| committer | karlf <[email protected]> | 2016-08-11 13:28:13 -0700 |
| commit | 96eb96dfb613e4c745db6bd1f53a92fe7e2290fc (patch) | |
| tree | ad5f3ede5cbcd6b598677ce41bcf8318471bdd92 /usb | |
| parent | 687b274aa38fd05c8c26e3068932121876d7f745 (diff) | |
Updated for "Windows 10 Anniversary Update" (Version 1607)
Diffstat (limited to 'usb')
197 files changed, 25724 insertions, 584 deletions
diff --git a/usb/UcmCxUcsi/Acpi.cpp b/usb/UcmCxUcsi/Acpi.cpp new file mode 100644 index 00000000..d905a3c7 --- /dev/null +++ b/usb/UcmCxUcsi/Acpi.cpp @@ -0,0 +1,775 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + Acpi.cpp + +Abstract: + + ACPI method evaluation helper routines. + +Environment: + + Kernel-mode only. + +--*/ + +#include "Pch.h" +#include "Acpi.tmh" + + +#define ACPI_METHOD_OUTPUT_BUFFER_SIZE 1024 + +// {6F8398C2-7CA4-11E4-AD36-631042B5008F} +DEFINE_GUID(GUID_UCSI_DSM, +0x6f8398c2, 0x7ca4, 0x11e4, 0xad, 0x36, 0x63, 0x10, 0x42, 0xb5, 0x00, 0x8f); + +#define UCSI_DSM_REVISION 0 +#define UCSI_DSM_FUNCTION_SUPPORTED_FUNCTIONS_INDEX 0x0 +#define UCSI_DSM_FUNCTION_SEND_DATA_INDEX 0x1 +#define UCSI_DSM_FUNCTION_RECEIVE_DATA_INDEX 0x2 +#define UCSI_DSM_FUNCTION_USB_DEVICE_CONTROLLER_STATUS_INDEX 0x3 + +#define UCSI_DSM_EXECUTION_TIMEOUT_IN_MS 3000 + +EXTERN_C_START + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Acpi_EvaluateUcsiDsm ( + _In_ PACPI_CONTEXT AcpiCtx, + _In_ ULONG FunctionIndex, + _Outptr_opt_ PACPI_EVAL_OUTPUT_BUFFER* Output + ); + +EXTERN_C_END + +#pragma alloc_text(PAGE, Acpi_PrepareHardware) +#pragma alloc_text(PAGE, Acpi_ReleaseHardware) +#pragma alloc_text(PAGE, Acpi_UcsiDsmSendData) +#pragma alloc_text(PAGE, Acpi_UcsiDsmReceiveData) +#pragma alloc_text(PAGE, Acpi_EnumChildren) +#pragma alloc_text(PAGE, Acpi_EvaluatePld) +#pragma alloc_text(PAGE, Acpi_EvaluateUcsiDsm) +#pragma alloc_text(PAGE, Acpi_UcsiDsmIsUsbDeviceControllerEnabled) + + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Acpi_PrepareHardware ( + _In_ PACPI_CONTEXT AcpiCtx + ) +{ + NTSTATUS status; + WDFDEVICE device; + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_ACPI); + + device = Context_GetWdfDevice(AcpiCtx); + + if (AcpiCtx->Initialized != FALSE) + { + status = STATUS_INVALID_DEVICE_STATE; + TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] ACPI already initialized", device); + goto Exit; + } + + status = WdfFdoQueryForInterface(device, + &GUID_ACPI_INTERFACE_STANDARD2, + (PINTERFACE) &AcpiCtx->AcpiInterface, + sizeof(ACPI_INTERFACE_STANDARD2), + 1, + NULL); + + if (!NT_SUCCESS(status)) + { + TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] WdfFdoQueryForInterface for ACPI_INTERFACE_STANDARD2 failed - %!STATUS!", device, status); + goto Exit; + } + + AcpiCtx->Initialized = TRUE; + + TRACE_INFO(TRACE_FLAG_ACPI, "[Device: 0x%p] ACPI prepare hardware completed", device); + +Exit: + + TRACE_FUNC_EXIT(TRACE_FLAG_ACPI); + + return status; +} + + +_IRQL_requires_max_(PASSIVE_LEVEL) +VOID +Acpi_ReleaseHardware ( + _In_ PACPI_CONTEXT AcpiCtx + ) +{ + WDFDEVICE device; + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_ACPI); + + if (AcpiCtx->Initialized == FALSE) + { + goto Exit; + } + + device = Context_GetWdfDevice(AcpiCtx); + + AcpiCtx->AcpiInterface.InterfaceDereference(AcpiCtx->AcpiInterface.Context); + RtlZeroMemory(&AcpiCtx->AcpiInterface, sizeof(AcpiCtx->AcpiInterface)); + + AcpiCtx->Initialized = FALSE; + + TRACE_INFO(TRACE_FLAG_ACPI, "[Device: 0x%p] ACPI release hardware completed", device); + +Exit: + + TRACE_FUNC_EXIT(TRACE_FLAG_ACPI); +} + + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Acpi_UcsiDsmSendData ( + _In_ PACPI_CONTEXT AcpiCtx + ) +{ + NTSTATUS status; + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_ACPI); + + status = Acpi_EvaluateUcsiDsm(AcpiCtx, + UCSI_DSM_FUNCTION_SEND_DATA_INDEX, + nullptr); + if (!NT_SUCCESS(status)) + { + goto Exit; + } + +Exit: + + TRACE_FUNC_EXIT(TRACE_FLAG_ACPI); + + return status; +} + + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Acpi_UcsiDsmReceiveData ( + _In_ PACPI_CONTEXT AcpiCtx + ) +{ + NTSTATUS status; + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_ACPI); + + status = Acpi_EvaluateUcsiDsm(AcpiCtx, + UCSI_DSM_FUNCTION_RECEIVE_DATA_INDEX, + nullptr); + if (!NT_SUCCESS(status)) + { + goto Exit; + } + +Exit: + + TRACE_FUNC_EXIT(TRACE_FLAG_ACPI); + + return status; +} + + +_IRQL_requires_max_(PASSIVE_LEVEL) +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; +} + + +_IRQL_requires_max_(PASSIVE_LEVEL) +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; +} + + +_IRQL_requires_max_(PASSIVE_LEVEL) +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; +} + + +_IRQL_requires_max_(DISPATCH_LEVEL) +NTSTATUS +Acpi_RegisterNotificationCallback ( + _In_ PACPI_CONTEXT AcpiCtx, + _In_ PFN_ACPI_NOTIFY_CALLBACK Callback, + _In_ PVOID Context + ) +{ + NTSTATUS status; + WDFDEVICE device; + + TRACE_FUNC_ENTRY(TRACE_FLAG_ACPI); + + device = Context_GetWdfDevice(AcpiCtx); + + if (AcpiCtx->RegisteredForNotifications != FALSE) + { + status = STATUS_INVALID_DEVICE_STATE; + TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] Already registered for ACPI notifications", device); + goto Exit; + } + + status = AcpiCtx->AcpiInterface.RegisterForDeviceNotifications(AcpiCtx->AcpiInterface.Context, + Callback, + Context); + if (!NT_SUCCESS(status)) + { + TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] Registering for ACPI notifications failed - %!STATUS!", device, status); + goto Exit; + } + + AcpiCtx->RegisteredForNotifications = TRUE; + + TRACE_INFO(TRACE_FLAG_ACPI, "[Device: 0x%p] Registered for ACPI notifications", device); + +Exit: + + TRACE_FUNC_EXIT(TRACE_FLAG_ACPI); + + return status; +} + + +_IRQL_requires_max_(DISPATCH_LEVEL) +VOID +Acpi_UnregisterNotificationCallback ( + _In_ PACPI_CONTEXT AcpiCtx + ) +{ + WDFDEVICE device; + + TRACE_FUNC_ENTRY(TRACE_FLAG_ACPI); + + if (AcpiCtx->RegisteredForNotifications == FALSE) + { + goto Exit; + } + + device = Context_GetWdfDevice(AcpiCtx); + + AcpiCtx->AcpiInterface.UnregisterForDeviceNotifications(AcpiCtx->AcpiInterface.Context); + AcpiCtx->RegisteredForNotifications = FALSE; + + TRACE_INFO(TRACE_FLAG_ACPI, "[Device: 0x%p] Unregistered ACPI notifications", device); + +Exit: + + TRACE_FUNC_EXIT(TRACE_FLAG_ACPI); +} + + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Acpi_UcsiDsmIsUsbDeviceControllerEnabled ( + _In_ PACPI_CONTEXT AcpiCtx, + _Out_ PBOOLEAN IsUsbDeviceControllerEnabled + ) +{ + NTSTATUS status; + WDFDEVICE device; + PACPI_EVAL_OUTPUT_BUFFER output; + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_ACPI); + + output = nullptr; + device = Context_GetWdfDevice(AcpiCtx); + + status = Acpi_EvaluateUcsiDsm(AcpiCtx, UCSI_DSM_FUNCTION_SUPPORTED_FUNCTIONS_INDEX, &output); + if (!NT_SUCCESS(status)) + { + TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] _DSM query for supported functions failed - %!STATUS!", device, status); + goto Exit; + } + + if (output->Count != 1) + { + status = STATUS_ACPI_INVALID_DATA; + TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] _DSM query for supported functions returned unexpected number of arguments %lu", device, output->Count); + goto Exit; + } + + NT_ASSERT_ASSUME(output->Length == sizeof(ACPI_EVAL_OUTPUT_BUFFER)); + + if (output->Argument[0].Type != ACPI_METHOD_ARGUMENT_BUFFER) + { + status = STATUS_ACPI_INVALID_DATA; + TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] _DSM query for supported functions returned an unexpected argument of type %d", device, output->Argument[0].Type); + goto Exit; + } + + if (!TEST_BIT(output->Argument[0].Data[0], UCSI_DSM_FUNCTION_USB_DEVICE_CONTROLLER_STATUS_INDEX)) + { + // + // The function to query whether the device controller is enabled is not supported. Assume + // that the controller is enabled. + // + + status = STATUS_SUCCESS; + *IsUsbDeviceControllerEnabled = TRUE; + goto Exit; + } + + ExFreePoolWithTag(output, TAG_UCSI); + output = nullptr; + + status = Acpi_EvaluateUcsiDsm(AcpiCtx, + UCSI_DSM_FUNCTION_USB_DEVICE_CONTROLLER_STATUS_INDEX, + &output); + if (!NT_SUCCESS(status)) + { + TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] _DSM query for USB device controller status failed - %!STATUS!", device, status); + goto Exit; + } + + if (output->Count != 1) + { + status = STATUS_ACPI_INVALID_DATA; + TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] _DSM query for USB device controller status returned unexpected number of arguments %lu", device, output->Count); + goto Exit; + } + + NT_ASSERT_ASSUME(output->Length == sizeof(ACPI_EVAL_OUTPUT_BUFFER)); + + *IsUsbDeviceControllerEnabled = (output->Argument[0].Argument) ? TRUE : FALSE; + status = STATUS_SUCCESS; + +Exit: + + if (output) + { + ExFreePoolWithTag(output, TAG_UCSI); + } + + TRACE_FUNC_EXIT(TRACE_FLAG_ACPI); + + return status; +} diff --git a/usb/UcmCxUcsi/Acpi.h b/usb/UcmCxUcsi/Acpi.h new file mode 100644 index 00000000..4001b0b5 --- /dev/null +++ b/usb/UcmCxUcsi/Acpi.h @@ -0,0 +1,103 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + Acpi.h + +Abstract: + + ACPI method evaluation helper routines. + +Environment: + + Kernel-mode only. + +--*/ + +#pragma once + +EXTERN_C_START + +typedef struct _ACPI_CONTEXT +{ + BOOLEAN Initialized; + ACPI_INTERFACE_STANDARD2 AcpiInterface; + BOOLEAN RegisteredForNotifications; +} ACPI_CONTEXT, *PACPI_CONTEXT; + + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Acpi_PrepareHardware ( + _In_ PACPI_CONTEXT AcpiCtx + ); + +_IRQL_requires_max_(PASSIVE_LEVEL) +VOID +Acpi_ReleaseHardware ( + _In_ PACPI_CONTEXT AcpiCtx + ); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Acpi_UcsiDsmSendData ( + _In_ PACPI_CONTEXT AcpiCtx + ); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Acpi_UcsiDsmReceiveData ( + _In_ PACPI_CONTEXT AcpiCtx + ); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Acpi_UcsiDsmIsUsbDeviceControllerEnabled ( + _In_ PACPI_CONTEXT AcpiCtx, + _Out_ PBOOLEAN IsUsbDeviceControllerEnabled + ); + +typedef +_IRQL_requires_max_(DISPATCH_LEVEL) +VOID +EVT_ACPI_NOTIFY_CALLBACK ( + _In_ PVOID NotificationContext, + _In_ ULONG NotifyCode + ); + +typedef EVT_ACPI_NOTIFY_CALLBACK *PFN_ACPI_NOTIFY_CALLBACK; + +_IRQL_requires_max_(DISPATCH_LEVEL) +NTSTATUS +Acpi_RegisterNotificationCallback ( + _In_ PACPI_CONTEXT AcpiCtx, + _In_ PFN_ACPI_NOTIFY_CALLBACK Callback, + _In_ PVOID Context + ); + +_IRQL_requires_max_(DISPATCH_LEVEL) +VOID +Acpi_UnregisterNotificationCallback ( + _In_ PACPI_CONTEXT AcpiCtx + ); + +EVT_ACPI_NOTIFY_CALLBACK OpmAcpiNotifyCallback; + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Acpi_EnumChildren ( + _In_ PACPI_CONTEXT AcpiCtx, + _Out_ WDFMEMORY* EnumChildrenOutput + ); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Acpi_EvaluatePld ( + _In_ PACPI_CONTEXT AcpiCtx, + _In_ LPCSTR DeviceName, + _Out_ PACPI_PLD_BUFFER PldBuffer + ); + +EXTERN_C_END diff --git a/usb/UcmCxUcsi/Driver.cpp b/usb/UcmCxUcsi/Driver.cpp new file mode 100644 index 00000000..02b2ccdb --- /dev/null +++ b/usb/UcmCxUcsi/Driver.cpp @@ -0,0 +1,117 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + Driver.cpp + +Abstract: + + Driver object callbacks, functions, and types. + +Environment: + + Kernel-mode only. + +--*/ + +#include "Pch.h" +#include "Driver.tmh" + + +EXTERN_C_START + +DRIVER_INITIALIZE DriverEntry; +EVT_WDF_DRIVER_DEVICE_ADD Driver_EvtDriverDeviceAdd; +EVT_WDF_DRIVER_UNLOAD Driver_EvtDriverUnload; + +EXTERN_C_END + +#pragma alloc_text(INIT, DriverEntry) +#pragma alloc_text(PAGE, Driver_EvtDriverDeviceAdd) +#pragma alloc_text(PAGE, Driver_EvtDriverUnload) + + +NTSTATUS +DriverEntry ( + _In_ PDRIVER_OBJECT DriverObject, + _In_ PUNICODE_STRING RegistryPath + ) +{ + WDF_DRIVER_CONFIG config; + NTSTATUS status; + WDFDRIVER wdfDriver; + + WPP_INIT_TRACING(DriverObject, RegistryPath); + TRACE_FUNC_ENTRY(TRACE_FLAG_DRIVER); + + WDF_DRIVER_CONFIG_INIT(&config, Driver_EvtDriverDeviceAdd); + config.EvtDriverUnload = Driver_EvtDriverUnload; + config.DriverPoolTag = TAG_UCSI; + + status = WdfDriverCreate(DriverObject, + RegistryPath, + WDF_NO_OBJECT_ATTRIBUTES, + &config, + &wdfDriver + ); + + if (!NT_SUCCESS(status)) + { + TRACE_ERROR(TRACE_FLAG_DRIVER, "[WdfDriver: 0x%p] WdfDriverCreate failed - %!STATUS!", DriverObject, status); + goto Exit; + } + + TRACE_INFO(TRACE_FLAG_DRIVER, "[WdfDriver: 0x%p] Driver entry", wdfDriver); + +Exit: + + TRACE_FUNC_EXIT(TRACE_FLAG_DRIVER); + + if (!NT_SUCCESS(status)) + { + WPP_CLEANUP(DriverObject); + } + + return status; +} + + +NTSTATUS +Driver_EvtDriverDeviceAdd ( + _In_ WDFDRIVER Driver, + _Inout_ PWDFDEVICE_INIT DeviceInit + ) +{ + NTSTATUS status; + + UNREFERENCED_PARAMETER(Driver); + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_DRIVER); + + status = Fdo_Create(DeviceInit); + + TRACE_FUNC_EXIT(TRACE_FLAG_DRIVER); + + return status; +} + + +VOID +Driver_EvtDriverUnload ( + _In_ WDFDRIVER Driver + ) +{ + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_DRIVER); + + TRACE_INFO(TRACE_FLAG_DRIVER, "[WdfDriver: 0x%p] Driver unloading", Driver); + + TRACE_FUNC_EXIT(TRACE_FLAG_DRIVER); + + WPP_CLEANUP(WdfDriverWdmGetDriverObject(Driver)); +} diff --git a/usb/UcmCxUcsi/Driver.h b/usb/UcmCxUcsi/Driver.h new file mode 100644 index 00000000..ef0381e8 --- /dev/null +++ b/usb/UcmCxUcsi/Driver.h @@ -0,0 +1,23 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + Driver.cpp + +Abstract: + + Driver object callbacks, functions, and types. + +Environment: + + Kernel-mode only. + +--*/ + +#pragma once + +#define TAG_UCSI 'iscU' + +#define TEST_BIT(value, bitNumber) ((value) & (1<<(bitNumber))) ? true : false diff --git a/usb/UcmCxUcsi/Fdo.cpp b/usb/UcmCxUcsi/Fdo.cpp new file mode 100644 index 00000000..88aa9129 --- /dev/null +++ b/usb/UcmCxUcsi/Fdo.cpp @@ -0,0 +1,385 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + Fdo.cpp + +Abstract: + + FDO callbacks, functions, and types. + +Environment: + + Kernel-mode only. + +--*/ + +#include "Pch.h" +#include "Fdo.tmh" + +EXTERN_C_START + +EVT_WDF_DEVICE_PREPARE_HARDWARE Fdo_EvtDevicePrepareHardware; +EVT_WDF_DEVICE_RELEASE_HARDWARE Fdo_EvtDeviceReleaseHardware; +EVT_WDF_DEVICE_D0_ENTRY Fdo_EvtDeviceD0Entry; +EVT_WDF_DEVICE_D0_EXIT Fdo_EvtDeviceD0Exit; +EVT_WDF_DEVICE_SELF_MANAGED_IO_INIT Fdo_EvtDeviceSelfManagedIoInit; +EVT_WDF_DEVICE_SELF_MANAGED_IO_RESTART Fdo_EvtDeviceSelfManagedIoRestart; + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Fdo_Initialize ( + _In_ PFDO_CONTEXT FdoCtx + ); + +EXTERN_C_END + +#pragma alloc_text(PAGE, Fdo_Create) +#pragma alloc_text(PAGE, Fdo_Initialize) +#pragma alloc_text(PAGE, Fdo_EvtDevicePrepareHardware) +#pragma alloc_text(PAGE, Fdo_EvtDeviceReleaseHardware) +#pragma alloc_text(PAGE, Fdo_EvtDeviceD0Entry) +#pragma alloc_text(PAGE, Fdo_EvtDeviceD0Exit) +#pragma alloc_text(PAGE, Fdo_EvtDeviceSelfManagedIoInit) +#pragma alloc_text(PAGE, Fdo_EvtDeviceSelfManagedIoRestart) + + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Fdo_Create ( + _Inout_ PWDFDEVICE_INIT DeviceInit + ) +{ + WDF_OBJECT_ATTRIBUTES attributes; + WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks; + PFDO_CONTEXT fdoCtx; + WDFDEVICE wdfDevice; + NTSTATUS status; + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_FDO); + + WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks); + pnpPowerCallbacks.EvtDevicePrepareHardware = Fdo_EvtDevicePrepareHardware; + pnpPowerCallbacks.EvtDeviceReleaseHardware = Fdo_EvtDeviceReleaseHardware; + pnpPowerCallbacks.EvtDeviceD0Entry = Fdo_EvtDeviceD0Entry; + pnpPowerCallbacks.EvtDeviceD0Exit = Fdo_EvtDeviceD0Exit; + pnpPowerCallbacks.EvtDeviceSelfManagedIoInit = Fdo_EvtDeviceSelfManagedIoInit; + pnpPowerCallbacks.EvtDeviceSelfManagedIoRestart = Fdo_EvtDeviceSelfManagedIoRestart; + WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks); + + WdfDeviceInitSetPowerPageable(DeviceInit); + + WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, FDO_CONTEXT); + status = WdfDeviceCreate(&DeviceInit, &attributes, &wdfDevice); + if (!NT_SUCCESS(status)) + { + TRACE_ERROR(TRACE_FLAG_FDO, "[DeviceInit: 0x%p] WdfDeviceCreate failed - %!STATUS!", DeviceInit, status); + goto Exit; + } + + fdoCtx = Fdo_GetContext(wdfDevice); + fdoCtx->WdfDevice = wdfDevice; + + status = Fdo_Initialize(fdoCtx); + if (!NT_SUCCESS(status)) + { + goto Exit; + } + + status = Ppm_Initialize(&fdoCtx->PpmCtx); + if (!NT_SUCCESS(status)) + { + goto Exit; + } + + TRACE_INFO(TRACE_FLAG_FDO, "[Device: 0x%p] Device created", wdfDevice); + +Exit: + + TRACE_FUNC_EXIT(TRACE_FLAG_FDO); + + return status; +} + + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Fdo_Initialize ( + _In_ PFDO_CONTEXT FdoCtx + ) +{ + WDFDEVICE device; + WDF_DEVICE_STATE deviceState; + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_FDO); + + device = FdoCtx->WdfDevice; + + // + // ACPI-enumerated devices are not disableable by default. Override that, + // since there is no need for that restriction. + // + + WDF_DEVICE_STATE_INIT(&deviceState); + deviceState.NotDisableable = WdfFalse; + WdfDeviceSetDeviceState(device, &deviceState); + + TRACE_INFO(TRACE_FLAG_FDO, "[Device: 0x%p] FDO initialized", device); + + TRACE_FUNC_EXIT(TRACE_FLAG_FDO); + + return STATUS_SUCCESS; +} + + +NTSTATUS +Fdo_EvtDevicePrepareHardware ( + _In_ WDFDEVICE Device, + _In_ WDFCMRESLIST ResourcesRaw, + _In_ WDFCMRESLIST ResourcesTranslated + ) +{ + NTSTATUS status; + PFDO_CONTEXT fdoCtx; + ULONG index; + ULONG resourceCount; + BOOLEAN allResourcesFound; + PCM_PARTIAL_RESOURCE_DESCRIPTOR res; + PCM_PARTIAL_RESOURCE_DESCRIPTOR rawRes; + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_FDO); + + fdoCtx = Fdo_GetContext(Device); + resourceCount = WdfCmResourceListGetCount(ResourcesTranslated); + allResourcesFound = FALSE; + + for (index = 0; !allResourcesFound && (index < resourceCount); ++index) + { + res = WdfCmResourceListGetDescriptor(ResourcesTranslated, index); + if (res->Type != CmResourceTypeMemory) + { + continue; + } + + rawRes = WdfCmResourceListGetDescriptor(ResourcesRaw, index); + + // + // Verify if address is below 4GB and not straddling the 4GB boundary. + // + + if ((rawRes->u.Memory.Start.HighPart != 0) || + ((rawRes->u.Memory.Start.LowPart + rawRes->u.Memory.Length) < + rawRes->u.Memory.Start.LowPart)) + { + status = STATUS_INSUFFICIENT_RESOURCES; + TRACE_ERROR(TRACE_FLAG_FDO, "[Device: 0x%p] Memory resource address (%I64x) not below 4GB", Device, rawRes->u.Memory.Start.QuadPart); + goto Exit; + } + + status = Ppm_PrepareHardware(&fdoCtx->PpmCtx, res->u.Memory.Start, res->u.Memory.Length); + if (!NT_SUCCESS(status)) + { + goto Exit; + } + + allResourcesFound = TRUE; + } + + if (allResourcesFound == FALSE) + { + status = STATUS_INSUFFICIENT_RESOURCES; + TRACE_ERROR(TRACE_FLAG_FDO, "[Device: 0x%p] Could not find required resources", Device); + goto Exit; + } + + status = Acpi_PrepareHardware(&fdoCtx->AcpiCtx); + if (!NT_SUCCESS(status)) + { + goto Exit; + } + + TRACE_INFO(TRACE_FLAG_FDO, "[Device: 0x%p] Prepare hardware completed", Device); + +Exit: + + TRACE_FUNC_EXIT(TRACE_FLAG_FDO); + + return status; +} + + +NTSTATUS +Fdo_EvtDeviceReleaseHardware ( + _In_ WDFDEVICE Device, + _In_ WDFCMRESLIST ResourcesTranslated + ) +{ + PFDO_CONTEXT fdoCtx; + + UNREFERENCED_PARAMETER(ResourcesTranslated); + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_FDO); + + fdoCtx = Fdo_GetContext(Device); + + Acpi_ReleaseHardware(&fdoCtx->AcpiCtx); + + Ppm_ReleaseHardware(&fdoCtx->PpmCtx); + + TRACE_INFO(TRACE_FLAG_FDO, "[Device: 0x%p] Release hardware completed", Device); + + TRACE_FUNC_EXIT(TRACE_FLAG_FDO); + + return STATUS_SUCCESS; +} + + +NTSTATUS +Fdo_EvtDeviceD0Entry ( + _In_ WDFDEVICE Device, + _In_ WDF_POWER_DEVICE_STATE PreviousState + ) +{ + NTSTATUS status; + PFDO_CONTEXT fdoCtx; + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_FDO); + + fdoCtx = Fdo_GetContext(Device); + + TRACE_INFO(TRACE_FLAG_FDO, "[Device: 0x%p] Entering D0 from %!WDF_POWER_DEVICE_STATE!", Device, PreviousState); + + status = Ppm_PowerOn(&fdoCtx->PpmCtx); + if (!NT_SUCCESS(status)) + { + goto Exit; + } + +Exit: + + TRACE_FUNC_EXIT(TRACE_FLAG_FDO); + + return status; +} + + +NTSTATUS +Fdo_EvtDeviceD0Exit ( + _In_ WDFDEVICE Device, + _In_ WDF_POWER_DEVICE_STATE TargetState + ) +{ + PFDO_CONTEXT fdoCtx; + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_FDO); + + fdoCtx = Fdo_GetContext(Device); + + TRACE_INFO(TRACE_FLAG_FDO, "[Device: 0x%p] Exiting D0 to %!WDF_POWER_DEVICE_STATE!", Device, TargetState); + + Ppm_PowerOff(&fdoCtx->PpmCtx); + + TRACE_FUNC_EXIT(TRACE_FLAG_FDO); + + return STATUS_SUCCESS; +} + + +NTSTATUS +Fdo_EvtDeviceSelfManagedIoInit ( + _In_ WDFDEVICE Device + ) +{ + NTSTATUS status; + PPPM_CONTEXT ppmCtx; + UCM_MANAGER_CONFIG ucmConfig; + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_FDO); + + ppmCtx = &Fdo_GetContext(Device)->PpmCtx; + + // + // Since the PPM uses a power-managed queue to handle command requests, self-managed I/O init + // is when we can start processing commands. + // + + UCM_MANAGER_CONFIG_INIT(&ucmConfig); + + // + // Initialize our device with UCM. + // + + status = UcmInitializeDevice(Device, &ucmConfig); + if (!NT_SUCCESS(status)) + { + TRACE_ERROR(TRACE_FLAG_FDO, "[Device: 0x%p] UcmInitializeDevice failed - %!STATUS!", Device, status); + goto Exit; + } + + + status = Ucm_CreateConnectors(ppmCtx); + if (!NT_SUCCESS(status)) + { + goto Exit; + } + + // + // Connector objects are ready. Now we can enable all notifications. + // + + status = Ppm_EnableNotifications(ppmCtx); + if (!NT_SUCCESS(status)) + { + goto Exit; + } + +Exit: + + TRACE_FUNC_EXIT(TRACE_FLAG_FDO); + + return status; +} + + +NTSTATUS +Fdo_EvtDeviceSelfManagedIoRestart ( + _In_ WDFDEVICE Device + ) +{ + NTSTATUS status; + PPPM_CONTEXT ppmCtx; + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_FDO); + + ppmCtx = &Fdo_GetContext(Device)->PpmCtx; + + status = Ppm_EnableNotifications(ppmCtx); + if (!NT_SUCCESS(status)) + { + goto Exit; + } + +Exit: + + TRACE_FUNC_EXIT(TRACE_FLAG_FDO); + + return status; +} diff --git a/usb/UcmCxUcsi/Fdo.h b/usb/UcmCxUcsi/Fdo.h new file mode 100644 index 00000000..c6f2c921 --- /dev/null +++ b/usb/UcmCxUcsi/Fdo.h @@ -0,0 +1,68 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + Fdo.h + +Abstract: + + FDO callbacks, functions, and types. + +Environment: + + Kernel-mode only. + +--*/ + +#pragma once + +EXTERN_C_START + +typedef struct _FDO_CONTEXT +{ + WDFDEVICE WdfDevice; + + ACPI_CONTEXT AcpiCtx; + PPM_CONTEXT PpmCtx; + +} FDO_CONTEXT, *PFDO_CONTEXT; + +WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(FDO_CONTEXT, Fdo_GetContext) + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Fdo_Create ( + _Inout_ PWDFDEVICE_INIT DeviceInit + ); + +EXTERN_C_END + +PFDO_CONTEXT +FORCEINLINE +Context_GetFdoContext ( + _In_ PACPI_CONTEXT AcpiCtx + ) +{ + return CONTAINING_RECORD(AcpiCtx, FDO_CONTEXT, AcpiCtx); +} + +PFDO_CONTEXT +FORCEINLINE +Context_GetFdoContext ( + _In_ PPPM_CONTEXT PpmCtx + ) +{ + return CONTAINING_RECORD(PpmCtx, FDO_CONTEXT, PpmCtx); +} + +template<typename ContextType> +WDFDEVICE +FORCEINLINE +Context_GetWdfDevice ( + _In_ ContextType Ctx + ) +{ + return Context_GetFdoContext(Ctx)->WdfDevice; +} diff --git a/usb/UcmCxUcsi/Pch.h b/usb/UcmCxUcsi/Pch.h new file mode 100644 index 00000000..868f53ae --- /dev/null +++ b/usb/UcmCxUcsi/Pch.h @@ -0,0 +1,41 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + + Module Name: + +Pch.h + +Abstract: + + Precompiled header. + +Environment: + + Kernel-mode only. + +--*/ + +#pragma once + +#include <initguid.h> +#include <ntddk.h> +#include <wdmguid.h> +#include <wdf.h> +#include <intsafe.h> +#include <ntstrsafe.h> +#include <acpiioct.h> +#include <acpitabl.h> + +#include <UcmCx.h> +#include <UcsiInterface.h> +#include <Ucsi.h> + +#include "Trace.h" +#include "Driver.h" +#include "Acpi.h" +#include "UcmCallbacks.h" +#include "Ppm.h" +#include "Fdo.h" +#include "UcsiUcmConvert.h" +#include "UcmNotifications.h"
\ No newline at end of file diff --git a/usb/UcmCxUcsi/Ppm.cpp b/usb/UcmCxUcsi/Ppm.cpp new file mode 100644 index 00000000..cc866a21 --- /dev/null +++ b/usb/UcmCxUcsi/Ppm.cpp @@ -0,0 +1,1890 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + Ppm.cpp + +Abstract: + + Type-C Platform Policy Manager. Main interface to talk to the hardware. + +Environment: + + Kernel-mode only. + +--*/ + +#include "Pch.h" +#include "Ppm.tmh" + +#pragma alloc_text(PAGE, Ppm_Initialize) +#pragma alloc_text(PAGE, Ppm_PrepareHardware) +#pragma alloc_text(PAGE, Ppm_ReleaseHardware) +#pragma alloc_text(PAGE, Ppm_SendCommandSynchronously) +#pragma alloc_text(PAGE, Ppm_PowerOn) +#pragma alloc_text(PAGE, Ppm_PowerOff) +#pragma alloc_text(PAGE, Ppm_WaitForResetComplete) +#pragma alloc_text(PAGE, Ppm_EvtIoInternalDeviceControl) +#pragma alloc_text(PAGE, Ppm_ExecuteCommand) +#pragma alloc_text(PAGE, Ppm_CommandCompletionWorkItem) +#pragma alloc_text(PAGE, Ppm_QueryConnectors) +#pragma alloc_text(PAGE, Ppm_CommandCompletionHandler) +#pragma alloc_text(PAGE, Ppm_GetCapability) +#pragma alloc_text(PAGE, Ppm_GetConnectorCapability) +#pragma alloc_text(PAGE, Ppm_AddConnector) +#pragma alloc_text(PAGE, Ppm_EvtGetConnectorStatusCompleted) +#pragma alloc_text(PAGE, Ppm_EnableNotifications) +#pragma alloc_text(PAGE, Ppm_ReportNegotiatedPowerLevelChanged) +#pragma alloc_text(PAGE, Ppm_ConnectorSetUor) +#pragma alloc_text(PAGE, Ppm_ConnectorSetPdr) +#pragma alloc_text(PAGE, Ppm_PerformRoleCorrection) + + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Ppm_Initialize ( + _In_ PPPM_CONTEXT PpmCtx +) +{ + NTSTATUS status; + WDFDEVICE device; + WDF_OBJECT_ATTRIBUTES attributes; + WDF_IO_QUEUE_CONFIG queueConfig; + WDF_IO_TARGET_OPEN_PARAMS openParams; + WDF_WORKITEM_CONFIG workItemConfig; + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_PPM); + + device = Context_GetWdfDevice(PpmCtx); + + // + // UCSI can process only one command at a time, hence this queue needs to be + // sequential. + // + + WDF_IO_QUEUE_CONFIG_INIT(&queueConfig, WdfIoQueueDispatchSequential); + + queueConfig.EvtIoInternalDeviceControl = Ppm_EvtIoInternalDeviceControl; + + WDF_OBJECT_ATTRIBUTES_INIT(&attributes); + + // + // It is more convenient to do command processing at PASSIVE_LEVEL. + // + + attributes.ExecutionLevel = WdfExecutionLevelPassive; + + status = WdfIoQueueCreate(device, &queueConfig, &attributes, &PpmCtx->CommandQueue); + if (!NT_SUCCESS(status)) + { + TRACE_ERROR(TRACE_FLAG_PPM, "[Device: 0x%p] WdfIoQueueCreate failed - %!STATUS!", device, status); + goto Exit; + } + + // + // Steal all IRP_MJ_INTERNAL_DEVICE_CONTROL because we expect the only code we receive to + // be IOCTL_INTERNAL_UCSI_SEND_COMMAND. If we ever need to support more codes and some other + // component needs to handle them, we need to configure an IRP preprocess routine, and redirect + // the requests accordingly. + // + + status = WdfDeviceConfigureRequestDispatching(device, + PpmCtx->CommandQueue, + WdfRequestTypeDeviceControlInternal); + if (!NT_SUCCESS(status)) + { + TRACE_ERROR(TRACE_FLAG_PPM, "[Device: 0x%p] WdfDeviceConfigureRequestDispatching failed - %!STATUS!", device, status); + goto Exit; + } + + WDF_OBJECT_ATTRIBUTES_INIT(&attributes); + attributes.ParentObject = device; + + status = WdfIoTargetCreate(device, &attributes, &PpmCtx->SelfIoTarget); + if (!NT_SUCCESS(status)) + { + TRACE_ERROR(TRACE_FLAG_PPM, "[Device: 0x%p] WdfIoTargetCreate failed - %!STATUS!", device, status); + goto Exit; + } + + WDF_IO_TARGET_OPEN_PARAMS_INIT_EXISTING_DEVICE(&openParams, WdfDeviceWdmGetDeviceObject(device)); + + status = WdfIoTargetOpen(PpmCtx->SelfIoTarget, &openParams); + if (!NT_SUCCESS(status)) + { + TRACE_ERROR(TRACE_FLAG_PPM, "[Device: 0x%p] WdfIoTargetOpen failed - %!STATUS!", device, status); + goto Exit; + } + + WDF_WORKITEM_CONFIG_INIT(&workItemConfig, Ppm_CommandCompletionWorkItem); + + WDF_OBJECT_ATTRIBUTES_INIT(&attributes); + attributes.ParentObject = device; + + status = WdfWorkItemCreate(&workItemConfig, &attributes, &PpmCtx->CommandCompletionWorkItem); + if (!NT_SUCCESS(status)) + { + TRACE_ERROR(TRACE_FLAG_PPM, "[Device: 0x%p] WdfWorkItemCreate failed - %!STATUS!", device, status); + goto Exit; + } + + TRACE_INFO(TRACE_FLAG_PPM, "[Device: 0x%p] PPM initialized", device); + +Exit: + + TRACE_FUNC_EXIT(TRACE_FLAG_PPM); + + return status; +} + + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Ppm_PrepareHardware ( + _In_ PPPM_CONTEXT PpmCtx, + _In_ PHYSICAL_ADDRESS MemoryAddress, + _In_ ULONG MemoryLength + ) +{ + NTSTATUS status; + WDFDEVICE device; + PVOID mappedMemory; + PACPI_CONTEXT acpiCtx; + UCSI_VERSION version; + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_PPM); + + device = Context_GetWdfDevice(PpmCtx); + + mappedMemory = MmMapIoSpaceEx(MemoryAddress, + MemoryLength, + PAGE_NOCACHE | PAGE_READWRITE); + +#pragma prefast(suppress: __WARNING_REDUNDANT_POINTER_TEST, "API indicates failure by returning NULL") + if (mappedMemory == NULL) + { + status = STATUS_INSUFFICIENT_RESOURCES; + TRACE_ERROR(TRACE_FLAG_PPM, "[Device: 0x%p] MmMapIoSpaceEx failed", device); + goto Exit; + } + + PpmCtx->UcsiDataBlock = (PUCSI_DATA_BLOCK) mappedMemory; + PpmCtx->MappedMemoryLength = MemoryLength; + + version = PpmCtx->UcsiDataBlock->UcsiVersion; + TRACE_INFO(TRACE_FLAG_PPM, "[Device: 0x%p] UCSI version Major: %hx Minor: %hx SubMinor: %hx", device, version.MajorVersion, version.MinorVersion, version.SubMinorVersion); + + status = Ppm_QueryConnectors(PpmCtx); + if (!NT_SUCCESS(status)) + { + goto Exit; + } + + acpiCtx = &Context_GetFdoContext(PpmCtx)->AcpiCtx; + status = Acpi_UcsiDsmIsUsbDeviceControllerEnabled(acpiCtx, + &PpmCtx->IsUsbDeviceControllerEnabled); + if (!NT_SUCCESS(status)) + { + goto Exit; + } + + if (PpmCtx->IsUsbDeviceControllerEnabled) + { + TRACE_INFO(TRACE_FLAG_PPM, "[Device: 0x%p] USB Device Controller is enabled", device); + } + else + { + TRACE_INFO(TRACE_FLAG_PPM, "[Device: 0x%p] USB Device Controller is disabled", device); + } + + TRACE_INFO(TRACE_FLAG_PPM, "[Device: 0x%p] PPM prepare hardware completed", device); + +Exit: + + TRACE_FUNC_EXIT(TRACE_FLAG_PPM); + + return status; +} + + +_IRQL_requires_max_(PASSIVE_LEVEL) +VOID +Ppm_ReleaseHardware ( + _In_ PPPM_CONTEXT PpmCtx + ) +{ + WDFDEVICE device; + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_PPM); + + if (PpmCtx->UcsiDataBlock == nullptr) + { + goto Exit; + } + + device = Context_GetWdfDevice(PpmCtx); + + MmUnmapIoSpace(PpmCtx->UcsiDataBlock, PpmCtx->MappedMemoryLength); + PpmCtx->UcsiDataBlock = nullptr; + PpmCtx->MappedMemoryLength = 0; + + if (PpmCtx->Connectors != WDF_NO_HANDLE) + { + WdfObjectDelete(PpmCtx->Connectors); + PpmCtx->Connectors = WDF_NO_HANDLE; + } + + TRACE_INFO(TRACE_FLAG_PPM, "[Device: 0x%p] PPM release hardware completed", device); + +Exit: + + TRACE_FUNC_EXIT(TRACE_FLAG_PPM); +} + + +VOID +Ppm_CommandRequestCompletionRoutine ( + _In_ WDFREQUEST Request, + _In_ WDFIOTARGET Target, + _In_ PWDF_REQUEST_COMPLETION_PARAMS Params, + _In_ WDFCONTEXT Context + ) +{ + PPPM_CONTEXT ppmCtx; + WDFDEVICE device; + NTSTATUS status; + PPPM_REQUEST_CONTEXT reqCtx; + UCSI_CONTROL command; + + UNREFERENCED_PARAMETER(Target); + + TRACE_FUNC_ENTRY(TRACE_FLAG_PPM); + + ppmCtx = (PPPM_CONTEXT) Context; + device = Context_GetWdfDevice(ppmCtx); + reqCtx = PpmRequest_GetContext(Request); + command = reqCtx->Command; + + status = Params->IoStatus.Status; + + if (!NT_SUCCESS(status)) + { + TRACE_ERROR(TRACE_FLAG_PPM, "[Device: 0x%p] PPM asynchronous command 0x%016I64x (%!UCSI_COMMAND!) failed - %!STATUS!", device, command.AsUInt64, command.Command, status); + } + else + { + TRACE_INFO(TRACE_FLAG_PPM, "[Device: 0x%p] PPM asynchronous command 0x%016I64x (%!UCSI_COMMAND!) completed", device, command.AsUInt64, command.Command); + } + + WdfObjectDelete(Request); + + TRACE_FUNC_EXIT(TRACE_FLAG_PPM); +} + + +_IRQL_requires_max_(DISPATCH_LEVEL) +NTSTATUS +Ppm_SendCommand ( + _In_ PPPM_CONTEXT PpmCtx, + _In_ UCSI_CONTROL Command, + _In_opt_ PFN_PPM_COMMAND_COMPLETION_ROUTINE CompletionRoutine, + _In_opt_ PVOID Context + ) +{ + NTSTATUS status; + WDFDEVICE device; + WDFREQUEST request; + WDF_OBJECT_ATTRIBUTES attributes; + WDFMEMORY inputMemory; + PPPM_SEND_COMMAND_PARAMS sendCommandParams; + WDFMEMORY outputMemory; + PPPM_REQUEST_CONTEXT reqCtx; + BOOLEAN sent; + + TRACE_FUNC_ENTRY(TRACE_FLAG_PPM); + + device = Context_GetWdfDevice(PpmCtx); + request = WDF_NO_HANDLE; + + TRACE_INFO(TRACE_FLAG_PPM, "[Device: 0x%p] Sending command asynchronously - 0x%016I64x (%!UCSI_COMMAND!)", device, Command.AsUInt64, Command.Command); + + WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, PPM_REQUEST_CONTEXT); + attributes.ParentObject = device; + + status = WdfRequestCreate(&attributes, PpmCtx->SelfIoTarget, &request); + if (!NT_SUCCESS(status)) + { + TRACE_ERROR(TRACE_FLAG_PPM, "[Device: 0x%p] WdfRequestCreate failed - %!STATUS!", device, status); + goto Exit; + } + + reqCtx = PpmRequest_GetContext(request); + reqCtx->Command = Command; + + WDF_OBJECT_ATTRIBUTES_INIT(&attributes); + attributes.ParentObject = request; + + status = WdfMemoryCreate(&attributes, + NonPagedPoolNx, + 0, + sizeof(*sendCommandParams), + &inputMemory, + (PVOID*) &sendCommandParams); + if (!NT_SUCCESS(status)) + { + TRACE_ERROR(TRACE_FLAG_PPM, "[Device: 0x%p] WdfMemoryCreate for input memory failed - %!STATUS!", device, status); + goto Exit; + } + + RtlZeroMemory(sendCommandParams, sizeof(*sendCommandParams)); + sendCommandParams->Command = Command; + sendCommandParams->CompletionRoutine = CompletionRoutine; + sendCommandParams->Context = Context; + + WDF_OBJECT_ATTRIBUTES_INIT(&attributes); + attributes.ParentObject = request; + + status = WdfMemoryCreate(&attributes, NonPagedPoolNx, 0, sizeof(UCSI_MESSAGE_IN), &outputMemory, nullptr); + if (!NT_SUCCESS(status)) + { + TRACE_ERROR(TRACE_FLAG_PPM, "[Device: 0x%p] WdfMemoryCreate for output memory failed - %!STATUS!", device, status); + goto Exit; + } + + status = WdfIoTargetFormatRequestForInternalIoctl(PpmCtx->SelfIoTarget, + request, + IOCTL_INTERNAL_UCSI_SEND_COMMAND, + inputMemory, + nullptr, + outputMemory, + nullptr); + if (!NT_SUCCESS(status)) + { + TRACE_ERROR(TRACE_FLAG_PPM, "[Device: 0x%p] WdfIoTargetFormatRequestForInternalIoctl failed - %!STATUS!", device, status); + goto Exit; + } + + WdfRequestSetCompletionRoutine(request, Ppm_CommandRequestCompletionRoutine, PpmCtx); + + sent = WdfRequestSend(request, PpmCtx->SelfIoTarget, nullptr); + if (sent == FALSE) + { + status = WdfRequestGetStatus(request); + TRACE_ERROR(TRACE_FLAG_PPM, "[Device: 0x%p] PPM command 0x%016I64x dispatch failed - %!STATUS!", device, Command.AsUInt64, status); + goto Exit; + } + +Exit: + + if (!NT_SUCCESS(status) && (request != WDF_NO_HANDLE)) + { + WdfObjectDelete(request); + } + + TRACE_FUNC_EXIT(TRACE_FLAG_PPM); + + return status; +} + + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Ppm_SendCommandSynchronously ( + _In_ PPPM_CONTEXT PpmCtx, + _In_ UCSI_CONTROL Command, + _Out_opt_ PUCSI_MESSAGE_IN MessageIn, + _Out_opt_ PULONG_PTR BytesReturned + ) +{ + NTSTATUS status; + WDFDEVICE device; + PPM_SEND_COMMAND_PARAMS sendCommandParams; + WDF_MEMORY_DESCRIPTOR inputMem; + WDF_MEMORY_DESCRIPTOR outputMem; + PWDF_MEMORY_DESCRIPTOR outputMemPtr; + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_PPM); + + device = Context_GetWdfDevice(PpmCtx); + + TRACE_INFO(TRACE_FLAG_PPM, "[Device: 0x%p] Sending command synchronously - 0x%016I64x (%!UCSI_COMMAND!)", device, Command.AsUInt64, Command.Command); + + RtlZeroMemory(&sendCommandParams, sizeof(sendCommandParams)); + sendCommandParams.Command = Command; + + WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&inputMem, &sendCommandParams, sizeof(sendCommandParams)); + + if (MessageIn == nullptr) + { + outputMemPtr = nullptr; + } + else + { +#pragma prefast(suppress:__WARNING_USING_UNINIT_VAR, "This is the out buffer") + WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&outputMem, MessageIn, sizeof(*MessageIn)); + outputMemPtr = &outputMem; + } + + status = WdfIoTargetSendInternalIoctlSynchronously(PpmCtx->SelfIoTarget, + NULL, + IOCTL_INTERNAL_UCSI_SEND_COMMAND, + &inputMem, + outputMemPtr, + nullptr, + BytesReturned); + + if (!NT_SUCCESS(status)) + { + TRACE_ERROR(TRACE_FLAG_PPM, "[Device: 0x%p] PPM synchronous command 0x%016I64x (%!UCSI_COMMAND!) failed - %!STATUS!", device, Command.AsUInt64, Command.Command, status); + goto Exit; + } + + TRACE_INFO(TRACE_FLAG_PPM, "[Device: 0x%p] PPM synchronous command 0x%016I64x (%!UCSI_COMMAND!) completed", device, Command.AsUInt64, Command.Command); + +Exit: + + TRACE_FUNC_EXIT(TRACE_FLAG_PPM); + + return status; +} + + +_IRQL_requires_max_(HIGH_LEVEL) +NTSTATUS +Ppm_GetCci ( + _In_ PPPM_CONTEXT PpmCtx, + _Out_ PUCSI_CCI UcsiCci + ) +{ + PUCSI_DATA_BLOCK ucsiDataBlock; + + TRACE_FUNC_ENTRY(TRACE_FLAG_PPM); + + ucsiDataBlock = PpmCtx->UcsiDataBlock; + + *UcsiCci = ucsiDataBlock->CCI; + + TRACE_FUNC_EXIT(TRACE_FLAG_PPM); + + return STATUS_SUCCESS; +} + + +_IRQL_requires_max_(HIGH_LEVEL) +NTSTATUS +Ppm_GetMessage ( + _In_ PPPM_CONTEXT PpmCtx, + _Out_ UINT8 (&Message)[UCSI_MAX_DATA_LENGTH] + ) +{ + PUCSI_DATA_BLOCK ucsiDataBlock; + + TRACE_FUNC_ENTRY(TRACE_FLAG_PPM); + + ucsiDataBlock = PpmCtx->UcsiDataBlock; + + RtlCopyMemory(Message, ucsiDataBlock->MessageIn.AsBuffer, sizeof(Message)); + + TRACE_FUNC_EXIT(TRACE_FLAG_PPM); + + return STATUS_SUCCESS; +} + + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Ppm_PowerOn ( + _In_ PPPM_CONTEXT PpmCtx + ) +{ + NTSTATUS status; + PACPI_CONTEXT acpiCtx; + WDFDEVICE device; + UCSI_CONTROL command; + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_PPM); + + device = Context_GetWdfDevice(PpmCtx); + acpiCtx = &Context_GetFdoContext(PpmCtx)->AcpiCtx; + status = Acpi_RegisterNotificationCallback(acpiCtx, Ppm_NotificationHandler, PpmCtx); + if (!NT_SUCCESS(status)) + { + goto Exit; + } + + // + // Execute a PPM_RESET, bypassing the command queue. We can do that because completion of + // PPM_RESET is not indicated using a notification (we need to poll for completion), so + // we don't need to use all the command completion handling logic. + // + // Ppm_ExecuteCommand will poll for completion of the PPM_RESET. + // + + command.AsUInt64 = 0; + command.Command = UcsiCommandPpmReset; + status = Ppm_ExecuteCommand(PpmCtx, command); + if (!NT_SUCCESS(status)) + { + goto Exit; + } + + // + // Queue a request to enable command completion notifications. + // + // N.B. We only enable command completion notifications here. All other notifications should + // be enabled separately. This is because we need to query some information and create + // the connector objects before we can enable connector change notifications. + // + + command.AsUInt64 = 0; + command.Command = UcsiCommandSetNotificationEnable; + command.SetNotificationEnable.CommandCompleteNotificationEnable = 1; + status = Ppm_SendCommand(PpmCtx, command, nullptr, nullptr); + if (!NT_SUCCESS(status)) + { + goto Exit; + } + + TRACE_INFO(TRACE_FLAG_PPM, "[Device: 0x%p] PPM power-on complete", device); + +Exit: + + TRACE_FUNC_EXIT(TRACE_FLAG_PPM); + + return status; +} + + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Ppm_EnableNotifications ( + _In_ PPPM_CONTEXT PpmCtx + ) +{ + NTSTATUS status; + WDFDEVICE device; + UCSI_CONTROL command; + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_PPM); + + device = Context_GetWdfDevice(PpmCtx); + + command.AsUInt64 = 0; + command.Command = UcsiCommandSetNotificationEnable; + command.SetNotificationEnable.NotificationEnable = 0xffff; + status = Ppm_SendCommand(PpmCtx, command, nullptr, nullptr); + if (!NT_SUCCESS(status)) + { + goto Exit; + } + + TRACE_INFO(TRACE_FLAG_PPM, "[Device: 0x%p] PPM notifications enabled", device); + +Exit: + + TRACE_FUNC_EXIT(TRACE_FLAG_PPM); + + return status; +} + + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Ppm_PowerOff ( + _In_ PPPM_CONTEXT PpmCtx + ) +{ + NTSTATUS status; + PACPI_CONTEXT acpiCtx; + WDFDEVICE device; + UCSI_CONTROL command; + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_PPM); + + device = Context_GetWdfDevice(PpmCtx); + + command.AsUInt64 = 0; + command.Command = UcsiCommandSetNotificationEnable; + command.SetNotificationEnable.NotificationEnable = 0; + status = Ppm_ExecuteCommand(PpmCtx, command); + if (!NT_SUCCESS(status)) + { + goto Exit; + } + + acpiCtx = &Context_GetFdoContext(PpmCtx)->AcpiCtx; + Acpi_UnregisterNotificationCallback(acpiCtx); + + TRACE_INFO(TRACE_FLAG_PPM, "[Device: 0x%p] PPM power-off complete", device); + +Exit: + + TRACE_FUNC_EXIT(TRACE_FLAG_PPM); + + return status; +} + + +_IRQL_requires_max_(DISPATCH_LEVEL) +VOID +Ppm_NotificationHandler ( + _In_ PVOID Context, + _In_ ULONG NotifyValue + ) +{ + PPPM_CONTEXT ppmCtx; + WDFDEVICE device; + + TRACE_FUNC_ENTRY(TRACE_FLAG_PPM); + + ppmCtx = (PPPM_CONTEXT) Context; + device = Context_GetWdfDevice(ppmCtx); + + if (NotifyValue != UCSI_EXPECTED_NOTIFY_CODE) + { + TRACE_WARN(TRACE_FLAG_PPM, "[Device: 0x%p] Unexpected notify code %lu", device, NotifyValue); + goto Exit; + } + + Ppm_ProcessNotifications(ppmCtx); + +Exit: + + TRACE_FUNC_EXIT(TRACE_FLAG_PPM); +} + + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Ppm_WaitForResetComplete ( + _In_ PPPM_CONTEXT PpmCtx + ) +{ + WDFDEVICE device; + PACPI_CONTEXT acpiCtx; + NTSTATUS status; + ULONG retries; + LARGE_INTEGER delay; + const ULONG MAX_RETRIES = 20; + const ULONG WAIT_IN_MS = 20; + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_PPM); + + device = Context_GetWdfDevice(PpmCtx); + acpiCtx = &Context_GetFdoContext(PpmCtx)->AcpiCtx; + + delay.QuadPart = WDF_REL_TIMEOUT_IN_MS(WAIT_IN_MS); + + for (retries = 0; retries <= MAX_RETRIES; ++retries) + { + KeDelayExecutionThread(KernelMode, FALSE, &delay); + + status = Acpi_UcsiDsmReceiveData(acpiCtx); + if (!NT_SUCCESS(status)) + { + goto Exit; + } + + if (PpmCtx->UcsiDataBlock->CCI.ResetCompletedIndicator) + { + TRACE_INFO(TRACE_FLAG_PPM, "[Device: 0x%p] Reset completed after %u retries", device, retries); + break; + } + } + + if (retries > MAX_RETRIES) + { + status = STATUS_DEVICE_BUSY; + TRACE_ERROR(TRACE_FLAG_PPM, "[Device: 0x%p] Reset timed-out", device); + goto Exit; + } + + status = STATUS_SUCCESS; + +Exit: + + TRACE_FUNC_EXIT(TRACE_FLAG_PPM); + + return status; +} + + +_IRQL_requires_max_(DISPATCH_LEVEL) +VOID +Ppm_ProcessNotifications ( + _In_ PPPM_CONTEXT PpmCtx + ) +{ + WDFDEVICE device; + UCSI_CCI cci; + LONG oldValue; + + TRACE_FUNC_ENTRY(TRACE_FLAG_PPM); + + device = Context_GetWdfDevice(PpmCtx); + cci = PpmCtx->UcsiDataBlock->CCI; + + TRACE_INFO(TRACE_FLAG_PPM, "[Device: 0x%p] PPM notification received. CCI: 0x%08x", device, cci.AsUInt32); + + if (cci.AcknowledgeCommandIndicator) + { + // + // If we did send an acknowledgment for command completion earlier, this bit + // indicates that we can now complete the request from the command queue. Otherwise + // this is simply a stale bit from the last command completion. + // + + oldValue = InterlockedExchange(&PpmCtx->ActiveCommandCtx.CompletionAcked, 0); + + if (oldValue) + { + TRACE_INFO(TRACE_FLAG_PPM, "[Device: 0x%p] Acknowledge command indicator", device); + Ppm_CompleteActiveRequest(PpmCtx); + } + } + + // + // Now check mutually exclusive cases. + // + + if (cci.ConnectorChangeIndicator && + (InterlockedExchange(&PpmCtx->ConnectorChangeCtx.InProgress, 1) == 0)) + { + // + // A new connector change. Process it. + // + + Ppm_HandleConnectorChangeNotification(PpmCtx, cci); + } + else if (cci.CommandCompletedIndicator) + { + Ppm_HandleCommandCompletionNotification(PpmCtx, cci); + } + else if (cci.BusyIndicator) + { + TRACE_INFO(TRACE_FLAG_PPM, "[Device: 0x%p] Busy indicator for command %!UCSI_COMMAND!", device, PpmCtx->ActiveCommandCtx.Command.Command); + } + + TRACE_FUNC_EXIT(TRACE_FLAG_PPM); +} + + +_IRQL_requires_max_(DISPATCH_LEVEL) +VOID +Ppm_HandleConnectorChangeNotification ( + _In_ PPPM_CONTEXT PpmCtx, + _In_ UCSI_CCI Cci + ) +{ + WDFDEVICE device; + UCSI_CONTROL command; + + TRACE_FUNC_ENTRY(TRACE_FLAG_PPM); + + device = Context_GetWdfDevice(PpmCtx); + + TRACE_INFO(TRACE_FLAG_PPM, "[Device: 0x%p] Connector change indicated for connector %u. Getting connector status", device, Cci.ConnectorChangeIndicator); + + command.AsUInt64 = 0; + command.Command = UcsiCommandGetConnectorStatus; + command.GetConnectorStatus.ConnectorNumber = Cci.ConnectorChangeIndicator; + + // + // It may be that we had already sent a command down to the PPM (or are about to), and we + // got this notification just before we did, or the PPM decided to send us a notification + // first. Queue this command into the command queue so that everything is synchronized + // nicely. + + (void) Ppm_SendCommand(PpmCtx, command, Ppm_EvtGetConnectorStatusCompleted, PpmCtx); + + TRACE_FUNC_EXIT(TRACE_FLAG_PPM); +} + + +_IRQL_requires_max_(DISPATCH_LEVEL) +VOID +Ppm_HandleCommandCompletionNotification ( + _In_ PPPM_CONTEXT PpmCtx, + _In_ UCSI_CCI Cci + ) +{ + UNREFERENCED_PARAMETER(Cci); + + TRACE_FUNC_ENTRY(TRACE_FLAG_PPM); + + // + // Send a command to acknowledge the completion. Obviously we can't send the command to + // the command queue because there is already an outstanding request (the one we got the + // completion for), and that request will be completed only when we get the Acknowledge + // Command Indicator. However, we can safely execute the command right now, because we + // know the PPM is ready to accept an ACK_CC_CI command. + // + + if (KeGetCurrentIrql() == PASSIVE_LEVEL) + { + (void) Ppm_CommandCompletionHandler(PpmCtx); + } + else + { + WdfWorkItemEnqueue(PpmCtx->CommandCompletionWorkItem); + } + + TRACE_FUNC_EXIT(TRACE_FLAG_PPM); +} + + +VOID +Ppm_EvtIoInternalDeviceControl ( + _In_ WDFQUEUE Queue, + _In_ WDFREQUEST Request, + _In_ size_t OutputBufferLength, + _In_ size_t InputBufferLength, + _In_ ULONG IoControlCode + ) +{ + WDFDEVICE device; + PPPM_CONTEXT ppmCtx; + PPPM_ACTIVE_COMMAND_CONTEXT cmdCtx; + NTSTATUS status; + size_t expectedInputSize; + PPPM_SEND_COMMAND_PARAMS sendCommandParams; + BOOLEAN tookOwnership; + + UNREFERENCED_PARAMETER(OutputBufferLength); + + NT_ANALYSIS_ASSUME(KeGetCurrentIrql() == PASSIVE_LEVEL); + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_PPM); + + device = WdfIoQueueGetDevice(Queue); + ppmCtx = &Fdo_GetContext(device)->PpmCtx; + cmdCtx = &ppmCtx->ActiveCommandCtx; + tookOwnership = FALSE; + + if (IoControlCode != IOCTL_INTERNAL_UCSI_SEND_COMMAND) + { + status = STATUS_NOT_SUPPORTED; + TRACE_ERROR(TRACE_FLAG_PPM, "[Device: 0x%p] PPM command processor received unknown IOCTL 0x%lu", device, IoControlCode); + goto Exit; + } + + expectedInputSize = sizeof(*sendCommandParams); + + if (InputBufferLength != expectedInputSize) + { + status = STATUS_INVALID_BUFFER_SIZE; + TRACE_ERROR(TRACE_FLAG_PPM, "[Device: 0x%p] Invalid buffer size. Expected %Iu, got %Iu", device, expectedInputSize, InputBufferLength); + goto Exit; + } + + status = WdfRequestRetrieveInputBuffer(Request, + expectedInputSize, + (PVOID*) &sendCommandParams, + nullptr); + if (!NT_SUCCESS(status)) + { + TRACE_ERROR(TRACE_FLAG_PPM, "[Device: 0x%p] WdfRequestRetrieveInputBuffer failed - %!STATUS!", device, status); + goto Exit; + } + + NT_ASSERT(cmdCtx->Request == WDF_NO_HANDLE); + cmdCtx->Request = Request; + + NT_ASSERT(cmdCtx->Command.AsUInt64 == 0); + cmdCtx->Command = sendCommandParams->Command; + + NT_ASSERT(cmdCtx->CompletionRoutine == nullptr); + cmdCtx->CompletionRoutine = sendCommandParams->CompletionRoutine; + + NT_ASSERT(cmdCtx->CompletionContext == nullptr); + cmdCtx->CompletionContext = sendCommandParams->Context; + + NT_ASSERT(cmdCtx->CompletionAcked == 0); + cmdCtx->CompletionAcked = 0; + + cmdCtx->Status = STATUS_PENDING; + tookOwnership = TRUE; + + status = Ppm_ExecuteCommand(ppmCtx, cmdCtx->Command); + if (!NT_SUCCESS(status)) + { + cmdCtx->Status = status; + Ppm_CompleteActiveRequest(ppmCtx); + goto Exit; + } + + // + // If command completion notifications are enabled, we let the notification handler + // complete the request. Otherwise, complete it here. Note that in the latter case, we + // cannot return the MESSAGE_IN contents because we have no idea when it will be valid (or if + // at all it will be). + // + + if (ppmCtx->CommandCompleteNotificationEnabled == FALSE) + { + TRACE_INFO(TRACE_FLAG_PPM, "[Device: 0x%p] Command completion notification not enabled", device); + cmdCtx->Status = STATUS_SUCCESS; + Ppm_CompleteActiveRequest(ppmCtx); + } + +Exit: + + if (!NT_SUCCESS(status) && !tookOwnership) + { + RtlZeroMemory(cmdCtx, sizeof(*cmdCtx)); + WdfRequestComplete(Request, status); + } + + TRACE_FUNC_EXIT(TRACE_FLAG_PPM); +} + + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Ppm_ExecuteCommand ( + _In_ PPPM_CONTEXT PpmCtx, + _In_ UCSI_CONTROL Command + ) +{ + WDFDEVICE device; + NTSTATUS status; + PUCSI_DATA_BLOCK ucsiDataBlock; + PACPI_CONTEXT acpiCtx; + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_PPM); + + device = Context_GetWdfDevice(PpmCtx); + + TRACE_INFO(TRACE_FLAG_PPM, "[Device: 0x%p] Executing command - 0x%016I64x (%!UCSI_COMMAND!)", device, Command.AsUInt64, Command.Command); + + ucsiDataBlock = PpmCtx->UcsiDataBlock; + ucsiDataBlock->Control = Command; + + acpiCtx = &Context_GetFdoContext(PpmCtx)->AcpiCtx; + + status = Acpi_UcsiDsmSendData(acpiCtx); + if (!NT_SUCCESS(status)) + { + goto Exit; + } + + // + // See if this command would have updated the status of the command completion notification. + // This will be used to decide when to complete this request and any future requests in the + // command queue. Note that if this command enabled the notification, the notification handler + // may have already run and completed the request. + // + + if (Command.Command == UcsiCommandSetNotificationEnable) + { + PpmCtx->CommandCompleteNotificationEnabled = + !!Command.SetNotificationEnable.CommandCompleteNotificationEnable; + } + else if (Command.Command == UcsiCommandPpmReset) + { + // + // All notifications will be disabled on PPM_RESET. + // + + PpmCtx->CommandCompleteNotificationEnabled = FALSE; + + status = Ppm_WaitForResetComplete(PpmCtx); + if (!NT_SUCCESS(status)) + { + TRACE_ERROR(TRACE_FLAG_PPM, "[Device: 0x%p] Wait for reset completion failed - %!STATUS!", device, status); + goto Exit; + } + } + + TRACE_INFO(TRACE_FLAG_PPM, "[Device: 0x%p] PPM command execution completed", device); + +Exit: + + TRACE_FUNC_EXIT(TRACE_FLAG_PPM); + + return status; +} + + +VOID +Ppm_CommandCompletionWorkItem ( + _In_ WDFWORKITEM WorkItem + ) +{ + WDFDEVICE device; + PPPM_CONTEXT ppmCtx; + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_PPM); + + device = (WDFDEVICE) WdfWorkItemGetParentObject(WorkItem); + ppmCtx = &Fdo_GetContext(device)->PpmCtx; + + TRACE_INFO(TRACE_FLAG_PPM, "[Device: 0x%p] Handling command completion in a workitem", device); + + (void) Ppm_CommandCompletionHandler(ppmCtx); + + TRACE_FUNC_EXIT(TRACE_FLAG_PPM); +} + + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Ppm_CommandCompletionHandler ( + _In_ PPPM_CONTEXT PpmCtx + ) +{ + NTSTATUS status; + PPPM_ACTIVE_COMMAND_CONTEXT cmdCtx; + UCSI_CONTROL ackCommand; + PPM_COMMAND_ACK_PARAMS ackParams; + WDFDEVICE device; + UCSI_CCI cci; + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_PPM); + + device = Context_GetWdfDevice(PpmCtx); + cmdCtx = &PpmCtx->ActiveCommandCtx; + cci = PpmCtx->UcsiDataBlock->CCI; + + if (cci.ErrorIndicator) + { + TRACE_ERROR(TRACE_FLAG_PPM, "[Device: 0x%p] Error indicator. Active command: 0x%016I64x (%!UCSI_COMMAND!)", device, cmdCtx->Command.AsUInt64, cmdCtx->Command.Command); + cmdCtx->Status = STATUS_UNSUCCESSFUL; + } + else if (cci.NotSupportedIndicator) + { + TRACE_ERROR(TRACE_FLAG_PPM, "[Device: 0x%p] Not supported indicator. Active command: 0x%016I64x (%!UCSI_COMMAND!)", device, cmdCtx->Command.AsUInt64, cmdCtx->Command.Command); + cmdCtx->Status = STATUS_NOT_SUPPORTED; + } + else + { + TRACE_INFO(TRACE_FLAG_PPM, "[Device: 0x%p] Command completed indicator. Active command: 0x%016I64x (%!UCSI_COMMAND!)", device, cmdCtx->Command.AsUInt64, cmdCtx->Command.Command); + Ppm_SaveMessageInContentsInRequest(PpmCtx); + cmdCtx->Status = STATUS_SUCCESS; + } + + ackCommand.AsUInt64 = 0; + ackCommand.Command = UcsiCommandAckCcCi; + ackCommand.AckCcCi.CommandCompletedAcknowledge = 1; + + if (cmdCtx->CompletionRoutine != nullptr) + { + RtlZeroMemory(&ackParams, sizeof(ackParams)); + cmdCtx->CompletionRoutine(cmdCtx->Command, + cmdCtx->CompletionContext, + &ackParams); + + if (ackParams.AckConnectorChange) + { + TRACE_INFO(TRACE_FLAG_PPM, "[Device: 0x%p] Acknowledging connector change", device); + ackCommand.AckCcCi.ConnectorChangeAcknowledge = 1; + PpmCtx->ConnectorChangeCtx.InProgress = 0; + } + } + + cmdCtx->CompletionAcked = 1; + status = Ppm_ExecuteCommand(PpmCtx, ackCommand); + + TRACE_FUNC_EXIT(TRACE_FLAG_PPM); + + return status; +} + + +_IRQL_requires_max_(DISPATCH_LEVEL) +VOID +Ppm_CompleteActiveRequest ( + _In_ PPPM_CONTEXT PpmCtx + ) +{ + WDFREQUEST request; + WDFDEVICE device; + UCSI_CONTROL command; + NTSTATUS status; + PPPM_ACTIVE_COMMAND_CONTEXT cmdCtx; + + TRACE_FUNC_ENTRY(TRACE_FLAG_PPM); + + cmdCtx = &PpmCtx->ActiveCommandCtx; + device = Context_GetWdfDevice(PpmCtx); + request = cmdCtx->Request; + command = cmdCtx->Command; + status = cmdCtx->Status; + + RtlZeroMemory(cmdCtx, sizeof(*cmdCtx)); + + if (!NT_SUCCESS(status)) + { + TRACE_ERROR(TRACE_FLAG_PPM, "[Device: 0x%p] Completing command 0x%016I64x (%!UCSI_COMMAND!) with %!STATUS!", device, command.AsUInt64, command.Command, status); + } + else + { + TRACE_INFO(TRACE_FLAG_PPM, "[Device: 0x%p] Completing command 0x%016I64x (%!UCSI_COMMAND!) with %!STATUS!", device, command.AsUInt64, command.Command, status); + } + + WdfRequestComplete(request, status); + + TRACE_FUNC_EXIT(TRACE_FLAG_PPM); +} + + +_IRQL_requires_max_(DISPATCH_LEVEL) +VOID +Ppm_SaveMessageInContentsInRequest ( + _In_ PPPM_CONTEXT PpmCtx + ) +{ + WDFREQUEST request; + PUCSI_MESSAGE_IN messageIn; + NTSTATUS status; + ULONG_PTR information; + size_t outputSize; + + TRACE_FUNC_ENTRY(TRACE_FLAG_PPM); + + request = PpmCtx->ActiveCommandCtx.Request; + + Ppm_PrettyDebugPrintMessageIn(PpmCtx); + + outputSize = PpmCtx->UcsiDataBlock->CCI.DataLength; + status = WdfRequestRetrieveOutputBuffer(request, outputSize, (PVOID*) &messageIn, nullptr); + if (NT_SUCCESS(status)) + { + RtlCopyMemory(messageIn, PpmCtx->UcsiDataBlock->MessageIn.AsBuffer, outputSize); + information = outputSize; + } + else + { + information = 0; + } + + WdfRequestSetInformation(request, information); + + TRACE_FUNC_EXIT(TRACE_FLAG_PPM); +} + + +_IRQL_requires_max_(DISPATCH_LEVEL) +VOID +Ppm_PrettyDebugPrintMessageIn ( + _In_ PPPM_CONTEXT PpmCtx + ) +{ + WDFDEVICE device; + ULONG i; + PUINT8 messageBuf; + UCSI_CONTROL activeCommand; + PUCSI_GET_CONNECTOR_STATUS_IN connStatus; + size_t messageInSize; + + TRACE_FUNC_ENTRY(TRACE_FLAG_PPM); + + device = Context_GetWdfDevice(PpmCtx); + activeCommand = PpmCtx->ActiveCommandCtx.Command; + messageInSize = PpmCtx->UcsiDataBlock->CCI.DataLength; + + static_assert(sizeof(UCSI_MESSAGE_IN) == 16, "MESSAGE_IN size assumption out-of-sync"); + + if (activeCommand.Command == UcsiCommandGetConnectorStatus) + { + connStatus = &PpmCtx->UcsiDataBlock->MessageIn.ConnectorStatus; + + TRACE_INFO(TRACE_FLAG_PPM, "[Device: 0x%p] Connector Status", device); + + TRACE_INFO( + TRACE_FLAG_PPM, + "[Device: 0x%p] " + "%s %s %s %s %s %s %s %s %s %s %s", + device, + connStatus->ConnectorStatusChange.ExternalSupplyChange ? "ExternalSupplyChange" : " ", + connStatus->ConnectorStatusChange.PowerOperationModeChange ? "PowerOperationModeChange" : " ", + connStatus->ConnectorStatusChange.SupportedProviderCapabilitiesChange ? "SupportedProviderCapabilitiesChange" : " ", + connStatus->ConnectorStatusChange.NegotiatedPowerLevelChange ? "NegotiatedPowerLevelChange" : " ", + connStatus->ConnectorStatusChange.PdResetComplete ? "PdResetComplete" : " ", + connStatus->ConnectorStatusChange.SupportedCamChange ? "SupportedCamChange" : " ", + connStatus->ConnectorStatusChange.BatteryChargingStatusChange ? "BatteryChargingStatusChange" : " ", + connStatus->ConnectorStatusChange.ConnectorPartnerChange ? "ConnectorPartnerChange" : " ", + connStatus->ConnectorStatusChange.PowerDirectionChange ? "PowerDirectionChange" : " ", + connStatus->ConnectorStatusChange.ConnectChange ? "ConnectChange" : " ", + connStatus->ConnectorStatusChange.Error ? "Error" : " " + ); + + TRACE_INFO( + TRACE_FLAG_PPM, + "[Device: 0x%p] " + "Connect: %d PartnerFlags: %d RDO: 0x%x", + device, + connStatus->ConnectStatus, + connStatus->ConnectorPartnerFlags, + connStatus->RequestDataObject + ); + + TRACE_INFO( + TRACE_FLAG_PPM, + "[Device: 0x%p] " + "%!UCSI_POWER_OPERATION_MODE! " + "%!UCSI_POWER_DIRECTION! " + "%!UCSI_CONNECTOR_PARTNER_TYPE! " + "%!UCSI_BATTERY_CHARGING_STATUS!", + device, + connStatus->PowerOperationMode, + connStatus->PowerDirection, + connStatus->ConnectorPartnerType, + connStatus->BatteryChargingStatus + ); + } + else + { + for (i = 0; (i < 4) && messageInSize; ++i) + { + messageBuf = &PpmCtx->UcsiDataBlock->MessageIn.AsBuffer[i * 4]; + TRACE_INFO(TRACE_FLAG_PPM, "[Device: 0x%p] MESSAGE_IN[%d]: %02x %02x %02x %02x", device, i, messageBuf[0], messageBuf[1], messageBuf[2], messageBuf[3]); + + messageInSize -= min(messageInSize, 4); + } + } + + TRACE_FUNC_EXIT(TRACE_FLAG_PPM); +} + + +_IRQL_requires_max_(PASSIVE_LEVEL) +VOID +Ppm_ReportNegotiatedPowerLevelChanged ( + _In_ PPPM_CONTEXT PpmCtx, + _In_ PPPM_CONNECTOR Connector, + _Inout_ PUCSI_GET_CONNECTOR_STATUS_IN ConnStatus, + _Inout_ PPPM_COMMAND_ACK_PARAMS CommandAckParams + ) +{ + WDFDEVICE device; + NTSTATUS status; + UCSI_CONTROL cmd; + + UNREFERENCED_PARAMETER(CommandAckParams); + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_PPM); + + NT_ASSERT(ConnStatus->PowerOperationMode == UcsiPowerOperationModePd); + + device = Context_GetWdfDevice(PpmCtx); + + // + // Save off stuff we will need for later. + // + + PpmCtx->ConnectorChangeCtx.Rdo.Ul = ConnStatus->RequestDataObject; + + if (!Convert((UCSI_BATTERY_CHARGING_STATUS) ConnStatus->BatteryChargingStatus, + PpmCtx->ConnectorChangeCtx.ChargingState)) + { + TRACE_ERROR(TRACE_FLAG_PPM, "[Device: 0x%p] Invalid battery charging state %u", device, ConnStatus->BatteryChargingStatus); + goto Exit; + } + + TRACE_INFO(TRACE_FLAG_PPM, "[Device: 0x%p] Retrieving PD contract details", device); + + cmd.AsUInt64 = 0; + cmd.Command = UcsiCommandGetPdos; + cmd.GetPdos.ConnectorNumber = Connector->Index; + cmd.GetPdos.NumberOfPdos = 3; + + if (ConnStatus->PowerDirection == UcsiPowerDirectionConsumer) + { + cmd.GetPdos.PartnerPdo = 1; + } + else + { + cmd.GetPdos.PartnerPdo = 0; + } + + cmd.GetPdos.SourceOrSinkPdos = UcsiGetPdosTypeSource; + cmd.GetPdos.PdoOffset = 0; + + status = Ppm_SendCommand(PpmCtx, cmd, Ucm_EvtGetPdosCompleted, PpmCtx); + if (!NT_SUCCESS(status)) + { + goto Exit; + } + + // + // Don't acknowledge the change just yet. Wait till we get the PD contract information + // as well. + // + + CommandAckParams->AckConnectorChange = FALSE; + + // + // We will report the charging state when we report the PD contract details. + // + + ConnStatus->ConnectorStatusChange.BatteryChargingStatusChange = 0; + ConnStatus->ConnectorStatusChange.NegotiatedPowerLevelChange = 0; + +Exit: + + TRACE_FUNC_EXIT(TRACE_FLAG_PPM); +} + + +VOID +Ppm_EvtGetConnectorStatusCompleted ( + _In_ UCSI_CONTROL Command, + _In_ PVOID Context, + _Inout_ PPPM_COMMAND_ACK_PARAMS CommandAckParams + ) +{ + PPPM_CONTEXT ppmCtx; + UCSI_GET_CONNECTOR_STATUS_IN connStatus; + PPPM_CONNECTOR connector; + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_PPM); + + ppmCtx = (PPPM_CONTEXT) Context; + + NT_ASSERT(Command.Command == UcsiCommandGetConnectorStatus); + + // + // Default disposition is to acknowledge the connector change. If we need to send more + // commands to get more details on the change, then don't acknowledge; individual handler + // routines will update the CommandAckParams accordingly. + // + + CommandAckParams->AckConnectorChange = TRUE; + + if (!UCSI_CMD_SUCCEEDED(ppmCtx->UcsiDataBlock->CCI)) + { + // + // The command failed. Acknowledge the connector change and move on. + // + + goto Exit; + } + + // + // Send all the appropriate notifications to UCM. In the process of handling each type of + // change, other related bits in the connector status change may be cleared by the handler + // because the associated information has already been reported. + // + // N.B. Even if we encounter errors, make sure to acknowledge the connector change. Else + // we will not get any more notifications. + // + + connStatus = ppmCtx->UcsiDataBlock->MessageIn.ConnectorStatus; + connector = Ppm_GetConnector(ppmCtx, Command.GetConnectorStatus.ConnectorNumber); + + if (connStatus.ConnectorStatusChange.ConnectChange) + { + if (connStatus.ConnectStatus) + { + Ucm_ReportTypeCAttach(ppmCtx, connector, &connStatus, CommandAckParams); + + // + // If PD has already been negotiated, report that information as well. + // + + if (connStatus.PowerOperationMode == UcsiPowerOperationModePd) + { + Ppm_ReportNegotiatedPowerLevelChanged(ppmCtx, + connector, + &connStatus, + CommandAckParams); + } + } + else + { + Ucm_ReportTypeCDetach(ppmCtx, connector, &connStatus, CommandAckParams); + + // + // If ConnectStatus is not set, nothing else is valid. + // + goto Exit; + } + } + + if (connStatus.ConnectorStatusChange.PowerOperationModeChange) + { + Ucm_ReportPowerOperationMode(ppmCtx, connector, &connStatus, CommandAckParams); + } + + if(connStatus.ConnectorStatusChange.PowerDirectionChange) + { + Ucm_ReportPowerDirectionChanged(ppmCtx, connector, &connStatus, CommandAckParams); + } + + if (connStatus.ConnectorStatusChange.ConnectorPartnerChange) + { + Ucm_ReportDataDirectionChanged(ppmCtx, connector, &connStatus, CommandAckParams); + } + + if (connStatus.ConnectorStatusChange.BatteryChargingStatusChange) + { + Ucm_ReportChargingStatusChanged(ppmCtx, connector, &connStatus, CommandAckParams); + } + + if (connStatus.ConnectorStatusChange.NegotiatedPowerLevelChange) + { + Ppm_ReportNegotiatedPowerLevelChanged(ppmCtx, connector, &connStatus, CommandAckParams); + } + +Exit: + + TRACE_FUNC_EXIT(TRACE_FLAG_PPM); +} + + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Ppm_QueryConnectors ( + _In_ PPPM_CONTEXT PpmCtx + ) +{ + NTSTATUS status; + WDFDEVICE device; + WDFMEMORY enumChildrenMem; + PPPM_CONNECTOR connector; + PACPI_ENUM_CHILDREN_OUTPUT_BUFFER enumChildrenBuf; + PACPI_ENUM_CHILD enumChild; + ACPI_PLD_BUFFER pldBuffer; + PACPI_CONTEXT acpiCtx; + ULONG64 connectorId; + WDF_OBJECT_ATTRIBUTES attributes; + ULONG i; + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_PPM); + + enumChildrenMem = WDF_NO_HANDLE; + device = Context_GetWdfDevice(PpmCtx); + acpiCtx = &Context_GetFdoContext(PpmCtx)->AcpiCtx; + + WDF_OBJECT_ATTRIBUTES_INIT(&attributes); + attributes.ParentObject = device; + + status = WdfCollectionCreate(&attributes, &PpmCtx->Connectors); + if (!NT_SUCCESS(status)) + { + TRACE_ERROR(TRACE_FLAG_PPM, "[Device: 0x%p] WdfCollectionCreate failed - %!STATUS!", device, status); + goto Exit; + } + + status = Acpi_EnumChildren(acpiCtx, &enumChildrenMem); + if (!NT_SUCCESS(status)) + { + goto Exit; + } + + enumChildrenBuf = + (PACPI_ENUM_CHILDREN_OUTPUT_BUFFER) WdfMemoryGetBuffer(enumChildrenMem, nullptr); + + // + // If there is only one child, which is this device itself, then there is no connector + // information available. Assume there is only one connector. + // + + if (enumChildrenBuf->NumberOfChildren == 1) + { + TRACE_INFO(TRACE_FLAG_PPM, "[Device: 0x%p] Connector information not found. Assuming single-connector system", device); + + connector = Ppm_AddConnector(PpmCtx); + if (connector == nullptr) + { + status = STATUS_INSUFFICIENT_RESOURCES; + goto Exit; + } + + connector->Id = 0; + connector->Index = 1; + + goto Exit; + } + + enumChild = enumChildrenBuf->Children; + + for (i = 1; i < enumChildrenBuf->NumberOfChildren; ++i) + { + enumChild = ACPI_ENUM_CHILD_NEXT(enumChild); + + // + // Connectors are child devices that have a _PLD method. Skip any children + // that don't have any children, and attempt to evaluate _PLD on the ones that do. + // + + if ((enumChild->Flags & ACPI_OBJECT_HAS_CHILDREN) == 0) + { + continue; + } + + status = Acpi_EvaluatePld(acpiCtx, enumChild->Name, &pldBuffer); + if (!NT_SUCCESS(status)) + { + continue; + } + + connectorId = UCM_CONNECTOR_ID_FROM_ACPI_PLD(&pldBuffer); + + TRACE_INFO(TRACE_FLAG_PPM, "[Device: 0x%p] Found connector %s with ID 0x%I64x", device, enumChild->Name, connectorId); + + connector = Ppm_AddConnector(PpmCtx); + if (connector == nullptr) + { + status = STATUS_INSUFFICIENT_RESOURCES; + goto Exit; + } + + connector->Id = connectorId; + } + + TRACE_INFO(TRACE_FLAG_PPM, "[Device: 0x%p] Found %lu connectors", device, WdfCollectionGetCount(PpmCtx->Connectors)); + +Exit: + + if (enumChildrenMem != WDF_NO_HANDLE) + { + WdfObjectDelete(enumChildrenMem); + } + + TRACE_FUNC_EXIT(TRACE_FLAG_PPM); + + return status; +} + + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Ppm_GetCapability ( + _In_ PPPM_CONTEXT PpmCtx, + _Out_ PUCSI_GET_CAPABILITY_IN Caps + ) +{ + NTSTATUS status; + WDFDEVICE device; + UCSI_CONTROL cmd; + UCSI_MESSAGE_IN msg; + ULONG_PTR bytesReturned; + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_PPM); + + device = Context_GetWdfDevice(PpmCtx); + + cmd.AsUInt64 = 0; + cmd.Command = UcsiCommandGetCapability; + + status = Ppm_SendCommandSynchronously(PpmCtx, cmd, &msg, &bytesReturned); + if (!NT_SUCCESS(status)) + { + TRACE_ERROR(TRACE_FLAG_PPM, "[Device: 0x%p] Failed to retrieve capabilities - %!STATUS!", device, status); + goto Exit; + } + + if (bytesReturned != sizeof(*Caps)) + { + status = STATUS_INVALID_BUFFER_SIZE; + TRACE_ERROR(TRACE_FLAG_PPM, "[Device: 0x%p] Invalid capabilities buffer size", device); + goto Exit; + } + + RtlCopyMemory(Caps, &msg.Capability, sizeof(*Caps)); + +Exit: + + TRACE_FUNC_EXIT(TRACE_FLAG_PPM); + + return status; +} + + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Ppm_GetConnectorCapability ( + _In_ PPPM_CONTEXT PpmCtx, + _In_ CONNECTOR_INDEX ConnectorIndex, + _Out_ PUCSI_GET_CONNECTOR_CAPABILITY_IN ConnCaps + ) +{ + NTSTATUS status; + WDFDEVICE device; + UCSI_CONTROL cmd; + UCSI_MESSAGE_IN msg; + ULONG_PTR bytesReturned; + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_PPM); + + device = Context_GetWdfDevice(PpmCtx); + + cmd.AsUInt64 = 0; + cmd.Command = UcsiCommandGetConnectorCapability; + cmd.GetConnectorCapability.ConnectorNumber = ConnectorIndex; + + status = Ppm_SendCommandSynchronously(PpmCtx, cmd, &msg, &bytesReturned); + if (!NT_SUCCESS(status)) + { + TRACE_ERROR(TRACE_FLAG_PPM, "[Device: 0x%p] Failed to retrieve connector capabilities for connector index %u - %!STATUS!", device, ConnectorIndex, status); + goto Exit; + } + + if (bytesReturned != sizeof(*ConnCaps)) + { + status = STATUS_INVALID_BUFFER_SIZE; + TRACE_ERROR(TRACE_FLAG_PPM, "[Device: 0x%p] Invalid connector capabilities buffer size", device); + goto Exit; + } + + RtlCopyMemory(ConnCaps, &msg.Capability, sizeof(*ConnCaps)); + +Exit: + + TRACE_FUNC_EXIT(TRACE_FLAG_PPM); + + return status; +} + + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Ppm_ConnectorSetUor ( + _In_ PPPM_CONTEXT PpmCtx, + _In_ CONNECTOR_INDEX ConnectorIndex, + _In_ UCSI_USB_OPERATION_ROLE Uor + ) +{ + WDFDEVICE device; + PPPM_CONNECTOR connector; + UCM_DATA_ROLE dataRole; + NTSTATUS status; + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_PPM); + + device = Context_GetWdfDevice(PpmCtx); + + if (!Convert(Uor, dataRole)) + { + status = STATUS_INVALID_PARAMETER; + TRACE_ERROR(TRACE_FLAG_PPM, "[Device: 0x%p] Invalid USB operation role 0x%x", device, Uor); + goto Exit; + } + + TRACE_INFO(TRACE_FLAG_PPM, "[Device: 0x%p] Test interface invoking SetDataRole for %!UCM_DATA_ROLE!", device, dataRole); + + connector = Ppm_GetConnector(PpmCtx, ConnectorIndex); + status = Ucm_EvtConnectorSetDataRole(connector->Handle, dataRole); + +Exit: + + TRACE_FUNC_EXIT(TRACE_FLAG_PPM); + + return status; +} + + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Ppm_ConnectorSetPdr ( + _In_ PPPM_CONTEXT PpmCtx, + _In_ CONNECTOR_INDEX ConnectorIndex, + _In_ UCSI_POWER_DIRECTION_ROLE Pdr + ) +{ + WDFDEVICE device; + PPPM_CONNECTOR connector; + UCM_POWER_ROLE powerRole; + NTSTATUS status; + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_PPM); + + device = Context_GetWdfDevice(PpmCtx); + + if (!Convert(Pdr, powerRole)) + { + status = STATUS_INVALID_PARAMETER; + TRACE_ERROR(TRACE_FLAG_PPM, "[Device: 0x%p] Invalid power direction role 0x%x", device, Pdr); + goto Exit; + } + + TRACE_INFO(TRACE_FLAG_PPM, "[Device: 0x%p] Test interface invoking SetPowerRole for %!UCM_POWER_ROLE!", device, powerRole); + + connector = Ppm_GetConnector(PpmCtx, ConnectorIndex); + status = Ucm_EvtConnectorSetPowerRole(connector->Handle, powerRole); + +Exit: + + TRACE_FUNC_EXIT(TRACE_FLAG_PPM); + + return status; +} + + +_IRQL_requires_max_(PASSIVE_LEVEL) +_Must_inspect_result_ +_Success_(return != 0) +PPPM_CONNECTOR +Ppm_AddConnector ( + _In_ PPPM_CONTEXT PpmCtx + ) +{ + NTSTATUS status; + WDFDEVICE device; + WDFMEMORY connectorMem; + PPPM_CONNECTOR connector; + WDF_OBJECT_ATTRIBUTES attributes; + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_PPM); + + device = Context_GetWdfDevice(PpmCtx); + connector = nullptr; + + WDF_OBJECT_ATTRIBUTES_INIT(&attributes); + attributes.ParentObject = PpmCtx->Connectors; + status = WdfMemoryCreate(&attributes, + NonPagedPoolNx, + 0, + sizeof(PPM_CONNECTOR), + &connectorMem, + (PVOID*) &connector); + if (!NT_SUCCESS(status)) + { + TRACE_ERROR(TRACE_FLAG_PPM, "[Device: 0x%p] WdfMemoryCreate for PPM_CONNECTOR failed - %!STATUS!", device, status); + goto Exit; + } + + status = WdfCollectionAdd(PpmCtx->Connectors, connectorMem); + if (!NT_SUCCESS(status)) + { + TRACE_ERROR(TRACE_FLAG_PPM, "[Device: 0x%p] WdfCollectionAdd for connector failed - %!STATUS!", device, status); + goto Exit; + } + + // + // N.B. Should not fail beyond this point, else the connector object must be removed + // from the collection. + // + + RtlZeroMemory(connector, sizeof(*connector)); + + connector->WdfDevice = device; + connector->Index = WdfCollectionGetCount(PpmCtx->Connectors); + +Exit: + + if (!NT_SUCCESS(status) && (connector != nullptr)) + { + WdfObjectDelete(connectorMem); + connector = nullptr; + } + + TRACE_FUNC_EXIT(TRACE_FLAG_PPM); + + return connector; +} + + +_IRQL_requires_max_(DISPATCH_LEVEL) +PPPM_CONNECTOR +Ppm_GetConnector ( + _In_ PPPM_CONTEXT PpmCtx, + _In_ CONNECTOR_INDEX Index + ) +{ + WDFMEMORY connectorMem; + PPPM_CONNECTOR connector; + + TRACE_FUNC_ENTRY(TRACE_FLAG_PPM); + + // + // UCSI connector index is one-based. + // + + connectorMem = (WDFMEMORY) WdfCollectionGetItem(PpmCtx->Connectors, Index - 1); + + // + // Assuming caller knows what they are doing. + // + + NT_ASSERT_ASSUME(connectorMem != NULL); + + connector = (PPPM_CONNECTOR) WdfMemoryGetBuffer(connectorMem, nullptr); + + NT_ASSERTMSG("Connectors were added in incorrect order", connector->Index == Index); + + TRACE_FUNC_EXIT(TRACE_FLAG_PPM); + + return connector; +} + + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Ppm_PerformRoleCorrection ( + _In_ PPPM_CONTEXT PpmCtx, + _In_ PPPM_CONNECTOR Connector + ) +{ + WDFDEVICE device; + UCSI_CONTROL cmd; + NTSTATUS status; + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_PPM); + + device = Context_GetWdfDevice(PpmCtx); + + TRACE_INFO(TRACE_FLAG_PPM, "[Device: 0x%p] Performing role-correction on connector ID 0x%I64x", device, Connector->Id); + + cmd.AsUInt64 = 0; + cmd.Command = UcsiCommandSetUor; + cmd.SetUor.ConnectorNumber = Connector->Index; + cmd.SetUor.UsbOperationRole = UcsiUsbOperationRoleDfp; + + status = Ppm_SendCommand(PpmCtx, cmd, Ucm_EvtSetDataRoleCompleted, PpmCtx); + if (!NT_SUCCESS(status)) + { + goto Exit; + } + +Exit: + + TRACE_FUNC_EXIT(TRACE_FLAG_PPM); + + return status; +} diff --git a/usb/UcmCxUcsi/Ppm.h b/usb/UcmCxUcsi/Ppm.h new file mode 100644 index 00000000..341c25d4 --- /dev/null +++ b/usb/UcmCxUcsi/Ppm.h @@ -0,0 +1,351 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + Ppm.h + +Abstract: + + Type-C Platform Policy Manager. Main interface to talk to the hardware. + +Environment: + + Kernel-mode only. + +--*/ + +#pragma once + +#define MAKEWORD(a, b) ((WORD)(((BYTE)(((DWORD_PTR)(a)) & 0xff)) | ((WORD)((BYTE)(((DWORD_PTR)(b)) & 0xff))) << 8)) + +#define UCSI_EXPECTED_NOTIFY_CODE 0x80 + +#define FILE_DEVICE_PPM 32769 + +#define IOCTL_INTERNAL_UCSI_SEND_COMMAND \ + (DWORD) CTL_CODE(FILE_DEVICE_PPM, \ + 0x900, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +EXTERN_C_START + +typedef struct _PPM_COMMAND_ACK_PARAMS +{ + BOOLEAN AckConnectorChange; +} PPM_COMMAND_ACK_PARAMS, *PPPM_COMMAND_ACK_PARAMS; + +typedef +_Function_class_(EVT_PPM_COMMAND_COMPLETION_ROUTINE) +_IRQL_requires_max_(PASSIVE_LEVEL) +_IRQL_requires_same_ +VOID +EVT_PPM_COMMAND_COMPLETION_ROUTINE ( + _In_ UCSI_CONTROL Command, + _In_ PVOID Context, + _Inout_ PPPM_COMMAND_ACK_PARAMS CommandAckParams + ); + +typedef EVT_PPM_COMMAND_COMPLETION_ROUTINE *PFN_PPM_COMMAND_COMPLETION_ROUTINE; + +typedef ULONG CONNECTOR_INDEX; + +typedef struct _PPM_ACTIVE_COMMAND_CONTEXT +{ + WDFREQUEST Request; + NTSTATUS Status; + UCSI_CONTROL Command; + PFN_PPM_COMMAND_COMPLETION_ROUTINE CompletionRoutine; + PVOID CompletionContext; + BOOLEAN CompletionRoutineInvoked; + LONG CompletionAcked; +} PPM_ACTIVE_COMMAND_CONTEXT, *PPPM_ACTIVE_COMMAND_CONTEXT; + +typedef struct _PPM_CONNECTOR_CHANGE_CONTEXT +{ + LONG InProgress; + UCM_CHARGING_STATE ChargingState; + UCM_PD_REQUEST_DATA_OBJECT Rdo; + UCM_PD_POWER_DATA_OBJECT Pdos[7]; + UCHAR PdoCount; +} PPM_CONNECTOR_CHANGE_CONTEXT, *PPPM_CONNECTOR_CHANGE_CONTEXT; + +typedef struct _PPM_CONTEXT +{ + PUCSI_DATA_BLOCK UcsiDataBlock; + ULONG MappedMemoryLength; + BOOLEAN IsUsbDeviceControllerEnabled; + WDFIOTARGET SelfIoTarget; + WDFQUEUE CommandQueue; + WDFWORKITEM CommandCompletionWorkItem; + BOOLEAN CommandCompleteNotificationEnabled; + WDFCOLLECTION Connectors; + + // + // State associated with the current command. + // + PPM_ACTIVE_COMMAND_CONTEXT ActiveCommandCtx; + + // + // Temporary state associated with a reported connector + // change. Since multiple commands may need to be sent, + // all the data is temporarily staged in here, before reporting + // it all to the Cx. + // + PPM_CONNECTOR_CHANGE_CONTEXT ConnectorChangeCtx; +} PPM_CONTEXT, *PPPM_CONTEXT; + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Ppm_Initialize( + _In_ PPPM_CONTEXT PpmCtx +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Ppm_PrepareHardware ( + _In_ PPPM_CONTEXT PpmCtx, + _In_ PHYSICAL_ADDRESS MemoryAddress, + _In_ ULONG MemoryLength + ); + +_IRQL_requires_max_(PASSIVE_LEVEL) +VOID +Ppm_ReleaseHardware ( + _In_ PPPM_CONTEXT PpmCtx + ); + +_IRQL_requires_max_(DISPATCH_LEVEL) +NTSTATUS +Ppm_SendCommand ( + _In_ PPPM_CONTEXT PpmCtx, + _In_ UCSI_CONTROL Command, + _In_opt_ PFN_PPM_COMMAND_COMPLETION_ROUTINE CompletionRoutine, + _In_opt_ PVOID Context + ); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Ppm_SendCommandSynchronously ( + _In_ PPPM_CONTEXT PpmCtx, + _In_ UCSI_CONTROL Command, + _Out_opt_ PUCSI_MESSAGE_IN MessageIn, + _Out_opt_ PULONG_PTR BytesReturned + ); + +_IRQL_requires_max_(HIGH_LEVEL) +NTSTATUS +Ppm_GetCci ( + _In_ PPPM_CONTEXT PpmCtx, + _Out_ PUCSI_CCI UcsiCci + ); + +_IRQL_requires_max_(HIGH_LEVEL) +NTSTATUS +Ppm_GetMessage ( + _In_ PPPM_CONTEXT PpmCtx, + _Out_ UINT8 (&Message)[UCSI_MAX_DATA_LENGTH] + ); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Ppm_PowerOn ( + _In_ PPPM_CONTEXT PpmCtx + ); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Ppm_EnableNotifications ( + _In_ PPPM_CONTEXT PpmCtx + ); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Ppm_PowerOff ( + _In_ PPPM_CONTEXT PpmCtx + ); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Ppm_ConnectorSetUor ( + _In_ PPPM_CONTEXT PpmCtx, + _In_ CONNECTOR_INDEX ConnectorIndex, + _In_ UCSI_USB_OPERATION_ROLE Uor + ); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Ppm_ConnectorSetPdr ( + _In_ PPPM_CONTEXT PpmCtx, + _In_ CONNECTOR_INDEX ConnectorIndex, + _In_ UCSI_POWER_DIRECTION_ROLE Pdr + ); + +EVT_ACPI_NOTIFY_CALLBACK Ppm_NotificationHandler; + +_IRQL_requires_max_(HIGH_LEVEL) +ULONG64 +FORCEINLINE +UCM_CONNECTOR_ID_FROM_ACPI_PLD( + _In_ PACPI_PLD_BUFFER PldBuffer +) +{ + ULONG64 connectorId; + + connectorId = 0; + connectorId |= (PldBuffer->GroupToken & 0xFF); + connectorId <<= 8; + connectorId |= (PldBuffer->GroupPosition & 0xFF); + + return connectorId; +} + + +typedef struct _PPM_SEND_COMMAND_PARAMS +{ + UCSI_CONTROL Command; + PFN_PPM_COMMAND_COMPLETION_ROUTINE CompletionRoutine; + PVOID Context; +} PPM_SEND_COMMAND_PARAMS, *PPPM_SEND_COMMAND_PARAMS; + +typedef struct _PPM_REQUEST_CONTEXT +{ + UCSI_CONTROL Command; +} PPM_REQUEST_CONTEXT, *PPPM_REQUEST_CONTEXT; + +WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(PPM_REQUEST_CONTEXT, PpmRequest_GetContext); + +typedef struct _PPM_CONNECTOR +{ + WDFDEVICE WdfDevice; + ULONGLONG Id; + CONNECTOR_INDEX Index; + UCMCONNECTOR Handle; + BOOLEAN PerformRoleCorrectionOnNextPdContract; +} PPM_CONNECTOR, *PPPM_CONNECTOR; + +typedef struct _PPM_UCM_CONNECTOR_CONTEXT +{ + PPPM_CONNECTOR PpmConnector; +} PPM_UCM_CONNECTOR_CONTEXT, *PPPM_UCM_CONNECTOR_CONTEXT; + +WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(PPM_UCM_CONNECTOR_CONTEXT, PpmUcmConnector_GetContext); + +EVT_WDF_IO_QUEUE_IO_INTERNAL_DEVICE_CONTROL Ppm_EvtIoInternalDeviceControl; +EVT_WDF_REQUEST_COMPLETION_ROUTINE Ppm_CommandRequestCompletionRoutine; +EVT_WDF_WORKITEM Ppm_CommandCompletionWorkItem; +EVT_PPM_COMMAND_COMPLETION_ROUTINE Ppm_EvtGetConnectorStatusCompleted; + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Ppm_WaitForResetComplete( + _In_ PPPM_CONTEXT PpmCtx +); + +_IRQL_requires_max_(DISPATCH_LEVEL) +VOID +Ppm_ProcessNotifications( + _In_ PPPM_CONTEXT PpmCtx +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Ppm_ExecuteCommand( + _In_ PPPM_CONTEXT PpmCtx, + _In_ UCSI_CONTROL Command +); + +_IRQL_requires_max_(DISPATCH_LEVEL) +VOID +Ppm_CompleteActiveRequest( + _In_ PPPM_CONTEXT PpmCtx +); + +_IRQL_requires_max_(DISPATCH_LEVEL) +VOID +Ppm_SaveMessageInContentsInRequest( + _In_ PPPM_CONTEXT PpmCtx +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Ppm_QueryConnectors( + _In_ PPPM_CONTEXT PpmCtx +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Ppm_CommandCompletionHandler( + _In_ PPPM_CONTEXT PpmCtx +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Ppm_GetCapability( + _In_ PPPM_CONTEXT PpmCtx, + _Out_ PUCSI_GET_CAPABILITY_IN Caps +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Ppm_GetConnectorCapability( + _In_ PPPM_CONTEXT PpmCtx, + _In_ CONNECTOR_INDEX ConnectorIndex, + _Out_ PUCSI_GET_CONNECTOR_CAPABILITY_IN ConnCaps +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +_Must_inspect_result_ +_Success_(return != 0) +PPPM_CONNECTOR +Ppm_AddConnector( + _In_ PPPM_CONTEXT PpmCtx +); + +_IRQL_requires_max_(DISPATCH_LEVEL) +PPPM_CONNECTOR +Ppm_GetConnector( + _In_ PPPM_CONTEXT PpmCtx, + _In_ CONNECTOR_INDEX Index +); + +_IRQL_requires_max_(DISPATCH_LEVEL) +VOID +Ppm_HandleCommandCompletionNotification( + _In_ PPPM_CONTEXT PpmCtx, + _In_ UCSI_CCI Cci +); + +_IRQL_requires_max_(DISPATCH_LEVEL) +VOID +Ppm_HandleConnectorChangeNotification( + _In_ PPPM_CONTEXT PpmCtx, + _In_ UCSI_CCI Cci +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +VOID +Ppm_ReportNegotiatedPowerLevelChanged( + _In_ PPPM_CONTEXT PpmCtx, + _In_ PPPM_CONNECTOR Connector, + _Inout_ PUCSI_GET_CONNECTOR_STATUS_IN ConnStatus, + _Inout_ PPPM_COMMAND_ACK_PARAMS CommandAckParams +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Ppm_PerformRoleCorrection( + _In_ PPPM_CONTEXT PpmCtx, + _In_ PPPM_CONNECTOR Connector +); + +_IRQL_requires_max_(DISPATCH_LEVEL) +VOID +Ppm_PrettyDebugPrintMessageIn( + _In_ PPPM_CONTEXT PpmCtx +); + + +EXTERN_C_END diff --git a/usb/UcmCxUcsi/README.md b/usb/UcmCxUcsi/README.md new file mode 100644 index 00000000..dc6b865d --- /dev/null +++ b/usb/UcmCxUcsi/README.md @@ -0,0 +1,49 @@ +# UcmTcpciCx Port Controller Client Driver + +This is a sample driver that shows how to create a Windows USB Type-C port controller driver using the USB Connector Manager class extension driver (UcmCx). The sample is a driver for an embedded controller which is complient with the [USB Type-C Connector System Software Interface (UCSI)](http://www.intel.com/content/www/us/en/io/universal-serial-bus/usb-type-c-ucsi-spec.html). + +## Background reading - UcmCx documentation + +Start at the UcmCx documentation at [USB Type-C connector driver programming reference](https://msdn.microsoft.com/en-us/library/windows/hardware/mt188011(v=vs.85).aspx). + +## Note on UCSI + +Microsoft already provides an inbox UCSI driver, UcmUcsi.sys. This UcmCxUcsi sample driver is not identical to the inbox UCSI driver. Microsoft recommends that you use the inbox UcmUcsi.sys for your UCSI-compliant system rather than writing your own. This sample driver is meant for developers bringing up a UcmCx driver for their own non-UCSI platforms. For more information about the UCSI driver, reference [USB Type-C Connector System Software Interface (UCSI) driver](https://msdn.microsoft.com/en-us/library/windows/hardware/mt710944(v=vs.85).aspx). + +This sample demonstrates the following: + +- Registration with the USB Connector Manager (UCM) class extension driver. +- Initializing the port controller's Type-C and Power Delivery capabilities. +- Performing data and power role swaps requested by UCM +- Notifying UCM of Type-C and Power Delivery events on the connector. + +## Customizing the sample for your port controller +This sample is specific to UCSI systems. You may choose to structure your driver in a similar way for your own hardware. Understand the requirements and specification of your own system prior to writing a new UcmCx client driver. In addition to making the logic and functionality suit your specific port controller hardware, you will need to modify the .inf such that it matches your device's information. + +### UcmCxUcsi structure + +In this sample, UCM-specific interactions are split apart from most of the UCSI-specific operations. + +#### UcmCx Interactions +The following files contain methods that interface with UcmCx. + +- UcmCallbacks.cpp + - Contains the implementations [EVT_UCM_CONNECTOR_SET_DATA_ROLE](https://msdn.microsoft.com/en-us/library/windows/hardware/mt187818(v=vs.85).aspx) and [EVT_UCM_CONNECTOR_SET_POWER_ROLE](https://msdn.microsoft.com/en-us/library/windows/hardware/mt187818(v=vs.85).aspx). These are callbacks from UCM which ask the client driver to perform role swaps. +- UcmNotifications.cpp + - Contains methods that communicate with UcmCx using the client driver support methods described in the [USB Type-C connector driver programming reference](https://msdn.microsoft.com/en-us/library/windows/hardware/mt188011(v=vs.85).aspx). +- Fdo.cpp + - FDO callbacks, functions, and types, most of which do not interface with UCM. However, the method `Fdo_EvtDeviceSelfManagedIoInit` contains the code segment which initializes the device with UCM. + +#### UCSI and WDF Interactions +The remainder of the files perform operations for UCSI and WDF, non-specific to UCM. + +- Acpi.cpp + - ACPI method evaluation helper routines. +- Driver.cpp + - Entry point to the driver. Initializes the driver with WDF. +- Ppm.cpp + - Type-C Platform Policy Manager. Main interface to talk to the UCSI-compliant hardware. + + +## When to write a UcmCx client driver +UcmCx is intended for system port controller drivers. If you are bringing up a USB Type-C peripheral, you do not need to write a USB Type-C specific driver; a regular USB client driver will suffice. Refer to [Developing Windows client drivers for USB devices](https://msdn.microsoft.com/en-us/library/windows/hardware/hh406260(v=vs.85).aspx) to determine what type of driver, if any, you need to write to make your USB device work with Windows. You may look at [Do I need to write a driver for my USB Type-C hardware?](https://blogs.msdn.microsoft.com/usbcoreblog/2016/06/20/do-i-need-to-write-a-driver-for-my-usb-type-c-hardware/) for a more detailed overview.
\ No newline at end of file diff --git a/usb/UcmCxUcsi/Trace.h b/usb/UcmCxUcsi/Trace.h new file mode 100644 index 00000000..a057ddae --- /dev/null +++ b/usb/UcmCxUcsi/Trace.h @@ -0,0 +1,66 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + Trace.h + +Abstract: + + WPP tracing definitions. + +Environment: + + Kernel-mode only. + +--*/ + +// +// Tracing GUID - {EAD1EE75-4BFE-4E28-8AFA-E94B0A1BAF37} +// + +#pragma once + +#define WPP_CONTROL_GUIDS \ + WPP_DEFINE_CONTROL_GUID( \ + UcsiTraceGuid, (EAD1EE75,4BFE,4E28,8AFA,E94B0A1BAF37), \ + WPP_DEFINE_BIT(TRACE_FLAG_DRIVER) \ + WPP_DEFINE_BIT(TRACE_FLAG_FDO) \ + WPP_DEFINE_BIT(TRACE_FLAG_ACPI) \ + WPP_DEFINE_BIT(TRACE_FLAG_PPM) \ + WPP_DEFINE_BIT(TRACE_FLAG_UCMCALLBACKS) \ + WPP_DEFINE_BIT(TRACE_FLAG_UCMNOTIFICATIONS) \ + ) + +#define WPP_LEVEL_FLAGS_LOGGER(lvl, flags) \ + WPP_LEVEL_LOGGER(flags) + +#define WPP_LEVEL_FLAGS_ENABLED(lvl, flags) \ + (WPP_LEVEL_ENABLED(flags) && WPP_CONTROL(WPP_BIT_ ## flags).Level >= lvl) + +// +// begin_wpp config +// +// FUNC TRACE_ERROR{LEVEL=TRACE_LEVEL_ERROR}(FLAGS, MSG,...); +// +// FUNC TRACE_WARN{LEVEL=TRACE_LEVEL_WARNING}(FLAGS, MSG, ...); +// +// FUNC TRACE_INFO{LEVEL=TRACE_LEVEL_INFORMATION}(FLAGS, MSG, ...); +// +// FUNC TRACE_VERBOSE{LEVEL=TRACE_LEVEL_VERBOSE}(FLAGS, MSG, ...); +// +// FUNC TRACE_FUNC_ENTRY{LEVEL=TRACE_LEVEL_VERBOSE}(FLAGS, ...); +// USESUFFIX(TRACE_FUNC_ENTRY, "%!FUNC! Entry"); +// +// FUNC TRACE_FUNC_EXIT{LEVEL=TRACE_LEVEL_VERBOSE}(FLAGS, ...); +// USESUFFIX(TRACE_FUNC_EXIT, "%!FUNC! Exit"); +// +// CUSTOM_TYPE(UCSI_COMMAND, ItemEnum(_UCSI_COMMAND)); +// CUSTOM_TYPE(UCSI_POWER_OPERATION_MODE, ItemEnum(_UCSI_POWER_OPERATION_MODE)); +// CUSTOM_TYPE(UCSI_POWER_DIRECTION, ItemEnum(_UCSI_POWER_DIRECTION)); +// CUSTOM_TYPE(UCSI_CONNECTOR_PARTNER_TYPE, ItemEnum(_UCSI_CONNECTOR_PARTNER_TYPE)); +// CUSTOM_TYPE(UCSI_BATTERY_CHARGING_STATUS, ItemEnum(_UCSI_BATTERY_CHARGING_STATUS)); +// +// end_wpp +//
\ No newline at end of file diff --git a/usb/UcmCxUcsi/UcmCallbacks.cpp b/usb/UcmCxUcsi/UcmCallbacks.cpp new file mode 100644 index 00000000..12d99148 --- /dev/null +++ b/usb/UcmCxUcsi/UcmCallbacks.cpp @@ -0,0 +1,156 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + UcmCallbacks.cpp + +Abstract: + + Interface for callbacks from UcmCx. + +Environment: + + Kernel-mode only. + +--*/ + +#include "Pch.h" +#include "UcmCallbacks.tmh" + +#pragma alloc_text(PAGE, Ucm_EvtConnectorSetDataRole) +#pragma alloc_text(PAGE, Ucm_EvtConnectorSetPowerRole) + +NTSTATUS +Ucm_EvtConnectorSetDataRole( + _In_ UCMCONNECTOR Connector, + _In_ UCM_DATA_ROLE DataRole +) +/*++ + +Routine Description: + + Set the power role on a given connector. This may require performing + a data role swap. + +Arguments: + + Connector - The connector on which to set the power role. + + DataRole - The data role to set on the connector. + +Returns: + + NTSTATUS + +--*/ +{ + NTSTATUS status; + WDFDEVICE device; + PPPM_CONNECTOR connector; + PPPM_CONTEXT ppmCtx; + UCSI_USB_OPERATION_ROLE role; + UCSI_CONTROL cmd; + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_UCMCALLBACKS); + + connector = PpmUcmConnector_GetContext(Connector)->PpmConnector; + device = connector->WdfDevice; + ppmCtx = &Fdo_GetContext(device)->PpmCtx; + + TRACE_INFO(TRACE_FLAG_UCMCALLBACKS, "[Device: 0x%p] Data role change to %!UCM_DATA_ROLE! requested", device, DataRole); + + if (!Convert(DataRole, role)) + { + status = STATUS_INVALID_PARAMETER; + TRACE_ERROR(TRACE_FLAG_UCMCALLBACKS, "[Device: 0x%p] Invalid data role requested %!UCM_DATA_ROLE!", device, DataRole); + goto Exit; + } + + cmd.AsUInt64 = 0; + cmd.Command = UcsiCommandSetUor; + cmd.SetUor.ConnectorNumber = connector->Index; + cmd.SetUor.UsbOperationRole = role; + + status = Ppm_SendCommand(ppmCtx, cmd, Ucm_EvtSetDataRoleCompleted, ppmCtx); + if (!NT_SUCCESS(status)) + { + goto Exit; + } + +Exit: + + TRACE_FUNC_EXIT(TRACE_FLAG_UCMCALLBACKS); + + return status; +} + + +NTSTATUS +Ucm_EvtConnectorSetPowerRole( + _In_ UCMCONNECTOR Connector, + _In_ UCM_POWER_ROLE PowerRole +) +/*++ + +Routine Description: + + Set the power role on a given connector. This may require performing + a power role swap. + +Arguments: + + Connector - The connector on which to set the power role. + + PowerRole - The power role to set on the connector. + +Returns: + + NTSTATUS + +--*/ +{ + NTSTATUS status; + WDFDEVICE device; + PPPM_CONNECTOR connector; + PPPM_CONTEXT ppmCtx; + UCSI_POWER_DIRECTION_ROLE role; + UCSI_CONTROL cmd; + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_UCMCALLBACKS); + + connector = PpmUcmConnector_GetContext(Connector)->PpmConnector; + device = connector->WdfDevice; + ppmCtx = &Fdo_GetContext(device)->PpmCtx; + + TRACE_INFO(TRACE_FLAG_UCMCALLBACKS, "[Device: 0x%p] Power role change to %!UCM_POWER_ROLE! requested", device, PowerRole); + + if (!Convert(PowerRole, role)) + { + status = STATUS_INVALID_PARAMETER; + TRACE_ERROR(TRACE_FLAG_UCMCALLBACKS, "[Device: 0x%p] Invalid power role requested %!UCM_POWER_ROLE!", device, PowerRole); + goto Exit; + } + + cmd.AsUInt64 = 0; + cmd.Command = UcsiCommandSetPdr; + cmd.SetPdr.ConnectorNumber = connector->Index; + cmd.SetPdr.PowerDirectionRole = role; + + status = Ppm_SendCommand(ppmCtx, cmd, Ucm_EvtSetPowerRoleCompleted, ppmCtx); + if (!NT_SUCCESS(status)) + { + goto Exit; + } + +Exit: + + TRACE_FUNC_EXIT(TRACE_FLAG_UCMCALLBACKS); + + return status; +}
\ No newline at end of file diff --git a/usb/UcmCxUcsi/UcmCallbacks.h b/usb/UcmCxUcsi/UcmCallbacks.h new file mode 100644 index 00000000..2bc83358 --- /dev/null +++ b/usb/UcmCxUcsi/UcmCallbacks.h @@ -0,0 +1,26 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + UcmCallbacks.h + +Abstract: + + Type-C Platform Policy Manager. Interface for callbacks from UcmCx. + +Environment: + + Kernel-mode only. + +--*/ + +#pragma once + +EXTERN_C_START + +EVT_UCM_CONNECTOR_SET_DATA_ROLE Ucm_EvtConnectorSetDataRole; +EVT_UCM_CONNECTOR_SET_POWER_ROLE Ucm_EvtConnectorSetPowerRole; + +EXTERN_C_END
\ No newline at end of file diff --git a/usb/UcmCxUcsi/UcmCxUcsi.inf b/usb/UcmCxUcsi/UcmCxUcsi.inf Binary files differnew file mode 100644 index 00000000..604f04ba --- /dev/null +++ b/usb/UcmCxUcsi/UcmCxUcsi.inf diff --git a/usb/UcmCxUcsi/UcmCxUcsi.sln b/usb/UcmCxUcsi/UcmCxUcsi.sln new file mode 100644 index 00000000..9dcd0985 --- /dev/null +++ b/usb/UcmCxUcsi/UcmCxUcsi.sln @@ -0,0 +1,48 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25123.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UcmCxUcsi", "UcmCxUcsi.vcxproj", "{B19576FD-D35C-475C-BFDB-0E4D1BE3F80F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|ARM = Debug|ARM + Debug|ARM64 = Debug|ARM64 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|ARM = Release|ARM + Release|ARM64 = Release|ARM64 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B19576FD-D35C-475C-BFDB-0E4D1BE3F80F}.Debug|ARM.ActiveCfg = Debug|ARM + {B19576FD-D35C-475C-BFDB-0E4D1BE3F80F}.Debug|ARM.Build.0 = Debug|ARM + {B19576FD-D35C-475C-BFDB-0E4D1BE3F80F}.Debug|ARM.Deploy.0 = Debug|ARM + {B19576FD-D35C-475C-BFDB-0E4D1BE3F80F}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {B19576FD-D35C-475C-BFDB-0E4D1BE3F80F}.Debug|ARM64.Build.0 = Debug|ARM64 + {B19576FD-D35C-475C-BFDB-0E4D1BE3F80F}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {B19576FD-D35C-475C-BFDB-0E4D1BE3F80F}.Debug|x64.ActiveCfg = Debug|x64 + {B19576FD-D35C-475C-BFDB-0E4D1BE3F80F}.Debug|x64.Build.0 = Debug|x64 + {B19576FD-D35C-475C-BFDB-0E4D1BE3F80F}.Debug|x64.Deploy.0 = Debug|x64 + {B19576FD-D35C-475C-BFDB-0E4D1BE3F80F}.Debug|x86.ActiveCfg = Debug|Win32 + {B19576FD-D35C-475C-BFDB-0E4D1BE3F80F}.Debug|x86.Build.0 = Debug|Win32 + {B19576FD-D35C-475C-BFDB-0E4D1BE3F80F}.Debug|x86.Deploy.0 = Debug|Win32 + {B19576FD-D35C-475C-BFDB-0E4D1BE3F80F}.Release|ARM.ActiveCfg = Release|ARM + {B19576FD-D35C-475C-BFDB-0E4D1BE3F80F}.Release|ARM.Build.0 = Release|ARM + {B19576FD-D35C-475C-BFDB-0E4D1BE3F80F}.Release|ARM.Deploy.0 = Release|ARM + {B19576FD-D35C-475C-BFDB-0E4D1BE3F80F}.Release|ARM64.ActiveCfg = Release|ARM64 + {B19576FD-D35C-475C-BFDB-0E4D1BE3F80F}.Release|ARM64.Build.0 = Release|ARM64 + {B19576FD-D35C-475C-BFDB-0E4D1BE3F80F}.Release|ARM64.Deploy.0 = Release|ARM64 + {B19576FD-D35C-475C-BFDB-0E4D1BE3F80F}.Release|x64.ActiveCfg = Release|x64 + {B19576FD-D35C-475C-BFDB-0E4D1BE3F80F}.Release|x64.Build.0 = Release|x64 + {B19576FD-D35C-475C-BFDB-0E4D1BE3F80F}.Release|x64.Deploy.0 = Release|x64 + {B19576FD-D35C-475C-BFDB-0E4D1BE3F80F}.Release|x86.ActiveCfg = Release|Win32 + {B19576FD-D35C-475C-BFDB-0E4D1BE3F80F}.Release|x86.Build.0 = Release|Win32 + {B19576FD-D35C-475C-BFDB-0E4D1BE3F80F}.Release|x86.Deploy.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/usb/UcmCxUcsi/UcmCxUcsi.vcxproj b/usb/UcmCxUcsi/UcmCxUcsi.vcxproj new file mode 100644 index 00000000..6a028bd4 --- /dev/null +++ b/usb/UcmCxUcsi/UcmCxUcsi.vcxproj @@ -0,0 +1,131 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{B19576FD-D35C-475C-BFDB-0E4D1BE3F80F}</ProjectGuid> + <TemplateGuid>{1bc93793-694f-48fe-9372-81e2b05556fd}</TemplateGuid> + <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> + <MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion> + <Configuration>Debug</Configuration> + <Platform Condition="'$(Platform)' == ''">Win32</Platform> + <RootNamespace>UcmCxUcsi</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> + <ConfigurationType>Driver</ConfigurationType> + <DriverType>KMDF</DriverType> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + <UcmDriver>true</UcmDriver> + <UCM_VERSION_MAJOR>1</UCM_VERSION_MAJOR> + <UCM_VERSION_MINOR>0</UCM_VERSION_MINOR> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'"> + <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'"> + <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'"> + <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'"> + <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor> + </PropertyGroup> + <ItemDefinitionGroup> + <ClCompile> + <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> + <WppEnabled>true</WppEnabled> + <WppRecorderEnabled>true</WppRecorderEnabled> + <WppScanConfigurationData>trace.h</WppScanConfigurationData> + <WppAlternateConfigurationFile> + </WppAlternateConfigurationFile> + <WppAdditionalOptions>-scan:"$(UCM_INC_PATH)\$(UCM_VER_PATH)\UcmTraceEnums.h" -scan:"$(KMDF_INC_PATH)\$(KMDF_VER_PATH)\wdftraceenums.h" %(WppAdditionalOptions)</WppAdditionalOptions> + </ClCompile> + </ItemDefinitionGroup> + <ItemGroup> + <Inf Include="UcmCxUcsi.inf" /> + </ItemGroup> + <ItemGroup> + <FilesToPackage Include="$(TargetPath)" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="Acpi.cpp" /> + <ClCompile Include="Driver.cpp" /> + <ClCompile Include="Fdo.cpp" /> + <ClCompile Include="Ppm.cpp" /> + <ClCompile Include="UcmCallbacks.cpp" /> + <ClCompile Include="UcmNotifications.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="Acpi.h" /> + <ClInclude Include="Driver.h" /> + <ClInclude Include="Fdo.h" /> + <ClInclude Include="Pch.h" /> + <ClInclude Include="Ppm.h" /> + <ClInclude Include="Trace.h" /> + <ClInclude Include="UcmCallbacks.h" /> + <ClInclude Include="UcmNotifications.h" /> + <ClInclude Include="Ucsi.h" /> + <ClInclude Include="UcsiInterface.h" /> + <ClInclude Include="UcsiUcmConvert.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/usb/UcmCxUcsi/UcmCxUcsi.vcxproj.Filters b/usb/UcmCxUcsi/UcmCxUcsi.vcxproj.Filters new file mode 100644 index 00000000..de404493 --- /dev/null +++ b/usb/UcmCxUcsi/UcmCxUcsi.vcxproj.Filters @@ -0,0 +1,81 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + <Filter Include="Driver Files"> + <UniqueIdentifier>{8E41214B-6785-4CFE-B992-037D68949A14}</UniqueIdentifier> + <Extensions>inf;inv;inx;mof;mc;</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <Inf Include="UcmCxUcsi.inf"> + <Filter>Driver Files</Filter> + </Inf> + </ItemGroup> + <ItemGroup> + <ClCompile Include="Acpi.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Driver.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Fdo.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Ppm.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="UcmCallbacks.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="UcmNotifications.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="Trace.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="UcsiUcmConvert.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Acpi.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Driver.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Fdo.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Ppm.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Pch.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Ucsi.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="UcsiInterface.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="UcmCallbacks.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="UcmNotifications.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/usb/UcmCxUcsi/UcmNotifications.cpp b/usb/UcmCxUcsi/UcmNotifications.cpp new file mode 100644 index 00000000..babed947 --- /dev/null +++ b/usb/UcmCxUcsi/UcmNotifications.cpp @@ -0,0 +1,909 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + UcmNotifications.cpp + +Abstract: + + Type-C Platform Policy Manager. Interface to notify UcmCx of events. + +Environment: + +Kernel-mode only. + +--*/ + +#include "Pch.h" +#include "UcmNotifications.tmh" + +#pragma alloc_text(PAGE, Ucm_CreateConnectors) +#pragma alloc_text(PAGE, Ucm_EvtGetPdosCompleted) +#pragma alloc_text(PAGE, Ucm_EvtSetDataRoleCompleted) +#pragma alloc_text(PAGE, Ucm_EvtSetPowerRoleCompleted) +#pragma alloc_text(PAGE, Ucm_ReportTypeCAttach) +#pragma alloc_text(PAGE, Ucm_ReportTypeCDetach) +#pragma alloc_text(PAGE, Ucm_ReportPowerOperationMode) +#pragma alloc_text(PAGE, Ucm_ReportPowerDirectionChanged) +#pragma alloc_text(PAGE, Ucm_ReportDataDirectionChanged) +#pragma alloc_text(PAGE, Ucm_ReportChargingStatusChanged) + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Ucm_CreateConnectors ( + _In_ PPPM_CONTEXT PpmCtx +) +/*++ + +Routine Description: + + Create connector objects and register them with UCM. + +Arguments: + + PpmCtx - Platform policy manager context object. + +--*/ +{ + NTSTATUS status; + WDFDEVICE device; + UCSI_GET_CAPABILITY_IN caps; + UCSI_GET_CONNECTOR_CAPABILITY_IN connCaps; + UCM_CONNECTOR_CONFIG connConfig; + UCM_CONNECTOR_TYPEC_CONFIG typeCConfig; + UCM_CONNECTOR_PD_CONFIG pdConfig; + ULONG supportedOperatingModes; + ULONG supportedPowerSourcingCapabilities; + ULONG supportedPdPowerRoles; + PPPM_CONNECTOR connector; + ULONG connectorCount; + WDF_OBJECT_ATTRIBUTES attributes; + PPPM_UCM_CONNECTOR_CONTEXT connectorCtx; + CONNECTOR_INDEX i; + + UNREFERENCED_PARAMETER(PpmCtx); + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_UCMNOTIFICATIONS); + + device = Context_GetWdfDevice(PpmCtx); + + status = Ppm_GetCapability(PpmCtx, &caps); + if (!NT_SUCCESS(status)) + { + goto Exit; + } + + TRACE_INFO(TRACE_FLAG_UCMNOTIFICATIONS, "[Device: 0x%p] PPM optional features: 0x%x", device, caps.OptionalFeatures); + + connectorCount = WdfCollectionGetCount(PpmCtx->Connectors); + if (connectorCount != caps.bNumConnectors) + { + status = STATUS_DEVICE_PROTOCOL_ERROR; + TRACE_ERROR(TRACE_FLAG_UCMNOTIFICATIONS, "[Device: 0x%p] Connector count mismatch. ACPI reported %lu, UCSI reported %lu", device, connectorCount, caps.bNumConnectors); + goto Exit; + } + + for (i = 1; i <= connectorCount; ++i) + { + status = Ppm_GetConnectorCapability(PpmCtx, i, &connCaps); + if (!NT_SUCCESS(status)) + { + goto Exit; + } + + connector = Ppm_GetConnector(PpmCtx, i); + + supportedOperatingModes = (connCaps.OperationMode.DfpOnly ? UcmTypeCOperatingModeDfp : 0) | + (connCaps.OperationMode.UfpOnly ? UcmTypeCOperatingModeUfp : 0) | + (connCaps.OperationMode.Drp ? UcmTypeCOperatingModeDrp : 0); + + if (connCaps.Provider) + { + supportedPowerSourcingCapabilities = UcmTypeCCurrentDefaultUsb | + UcmTypeCCurrent1500mA | + UcmTypeCCurrent3000mA; + } + else + { + supportedPowerSourcingCapabilities = 0; + } + + // + // Assemble the Type-C and PD configuration for UCM. + // + + UCM_CONNECTOR_CONFIG_INIT(&connConfig, connector->Id); + + UCM_CONNECTOR_TYPEC_CONFIG_INIT(&typeCConfig, + supportedOperatingModes, + supportedPowerSourcingCapabilities); + + typeCConfig.EvtSetDataRole = Ucm_EvtConnectorSetDataRole; + typeCConfig.AudioAccessoryCapable = connCaps.OperationMode.AudioAccessoryMode; + + supportedPdPowerRoles = (connCaps.Provider ? UcmPowerRoleSource : 0) | + (connCaps.Consumer ? UcmPowerRoleSink : 0); + + UCM_CONNECTOR_PD_CONFIG_INIT(&pdConfig, supportedPdPowerRoles); + + pdConfig.EvtSetPowerRole = Ucm_EvtConnectorSetPowerRole; + + connConfig.TypeCConfig = &typeCConfig; + connConfig.PdConfig = &pdConfig; + + WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, PPM_UCM_CONNECTOR_CONTEXT); + + // + // Create the UCM connector object. + // + + status = UcmConnectorCreate(device, &connConfig, &attributes, &connector->Handle); + if (!NT_SUCCESS(status)) + { + TRACE_ERROR(TRACE_FLAG_UCMNOTIFICATIONS, "[Device: 0x%p] UcmConnectorCreate failed - %!STATUS!", device, status); + goto Exit; + } + + connectorCtx = PpmUcmConnector_GetContext(connector->Handle); + connectorCtx->PpmConnector = connector; + } + +Exit: + + TRACE_FUNC_EXIT(TRACE_FLAG_UCMNOTIFICATIONS); + + return status; +} + + +VOID +Ucm_EvtGetPdosCompleted ( + _In_ UCSI_CONTROL Command, + _In_ PVOID Context, + _Inout_ PPPM_COMMAND_ACK_PARAMS CommandAckParams +) +/*++ + +Routine Description: + + GetPdos command completion routine. Notifies UCM of new source capabilities and PD contract. + +Arguments: + + Command - The UCSI command that was completed. In this case, it should only be UcsiCommandGetPdos. + + Context - Platform policy manager context object. + + CommandAckParams - UCSI command acknowledge parameters. + +--*/ +{ + WDFDEVICE device; + PPPM_CONTEXT ppmCtx; + PUCSI_GET_PDOS_IN pdos; + UCHAR pdoCount; + UINT8 pdoOffset; + UCSI_CONTROL newCmd; + PPPM_CONNECTOR connector; + UCM_CONNECTOR_PD_CONN_STATE_CHANGED_PARAMS connParams; + bool forPartner; + NTSTATUS status; + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_UCMNOTIFICATIONS); + + ppmCtx = (PPPM_CONTEXT)Context; + device = Context_GetWdfDevice(ppmCtx); + + NT_ASSERT(Command.Command == UcsiCommandGetPdos); + + // + // This GetPdos command was sent in response to a change in the PD contract. So we + // need to acknowledge the connector change that we know is pending. + // + + CommandAckParams->AckConnectorChange = TRUE; + + if (!UCSI_CMD_SUCCEEDED(ppmCtx->UcsiDataBlock->CCI)) + { + // + // The command failed. Acknowledge the connector change and move on. + // + + goto Exit; + } + + pdos = &ppmCtx->UcsiDataBlock->MessageIn.Pdos; + pdoOffset = Command.GetPdos.PdoOffset; + pdoCount = (UCHAR)(ppmCtx->UcsiDataBlock->CCI.DataLength / sizeof(pdos->Pdos[0])); + connector = Ppm_GetConnector(ppmCtx, Command.GetPdos.ConnectorNumber); + forPartner = (Command.GetPdos.PartnerPdo == 1); + + if (pdoCount == 0) + { + if (forPartner) + { + TRACE_ERROR(TRACE_FLAG_UCMNOTIFICATIONS, "[Device: 0x%p] Port partner of connector ID 0x%I64x returned zero source PDOs", device, connector->Id); + } + else + { + TRACE_ERROR(TRACE_FLAG_UCMNOTIFICATIONS, "[Device: 0x%p] Connector ID 0x%I64x returned zero source PDOs", device, connector->Id); + } + + goto Exit; + } + + NT_ASSERT_ASSUME(pdoCount <= MAX_MESSAGE_IN_PDOS); + + if (pdoOffset >= ARRAYSIZE(ppmCtx->ConnectorChangeCtx.Pdos)) + { + TRACE_ERROR(TRACE_FLAG_UCMNOTIFICATIONS, "[Device: 0x%p] Invalid offset (%u) used in %!UCSI_COMMAND! command on connector ID 0x%I64x", device, pdoOffset, Command.Command, connector->Id); + status = STATUS_INVALID_PARAMETER; + goto Exit; + } + + RtlCopyMemory(&ppmCtx->ConnectorChangeCtx.Pdos[pdoOffset], pdos->Pdos, pdoCount * sizeof(pdos->Pdos[0])); + ppmCtx->ConnectorChangeCtx.PdoCount = pdoOffset + pdoCount; + + // + // Check to see if there might be more PDOs to retrieve. If so, don't acknowledge the connector + // change just yet, and send the command again to fetch the remaining PDOs. + // + // If we got 4 PDOs in this batch (the maximum we can retrieve at once), and the total number of + // PDOs we have received so far is less than 7 (the maximum allowed by the PD spec), there may + // be more PDOs to retrieve. + // + + if ((pdoCount == MAX_MESSAGE_IN_PDOS) && (ppmCtx->ConnectorChangeCtx.PdoCount < MAX_PDO_COUNT)) + { + newCmd = Command; + newCmd.GetPdos.PdoOffset = ppmCtx->ConnectorChangeCtx.PdoCount; + + status = Ppm_SendCommand(ppmCtx, newCmd, Ucm_EvtGetPdosCompleted, ppmCtx); + if (!NT_SUCCESS(status)) + { + goto Exit; + } + + CommandAckParams->AckConnectorChange = FALSE; + goto Exit; + } + + if (forPartner) + { + // + // Notify UCM of the partner's source capabilities. + // + + TRACE_INFO(TRACE_FLAG_UCMNOTIFICATIONS, "[Device: 0x%p] Reporting PD port partner source caps on connector ID 0x%I64x", device, connector->Id); + status = UcmConnectorPdPartnerSourceCaps(connector->Handle, + ppmCtx->ConnectorChangeCtx.Pdos, + ppmCtx->ConnectorChangeCtx.PdoCount); + if (!NT_SUCCESS(status)) + { + TRACE_ERROR(TRACE_FLAG_UCMNOTIFICATIONS, "[Device: 0x%p] UcmConnectorPdPartnerSourceCaps for connector ID 0x%I64x failed - %!STATUS!", device, connector->Id, status); + goto Exit; + } + } + else + { + // + // Notify UCM of our own source capabilities. + // + + TRACE_INFO(TRACE_FLAG_UCMNOTIFICATIONS, "[Device: 0x%p] Reporting PD source caps on connector ID 0x%I64x", device, connector->Id); + status = UcmConnectorPdSourceCaps(connector->Handle, + ppmCtx->ConnectorChangeCtx.Pdos, + ppmCtx->ConnectorChangeCtx.PdoCount); + if (!NT_SUCCESS(status)) + { + TRACE_ERROR(TRACE_FLAG_UCMNOTIFICATIONS, "[Device: 0x%p] UcmConnectorPdSourceCaps for connector ID 0x%I64x failed - %!STATUS!", device, connector->Id, status); + goto Exit; + } + } + + UCM_CONNECTOR_PD_CONN_STATE_CHANGED_PARAMS_INIT(&connParams, + UcmPdConnStateNegotiationSucceeded); + + if (forPartner) + { + connParams.ChargingState = ppmCtx->ConnectorChangeCtx.ChargingState; + } + connParams.Rdo = ppmCtx->ConnectorChangeCtx.Rdo; + + // + // Notify UCM that the PD connection state has changed on a certain connector. + // + + TRACE_INFO(TRACE_FLAG_UCMNOTIFICATIONS, "[Device: 0x%p] Reporting PD connection state change on connector ID 0x%I64x", device, connector->Id); + + status = UcmConnectorPdConnectionStateChanged(connector->Handle, &connParams); + if (!NT_SUCCESS(status)) + { + TRACE_ERROR(TRACE_FLAG_UCMNOTIFICATIONS, "[Device: 0x%p] UcmConnectorPdConnectionStateChanged for connector ID 0x%I64x failed - %!STATUS!", device, connector->Id, status); + goto Exit; + } + + // + // A PD contract has been established at this point. Perform role correction if necessary. + // + + if (connector->PerformRoleCorrectionOnNextPdContract) + { + connector->PerformRoleCorrectionOnNextPdContract = FALSE; + status = Ppm_PerformRoleCorrection(ppmCtx, connector); + if (!NT_SUCCESS(status)) + { + goto Exit; + } + } + +Exit: + + TRACE_FUNC_EXIT(TRACE_FLAG_UCMNOTIFICATIONS); +} + + +VOID +Ucm_EvtSetPowerRoleCompleted ( + _In_ UCSI_CONTROL Command, + _In_ PVOID Context, + _Inout_ PPPM_COMMAND_ACK_PARAMS CommandAckParams +) +/*++ + +Routine Description: + + Set power role command completion routine. Notifies UCM that the power direction has changed. + +Arguments: + + Command - The UCSI command that was completed. In this case, it should be only SetPdr.PowerDirectionRole. + + Context - Platform policy manager context object. + + CommandAckParams - UCSI command acknowledge parameters. + +--*/ +{ + UCM_POWER_ROLE powerRole; + PPPM_CONTEXT ppmCtx; + WDFDEVICE device; + PPPM_CONNECTOR connector; + BOOLEAN success; + + UNREFERENCED_PARAMETER(CommandAckParams); + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_UCMNOTIFICATIONS); + + ppmCtx = (PPPM_CONTEXT)Context; + device = Context_GetWdfDevice(ppmCtx); + connector = Ppm_GetConnector(ppmCtx, Command.SetPdr.ConnectorNumber); + + NT_VERIFY(Convert((UCSI_POWER_DIRECTION_ROLE)Command.SetPdr.PowerDirectionRole, powerRole)); + + success = UCSI_CMD_SUCCEEDED(ppmCtx->UcsiDataBlock->CCI); + + if (success) + { + TRACE_INFO(TRACE_FLAG_UCMNOTIFICATIONS, "[Device: 0x%p] Power role successfully changed to %!UCM_POWER_ROLE!", device, powerRole); + } + else + { + TRACE_ERROR(TRACE_FLAG_UCMNOTIFICATIONS, "[Device: 0x%p] Power role change to %!UCM_POWER_ROLE! failed", device, powerRole); + } + + // + // Notify UCM that the power direction has changed. + // + + UcmConnectorPowerDirectionChanged(connector->Handle, success, powerRole); + + TRACE_FUNC_EXIT(TRACE_FLAG_UCMNOTIFICATIONS); +} + + +VOID +Ucm_EvtSetDataRoleCompleted ( + _In_ UCSI_CONTROL Command, + _In_ PVOID Context, + _Inout_ PPPM_COMMAND_ACK_PARAMS CommandAckParams +) +/*++ + +Routine Description: + + Set data role command completion routine. Notifies UCM that the power direction has changed. + +Arguments: + + Command - The UCSI command that was completed. In this case, it should be only SetUor.UsbOperationRole. + + Context - Platform policy manager context object. + + CommandAckParams - UCSI command acknowledge parameters. + +--*/ +{ + UCM_DATA_ROLE dataRole; + PPPM_CONTEXT ppmCtx; + WDFDEVICE device; + PPPM_CONNECTOR connector; + BOOLEAN success; + + UNREFERENCED_PARAMETER(CommandAckParams); + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_UCMNOTIFICATIONS); + + ppmCtx = (PPPM_CONTEXT)Context; + device = Context_GetWdfDevice(ppmCtx); + connector = Ppm_GetConnector(ppmCtx, Command.SetUor.ConnectorNumber); + + NT_VERIFY(Convert((UCSI_USB_OPERATION_ROLE)Command.SetUor.UsbOperationRole, dataRole)); + + success = UCSI_CMD_SUCCEEDED(ppmCtx->UcsiDataBlock->CCI); + + if (success) + { + TRACE_INFO(TRACE_FLAG_UCMNOTIFICATIONS, "[Device: 0x%p] Data role successfully changed to %!UCM_DATA_ROLE!", device, dataRole); + } + else + { + TRACE_ERROR(TRACE_FLAG_UCMNOTIFICATIONS, "[Device: 0x%p] Data role change to %!UCM_DATA_ROLE! failed", device, dataRole); + } + + // + // Notify UCM that the data direction has changed. + // + + UcmConnectorDataDirectionChanged(connector->Handle, success, dataRole); + + TRACE_FUNC_EXIT(TRACE_FLAG_UCMNOTIFICATIONS); +} + + +_IRQL_requires_max_(PASSIVE_LEVEL) +VOID +Ucm_ReportPowerOperationMode ( + _In_ PPPM_CONTEXT PpmCtx, + _In_ PPPM_CONNECTOR Connector, + _Inout_ PUCSI_GET_CONNECTOR_STATUS_IN ConnStatus, + _Inout_ PPPM_COMMAND_ACK_PARAMS CommandAckParams +) +/*++ + +Routine Description: + + Report power information to UCM. + +Arguments: + + PpmCtx - Platform policy manager context object. + + Connector - The connector for which to report the mode. + + ConnStatus - The connector status for the given connector. + + CommandAckParams - UCSI command acknowledge parameters. + +--*/ +{ + WDFDEVICE device; + NTSTATUS status; + UCM_TYPEC_CURRENT currentAd; + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_UCMNOTIFICATIONS); + + device = Context_GetWdfDevice(PpmCtx); + + if (ConnStatus->PowerOperationMode == UcsiPowerOperationModePd) + { + Ppm_ReportNegotiatedPowerLevelChanged(PpmCtx, Connector, ConnStatus, CommandAckParams); + + goto Exit; + } + + // + // The other cases indicate a change in Type-C current advertisement. + // + if (!Convert((UCSI_POWER_OPERATION_MODE)ConnStatus->PowerOperationMode, currentAd)) + { + TRACE_ERROR(TRACE_FLAG_UCMNOTIFICATIONS, "[Device: 0x%p] Invalid power operation mode %u", device, ConnStatus->PowerOperationMode); + goto Exit; + } + + TRACE_INFO(TRACE_FLAG_UCMNOTIFICATIONS, "[Device: 0x%p] Reporting Type-C current advertisement change on connector ID 0x%I64x", device, Connector->Id); + + // + // Notify UCM that the Type-C current advertisement has changed. + // + + status = UcmConnectorTypeCCurrentAdChanged(Connector->Handle, currentAd); + if (!NT_SUCCESS(status)) + { + TRACE_ERROR(TRACE_FLAG_UCMNOTIFICATIONS, "[Device: 0x%p] UcmConnectorTypeCCurrentAdChanged for connector 0x%I64x failed - %!STATUS!", device, Connector->Id, status); + goto Exit; + } + + ConnStatus->ConnectorStatusChange.PowerOperationModeChange = 0; + +Exit: + + TRACE_FUNC_EXIT(TRACE_FLAG_UCMNOTIFICATIONS); +} + + +_IRQL_requires_max_(PASSIVE_LEVEL) +VOID +Ucm_ReportTypeCAttach ( + _In_ PPPM_CONTEXT PpmCtx, + _In_ PPPM_CONNECTOR Connector, + _Inout_ PUCSI_GET_CONNECTOR_STATUS_IN ConnStatus, + _Inout_ PPPM_COMMAND_ACK_PARAMS CommandAckParams +) +/*++ + +Routine Description: + + Report a Type-C attach event to UCM. + +Arguments: + + PpmCtx - Platform policy manager context object. + + Connector - The connector for which to report the attach. + + ConnStatus - The connector status for the given connector. + + CommandAckParams - UCSI command acknowledge parameters. + +--*/ +{ + WDFDEVICE device; + NTSTATUS status; + UCM_CONNECTOR_TYPEC_ATTACH_PARAMS typeCParams; + UCM_TYPEC_PARTNER partner; + + UNREFERENCED_PARAMETER(CommandAckParams); + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_UCMNOTIFICATIONS); + + device = Context_GetWdfDevice(PpmCtx); + + TRACE_INFO(TRACE_FLAG_UCMNOTIFICATIONS, "[Device: 0x%p] Reporting Type-C attach on connector ID 0x%I64x", device, Connector->Id); + + if (!Convert((UCSI_CONNECTOR_PARTNER_TYPE)ConnStatus->ConnectorPartnerType, partner)) + { + TRACE_ERROR(TRACE_FLAG_UCMNOTIFICATIONS, "[Device: 0x%p] Invalid connector partner type %u", device, ConnStatus->ConnectorPartnerType); + goto Exit; + } + + UCM_CONNECTOR_TYPEC_ATTACH_PARAMS_INIT(&typeCParams, partner); + + if (ConnStatus->PowerDirection == UcsiPowerDirectionConsumer) + { + if (!Convert((UCSI_BATTERY_CHARGING_STATUS)ConnStatus->BatteryChargingStatus, + typeCParams.ChargingState)) + { + TRACE_ERROR(TRACE_FLAG_UCMNOTIFICATIONS, "[Device: 0x%p] Invalid battery charging state %u", device, ConnStatus->BatteryChargingStatus); + goto Exit; + } + } + + // + // N.B. Even in the case of PD, convert the power operation mode to the some Type-C + // current advertisement. UCSI has no way of telling us the Type-C advertisement when + // there is a PD connection, and the PD spec has certain rules around what that + // advertisement should be. Since we don't have that information from UCSI, + // we simply assume the current level is 3.0A in the PD case. + // + + if (!Convert((UCSI_POWER_OPERATION_MODE)ConnStatus->PowerOperationMode, + typeCParams.CurrentAdvertisement)) + { + TRACE_ERROR(TRACE_FLAG_UCMNOTIFICATIONS, "[Device: 0x%p] Invalid connector power operation mode %u", device, ConnStatus->PowerOperationMode); + goto Exit; + } + + // + // Notify UCM that we have detected an attach event on the connector. + // + + status = UcmConnectorTypeCAttach(Connector->Handle, &typeCParams); + if (!NT_SUCCESS(status)) + { + TRACE_ERROR(TRACE_FLAG_UCMNOTIFICATIONS, "[Device: 0x%p] UcmConnectorTypeCAttach failed - %!STATUS!", device, status); + goto Exit; + } + + // + // Clear all the bits for information we may have processed here. + // + + ConnStatus->ConnectorStatusChange.ConnectChange = 0; + ConnStatus->ConnectorStatusChange.ConnectorPartnerChange = 0; + ConnStatus->ConnectorStatusChange.BatteryChargingStatusChange = 0; + ConnStatus->ConnectorStatusChange.PowerOperationModeChange = 0; + + if (!PpmCtx->IsUsbDeviceControllerEnabled && (partner == UcmTypeCPartnerDfp)) + { + Connector->PerformRoleCorrectionOnNextPdContract = TRUE; + } + else + { + Connector->PerformRoleCorrectionOnNextPdContract = FALSE; + } + +Exit: + + TRACE_FUNC_EXIT(TRACE_FLAG_UCMNOTIFICATIONS); +} + + +_IRQL_requires_max_(PASSIVE_LEVEL) +VOID +Ucm_ReportTypeCDetach ( + _In_ PPPM_CONTEXT PpmCtx, + _In_ PPPM_CONNECTOR Connector, + _Inout_ PUCSI_GET_CONNECTOR_STATUS_IN ConnStatus, + _Inout_ PPPM_COMMAND_ACK_PARAMS CommandAckParams +) +/*++ + +Routine Description: + + Report a Type-C detach event to UCM. + +Arguments: + + PpmCtx - Platform policy manager context object. + + Connector - The connector for which to report the detach. + + ConnStatus - The connector status for the given connector. + + CommandAckParams - UCSI command acknowledge parameters. + +--*/ +{ + WDFDEVICE device; + NTSTATUS status; + + UNREFERENCED_PARAMETER(ConnStatus); + UNREFERENCED_PARAMETER(CommandAckParams); + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_UCMNOTIFICATIONS); + + device = Context_GetWdfDevice(PpmCtx); + + TRACE_INFO(TRACE_FLAG_UCMNOTIFICATIONS, "[Device: 0x%p] Reporting Type-C detach on connector ID 0x%I64x", device, Connector->Id); + + // + // Notify UCM that we have detected a detach event on the connector. + // + + status = UcmConnectorTypeCDetach(Connector->Handle); + if (!NT_SUCCESS(status)) + { + TRACE_ERROR(TRACE_FLAG_UCMNOTIFICATIONS, "[Device: 0x%p] UcmConnectorTypeCDetach failed - %!STATUS!", device, status); + goto Exit; + } + +Exit: + + TRACE_FUNC_EXIT(TRACE_FLAG_UCMNOTIFICATIONS); +} + + +_IRQL_requires_max_(PASSIVE_LEVEL) +VOID +Ucm_ReportPowerDirectionChanged ( + _In_ PPPM_CONTEXT PpmCtx, + _In_ PPPM_CONNECTOR Connector, + _Inout_ PUCSI_GET_CONNECTOR_STATUS_IN ConnStatus, + _Inout_ PPPM_COMMAND_ACK_PARAMS CommandAckParams +) +/*++ + +Routine Description: + + Report to UCM that the power direction has changed. This may be called + after a role swap completes. + +Arguments: + + PpmCtx - Platform policy manager context object. + + Connector - The connector for which to report the power direction change. + + ConnStatus - The connector status for the given connector. + + CommandAckParams - UCSI command acknowledge parameters. + +--*/ +{ + WDFDEVICE device; + UCM_POWER_ROLE powerRole; + + UNREFERENCED_PARAMETER(CommandAckParams); + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_UCMNOTIFICATIONS); + + device = Context_GetWdfDevice(PpmCtx); + + if (!Convert((UCSI_POWER_DIRECTION)ConnStatus->PowerDirection, powerRole)) + { + TRACE_ERROR(TRACE_FLAG_UCMNOTIFICATIONS, "[Device: 0x%p] Invalid power direction %u", device, ConnStatus->PowerDirection); + goto Exit; + } + + TRACE_INFO(TRACE_FLAG_UCMNOTIFICATIONS, "[Device: 0x%p] Reporting power role change to %!UCM_POWER_ROLE! on connector ID 0x%I64x", device, powerRole, Connector->Id); + + // + // Notify UCM that the power direction has changed. + // + + UcmConnectorPowerDirectionChanged(Connector->Handle, TRUE, powerRole); + + ConnStatus->ConnectorStatusChange.PowerDirectionChange = 0; + +Exit: + + TRACE_FUNC_EXIT(TRACE_FLAG_UCMNOTIFICATIONS); +} + + +_IRQL_requires_max_(PASSIVE_LEVEL) +VOID +Ucm_ReportDataDirectionChanged ( + _In_ PPPM_CONTEXT PpmCtx, + _In_ PPPM_CONNECTOR Connector, + _Inout_ PUCSI_GET_CONNECTOR_STATUS_IN ConnStatus, + _Inout_ PPPM_COMMAND_ACK_PARAMS CommandAckParams +) +/*++ + +Routine Description: + + Report to UCM that the data direction has changed. This may be called + after a role swap completes. + +Arguments: + + PpmCtx - Platform policy manager context object. + + Connector - The connector for which to report the data direction change. + + ConnStatus - The connector status for the given connector. + + CommandAckParams - UCSI command acknowledge parameters. + +--*/ +{ + WDFDEVICE device; + UCM_TYPEC_PARTNER partnerType; + UCM_DATA_ROLE newDataRole; + + UNREFERENCED_PARAMETER(CommandAckParams); + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_UCMNOTIFICATIONS); + + device = Context_GetWdfDevice(PpmCtx); + + if (!Convert((UCSI_CONNECTOR_PARTNER_TYPE)ConnStatus->ConnectorPartnerType, partnerType)) + { + TRACE_ERROR(TRACE_FLAG_UCMNOTIFICATIONS, "[Device: 0x%p] Invalid connector partner type %u", device, ConnStatus->ConnectorPartnerType); + goto Exit; + } + + if ((partnerType != UcmTypeCPartnerDfp) && (partnerType != UcmTypeCPartnerUfp)) + { + // + // This is one of those other cases where the partner type changed, for instance, + // PoweredCableNoUfp changed to PoweredCableWithUfp. + // + + goto Exit; + } + + newDataRole = (partnerType == UcmTypeCPartnerDfp) ? UcmDataRoleUfp : UcmDataRoleDfp; + + TRACE_INFO(TRACE_FLAG_UCMNOTIFICATIONS, "[Device: 0x%p] Reporting date role change to %!UCM_DATA_ROLE! on connector ID 0x%I64x", device, newDataRole, Connector->Id); + + // + // Notify UCM that the data direction has changed. + // + + UcmConnectorDataDirectionChanged(Connector->Handle, TRUE, newDataRole); + + ConnStatus->ConnectorStatusChange.ConnectorPartnerChange = 0; + +Exit: + + TRACE_FUNC_EXIT(TRACE_FLAG_UCMNOTIFICATIONS); +} + + +_IRQL_requires_max_(PASSIVE_LEVEL) +VOID +Ucm_ReportChargingStatusChanged ( + _In_ PPPM_CONTEXT PpmCtx, + _In_ PPPM_CONNECTOR Connector, + _Inout_ PUCSI_GET_CONNECTOR_STATUS_IN ConnStatus, + _Inout_ PPPM_COMMAND_ACK_PARAMS CommandAckParams +) +/*++ + +Routine Description: + + Report to UCM that the charging status has changed. This may be called + after a role swap completes. + +Arguments: + + PpmCtx - Platform policy manager context object. + + Connector - The connector for which to report the charging status change. + + ConnStatus - The connector status for the given connector. + + CommandAckParams - UCSI command acknowledge parameters. + +--*/ +{ + WDFDEVICE device; + UCM_CHARGING_STATE chargingState; + NTSTATUS status; + + UNREFERENCED_PARAMETER(CommandAckParams); + + PAGED_CODE(); + + TRACE_FUNC_ENTRY(TRACE_FLAG_UCMNOTIFICATIONS); + + device = Context_GetWdfDevice(PpmCtx); + + if (!Convert((UCSI_BATTERY_CHARGING_STATUS)ConnStatus->BatteryChargingStatus, chargingState)) + { + TRACE_ERROR(TRACE_FLAG_UCMNOTIFICATIONS, "[Device: 0x%p] Invalid charging state %u", device, ConnStatus->BatteryChargingStatus); + goto Exit; + } + + TRACE_INFO(TRACE_FLAG_UCMNOTIFICATIONS, "[Device: 0x%p] Reporting charging status change to %!UCM_CHARGING_STATE! on connector ID 0x%I64x", device, chargingState, Connector->Id); + + // + // Notify UCM that the charging state has changed. + // + + status = UcmConnectorChargingStateChanged(Connector->Handle, chargingState); + if (!NT_SUCCESS(status)) + { + TRACE_ERROR(TRACE_FLAG_UCMNOTIFICATIONS, "[Device: 0x%p] UcmConnectorChargingStateChanged failed - %!STATUS!", device, status); + goto Exit; + } + + ConnStatus->ConnectorStatusChange.BatteryChargingStatusChange = 0; + +Exit: + + TRACE_FUNC_EXIT(TRACE_FLAG_UCMNOTIFICATIONS); +} diff --git a/usb/UcmCxUcsi/UcmNotifications.h b/usb/UcmCxUcsi/UcmNotifications.h new file mode 100644 index 00000000..84426ca9 --- /dev/null +++ b/usb/UcmCxUcsi/UcmNotifications.h @@ -0,0 +1,97 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + UcmNotifications.h + +Abstract: + + Interface to notify UcmCx of events. + +Environment: + + Kernel-mode only. + +--*/ +#pragma once + +// +// There is only enough space for 4 PDOs in the message-in. +// +#define MAX_MESSAGE_IN_PDOS 4 + +// +// The PD specification defines an upper limit of 7 PDOs in a message. +// +#define MAX_PDO_COUNT 7 + +EXTERN_C_START + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +Ucm_CreateConnectors( + _In_ PPPM_CONTEXT PpmCtx +); + +EVT_PPM_COMMAND_COMPLETION_ROUTINE Ucm_EvtGetPdosCompleted; +EVT_PPM_COMMAND_COMPLETION_ROUTINE Ucm_EvtSetDataRoleCompleted; +EVT_PPM_COMMAND_COMPLETION_ROUTINE Ucm_EvtSetPowerRoleCompleted; + + +_IRQL_requires_max_(PASSIVE_LEVEL) +VOID +Ucm_ReportPowerOperationMode( + _In_ PPPM_CONTEXT PpmCtx, + _In_ PPPM_CONNECTOR Connector, + _Inout_ PUCSI_GET_CONNECTOR_STATUS_IN ConnStatus, + _Inout_ PPPM_COMMAND_ACK_PARAMS CommandAckParams +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +VOID +Ucm_ReportTypeCAttach( + _In_ PPPM_CONTEXT PpmCtx, + _In_ PPPM_CONNECTOR Connector, + _Inout_ PUCSI_GET_CONNECTOR_STATUS_IN ConnStatus, + _Inout_ PPPM_COMMAND_ACK_PARAMS CommandAckParams +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +VOID +Ucm_ReportTypeCDetach( + _In_ PPPM_CONTEXT PpmCtx, + _In_ PPPM_CONNECTOR Connector, + _Inout_ PUCSI_GET_CONNECTOR_STATUS_IN ConnStatus, + _Inout_ PPPM_COMMAND_ACK_PARAMS CommandAckParams +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +VOID +Ucm_ReportPowerDirectionChanged( + _In_ PPPM_CONTEXT PpmCtx, + _In_ PPPM_CONNECTOR Connector, + _Inout_ PUCSI_GET_CONNECTOR_STATUS_IN ConnStatus, + _Inout_ PPPM_COMMAND_ACK_PARAMS CommandAckParams +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +VOID +Ucm_ReportDataDirectionChanged( + _In_ PPPM_CONTEXT PpmCtx, + _In_ PPPM_CONNECTOR Connector, + _Inout_ PUCSI_GET_CONNECTOR_STATUS_IN ConnStatus, + _Inout_ PPPM_COMMAND_ACK_PARAMS CommandAckParams +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +VOID +Ucm_ReportChargingStatusChanged( + _In_ PPPM_CONTEXT PpmCtx, + _In_ PPPM_CONNECTOR Connector, + _Inout_ PUCSI_GET_CONNECTOR_STATUS_IN ConnStatus, + _Inout_ PPPM_COMMAND_ACK_PARAMS CommandAckParams +); + +EXTERN_C_END
\ No newline at end of file diff --git a/usb/UcmCxUcsi/Ucsi.h b/usb/UcmCxUcsi/Ucsi.h new file mode 100644 index 00000000..72950d6c --- /dev/null +++ b/usb/UcmCxUcsi/Ucsi.h @@ -0,0 +1,790 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + Ucsi.h + +Abstract: + + UCSI specification structure definitions. + UCSI version 1.0 + +Environment: + + Kernel-mode and user-mode. + +--*/ + +#pragma once + +#include <pshpack1.h> + +#pragma warning(push) +#pragma warning(disable:4201) // nonstandard extension used : nameless struct/union + + +#define UCSI_MAX_DATA_LENGTH 0x10 +#define UCSI_MAX_NUM_ALT_MODE 0x80 +#define UCSI_MIN_TIME_TO_RESPOND_WITH_BUSY 0x0A +#define UCSI_GET_ERROR_STATUS_DATA_LENGTH 0x10 +#define UCSI_MAX_NUM_PDOS 0x32 // Table 6-32 Counter parameters PD 2.0 V1.1 + + +typedef enum _UCSI_COMMAND +{ + UcsiCommandPpmReset = 0x01, + UcsiCommandCancel = 0x02, + UcsiCommandConnectorReset = 0x03, + UcsiCommandAckCcCi = 0x04, + UcsiCommandSetNotificationEnable = 0x05, + UcsiCommandGetCapability = 0x06, + UcsiCommandGetConnectorCapability = 0x07, + UcsiCommandSetUom = 0x08, + UcsiCommandSetUor = 0x09, + UcsiCommandSetPdm = 0x0A, + UcsiCommandSetPdr = 0x0B, + UcsiCommandGetAlternateModes = 0x0C, + UcsiCommandGetCamSupported = 0x0D, + UcsiCommandGetCurrentCam = 0x0E, + UcsiCommandSetNewCam = 0x0F, + UcsiCommandGetPdos = 0x10, + UcsiCommandGetCableProperty = 0x11, + UcsiCommandGetConnectorStatus = 0x12, + UcsiCommandGetErrorStatus = 0x13, + UcsiCommandMax = 0x14 +} UCSI_COMMAND; + + +typedef union _UCSI_VERSION +{ + UINT16 AsUInt16; + struct + { + UINT16 SubMinorVersion: 4; + UINT16 MinorVersion : 4; + UINT16 MajorVersion : 8; + }; +} UCSI_VERSION, *PUCSI_VERSION; + +static_assert(sizeof(UCSI_VERSION) == 2, "Incorrect size"); + + +typedef union _UCSI_CCI +{ + UINT32 AsUInt32; + struct + { + UINT32 : 1; + UINT32 ConnectorChangeIndicator : 7; + UINT32 DataLength : 8; + UINT32 : 9; + UINT32 NotSupportedIndicator : 1; + UINT32 CancelCompletedIndicator : 1; + UINT32 ResetCompletedIndicator : 1; + UINT32 BusyIndicator : 1; + UINT32 AcknowledgeCommandIndicator : 1; + UINT32 ErrorIndicator : 1; + UINT32 CommandCompletedIndicator : 1; + }; + +} UCSI_CCI, *PUCSI_CCI; + +static_assert(sizeof(UCSI_CCI) == 4, "Incorrect size"); + +BOOLEAN +FORCEINLINE +UCSI_CMD_SUCCEEDED ( + _In_ UCSI_CCI Cci + ) +{ + return Cci.CommandCompletedIndicator && + !(Cci.NotSupportedIndicator || Cci.CancelCompletedIndicator || Cci.ErrorIndicator); +} + + +typedef union _UCSI_CONNECTOR_RESET_COMMAND +{ + UINT64 AsUInt64; + struct + { + UINT64 Command : 8; + UINT64 DataLength : 8; + UINT64 ConnectorNumber : 7; + UINT64 HardReset : 1; + UINT64 : 40; + }; +} UCSI_CONNECTOR_RESET_COMMAND, *PUCSI_CONNECTOR_RESET_COMMAND; + +static_assert(sizeof(UCSI_CONNECTOR_RESET_COMMAND) == 8, "Incorrect size"); + + +typedef union _UCSI_ACK_CC_CI_COMMAND +{ + UINT64 AsUInt64; + struct + { + UINT64 Command : 8; + UINT64 DataLength : 8; + UINT64 ConnectorChangeAcknowledge : 1; + UINT64 CommandCompletedAcknowledge : 1; + UINT64 : 46; + }; +} UCSI_ACK_CC_CI_COMMAND, *PUCSI_ACK_CC_CI_COMMAND; + +static_assert(sizeof(UCSI_ACK_CC_CI_COMMAND) == 8, "Incorrect size"); + + +typedef union _UCSI_SET_NOTIFICATION_ENABLE_COMMAND +{ + UINT64 AsUInt64; + struct + { + UINT8 Command; + UINT8 DataLength; + union + { + UINT16 NotificationEnable; + struct + { + UINT16 CommandCompleteNotificationEnable : 1; + UINT16 ExternalSupplyChangeNotificationEnable : 1; + UINT16 PowerOperationModeChangeNotificationEnable : 1; + UINT16 : 1; + UINT16 : 1; + UINT16 SupportedProviderCapabilitiesChangeNotificationEnable : 1; + UINT16 NegotiatedPowerLevelChangeNotificationEnable : 1; + UINT16 PdResetNotificationEnable : 1; + UINT16 SupportedCamChangeNotificationEnable : 1; + UINT16 : 1; + UINT16 : 1; + UINT16 DataRoleSwapCompletedNotificationEnable : 1; + UINT16 PowerRoleSwapCompletedNotificationEnable : 1; + UINT16 : 1; + UINT16 ConnectChangeNotificationEnable : 1; + UINT16 ErrorNotificationEnable : 1; + }; + }; + UINT32 : 32; + }; +} UCSI_SET_NOTIFICATION_ENABLE_COMMAND, *PUCSI_SET_NOTIFICATION_ENABLE_COMMAND; + +static_assert(sizeof(UCSI_SET_NOTIFICATION_ENABLE_COMMAND) == 8, "Incorrect size"); + + +typedef union _UCSI_BM_POWER_SOURCE +{ + UINT8 AsUInt8; + struct + { + UINT8 AcSupply : 1; + UINT8 : 1; + UINT8 Other : 1; + UINT8 : 3; + UINT8 UsesVBus : 1; + UINT8 : 1; + }; +} UCSI_BM_POWER_SOURCE, *PUCSI_BM_POWER_SOURCE; + +static_assert(sizeof(UCSI_BM_POWER_SOURCE) == 1, "Incorrect size"); + +typedef struct _UCSI_GET_CAPABILITY_IN +{ + union + { + UINT32 AsUInt32; + struct + { + UINT32 DisabledStateSupport : 1; + UINT32 BatteryCharging : 1; + UINT32 UsbPowerDelivery : 1; + UINT32 : 3; + UINT32 UsbTypeCCurrent : 1; + UINT32 : 1; + UINT32 bmPowerSource : 8; + UINT32 : 16; + }; + } bmAttributes; + + union + { + UINT8 bNumConnectors : 7; + UINT8 : 1; + }; + + union + { + struct + { + UINT32 SetUomSupported : 1; + UINT32 SetPdmSupported : 1; + UINT32 AlternateModeDetailsAvailable : 1; + UINT32 AlternateModeOverrideSupported : 1; + UINT32 PdoDetailsAvailable : 1; + UINT32 CableDetailsAvailable : 1; + UINT32 ExternalSupplyNotificationSupported : 1; + UINT32 PdResetNotificationSupported : 1; + UINT32 : 16; + } bmOptionalFeatures; + + struct + { + UINT32 OptionalFeatures : 24; + UINT32 bNumAltModes : 8; + }; + }; + + UINT8 : 8; + UINT16 bcdBcVersion; + UINT16 bcdPdVersion; + UINT16 bcdUsbTypeCVersion; + +} UCSI_GET_CAPABILITY_IN, *PUCSI_GET_CAPABILITY_IN; + +static_assert(sizeof(UCSI_GET_CAPABILITY_IN) == 16, "Incorrect size"); + + +typedef union _UCSI_GET_CONNECTOR_CAPABILITY_COMMAND +{ + UINT64 AsUInt64; + struct + { + UINT64 Command : 8; + UINT64 DataLength : 8; + UINT64 ConnectorNumber : 7; + UINT64 : 41; + }; +} UCSI_GET_CONNECTOR_CAPABILITY_COMMAND, *PUCSI_GET_CONNECTOR_CAPABILITY_COMMAND; + +static_assert(sizeof(UCSI_GET_CONNECTOR_CAPABILITY_COMMAND) == 8, "Incorrect size"); + +typedef struct _UCSI_GET_CONNECTOR_CAPABILITY_IN +{ + union + { + UINT8 AsUInt8; + struct + { + UINT8 DfpOnly : 1; + UINT8 UfpOnly : 1; + UINT8 Drp : 1; + UINT8 AudioAccessoryMode : 1; + UINT8 DebugAccessoryMode : 1; + UINT8 Usb2 : 1; + UINT8 Usb3 : 1; + UINT8 AlternateMode : 1; + }; + } OperationMode; + + UINT8 Provider : 1; + UINT8 Consumer : 1; + UINT8 : 6; +} UCSI_GET_CONNECTOR_CAPABILITY_IN, *PUCSI_GET_CONNECTOR_CAPABILITY_IN; + +static_assert(sizeof(UCSI_GET_CONNECTOR_CAPABILITY_IN) == 2, "Incorrect size"); + + +typedef enum _UCSI_USB_OPERATION_MODE +{ + UcsiUsbOperationModeDfp = 0x1, + UcsiUsbOperationModeUfp = 0x2, + UcsiUsbOperationModeDrp = 0x4 +} UCSI_USB_OPERATION_MODE; + +typedef union _UCSI_SET_UOM_COMMAND +{ + UINT64 AsUInt64; + struct + { + UINT64 Command : 8; + UINT64 DataLength : 8; + UINT64 ConnectorNumber : 7; + UINT64 UsbOperationMode : 3; + UINT64 : 38; + }; +} UCSI_SET_UOM_COMMAND, *PUCSI_SET_UOM_COMMAND; + +static_assert(sizeof(UCSI_SET_UOM_COMMAND) == 8, "Incorrect size"); + + +typedef enum _UCSI_USB_OPERATION_ROLE +{ + UcsiUsbOperationRoleDfp = 0x1, + UcsiUsbOperationRoleUfp = 0x2, + UcsiUsbOperationRoleAcceptSwap = 0x4 +} UCSI_USB_OPERATION_ROLE; + +typedef union _UCSI_SET_UOR_COMMAND +{ + UINT64 AsUInt64; + struct + { + UINT64 Command : 8; + UINT64 DataLength : 8; + UINT64 ConnectorNumber : 7; + UINT64 UsbOperationRole : 3; + UINT64 : 38; + }; +} UCSI_SET_UOR_COMMAND, *PUCSI_SET_UOR_COMMAND; + +static_assert(sizeof(UCSI_SET_UOR_COMMAND) == 8, "Incorrect size"); + + +typedef enum _UCSI_POWER_DIRECTION_MODE +{ + UcsiPowerDirectionModeProvider = 0x1, + UcsiPowerDirectionModeConsumer = 0x2, + UcsiPowerDirectionModeEither = 0x4 +} UCSI_POWER_DIRECTION_MODE; + +typedef union _UCSI_SET_PDM_COMMAND +{ + UINT64 AsUInt64; + struct + { + UINT64 Command : 8; + UINT64 DataLength : 8; + UINT64 ConnectorNumber : 7; + UINT64 PowerDirectionMode : 3; + UINT64 : 38; + }; +} UCSI_SET_PDM_COMMAND, *PUCSI_SET_PDM_COMMAND; + +static_assert(sizeof(UCSI_SET_PDM_COMMAND) == 8, "Incorrect size"); + + +typedef enum _UCSI_POWER_DIRECTION_ROLE +{ + UcsiPowerDirectionRoleProvider = 0x1, + UcsiPowerDirectionRoleConsumer = 0x2, + UcsiPowerDirectionRoleAcceptSwap = 0x4 +} UCSI_POWER_DIRECTION_ROLE; + +typedef union _UCSI_SET_PDR_COMMAND +{ + UINT64 AsUInt64; + struct + { + UINT64 Command : 8; + UINT64 DataLength : 8; + UINT64 ConnectorNumber : 7; + UINT64 PowerDirectionRole : 3; + UINT64 : 38; + }; +} UCSI_SET_PDR_COMMAND, *PUCSI_SET_PDR_COMMAND; + +static_assert(sizeof(UCSI_SET_PDR_COMMAND) == 8, "Incorrect size"); + + +typedef enum _UCSI_GET_ALTERNATE_MODES_RECIPIENT +{ + UcsiGetAlternateModesRecipientConnector = 0, + UcsiGetAlternateModesRecipientSop = 1, + UcsiGetAlternateModesRecipientSopP = 2, + UcsiGetAlternateModesRecipientSopPP = 3 +} UCSI_GET_ALTERNATE_MODES_RECIPIENT; + +typedef union _UCSI_GET_ALTERNATE_MODES_COMMAND +{ + UINT64 AsUInt64; + struct + { + UINT64 Command : 8; + UINT64 DataLength : 8; + UINT64 Recipient : 3; + UINT64 : 5; + UINT64 ConnectorNumber : 7; + UINT64 : 1; + UINT64 AlternateModeOffset : 8; + UINT64 NumberOfAlternateModes : 2; + UINT64 : 22; + }; +} UCSI_GET_ALTERNATE_MODES_COMMAND, *PUCSI_GET_ALTERNATE_MODES_COMMAND; + +static_assert(sizeof(UCSI_GET_ALTERNATE_MODES_COMMAND) == 8, "Incorrect size"); + +typedef struct _UCSI_ALTERNATE_MODE +{ + UINT16 Svid; + UINT32 Mode; +} UCSI_ALTERNATE_MODE, *PUCSI_ALTERNATE_MODE; + +static_assert(sizeof(UCSI_ALTERNATE_MODE) == 6, "Incorrect size"); + +typedef struct _UCSI_GET_ALTERNATE_MODES_IN +{ + UCSI_ALTERNATE_MODE AlternateModes[2]; +} UCSI_GET_ALTERNATE_MODES_IN, *PUCSI_GET_ALTERNATE_MODES_IN; + +static_assert(sizeof(UCSI_GET_ALTERNATE_MODES_IN) == 12, "Incorrect size"); + + +typedef union _UCSI_GET_CAM_SUPPORTED_COMMAND +{ + UINT64 AsUInt64; + struct + { + UINT64 Command : 8; + UINT64 DataLength : 8; + UINT64 ConnectorNumber : 7; + UINT64 : 41; + }; +} UCSI_GET_CAM_SUPPORTED_COMMAND, *PUCSI_GET_CAM_SUPPORTED_COMMAND; + +static_assert(sizeof(UCSI_GET_CAM_SUPPORTED_COMMAND) == 8, "Incorrect size"); + +typedef struct _UCSI_GET_CAM_SUPPORTED_IN +{ + UINT8 bmAlternateModeSupported[16]; +} UCSI_GET_CAM_SUPPORTED_IN, *PUCSI_GET_CAM_SUPPORTED_IN; + +static_assert(sizeof(UCSI_GET_CAM_SUPPORTED_IN) == UCSI_MAX_DATA_LENGTH, "Incorrect size"); + + +typedef union _UCSI_GET_CURRENT_CAM_COMMAND +{ + UINT64 AsUInt64; + struct + { + UINT64 Command : 8; + UINT64 DataLength : 8; + UINT64 ConnectorNumber : 7; + UINT64 : 41; + }; +} UCSI_GET_CURRENT_CAM_COMMAND, *PUCSI_GET_CURRENT_CAM_COMMAND; + +static_assert(sizeof(UCSI_GET_CURRENT_CAM_COMMAND) == 8, "Incorrect size"); + +typedef struct _UCSI_GET_CURRENT_CAM_IN +{ + UINT8 CurrentAlternateMode; +} UCSI_GET_CURRENT_CAM_IN, *PUCSI_GET_CURRENT_CAM_IN; + +static_assert(sizeof(UCSI_GET_CURRENT_CAM_IN) == 1, "Incorrect size"); + + +typedef union _UCSI_SET_NEW_CAM_COMMAND +{ + UINT64 AsUInt64; + struct + { + UINT64 Command : 8; + UINT64 DataLength : 8; + UINT64 ConnectorNumber : 7; + UINT64 EnterOrExit : 1; + UINT64 NewCam : 8; + UINT64 AmSpecific: 32; + }; +} UCSI_SET_NEW_CAM_COMMAND, *PUCSI_SET_NEW_CAM_COMMAND; + +static_assert(sizeof(UCSI_SET_NEW_CAM_COMMAND) == 8, "Incorrect size"); + + +typedef enum _UCSI_GET_PDOS_TYPE +{ + UcsiGetPdosTypeSink = 0, + UcsiGetPdosTypeSource = 1 +} UCSI_GET_PDOS_TYPE; + +typedef enum _UCSI_GET_PDOS_SOURCE_CAPABILITIES_TYPE +{ + UcsiGetPdosCurrentSourceCapabilities = 0, + UcsiGetPdosAdvertisedSourceCapabilities = 1, + UcsiGetPdosMaxSourceCapabilities = 2 +} UCSI_GET_PDOS_SOURCE_CAPABILITIES_TYPE; + +typedef union _UCSI_GET_PDOS_COMMAND +{ + UINT64 AsUInt64; + struct + { + UINT64 Command : 8; + UINT64 DataLength : 8; + UINT64 ConnectorNumber : 7; + UINT64 PartnerPdo : 1; + UINT64 PdoOffset : 8; + UINT64 NumberOfPdos : 2; + UINT64 SourceOrSinkPdos : 1; + UINT64 SourceCapabilitiesType : 2; + UINT64 : 27; + }; +} UCSI_GET_PDOS_COMMAND, *PUCSI_GET_PDOS_COMMAND; + +static_assert(sizeof(UCSI_GET_PDOS_COMMAND) == 8, "Incorrect size"); + +typedef struct _UCSI_GET_PDOS_IN +{ + UINT32 Pdos[4]; +} UCSI_GET_PDOS_IN, *PUCSI_GET_PDOS_IN; + +static_assert(sizeof(UCSI_GET_PDOS_IN) == 16, "Incorrect size"); + + +typedef union _UCSI_GET_CABLE_PROPERTY_COMMAND +{ + UINT64 AsUInt64; + struct + { + UINT64 Command : 8; + UINT64 DataLength : 8; + UINT64 ConnectorNumber : 7; + UINT64 : 41; + }; +} UCSI_GET_CABLE_PROPERTY_COMMAND, *PUCSI_GET_CABLE_PROPERTY_COMMAND; + +static_assert(sizeof(UCSI_GET_CABLE_PROPERTY_COMMAND) == 8, "Incorrect size"); + +typedef struct _UCSI_GET_CABLE_PROPERTY_IN +{ + union + { + UINT16 AsUInt16; + struct + { + UINT16 SpeedExponent : 2; + UINT16 Mantissa : 14; + }; + } bmSpeedSupported; + + UINT8 bCurrentCapability; + UINT16 VBusInCable : 1; + UINT16 CableType : 1; + UINT16 Directionality : 1; + UINT16 PlugEndType : 2; + UINT16 ModeSupport : 1; + UINT16 : 2; + UINT16 Latency : 4; + UINT16 : 4; +} UCSI_GET_CABLE_PROPERTY_IN, *PUCSI_GET_CABLE_PROPERTY_IN; + +static_assert(sizeof(UCSI_GET_CABLE_PROPERTY_IN) == 5, "Incorrect size"); + + +typedef union _UCSI_GET_CONNECTOR_STATUS_COMMAND +{ + UINT64 AsUInt64; + struct + { + UINT64 Command : 8; + UINT64 DataLength : 8; + UINT64 ConnectorNumber : 7; + UINT64 : 41; + }; +} UCSI_GET_CONNECTOR_STATUS_COMMAND, *PUCSI_GET_CONNECTOR_STATUS_COMMAND; + +static_assert(sizeof(UCSI_GET_CONNECTOR_STATUS_COMMAND) == 8, "Incorrect size"); + +typedef enum _UCSI_POWER_OPERATION_MODE +{ + UcsiPowerOperationModeNoConsumer = 0, + UcsiPowerOperationModeDefaultUsb = 1, + UcsiPowerOperationModeBc = 2, + UcsiPowerOperationModePd = 3, + UcsiPowerOperationModeTypeC1500 = 4, + UcsiPowerOperationModeTypeC3000 = 5 +} UCSI_POWER_OPERATION_MODE; + +typedef enum _UCSI_POWER_DIRECTION +{ + UcsiPowerDirectionConsumer = 0, + UcsiPowerDirectionProvider = 1 +} UCSI_POWER_DIRECTION; + +typedef enum _UCSI_CONNECTOR_PARTNER_FLAGS +{ + UcsiConnectorPartnerFlagUsb = 0x1, + UcsiConnectorPartnerFlagAlternateMode = 0x2 +} UCSI_CONNECTOR_PARTNER_FLAGS; + +typedef enum _UCSI_CONNECTOR_PARTNER_TYPE +{ + UcsiConnectorPartnerTypeDfp = 1, + UcsiConnectorPartnerTypeUfp = 2, + UcsiConnectorPartnerTypePoweredCableNoUfp = 3, + UcsiConnectorPartnerTypePoweredCableWithUfp = 4, + UcsiConnectorPartnerTypeDebugAccessory = 5, + UcsiConnectorPartnerTypeAudioAccessory = 6 +} UCSI_CONNECTOR_PARTNER_TYPE; + +typedef enum _UCSI_BATTERY_CHARGING_STATUS +{ + UcsiBatteryChargingNotCharging = 0, + UcsiBatteryChargingNominal = 1, + UcsiBatteryChargingSlowCharging = 2, + UcsiBatteryChargingTrickleCharging = 3 +} UCSI_BATTERY_CHARGING_STATUS; + +typedef struct _UCSI_GET_CONNECTOR_STATUS_IN +{ + union + { + UINT16 AsUInt16; + struct + { + UINT16 : 1; + UINT16 ExternalSupplyChange : 1; + UINT16 PowerOperationModeChange : 1; + UINT16 : 1; + UINT16 : 1; + UINT16 SupportedProviderCapabilitiesChange : 1; + UINT16 NegotiatedPowerLevelChange : 1; + UINT16 PdResetComplete : 1; + UINT16 SupportedCamChange : 1; + UINT16 BatteryChargingStatusChange : 1; + UINT16 : 1; + UINT16 ConnectorPartnerChange : 1; + UINT16 PowerDirectionChange : 1; + UINT16 : 1; + UINT16 ConnectChange : 1; + UINT16 Error : 1; + }; + } ConnectorStatusChange; + + UINT16 PowerOperationMode : 3; + UINT16 ConnectStatus : 1; + UINT16 PowerDirection : 1; + UINT16 ConnectorPartnerFlags : 8; + UINT16 ConnectorPartnerType : 3; + + UINT32 RequestDataObject; + + union + { + struct + { + UINT8 BatteryChargingStatus : 2; + UINT8 PowerBudgetLimitedReason : 4; + UINT8 : 2; + }; + + struct + { + UINT8 : 2; + UINT8 PowerBudgetLowered : 1; + UINT8 ReachingPowerBudgetLimit : 1; + UINT8 : 1; + UINT8 : 1; + UINT8 : 2; + } bmPowerBudgetLimitedReason; + }; +} UCSI_GET_CONNECTOR_STATUS_IN, *PUCSI_GET_CONNECTOR_STATUS_IN; + +static_assert(sizeof(UCSI_GET_CONNECTOR_STATUS_IN) == 9, "Incorrect size"); + + +typedef union _UCSI_GET_ERROR_STATUS_COMMAND +{ + UINT64 AsUInt64; + struct + { + UINT64 Command : 8; + UINT64 DataLength : 8; + UINT64 : 48; + }; +} UCSI_GET_ERROR_STATUS_COMMAND, *PUCSI_GET_ERROR_STATUS_COMMAND; + +static_assert(sizeof(UCSI_GET_ERROR_STATUS_COMMAND) == 8, "Incorrect size"); + +typedef struct _UCSI_GET_ERROR_STATUS_IN +{ + union + { + UINT16 AsUInt16; + struct + { + UINT16 UnrecognizedCommandError : 1; + UINT16 NonExistentConnectorNumberError : 1; + UINT16 InvalidCommandParametersError : 1; + UINT16 IncompatibleConnectorPartnerError : 1; + UINT16 CcCommunicationError : 1; + UINT16 CommandFailureDueToDeadBattery : 1; + UINT16 ContractNegotiationFailure : 1; + UINT16 : 9; + }; + } ErrorInformation; + + UINT8 VendorDefined[14]; + +} UCSI_GET_ERROR_STATUS_IN, *PUCSI_GET_ERROR_STATUS_IN; + +static_assert(sizeof(UCSI_GET_ERROR_STATUS_IN) == UCSI_MAX_DATA_LENGTH, "Incorrect size"); + + +typedef union _UCSI_CONTROL +{ + UINT64 AsUInt64; + + struct + { + UINT64 Command : 8; + UINT64 DataLength : 8; + UINT64 CommandSpecific : 48; + }; + + UCSI_CONNECTOR_RESET_COMMAND ConnectorReset; + UCSI_ACK_CC_CI_COMMAND AckCcCi; + UCSI_SET_NOTIFICATION_ENABLE_COMMAND SetNotificationEnable; + UCSI_GET_CONNECTOR_CAPABILITY_COMMAND GetConnectorCapability; + UCSI_SET_UOM_COMMAND SetUom; + UCSI_SET_UOR_COMMAND SetUor; + UCSI_SET_PDM_COMMAND SetPdm; + UCSI_SET_PDR_COMMAND SetPdr; + UCSI_GET_ALTERNATE_MODES_COMMAND GetAlternateModes; + UCSI_GET_CAM_SUPPORTED_COMMAND GetCamSupported; + UCSI_GET_CURRENT_CAM_COMMAND GetCurrentCam; + UCSI_SET_NEW_CAM_COMMAND SetNewCam; + UCSI_GET_PDOS_COMMAND GetPdos; + UCSI_GET_CABLE_PROPERTY_COMMAND GetCableProperty; + UCSI_GET_CONNECTOR_STATUS_COMMAND GetConnectorStatus; + UCSI_GET_ERROR_STATUS_COMMAND GetErrorStatus; + +} UCSI_CONTROL, *PUCSI_CONTROL; + +static_assert(sizeof(UCSI_CONTROL) == 8, "Incorrect size"); + + +typedef union _UCSI_MESSAGE_IN +{ + UINT8 AsBuffer[UCSI_MAX_DATA_LENGTH]; + + UCSI_GET_CAPABILITY_IN Capability; + UCSI_GET_CONNECTOR_CAPABILITY_IN ConnectorCapability; + UCSI_GET_ALTERNATE_MODES_IN AlternateModes; + UCSI_GET_CAM_SUPPORTED_IN CamSupported; + UCSI_GET_CURRENT_CAM_IN CurrentCam; + UCSI_GET_PDOS_IN Pdos; + UCSI_GET_CABLE_PROPERTY_IN CableProperty; + UCSI_GET_CONNECTOR_STATUS_IN ConnectorStatus; + UCSI_GET_ERROR_STATUS_IN ErrorStatus; + +} UCSI_MESSAGE_IN, *PUCSI_MESSAGE_IN; + +static_assert(sizeof(UCSI_MESSAGE_IN) == UCSI_MAX_DATA_LENGTH, "Incorrect size"); + + +typedef union _UCSI_MESSAGE_OUT +{ + UINT8 AsBuffer[UCSI_MAX_DATA_LENGTH]; + +} UCSI_MESSAGE_OUT, *PUCSI_MESSAGE_OUT; + +static_assert(sizeof(UCSI_MESSAGE_OUT) == UCSI_MAX_DATA_LENGTH, "Incorrect size"); + + +typedef struct _UCSI_DATA_BLOCK +{ + UCSI_VERSION UcsiVersion; + UINT16 : 16; + UCSI_CCI CCI; + UCSI_CONTROL Control; + UCSI_MESSAGE_IN MessageIn; + UCSI_MESSAGE_OUT MessageOut; +} UCSI_DATA_BLOCK, *PUCSI_DATA_BLOCK; + +static_assert(sizeof(UCSI_DATA_BLOCK) == 48, "Incorrect size"); + + +#pragma warning(pop) + +#include <poppack.h> diff --git a/usb/UcmCxUcsi/UcsiInterface.h b/usb/UcmCxUcsi/UcsiInterface.h new file mode 100644 index 00000000..e99a4c07 --- /dev/null +++ b/usb/UcmCxUcsi/UcsiInterface.h @@ -0,0 +1,73 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + UcsiInterface.h + +Abstract: + + Interface to the driver. + +Environment: + + Kernel-mode and user-mode. + +--*/ + + +#pragma once + + +// {6C846EEA-9649-46B3-9C37-2556133E5006} +DEFINE_GUID(GUID_DEVINTERFACE_UCSI_TEST, +0x6c846eea, 0x9649, 0x46b3, 0x9c, 0x37, 0x25, 0x56, 0x13, 0x3e, 0x50, 0x6); + +// +// A random value from the Microsoft-reserved range. +// +#define FILE_DEVICE_UCSI 4627 + +#define IOCTL_UCSI_SEND_COMMAND \ + (DWORD) CTL_CODE(FILE_DEVICE_UCSI, \ + 0x401, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define IOCTL_UCSI_GET_CCI \ + (DWORD) CTL_CODE(FILE_DEVICE_UCSI, \ + 0x402, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +#define IOCTL_UCSI_GET_MESSAGE \ + (DWORD) CTL_CODE(FILE_DEVICE_UCSI, \ + 0x403, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) + +// +// An enum defined to make it convenient to pretty-print the IOCTL name +// in WPP. +// + +typedef enum _UCSI_IOCTL { + + _IOCTL_UCSI_SEND_COMMAND = IOCTL_UCSI_SEND_COMMAND, + _IOCTL_UCSI_GET_CCI = IOCTL_UCSI_GET_CCI, + _IOCTL_UCSI_GET_MESSAGE = IOCTL_UCSI_GET_MESSAGE + +} UCSI_IOCTL; + +// +// WPP tracing for enums +// + +// +// begin_wpp config +// +// CUSTOM_TYPE(UcsiIoctl, ItemEnum(_UCSI_IOCTL)); +// +// end_wpp +// diff --git a/usb/UcmCxUcsi/UcsiUcmConvert.h b/usb/UcmCxUcsi/UcsiUcmConvert.h new file mode 100644 index 00000000..d38eabea --- /dev/null +++ b/usb/UcmCxUcsi/UcsiUcmConvert.h @@ -0,0 +1,284 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + UcsiUcmConvert.h + +Abstract: + + Helpers to convert between UCM and UCSI enums. + +Environment: + + Kernel-mode only. + +--*/ + +#pragma once + +template<typename A, typename B> +_Success_(return != false) +_Must_inspect_result_ +bool +FORCEINLINE +Convert ( + _In_ A From, + _Out_ B& To + ); + + +template<> +_Success_(return != false) +_Must_inspect_result_ +bool +FORCEINLINE +Convert<UCSI_CONNECTOR_PARTNER_TYPE, UCM_TYPEC_PARTNER> ( + _In_ UCSI_CONNECTOR_PARTNER_TYPE PartnerType, + _Out_ UCM_TYPEC_PARTNER& ConvertedValue + ) +{ + UCM_TYPEC_PARTNER ucmPartner; + + switch (PartnerType) + { + case UcsiConnectorPartnerTypeDfp: + ucmPartner = UcmTypeCPartnerDfp; + break; + case UcsiConnectorPartnerTypeUfp: + ucmPartner = UcmTypeCPartnerUfp; + break; + case UcsiConnectorPartnerTypePoweredCableNoUfp: + ucmPartner = UcmTypeCPartnerPoweredCableNoUfp; + break; + case UcsiConnectorPartnerTypePoweredCableWithUfp: + ucmPartner = UcmTypeCPartnerPoweredCableWithUfp; + break; + case UcsiConnectorPartnerTypeDebugAccessory: + ucmPartner = UcmTypeCPartnerDebugAccessory; + break; + case UcsiConnectorPartnerTypeAudioAccessory: + ucmPartner = UcmTypeCPartnerAudioAccessory; + break; + default: + return false; + } + + ConvertedValue = ucmPartner; + return true; +} + + +template<> +_Success_(return != false) +_Must_inspect_result_ +bool +FORCEINLINE +Convert<UCSI_BATTERY_CHARGING_STATUS, UCM_CHARGING_STATE> ( + _In_ UCSI_BATTERY_CHARGING_STATUS ChargingState, + _Out_ UCM_CHARGING_STATE& ConvertedValue + ) +{ + UCM_CHARGING_STATE ucmChargingState; + + switch (ChargingState) + { + case UcsiBatteryChargingNotCharging: + ucmChargingState = UcmChargingStateNotCharging; + break; + case UcsiBatteryChargingSlowCharging: + ucmChargingState = UcmChargingStateSlowCharging; + break; + case UcsiBatteryChargingTrickleCharging: + ucmChargingState = UcmChargingStateTrickleCharging; + break; + case UcsiBatteryChargingNominal: + ucmChargingState = UcmChargingStateNominalCharging; + break; + default: + return false; + } + + ConvertedValue = ucmChargingState; + return true; +} + + +template<> +_Success_(return != false) +_Must_inspect_result_ +bool +FORCEINLINE +Convert<UCM_DATA_ROLE, UCSI_USB_OPERATION_ROLE> ( + _In_ UCM_DATA_ROLE DataRole, + _Out_ UCSI_USB_OPERATION_ROLE& UsbRole + ) +{ + UCSI_USB_OPERATION_ROLE usbRole; + + switch (DataRole) + { + case UcmDataRoleDfp: + usbRole = UcsiUsbOperationRoleDfp; + break; + case UcmDataRoleUfp: + usbRole = UcsiUsbOperationRoleUfp; + break; + default: + return false; + } + + UsbRole = usbRole; + return true; +} + + +template<> +_Success_(return != false) +_Must_inspect_result_ +bool +FORCEINLINE +Convert<UCSI_USB_OPERATION_ROLE, UCM_DATA_ROLE> ( + _In_ UCSI_USB_OPERATION_ROLE UsbRole, + _Out_ UCM_DATA_ROLE& DataRole + ) +{ + UCM_DATA_ROLE dataRole; + + switch (UsbRole) + { + case UcsiUsbOperationRoleDfp: + dataRole = UcmDataRoleDfp; + break; + case UcsiUsbOperationRoleUfp: + dataRole = UcmDataRoleUfp; + break; + default: + return false; + } + + DataRole = dataRole; + return true; +} + + +template<> +_Success_(return != false) +_Must_inspect_result_ +bool +FORCEINLINE +Convert<UCSI_POWER_OPERATION_MODE, UCM_TYPEC_CURRENT> ( + _In_ UCSI_POWER_OPERATION_MODE PowerOperationMode, + _Out_ UCM_TYPEC_CURRENT& ConvertedValue + ) +{ + UCM_TYPEC_CURRENT typeCCurrent; + + switch (PowerOperationMode) + { + case UcsiPowerOperationModeTypeC1500: + typeCCurrent = UcmTypeCCurrent1500mA; + break; + case UcsiPowerOperationModeTypeC3000: + typeCCurrent = UcmTypeCCurrent3000mA; + break; + case UcsiPowerOperationModeBc: + case UcsiPowerOperationModeDefaultUsb: + case UcsiPowerOperationModePd: + typeCCurrent = UcmTypeCCurrentDefaultUsb; + break; + default: + return false; + } + + ConvertedValue = typeCCurrent; + return true; +} + + +template<> +_Success_(return != false) +_Must_inspect_result_ +bool +FORCEINLINE +Convert<UCM_POWER_ROLE, UCSI_POWER_DIRECTION_ROLE> ( + _In_ UCM_POWER_ROLE PowerRole, + _Out_ UCSI_POWER_DIRECTION_ROLE& ConvertedValue + ) +{ + UCSI_POWER_DIRECTION_ROLE powerRole; + + switch (PowerRole) + { + case UcmPowerRoleSource: + powerRole = UcsiPowerDirectionRoleProvider; + break; + case UcmPowerRoleSink: + powerRole = UcsiPowerDirectionRoleConsumer; + break; + default: + return false; + } + + ConvertedValue = powerRole; + return true; +} + + +template<> +_Success_(return != false) +_Must_inspect_result_ +bool +FORCEINLINE +Convert<UCSI_POWER_DIRECTION_ROLE, UCM_POWER_ROLE> ( + _In_ UCSI_POWER_DIRECTION_ROLE PowerRole, + _Out_ UCM_POWER_ROLE& ConvertedValue + ) +{ + UCM_POWER_ROLE powerRole; + + switch (PowerRole) + { + case UcsiPowerDirectionRoleProvider: + powerRole = UcmPowerRoleSource; + break; + case UcsiPowerDirectionRoleConsumer: + powerRole = UcmPowerRoleSink; + break; + default: + return false; + } + + ConvertedValue = powerRole; + return true; +} + + +template<> +_Success_(return != false) +_Must_inspect_result_ +bool +FORCEINLINE +Convert<UCSI_POWER_DIRECTION, UCM_POWER_ROLE> ( + _In_ UCSI_POWER_DIRECTION PowerDirection, + _Out_ UCM_POWER_ROLE& ConvertedValue + ) +{ + UCM_POWER_ROLE powerRole; + + switch (PowerDirection) + { + case UcsiPowerDirectionProvider: + powerRole = UcmPowerRoleSource; + break; + case UcsiPowerDirectionConsumer: + powerRole = UcmPowerRoleSink; + break; + default: + return false; + } + + ConvertedValue = powerRole; + return true; +} diff --git a/usb/UcmCxUcsi/resource.rc b/usb/UcmCxUcsi/resource.rc new file mode 100644 index 00000000..55dd4e36 --- /dev/null +++ b/usb/UcmCxUcsi/resource.rc @@ -0,0 +1,25 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + resource.rc + +Abstract: + + Resources for the binary. + +--*/ + + +#include <windows.h> +#include <ntverp.h> + +#define VER_FILETYPE VFT_DRV +#define VER_FILESUBTYPE VFT2_DRV_SYSTEM +#define VER_FILEDESCRIPTION_STR "USB Connector Manager Sample UCSI Client" +#define VER_INTERNALNAME_STR "UcmCxUcsi.sys" +#define VER_ORIGINALFILENAME_STR "UcmCxUcsi.sys" + +#include "common.ver" diff --git a/usb/kmdf_enumswitches/inc/public.h b/usb/kmdf_enumswitches/inc/public.h index 12ddf21f..f1fc6be3 100644 --- a/usb/kmdf_enumswitches/inc/public.h +++ b/usb/kmdf_enumswitches/inc/public.h @@ -119,7 +119,7 @@ typedef struct _SWITCH_STATE { #pragma warning(pop) #define IOCTL_INDEX 0x800 -#define FILE_DEVICE_OSRUSBFX2 0x65500 +#define FILE_DEVICE_OSRUSBFX2 65500U #define IOCTL_OSRUSBFX2_GET_CONFIG_DESCRIPTOR CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ IOCTL_INDEX, \ diff --git a/usb/kmdf_enumswitches/kmdf_enumswitches.sln b/usb/kmdf_enumswitches/kmdf_enumswitches.sln index 32b903cb..c1e962bf 100644 --- a/usb/kmdf_enumswitches/kmdf_enumswitches.sln +++ b/usb/kmdf_enumswitches/kmdf_enumswitches.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2013 VisualStudioVersion = 12.0 MinimumVisualStudioVersion = 12.0 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kmdf_enumswitches", "sys\kmdf_enumswitches.vcxproj", "{CE94DCE1-20AE-4D06-BFA9-13E9D92D339A}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kmdf_enumswitches", "sys\kmdf_enumswitches.vcxproj", "{4F9EF7B8-4C30-4654-B431-B6D64C3A2C56}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -13,14 +13,14 @@ Global Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {CE94DCE1-20AE-4D06-BFA9-13E9D92D339A}.Debug|Win32.ActiveCfg = Debug|Win32 - {CE94DCE1-20AE-4D06-BFA9-13E9D92D339A}.Debug|Win32.Build.0 = Debug|Win32 - {CE94DCE1-20AE-4D06-BFA9-13E9D92D339A}.Release|Win32.ActiveCfg = Release|Win32 - {CE94DCE1-20AE-4D06-BFA9-13E9D92D339A}.Release|Win32.Build.0 = Release|Win32 - {CE94DCE1-20AE-4D06-BFA9-13E9D92D339A}.Debug|x64.ActiveCfg = Debug|x64 - {CE94DCE1-20AE-4D06-BFA9-13E9D92D339A}.Debug|x64.Build.0 = Debug|x64 - {CE94DCE1-20AE-4D06-BFA9-13E9D92D339A}.Release|x64.ActiveCfg = Release|x64 - {CE94DCE1-20AE-4D06-BFA9-13E9D92D339A}.Release|x64.Build.0 = Release|x64 + {4F9EF7B8-4C30-4654-B431-B6D64C3A2C56}.Debug|Win32.ActiveCfg = Debug|Win32 + {4F9EF7B8-4C30-4654-B431-B6D64C3A2C56}.Debug|Win32.Build.0 = Debug|Win32 + {4F9EF7B8-4C30-4654-B431-B6D64C3A2C56}.Release|Win32.ActiveCfg = Release|Win32 + {4F9EF7B8-4C30-4654-B431-B6D64C3A2C56}.Release|Win32.Build.0 = Release|Win32 + {4F9EF7B8-4C30-4654-B431-B6D64C3A2C56}.Debug|x64.ActiveCfg = Debug|x64 + {4F9EF7B8-4C30-4654-B431-B6D64C3A2C56}.Debug|x64.Build.0 = Debug|x64 + {4F9EF7B8-4C30-4654-B431-B6D64C3A2C56}.Release|x64.ActiveCfg = Release|x64 + {4F9EF7B8-4C30-4654-B431-B6D64C3A2C56}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/usb/kmdf_enumswitches/sys/driver.c b/usb/kmdf_enumswitches/sys/driver.c index 10586be3..aefc6c2b 100644 --- a/usb/kmdf_enumswitches/sys/driver.c +++ b/usb/kmdf_enumswitches/sys/driver.c @@ -106,9 +106,6 @@ Return Value: TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, "OSRUSBFX2 Driver Sample - Driver Framework Edition.\n"); - TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, - "Built %s %s\n", __DATE__, __TIME__); - // // Initiialize driver config to control the attributes that // are global to the driver. Note that framework by default diff --git a/usb/kmdf_enumswitches/sys/kmdf_enumswitches.inx b/usb/kmdf_enumswitches/sys/kmdf_enumswitches.inx Binary files differindex 6ecf53ba..52017d13 100644 --- a/usb/kmdf_enumswitches/sys/kmdf_enumswitches.inx +++ b/usb/kmdf_enumswitches/sys/kmdf_enumswitches.inx diff --git a/usb/kmdf_enumswitches/sys/kmdf_enumswitches.vcxproj b/usb/kmdf_enumswitches/sys/kmdf_enumswitches.vcxproj index 46f1b42e..3230fc6e 100644 --- a/usb/kmdf_enumswitches/sys/kmdf_enumswitches.vcxproj +++ b/usb/kmdf_enumswitches/sys/kmdf_enumswitches.vcxproj @@ -19,12 +19,12 @@ </ProjectConfiguration> </ItemGroup> <PropertyGroup Label="Globals"> - <ProjectGuid>{96607BB4-3861-408E-B117-CAA8D0B6D372}</ProjectGuid> + <ProjectGuid>{4F9EF7B8-4C30-4654-B431-B6D64C3A2C56}</ProjectGuid> <RootNamespace>$(MSBuildProjectName)</RootNamespace> <KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR> <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration> <Platform Condition="'$(Platform)' == ''">Win32</Platform> - <SampleGuid>{3017F5B6-A432-4BC6-982C-92EDBF88C56D}</SampleGuid> + <SampleGuid>{B11DDDBD-A80C-4105-B342-96834A1D1DA6}</SampleGuid> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> @@ -82,11 +82,6 @@ <WppTraceFunction>TraceEvents(LEVEL,FLAGS,MSG,...)</WppTraceFunction> <WppGenerateUsingTemplateFile>{km-WdfDefault.tpl}*.tmh</WppGenerateUsingTemplateFile> </ClCompile> - <Inf Include="kmdf_enumswitches.inx"> - <Architecture>$(InfArch)</Architecture> - <SpecifyArchitecture>true</SpecifyArchitecture> - <CopyOutput>.\$(IntDir)\kmdf_enumswitches.inf</CopyOutput> - </Inf> </ItemGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <TargetName>kmdf_enumswitches</TargetName> diff --git a/usb/kmdf_enumswitches/sys/kmdf_enumswitches.vcxproj.Filters b/usb/kmdf_enumswitches/sys/kmdf_enumswitches.vcxproj.Filters index 6d286cd3..e772a84c 100644 --- a/usb/kmdf_enumswitches/sys/kmdf_enumswitches.vcxproj.Filters +++ b/usb/kmdf_enumswitches/sys/kmdf_enumswitches.vcxproj.Filters @@ -3,19 +3,19 @@ <ItemGroup> <Filter Include="Source Files"> <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions> - <UniqueIdentifier>{51861499-AB32-435D-A5D8-467D00D1A71D}</UniqueIdentifier> + <UniqueIdentifier>{DD6C0A8F-CD5A-4780-8FF9-CBB81D0D855E}</UniqueIdentifier> </Filter> <Filter Include="Header Files"> <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> - <UniqueIdentifier>{407A2F5C-65A7-44BA-AF3B-6543832CDE3F}</UniqueIdentifier> + <UniqueIdentifier>{A1497843-5B68-4D99-AAE0-E16180026D77}</UniqueIdentifier> </Filter> <Filter Include="Resource Files"> <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions> - <UniqueIdentifier>{CDF3E397-8551-4B6E-BD1F-6E63053324D5}</UniqueIdentifier> + <UniqueIdentifier>{3497842A-32EA-48D3-97E5-2EEE032D4AA3}</UniqueIdentifier> </Filter> <Filter Include="Driver Files"> <Extensions>inf;inv;inx;mof;mc;</Extensions> - <UniqueIdentifier>{59DF9552-63A9-4ABC-8DAF-9E8811DE79AE}</UniqueIdentifier> + <UniqueIdentifier>{C1A4FA85-8FA5-465E-B288-325A1296C6E9}</UniqueIdentifier> </Filter> </ItemGroup> <ItemGroup> @@ -32,9 +32,4 @@ <Filter>Source Files</Filter> </ClCompile> </ItemGroup> - <ItemGroup> - <Inf Include="kmdf_enumswitches.inx"> - <Filter>Driver Files</Filter> - </Inf> - </ItemGroup> </Project>
\ No newline at end of file diff --git a/usb/kmdf_fx2/driver/Device.c b/usb/kmdf_fx2/driver/Device.c index 87ead857..8516ef09 100644 --- a/usb/kmdf_fx2/driver/Device.c +++ b/usb/kmdf_fx2/driver/Device.c @@ -970,7 +970,7 @@ Return Value: status = WdfDeviceAllocAndQueryProperty(Device, DevicePropertyFriendlyName, - NonPagedPool, + NonPagedPoolNx, &objectAttributes, &deviceNameMemory); @@ -978,7 +978,7 @@ Return Value: { status = WdfDeviceAllocAndQueryProperty(Device, DevicePropertyDeviceDescription, - NonPagedPool, + NonPagedPoolNx, &objectAttributes, &deviceNameMemory); } @@ -1000,7 +1000,7 @@ Return Value: status = WdfDeviceAllocAndQueryProperty(Device, DevicePropertyLocationInformation, - NonPagedPool, + NonPagedPoolNx, WDF_NO_OBJECT_ATTRIBUTES, &locationMemory); diff --git a/usb/kmdf_fx2/driver/driver.c b/usb/kmdf_fx2/driver/driver.c index d3b44573..44939a3b 100644 --- a/usb/kmdf_fx2/driver/driver.c +++ b/usb/kmdf_fx2/driver/driver.c @@ -114,9 +114,6 @@ Return Value: TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, "OSRUSBFX2 Driver Sample - Driver Framework Edition.\n"); - TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, - "Built %s %s\n", __DATE__, __TIME__); - // // IRP activity ID functions are available on some versions, save them into // globals (or NULL if not available) diff --git a/usb/kmdf_fx2/driver/osrusbfx2.inx b/usb/kmdf_fx2/driver/osrusbfx2.inx Binary files differindex 6bb5ccc5..d515de34 100644 --- a/usb/kmdf_fx2/driver/osrusbfx2.inx +++ b/usb/kmdf_fx2/driver/osrusbfx2.inx diff --git a/usb/kmdf_fx2/driver/osrusbfx2.vcxproj b/usb/kmdf_fx2/driver/osrusbfx2.vcxproj index 29fe9c3a..2db1f7c1 100644 --- a/usb/kmdf_fx2/driver/osrusbfx2.vcxproj +++ b/usb/kmdf_fx2/driver/osrusbfx2.vcxproj @@ -19,18 +19,20 @@ </ProjectConfiguration> </ItemGroup> <PropertyGroup Label="Globals"> - <ProjectGuid>{E7ECAF21-2522-4E7D-8475-67C4A5E43F70}</ProjectGuid> + <ProjectGuid>{837F98CF-D3A4-472C-BACC-47950340E57B}</ProjectGuid> <RootNamespace>$(MSBuildProjectName)</RootNamespace> <KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR> + <SupportsPackaging>false</SupportsPackaging> + <RequiresPackageProject>true</RequiresPackageProject> <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration> <Platform Condition="'$(Platform)' == ''">Win32</Platform> - <SampleGuid>{95AAF552-36F7-487B-A556-B969D823DC9F}</SampleGuid> + <SampleGuid>{3EBA8CBF-2E65-4819-9EEA-E10825BB0705}</SampleGuid> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <TargetVersion>Windows10</TargetVersion> <UseDebugLibraries>False</UseDebugLibraries> - <DriverTargetPlatform>Universal</DriverTargetPlatform> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> <DriverType>KMDF</DriverType> <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> <ConfigurationType>Driver</ConfigurationType> @@ -38,7 +40,7 @@ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <TargetVersion>Windows10</TargetVersion> <UseDebugLibraries>True</UseDebugLibraries> - <DriverTargetPlatform>Universal</DriverTargetPlatform> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> <DriverType>KMDF</DriverType> <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> <ConfigurationType>Driver</ConfigurationType> @@ -46,7 +48,7 @@ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <TargetVersion>Windows10</TargetVersion> <UseDebugLibraries>False</UseDebugLibraries> - <DriverTargetPlatform>Universal</DriverTargetPlatform> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> <DriverType>KMDF</DriverType> <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> <ConfigurationType>Driver</ConfigurationType> @@ -54,7 +56,7 @@ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <TargetVersion>Windows10</TargetVersion> <UseDebugLibraries>True</UseDebugLibraries> - <DriverTargetPlatform>Universal</DriverTargetPlatform> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> <DriverType>KMDF</DriverType> <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> <ConfigurationType>Driver</ConfigurationType> @@ -82,11 +84,6 @@ <WppTraceFunction>TraceEvents(LEVEL,FLAGS,MSG,...)</WppTraceFunction> <WppGenerateUsingTemplateFile>{km-WdfDefault.tpl}*.tmh</WppGenerateUsingTemplateFile> </ClCompile> - <Inf Include=".\osrusbfx2.inx"> - <Architecture>$(InfArch)</Architecture> - <SpecifyArchitecture>true</SpecifyArchitecture> - <CopyOutput>.\$(IntDir)\osrusbfx2.inf</CopyOutput> - </Inf> <MessageCompile Include="osrusbfx2.man"> <GenerateKernelModeLoggingMacros>true</GenerateKernelModeLoggingMacros> <GenerateMofFile>true</GenerateMofFile> @@ -204,10 +201,6 @@ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ALLOW_DATE_TIME>1</ALLOW_DATE_TIME> </PropertyGroup> - <ItemGroup> - <FilesToPackage Include="..\deviceMetadata\B4D697F5-1C56-4807-ACCD-B28C09D37FF0.devicemetadata-ms" /> - <None Include="..\deviceMetadata\B4D697F5-1C56-4807-ACCD-B28C09D37FF0.devicemetadata-ms" /> - </ItemGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ClCompile> <ExceptionHandling> @@ -240,27 +233,9 @@ <FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" /> </ItemGroup> <ItemGroup> - <None Include="*.txt" Exclude="@(None)" /> - <None Include="*.htm" Exclude="@(None)" /> - <None Include="*.html" Exclude="@(None)" /> - <None Include="*.ico" Exclude="@(None)" /> - <None Include="*.cur" Exclude="@(None)" /> - <None Include="*.bmp" Exclude="@(None)" /> - <None Include="*.dlg" Exclude="@(None)" /> - <None Include="*.rct" Exclude="@(None)" /> - <None Include="*.gif" Exclude="@(None)" /> - <None Include="*.jpg" Exclude="@(None)" /> - <None Include="*.jpeg" Exclude="@(None)" /> - <None Include="*.wav" Exclude="@(None)" /> - <None Include="*.jpe" Exclude="@(None)" /> - <None Include="*.tiff" Exclude="@(None)" /> - <None Include="*.tif" Exclude="@(None)" /> - <None Include="*.png" Exclude="@(None)" /> - <None Include="*.rc2" Exclude="@(None)" /> - <None Include="*.def" Exclude="@(None)" /> - <None Include="*.bat" Exclude="@(None)" /> - <None Include="*.hpj" Exclude="@(None)" /> - <None Include="*.asmx" Exclude="@(None)" /> + <None Exclude="@(None)" Include="*.txt;*.htm;*.html" /> + <None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" /> + <None Exclude="@(None)" Include="*.def;*.bat;*.hpj;*.asmx" /> </ItemGroup> <ItemGroup> <ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" /> diff --git a/usb/kmdf_fx2/driver/osrusbfx2.vcxproj.Filters b/usb/kmdf_fx2/driver/osrusbfx2.vcxproj.Filters index 296911ee..baf7ab2e 100644 --- a/usb/kmdf_fx2/driver/osrusbfx2.vcxproj.Filters +++ b/usb/kmdf_fx2/driver/osrusbfx2.vcxproj.Filters @@ -3,19 +3,19 @@ <ItemGroup> <Filter Include="Source Files"> <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions> - <UniqueIdentifier>{50246F0E-8E24-4871-83C5-D835604F0997}</UniqueIdentifier> + <UniqueIdentifier>{F859293F-10B7-4E6D-99E2-120A09448FF9}</UniqueIdentifier> </Filter> <Filter Include="Header Files"> <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> - <UniqueIdentifier>{3A59DDAC-0E70-44F4-BDA7-AF03A36ADAD4}</UniqueIdentifier> + <UniqueIdentifier>{3DCE0FEA-C37D-448E-B9E4-B69865E71B5F}</UniqueIdentifier> </Filter> <Filter Include="Resource Files"> <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions> - <UniqueIdentifier>{E82DF9C5-AE82-4CFF-A0C5-AA939075A927}</UniqueIdentifier> + <UniqueIdentifier>{A1BB449A-54EF-4B2B-BD68-2254963FF387}</UniqueIdentifier> </Filter> <Filter Include="Driver Files"> <Extensions>inf;inv;inx;mof;mc;</Extensions> - <UniqueIdentifier>{57D03874-86BB-4AC8-B719-A39C7A4EF75F}</UniqueIdentifier> + <UniqueIdentifier>{A03D3DFA-E9BD-48A3-BEDE-E8AAED283D03}</UniqueIdentifier> </Filter> </ItemGroup> <ItemGroup> @@ -36,11 +36,6 @@ </ClCompile> </ItemGroup> <ItemGroup> - <Inf Include=".\osrusbfx2.inx"> - <Filter>Driver Files</Filter> - </Inf> - </ItemGroup> - <ItemGroup> <MessageCompile Include="osrusbfx2.man"> <Filter>Resource Files</Filter> </MessageCompile> diff --git a/usb/kmdf_fx2/exe/osrusbfx2.vcxproj b/usb/kmdf_fx2/exe/osrusbfx2.vcxproj index b2388c67..9da8f04b 100644 --- a/usb/kmdf_fx2/exe/osrusbfx2.vcxproj +++ b/usb/kmdf_fx2/exe/osrusbfx2.vcxproj @@ -19,11 +19,11 @@ </ProjectConfiguration> </ItemGroup> <PropertyGroup Label="Globals"> - <ProjectGuid>{7289C9A2-233A-449D-AEEC-0D9FC929E0F0}</ProjectGuid> + <ProjectGuid>{6EED5CDD-5526-40DC-97F9-582857E10187}</ProjectGuid> <RootNamespace>$(MSBuildProjectName)</RootNamespace> <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration> <Platform Condition="'$(Platform)' == ''">Win32</Platform> - <SampleGuid>{6BC89B61-F14B-48F5-93B6-6F897425DDDA}</SampleGuid> + <SampleGuid>{F19E45AF-8B05-4204-A66B-9BDBFE333233}</SampleGuid> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> diff --git a/usb/kmdf_fx2/exe/osrusbfx2.vcxproj.Filters b/usb/kmdf_fx2/exe/osrusbfx2.vcxproj.Filters index 485e09f4..f9efc3e3 100644 --- a/usb/kmdf_fx2/exe/osrusbfx2.vcxproj.Filters +++ b/usb/kmdf_fx2/exe/osrusbfx2.vcxproj.Filters @@ -3,15 +3,15 @@ <ItemGroup> <Filter Include="Source Files"> <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions> - <UniqueIdentifier>{2C8645BA-E3D5-49E8-97D5-033593663D52}</UniqueIdentifier> + <UniqueIdentifier>{D5BFAD22-1AD2-44F8-AC33-05C04A9C26D9}</UniqueIdentifier> </Filter> <Filter Include="Header Files"> <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> - <UniqueIdentifier>{F8EADFE4-D5EF-4492-96A2-7C5534C7FEF2}</UniqueIdentifier> + <UniqueIdentifier>{14E678C7-EAC3-42F6-9F4B-2CDD17427D73}</UniqueIdentifier> </Filter> <Filter Include="Resource Files"> <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions> - <UniqueIdentifier>{61995FA8-8FC0-43EA-A5CA-17AEEA8827B6}</UniqueIdentifier> + <UniqueIdentifier>{CEE0A75C-90B6-472A-8FC1-9375F1EAD2C9}</UniqueIdentifier> </Filter> </ItemGroup> <ItemGroup> diff --git a/usb/kmdf_fx2/inc/public.h b/usb/kmdf_fx2/inc/public.h index 12ddf21f..f1fc6be3 100644 --- a/usb/kmdf_fx2/inc/public.h +++ b/usb/kmdf_fx2/inc/public.h @@ -119,7 +119,7 @@ typedef struct _SWITCH_STATE { #pragma warning(pop) #define IOCTL_INDEX 0x800 -#define FILE_DEVICE_OSRUSBFX2 0x65500 +#define FILE_DEVICE_OSRUSBFX2 65500U #define IOCTL_OSRUSBFX2_GET_CONFIG_DESCRIPTOR CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ IOCTL_INDEX, \ diff --git a/usb/kmdf_fx2/kmdf_fx2.sln b/usb/kmdf_fx2/kmdf_fx2.sln index 59e8e548..1f176bb1 100644 --- a/usb/kmdf_fx2/kmdf_fx2.sln +++ b/usb/kmdf_fx2/kmdf_fx2.sln @@ -3,13 +3,13 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2013 VisualStudioVersion = 12.0 MinimumVisualStudioVersion = 12.0 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Driver", "Driver", "{219EAF9D-A9F6-4F9D-897D-91AB46B2A71B}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Driver", "Driver", "{BCB7D745-20C8-48E1-A792-F708EF65B29F}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Exe", "Exe", "{7E5E361E-E36E-4728-9D4C-E030A0134F40}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Exe", "Exe", "{4B2BB962-B51B-42F1-9EF7-06025B7A8E83}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "osrusbfx2", "driver\osrusbfx2.vcxproj", "{E7ECAF21-2522-4E7D-8475-67C4A5E43F70}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "osrusbfx2", "driver\osrusbfx2.vcxproj", "{CACAC18F-9566-4F5B-AB98-CB50469D850A}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "osrusbfx2", "exe\osrusbfx2.vcxproj", "{7289C9A2-233A-449D-AEEC-0D9FC929E0F0}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "osrusbfx2", "exe\osrusbfx2.vcxproj", "{1EDF6B64-0C4A-4481-AD82-D42C0EA2CF58}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -19,28 +19,28 @@ Global Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {E7ECAF21-2522-4E7D-8475-67C4A5E43F70}.Debug|Win32.ActiveCfg = Debug|Win32 - {E7ECAF21-2522-4E7D-8475-67C4A5E43F70}.Debug|Win32.Build.0 = Debug|Win32 - {E7ECAF21-2522-4E7D-8475-67C4A5E43F70}.Release|Win32.ActiveCfg = Release|Win32 - {E7ECAF21-2522-4E7D-8475-67C4A5E43F70}.Release|Win32.Build.0 = Release|Win32 - {E7ECAF21-2522-4E7D-8475-67C4A5E43F70}.Debug|x64.ActiveCfg = Debug|x64 - {E7ECAF21-2522-4E7D-8475-67C4A5E43F70}.Debug|x64.Build.0 = Debug|x64 - {E7ECAF21-2522-4E7D-8475-67C4A5E43F70}.Release|x64.ActiveCfg = Release|x64 - {E7ECAF21-2522-4E7D-8475-67C4A5E43F70}.Release|x64.Build.0 = Release|x64 - {7289C9A2-233A-449D-AEEC-0D9FC929E0F0}.Debug|Win32.ActiveCfg = Debug|Win32 - {7289C9A2-233A-449D-AEEC-0D9FC929E0F0}.Debug|Win32.Build.0 = Debug|Win32 - {7289C9A2-233A-449D-AEEC-0D9FC929E0F0}.Release|Win32.ActiveCfg = Release|Win32 - {7289C9A2-233A-449D-AEEC-0D9FC929E0F0}.Release|Win32.Build.0 = Release|Win32 - {7289C9A2-233A-449D-AEEC-0D9FC929E0F0}.Debug|x64.ActiveCfg = Debug|x64 - {7289C9A2-233A-449D-AEEC-0D9FC929E0F0}.Debug|x64.Build.0 = Debug|x64 - {7289C9A2-233A-449D-AEEC-0D9FC929E0F0}.Release|x64.ActiveCfg = Release|x64 - {7289C9A2-233A-449D-AEEC-0D9FC929E0F0}.Release|x64.Build.0 = Release|x64 + {CACAC18F-9566-4F5B-AB98-CB50469D850A}.Debug|Win32.ActiveCfg = Debug|Win32 + {CACAC18F-9566-4F5B-AB98-CB50469D850A}.Debug|Win32.Build.0 = Debug|Win32 + {CACAC18F-9566-4F5B-AB98-CB50469D850A}.Release|Win32.ActiveCfg = Release|Win32 + {CACAC18F-9566-4F5B-AB98-CB50469D850A}.Release|Win32.Build.0 = Release|Win32 + {CACAC18F-9566-4F5B-AB98-CB50469D850A}.Debug|x64.ActiveCfg = Debug|x64 + {CACAC18F-9566-4F5B-AB98-CB50469D850A}.Debug|x64.Build.0 = Debug|x64 + {CACAC18F-9566-4F5B-AB98-CB50469D850A}.Release|x64.ActiveCfg = Release|x64 + {CACAC18F-9566-4F5B-AB98-CB50469D850A}.Release|x64.Build.0 = Release|x64 + {1EDF6B64-0C4A-4481-AD82-D42C0EA2CF58}.Debug|Win32.ActiveCfg = Debug|Win32 + {1EDF6B64-0C4A-4481-AD82-D42C0EA2CF58}.Debug|Win32.Build.0 = Debug|Win32 + {1EDF6B64-0C4A-4481-AD82-D42C0EA2CF58}.Release|Win32.ActiveCfg = Release|Win32 + {1EDF6B64-0C4A-4481-AD82-D42C0EA2CF58}.Release|Win32.Build.0 = Release|Win32 + {1EDF6B64-0C4A-4481-AD82-D42C0EA2CF58}.Debug|x64.ActiveCfg = Debug|x64 + {1EDF6B64-0C4A-4481-AD82-D42C0EA2CF58}.Debug|x64.Build.0 = Debug|x64 + {1EDF6B64-0C4A-4481-AD82-D42C0EA2CF58}.Release|x64.ActiveCfg = Release|x64 + {1EDF6B64-0C4A-4481-AD82-D42C0EA2CF58}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {E7ECAF21-2522-4E7D-8475-67C4A5E43F70} = {219EAF9D-A9F6-4F9D-897D-91AB46B2A71B} - {7289C9A2-233A-449D-AEEC-0D9FC929E0F0} = {7E5E361E-E36E-4728-9D4C-E030A0134F40} + {CACAC18F-9566-4F5B-AB98-CB50469D850A} = {BCB7D745-20C8-48E1-A792-F708EF65B29F} + {1EDF6B64-0C4A-4481-AD82-D42C0EA2CF58} = {4B2BB962-B51B-42F1-9EF7-06025B7A8E83} EndGlobalSection EndGlobal diff --git a/usb/ufxclientsample/UfxClientSample.man b/usb/ufxclientsample/UfxClientSample.man index 122aa6dd..6568d6e7 100644 --- a/usb/ufxclientsample/UfxClientSample.man +++ b/usb/ufxclientsample/UfxClientSample.man @@ -114,23 +114,23 @@ outType="xs:string" /> <data - inType="win:UInt32" + inType="win:Pointer" name="Endpoint" - outType="win:HexInt32" + outType="win:HexInt64" /> <data inType="win:UInt32" name="PhysicalEndpoint" /> <data - inType="win:UInt32" + inType="win:Pointer" name="Request" - outType="win:HexInt32" + outType="win:HexInt64" /> <data - inType="win:UInt32" + inType="win:Pointer" name="Transaction" - outType="win:HexInt32" + outType="win:HexInt64" /> <data inType="win:UInt32" diff --git a/usb/ufxclientsample/device.c b/usb/ufxclientsample/device.c index 8bb12b52..3aa46c4c 100644 --- a/usb/ufxclientsample/device.c +++ b/usb/ufxclientsample/device.c @@ -536,7 +536,7 @@ Arguments: #pragma prefast(suppress:6014, "Memory allocation is expected") HardwareFailureContext = ExAllocatePoolWithTag( - NonPagedPool, + NonPagedPoolNx, sizeof(HARDWARE_FAILURE_CONTEXT), UFX_CLIENT_TAG); diff --git a/usb/ufxclientsample/transfer.c b/usb/ufxclientsample/transfer.c index 0a34b8f4..e1ed6a45 100644 --- a/usb/ufxclientsample/transfer.c +++ b/usb/ufxclientsample/transfer.c @@ -50,7 +50,7 @@ TraceTransfer ( SgProgrammed = 0; SgLength = 0; - if (Request == NULL) { + if (Request == NULL) { Transaction = UfxEndpointGetTransferContext(Endpoint)->Transaction; if (Transaction != NULL) { PDMA_CONTEXT DmaContext; @@ -78,22 +78,22 @@ TraceTransfer ( } } - EventWriteTransfer( - &UfxClientSampleGuid, + EventWriteTransfer( + &UfxClientSampleGuid, Stage, - (ULONG) Endpoint, + Endpoint, UfxEndpointGetContext(Endpoint)->PhysicalEndpoint, - (ULONG) Request, - (ULONG) Transaction, + Request, + Transaction, BytesRequested, BytesProgrammed, BytesTransferred, SgProgrammed, SgLength); - TraceInformation("TRANSFER %s: %08X (%d), RQ: %08X, DMA: %08X, BytesReq: %08X, BytesProg: %08X, BytesTrans: %08X, SG: %d/%d", - Stage, (ULONG) Endpoint, UfxEndpointGetContext(Endpoint)->PhysicalEndpoint, (ULONG) Request, - (ULONG) Transaction, BytesRequested, BytesProgrammed, BytesTransferred, SgProgrammed, SgLength); + TraceInformation("TRANSFER %s: 0x%p (%d), RQ: 0x%p, DMA: 0x%p, BytesReq: %08X, BytesProg: %08X, BytesTrans: %08X, SG: %d/%d", + Stage, Endpoint, UfxEndpointGetContext(Endpoint)->PhysicalEndpoint, Request, + Transaction, BytesRequested, BytesProgrammed, BytesTransferred, SgProgrammed, SgLength); } #define TRACE_TRANSFER(Stage, Endpoint, Request) \ @@ -178,7 +178,7 @@ Parameters Description: --*/ { PTRANSFER_CONTEXT TransferContext; - + TraceEntry(); TransferContext = UfxEndpointGetTransferContext(Endpoint); @@ -342,7 +342,7 @@ Parameters Description: TraceEntry(); TransferContext = UfxEndpointGetTransferContext(Endpoint); - + if (TransferContext->TransferStarted) { TransferCommandUpdate(Endpoint); @@ -374,7 +374,7 @@ Parameters Description: NTSTATUS Status; PDMA_CONTEXT DmaContext; UFXENDPOINT Endpoint; - + DmaContext = DmaGetContext(Transaction); Endpoint = DmaContext->Endpoint; @@ -408,12 +408,12 @@ OnEvtRequestCancel ( Routine Description: EvtRequestCancel callback for cancellable transfer requests. - This cancels a programmed transfer request by issuing a corresponding + This cancels a programmed transfer request by issuing a corresponding 'TransferEnd' command to the contoller. Parameters Description: - Request - Request being cancelled. + Request - Request being cancelled. --*/ { @@ -431,14 +431,14 @@ TransferRequestCancel ( /*++ Routine Description: - This cancels a programmed transfer request by issuing a corresponding + This cancels a programmed transfer request by issuing a corresponding 'TransferEnd' command to the contoller. Parameters Description: - Request - Request being cancelled. + Request - Request being cancelled. - QueueIsStopped - indicates if this request is being stopped and cancellation + QueueIsStopped - indicates if this request is being stopped and cancellation should avoid fetching subsequent request from queue --*/ @@ -465,7 +465,7 @@ Parameters Description: Status = WdfRequestUnmarkCancelable(Request); CHK_NT_MSG(Status, "WdfRequestUnmarkCancelable failed during queue stop"); - + } else { TRACE_TRANSFER("CANCEL", Endpoint, Request); } @@ -493,7 +493,7 @@ Parameters Description: // is considered an error by driver verifier since the DMA state is // FxDmaTransactionStateTransferFailed. // - + DmaContext->State = Cancelled; } else { @@ -510,7 +510,7 @@ Parameters Description: if (TransferContext->TransferStarted) { TransferContext->CleanupOnEndComplete = TRUE; TransferCommandEnd(Endpoint); - + } else if (Cleanup) { NewTransaction = TransferCancelCleanup(Endpoint); } @@ -552,7 +552,7 @@ Parameters Description: // // Start transfer // - + TransferCommandStart(Endpoint); ControlContext->SetupRequested = TRUE; ControlContext->HandshakeRequested = FALSE; @@ -603,7 +603,7 @@ Parameters Description: ControlContext = UfxEndpointGetControlContext(Endpoint); RequestToCancel = ControlContext->HandshakeRequest; - } + } // // Before canceling, we need to make sure we can unmark it cancelable. @@ -660,7 +660,7 @@ Parameters Description: Transaction = TransferContext->Transaction; if (Transaction != NULL) { PDMA_CONTEXT DmaContext; - + DmaContext = DmaGetContext(Transaction); RequestToCancel = DmaContext->Request; @@ -700,13 +700,13 @@ Parameters Description: FetchNextRequest = !RequestContext->QueueIsStopped; Referenced = RequestContext->ReferencedOnCancel; - + // // In case the completion work-item has already been queued, prevent // it from also trying to complete this request when it executes. // TransferContext->PendingCompletion = FALSE; - + WdfRequestComplete(RequestToCancel, STATUS_CANCELLED); if (Referenced) { WdfObjectDereference(RequestToCancel); @@ -720,7 +720,7 @@ Parameters Description: if (TransferContext->Stalled) { CommandStallClear(Endpoint); } - + // // Bring control endpoint back to setup stage. // @@ -768,7 +768,7 @@ Return Value: PUFXENDPOINT_CONTEXT EpContext; TraceEntry(); - + TransferContext = UfxEndpointGetTransferContext(Endpoint); EpContext = UfxEndpointGetContext(Endpoint); DmaContext = DmaGetContext(Transaction); @@ -795,7 +795,7 @@ Return Value: // // #### TODO: Insert code to map scatter gather buffers to controller transfer structures #### // - + // // Need to remember how much we really programmed // @@ -818,9 +818,9 @@ Return Value: TRACE_TRANSFER("EXTRA", Endpoint, DmaContext->Request); // - // #### TODO: Insert code to append an extra buffer to the transfer structures #### + // #### TODO: Insert code to append an extra buffer to the transfer structures #### // - + } // @@ -897,7 +897,7 @@ Parameters Description: // Status = WdfRequestUnmarkCancelable(DmaContext->Request); CHK_NT_MSG(Status, "WdfRequestUnmarkCancelable failed during programming"); - + Status = WdfRequestMarkCancelableEx(DmaContext->Request, OnEvtRequestCancel); if (Status == STATUS_CANCELLED) { LOG_NT_MSG(Status, "Request cancelled during programming"); @@ -953,7 +953,7 @@ Parameters Description: TransferContext->CleanupOnEndComplete = FALSE; Transaction = TransferCancelCleanup(Endpoint); } - + TransferUnlock(Endpoint); TransferDmaExecute(Transaction); TraceExit(); @@ -989,30 +989,30 @@ Parameters Description: // // #### TODO: Insert code to determine status of command #### // - + // sample will assume no error for illustration purposes CommandStatus = 0; - + // // Command start has failed. Clean up the request. // if (CommandStatus != 0) { TRACE_TRANSFER("START FAIL", Endpoint, NULL); - + TransferContext->TransferStarted = FALSE; - + if (CONTROL_ENDPOINT(Endpoint)) { PCONTROL_CONTEXT ControlContext; - + ControlContext = UfxEndpointGetControlContext(Endpoint); - + if (ControlContext->SetupRequested) { // // Error on a setup request. Wait for host to reset us or user reconnect. // TraceError("ERROR: Failed a setup packet!"); NT_ASSERT(FALSE); - + } else { CommandStallSet(Endpoint); } @@ -1020,7 +1020,7 @@ Parameters Description: } else { Transaction = TransferRequestTryUnmarkCancelableAndCleanup(Endpoint); } - + } else { TransferContext->TransferCommandStartComplete = TRUE; } @@ -1068,7 +1068,7 @@ Parameters Description: } Transaction = TransferContext->Transaction; - + // // Make sure request wasn't cancelled before work item got to run. // @@ -1091,7 +1091,7 @@ Parameters Description: BytesTransferred = DmaContext->BytesProgrammed - DmaContext->BytesRemaining; if (BytesTransferred > DmaContext->BytesRequested) { TraceWarning("Transferred more than what is asked for: " - "Bytes Requested: %d, Bytes Transferred:%d", + "Bytes Requested: %d, Bytes Transferred:%d", DmaContext->BytesRequested, BytesTransferred); BytesTransferred = DmaContext->BytesRequested; } @@ -1112,7 +1112,7 @@ Parameters Description: TransferContext->TransferStarted = FALSE; Transaction = TransferNextRequest(Endpoint); -End: +End: TransferUnlock(Endpoint); if (Transaction != NULL) { @@ -1169,16 +1169,16 @@ Parameters Description: // Sample will assume transfer is complete TransferComplete = TRUE; - + // - // If the transfer is complete we need to complete the request. + // If the transfer is complete we need to complete the request. // if (TransferComplete) { DmaContext->BytesRemaining = BytesRemaining; TRACE_TRANSFER("COMPLETE (Last packet or short packet)", Endpoint, NULL); TransferContext->PendingCompletion = TRUE; WdfWorkItemEnqueue(TransferContext->CompletionWorkItem); - + // // If transfer is still in progress, we need to program more transfers // @@ -1200,7 +1200,7 @@ Parameters Description: if (Status != STATUS_MORE_PROCESSING_REQUIRED && !NT_SUCCESS(Status)) { NewTransaction = TransferRequestTryUnmarkCancelableAndCleanup(Endpoint); - } + } } End: @@ -1242,7 +1242,7 @@ Parameters Description: // if (ControlContext->SetupRequested) { TRACE_TRANSFER("COMPLETE (Setup)", Endpoint, NULL); - + ControlContext->SetupRequested = FALSE; TransferContext->TransferStarted = FALSE; @@ -1255,7 +1255,7 @@ Parameters Description: NTSTATUS Status; TRACE_TRANSFER("COMPLETE (Handshake)", Endpoint, ControlContext->HandshakeRequest); - + Status = WdfRequestUnmarkCancelable(ControlContext->HandshakeRequest); if (Status != STATUS_CANCELLED) { WdfRequestComplete(ControlContext->HandshakeRequest, Status); @@ -1366,7 +1366,7 @@ Parameters Description: SetupPacketBuffer = NULL; if (CONTROL_ENDPOINT(Endpoint)) { PCONTROL_CONTEXT ControlContext; - + ControlContext = UfxEndpointGetControlContext(Endpoint); SetupPacketBuffer = ControlContext->SetupPacketBuffer; ControlContext->SetupPacketBuffer = NULL; @@ -1469,16 +1469,16 @@ Return Value: } Buffer = WdfCommonBufferGetAlignedVirtualAddress(TransferContext->CommonBuffer); - TransferContext->LogicalCommonBuffer = - WdfCommonBufferGetAlignedLogicalAddress(TransferContext->CommonBuffer); + TransferContext->LogicalCommonBuffer = + WdfCommonBufferGetAlignedLogicalAddress(TransferContext->CommonBuffer); TransferContext->Buffer = Buffer; RtlZeroMemory(TransferContext->CommonBuffer, ENDPOINT_COMMON_BUFFER_SIZE); - + // // #### TODO: Insert code to initialize controller data structures in the shared common buffer // - + // // Map physical endpoint // @@ -1663,7 +1663,7 @@ Parameters Description: ControlContext = UfxEndpointGetControlContext(Endpoint); ControlContext->DataStageExists = TRUE; } - + // // Keep track of DMA // @@ -1683,7 +1683,7 @@ Parameters Description: if (DmaContext->BytesRequested == 0) { DmaContext->ZeroLength = TRUE; - + TRACE_TRANSFER("ZERO LENGTH", Endpoint, DmaContext->Request); DmaContext->ExtraBytes = 0; @@ -1704,7 +1704,7 @@ Parameters Description: // // Caller is expected to execute the DMA. // - } + } End: if (!NT_SUCCESS(Status)) { @@ -1715,7 +1715,7 @@ End: Transaction = NULL; } } - + TraceExit(); return Transaction; } @@ -1848,23 +1848,23 @@ Fetch: } CHK_NT_MSG(Status, "Failed to retrieve next request"); - + WDF_REQUEST_PARAMETERS_INIT(&Params); WdfRequestGetParameters(Request, &Params); Ioctl = Params.Parameters.DeviceIoControl.IoControlCode; if (Ioctl == IOCTL_INTERNAL_USBFN_CONTROL_STATUS_HANDSHAKE_IN) { TransferHandshake(Endpoint, Request, TRUE); - + } else if (Ioctl == IOCTL_INTERNAL_USBFN_CONTROL_STATUS_HANDSHAKE_OUT) { TransferHandshake(Endpoint, Request, FALSE); - + } else if (DIRECTION_IN(Endpoint) && Ioctl == IOCTL_INTERNAL_USBFN_TRANSFER_IN) { Transaction = TransferBegin(Endpoint, Request, TRUE, FALSE); - } else if (DIRECTION_IN(Endpoint) && + } else if (DIRECTION_IN(Endpoint) && Ioctl == IOCTL_INTERNAL_USBFN_TRANSFER_IN_APPEND_ZERO_PKT) { Transaction = TransferBegin(Endpoint, Request, TRUE, TRUE); @@ -1875,8 +1875,8 @@ Fetch: Transaction = TransferBegin(Endpoint, Request, FALSE, FALSE); } else { - TraceWarning("INVALID: %08X (%d), Ioctl: %08X", - (ULONG) Endpoint, EpContext->PhysicalEndpoint, Ioctl); + TraceWarning("INVALID: 0x%p (%d), Ioctl: %08X", + Endpoint, EpContext->PhysicalEndpoint, Ioctl); WdfRequestComplete(Request, STATUS_INVALID_DEVICE_REQUEST); goto Fetch; } @@ -1912,7 +1912,7 @@ Parameters Description: EpContext = UfxEndpointGetContext(Endpoint); TransferContext = UfxEndpointGetTransferContext(Endpoint); - + TransferLock(Endpoint); TRACE_TRANSFER("RESET", Endpoint, NULL); @@ -1939,7 +1939,7 @@ Parameters Description: TransferCommandEnd(Endpoint); } } - + TransferUnlock(Endpoint); TraceExit(); } @@ -2080,7 +2080,7 @@ Parameters Description: NewTransaction = NULL; TransferLock(Endpoint); - + // // If we stall a control endpoint, we need to reset its state and start // over from the setup packet request. @@ -2091,7 +2091,7 @@ Parameters Description: NewTransaction = TransferRequestTryUnmarkCancelableAndCleanup(Endpoint); } } - + if (EpContext->StallRequest) { Request = EpContext->StallRequest; EpContext->StallRequest = NULL; @@ -2127,9 +2127,9 @@ Parameters Description: EpContext = UfxEndpointGetContext(Endpoint); TransferLock(Endpoint); - + NT_ASSERT(!CONTROL_ENDPOINT(Endpoint)); - + if (EpContext->ClearRequest) { Request = EpContext->ClearRequest; EpContext->ClearRequest = NULL; diff --git a/usb/ufxclientsample/ufxclientsample.sln b/usb/ufxclientsample/ufxclientsample.sln index 63b6eb8d..28afebbd 100644 --- a/usb/ufxclientsample/ufxclientsample.sln +++ b/usb/ufxclientsample/ufxclientsample.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2013 VisualStudioVersion = 12.0 MinimumVisualStudioVersion = 12.0 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ufxclientsample", "ufxclientsample.vcxproj", "{53F86825-E305-471C-8180-34E9987E4431}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ufxclientsample", "ufxclientsample.vcxproj", "{DC336318-35D0-4770-A842-46952EDD50D0}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -13,14 +13,14 @@ Global Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {53F86825-E305-471C-8180-34E9987E4431}.Debug|Win32.ActiveCfg = Debug|Win32 - {53F86825-E305-471C-8180-34E9987E4431}.Debug|Win32.Build.0 = Debug|Win32 - {53F86825-E305-471C-8180-34E9987E4431}.Release|Win32.ActiveCfg = Release|Win32 - {53F86825-E305-471C-8180-34E9987E4431}.Release|Win32.Build.0 = Release|Win32 - {53F86825-E305-471C-8180-34E9987E4431}.Debug|x64.ActiveCfg = Debug|x64 - {53F86825-E305-471C-8180-34E9987E4431}.Debug|x64.Build.0 = Debug|x64 - {53F86825-E305-471C-8180-34E9987E4431}.Release|x64.ActiveCfg = Release|x64 - {53F86825-E305-471C-8180-34E9987E4431}.Release|x64.Build.0 = Release|x64 + {DC336318-35D0-4770-A842-46952EDD50D0}.Debug|Win32.ActiveCfg = Debug|Win32 + {DC336318-35D0-4770-A842-46952EDD50D0}.Debug|Win32.Build.0 = Debug|Win32 + {DC336318-35D0-4770-A842-46952EDD50D0}.Release|Win32.ActiveCfg = Release|Win32 + {DC336318-35D0-4770-A842-46952EDD50D0}.Release|Win32.Build.0 = Release|Win32 + {DC336318-35D0-4770-A842-46952EDD50D0}.Debug|x64.ActiveCfg = Debug|x64 + {DC336318-35D0-4770-A842-46952EDD50D0}.Debug|x64.Build.0 = Debug|x64 + {DC336318-35D0-4770-A842-46952EDD50D0}.Release|x64.ActiveCfg = Release|x64 + {DC336318-35D0-4770-A842-46952EDD50D0}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/usb/ufxclientsample/ufxclientsample.vcxproj b/usb/ufxclientsample/ufxclientsample.vcxproj index df653028..9d7a21ff 100644 --- a/usb/ufxclientsample/ufxclientsample.vcxproj +++ b/usb/ufxclientsample/ufxclientsample.vcxproj @@ -19,18 +19,18 @@ </ProjectConfiguration> </ItemGroup> <PropertyGroup Label="Globals"> - <ProjectGuid>{53F86825-E305-471C-8180-34E9987E4431}</ProjectGuid> + <ProjectGuid>{DC336318-35D0-4770-A842-46952EDD50D0}</ProjectGuid> <RootNamespace>$(MSBuildProjectName)</RootNamespace> <KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR> <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration> <Platform Condition="'$(Platform)' == ''">Win32</Platform> - <SampleGuid>{0A165ABC-5762-4BCF-AE58-360CF9D52BD8}</SampleGuid> + <SampleGuid>{7554DEF4-B6D7-4342-9E53-4D8D6173C5E8}</SampleGuid> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <TargetVersion>Windows10</TargetVersion> <UseDebugLibraries>False</UseDebugLibraries> - <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverTargetPlatform>Universal</DriverTargetPlatform> <DriverType>KMDF</DriverType> <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> <ConfigurationType>Driver</ConfigurationType> @@ -38,7 +38,7 @@ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <TargetVersion>Windows10</TargetVersion> <UseDebugLibraries>True</UseDebugLibraries> - <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverTargetPlatform>Universal</DriverTargetPlatform> <DriverType>KMDF</DriverType> <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> <ConfigurationType>Driver</ConfigurationType> @@ -46,7 +46,7 @@ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <TargetVersion>Windows10</TargetVersion> <UseDebugLibraries>False</UseDebugLibraries> - <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverTargetPlatform>Universal</DriverTargetPlatform> <DriverType>KMDF</DriverType> <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> <ConfigurationType>Driver</ConfigurationType> @@ -54,7 +54,7 @@ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <TargetVersion>Windows10</TargetVersion> <UseDebugLibraries>True</UseDebugLibraries> - <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverTargetPlatform>Universal</DriverTargetPlatform> <DriverType>KMDF</DriverType> <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> <ConfigurationType>Driver</ConfigurationType> @@ -82,11 +82,6 @@ <WppModuleName>ufxclientsample</WppModuleName> <WppScanConfigurationData>trace.h</WppScanConfigurationData> </ClCompile> - <Inf Include=".\ufxclientsample.inx"> - <Architecture>$(InfArch)</Architecture> - <SpecifyArchitecture>true</SpecifyArchitecture> - <CopyOutput>.\$(IntDir)\ufxclientsample.inf</CopyOutput> - </Inf> <MessageCompile Include="ufxclientsample.man"> <GenerateKernelModeLoggingMacros>true</GenerateKernelModeLoggingMacros> <GenerateMofFile>true</GenerateMofFile> diff --git a/usb/ufxclientsample/ufxclientsample.vcxproj.Filters b/usb/ufxclientsample/ufxclientsample.vcxproj.Filters index ba38b7e1..9b7000eb 100644 --- a/usb/ufxclientsample/ufxclientsample.vcxproj.Filters +++ b/usb/ufxclientsample/ufxclientsample.vcxproj.Filters @@ -3,19 +3,19 @@ <ItemGroup> <Filter Include="Source Files"> <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions> - <UniqueIdentifier>{913D3EC7-37FD-4BC5-B8F3-5B0316F839BD}</UniqueIdentifier> + <UniqueIdentifier>{4F0B7594-FA2A-4042-8049-D0430408CF13}</UniqueIdentifier> </Filter> <Filter Include="Header Files"> <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> - <UniqueIdentifier>{CFA48238-7E09-4139-BABE-B24CA80F2A32}</UniqueIdentifier> + <UniqueIdentifier>{D0032D76-9227-4277-A41F-DB8C231318A3}</UniqueIdentifier> </Filter> <Filter Include="Resource Files"> <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions> - <UniqueIdentifier>{088F289C-03FC-4BBE-B6D4-FEBA220934FD}</UniqueIdentifier> + <UniqueIdentifier>{9A2DC11D-9B3A-43E6-B800-D10DB0FD86A7}</UniqueIdentifier> </Filter> <Filter Include="Driver Files"> <Extensions>inf;inv;inx;mof;mc;</Extensions> - <UniqueIdentifier>{B057205B-0933-44FF-A94F-65B1491C15CE}</UniqueIdentifier> + <UniqueIdentifier>{1C7FA3C4-EB62-4228-BDC6-545602320AC5}</UniqueIdentifier> </Filter> </ItemGroup> <ItemGroup> @@ -48,11 +48,6 @@ </ClCompile> </ItemGroup> <ItemGroup> - <Inf Include=".\ufxclientsample.inx"> - <Filter>Driver Files</Filter> - </Inf> - </ItemGroup> - <ItemGroup> <MessageCompile Include="ufxclientsample.man"> <Filter>Resource Files</Filter> </MessageCompile> diff --git a/usb/ufxclientsample/ufxendpoint.c b/usb/ufxclientsample/ufxendpoint.c index 195501ec..fbc45e56 100644 --- a/usb/ufxclientsample/ufxendpoint.c +++ b/usb/ufxclientsample/ufxendpoint.c @@ -91,7 +91,7 @@ Return Value: // WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&TransferQueueAttributes, ENDPOINT_QUEUE_CONTEXT); TransferQueueAttributes.ExecutionLevel = WdfExecutionLevelPassive; - + WDF_IO_QUEUE_CONFIG_INIT(&TransferQueueConfig, WdfIoQueueDispatchManual); TransferQueueConfig.AllowZeroLengthRequests = TRUE; TransferQueueConfig.EvtIoStop = EndpointQueue_EvtIoStop; @@ -134,7 +134,7 @@ Return Value: Status = TransferInitialize(Endpoint); CHK_NT_MSG(Status, "Failed to initialize endpoint transfers"); - + // // This can happen if we're handling a SetInterface command. // @@ -182,11 +182,11 @@ Parameters Description: EpContext = UfxEndpointGetContext(Endpoint); - TraceInformation("CONFIGURE ENDPOINT: %08X Endpoint (%d)", (ULONG) Endpoint, EpContext->PhysicalEndpoint); + TraceInformation("CONFIGURE ENDPOINT: 0x%p Endpoint (%d)", Endpoint, EpContext->PhysicalEndpoint); // // ControllerContext = DeviceGetControllerContext(EpContext->WdfDevice); - // + // // The USB address is: // EpContext->Descriptor.bEndpointAddress & USB_ENDPOINT_ADDRESS_MASK // @@ -248,12 +248,12 @@ Parameters Description: } Address = EpContext->Descriptor.bEndpointAddress & USB_ENDPOINT_ADDRESS_MASK; - + // // Configure the endpoint // UfxEndpointConfigureHardware(Endpoint, Address == 0); - + // // #### TODO: Insert code to enable the endpoint on the controller #### // @@ -291,7 +291,7 @@ Return Value: --*/ { PUFXENDPOINT_CONTEXT EpContext; - + TraceEntry(); EpContext = UfxEndpointGetContext(Endpoint); @@ -383,14 +383,14 @@ Parameters Description: Request - The request to be completed, requeued, or suspended. ActionFlags - Bitmask indicating action to take and if request is cancelable. - + --*/ -{ +{ UNREFERENCED_PARAMETER(Queue); UNREFERENCED_PARAMETER(ActionFlags); TraceEntry(); - + TransferRequestCancel(Request, TRUE); TraceExit(); @@ -420,7 +420,7 @@ Parameters Description: InputBufferLength - size of the input buffer. IoControlCode - IOCTL for the request. - + --*/ { @@ -433,7 +433,7 @@ Parameters Description: UNREFERENCED_PARAMETER(InputBufferLength); TraceEntry(); - + QueueContext = EndpointQueueGetContext(Queue); EpContext = UfxEndpointGetContext(QueueContext->Endpoint); @@ -472,7 +472,7 @@ Parameters Description: Status = STATUS_INVALID_DEVICE_REQUEST; goto End; } - + End: if (!NT_SUCCESS(Status)) { WdfRequestComplete(Request, Status); diff --git a/usb/umdf2_fx2/driver/driver.c b/usb/umdf2_fx2/driver/driver.c index 10bf3d39..fb00f9de 100644 --- a/usb/umdf2_fx2/driver/driver.c +++ b/usb/umdf2_fx2/driver/driver.c @@ -110,9 +110,6 @@ Return Value: TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, "OSRUSBFX2 Driver Sample - Driver Framework Edition.\n"); - TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, - "Built %s %s\n", __DATE__, __TIME__); - // // Register with ETW (unified tracing) // diff --git a/usb/umdf2_fx2/driver/osrusbfx2um.inx b/usb/umdf2_fx2/driver/osrusbfx2um.inx Binary files differindex 4f445ae3..41879bce 100644 --- a/usb/umdf2_fx2/driver/osrusbfx2um.inx +++ b/usb/umdf2_fx2/driver/osrusbfx2um.inx diff --git a/usb/umdf2_fx2/driver/osrusbfx2um.vcxproj b/usb/umdf2_fx2/driver/osrusbfx2um.vcxproj index b6b1e253..8e3127cd 100644 --- a/usb/umdf2_fx2/driver/osrusbfx2um.vcxproj +++ b/usb/umdf2_fx2/driver/osrusbfx2um.vcxproj @@ -19,12 +19,12 @@ </ProjectConfiguration> </ItemGroup> <PropertyGroup Label="Globals"> - <ProjectGuid>{AC913FF4-1E9D-4666-BA65-BA9C3C6BDC7A}</ProjectGuid> + <ProjectGuid>{5B711254-3F53-4E1D-A1AD-CC81E34588B7}</ProjectGuid> <RootNamespace>$(MSBuildProjectName)</RootNamespace> <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR> <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration> <Platform Condition="'$(Platform)' == ''">Win32</Platform> - <SampleGuid>{C259646B-9566-4D0C-96B5-74D23C92DABF}</SampleGuid> + <SampleGuid>{F915ED95-7BE9-4CDB-B09A-0D3F4C9657FE}</SampleGuid> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> @@ -83,11 +83,6 @@ <WppGenerateUsingTemplateFile>{um-default.tpl}*.tmh</WppGenerateUsingTemplateFile> <WppPreprocessorDefinitions>ENABLE_WPP_RECORDER=1;WPP_MACRO_USE_KM_VERSION_FOR_UM=1</WppPreprocessorDefinitions> </ClCompile> - <Inf Include=".\osrusbfx2um.inx"> - <Architecture>$(InfArch)</Architecture> - <SpecifyArchitecture>true</SpecifyArchitecture> - <CopyOutput>.\$(IntDir)\osrusbfx2um.inf</CopyOutput> - </Inf> <MessageCompile Include="osrusbfx2.man"> <GenerateUserModeLoggingMacros>true</GenerateUserModeLoggingMacros> <GenerateMofFile>true</GenerateMofFile> diff --git a/usb/umdf2_fx2/driver/osrusbfx2um.vcxproj.Filters b/usb/umdf2_fx2/driver/osrusbfx2um.vcxproj.Filters index cf5c627c..45a570c5 100644 --- a/usb/umdf2_fx2/driver/osrusbfx2um.vcxproj.Filters +++ b/usb/umdf2_fx2/driver/osrusbfx2um.vcxproj.Filters @@ -3,19 +3,19 @@ <ItemGroup> <Filter Include="Source Files"> <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions> - <UniqueIdentifier>{043629B9-E054-4FF3-874E-548E7D4FFBB7}</UniqueIdentifier> + <UniqueIdentifier>{F15AAD6B-59E8-4958-90A3-552BD48EAFE2}</UniqueIdentifier> </Filter> <Filter Include="Header Files"> <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> - <UniqueIdentifier>{C31DA020-0B3B-4F1A-919E-C366757C9957}</UniqueIdentifier> + <UniqueIdentifier>{4DD84A7D-DF53-4EE0-A484-1352320A6750}</UniqueIdentifier> </Filter> <Filter Include="Resource Files"> <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions> - <UniqueIdentifier>{0D5B6280-46CF-448E-ACA9-DF9F20586F0A}</UniqueIdentifier> + <UniqueIdentifier>{EF018331-C5CB-4F90-8D54-2EF10F370E8A}</UniqueIdentifier> </Filter> <Filter Include="Driver Files"> <Extensions>inf;inv;inx;mof;mc;</Extensions> - <UniqueIdentifier>{B23BCA35-0435-4D67-8FEB-818995B8239C}</UniqueIdentifier> + <UniqueIdentifier>{9A3958FE-0B1F-4C9F-9827-83322770EC8A}</UniqueIdentifier> </Filter> </ItemGroup> <ItemGroup> @@ -36,11 +36,6 @@ </ClCompile> </ItemGroup> <ItemGroup> - <Inf Include=".\osrusbfx2um.inx"> - <Filter>Driver Files</Filter> - </Inf> - </ItemGroup> - <ItemGroup> <MessageCompile Include="osrusbfx2.man"> <Filter>Resource Files</Filter> </MessageCompile> diff --git a/usb/umdf2_fx2/exe/osrusbfx2.vcxproj b/usb/umdf2_fx2/exe/osrusbfx2.vcxproj index 8ebd4c2b..9da8f04b 100644 --- a/usb/umdf2_fx2/exe/osrusbfx2.vcxproj +++ b/usb/umdf2_fx2/exe/osrusbfx2.vcxproj @@ -19,11 +19,11 @@ </ProjectConfiguration> </ItemGroup> <PropertyGroup Label="Globals"> - <ProjectGuid>{9D6DB868-3478-4CD3-9C16-CE9E1FD04AA6}</ProjectGuid> + <ProjectGuid>{6EED5CDD-5526-40DC-97F9-582857E10187}</ProjectGuid> <RootNamespace>$(MSBuildProjectName)</RootNamespace> <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration> <Platform Condition="'$(Platform)' == ''">Win32</Platform> - <SampleGuid>{71E76691-6085-472A-AEE3-32F302D432A1}</SampleGuid> + <SampleGuid>{F19E45AF-8B05-4204-A66B-9BDBFE333233}</SampleGuid> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> diff --git a/usb/umdf2_fx2/exe/osrusbfx2.vcxproj.Filters b/usb/umdf2_fx2/exe/osrusbfx2.vcxproj.Filters index 189b77ca..f9efc3e3 100644 --- a/usb/umdf2_fx2/exe/osrusbfx2.vcxproj.Filters +++ b/usb/umdf2_fx2/exe/osrusbfx2.vcxproj.Filters @@ -3,15 +3,15 @@ <ItemGroup> <Filter Include="Source Files"> <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions> - <UniqueIdentifier>{7FC48C4A-E699-452E-9AC1-B87A1398097A}</UniqueIdentifier> + <UniqueIdentifier>{D5BFAD22-1AD2-44F8-AC33-05C04A9C26D9}</UniqueIdentifier> </Filter> <Filter Include="Header Files"> <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> - <UniqueIdentifier>{4AB8E4FC-C777-4E53-B3B1-546910707A69}</UniqueIdentifier> + <UniqueIdentifier>{14E678C7-EAC3-42F6-9F4B-2CDD17427D73}</UniqueIdentifier> </Filter> <Filter Include="Resource Files"> <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions> - <UniqueIdentifier>{9A57DDF7-3E20-42F4-BE75-466CADEFA001}</UniqueIdentifier> + <UniqueIdentifier>{CEE0A75C-90B6-472A-8FC1-9375F1EAD2C9}</UniqueIdentifier> </Filter> </ItemGroup> <ItemGroup> diff --git a/usb/umdf2_fx2/inc/public.h b/usb/umdf2_fx2/inc/public.h index 12ddf21f..f1fc6be3 100644 --- a/usb/umdf2_fx2/inc/public.h +++ b/usb/umdf2_fx2/inc/public.h @@ -119,7 +119,7 @@ typedef struct _SWITCH_STATE { #pragma warning(pop) #define IOCTL_INDEX 0x800 -#define FILE_DEVICE_OSRUSBFX2 0x65500 +#define FILE_DEVICE_OSRUSBFX2 65500U #define IOCTL_OSRUSBFX2_GET_CONFIG_DESCRIPTOR CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ IOCTL_INDEX, \ diff --git a/usb/umdf2_fx2/umdf2_fx2.sln b/usb/umdf2_fx2/umdf2_fx2.sln index fd2f0eb1..c878c062 100644 --- a/usb/umdf2_fx2/umdf2_fx2.sln +++ b/usb/umdf2_fx2/umdf2_fx2.sln @@ -3,13 +3,13 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2013 VisualStudioVersion = 12.0 MinimumVisualStudioVersion = 12.0 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Driver", "Driver", "{3868A978-E3AA-4A0C-B3CA-23BA75D19CF8}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Driver", "Driver", "{3B268182-F450-4AB8-B350-A2CF6495F756}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Exe", "Exe", "{60363E6C-E86C-42ED-8222-ACAC1F71D486}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Exe", "Exe", "{52ABC41E-9AAA-4DA8-8986-F6298E32C8A3}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "osrusbfx2um", "driver\osrusbfx2um.vcxproj", "{C25F378C-3D8F-4AF2-AFBB-7D438CBAB326}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "osrusbfx2um", "driver\osrusbfx2um.vcxproj", "{5B711254-3F53-4E1D-A1AD-CC81E34588B7}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "osrusbfx2", "exe\osrusbfx2.vcxproj", "{9D6DB868-3478-4CD3-9C16-CE9E1FD04AA6}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "osrusbfx2", "exe\osrusbfx2.vcxproj", "{9DA0D0CB-D2F6-4E86-BAE8-9A7500820F5F}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -19,28 +19,28 @@ Global Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {C25F378C-3D8F-4AF2-AFBB-7D438CBAB326}.Debug|Win32.ActiveCfg = Debug|Win32 - {C25F378C-3D8F-4AF2-AFBB-7D438CBAB326}.Debug|Win32.Build.0 = Debug|Win32 - {C25F378C-3D8F-4AF2-AFBB-7D438CBAB326}.Release|Win32.ActiveCfg = Release|Win32 - {C25F378C-3D8F-4AF2-AFBB-7D438CBAB326}.Release|Win32.Build.0 = Release|Win32 - {C25F378C-3D8F-4AF2-AFBB-7D438CBAB326}.Debug|x64.ActiveCfg = Debug|x64 - {C25F378C-3D8F-4AF2-AFBB-7D438CBAB326}.Debug|x64.Build.0 = Debug|x64 - {C25F378C-3D8F-4AF2-AFBB-7D438CBAB326}.Release|x64.ActiveCfg = Release|x64 - {C25F378C-3D8F-4AF2-AFBB-7D438CBAB326}.Release|x64.Build.0 = Release|x64 - {9D6DB868-3478-4CD3-9C16-CE9E1FD04AA6}.Debug|Win32.ActiveCfg = Debug|Win32 - {9D6DB868-3478-4CD3-9C16-CE9E1FD04AA6}.Debug|Win32.Build.0 = Debug|Win32 - {9D6DB868-3478-4CD3-9C16-CE9E1FD04AA6}.Release|Win32.ActiveCfg = Release|Win32 - {9D6DB868-3478-4CD3-9C16-CE9E1FD04AA6}.Release|Win32.Build.0 = Release|Win32 - {9D6DB868-3478-4CD3-9C16-CE9E1FD04AA6}.Debug|x64.ActiveCfg = Debug|x64 - {9D6DB868-3478-4CD3-9C16-CE9E1FD04AA6}.Debug|x64.Build.0 = Debug|x64 - {9D6DB868-3478-4CD3-9C16-CE9E1FD04AA6}.Release|x64.ActiveCfg = Release|x64 - {9D6DB868-3478-4CD3-9C16-CE9E1FD04AA6}.Release|x64.Build.0 = Release|x64 + {5B711254-3F53-4E1D-A1AD-CC81E34588B7}.Debug|Win32.ActiveCfg = Debug|Win32 + {5B711254-3F53-4E1D-A1AD-CC81E34588B7}.Debug|Win32.Build.0 = Debug|Win32 + {5B711254-3F53-4E1D-A1AD-CC81E34588B7}.Release|Win32.ActiveCfg = Release|Win32 + {5B711254-3F53-4E1D-A1AD-CC81E34588B7}.Release|Win32.Build.0 = Release|Win32 + {5B711254-3F53-4E1D-A1AD-CC81E34588B7}.Debug|x64.ActiveCfg = Debug|x64 + {5B711254-3F53-4E1D-A1AD-CC81E34588B7}.Debug|x64.Build.0 = Debug|x64 + {5B711254-3F53-4E1D-A1AD-CC81E34588B7}.Release|x64.ActiveCfg = Release|x64 + {5B711254-3F53-4E1D-A1AD-CC81E34588B7}.Release|x64.Build.0 = Release|x64 + {9DA0D0CB-D2F6-4E86-BAE8-9A7500820F5F}.Debug|Win32.ActiveCfg = Debug|Win32 + {9DA0D0CB-D2F6-4E86-BAE8-9A7500820F5F}.Debug|Win32.Build.0 = Debug|Win32 + {9DA0D0CB-D2F6-4E86-BAE8-9A7500820F5F}.Release|Win32.ActiveCfg = Release|Win32 + {9DA0D0CB-D2F6-4E86-BAE8-9A7500820F5F}.Release|Win32.Build.0 = Release|Win32 + {9DA0D0CB-D2F6-4E86-BAE8-9A7500820F5F}.Debug|x64.ActiveCfg = Debug|x64 + {9DA0D0CB-D2F6-4E86-BAE8-9A7500820F5F}.Debug|x64.Build.0 = Debug|x64 + {9DA0D0CB-D2F6-4E86-BAE8-9A7500820F5F}.Release|x64.ActiveCfg = Release|x64 + {9DA0D0CB-D2F6-4E86-BAE8-9A7500820F5F}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {C25F378C-3D8F-4AF2-AFBB-7D438CBAB326} = {3868A978-E3AA-4A0C-B3CA-23BA75D19CF8} - {9D6DB868-3478-4CD3-9C16-CE9E1FD04AA6} = {60363E6C-E86C-42ED-8222-ACAC1F71D486} + {5B711254-3F53-4E1D-A1AD-CC81E34588B7} = {3B268182-F450-4AB8-B350-A2CF6495F756} + {9DA0D0CB-D2F6-4E86-BAE8-9A7500820F5F} = {52ABC41E-9AAA-4DA8-8986-F6298E32C8A3} EndGlobalSection EndGlobal diff --git a/usb/umdf_filter_kmdf/Package/package.VcxProj b/usb/umdf_filter_kmdf/Package/package.VcxProj index 4ca7636e..21ae1e67 100644 --- a/usb/umdf_filter_kmdf/Package/package.VcxProj +++ b/usb/umdf_filter_kmdf/Package/package.VcxProj @@ -20,10 +20,10 @@ </ItemGroup> <ItemGroup> <ProjectReference Include="..\kmdf_driver\osrusbfx2.vcxproj"> - <Project>{6ABDB82A-B2BA-4EE3-A4CC-C0B00B7B5220}</Project> + <Project>{837F98CF-D3A4-472C-BACC-47950340E57B}</Project> </ProjectReference> <ProjectReference Include="..\umdf_filter\WUDFOsrUsbFilter.vcxproj"> - <Project>{BE14DB05-36A7-4ECE-88E1-FB8157CA568E}</Project> + <Project>{ADCCB27A-E522-4367-86B9-9C9DF2636B93}</Project> </ProjectReference> </ItemGroup> <PropertyGroup Label="PropertySheets"> @@ -35,8 +35,8 @@ </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Label="Globals"> - <ProjectGuid>{2BA68E64-0EBB-409C-937F-FDAC3FB7A39D}</ProjectGuid> - <SampleGuid>{9515D06E-6666-40E0-BC9B-4D353B06AF3B}</SampleGuid> + <ProjectGuid>{10E372EF-AE85-4528-919C-A261253EDDAE}</ProjectGuid> + <SampleGuid>{4535F3DF-5A13-4953-9565-74B05B8FA4C6}</SampleGuid> <RootNamespace>$(MSBuildProjectName)</RootNamespace> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> diff --git a/usb/umdf_filter_kmdf/Package/package.VcxProj.Filters b/usb/umdf_filter_kmdf/Package/package.VcxProj.Filters index 9aaef831..fde842eb 100644 --- a/usb/umdf_filter_kmdf/Package/package.VcxProj.Filters +++ b/usb/umdf_filter_kmdf/Package/package.VcxProj.Filters @@ -3,19 +3,19 @@ <ItemGroup> <Filter Include="Source Files"> <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions> - <UniqueIdentifier>{86971831-99C4-48F4-BA75-63AFA1FF01D6}</UniqueIdentifier> + <UniqueIdentifier>{0ED5A10B-EA82-464B-939C-FD3665A42A97}</UniqueIdentifier> </Filter> <Filter Include="Header Files"> <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> - <UniqueIdentifier>{49BD12DD-8C0A-47ED-9D86-487828F8E2E1}</UniqueIdentifier> + <UniqueIdentifier>{8283F5F0-093B-48C9-A2FC-EA7455F9A36D}</UniqueIdentifier> </Filter> <Filter Include="Resource Files"> <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions> - <UniqueIdentifier>{A74FBF55-5FC8-4073-89C5-B13BFE528197}</UniqueIdentifier> + <UniqueIdentifier>{0B52CF91-796F-49F5-9C6E-23FC9C521570}</UniqueIdentifier> </Filter> <Filter Include="Driver Files"> <Extensions>inf;inv;inx;mof;mc;</Extensions> - <UniqueIdentifier>{71D5E423-057B-48A2-90E2-66C66E3CC18C}</UniqueIdentifier> + <UniqueIdentifier>{7C0D1D60-5B24-411C-BA58-9FED667338B0}</UniqueIdentifier> </Filter> </ItemGroup> </Project>
\ No newline at end of file diff --git a/usb/umdf_filter_kmdf/inc/public.h b/usb/umdf_filter_kmdf/inc/public.h index 22f6cb6d..2c3f6805 100644 --- a/usb/umdf_filter_kmdf/inc/public.h +++ b/usb/umdf_filter_kmdf/inc/public.h @@ -155,7 +155,7 @@ typedef struct _FILE_PLAYBACK #include <poppack.h> #define IOCTL_INDEX 0x800 -#define FILE_DEVICE_OSRUSBFX2 0x65500 +#define FILE_DEVICE_OSRUSBFX2 65500U #define IOCTL_OSRUSBFX2_GET_CONFIG_DESCRIPTOR CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ IOCTL_INDEX, \ diff --git a/usb/umdf_filter_kmdf/kmdf_driver/Device.c b/usb/umdf_filter_kmdf/kmdf_driver/Device.c index 87ead857..8516ef09 100644 --- a/usb/umdf_filter_kmdf/kmdf_driver/Device.c +++ b/usb/umdf_filter_kmdf/kmdf_driver/Device.c @@ -970,7 +970,7 @@ Return Value: status = WdfDeviceAllocAndQueryProperty(Device, DevicePropertyFriendlyName, - NonPagedPool, + NonPagedPoolNx, &objectAttributes, &deviceNameMemory); @@ -978,7 +978,7 @@ Return Value: { status = WdfDeviceAllocAndQueryProperty(Device, DevicePropertyDeviceDescription, - NonPagedPool, + NonPagedPoolNx, &objectAttributes, &deviceNameMemory); } @@ -1000,7 +1000,7 @@ Return Value: status = WdfDeviceAllocAndQueryProperty(Device, DevicePropertyLocationInformation, - NonPagedPool, + NonPagedPoolNx, WDF_NO_OBJECT_ATTRIBUTES, &locationMemory); diff --git a/usb/umdf_filter_kmdf/kmdf_driver/driver.c b/usb/umdf_filter_kmdf/kmdf_driver/driver.c index d3b44573..44939a3b 100644 --- a/usb/umdf_filter_kmdf/kmdf_driver/driver.c +++ b/usb/umdf_filter_kmdf/kmdf_driver/driver.c @@ -114,9 +114,6 @@ Return Value: TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, "OSRUSBFX2 Driver Sample - Driver Framework Edition.\n"); - TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, - "Built %s %s\n", __DATE__, __TIME__); - // // IRP activity ID functions are available on some versions, save them into // globals (or NULL if not available) diff --git a/usb/umdf_filter_kmdf/kmdf_driver/osrusbfx2.vcxproj b/usb/umdf_filter_kmdf/kmdf_driver/osrusbfx2.vcxproj index 979852e9..2db1f7c1 100644 --- a/usb/umdf_filter_kmdf/kmdf_driver/osrusbfx2.vcxproj +++ b/usb/umdf_filter_kmdf/kmdf_driver/osrusbfx2.vcxproj @@ -19,14 +19,14 @@ </ProjectConfiguration> </ItemGroup> <PropertyGroup Label="Globals"> - <ProjectGuid>{6ABDB82A-B2BA-4EE3-A4CC-C0B00B7B5220}</ProjectGuid> + <ProjectGuid>{837F98CF-D3A4-472C-BACC-47950340E57B}</ProjectGuid> <RootNamespace>$(MSBuildProjectName)</RootNamespace> <KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR> <SupportsPackaging>false</SupportsPackaging> <RequiresPackageProject>true</RequiresPackageProject> <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration> <Platform Condition="'$(Platform)' == ''">Win32</Platform> - <SampleGuid>{18C4C80D-74E9-4145-BD1A-9525E8F04FCF}</SampleGuid> + <SampleGuid>{3EBA8CBF-2E65-4819-9EEA-E10825BB0705}</SampleGuid> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> diff --git a/usb/umdf_filter_kmdf/kmdf_driver/osrusbfx2.vcxproj.Filters b/usb/umdf_filter_kmdf/kmdf_driver/osrusbfx2.vcxproj.Filters index 13f23acc..baf7ab2e 100644 --- a/usb/umdf_filter_kmdf/kmdf_driver/osrusbfx2.vcxproj.Filters +++ b/usb/umdf_filter_kmdf/kmdf_driver/osrusbfx2.vcxproj.Filters @@ -3,19 +3,19 @@ <ItemGroup> <Filter Include="Source Files"> <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions> - <UniqueIdentifier>{7BBF30E5-9EE0-4544-BC21-3F9BBA4719F6}</UniqueIdentifier> + <UniqueIdentifier>{F859293F-10B7-4E6D-99E2-120A09448FF9}</UniqueIdentifier> </Filter> <Filter Include="Header Files"> <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> - <UniqueIdentifier>{F4DA0DF1-D522-4DE8-A128-0E3856D30A60}</UniqueIdentifier> + <UniqueIdentifier>{3DCE0FEA-C37D-448E-B9E4-B69865E71B5F}</UniqueIdentifier> </Filter> <Filter Include="Resource Files"> <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions> - <UniqueIdentifier>{86AACBD7-6DA3-4FF9-850F-FD8BA69A2316}</UniqueIdentifier> + <UniqueIdentifier>{A1BB449A-54EF-4B2B-BD68-2254963FF387}</UniqueIdentifier> </Filter> <Filter Include="Driver Files"> <Extensions>inf;inv;inx;mof;mc;</Extensions> - <UniqueIdentifier>{C3F34238-DF88-433F-9C43-9B4DA776DCB5}</UniqueIdentifier> + <UniqueIdentifier>{A03D3DFA-E9BD-48A3-BEDE-E8AAED283D03}</UniqueIdentifier> </Filter> </ItemGroup> <ItemGroup> diff --git a/usb/umdf_filter_kmdf/umdf_filter/WUDFOsrUsbFilter.vcxproj b/usb/umdf_filter_kmdf/umdf_filter/WUDFOsrUsbFilter.vcxproj index a0df5d88..f12c647f 100644 --- a/usb/umdf_filter_kmdf/umdf_filter/WUDFOsrUsbFilter.vcxproj +++ b/usb/umdf_filter_kmdf/umdf_filter/WUDFOsrUsbFilter.vcxproj @@ -19,7 +19,7 @@ </ProjectConfiguration> </ItemGroup> <PropertyGroup Label="Globals"> - <ProjectGuid>{BE14DB05-36A7-4ECE-88E1-FB8157CA568E}</ProjectGuid> + <ProjectGuid>{502F5F25-02A2-4047-8DD1-EB3DF0CC7127}</ProjectGuid> <RootNamespace>$(MSBuildProjectName)</RootNamespace> <UMDF_VERSION_MAJOR>1</UMDF_VERSION_MAJOR> <KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR> @@ -27,7 +27,7 @@ <RequiresPackageProject>true</RequiresPackageProject> <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration> <Platform Condition="'$(Platform)' == ''">Win32</Platform> - <SampleGuid>{248CCFA9-D129-42B1-A548-A0C5CD4F8AFE}</SampleGuid> + <SampleGuid>{45297D7C-3015-4F09-B0E7-469440EB9458}</SampleGuid> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> @@ -84,11 +84,6 @@ <WppDllMacro>true</WppDllMacro> <WppScanConfigurationData>internal.h</WppScanConfigurationData> </ClCompile> - <Inf Include="WUDFOsrUsbFilterOnKmDriver.inx"> - <Architecture>$(InfArch)</Architecture> - <SpecifyArchitecture>true</SpecifyArchitecture> - <CopyOutput>.\$(IntDir)\WUDFOsrUsbFilterOnKmDriver.Inf</CopyOutput> - </Inf> <OtherWpp Include="OsrUsbFilter.rc"> <WppEnabled>true</WppEnabled> <WppDllMacro>true</WppDllMacro> diff --git a/usb/umdf_filter_kmdf/umdf_filter/WUDFOsrUsbFilter.vcxproj.Filters b/usb/umdf_filter_kmdf/umdf_filter/WUDFOsrUsbFilter.vcxproj.Filters index ebc49f02..7a4a8f8d 100644 --- a/usb/umdf_filter_kmdf/umdf_filter/WUDFOsrUsbFilter.vcxproj.Filters +++ b/usb/umdf_filter_kmdf/umdf_filter/WUDFOsrUsbFilter.vcxproj.Filters @@ -3,19 +3,19 @@ <ItemGroup> <Filter Include="Source Files"> <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions> - <UniqueIdentifier>{80542188-20E5-48F5-9843-73E5C5357618}</UniqueIdentifier> + <UniqueIdentifier>{3CE4C3CE-9C1D-4790-B2EF-784C3412310A}</UniqueIdentifier> </Filter> <Filter Include="Header Files"> <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> - <UniqueIdentifier>{06DDFA1D-9B66-4847-90DA-9B47DAA6BB4D}</UniqueIdentifier> + <UniqueIdentifier>{4A9BD78B-5831-48AA-8C22-28BEBBC8A7AB}</UniqueIdentifier> </Filter> <Filter Include="Resource Files"> <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions> - <UniqueIdentifier>{CFF95FF0-CB6A-408A-BDEB-2EB542DABA61}</UniqueIdentifier> + <UniqueIdentifier>{ACD57755-0E18-4D24-A740-0D944929A053}</UniqueIdentifier> </Filter> <Filter Include="Driver Files"> <Extensions>inf;inv;inx;mof;mc;</Extensions> - <UniqueIdentifier>{9E1415BD-A138-4C82-9F05-75AAEFB9ADC2}</UniqueIdentifier> + <UniqueIdentifier>{2084F476-D6F1-485F-B9A6-581DD86D24F1}</UniqueIdentifier> </Filter> </ItemGroup> <ItemGroup> @@ -39,11 +39,6 @@ </None> </ItemGroup> <ItemGroup> - <Inf Include="WUDFOsrUsbFilterOnKmDriver.inx"> - <Filter>Driver Files</Filter> - </Inf> - </ItemGroup> - <ItemGroup> <ResourceCompile Include="OsrUsbFilter.rc"> <Filter>Resource Files</Filter> </ResourceCompile> diff --git a/usb/umdf_filter_kmdf/umdf_filter/WUDFOsrUsbFilterOnKmDriver.inx b/usb/umdf_filter_kmdf/umdf_filter/WUDFOsrUsbFilterOnKmDriver.inx Binary files differindex 3ee5cd16..a267e119 100644 --- a/usb/umdf_filter_kmdf/umdf_filter/WUDFOsrUsbFilterOnKmDriver.inx +++ b/usb/umdf_filter_kmdf/umdf_filter/WUDFOsrUsbFilterOnKmDriver.inx diff --git a/usb/umdf_filter_kmdf/umdf_filter_kmdf.sln b/usb/umdf_filter_kmdf/umdf_filter_kmdf.sln index 3d7cb72a..5a39a03d 100644 --- a/usb/umdf_filter_kmdf/umdf_filter_kmdf.sln +++ b/usb/umdf_filter_kmdf/umdf_filter_kmdf.sln @@ -3,17 +3,17 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2013 VisualStudioVersion = 12.0 MinimumVisualStudioVersion = 12.0 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Package", "Package", "{C1316664-1EF9-40B6-BB74-C6680FB441CA}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Package", "Package", "{0C11CE20-E0CC-403B-B957-FB72E3AD659A}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Umdf_filter", "Umdf_filter", "{619F52B1-AE17-4645-9FDB-7B2D3D2679DD}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Umdf_filter", "Umdf_filter", "{FD04F724-4BA6-4E88-B269-53F28C44E2F2}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Kmdf_driver", "Kmdf_driver", "{865605E4-9818-4413-9177-9330DA3B724B}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Kmdf_driver", "Kmdf_driver", "{8FED241E-8771-423B-8ED2-EF4873FAED48}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "package", "Package\package.VcxProj", "{2BA68E64-0EBB-409C-937F-FDAC3FB7A39D}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "package", "Package\package.VcxProj", "{10E372EF-AE85-4528-919C-A261253EDDAE}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WUDFOsrUsbFilter", "umdf_filter\WUDFOsrUsbFilter.vcxproj", "{BE14DB05-36A7-4ECE-88E1-FB8157CA568E}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WUDFOsrUsbFilter", "umdf_filter\WUDFOsrUsbFilter.vcxproj", "{ADCCB27A-E522-4367-86B9-9C9DF2636B93}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "osrusbfx2", "kmdf_driver\osrusbfx2.vcxproj", "{6ABDB82A-B2BA-4EE3-A4CC-C0B00B7B5220}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "osrusbfx2", "kmdf_driver\osrusbfx2.vcxproj", "{837F98CF-D3A4-472C-BACC-47950340E57B}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -23,37 +23,37 @@ Global Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {2BA68E64-0EBB-409C-937F-FDAC3FB7A39D}.Debug|Win32.ActiveCfg = Debug|Win32 - {2BA68E64-0EBB-409C-937F-FDAC3FB7A39D}.Debug|Win32.Build.0 = Debug|Win32 - {2BA68E64-0EBB-409C-937F-FDAC3FB7A39D}.Release|Win32.ActiveCfg = Release|Win32 - {2BA68E64-0EBB-409C-937F-FDAC3FB7A39D}.Release|Win32.Build.0 = Release|Win32 - {2BA68E64-0EBB-409C-937F-FDAC3FB7A39D}.Debug|x64.ActiveCfg = Debug|x64 - {2BA68E64-0EBB-409C-937F-FDAC3FB7A39D}.Debug|x64.Build.0 = Debug|x64 - {2BA68E64-0EBB-409C-937F-FDAC3FB7A39D}.Release|x64.ActiveCfg = Release|x64 - {2BA68E64-0EBB-409C-937F-FDAC3FB7A39D}.Release|x64.Build.0 = Release|x64 - {BE14DB05-36A7-4ECE-88E1-FB8157CA568E}.Debug|Win32.ActiveCfg = Debug|Win32 - {BE14DB05-36A7-4ECE-88E1-FB8157CA568E}.Debug|Win32.Build.0 = Debug|Win32 - {BE14DB05-36A7-4ECE-88E1-FB8157CA568E}.Release|Win32.ActiveCfg = Release|Win32 - {BE14DB05-36A7-4ECE-88E1-FB8157CA568E}.Release|Win32.Build.0 = Release|Win32 - {BE14DB05-36A7-4ECE-88E1-FB8157CA568E}.Debug|x64.ActiveCfg = Debug|x64 - {BE14DB05-36A7-4ECE-88E1-FB8157CA568E}.Debug|x64.Build.0 = Debug|x64 - {BE14DB05-36A7-4ECE-88E1-FB8157CA568E}.Release|x64.ActiveCfg = Release|x64 - {BE14DB05-36A7-4ECE-88E1-FB8157CA568E}.Release|x64.Build.0 = Release|x64 - {6ABDB82A-B2BA-4EE3-A4CC-C0B00B7B5220}.Debug|Win32.ActiveCfg = Debug|Win32 - {6ABDB82A-B2BA-4EE3-A4CC-C0B00B7B5220}.Debug|Win32.Build.0 = Debug|Win32 - {6ABDB82A-B2BA-4EE3-A4CC-C0B00B7B5220}.Release|Win32.ActiveCfg = Release|Win32 - {6ABDB82A-B2BA-4EE3-A4CC-C0B00B7B5220}.Release|Win32.Build.0 = Release|Win32 - {6ABDB82A-B2BA-4EE3-A4CC-C0B00B7B5220}.Debug|x64.ActiveCfg = Debug|x64 - {6ABDB82A-B2BA-4EE3-A4CC-C0B00B7B5220}.Debug|x64.Build.0 = Debug|x64 - {6ABDB82A-B2BA-4EE3-A4CC-C0B00B7B5220}.Release|x64.ActiveCfg = Release|x64 - {6ABDB82A-B2BA-4EE3-A4CC-C0B00B7B5220}.Release|x64.Build.0 = Release|x64 + {10E372EF-AE85-4528-919C-A261253EDDAE}.Debug|Win32.ActiveCfg = Debug|Win32 + {10E372EF-AE85-4528-919C-A261253EDDAE}.Debug|Win32.Build.0 = Debug|Win32 + {10E372EF-AE85-4528-919C-A261253EDDAE}.Release|Win32.ActiveCfg = Release|Win32 + {10E372EF-AE85-4528-919C-A261253EDDAE}.Release|Win32.Build.0 = Release|Win32 + {10E372EF-AE85-4528-919C-A261253EDDAE}.Debug|x64.ActiveCfg = Debug|x64 + {10E372EF-AE85-4528-919C-A261253EDDAE}.Debug|x64.Build.0 = Debug|x64 + {10E372EF-AE85-4528-919C-A261253EDDAE}.Release|x64.ActiveCfg = Release|x64 + {10E372EF-AE85-4528-919C-A261253EDDAE}.Release|x64.Build.0 = Release|x64 + {ADCCB27A-E522-4367-86B9-9C9DF2636B93}.Debug|Win32.ActiveCfg = Debug|Win32 + {ADCCB27A-E522-4367-86B9-9C9DF2636B93}.Debug|Win32.Build.0 = Debug|Win32 + {ADCCB27A-E522-4367-86B9-9C9DF2636B93}.Release|Win32.ActiveCfg = Release|Win32 + {ADCCB27A-E522-4367-86B9-9C9DF2636B93}.Release|Win32.Build.0 = Release|Win32 + {ADCCB27A-E522-4367-86B9-9C9DF2636B93}.Debug|x64.ActiveCfg = Debug|x64 + {ADCCB27A-E522-4367-86B9-9C9DF2636B93}.Debug|x64.Build.0 = Debug|x64 + {ADCCB27A-E522-4367-86B9-9C9DF2636B93}.Release|x64.ActiveCfg = Release|x64 + {ADCCB27A-E522-4367-86B9-9C9DF2636B93}.Release|x64.Build.0 = Release|x64 + {837F98CF-D3A4-472C-BACC-47950340E57B}.Debug|Win32.ActiveCfg = Debug|Win32 + {837F98CF-D3A4-472C-BACC-47950340E57B}.Debug|Win32.Build.0 = Debug|Win32 + {837F98CF-D3A4-472C-BACC-47950340E57B}.Release|Win32.ActiveCfg = Release|Win32 + {837F98CF-D3A4-472C-BACC-47950340E57B}.Release|Win32.Build.0 = Release|Win32 + {837F98CF-D3A4-472C-BACC-47950340E57B}.Debug|x64.ActiveCfg = Debug|x64 + {837F98CF-D3A4-472C-BACC-47950340E57B}.Debug|x64.Build.0 = Debug|x64 + {837F98CF-D3A4-472C-BACC-47950340E57B}.Release|x64.ActiveCfg = Release|x64 + {837F98CF-D3A4-472C-BACC-47950340E57B}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {2BA68E64-0EBB-409C-937F-FDAC3FB7A39D} = {C1316664-1EF9-40B6-BB74-C6680FB441CA} - {BE14DB05-36A7-4ECE-88E1-FB8157CA568E} = {619F52B1-AE17-4645-9FDB-7B2D3D2679DD} - {6ABDB82A-B2BA-4EE3-A4CC-C0B00B7B5220} = {865605E4-9818-4413-9177-9330DA3B724B} + {10E372EF-AE85-4528-919C-A261253EDDAE} = {0C11CE20-E0CC-403B-B957-FB72E3AD659A} + {ADCCB27A-E522-4367-86B9-9C9DF2636B93} = {FD04F724-4BA6-4E88-B269-53F28C44E2F2} + {837F98CF-D3A4-472C-BACC-47950340E57B} = {8FED241E-8771-423B-8ED2-EF4873FAED48} EndGlobalSection EndGlobal diff --git a/usb/umdf_filter_umdf/Package/package.VcxProj b/usb/umdf_filter_umdf/Package/package.VcxProj index 6bee13d5..c3d12b03 100644 --- a/usb/umdf_filter_umdf/Package/package.VcxProj +++ b/usb/umdf_filter_umdf/Package/package.VcxProj @@ -20,10 +20,10 @@ </ItemGroup> <ItemGroup> <ProjectReference Include="..\umdf_driver\WUDFOsrUsbFx2.vcxproj"> - <Project>{23F6BB7E-4FB3-4584-8972-5048C2C1CAEE}</Project> + <Project>{6E5D412E-EF25-4DA4-B64E-6EAE67AF8D98}</Project> </ProjectReference> <ProjectReference Include="..\umdf_filter\WUDFOsrUsbFilter.vcxproj"> - <Project>{4BBB6EA2-FEE6-4951-8D63-BA71C959958F}</Project> + <Project>{502F5F25-02A2-4047-8DD1-EB3DF0CC7127}</Project> </ProjectReference> </ItemGroup> <PropertyGroup Label="PropertySheets"> @@ -35,8 +35,8 @@ </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Label="Globals"> - <ProjectGuid>{7F3A9577-907F-41F9-A180-C7DFFA7C9F18}</ProjectGuid> - <SampleGuid>{5DD4B112-FC71-4CC4-BD6C-7A47B0C393EC}</SampleGuid> + <ProjectGuid>{A217E49A-2A5E-4E51-BA9E-D87D62F6E2F7}</ProjectGuid> + <SampleGuid>{46304089-31EE-4493-8063-28C9498B0AA5}</SampleGuid> <RootNamespace>$(MSBuildProjectName)</RootNamespace> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> diff --git a/usb/umdf_filter_umdf/Package/package.VcxProj.Filters b/usb/umdf_filter_umdf/Package/package.VcxProj.Filters index 338a8815..c76e39bb 100644 --- a/usb/umdf_filter_umdf/Package/package.VcxProj.Filters +++ b/usb/umdf_filter_umdf/Package/package.VcxProj.Filters @@ -3,19 +3,19 @@ <ItemGroup> <Filter Include="Source Files"> <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions> - <UniqueIdentifier>{CAA3CB0A-784F-417B-ADA4-267FD26703A4}</UniqueIdentifier> + <UniqueIdentifier>{C029FC84-457F-450E-ADA9-6D80AE7CD763}</UniqueIdentifier> </Filter> <Filter Include="Header Files"> <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> - <UniqueIdentifier>{9BD249E8-2871-4C6B-8319-A14DDF0914A2}</UniqueIdentifier> + <UniqueIdentifier>{7D823922-0DAE-4B96-8DB9-0746C3D33ACA}</UniqueIdentifier> </Filter> <Filter Include="Resource Files"> <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions> - <UniqueIdentifier>{6DF09A8E-2B37-41C7-AD3E-DBFB1708CECA}</UniqueIdentifier> + <UniqueIdentifier>{C9031396-E1B6-4B90-94EC-0D504E07410E}</UniqueIdentifier> </Filter> <Filter Include="Driver Files"> <Extensions>inf;inv;inx;mof;mc;</Extensions> - <UniqueIdentifier>{165858E4-F07F-4DBC-964A-A3E623018249}</UniqueIdentifier> + <UniqueIdentifier>{3B2590BD-4AA9-4039-8CA3-4C189ACEF76A}</UniqueIdentifier> </Filter> </ItemGroup> </Project>
\ No newline at end of file diff --git a/usb/umdf_filter_umdf/inc/public.h b/usb/umdf_filter_umdf/inc/public.h index 22f6cb6d..2c3f6805 100644 --- a/usb/umdf_filter_umdf/inc/public.h +++ b/usb/umdf_filter_umdf/inc/public.h @@ -155,7 +155,7 @@ typedef struct _FILE_PLAYBACK #include <poppack.h> #define IOCTL_INDEX 0x800 -#define FILE_DEVICE_OSRUSBFX2 0x65500 +#define FILE_DEVICE_OSRUSBFX2 65500U #define IOCTL_OSRUSBFX2_GET_CONFIG_DESCRIPTOR CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ IOCTL_INDEX, \ diff --git a/usb/umdf_filter_umdf/umdf_driver/WUDFOsrUsbFx2.vcxproj b/usb/umdf_filter_umdf/umdf_driver/WUDFOsrUsbFx2.vcxproj index bb103f8d..18b66c7f 100644 --- a/usb/umdf_filter_umdf/umdf_driver/WUDFOsrUsbFx2.vcxproj +++ b/usb/umdf_filter_umdf/umdf_driver/WUDFOsrUsbFx2.vcxproj @@ -19,7 +19,7 @@ </ProjectConfiguration> </ItemGroup> <PropertyGroup Label="Globals"> - <ProjectGuid>{23F6BB7E-4FB3-4584-8972-5048C2C1CAEE}</ProjectGuid> + <ProjectGuid>{6E5D412E-EF25-4DA4-B64E-6EAE67AF8D98}</ProjectGuid> <RootNamespace>$(MSBuildProjectName)</RootNamespace> <UMDF_VERSION_MAJOR>1</UMDF_VERSION_MAJOR> <KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR> @@ -27,7 +27,7 @@ <RequiresPackageProject>true</RequiresPackageProject> <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration> <Platform Condition="'$(Platform)' == ''">Win32</Platform> - <SampleGuid>{E4C6299E-8765-4C69-8CEB-B5F530F83D42}</SampleGuid> + <SampleGuid>{87BFB278-0771-439F-893D-89376B83F7F0}</SampleGuid> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> diff --git a/usb/umdf_filter_umdf/umdf_driver/WUDFOsrUsbFx2.vcxproj.Filters b/usb/umdf_filter_umdf/umdf_driver/WUDFOsrUsbFx2.vcxproj.Filters index 0ff60758..372badf0 100644 --- a/usb/umdf_filter_umdf/umdf_driver/WUDFOsrUsbFx2.vcxproj.Filters +++ b/usb/umdf_filter_umdf/umdf_driver/WUDFOsrUsbFx2.vcxproj.Filters @@ -3,19 +3,19 @@ <ItemGroup> <Filter Include="Source Files"> <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions> - <UniqueIdentifier>{8A850A2A-3EE0-48E3-9B10-C5D80ED01050}</UniqueIdentifier> + <UniqueIdentifier>{F8E1CCD2-AADC-44B5-B631-5C6E6D74CFCD}</UniqueIdentifier> </Filter> <Filter Include="Header Files"> <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> - <UniqueIdentifier>{2DE6E105-292A-4C7B-A2A0-7B39D9339979}</UniqueIdentifier> + <UniqueIdentifier>{0E050956-9FA9-495C-9F9F-D663EFA3A344}</UniqueIdentifier> </Filter> <Filter Include="Resource Files"> <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions> - <UniqueIdentifier>{D880698B-D054-49BC-B7B3-607606EAB71A}</UniqueIdentifier> + <UniqueIdentifier>{49CD21A6-260A-471B-B532-9E9E23F6195F}</UniqueIdentifier> </Filter> <Filter Include="Driver Files"> <Extensions>inf;inv;inx;mof;mc;</Extensions> - <UniqueIdentifier>{5CEFA42C-9FC9-4234-815F-4C86F8D5AE7D}</UniqueIdentifier> + <UniqueIdentifier>{A942026F-83A0-4223-881A-29732777F22C}</UniqueIdentifier> </Filter> </ItemGroup> <ItemGroup> diff --git a/usb/umdf_filter_umdf/umdf_filter/WUDFOsrUsbFilter.vcxproj b/usb/umdf_filter_umdf/umdf_filter/WUDFOsrUsbFilter.vcxproj index 99e4832d..f12c647f 100644 --- a/usb/umdf_filter_umdf/umdf_filter/WUDFOsrUsbFilter.vcxproj +++ b/usb/umdf_filter_umdf/umdf_filter/WUDFOsrUsbFilter.vcxproj @@ -19,7 +19,7 @@ </ProjectConfiguration> </ItemGroup> <PropertyGroup Label="Globals"> - <ProjectGuid>{4BBB6EA2-FEE6-4951-8D63-BA71C959958F}</ProjectGuid> + <ProjectGuid>{502F5F25-02A2-4047-8DD1-EB3DF0CC7127}</ProjectGuid> <RootNamespace>$(MSBuildProjectName)</RootNamespace> <UMDF_VERSION_MAJOR>1</UMDF_VERSION_MAJOR> <KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR> @@ -27,7 +27,7 @@ <RequiresPackageProject>true</RequiresPackageProject> <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration> <Platform Condition="'$(Platform)' == ''">Win32</Platform> - <SampleGuid>{D91D8948-9EF7-41ED-BBC4-7E870F5929F1}</SampleGuid> + <SampleGuid>{45297D7C-3015-4F09-B0E7-469440EB9458}</SampleGuid> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> @@ -84,11 +84,6 @@ <WppDllMacro>true</WppDllMacro> <WppScanConfigurationData>internal.h</WppScanConfigurationData> </ClCompile> - <Inf Include="WUDFOsrUsbFilterOnUmFx2Driver.inx"> - <Architecture>$(InfArch)</Architecture> - <SpecifyArchitecture>true</SpecifyArchitecture> - <CopyOutput>.\$(IntDir)\WUDFOsrUsbFilterOnUmFx2Driver.Inf</CopyOutput> - </Inf> <OtherWpp Include="OsrUsbFilter.rc"> <WppEnabled>true</WppEnabled> <WppDllMacro>true</WppDllMacro> diff --git a/usb/umdf_filter_umdf/umdf_filter/WUDFOsrUsbFilter.vcxproj.Filters b/usb/umdf_filter_umdf/umdf_filter/WUDFOsrUsbFilter.vcxproj.Filters index 2845ce7f..7a4a8f8d 100644 --- a/usb/umdf_filter_umdf/umdf_filter/WUDFOsrUsbFilter.vcxproj.Filters +++ b/usb/umdf_filter_umdf/umdf_filter/WUDFOsrUsbFilter.vcxproj.Filters @@ -3,19 +3,19 @@ <ItemGroup> <Filter Include="Source Files"> <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions> - <UniqueIdentifier>{C8E8CD40-00CA-4946-BD15-35A6AE9BC653}</UniqueIdentifier> + <UniqueIdentifier>{3CE4C3CE-9C1D-4790-B2EF-784C3412310A}</UniqueIdentifier> </Filter> <Filter Include="Header Files"> <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> - <UniqueIdentifier>{DAC345DC-1425-47B4-BC7A-F459FCFBEA26}</UniqueIdentifier> + <UniqueIdentifier>{4A9BD78B-5831-48AA-8C22-28BEBBC8A7AB}</UniqueIdentifier> </Filter> <Filter Include="Resource Files"> <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions> - <UniqueIdentifier>{396BA632-D58C-49AC-B3C3-E85ED7BB478F}</UniqueIdentifier> + <UniqueIdentifier>{ACD57755-0E18-4D24-A740-0D944929A053}</UniqueIdentifier> </Filter> <Filter Include="Driver Files"> <Extensions>inf;inv;inx;mof;mc;</Extensions> - <UniqueIdentifier>{884CE389-18D3-452C-9FEA-9E5F512FC4E2}</UniqueIdentifier> + <UniqueIdentifier>{2084F476-D6F1-485F-B9A6-581DD86D24F1}</UniqueIdentifier> </Filter> </ItemGroup> <ItemGroup> @@ -39,11 +39,6 @@ </None> </ItemGroup> <ItemGroup> - <Inf Include="WUDFOsrUsbFilterOnUmFx2Driver.inx"> - <Filter>Driver Files</Filter> - </Inf> - </ItemGroup> - <ItemGroup> <ResourceCompile Include="OsrUsbFilter.rc"> <Filter>Resource Files</Filter> </ResourceCompile> diff --git a/usb/umdf_filter_umdf/umdf_filter/WUDFOsrUsbFilterOnUmFx2Driver.inx b/usb/umdf_filter_umdf/umdf_filter/WUDFOsrUsbFilterOnUmFx2Driver.inx Binary files differindex 2d61a186..4d716e83 100644 --- a/usb/umdf_filter_umdf/umdf_filter/WUDFOsrUsbFilterOnUmFx2Driver.inx +++ b/usb/umdf_filter_umdf/umdf_filter/WUDFOsrUsbFilterOnUmFx2Driver.inx diff --git a/usb/umdf_filter_umdf/umdf_filter_umdf.sln b/usb/umdf_filter_umdf/umdf_filter_umdf.sln index a26f3f52..32dc6d8b 100644 --- a/usb/umdf_filter_umdf/umdf_filter_umdf.sln +++ b/usb/umdf_filter_umdf/umdf_filter_umdf.sln @@ -3,17 +3,17 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2013 VisualStudioVersion = 12.0 MinimumVisualStudioVersion = 12.0 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Package", "Package", "{72DF351F-0D1A-4DC2-84E6-E71F93608A08}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Package", "Package", "{23CDA216-49BA-49D6-98E9-6692D1E6D363}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Umdf_filter", "Umdf_filter", "{7B826E21-097E-4279-9B72-C812B012A2D9}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Umdf_filter", "Umdf_filter", "{EF4F817D-931F-4D72-B5A5-0E0FB30F1CE0}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Umdf_driver", "Umdf_driver", "{BF37E731-1A3F-4BA2-B71F-86BDC37D83F7}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Umdf_driver", "Umdf_driver", "{B3DCEF35-5C54-4506-981B-31B0611116E3}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "package", "Package\package.VcxProj", "{7F3A9577-907F-41F9-A180-C7DFFA7C9F18}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "package", "Package\package.VcxProj", "{A217E49A-2A5E-4E51-BA9E-D87D62F6E2F7}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WUDFOsrUsbFilter", "umdf_filter\WUDFOsrUsbFilter.vcxproj", "{4BBB6EA2-FEE6-4951-8D63-BA71C959958F}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WUDFOsrUsbFilter", "umdf_filter\WUDFOsrUsbFilter.vcxproj", "{502F5F25-02A2-4047-8DD1-EB3DF0CC7127}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WUDFOsrUsbFx2", "umdf_driver\WUDFOsrUsbFx2.vcxproj", "{23F6BB7E-4FB3-4584-8972-5048C2C1CAEE}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WUDFOsrUsbFx2", "umdf_driver\WUDFOsrUsbFx2.vcxproj", "{6E5D412E-EF25-4DA4-B64E-6EAE67AF8D98}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -23,37 +23,37 @@ Global Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {7F3A9577-907F-41F9-A180-C7DFFA7C9F18}.Debug|Win32.ActiveCfg = Debug|Win32 - {7F3A9577-907F-41F9-A180-C7DFFA7C9F18}.Debug|Win32.Build.0 = Debug|Win32 - {7F3A9577-907F-41F9-A180-C7DFFA7C9F18}.Release|Win32.ActiveCfg = Release|Win32 - {7F3A9577-907F-41F9-A180-C7DFFA7C9F18}.Release|Win32.Build.0 = Release|Win32 - {7F3A9577-907F-41F9-A180-C7DFFA7C9F18}.Debug|x64.ActiveCfg = Debug|x64 - {7F3A9577-907F-41F9-A180-C7DFFA7C9F18}.Debug|x64.Build.0 = Debug|x64 - {7F3A9577-907F-41F9-A180-C7DFFA7C9F18}.Release|x64.ActiveCfg = Release|x64 - {7F3A9577-907F-41F9-A180-C7DFFA7C9F18}.Release|x64.Build.0 = Release|x64 - {4BBB6EA2-FEE6-4951-8D63-BA71C959958F}.Debug|Win32.ActiveCfg = Debug|Win32 - {4BBB6EA2-FEE6-4951-8D63-BA71C959958F}.Debug|Win32.Build.0 = Debug|Win32 - {4BBB6EA2-FEE6-4951-8D63-BA71C959958F}.Release|Win32.ActiveCfg = Release|Win32 - {4BBB6EA2-FEE6-4951-8D63-BA71C959958F}.Release|Win32.Build.0 = Release|Win32 - {4BBB6EA2-FEE6-4951-8D63-BA71C959958F}.Debug|x64.ActiveCfg = Debug|x64 - {4BBB6EA2-FEE6-4951-8D63-BA71C959958F}.Debug|x64.Build.0 = Debug|x64 - {4BBB6EA2-FEE6-4951-8D63-BA71C959958F}.Release|x64.ActiveCfg = Release|x64 - {4BBB6EA2-FEE6-4951-8D63-BA71C959958F}.Release|x64.Build.0 = Release|x64 - {23F6BB7E-4FB3-4584-8972-5048C2C1CAEE}.Debug|Win32.ActiveCfg = Debug|Win32 - {23F6BB7E-4FB3-4584-8972-5048C2C1CAEE}.Debug|Win32.Build.0 = Debug|Win32 - {23F6BB7E-4FB3-4584-8972-5048C2C1CAEE}.Release|Win32.ActiveCfg = Release|Win32 - {23F6BB7E-4FB3-4584-8972-5048C2C1CAEE}.Release|Win32.Build.0 = Release|Win32 - {23F6BB7E-4FB3-4584-8972-5048C2C1CAEE}.Debug|x64.ActiveCfg = Debug|x64 - {23F6BB7E-4FB3-4584-8972-5048C2C1CAEE}.Debug|x64.Build.0 = Debug|x64 - {23F6BB7E-4FB3-4584-8972-5048C2C1CAEE}.Release|x64.ActiveCfg = Release|x64 - {23F6BB7E-4FB3-4584-8972-5048C2C1CAEE}.Release|x64.Build.0 = Release|x64 + {A217E49A-2A5E-4E51-BA9E-D87D62F6E2F7}.Debug|Win32.ActiveCfg = Debug|Win32 + {A217E49A-2A5E-4E51-BA9E-D87D62F6E2F7}.Debug|Win32.Build.0 = Debug|Win32 + {A217E49A-2A5E-4E51-BA9E-D87D62F6E2F7}.Release|Win32.ActiveCfg = Release|Win32 + {A217E49A-2A5E-4E51-BA9E-D87D62F6E2F7}.Release|Win32.Build.0 = Release|Win32 + {A217E49A-2A5E-4E51-BA9E-D87D62F6E2F7}.Debug|x64.ActiveCfg = Debug|x64 + {A217E49A-2A5E-4E51-BA9E-D87D62F6E2F7}.Debug|x64.Build.0 = Debug|x64 + {A217E49A-2A5E-4E51-BA9E-D87D62F6E2F7}.Release|x64.ActiveCfg = Release|x64 + {A217E49A-2A5E-4E51-BA9E-D87D62F6E2F7}.Release|x64.Build.0 = Release|x64 + {502F5F25-02A2-4047-8DD1-EB3DF0CC7127}.Debug|Win32.ActiveCfg = Debug|Win32 + {502F5F25-02A2-4047-8DD1-EB3DF0CC7127}.Debug|Win32.Build.0 = Debug|Win32 + {502F5F25-02A2-4047-8DD1-EB3DF0CC7127}.Release|Win32.ActiveCfg = Release|Win32 + {502F5F25-02A2-4047-8DD1-EB3DF0CC7127}.Release|Win32.Build.0 = Release|Win32 + {502F5F25-02A2-4047-8DD1-EB3DF0CC7127}.Debug|x64.ActiveCfg = Debug|x64 + {502F5F25-02A2-4047-8DD1-EB3DF0CC7127}.Debug|x64.Build.0 = Debug|x64 + {502F5F25-02A2-4047-8DD1-EB3DF0CC7127}.Release|x64.ActiveCfg = Release|x64 + {502F5F25-02A2-4047-8DD1-EB3DF0CC7127}.Release|x64.Build.0 = Release|x64 + {6E5D412E-EF25-4DA4-B64E-6EAE67AF8D98}.Debug|Win32.ActiveCfg = Debug|Win32 + {6E5D412E-EF25-4DA4-B64E-6EAE67AF8D98}.Debug|Win32.Build.0 = Debug|Win32 + {6E5D412E-EF25-4DA4-B64E-6EAE67AF8D98}.Release|Win32.ActiveCfg = Release|Win32 + {6E5D412E-EF25-4DA4-B64E-6EAE67AF8D98}.Release|Win32.Build.0 = Release|Win32 + {6E5D412E-EF25-4DA4-B64E-6EAE67AF8D98}.Debug|x64.ActiveCfg = Debug|x64 + {6E5D412E-EF25-4DA4-B64E-6EAE67AF8D98}.Debug|x64.Build.0 = Debug|x64 + {6E5D412E-EF25-4DA4-B64E-6EAE67AF8D98}.Release|x64.ActiveCfg = Release|x64 + {6E5D412E-EF25-4DA4-B64E-6EAE67AF8D98}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {7F3A9577-907F-41F9-A180-C7DFFA7C9F18} = {72DF351F-0D1A-4DC2-84E6-E71F93608A08} - {4BBB6EA2-FEE6-4951-8D63-BA71C959958F} = {7B826E21-097E-4279-9B72-C812B012A2D9} - {23F6BB7E-4FB3-4584-8972-5048C2C1CAEE} = {BF37E731-1A3F-4BA2-B71F-86BDC37D83F7} + {A217E49A-2A5E-4E51-BA9E-D87D62F6E2F7} = {23CDA216-49BA-49D6-98E9-6692D1E6D363} + {502F5F25-02A2-4047-8DD1-EB3DF0CC7127} = {EF4F817D-931F-4D72-B5A5-0E0FB30F1CE0} + {6E5D412E-EF25-4DA4-B64E-6EAE67AF8D98} = {B3DCEF35-5C54-4506-981B-31B0611116E3} EndGlobalSection EndGlobal diff --git a/usb/umdf_fx2/driver/WUDFOsrUsbFx2.inx b/usb/umdf_fx2/driver/WUDFOsrUsbFx2.inx Binary files differindex 529515c6..9ad339b6 100644 --- a/usb/umdf_fx2/driver/WUDFOsrUsbFx2.inx +++ b/usb/umdf_fx2/driver/WUDFOsrUsbFx2.inx diff --git a/usb/umdf_fx2/driver/WUDFOsrUsbFx2.vcxproj b/usb/umdf_fx2/driver/WUDFOsrUsbFx2.vcxproj index 4960ba7c..18b66c7f 100644 --- a/usb/umdf_fx2/driver/WUDFOsrUsbFx2.vcxproj +++ b/usb/umdf_fx2/driver/WUDFOsrUsbFx2.vcxproj @@ -19,13 +19,15 @@ </ProjectConfiguration> </ItemGroup> <PropertyGroup Label="Globals"> - <ProjectGuid>{BCB0C08D-E6FC-4FE6-BFDE-723B3706FA53}</ProjectGuid> + <ProjectGuid>{6E5D412E-EF25-4DA4-B64E-6EAE67AF8D98}</ProjectGuid> <RootNamespace>$(MSBuildProjectName)</RootNamespace> <UMDF_VERSION_MAJOR>1</UMDF_VERSION_MAJOR> <KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR> + <SupportsPackaging>false</SupportsPackaging> + <RequiresPackageProject>true</RequiresPackageProject> <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration> <Platform Condition="'$(Platform)' == ''">Win32</Platform> - <SampleGuid>{CB79CACC-78FE-4BD1-8CEF-F304F7B06047}</SampleGuid> + <SampleGuid>{87BFB278-0771-439F-893D-89376B83F7F0}</SampleGuid> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> @@ -82,11 +84,6 @@ <WppDllMacro>true</WppDllMacro> <WppScanConfigurationData>internal.h</WppScanConfigurationData> </ClCompile> - <Inf Include="WUDFOsrUsbFx2.inx"> - <Architecture>$(InfArch)</Architecture> - <SpecifyArchitecture>true</SpecifyArchitecture> - <CopyOutput>.\$(IntDir)\WUDFOsrUsbFx2.inf</CopyOutput> - </Inf> <OtherWpp Include="OsrUsbFx2.rc"> <WppEnabled>true</WppEnabled> <WppDllMacro>true</WppDllMacro> @@ -191,12 +188,15 @@ </ResourceCompile> <ClCompile> <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> </ClCompile> <Midl> <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\inc</AdditionalIncludeDirectories> </Midl> <Link> <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\kernel32.lib;$(SDK_LIB_PATH)\advapi32.lib;$(SDK_LIB_PATH)\setupapi.lib</AdditionalDependencies> + <ModuleDefinitionFile>exports.def</ModuleDefinitionFile> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> @@ -205,12 +205,15 @@ </ResourceCompile> <ClCompile> <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> </ClCompile> <Midl> <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\inc</AdditionalIncludeDirectories> </Midl> <Link> <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\kernel32.lib;$(SDK_LIB_PATH)\advapi32.lib;$(SDK_LIB_PATH)\setupapi.lib</AdditionalDependencies> + <ModuleDefinitionFile>exports.def</ModuleDefinitionFile> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> @@ -219,12 +222,15 @@ </ResourceCompile> <ClCompile> <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> </ClCompile> <Midl> <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\inc</AdditionalIncludeDirectories> </Midl> <Link> <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\kernel32.lib;$(SDK_LIB_PATH)\advapi32.lib;$(SDK_LIB_PATH)\setupapi.lib</AdditionalDependencies> + <ModuleDefinitionFile>exports.def</ModuleDefinitionFile> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> @@ -233,53 +239,16 @@ </ResourceCompile> <ClCompile> <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> </ClCompile> <Midl> <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\..\inc</AdditionalIncludeDirectories> </Midl> <Link> <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\kernel32.lib;$(SDK_LIB_PATH)\advapi32.lib;$(SDK_LIB_PATH)\setupapi.lib</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <FilesToPackage Include="..\deviceMetadata\B4D697F5-1C56-4807-ACCD-B28C09D37FF0.devicemetadata-ms" /> - <None Include="..\deviceMetadata\B4D697F5-1C56-4807-ACCD-B28C09D37FF0.devicemetadata-ms" /> - </ItemGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <Link> - <ModuleDefinitionFile>exports.def</ModuleDefinitionFile> - </Link> - <ClCompile> - <ExceptionHandling> - </ExceptionHandling> - </ClCompile> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <Link> - <ModuleDefinitionFile>exports.def</ModuleDefinitionFile> - </Link> - <ClCompile> - <ExceptionHandling> - </ExceptionHandling> - </ClCompile> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Link> - <ModuleDefinitionFile>exports.def</ModuleDefinitionFile> - </Link> - <ClCompile> - <ExceptionHandling> - </ExceptionHandling> - </ClCompile> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <Link> <ModuleDefinitionFile>exports.def</ModuleDefinitionFile> </Link> - <ClCompile> - <ExceptionHandling> - </ExceptionHandling> - </ClCompile> </ItemDefinitionGroup> <ItemGroup> <ResourceCompile Include="OsrUsbFx2.rc" /> @@ -289,27 +258,9 @@ <FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" /> </ItemGroup> <ItemGroup> - <None Include="*.txt" Exclude="@(None)" /> - <None Include="*.htm" Exclude="@(None)" /> - <None Include="*.html" Exclude="@(None)" /> - <None Include="*.ico" Exclude="@(None)" /> - <None Include="*.cur" Exclude="@(None)" /> - <None Include="*.bmp" Exclude="@(None)" /> - <None Include="*.dlg" Exclude="@(None)" /> - <None Include="*.rct" Exclude="@(None)" /> - <None Include="*.gif" Exclude="@(None)" /> - <None Include="*.jpg" Exclude="@(None)" /> - <None Include="*.jpeg" Exclude="@(None)" /> - <None Include="*.wav" Exclude="@(None)" /> - <None Include="*.jpe" Exclude="@(None)" /> - <None Include="*.tiff" Exclude="@(None)" /> - <None Include="*.tif" Exclude="@(None)" /> - <None Include="*.png" Exclude="@(None)" /> - <None Include="*.rc2" Exclude="@(None)" /> - <None Include="*.def" Exclude="@(None)" /> - <None Include="*.bat" Exclude="@(None)" /> - <None Include="*.hpj" Exclude="@(None)" /> - <None Include="*.asmx" Exclude="@(None)" /> + <None Exclude="@(None)" Include="*.txt;*.htm;*.html" /> + <None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" /> + <None Exclude="@(None)" Include="*.def;*.bat;*.hpj;*.asmx" /> </ItemGroup> <ItemGroup> <ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" /> diff --git a/usb/umdf_fx2/driver/WUDFOsrUsbFx2.vcxproj.Filters b/usb/umdf_fx2/driver/WUDFOsrUsbFx2.vcxproj.Filters index 2d50f351..372badf0 100644 --- a/usb/umdf_fx2/driver/WUDFOsrUsbFx2.vcxproj.Filters +++ b/usb/umdf_fx2/driver/WUDFOsrUsbFx2.vcxproj.Filters @@ -3,19 +3,19 @@ <ItemGroup> <Filter Include="Source Files"> <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions> - <UniqueIdentifier>{E1664368-3424-45A1-AF32-AAACC488825D}</UniqueIdentifier> + <UniqueIdentifier>{F8E1CCD2-AADC-44B5-B631-5C6E6D74CFCD}</UniqueIdentifier> </Filter> <Filter Include="Header Files"> <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> - <UniqueIdentifier>{137984AA-C7C2-452A-9DA3-3FCF41A038C9}</UniqueIdentifier> + <UniqueIdentifier>{0E050956-9FA9-495C-9F9F-D663EFA3A344}</UniqueIdentifier> </Filter> <Filter Include="Resource Files"> <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions> - <UniqueIdentifier>{B2A97895-8C0E-4645-AF01-3C7522D5A567}</UniqueIdentifier> + <UniqueIdentifier>{49CD21A6-260A-471B-B532-9E9E23F6195F}</UniqueIdentifier> </Filter> <Filter Include="Driver Files"> <Extensions>inf;inv;inx;mof;mc;</Extensions> - <UniqueIdentifier>{9B29C0A6-BE4B-4116-8FF9-8E8894F2055D}</UniqueIdentifier> + <UniqueIdentifier>{A942026F-83A0-4223-881A-29732777F22C}</UniqueIdentifier> </Filter> </ItemGroup> <ItemGroup> @@ -45,11 +45,6 @@ </None> </ItemGroup> <ItemGroup> - <Inf Include="WUDFOsrUsbFx2.inx"> - <Filter>Driver Files</Filter> - </Inf> - </ItemGroup> - <ItemGroup> <ResourceCompile Include="OsrUsbFx2.rc"> <Filter>Resource Files</Filter> </ResourceCompile> diff --git a/usb/umdf_fx2/exe/WudfOsrUsbFx2Test.vcxproj b/usb/umdf_fx2/exe/WudfOsrUsbFx2Test.vcxproj index b79ca2a3..e594febf 100644 --- a/usb/umdf_fx2/exe/WudfOsrUsbFx2Test.vcxproj +++ b/usb/umdf_fx2/exe/WudfOsrUsbFx2Test.vcxproj @@ -19,11 +19,11 @@ </ProjectConfiguration> </ItemGroup> <PropertyGroup Label="Globals"> - <ProjectGuid>{24745B15-B6D2-4D1A-AB27-C0F38B1C0086}</ProjectGuid> + <ProjectGuid>{B4244D54-7EBF-43D4-BB6D-C994C182C572}</ProjectGuid> <RootNamespace>$(MSBuildProjectName)</RootNamespace> <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration> <Platform Condition="'$(Platform)' == ''">Win32</Platform> - <SampleGuid>{9D5B23F4-B6A2-45BC-92DA-A299F0812254}</SampleGuid> + <SampleGuid>{6A99CFCE-4C34-4F5D-B7D4-D810AE496B95}</SampleGuid> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> diff --git a/usb/umdf_fx2/exe/WudfOsrUsbFx2Test.vcxproj.Filters b/usb/umdf_fx2/exe/WudfOsrUsbFx2Test.vcxproj.Filters index c7c570ef..a430f986 100644 --- a/usb/umdf_fx2/exe/WudfOsrUsbFx2Test.vcxproj.Filters +++ b/usb/umdf_fx2/exe/WudfOsrUsbFx2Test.vcxproj.Filters @@ -3,15 +3,15 @@ <ItemGroup> <Filter Include="Source Files"> <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions> - <UniqueIdentifier>{89C25BE5-A406-421D-A03E-1829A2E96921}</UniqueIdentifier> + <UniqueIdentifier>{047255FC-568B-4968-9167-306B7BC95B6D}</UniqueIdentifier> </Filter> <Filter Include="Header Files"> <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> - <UniqueIdentifier>{C1755921-6CDF-4C5E-A16F-564D80D9C88C}</UniqueIdentifier> + <UniqueIdentifier>{4B1DCCF4-7F0A-4571-BA4F-DF378E24BD68}</UniqueIdentifier> </Filter> <Filter Include="Resource Files"> <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions> - <UniqueIdentifier>{91D70E33-BE1D-40E5-B28D-65555B5DF102}</UniqueIdentifier> + <UniqueIdentifier>{AC1DECB1-7996-4C71-8D32-0543B4C57AD4}</UniqueIdentifier> </Filter> </ItemGroup> <ItemGroup> diff --git a/usb/umdf_fx2/exe/testapp.c b/usb/umdf_fx2/exe/testapp.c index 992b20c5..4aecf4c7 100644 --- a/usb/umdf_fx2/exe/testapp.c +++ b/usb/umdf_fx2/exe/testapp.c @@ -1037,7 +1037,7 @@ AsyncIo( error = GetLastError(); if (error != ERROR_IO_PENDING) { - wprintf(L" %d th read failed %d \n",i, GetLastError()); + wprintf(L" %Iu th read failed %d \n",i, GetLastError()); goto Error; } } @@ -1050,7 +1050,7 @@ AsyncIo( &pOvList[i]) == 0) { error = GetLastError(); if (error != ERROR_IO_PENDING) { - wprintf(L" %d th write failed %d \n",i, GetLastError()); + wprintf(L" %Iu th write failed %d \n",i, GetLastError()); goto Error; } } @@ -1080,7 +1080,7 @@ AsyncIo( i = completedOv - pOvList; - wprintf(L"Number of bytes read by request number %d is %d\n", + wprintf(L"Number of bytes read by request number %Iu is %d\n", i, numberOfBytesTransferred); if ( ReadFile( hDevice, @@ -1090,7 +1090,7 @@ AsyncIo( completedOv) == 0) { error = GetLastError(); if (error != ERROR_IO_PENDING) { - wprintf(L"%d th Read failed %d \n", i, GetLastError()); + wprintf(L"%Iu th Read failed %d \n", i, GetLastError()); goto Error; } } @@ -1098,7 +1098,7 @@ AsyncIo( i = completedOv - pOvList; - wprintf(L"Number of bytes written by request number %d is %d\n", + wprintf(L"Number of bytes written by request number %Iu is %d\n", i, numberOfBytesTransferred); if ( WriteFile( hDevice, @@ -1108,7 +1108,7 @@ AsyncIo( completedOv) == 0) { error = GetLastError(); if (error != ERROR_IO_PENDING) { - wprintf(L"%d th write failed %d \n", i, GetLastError()); + wprintf(L"%Iu th write failed %d \n", i, GetLastError()); goto Error; } } diff --git a/usb/umdf_fx2/inc/public.h b/usb/umdf_fx2/inc/public.h index 22f6cb6d..2c3f6805 100644 --- a/usb/umdf_fx2/inc/public.h +++ b/usb/umdf_fx2/inc/public.h @@ -155,7 +155,7 @@ typedef struct _FILE_PLAYBACK #include <poppack.h> #define IOCTL_INDEX 0x800 -#define FILE_DEVICE_OSRUSBFX2 0x65500 +#define FILE_DEVICE_OSRUSBFX2 65500U #define IOCTL_OSRUSBFX2_GET_CONFIG_DESCRIPTOR CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ IOCTL_INDEX, \ diff --git a/usb/umdf_fx2/umdf_fx2.sln b/usb/umdf_fx2/umdf_fx2.sln index bfaee1d4..c67f4db3 100644 --- a/usb/umdf_fx2/umdf_fx2.sln +++ b/usb/umdf_fx2/umdf_fx2.sln @@ -3,13 +3,13 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2013 VisualStudioVersion = 12.0 MinimumVisualStudioVersion = 12.0 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Driver", "Driver", "{8367199C-3B22-414B-BD8D-780BB74E06C6}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Driver", "Driver", "{0F58CCC8-C87F-436A-8155-C5A9C20AE3A0}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Exe", "Exe", "{002D6001-0177-4A2D-8CDF-6F2F6A9CAAB6}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Exe", "Exe", "{F891F391-8DC0-4256-B1E3-993DE7A0DEFF}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WUDFOsrUsbFx2", "driver\WUDFOsrUsbFx2.vcxproj", "{BCB0C08D-E6FC-4FE6-BFDE-723B3706FA53}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WUDFOsrUsbFx2", "driver\WUDFOsrUsbFx2.vcxproj", "{E73991B4-029F-448E-9CA8-0827CBE1EF0E}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WudfOsrUsbFx2Test", "exe\WudfOsrUsbFx2Test.vcxproj", "{24745B15-B6D2-4D1A-AB27-C0F38B1C0086}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WudfOsrUsbFx2Test", "exe\WudfOsrUsbFx2Test.vcxproj", "{F0965B23-D0A3-4587-85A3-FA4B20F2051D}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -19,28 +19,28 @@ Global Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {BCB0C08D-E6FC-4FE6-BFDE-723B3706FA53}.Debug|Win32.ActiveCfg = Debug|Win32 - {BCB0C08D-E6FC-4FE6-BFDE-723B3706FA53}.Debug|Win32.Build.0 = Debug|Win32 - {BCB0C08D-E6FC-4FE6-BFDE-723B3706FA53}.Release|Win32.ActiveCfg = Release|Win32 - {BCB0C08D-E6FC-4FE6-BFDE-723B3706FA53}.Release|Win32.Build.0 = Release|Win32 - {BCB0C08D-E6FC-4FE6-BFDE-723B3706FA53}.Debug|x64.ActiveCfg = Debug|x64 - {BCB0C08D-E6FC-4FE6-BFDE-723B3706FA53}.Debug|x64.Build.0 = Debug|x64 - {BCB0C08D-E6FC-4FE6-BFDE-723B3706FA53}.Release|x64.ActiveCfg = Release|x64 - {BCB0C08D-E6FC-4FE6-BFDE-723B3706FA53}.Release|x64.Build.0 = Release|x64 - {24745B15-B6D2-4D1A-AB27-C0F38B1C0086}.Debug|Win32.ActiveCfg = Debug|Win32 - {24745B15-B6D2-4D1A-AB27-C0F38B1C0086}.Debug|Win32.Build.0 = Debug|Win32 - {24745B15-B6D2-4D1A-AB27-C0F38B1C0086}.Release|Win32.ActiveCfg = Release|Win32 - {24745B15-B6D2-4D1A-AB27-C0F38B1C0086}.Release|Win32.Build.0 = Release|Win32 - {24745B15-B6D2-4D1A-AB27-C0F38B1C0086}.Debug|x64.ActiveCfg = Debug|x64 - {24745B15-B6D2-4D1A-AB27-C0F38B1C0086}.Debug|x64.Build.0 = Debug|x64 - {24745B15-B6D2-4D1A-AB27-C0F38B1C0086}.Release|x64.ActiveCfg = Release|x64 - {24745B15-B6D2-4D1A-AB27-C0F38B1C0086}.Release|x64.Build.0 = Release|x64 + {E73991B4-029F-448E-9CA8-0827CBE1EF0E}.Debug|Win32.ActiveCfg = Debug|Win32 + {E73991B4-029F-448E-9CA8-0827CBE1EF0E}.Debug|Win32.Build.0 = Debug|Win32 + {E73991B4-029F-448E-9CA8-0827CBE1EF0E}.Release|Win32.ActiveCfg = Release|Win32 + {E73991B4-029F-448E-9CA8-0827CBE1EF0E}.Release|Win32.Build.0 = Release|Win32 + {E73991B4-029F-448E-9CA8-0827CBE1EF0E}.Debug|x64.ActiveCfg = Debug|x64 + {E73991B4-029F-448E-9CA8-0827CBE1EF0E}.Debug|x64.Build.0 = Debug|x64 + {E73991B4-029F-448E-9CA8-0827CBE1EF0E}.Release|x64.ActiveCfg = Release|x64 + {E73991B4-029F-448E-9CA8-0827CBE1EF0E}.Release|x64.Build.0 = Release|x64 + {F0965B23-D0A3-4587-85A3-FA4B20F2051D}.Debug|Win32.ActiveCfg = Debug|Win32 + {F0965B23-D0A3-4587-85A3-FA4B20F2051D}.Debug|Win32.Build.0 = Debug|Win32 + {F0965B23-D0A3-4587-85A3-FA4B20F2051D}.Release|Win32.ActiveCfg = Release|Win32 + {F0965B23-D0A3-4587-85A3-FA4B20F2051D}.Release|Win32.Build.0 = Release|Win32 + {F0965B23-D0A3-4587-85A3-FA4B20F2051D}.Debug|x64.ActiveCfg = Debug|x64 + {F0965B23-D0A3-4587-85A3-FA4B20F2051D}.Debug|x64.Build.0 = Debug|x64 + {F0965B23-D0A3-4587-85A3-FA4B20F2051D}.Release|x64.ActiveCfg = Release|x64 + {F0965B23-D0A3-4587-85A3-FA4B20F2051D}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {BCB0C08D-E6FC-4FE6-BFDE-723B3706FA53} = {8367199C-3B22-414B-BD8D-780BB74E06C6} - {24745B15-B6D2-4D1A-AB27-C0F38B1C0086} = {002D6001-0177-4A2D-8CDF-6F2F6A9CAAB6} + {E73991B4-029F-448E-9CA8-0827CBE1EF0E} = {0F58CCC8-C87F-436A-8155-C5A9C20AE3A0} + {F0965B23-D0A3-4587-85A3-FA4B20F2051D} = {F891F391-8DC0-4256-B1E3-993DE7A0DEFF} EndGlobalSection EndGlobal diff --git a/usb/usbsamp/exe/usbsamp.vcxproj b/usb/usbsamp/exe/usbsamp.vcxproj index 5c27d51c..eea0d3e9 100644 --- a/usb/usbsamp/exe/usbsamp.vcxproj +++ b/usb/usbsamp/exe/usbsamp.vcxproj @@ -19,11 +19,11 @@ </ProjectConfiguration> </ItemGroup> <PropertyGroup Label="Globals"> - <ProjectGuid>{82B15C8E-818A-41C0-AE62-1AEA7270E8B6}</ProjectGuid> + <ProjectGuid>{623636B5-DD4A-4473-93C4-7F548F4F661C}</ProjectGuid> <RootNamespace>$(MSBuildProjectName)</RootNamespace> <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration> <Platform Condition="'$(Platform)' == ''">Win32</Platform> - <SampleGuid>{D84698F9-5D22-4B3F-ADC9-A65171DA8464}</SampleGuid> + <SampleGuid>{63EE6B90-F399-4C68-9C86-5A3C71ED4A9C}</SampleGuid> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> diff --git a/usb/usbsamp/exe/usbsamp.vcxproj.Filters b/usb/usbsamp/exe/usbsamp.vcxproj.Filters index d838bfe3..1f025d7a 100644 --- a/usb/usbsamp/exe/usbsamp.vcxproj.Filters +++ b/usb/usbsamp/exe/usbsamp.vcxproj.Filters @@ -3,15 +3,15 @@ <ItemGroup> <Filter Include="Source Files"> <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions> - <UniqueIdentifier>{EE38233A-C328-44AC-A845-0B8F28FBE8F3}</UniqueIdentifier> + <UniqueIdentifier>{EDAA5E88-8B8F-4E77-A983-EF46C5B66EC6}</UniqueIdentifier> </Filter> <Filter Include="Header Files"> <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> - <UniqueIdentifier>{F6CE757F-951D-4785-A12E-D52DE74A7231}</UniqueIdentifier> + <UniqueIdentifier>{F27EFB8E-EA0A-4FEC-B062-39268EE9A727}</UniqueIdentifier> </Filter> <Filter Include="Resource Files"> <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions> - <UniqueIdentifier>{9044173D-AE9F-4798-9138-C397123B741F}</UniqueIdentifier> + <UniqueIdentifier>{6AC21D38-62BA-4580-88B3-62FD7291113E}</UniqueIdentifier> </Filter> </ItemGroup> <ItemGroup> diff --git a/usb/usbsamp/sys/device.c b/usb/usbsamp/sys/device.c index a710a476..85e825e9 100644 --- a/usb/usbsamp/sys/device.c +++ b/usb/usbsamp/sys/device.c @@ -554,7 +554,7 @@ Return Value: attributes.ParentObject = pDeviceContext->WdfUsbTargetDevice; status = WdfMemoryCreate(&attributes, - NonPagedPool, + NonPagedPoolNx, POOL_TAG, size, &memory, diff --git a/usb/usbsamp/sys/driver/usbsamp.inx b/usb/usbsamp/sys/driver/usbsamp.inx Binary files differindex 88db6c19..4dc3fad2 100644 --- a/usb/usbsamp/sys/driver/usbsamp.inx +++ b/usb/usbsamp/sys/driver/usbsamp.inx diff --git a/usb/usbsamp/sys/driver/usbsamp.vcxproj b/usb/usbsamp/sys/driver/usbsamp.vcxproj index 0d96425a..ae4b4a66 100644 --- a/usb/usbsamp/sys/driver/usbsamp.vcxproj +++ b/usb/usbsamp/sys/driver/usbsamp.vcxproj @@ -19,12 +19,12 @@ </ProjectConfiguration> </ItemGroup> <PropertyGroup Label="Globals"> - <ProjectGuid>{6395CFC7-A0E1-40D8-A744-D1DC7B6513BA}</ProjectGuid> + <ProjectGuid>{EA4EE96E-A970-43CE-A269-514909A10BAB}</ProjectGuid> <RootNamespace>$(MSBuildProjectName)</RootNamespace> <KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR> <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration> <Platform Condition="'$(Platform)' == ''">Win32</Platform> - <SampleGuid>{D2F4B3C2-A1FA-433C-A698-DEF22D5B8A75}</SampleGuid> + <SampleGuid>{AA7C10D7-2E56-440D-8A5B-FFFA0FF2BB6C}</SampleGuid> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> @@ -75,13 +75,7 @@ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> </ImportGroup> - <ItemGroup Label="WrappedTaskItems"> - <Inf Include=".\usbsamp.inx"> - <Architecture>$(InfArch)</Architecture> - <SpecifyArchitecture>true</SpecifyArchitecture> - <CopyOutput>.\$(IntDir)\usbsamp.inf</CopyOutput> - </Inf> - </ItemGroup> + <ItemGroup Label="WrappedTaskItems" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <TargetName>usbsamp</TargetName> </PropertyGroup> diff --git a/usb/usbsamp/sys/driver/usbsamp.vcxproj.Filters b/usb/usbsamp/sys/driver/usbsamp.vcxproj.Filters index 18f603d0..c98c2f71 100644 --- a/usb/usbsamp/sys/driver/usbsamp.vcxproj.Filters +++ b/usb/usbsamp/sys/driver/usbsamp.vcxproj.Filters @@ -3,27 +3,22 @@ <ItemGroup> <Filter Include="Source Files"> <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions> - <UniqueIdentifier>{D6BF3D48-CBBA-42B5-B745-30ECADE8EC41}</UniqueIdentifier> + <UniqueIdentifier>{AD2988D8-6DA0-4869-9A1F-EFE79039AF5C}</UniqueIdentifier> </Filter> <Filter Include="Header Files"> <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> - <UniqueIdentifier>{DB8B8A2E-77FA-4567-8AA8-B36DE48FDC76}</UniqueIdentifier> + <UniqueIdentifier>{ED3E81C6-62FB-41AB-951A-E31D29B1D57A}</UniqueIdentifier> </Filter> <Filter Include="Resource Files"> <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions> - <UniqueIdentifier>{122D039B-46C3-41E1-AC33-2B0AFE33A066}</UniqueIdentifier> + <UniqueIdentifier>{496635AE-7630-4081-84FA-2AF8B9142237}</UniqueIdentifier> </Filter> <Filter Include="Driver Files"> <Extensions>inf;inv;inx;mof;mc;</Extensions> - <UniqueIdentifier>{EA2F6E70-5FFD-4177-A858-FCEA368FFBB1}</UniqueIdentifier> + <UniqueIdentifier>{7714C5D6-7632-4B05-BC97-BA989667B1BB}</UniqueIdentifier> </Filter> </ItemGroup> <ItemGroup> - <Inf Include=".\usbsamp.inx"> - <Filter>Driver Files</Filter> - </Inf> - </ItemGroup> - <ItemGroup> <ClCompile Include="..\bulkrwr.c"> <Filter>Source Files</Filter> </ClCompile> diff --git a/usb/usbsamp/usbsamp.sln b/usb/usbsamp/usbsamp.sln index 8be6bd1a..a267027e 100644 --- a/usb/usbsamp/usbsamp.sln +++ b/usb/usbsamp/usbsamp.sln @@ -3,15 +3,15 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2013 VisualStudioVersion = 12.0 MinimumVisualStudioVersion = 12.0 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Exe", "Exe", "{49A076C1-4A83-4A1D-9D0B-71543A6621D0}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Exe", "Exe", "{80AD724E-BFE1-47E0-B6FA-E932D5FCEB30}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Driver", "Driver", "{B3E94C51-B2D9-4787-95EF-4E9DFDEE5A6E}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Driver", "Driver", "{DF74B27B-D7BB-46F6-823D-45F57C939E3F}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Sys", "Sys", "{4305B583-BDD8-4C8B-BA67-EAD701F97A92}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Sys", "Sys", "{3049F8D5-4880-4493-A013-918EF97E262F}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "usbsamp", "exe\usbsamp.vcxproj", "{82B15C8E-818A-41C0-AE62-1AEA7270E8B6}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "usbsamp", "exe\usbsamp.vcxproj", "{623636B5-DD4A-4473-93C4-7F548F4F661C}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "usbsamp", "sys\driver\usbsamp.vcxproj", "{6395CFC7-A0E1-40D8-A744-D1DC7B6513BA}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "usbsamp", "sys\driver\usbsamp.vcxproj", "{EA4EE96E-A970-43CE-A269-514909A10BAB}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -21,29 +21,29 @@ Global Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {82B15C8E-818A-41C0-AE62-1AEA7270E8B6}.Debug|Win32.ActiveCfg = Debug|Win32 - {82B15C8E-818A-41C0-AE62-1AEA7270E8B6}.Debug|Win32.Build.0 = Debug|Win32 - {82B15C8E-818A-41C0-AE62-1AEA7270E8B6}.Release|Win32.ActiveCfg = Release|Win32 - {82B15C8E-818A-41C0-AE62-1AEA7270E8B6}.Release|Win32.Build.0 = Release|Win32 - {82B15C8E-818A-41C0-AE62-1AEA7270E8B6}.Debug|x64.ActiveCfg = Debug|x64 - {82B15C8E-818A-41C0-AE62-1AEA7270E8B6}.Debug|x64.Build.0 = Debug|x64 - {82B15C8E-818A-41C0-AE62-1AEA7270E8B6}.Release|x64.ActiveCfg = Release|x64 - {82B15C8E-818A-41C0-AE62-1AEA7270E8B6}.Release|x64.Build.0 = Release|x64 - {6395CFC7-A0E1-40D8-A744-D1DC7B6513BA}.Debug|Win32.ActiveCfg = Debug|Win32 - {6395CFC7-A0E1-40D8-A744-D1DC7B6513BA}.Debug|Win32.Build.0 = Debug|Win32 - {6395CFC7-A0E1-40D8-A744-D1DC7B6513BA}.Release|Win32.ActiveCfg = Release|Win32 - {6395CFC7-A0E1-40D8-A744-D1DC7B6513BA}.Release|Win32.Build.0 = Release|Win32 - {6395CFC7-A0E1-40D8-A744-D1DC7B6513BA}.Debug|x64.ActiveCfg = Debug|x64 - {6395CFC7-A0E1-40D8-A744-D1DC7B6513BA}.Debug|x64.Build.0 = Debug|x64 - {6395CFC7-A0E1-40D8-A744-D1DC7B6513BA}.Release|x64.ActiveCfg = Release|x64 - {6395CFC7-A0E1-40D8-A744-D1DC7B6513BA}.Release|x64.Build.0 = Release|x64 + {623636B5-DD4A-4473-93C4-7F548F4F661C}.Debug|Win32.ActiveCfg = Debug|Win32 + {623636B5-DD4A-4473-93C4-7F548F4F661C}.Debug|Win32.Build.0 = Debug|Win32 + {623636B5-DD4A-4473-93C4-7F548F4F661C}.Release|Win32.ActiveCfg = Release|Win32 + {623636B5-DD4A-4473-93C4-7F548F4F661C}.Release|Win32.Build.0 = Release|Win32 + {623636B5-DD4A-4473-93C4-7F548F4F661C}.Debug|x64.ActiveCfg = Debug|x64 + {623636B5-DD4A-4473-93C4-7F548F4F661C}.Debug|x64.Build.0 = Debug|x64 + {623636B5-DD4A-4473-93C4-7F548F4F661C}.Release|x64.ActiveCfg = Release|x64 + {623636B5-DD4A-4473-93C4-7F548F4F661C}.Release|x64.Build.0 = Release|x64 + {EA4EE96E-A970-43CE-A269-514909A10BAB}.Debug|Win32.ActiveCfg = Debug|Win32 + {EA4EE96E-A970-43CE-A269-514909A10BAB}.Debug|Win32.Build.0 = Debug|Win32 + {EA4EE96E-A970-43CE-A269-514909A10BAB}.Release|Win32.ActiveCfg = Release|Win32 + {EA4EE96E-A970-43CE-A269-514909A10BAB}.Release|Win32.Build.0 = Release|Win32 + {EA4EE96E-A970-43CE-A269-514909A10BAB}.Debug|x64.ActiveCfg = Debug|x64 + {EA4EE96E-A970-43CE-A269-514909A10BAB}.Debug|x64.Build.0 = Debug|x64 + {EA4EE96E-A970-43CE-A269-514909A10BAB}.Release|x64.ActiveCfg = Release|x64 + {EA4EE96E-A970-43CE-A269-514909A10BAB}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {82B15C8E-818A-41C0-AE62-1AEA7270E8B6} = {49A076C1-4A83-4A1D-9D0B-71543A6621D0} - {6395CFC7-A0E1-40D8-A744-D1DC7B6513BA} = {B3E94C51-B2D9-4787-95EF-4E9DFDEE5A6E} - {B3E94C51-B2D9-4787-95EF-4E9DFDEE5A6E} = {4305B583-BDD8-4C8B-BA67-EAD701F97A92} + {623636B5-DD4A-4473-93C4-7F548F4F661C} = {80AD724E-BFE1-47E0-B6FA-E932D5FCEB30} + {EA4EE96E-A970-43CE-A269-514909A10BAB} = {DF74B27B-D7BB-46F6-823D-45F57C939E3F} + {DF74B27B-D7BB-46F6-823D-45F57C939E3F} = {3049F8D5-4880-4493-A013-918EF97E262F} EndGlobalSection EndGlobal diff --git a/usb/usbview/usbview.sln b/usb/usbview/usbview.sln index 5993209e..bc2819c4 100644 --- a/usb/usbview/usbview.sln +++ b/usb/usbview/usbview.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2013 VisualStudioVersion = 12.0 MinimumVisualStudioVersion = 12.0 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "usbview", "usbview.vcxproj", "{3C291787-8A37-4E8C-86D5-0B739A1CEA74}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "usbview", "usbview.vcxproj", "{287B60C4-636F-4CE7-91C2-04E03A01B9C5}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -13,14 +13,14 @@ Global Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {3C291787-8A37-4E8C-86D5-0B739A1CEA74}.Debug|Win32.ActiveCfg = Debug|Win32 - {3C291787-8A37-4E8C-86D5-0B739A1CEA74}.Debug|Win32.Build.0 = Debug|Win32 - {3C291787-8A37-4E8C-86D5-0B739A1CEA74}.Release|Win32.ActiveCfg = Release|Win32 - {3C291787-8A37-4E8C-86D5-0B739A1CEA74}.Release|Win32.Build.0 = Release|Win32 - {3C291787-8A37-4E8C-86D5-0B739A1CEA74}.Debug|x64.ActiveCfg = Debug|x64 - {3C291787-8A37-4E8C-86D5-0B739A1CEA74}.Debug|x64.Build.0 = Debug|x64 - {3C291787-8A37-4E8C-86D5-0B739A1CEA74}.Release|x64.ActiveCfg = Release|x64 - {3C291787-8A37-4E8C-86D5-0B739A1CEA74}.Release|x64.Build.0 = Release|x64 + {287B60C4-636F-4CE7-91C2-04E03A01B9C5}.Debug|Win32.ActiveCfg = Debug|Win32 + {287B60C4-636F-4CE7-91C2-04E03A01B9C5}.Debug|Win32.Build.0 = Debug|Win32 + {287B60C4-636F-4CE7-91C2-04E03A01B9C5}.Release|Win32.ActiveCfg = Release|Win32 + {287B60C4-636F-4CE7-91C2-04E03A01B9C5}.Release|Win32.Build.0 = Release|Win32 + {287B60C4-636F-4CE7-91C2-04E03A01B9C5}.Debug|x64.ActiveCfg = Debug|x64 + {287B60C4-636F-4CE7-91C2-04E03A01B9C5}.Debug|x64.Build.0 = Debug|x64 + {287B60C4-636F-4CE7-91C2-04E03A01B9C5}.Release|x64.ActiveCfg = Release|x64 + {287B60C4-636F-4CE7-91C2-04E03A01B9C5}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/usb/usbview/usbview.vcxproj b/usb/usbview/usbview.vcxproj index bccb6d76..556eb823 100644 --- a/usb/usbview/usbview.vcxproj +++ b/usb/usbview/usbview.vcxproj @@ -19,11 +19,11 @@ </ProjectConfiguration> </ItemGroup> <PropertyGroup Label="Globals"> - <ProjectGuid>{3C291787-8A37-4E8C-86D5-0B739A1CEA74}</ProjectGuid> + <ProjectGuid>{287B60C4-636F-4CE7-91C2-04E03A01B9C5}</ProjectGuid> <RootNamespace>$(MSBuildProjectName)</RootNamespace> <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration> <Platform Condition="'$(Platform)' == ''">Win32</Platform> - <SampleGuid>{0B5874D8-CA5A-4459-9471-A4D9CBD82977}</SampleGuid> + <SampleGuid>{54E86405-9C3D-4F0F-B65C-AB86DE455DD7}</SampleGuid> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> diff --git a/usb/usbview/usbview.vcxproj.Filters b/usb/usbview/usbview.vcxproj.Filters index ee2d7801..41638088 100644 --- a/usb/usbview/usbview.vcxproj.Filters +++ b/usb/usbview/usbview.vcxproj.Filters @@ -3,15 +3,15 @@ <ItemGroup> <Filter Include="Source Files"> <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions> - <UniqueIdentifier>{24B15DD5-41FB-4742-A3C7-A074316B3FFD}</UniqueIdentifier> + <UniqueIdentifier>{C777FB60-2F35-4F70-B010-42EB0481E0AB}</UniqueIdentifier> </Filter> <Filter Include="Header Files"> <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> - <UniqueIdentifier>{52B35399-50CE-420D-B0C6-D6D79A82EF43}</UniqueIdentifier> + <UniqueIdentifier>{41539DC2-1C1B-4226-A94A-11E183276E61}</UniqueIdentifier> </Filter> <Filter Include="Resource Files"> <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions> - <UniqueIdentifier>{5DBEED0A-531F-4DD9-8C19-89D7EF22449E}</UniqueIdentifier> + <UniqueIdentifier>{F94D0D21-B95F-4E74-BB7A-11C427D0D82F}</UniqueIdentifier> </Filter> </ItemGroup> <ItemGroup> diff --git a/usb/usbview/xmlhelper.cpp b/usb/usbview/xmlhelper.cpp index cf39a87d..fc58840e 100644 --- a/usb/usbview/xmlhelper.cpp +++ b/usb/usbview/xmlhelper.cpp @@ -340,11 +340,11 @@ HRESULT XmlAddHostController(PSTR hcName, PUSBHOSTCONTROLLERINFO hcInfo) } else { - USB_CONTROLLER_FLAVOR flavor = hcInfo->ControllerInfo->ControllerFlavor; - // If protocol lookup failed based on service name, try Controller flavor if(NULL != hcInfo->ControllerInfo) { + USB_CONTROLLER_FLAVOR flavor = hcInfo->ControllerInfo->ControllerFlavor; + if(flavor == USB_HcGeneric) { hc->UsbProtocol = gcnew String(USB_GENERIC); @@ -353,11 +353,11 @@ HRESULT XmlAddHostController(PSTR hcName, PUSBHOSTCONTROLLERINFO hcInfo) { hc->UsbProtocol = gcnew String(USB_1_1); } - else if(flavor >= UHCI_Generic && flavor < EHCI_Generic) + else if(flavor >= UHCI_Generic && flavor <= EHCI_Generic) { hc->UsbProtocol = gcnew String(USB_2_0); } - else if(flavor >= EHCI_Generic) + else if(flavor > EHCI_Generic) { hc->UsbProtocol = gcnew String(USB_3_0); } diff --git a/usb/wdf_osrfx2_lab/README.md b/usb/wdf_osrfx2_lab/README.md new file mode 100644 index 00000000..6940418f --- /dev/null +++ b/usb/wdf_osrfx2_lab/README.md @@ -0,0 +1,370 @@ +WDF Sample Driver Learning Lab for OSR USB-FX2 +============================================== + +The wdf\_osrfx2\_lab sample contains a console test application and a series of iterative drivers for both Kernel-Mode Driver Framework (KMDF) and User-Mode Driver Framework (UMDF) version 1. + +In the Windows Driver Kit (WDK) for Windows 7 and earlier versions of Windows, the osrusbfx2 sample demonstrated how to perform bulk and interrupt data transfers to an USB device. The sample was written for the OSR USB-FX2 Learning Kit. + +Starting in Windows 8.1, the osrusbfx2 sample has been divided into these samples: + +- wdf\_osrfx2: This sample is a series of iterative drivers that demonstrate how to write a "Hello World" driver and adds additional features in each step. + +- [kmdf\_fx2](gallery_samples.123a_gallery#1): This sample is the final version of kernel-mode wdf\_osrfx2 driver. The sample demonstrates KMDF methods. + +- [umdf\_fx2](http://msdn.microsoft.com/en-us/library/windows/hardware/): This sample is the final version of the user-mode driver wdf\_osrfx2. The sample demonstrates UMDF methods. + +This sample is written for the OSR USB-FX2 Learning Kit. The specification for the device is at <http://www.osronline.com/hardware/OSRFX2_32.pdf>. + + +Related topics +-------------- + +[kmdf\_fx2](http://msdn.microsoft.com/en-us/library/windows/hardware/) + +[umdf\_fx2](http://msdn.microsoft.com/en-us/library/windows/hardware/) + + +Build the sample +---------------- + +The default Solution build configuration is Windows 8.1 Debug and Win32. You can change the default configuration to build for Windows 8 or Windows 7 version of the operating system. + +**To select a configuration and build a driver** + +1. Open the driver project or solution in Visual Studio 2013 (find *filtername*.sln or *filtername*.vcxproj). +2. Right-click the solution in the **Solutions Explorer** and select **Configuration Manager**. +3. From the **Configuration Manager**, select the **Active Solution Configuration** (for example, Windows 8.1 Debug or Windows 8.1 Release) and the **Active Solution Platform** (for example, Win32) that correspond to the type of build you are interested in. +4. Each driver project in this iterative sample creates a binary with the same name, osrusbfx2.sys. As a result, you can build only the single project you're currently working on, as well as the package project. You can do this by selecting only these two projects in **Configuration Manager**. +5. From the **Build** menu, click **Build Solution** (Ctrl+Shift+B). + +Overview +-------- + +Here is the overview of the device: + +- The device is based on the development board supplied with the Cypress EZ-USB FX2 Development Kit (CY3681). +- It contains 1 interface and 3 endpoints (Interrupt IN, Bulk Out, Bulk IN). +- Firmware supports vendor commands to query or set LED Bar graph display and 7-segment LED display, and to query toggle switch states. +- Interrupt Endpoint: + - Sends an 8-bit value that represents the state of the switches. + - Sent on startup, resume from suspend, and whenever the switch pack setting changes. + - Firmware does not de-bounce the switch pack. + - One switch change can result in multiple bytes being sent. + - Bits are in the reverse order of the labels on the pack (for example, bit 0x80 is labeled 1 on the pack). +- Bulk Endpoints are configured for loopback: + - The device moves data from IN endpoint to OUT endpoint. + - The device does not change the values of the data it receives nor does it internally create any data. + - Endpoints are always double buffered. + - Maximum packet size depends on speed (64 full speed, 512 high speed). + +Sample Contents for KMDF +------------------------ + +The KMDF sample contains a console test application and a series of drivers. The driver is iterative as a series of steps, starting with a basic "Hello World" driver. Each step is describe in the following table. + +<table> +<colgroup> +<col width="50%" /> +<col width="50%" /> +</colgroup> +<thead> +<tr class="header"> +<th align="left">Folder +Description</th> +</tr> +</thead> +<tbody> +<tr class="odd"> +<td align="left">usb\wdf_osrfx2_lab\kmdf\step1 +The most basic step. The source file contains a minimal amount of code to get the driver loaded in memory and respond to PnP and Power events. You can install, uninstall, disable, enable, suspend, and resume the system.</td> +<td align="left">usb\wdf_osrfx2_lab\kmdf\step2 +<ol> +<li>Creates a context with the WDFDEVICE object.</li> +<li>Initializes the USB device by registering a <em>EvtPrepareHardware</em> callback.</li> +<li>Registers an interface so that application can open a handle to the device.</li> +</ol></td> +</tr> +</tbody> +</table> + +Testing the driver +------------------ + +The sample includes a test application, osrusbfx2.exe, that you can use to test the device. This console application enumerates the interface registered by the driver and opens the device to send read, write, or IOCTL requests based on the command line options. + +Usage for Read/Write test: + +- -r [*n*], where *n* is number of bytes to read. +- -w [*n*], where *n* is number of bytes to write. +- -c [*n*], where *n* is number of iterations (default = 1). +- -v, shows verbose read data. +- -p, plays with Bar Display, Dip Switch, 7-Segment Display. +- -a, performs asynchronous I/O operation. +- -u, dumps USB configuration and pipe information. + +**Playing with the 7 segment display, toggle switches and bar graph display** + +Use the command **osrusbfx2.exe -p** with options 1-9 to set and clear bar graph display, set and get 7-segment state, and read the toggle switch states. The following list shows the function options: + +1. Light bar +2. Clear bar +3. Light entire bar graph +4. Clear entire bar graph +5. Get bar graph state +6. Get switch state +7. Get switch interrupt message +8. Get 7-segment state +9. Set 7-segment state +10. Reset the device +11. Re-enumerate the device + +0. Exit + +Selection: + +**Reset and re-enumerate the device** + +Use the command **osrusbfx2.exe -p** with option 10 and 11 to either reset the device or re-enumerate the device. + +**Read and write to bulk endpoints** + +The following commands send read and write requests to the device's bulk endpoint. + +- `osrusbfx2.exe -r 64` + + The preceding command reads 64 bytes to the bulk IN endpoint. + +- `osrusbfx2.exe -w 64 ` + + The preceding command writes 64 bytes to the bulk OUT endpoint. + +- `osrusbfx2.exe -r 64 -w 64 -c 100 -v` + + The preceding command first writes 64 bytes of data to bulk OUT endpoint (Pipe 1), then reads 64 bytes from bulk IN endpoint (Pipe 2), and then compares the read buffer with write buffer to see if they match. If the buffer contents match, it repeats this operation 100 times. + +- `osrusbfx2.exe -a` + + The preceding command reads and writes to the device asynchronously in an infinite loop. + +The bulk endpoints are double buffered. Depending on the operational speed (full or high), the buffer size is either 64 bytes or 512 bytes, respectively. A request to read data doesn't complete if the buffers are empty. If the buffers are full, a request to write data does not complete until the buffers are emptied. When you are doing a synchronous read, make sure the endpoint buffer has data (for example, when you send 512 bytes write request to the device operating in full speed mode). Because the endpoints are double buffered, the total buffer capacity is 256 bytes. The first 256 bytes fills the buffer and the write request waits in the USB stack until the buffers are emptied. If you run another instance of the application to read 512 bytes of data, both write and read requests complete successfully. + +**Displaying descriptors** + +The following command displays all the descriptors and endpoint information. + +**osrusbfx2.exe -u** + +If the device is operating in high speed mode, you get the following information: + +`===================` + +`USB_CONFIGURATION_DESCRIPTOR` + +`bLength = 0x9, decimal 9` + +`bDescriptorType = 0x2 ( USB_CONFIGURATION_DESCRIPTOR_TYPE )` + +`wTotalLength = 0x27, decimal 39` + +`bNumInterfaces = 0x1, decimal 1` + +`bConfigurationValue = 0x1, decimal 1` + +`iConfiguration = 0x4, decimal 4` + +`bmAttributes = 0xa0 ( USB_CONFIG_BUS_POWERED )` + +`MaxPower = 0x32, decimal 50` + +`-----------------------------` + +`USB_INTERFACE_DESCRIPTOR #0` + +`bLength = 0x9` + +`bDescriptorType = 0x4 ( USB_INTERFACE_DESCRIPTOR_TYPE )` + +`bInterfaceNumber = 0x0` + +`bAlternateSetting = 0x0` + +`bNumEndpoints = 0x3` + +`bInterfaceClass = 0xff` + +`bInterfaceSubClass = 0x0` + +`bInterfaceProtocol = 0x0` + +`bInterface = 0x0` + +`------------------------------` + +`USB_ENDPOINT_DESCRIPTOR for Pipe00` + +`bLength = 0x7` + +`bDescriptorType = 0x5 ( USB_ENDPOINT_DESCRIPTOR_TYPE )` + +`bEndpointAddress= 0x81 ( INPUT )` + +`bmAttributes= 0x3 ( USB_ENDPOINT_TYPE_INTERRUPT )` + +`wMaxPacketSize= 0x49, decimal 73` + +`bInterval = 0x1, decimal 1` + +`------------------------------` + +`USB_ENDPOINT_DESCRIPTOR for Pipe01` + +`bLength = 0x7` + +`bDescriptorType = 0x5 ( USB_ENDPOINT_DESCRIPTOR_TYPE )` + +`bEndpointAddress= 0x6 ( OUTPUT )` + +`bmAttributes= 0x2 ( USB_ENDPOINT_TYPE_BULK )` + +`wMaxPacketSize= 0x200, ` + +`decimal 512 bInterval = 0x0, ` + +`decimal 0` + +`------------------------------` + +`USB_ENDPOINT_DESCRIPTOR for Pipe02` + +`bLength = 0x7` + +`bDescriptorType = 0x5 ( USB_ENDPOINT_DESCRIPTOR_TYPE )` + +`bEndpointAddress= 0x88 ( INPUT )` + +`bmAttributes= 0x2 ( USB_ENDPOINT_TYPE_BULK )` + +`wMaxPacketSize= 0x200, decimal 512` + +`bInterval = 0x0, decimal 0` + +If the device is operating in low speed mode, you will get the following information: + +`===================` + +`USB_CONFIGURATION_DESCRIPTOR` + +`bLength = 0x9, decimal 9` + +`bDescriptorType = 0x2 ( USB_CONFIGURATION_DESCRIPTOR_TYPE )` + +`wTotalLength = 0x27, decimal 39` + +`bNumInterfaces = 0x1, decimal 1` + +`bConfigurationValue = 0x1, decimal 1` + +`iConfiguration = 0x3, decimal 3` + +`bmAttributes = 0xa0 ( USB_CONFIG_BUS_POWERED )` + +`MaxPower = 0x32, decimal 50 ` + +`-----------------------------` + +`USB_INTERFACE_DESCRIPTOR #0` + +`bLength = 0x9` + +`bDescriptorType = 0x4 ( USB_INTERFACE_DESCRIPTOR_TYPE )` + +`bInterfaceNumber = 0x0 bAlternateSetting = 0x0` + +`bNumEndpoints = 0x3` + +`bInterfaceClass = 0xff` + +`bInterfaceSubClass = 0x0` + +`bInterfaceProtocol = 0x0` + +`bInterface = 0x0` + +`------------------------------` + +`USB_ENDPOINT_DESCRIPTOR for Pipe00` + +`bLength = 0x7` + +`bDescriptorType = 0x5 ( USB_ENDPOINT_DESCRIPTOR_TYPE )` + +`bEndpointAddress= 0x81 ( INPUT )` + +`bmAttributes= 0x3 ( USB_ENDPOINT_TYPE_INTERRUPT )` + +`wMaxPacketSize= 0x49, decimal 73` + +`bInterval = 0x1, decimal 1` + +`------- -----------------------` + +`USB_ENDPOINT_DESCRIPTOR for Pipe01` + +`bLength = 0x7` + +`bDescriptorType = 0x5 ( USB_ENDPOINT_DESCRIPTOR_TYPE )` + +`bEndpointAddress= 0x6 ( OUTPUT )` + +`bmAttributes= 0x2 ( USB_ENDPOINT_TYPE_BULK )` + +`wMaxPacketSize= 0x40, decimal 64` + +`bInterval = 0x0, decimal 0` + +`------------------------------` + +`USB_ENDPOINT_DESCRIPTOR for Pipe02` + +`bLength = 0x7` + +`bDescriptorType = 0x5 ( USB_ENDPOINT_DESCRIPTOR_TYPE )` + +`bEndpointAddress= 0x88 ( INPUT )` + +`bmAttributes= 0x2 ( USB_ENDPOINT_TYPE_BULK )` + +`wMaxPacketSize= 0x40, decimal 64` + +`bInterval = 0x0, decimal 0 ` + +Sample Contents for UMDF +------------------------ + +The UMDF sample driver is developed as a series of steps, starting with a basic "Hello World" driver. Each step progressively adds functionality to the previous step. Each step is described in the following table. + +<table> +<colgroup> +<col width="50%" /> +<col width="50%" /> +</colgroup> +<thead> +<tr class="header"> +<th align="left">Folder +Description</th> +</tr> +</thead> +<tbody> +<tr class="odd"> +<td align="left">usb\wdf_osrfx2_lab\umdf\step1 +The most basic step. The source file contains a minimal amount of code to get the driver loaded in memory and respond to PnP and Power events. You can install, uninstall, disable, enable, suspend, and resume the system.</td> +<td align="left">usb\wdf_osrfx2_lab\umdf\step2 +<ol> +<li>The device registers a PnP device interface so that application can open a handle to the device.</li> +<li>The device object implements <strong>IPnpCallbackHardware</strong> interface and initializes USB I/O targets in <strong>IPnpCallbackHardware::OnPrepareHardware</strong> method.</li> +</ol></td> +</tr> +</tbody> +</table> + + diff --git a/usb/wdf_osrfx2_lab/kmdf/exe/dump.c b/usb/wdf_osrfx2_lab/kmdf/exe/dump.c new file mode 100644 index 00000000..69074bf1 --- /dev/null +++ b/usb/wdf_osrfx2_lab/kmdf/exe/dump.c @@ -0,0 +1,444 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + + THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR + PURPOSE. + +Module Name: + + DUMP.C + +Abstract: + + Routines to dump the descriptors information in a human readable form. + +Environment: + + user mode only + +--*/ + +#include <windows.h> +#include <stdio.h> +#include <stdlib.h> +#include "devioctl.h" + +#pragma warning(disable:4200) // +#pragma warning(disable:4201) // nameless struct/union +#pragma warning(disable:4214) // bit field types other than int + +#include <basetyps.h> +#include "usbdi.h" +#include "public.h" + +#pragma warning(default:4200) +#pragma warning(default:4201) +#pragma warning(default:4214) + +HANDLE +OpenDevice( + _In_ BOOL Synchronous + ); + + +char* +usbDescriptorTypeString(UCHAR bDescriptorType ) +/*++ +Routine Description: + + Called to get ascii string of USB descriptor + +Arguments: + + PUSB_ENDPOINT_DESCRIPTOR->bDescriptorType or + PUSB_DEVICE_DESCRIPTOR->bDescriptorType or + PUSB_INTERFACE_DESCRIPTOR->bDescriptorType or + PUSB_STRING_DESCRIPTOR->bDescriptorType or + PUSB_POWER_DESCRIPTOR->bDescriptorType or + PUSB_CONFIGURATION_DESCRIPTOR->bDescriptorType + +Return Value: + + ptr to string + +--*/ +{ + + switch(bDescriptorType) { + + case USB_DEVICE_DESCRIPTOR_TYPE: + return "USB_DEVICE_DESCRIPTOR_TYPE"; + + case USB_CONFIGURATION_DESCRIPTOR_TYPE: + return "USB_CONFIGURATION_DESCRIPTOR_TYPE"; + + + case USB_STRING_DESCRIPTOR_TYPE: + return "USB_STRING_DESCRIPTOR_TYPE"; + + + case USB_INTERFACE_DESCRIPTOR_TYPE: + return "USB_INTERFACE_DESCRIPTOR_TYPE"; + + + case USB_ENDPOINT_DESCRIPTOR_TYPE: + return "USB_ENDPOINT_DESCRIPTOR_TYPE"; + + +#ifdef USB_POWER_DESCRIPTOR_TYPE // this is the older definintion which is actually obsolete + // workaround for temporary bug in 98ddk, older USB100.h file + case USB_POWER_DESCRIPTOR_TYPE: + return "USB_POWER_DESCRIPTOR_TYPE"; +#endif + +#ifdef USB_RESERVED_DESCRIPTOR_TYPE // this is the current version of USB100.h as in NT5DDK + + case USB_RESERVED_DESCRIPTOR_TYPE: + return "USB_RESERVED_DESCRIPTOR_TYPE"; + + case USB_CONFIG_POWER_DESCRIPTOR_TYPE: + return "USB_CONFIG_POWER_DESCRIPTOR_TYPE"; + + case USB_INTERFACE_POWER_DESCRIPTOR_TYPE: + return "USB_INTERFACE_POWER_DESCRIPTOR_TYPE"; +#endif // for current nt5ddk version of USB100.h + + default: + return "??? UNKNOWN!!"; + } +} + + +char * +usbEndPointTypeString(UCHAR bmAttributes) +/*++ +Routine Description: + + Called to get ascii string of endpt descriptor type + +Arguments: + + PUSB_ENDPOINT_DESCRIPTOR->bmAttributes + +Return Value: + + ptr to string + +--*/ +{ + UINT typ = bmAttributes & USB_ENDPOINT_TYPE_MASK; + + + switch( typ) { + case USB_ENDPOINT_TYPE_INTERRUPT: + return "USB_ENDPOINT_TYPE_INTERRUPT"; + + case USB_ENDPOINT_TYPE_BULK: + return "USB_ENDPOINT_TYPE_BULK"; + + case USB_ENDPOINT_TYPE_ISOCHRONOUS: + return "USB_ENDPOINT_TYPE_ISOCHRONOUS"; + + case USB_ENDPOINT_TYPE_CONTROL: + return "USB_ENDPOINT_TYPE_CONTROL"; + + default: + return "??? UNKNOWN!!"; + } +} + + +char * +usbConfigAttributesString(UCHAR bmAttributes) +/*++ +Routine Description: + + Called to get ascii string of USB_CONFIGURATION_DESCRIPTOR attributes + +Arguments: + + PUSB_CONFIGURATION_DESCRIPTOR->bmAttributes + +Return Value: + + ptr to string + +--*/ +{ + UINT typ = bmAttributes & USB_CONFIG_POWERED_MASK; + + + switch( typ) { + + case USB_CONFIG_BUS_POWERED: + return "USB_CONFIG_BUS_POWERED"; + + case USB_CONFIG_SELF_POWERED: + return "USB_CONFIG_SELF_POWERED"; + + case USB_CONFIG_REMOTE_WAKEUP: + return "USB_CONFIG_REMOTE_WAKEUP"; + + + default: + return "??? UNKNOWN!!"; + } +} + + +void +print_USB_CONFIGURATION_DESCRIPTOR(PUSB_CONFIGURATION_DESCRIPTOR cd) +/*++ +Routine Description: + + Called to do formatted ascii dump to console of a USB config descriptor + +Arguments: + + ptr to USB configuration descriptor + +Return Value: + + none + +--*/ +{ + printf("\n===================\nUSB_CONFIGURATION_DESCRIPTOR\n"); + + printf( + "bLength = 0x%x, decimal %d\n", cd->bLength, cd->bLength + ); + + printf( + "bDescriptorType = 0x%x ( %s )\n", cd->bDescriptorType, + usbDescriptorTypeString( cd->bDescriptorType ) + ); + + printf( + "wTotalLength = 0x%x, decimal %d\n", cd->wTotalLength, cd->wTotalLength + ); + + printf( + "bNumInterfaces = 0x%x, decimal %d\n", cd->bNumInterfaces, cd->bNumInterfaces + ); + + printf( + "bConfigurationValue = 0x%x, decimal %d\n", + cd->bConfigurationValue, cd->bConfigurationValue + ); + + printf( + "iConfiguration = 0x%x, decimal %d\n", cd->iConfiguration, cd->iConfiguration + ); + + printf( + "bmAttributes = 0x%x ( %s )\n", cd->bmAttributes, + usbConfigAttributesString( cd->bmAttributes ) + ); + + printf( + "MaxPower = 0x%x, decimal %d\n", cd->MaxPower, cd->MaxPower + ); +} + + +void +print_USB_INTERFACE_DESCRIPTOR(PUSB_INTERFACE_DESCRIPTOR id, UINT ix) +/*++ +Routine Description: + + Called to do formatted ascii dump to console of a USB interface descriptor + +Arguments: + + ptr to USB interface descriptor + +Return Value: + + none + +--*/ +{ + printf("\n-----------------------------\nUSB_INTERFACE_DESCRIPTOR #%d\n", ix); + + + printf( + "bLength = 0x%x\n", id->bLength + ); + + + printf( + "bDescriptorType = 0x%x ( %s )\n", id->bDescriptorType, + usbDescriptorTypeString( id->bDescriptorType ) + ); + + + printf( + "bInterfaceNumber = 0x%x\n", id->bInterfaceNumber + ); + printf( + "bAlternateSetting = 0x%x\n", id->bAlternateSetting + ); + printf( + "bNumEndpoints = 0x%x\n", id->bNumEndpoints + ); + printf( + "bInterfaceClass = 0x%x\n", id->bInterfaceClass + ); + printf( + "bInterfaceSubClass = 0x%x\n", id->bInterfaceSubClass + ); + printf( + "bInterfaceProtocol = 0x%x\n", id->bInterfaceProtocol + ); + printf( + "bInterface = 0x%x\n", id->iInterface + ); +} + + +void +print_USB_ENDPOINT_DESCRIPTOR(PUSB_ENDPOINT_DESCRIPTOR ed, int i) +/*++ +Routine Description: + + Called to do formatted ascii dump to console of a USB endpoint descriptor + +Arguments: + + ptr to USB endpoint descriptor, + index of this endpt in interface desc + +Return Value: + + none + +--*/ +{ + printf( + "------------------------------\nUSB_ENDPOINT_DESCRIPTOR for Pipe%02d\n", i + ); + + printf( + "bLength = 0x%x\n", ed->bLength + ); + + printf( + "bDescriptorType = 0x%x ( %s )\n", ed->bDescriptorType, + usbDescriptorTypeString( ed->bDescriptorType ) + ); + + if ( USB_ENDPOINT_DIRECTION_IN( ed->bEndpointAddress ) ) { + printf( + "bEndpointAddress= 0x%x ( INPUT )\n", ed->bEndpointAddress + ); + } else { + printf( + "bEndpointAddress= 0x%x ( OUTPUT )\n", ed->bEndpointAddress + ); + } + + printf( + "bmAttributes= 0x%x ( %s )\n", ed->bmAttributes, + usbEndPointTypeString ( ed->bmAttributes ) + ); + + printf( + "wMaxPacketSize= 0x%x, decimal %d\n", ed->wMaxPacketSize, + ed->wMaxPacketSize + ); + + printf( + "bInterval = 0x%x, decimal %d\n", ed->bInterval, ed->bInterval + ); +} + + +BOOL +DumpUsbConfig() +/*++ +Routine Description: + + Called to do formatted ascii dump to console of USB + configuration, interface, and endpoint descriptors. + +Arguments: + + none + +Return Value: + + TRUE or FALSE + +--*/ +{ + HANDLE hDev; + UINT success; + int siz, nBytes; + char buf[256] = {'\0'}; + + hDev = OpenDevice(TRUE); + if(hDev == INVALID_HANDLE_VALUE) + { + return FALSE; + } + + siz = sizeof(buf); + + success = DeviceIoControl(hDev, + IOCTL_OSRUSBFX2_GET_CONFIG_DESCRIPTOR, + buf, + siz, + buf, + siz, + (PULONG) &nBytes, + NULL); + + if(success == FALSE) { + printf("Ioct - GetConfigDesc failed %d\n", GetLastError()); + } else { + + ULONG i; + UINT j, n; + char *pch; + PUSB_CONFIGURATION_DESCRIPTOR cd; + PUSB_INTERFACE_DESCRIPTOR id; + PUSB_ENDPOINT_DESCRIPTOR ed; + + pch = buf; + n = 0; + + cd = (PUSB_CONFIGURATION_DESCRIPTOR) pch; + + print_USB_CONFIGURATION_DESCRIPTOR( cd ); + + pch += cd->bLength; + + do { + id = (PUSB_INTERFACE_DESCRIPTOR) pch; + + print_USB_INTERFACE_DESCRIPTOR(id, n++); + + pch += id->bLength; + for (j=0; j<id->bNumEndpoints; j++) { + + ed = (PUSB_ENDPOINT_DESCRIPTOR) pch; + + print_USB_ENDPOINT_DESCRIPTOR(ed,j); + + pch += ed->bLength; + } + i = (ULONG)(pch - buf); + + } while (i<cd->wTotalLength); + } + + CloseHandle(hDev); + + return success; + +} + diff --git a/usb/wdf_osrfx2_lab/kmdf/exe/osrusbfx2.vcxproj b/usb/wdf_osrfx2_lab/kmdf/exe/osrusbfx2.vcxproj new file mode 100644 index 00000000..9da8f04b --- /dev/null +++ b/usb/wdf_osrfx2_lab/kmdf/exe/osrusbfx2.vcxproj @@ -0,0 +1,192 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{6EED5CDD-5526-40DC-97F9-582857E10187}</ProjectGuid> + <RootNamespace>$(MSBuildProjectName)</RootNamespace> + <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration> + <Platform Condition="'$(Platform)' == ''">Win32</Platform> + <SampleGuid>{F19E45AF-8B05-4204-A66B-9BDBFE333233}</SampleGuid> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + <DriverType /> + <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + <DriverType /> + <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + <DriverType /> + <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + <DriverType /> + <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <OutDir>$(IntDir)</OutDir> + </PropertyGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ItemGroup Label="WrappedTaskItems" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetName>osrusbfx2</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetName>osrusbfx2</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetName>osrusbfx2</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetName>osrusbfx2</TargetName> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\sys\inc</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\sys\inc</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions> + </ResourceCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\sys\inc</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);mincore.lib</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\sys\inc</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\sys\inc</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions> + </ResourceCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\sys\inc</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);mincore.lib</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\sys\inc</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\sys\inc</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions> + </ResourceCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\sys\inc</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);mincore.lib</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\sys\inc</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\sys\inc</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions> + </ResourceCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH);..\inc;..\sys\inc</AdditionalIncludeDirectories> + <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);mincore.lib</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="dump.c" /> + <ClCompile Include="testapp.c" /> + <ResourceCompile Include="testapp.rc" /> + </ItemGroup> + <ItemGroup> + <Inf Exclude="@(Inf)" Include="*.inf" /> + <FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" /> + </ItemGroup> + <ItemGroup> + <None Exclude="@(None)" Include="*.txt;*.htm;*.html" /> + <None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" /> + <None Exclude="@(None)" Include="*.def;*.bat;*.hpj;*.asmx" /> + </ItemGroup> + <ItemGroup> + <ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> +</Project>
\ No newline at end of file diff --git a/usb/wdf_osrfx2_lab/kmdf/exe/osrusbfx2.vcxproj.Filters b/usb/wdf_osrfx2_lab/kmdf/exe/osrusbfx2.vcxproj.Filters new file mode 100644 index 00000000..f9efc3e3 --- /dev/null +++ b/usb/wdf_osrfx2_lab/kmdf/exe/osrusbfx2.vcxproj.Filters @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions> + <UniqueIdentifier>{D5BFAD22-1AD2-44F8-AC33-05C04A9C26D9}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files"> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + <UniqueIdentifier>{14E678C7-EAC3-42F6-9F4B-2CDD17427D73}</UniqueIdentifier> + </Filter> + <Filter Include="Resource Files"> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions> + <UniqueIdentifier>{CEE0A75C-90B6-472A-8FC1-9375F1EAD2C9}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="dump.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="testapp.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="testapp.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/usb/wdf_osrfx2_lab/kmdf/exe/test.cmd b/usb/wdf_osrfx2_lab/kmdf/exe/test.cmd new file mode 100644 index 00000000..30b18b85 --- /dev/null +++ b/usb/wdf_osrfx2_lab/kmdf/exe/test.cmd @@ -0,0 +1,6 @@ +FOR /L %%i IN (0,1,100000) do ( + + osrusbfx2.exe -r 512 -w 512 -c 1000000 -v + +) + diff --git a/usb/wdf_osrfx2_lab/kmdf/exe/testapp.c b/usb/wdf_osrfx2_lab/kmdf/exe/testapp.c new file mode 100644 index 00000000..fce915b5 --- /dev/null +++ b/usb/wdf_osrfx2_lab/kmdf/exe/testapp.c @@ -0,0 +1,1210 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + + THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR + PURPOSE. + +Module Name: + + TESTAPP.C + +Abstract: + + Console test app for osrusbfx2 driver. + +Environment: + + user mode only + +--*/ + + +#include <DriverSpecs.h> +_Analysis_mode_(_Analysis_code_type_user_code_) + +#include <windows.h> +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> + +#include "devioctl.h" +#include "strsafe.h" + +#pragma warning(disable:4200) // +#pragma warning(disable:4201) // nameless struct/union +#pragma warning(disable:4214) // bit field types other than int + +#include <cfgmgr32.h> +#include <basetyps.h> +#include "usbdi.h" +#include "public.h" + +#pragma warning(default:4200) +#pragma warning(default:4201) +#pragma warning(default:4214) + +#define WHILE(a) \ +while(__pragma(warning(disable:4127)) a __pragma(warning(disable:4127))) + +#define MAX_DEVPATH_LENGTH 256 +#define NUM_ASYNCH_IO 100 +#define BUFFER_SIZE 1024 +#define READER_TYPE 1 +#define WRITER_TYPE 2 + +BOOL G_fDumpUsbConfig = FALSE; // flags set in response to console command line switches +BOOL G_fDumpReadData = FALSE; +BOOL G_fRead = FALSE; +BOOL G_fWrite = FALSE; +BOOL G_fPlayWithDevice = FALSE; +BOOL G_fPerformAsyncIo = FALSE; +ULONG G_IterationCount = 1; //count of iterations of the test we are to perform +ULONG G_WriteLen = 512; // #bytes to write +ULONG G_ReadLen = 512; // #bytes to read + +BOOL +DumpUsbConfig( // defined in dump.c + ); + +typedef enum _INPUT_FUNCTION { + LIGHT_ONE_BAR = 1, + CLEAR_ONE_BAR, + LIGHT_ALL_BARS, + CLEAR_ALL_BARS, + GET_BAR_GRAPH_LIGHT_STATE, + GET_SWITCH_STATE, + GET_SWITCH_STATE_AS_INTERRUPT_MESSAGE, + GET_7_SEGEMENT_STATE, + SET_7_SEGEMENT_STATE, + RESET_DEVICE, + REENUMERATE_DEVICE, +} INPUT_FUNCTION; + +_Success_(return) +BOOL +GetDevicePath( + _In_ LPGUID InterfaceGuid, + _Out_writes_z_(BufLen) PWCHAR DevicePath, + _In_ size_t BufLen + ) +{ + CONFIGRET cr = CR_SUCCESS; + PWSTR deviceInterfaceList = NULL; + ULONG deviceInterfaceListLength = 0; + PWSTR nextInterface; + HRESULT hr = E_FAIL; + BOOL bRet = TRUE; + + cr = CM_Get_Device_Interface_List_Size( + &deviceInterfaceListLength, + InterfaceGuid, + NULL, + CM_GET_DEVICE_INTERFACE_LIST_PRESENT); + if (cr != CR_SUCCESS) { + printf("Error 0x%x retrieving device interface list size.\n", cr); + goto clean0; + } + + if (deviceInterfaceListLength <= 1) { + bRet = FALSE; + printf("Error: No active device interfaces found.\n" + " Is the sample driver loaded?"); + goto clean0; + } + + deviceInterfaceList = (PWSTR)malloc(deviceInterfaceListLength * sizeof(WCHAR)); + if (deviceInterfaceList == NULL) { + printf("Error allocating memory for device interface list.\n"); + goto clean0; + } + ZeroMemory(deviceInterfaceList, deviceInterfaceListLength * sizeof(WCHAR)); + + cr = CM_Get_Device_Interface_List( + InterfaceGuid, + NULL, + deviceInterfaceList, + deviceInterfaceListLength, + CM_GET_DEVICE_INTERFACE_LIST_PRESENT); + if (cr != CR_SUCCESS) { + printf("Error 0x%x retrieving device interface list.\n", cr); + goto clean0; + } + + nextInterface = deviceInterfaceList + wcslen(deviceInterfaceList) + 1; + if (*nextInterface != UNICODE_NULL) { + printf("Warning: More than one device interface instance found. \n" + "Selecting first matching device.\n\n"); + } + + hr = StringCchCopy(DevicePath, BufLen, deviceInterfaceList); + if (FAILED(hr)) { + bRet = FALSE; + printf("Error: StringCchCopy failed with HRESULT 0x%x", hr); + goto clean0; + } + +clean0: + if (deviceInterfaceList != NULL) { + free(deviceInterfaceList); + } + if (CR_SUCCESS != cr) { + bRet = FALSE; + } + + return bRet; +} + + +HANDLE +OpenDevice( + _In_ BOOL Synchronous + ) + +/*++ +Routine Description: + + Called by main() to open an instance of our device after obtaining its name + +Arguments: + + Synchronous - TRUE, if Device is to be opened for synchronous access. + FALSE, otherwise. + +Return Value: + + Device handle on success else INVALID_HANDLE_VALUE + +--*/ + +{ + HANDLE hDev; + WCHAR completeDeviceName[MAX_DEVPATH_LENGTH]; + + if ( !GetDevicePath( + (LPGUID) &GUID_DEVINTERFACE_OSRUSBFX2, + completeDeviceName, + sizeof(completeDeviceName)/sizeof(completeDeviceName[0])) ) + { + return INVALID_HANDLE_VALUE; + } + + printf("DeviceName = (%S)\n", completeDeviceName); + + if(Synchronous) { + hDev = CreateFile(completeDeviceName, + GENERIC_WRITE | GENERIC_READ, + FILE_SHARE_WRITE | FILE_SHARE_READ, + NULL, // default security + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + } else { + + hDev = CreateFile(completeDeviceName, + GENERIC_WRITE | GENERIC_READ, + FILE_SHARE_WRITE | FILE_SHARE_READ, + NULL, // default security + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, + NULL); + } + + if (hDev == INVALID_HANDLE_VALUE) { + printf("Failed to open the device, error - %d", GetLastError()); + } else { + printf("Opened the device successfully.\n"); + } + + return hDev; +} + + + +VOID +Usage() + +/*++ +Routine Description: + + Called by main() to dump usage info to the console when + the app is called with no parms or with an invalid parm + +Arguments: + + None + +Return Value: + + None + +--*/ + +{ + printf("Usage for osrusbfx2 testapp:\n"); + printf("-r [n] where n is number of bytes to read\n"); + printf("-w [n] where n is number of bytes to write\n"); + printf("-c [n] where n is number of iterations (default = 1)\n"); + printf("-v verbose -- dumps read data\n"); + printf("-p to control bar LEDs, seven segment, and dip switch\n"); + printf("-a to perform asynchronous I/O\n"); + printf("-u to dump USB configuration and pipe info \n"); + + return; +} + + +void +Parse( + _In_ int argc, + _In_reads_(argc) LPSTR *argv + ) + +/*++ +Routine Description: + + Called by main() to parse command line parms + +Arguments: + + argc and argv that was passed to main() + +Return Value: + + Sets global flags as per user function request + +--*/ + +{ + int i; + + if ( argc < 2 ) // give usage if invoked with no parms + Usage(); + + for (i=0; i<argc; i++) { + if (argv[i][0] == '-' || + argv[i][0] == '/') { + switch(argv[i][1]) { + case 'r': + case 'R': + if (i+1 >= argc) { + Usage(); + exit(1); + } + else { +#pragma warning(suppress: 6385) + G_ReadLen = atoi(&argv[i+1][0]); + G_fRead = TRUE; + } + i++; + break; + case 'w': + case 'W': + if (i+1 >= argc) { + Usage(); + exit(1); + } + else { + G_WriteLen = atoi(&argv[i+1][0]); + G_fWrite = TRUE; + } + i++; + break; + case 'c': + case 'C': + if (i+1 >= argc) { + Usage(); + exit(1); + } + else { + G_IterationCount = atoi(&argv[i+1][0]); + } + i++; + break; + case 'u': + case 'U': + G_fDumpUsbConfig = TRUE; + break; + case 'p': + case 'P': + G_fPlayWithDevice = TRUE; + break; + case 'a': + case 'A': + G_fPerformAsyncIo = TRUE; + break; + case 'v': + case 'V': + G_fDumpReadData = TRUE; + break; + default: + Usage(); + } + } + } +} + +BOOL +Compare_Buffs( + _In_reads_bytes_(buff1length) char *buff1, + _In_ ULONG buff1length, + _In_reads_bytes_(buff2length) char *buff2, + _In_ ULONG buff2length + ) +/*++ +Routine Description: + + Called to verify read and write buffers match for loopback test + +Arguments: + + buffers to compare and length + +Return Value: + + TRUE if buffers match, else FALSE + +--*/ +{ + int ok = 1; + + if (buff1length != buff2length || memcmp(buff1, buff2, buff1length )) { + // Edi, and Esi point to the mismatching char and ecx indicates the + // remaining length. + ok = 0; + } + + return ok; +} + +#define NPERLN 8 + +VOID +Dump( + UCHAR *b, + int len +) + +/*++ +Routine Description: + + Called to do formatted ascii dump to console of the io buffer + +Arguments: + + buffer and length + +Return Value: + + none + +--*/ + +{ + ULONG i; + ULONG longLen = (ULONG)len / sizeof( ULONG ); + PULONG pBuf = (PULONG) b; + + // dump an ordinal ULONG for each sizeof(ULONG)'th byte + printf("\n****** BEGIN DUMP LEN decimal %d, 0x%x\n", len,len); + for (i=0; i<longLen; i++) { + printf("%04X ", *pBuf++); + if (i % NPERLN == (NPERLN - 1)) { + printf("\n"); + } + } + if (i % NPERLN != 0) { + printf("\n"); + } + printf("\n****** END DUMP LEN decimal %d, 0x%x\n", len,len); +} + + +BOOL +PlayWithDevice() +{ + HANDLE deviceHandle; + DWORD code; + ULONG index; + INPUT_FUNCTION function; + BAR_GRAPH_STATE barGraphState; + ULONG bar; + SWITCH_STATE switchState; + UCHAR sevenSegment = 0; + UCHAR i; + BOOL result = FALSE; + + deviceHandle = OpenDevice(FALSE); + + if (deviceHandle == INVALID_HANDLE_VALUE) { + + printf("Unable to find any OSR FX2 devices!\n"); + + return FALSE; + + } + + // + // Infinitely print out the list of choices, ask for input, process + // the request + // + WHILE(TRUE) { + + printf ("\nUSBFX TEST -- Functions:\n\n"); + printf ("\t1. Light Bar\n"); + printf ("\t2. Clear Bar\n"); + printf ("\t3. Light entire Bar graph\n"); + printf ("\t4. Clear entire Bar graph\n"); + printf ("\t5. Get bar graph state\n"); + printf ("\t6. Get Switch state\n"); + printf ("\t7. Get Switch Interrupt Message\n"); + printf ("\t8. Get 7 segment state\n"); + printf ("\t9. Set 7 segment state\n"); + printf ("\t10. Reset the device\n"); + printf ("\t11. Reenumerate the device\n"); + printf ("\n\t0. Exit\n"); + printf ("\n\tSelection: "); + + if (scanf_s ("%d", &function) <= 0) { + + printf("Error reading input!\n"); + goto Error; + + } + + switch(function) { + + case LIGHT_ONE_BAR: + + printf("Which Bar (input number 1 thru 8)?\n"); + if (scanf_s ("%d", &bar) <= 0) { + + printf("Error reading input!\n"); + goto Error; + + } + + if(bar == 0 || bar > 8){ + printf("Invalid bar number!\n"); + goto Error; + } + + bar--; // normalize to 0 to 7 + + barGraphState.BarsAsUChar = 1 << (UCHAR)bar; + + if (!DeviceIoControl(deviceHandle, + IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY, + &barGraphState, // Ptr to InBuffer + sizeof(BAR_GRAPH_STATE), // Length of InBuffer + NULL, // Ptr to OutBuffer + 0, // Length of OutBuffer + &index, // BytesReturned + 0)) { // Ptr to Overlapped structure + + code = GetLastError(); + + printf("DeviceIoControl failed with error 0x%x\n", code); + + goto Error; + } + + break; + + case CLEAR_ONE_BAR: + + + printf("Which Bar (input number 1 thru 8)?\n"); + if (scanf_s ("%d", &bar) <= 0) { + + printf("Error reading input!\n"); + goto Error; + + } + + if(bar == 0 || bar > 8){ + printf("Invalid bar number!\n"); + goto Error; + } + + bar--; + + // + // Read the current state + // + if (!DeviceIoControl(deviceHandle, + IOCTL_OSRUSBFX2_GET_BAR_GRAPH_DISPLAY, + NULL, // Ptr to InBuffer + 0, // Length of InBuffer + &barGraphState, // Ptr to OutBuffer + sizeof(BAR_GRAPH_STATE), // Length of OutBuffer + &index, // BytesReturned + 0)) { // Ptr to Overlapped structure + + code = GetLastError(); + + printf("DeviceIoControl failed with error 0x%x\n", code); + + goto Error; + } + + if (barGraphState.BarsAsUChar & (1 << bar)) { + + printf("Bar is set...Clearing it\n"); + barGraphState.BarsAsUChar &= ~(1 << bar); + + if (!DeviceIoControl(deviceHandle, + IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY, + &barGraphState, // Ptr to InBuffer + sizeof(BAR_GRAPH_STATE), // Length of InBuffer + NULL, // Ptr to OutBuffer + 0, // Length of OutBuffer + &index, // BytesReturned + 0)) { // Ptr to Overlapped structure + + code = GetLastError(); + + printf("DeviceIoControl failed with error 0x%x\n", code); + + goto Error; + + } + + } else { + + printf("Bar not set.\n"); + + } + + break; + + case LIGHT_ALL_BARS: + + barGraphState.BarsAsUChar = 0xFF; + + if (!DeviceIoControl(deviceHandle, + IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY, + &barGraphState, // Ptr to InBuffer + sizeof(BAR_GRAPH_STATE), // Length of InBuffer + NULL, // Ptr to OutBuffer + 0, // Length of OutBuffer + &index, // BytesReturned + 0)) { // Ptr to Overlapped structure + + code = GetLastError(); + + printf("DeviceIoControl failed with error 0x%x\n", code); + + goto Error; + } + + break; + + case CLEAR_ALL_BARS: + + barGraphState.BarsAsUChar = 0; + + if (!DeviceIoControl(deviceHandle, + IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY, + &barGraphState, // Ptr to InBuffer + sizeof(BAR_GRAPH_STATE), // Length of InBuffer + NULL, // Ptr to OutBuffer + 0, // Length of OutBuffer + &index, // BytesReturned + 0)) { // Ptr to Overlapped structure + + code = GetLastError(); + + printf("DeviceIoControl failed with error 0x%x\n", code); + + goto Error; + } + + break; + + + case GET_BAR_GRAPH_LIGHT_STATE: + + barGraphState.BarsAsUChar = 0; + + if (!DeviceIoControl(deviceHandle, + IOCTL_OSRUSBFX2_GET_BAR_GRAPH_DISPLAY, + NULL, // Ptr to InBuffer + 0, // Length of InBuffer + &barGraphState, // Ptr to OutBuffer + sizeof(BAR_GRAPH_STATE), // Length of OutBuffer + &index, // BytesReturned + 0)) { // Ptr to Overlapped structure + + code = GetLastError(); + + printf("DeviceIoControl failed with error 0x%x\n", code); + + goto Error; + } + + printf("Bar Graph: \n"); + printf(" Bar8 is %s\n", barGraphState.Bar8 ? "ON" : "OFF"); + printf(" Bar7 is %s\n", barGraphState.Bar7 ? "ON" : "OFF"); + printf(" Bar6 is %s\n", barGraphState.Bar6 ? "ON" : "OFF"); + printf(" Bar5 is %s\n", barGraphState.Bar5 ? "ON" : "OFF"); + printf(" Bar4 is %s\n", barGraphState.Bar4 ? "ON" : "OFF"); + printf(" Bar3 is %s\n", barGraphState.Bar3 ? "ON" : "OFF"); + printf(" Bar2 is %s\n", barGraphState.Bar2 ? "ON" : "OFF"); + printf(" Bar1 is %s\n", barGraphState.Bar1 ? "ON" : "OFF"); + + break; + + case GET_SWITCH_STATE: + + switchState.SwitchesAsUChar = 0; + + if (!DeviceIoControl(deviceHandle, + IOCTL_OSRUSBFX2_READ_SWITCHES, + NULL, // Ptr to InBuffer + 0, // Length of InBuffer + &switchState, // Ptr to OutBuffer + sizeof(SWITCH_STATE), // Length of OutBuffer + &index, // BytesReturned + 0)) { // Ptr to Overlapped structure + + code = GetLastError(); + + printf("DeviceIoControl failed with error 0x%x\n", code); + + goto Error; + } + + printf("Switches: \n"); + printf(" Switch8 is %s\n", switchState.Switch8 ? "ON" : "OFF"); + printf(" Switch7 is %s\n", switchState.Switch7 ? "ON" : "OFF"); + printf(" Switch6 is %s\n", switchState.Switch6 ? "ON" : "OFF"); + printf(" Switch5 is %s\n", switchState.Switch5 ? "ON" : "OFF"); + printf(" Switch4 is %s\n", switchState.Switch4 ? "ON" : "OFF"); + printf(" Switch3 is %s\n", switchState.Switch3 ? "ON" : "OFF"); + printf(" Switch2 is %s\n", switchState.Switch2 ? "ON" : "OFF"); + printf(" Switch1 is %s\n", switchState.Switch1 ? "ON" : "OFF"); + + break; + + case GET_SWITCH_STATE_AS_INTERRUPT_MESSAGE: + + switchState.SwitchesAsUChar = 0; + + if (!DeviceIoControl(deviceHandle, + IOCTL_OSRUSBFX2_GET_INTERRUPT_MESSAGE, + NULL, // Ptr to InBuffer + 0, // Length of InBuffer + &switchState, // Ptr to OutBuffer + sizeof(switchState), // Length of OutBuffer + &index, // BytesReturned + 0)) { // Ptr to Overlapped structure + + code = GetLastError(); + + printf("DeviceIoControl failed with error 0x%x\n", code); + + goto Error; + } + + printf("Switches: %d\n",index); + printf(" Switch8 is %s\n", switchState.Switch8 ? "ON" : "OFF"); + printf(" Switch7 is %s\n", switchState.Switch7 ? "ON" : "OFF"); + printf(" Switch6 is %s\n", switchState.Switch6 ? "ON" : "OFF"); + printf(" Switch5 is %s\n", switchState.Switch5 ? "ON" : "OFF"); + printf(" Switch4 is %s\n", switchState.Switch4 ? "ON" : "OFF"); + printf(" Switch3 is %s\n", switchState.Switch3 ? "ON" : "OFF"); + printf(" Switch2 is %s\n", switchState.Switch2 ? "ON" : "OFF"); + printf(" Switch1 is %s\n", switchState.Switch1 ? "ON" : "OFF"); + + break; + + case GET_7_SEGEMENT_STATE: + + sevenSegment = 0; + + if (!DeviceIoControl(deviceHandle, + IOCTL_OSRUSBFX2_GET_7_SEGMENT_DISPLAY, + NULL, // Ptr to InBuffer + 0, // Length of InBuffer + &sevenSegment, // Ptr to OutBuffer + sizeof(UCHAR), // Length of OutBuffer + &index, // BytesReturned + 0)) { // Ptr to Overlapped structure + + code = GetLastError(); + + printf("DeviceIoControl failed with error 0x%x\n", code); + + goto Error; + } + + printf("7 Segment mask: 0x%x\n", sevenSegment); + break; + + case SET_7_SEGEMENT_STATE: + + for (i = 0; i < 8; i++) { + + sevenSegment = 1 << i; + + if (!DeviceIoControl(deviceHandle, + IOCTL_OSRUSBFX2_SET_7_SEGMENT_DISPLAY, + &sevenSegment, // Ptr to InBuffer + sizeof(UCHAR), // Length of InBuffer + NULL, // Ptr to OutBuffer + 0, // Length of OutBuffer + &index, // BytesReturned + 0)) { // Ptr to Overlapped structure + + code = GetLastError(); + + printf("DeviceIoControl failed with error 0x%x\n", code); + + goto Error; + } + + printf("This is %d\n", i); + Sleep(500); + + } + + printf("7 Segment mask: 0x%x\n", sevenSegment); + break; + + case RESET_DEVICE: + + printf("Reset the device\n"); + + if (!DeviceIoControl(deviceHandle, + IOCTL_OSRUSBFX2_RESET_DEVICE, + NULL, // Ptr to InBuffer + 0, // Length of InBuffer + NULL, // Ptr to OutBuffer + 0, // Length of OutBuffer + &index, // BytesReturned + NULL)) { // Ptr to Overlapped structure + + code = GetLastError(); + + printf("DeviceIoControl failed with error 0x%x\n", code); + + goto Error; + } + + break; + + case REENUMERATE_DEVICE: + + printf("Re-enumerate the device\n"); + + if (!DeviceIoControl(deviceHandle, + IOCTL_OSRUSBFX2_REENUMERATE_DEVICE, + NULL, // Ptr to InBuffer + 0, // Length of InBuffer + NULL, // Ptr to OutBuffer + 0, // Length of OutBuffer + &index, // BytesReturned + NULL)) { // Ptr to Overlapped structure + + code = GetLastError(); + + printf("DeviceIoControl failed with error 0x%x\n", code); + + goto Error; + } + + // + // Close the handle to the device and exit out so that + // the driver can unload when the device is surprise-removed + // and reenumerated. + // + default: + + result = TRUE; + goto Error; + + } + + } // end of while loop + +Error: + + CloseHandle(deviceHandle); + return result; + +} + + +ULONG +AsyncIo( + PVOID ThreadParameter + ) +{ + HANDLE hDevice = INVALID_HANDLE_VALUE; + HANDLE hCompletionPort = NULL; + OVERLAPPED *pOvList = NULL; + PUCHAR buf = NULL; + ULONG_PTR i; + ULONG ioType = (ULONG)(ULONG_PTR)ThreadParameter; + ULONG error; + + hDevice = OpenDevice(FALSE); + + if (hDevice == INVALID_HANDLE_VALUE) { + printf("Cannot open device %d\n", GetLastError()); + goto Error; + } + + hCompletionPort = CreateIoCompletionPort(hDevice, NULL, 1, 0); + + if (hCompletionPort == NULL) { + printf("Cannot open completion port %d \n",GetLastError()); + goto Error; + } + + pOvList = (OVERLAPPED *)malloc(NUM_ASYNCH_IO * sizeof(OVERLAPPED)); + + if (pOvList == NULL) { + printf("Cannot allocate overlapped array \n"); + goto Error; + } + + buf = (PUCHAR)malloc(NUM_ASYNCH_IO * BUFFER_SIZE); + + if (buf == NULL) { + printf("Cannot allocate buffer \n"); + goto Error; + } + + ZeroMemory(pOvList, NUM_ASYNCH_IO * sizeof(OVERLAPPED)); + ZeroMemory(buf, NUM_ASYNCH_IO * BUFFER_SIZE); + + // + // Issue asynch I/O + // + + for (i = 0; i < NUM_ASYNCH_IO; i++) { + if (ioType == READER_TYPE) { + if ( ReadFile( hDevice, + buf + (i* BUFFER_SIZE), + BUFFER_SIZE, + NULL, + &pOvList[i]) == 0) { + + error = GetLastError(); + if (error != ERROR_IO_PENDING) { + printf(" %Iu th read failed %d \n",i, GetLastError()); + goto Error; + } + } + + } else { + if ( WriteFile( hDevice, + buf + (i* BUFFER_SIZE), + BUFFER_SIZE, + NULL, + &pOvList[i]) == 0) { + error = GetLastError(); + if (error != ERROR_IO_PENDING) { + printf(" %Iu th write failed %d \n",i, GetLastError()); + goto Error; + } + } + } + } + + // + // Wait for the I/Os to complete. If one completes then reissue the I/O + // + + WHILE (1) { + OVERLAPPED *completedOv; + ULONG_PTR key; + ULONG numberOfBytesTransferred; + + if ( GetQueuedCompletionStatus(hCompletionPort, &numberOfBytesTransferred, + &key, &completedOv, INFINITE) == 0) { + printf("GetQueuedCompletionStatus failed %d\n", GetLastError()); + goto Error; + } + + // + // Read successfully completed. Issue another one. + // + + if (ioType == READER_TYPE) { + + i = completedOv - pOvList; + + printf("Number of bytes read by request number %Iu is %d\n", + i, numberOfBytesTransferred); + + if ( ReadFile( hDevice, + buf + (i * BUFFER_SIZE), + BUFFER_SIZE, + NULL, + completedOv) == 0) { + error = GetLastError(); + if (error != ERROR_IO_PENDING) { + printf("%Iu th Read failed %d \n", i, GetLastError()); + goto Error; + } + } + } else { + + i = completedOv - pOvList; + + printf("Number of bytes written by request number %Iu is %d\n", + i, numberOfBytesTransferred); + + if ( WriteFile( hDevice, + buf + (i * BUFFER_SIZE), + BUFFER_SIZE, + NULL, + completedOv) == 0) { + error = GetLastError(); + if (error != ERROR_IO_PENDING) { + printf("%Iu th write failed %d \n", i, GetLastError()); + goto Error; + } + } + } + } + +Error: + if (hDevice != INVALID_HANDLE_VALUE) { + CloseHandle(hDevice); + } + + if (hCompletionPort) { + CloseHandle(hCompletionPort); + } + + if (pOvList) { + free(pOvList); + } + if (buf) { + free(buf); + } + + return 1; + +} + + +int +_cdecl +main( + _In_ int argc, + _In_reads_(argc) LPSTR *argv + ) +/*++ +Routine Description: + + Entry point to rwbulk.exe + Parses cmdline, performs user-requested tests + +Arguments: + + argc, argv standard console 'c' app arguments + +Return Value: + + Zero + +--*/ + +{ + char * pinBuf = NULL; + char * poutBuf = NULL; + ULONG nBytesRead; + ULONG nBytesWrite = 0; + int ok; + int retValue = 0; + UINT success; + HANDLE hRead = INVALID_HANDLE_VALUE; + HANDLE hWrite = INVALID_HANDLE_VALUE; + ULONG fail = 0L; + ULONG i; + + + Parse(argc, argv ); + + // + // dump USB configuation and pipe info + // + if (G_fDumpUsbConfig) { + DumpUsbConfig(); + } + + if (G_fPlayWithDevice) { + PlayWithDevice(); + goto exit; + } + + if (G_fPerformAsyncIo) { + HANDLE th1; + + // + // Create a reader thread + // + th1 = CreateThread( NULL, // Default Security Attrib. + 0, // Initial Stack Size, + AsyncIo, // Thread Func + (LPVOID)READER_TYPE, + 0, // Creation Flags + NULL ); // Don't need the Thread Id. + + if (th1 == NULL) { + printf("Couldn't create reader thread - error %d\n", GetLastError()); + retValue = 1; + goto exit; + } + + // + // Use this thread for peforming write. + // + AsyncIo((PVOID)WRITER_TYPE); + + goto exit; + } + + // + // doing a read, write, or both test + // + if ((G_fRead) || (G_fWrite)) { + + if (G_fRead) { + if ( G_fDumpReadData ) { // round size to sizeof ULONG for readable dumping + while( G_ReadLen % sizeof( ULONG ) ) { + G_ReadLen++; + } + } + + // + // open the output file + // + hRead = OpenDevice(TRUE); + if(hRead == INVALID_HANDLE_VALUE) { + retValue = 1; + goto exit; + } + + pinBuf = malloc(G_ReadLen); + } + + if (G_fWrite) { + if ( G_fDumpReadData ) { // round size to sizeof ULONG for readable dumping + while( G_WriteLen % sizeof( ULONG ) ) { + G_WriteLen++; + } + } + + // + // open the output file + // + hWrite = OpenDevice(TRUE); + if(hWrite == INVALID_HANDLE_VALUE) { + retValue = 1; + goto exit; + } + + poutBuf = malloc(G_WriteLen); + } + + for (i = 0; i < G_IterationCount; i++) { + ULONG j; + + if (G_fWrite && poutBuf && hWrite != INVALID_HANDLE_VALUE) { + + PULONG pOut = (PULONG) poutBuf; + ULONG numLongs = G_WriteLen / sizeof( ULONG ); + + // + // put some data in the output buffer + // + for (j=0; j<numLongs; j++) { + *(pOut+j) = j; + } + + // + // send the write + // + success = WriteFile(hWrite, poutBuf, G_WriteLen, &nBytesWrite, NULL); + if(success == 0) { + printf("WriteFile failed - error %d\n", GetLastError()); + retValue = 1; + goto exit; + } + printf("Write (%04.4u) : request %06.6u bytes -- %06.6u bytes written\n", + i, G_WriteLen, nBytesWrite); + + assert(nBytesWrite == G_WriteLen); + } + + if (G_fRead && pinBuf) { + + success = ReadFile(hRead, pinBuf, G_ReadLen, &nBytesRead, NULL); + if(success == 0) { + printf("ReadFile failed - error %d\n", GetLastError()); + retValue = 1; + goto exit; + } + + printf("Read (%04.4u) : request %06.6u bytes -- %06.6u bytes read\n", + i, G_ReadLen, nBytesRead); + + if (G_fWrite && poutBuf) { + + // + // validate the input buffer against what + // we sent to the 82930 (loopback test) + // + ok = Compare_Buffs(pinBuf, nBytesRead, poutBuf, nBytesWrite); + + if( G_fDumpReadData ) { + printf("Dumping read buffer\n"); + Dump( (PUCHAR) pinBuf, nBytesRead ); + printf("Dumping write buffer\n"); + Dump( (PUCHAR) poutBuf, nBytesRead ); + } + assert(ok); + + if(ok != 1) { + fail++; + } + + assert(G_ReadLen == G_WriteLen); + assert(nBytesRead == G_ReadLen); + } + } + } + + } + +exit: + + if (pinBuf) { + free(pinBuf); + } + + if (poutBuf) { + free(poutBuf); + } + + // close devices if needed + if (hRead != INVALID_HANDLE_VALUE) { + CloseHandle(hRead); + } + + if (hWrite != INVALID_HANDLE_VALUE) { + CloseHandle(hWrite); + } + + return retValue; +} + + diff --git a/usb/wdf_osrfx2_lab/kmdf/exe/testapp.rc b/usb/wdf_osrfx2_lab/kmdf/exe/testapp.rc new file mode 100644 index 00000000..3947204a --- /dev/null +++ b/usb/wdf_osrfx2_lab/kmdf/exe/testapp.rc @@ -0,0 +1,12 @@ +#include <windows.h> + +#include <ntverp.h> + +#define VER_FILETYPE VFT_DLL +#define VER_FILESUBTYPE VFT2_UNKNOWN +#define VER_FILEDESCRIPTION_STR "OSRUSBFX2 Bulk & Isoch Read and Write test App" +#define VER_INTERNALNAME_STR "osrusbfx2.exe" +#define VER_ORIGINALFILENAME_STR "osrusbfx2.exe" + +#include <common.ver> + diff --git a/usb/wdf_osrfx2_lab/kmdf/inc/prototypes.h b/usb/wdf_osrfx2_lab/kmdf/inc/prototypes.h new file mode 100644 index 00000000..cc99cdfe --- /dev/null +++ b/usb/wdf_osrfx2_lab/kmdf/inc/prototypes.h @@ -0,0 +1,14 @@ +DRIVER_INITIALIZE DriverEntry; + +EVT_WDF_DRIVER_DEVICE_ADD EvtDeviceAdd; + +EVT_WDF_DEVICE_CONTEXT_CLEANUP EvtDriverContextCleanup; +EVT_WDF_DEVICE_PREPARE_HARDWARE EvtDevicePrepareHardware; + +EVT_WDF_IO_QUEUE_IO_READ EvtIoRead; +EVT_WDF_IO_QUEUE_IO_WRITE EvtIoWrite; +EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL EvtIoDeviceControl; + +EVT_WDF_REQUEST_COMPLETION_ROUTINE EvtRequestReadCompletionRoutine; +EVT_WDF_REQUEST_COMPLETION_ROUTINE EvtRequestWriteCompletionRoutine; + diff --git a/usb/wdf_osrfx2_lab/kmdf/inc/public.h b/usb/wdf_osrfx2_lab/kmdf/inc/public.h new file mode 100644 index 00000000..f1fc6be3 --- /dev/null +++ b/usb/wdf_osrfx2_lab/kmdf/inc/public.h @@ -0,0 +1,173 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + + THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR + PURPOSE. + +Module Name: + + public.h + +Abstract: + +Environment: + + User & Kernel mode + +--*/ + +#ifndef _PUBLIC_H +#define _PUBLIC_H + +#include <initguid.h> + +// {573E8C73-0CB4-4471-A1BF-FAB26C31D384} +DEFINE_GUID(GUID_DEVINTERFACE_OSRUSBFX2, + 0x573e8c73, 0xcb4, 0x4471, 0xa1, 0xbf, 0xfa, 0xb2, 0x6c, 0x31, 0xd3, 0x84); + +#pragma warning(push) +#pragma warning(disable:4201) // nameless struct/union +#pragma warning(disable:4214) // bit field types other than int + +// +// Define the structures that will be used by the IOCTL +// interface to the driver +// + +// +// BAR_GRAPH_STATE +// +// BAR_GRAPH_STATE is a bit field structure with each +// bit corresponding to one of the bar graph on the +// OSRFX2 Development Board +// +#include <pshpack1.h> +typedef struct _BAR_GRAPH_STATE { + + union { + + struct { + // + // Individual bars starting from the + // top of the stack of bars + // + // NOTE: There are actually 10 bars, + // but the very top two do not light + // and are not counted here + // + UCHAR Bar1 : 1; + UCHAR Bar2 : 1; + UCHAR Bar3 : 1; + UCHAR Bar4 : 1; + UCHAR Bar5 : 1; + UCHAR Bar6 : 1; + UCHAR Bar7 : 1; + UCHAR Bar8 : 1; + }; + + // + // The state of all the bar graph as a single + // UCHAR + // + UCHAR BarsAsUChar; + + }; + +}BAR_GRAPH_STATE, *PBAR_GRAPH_STATE; + +// +// SWITCH_STATE +// +// SWITCH_STATE is a bit field structure with each +// bit corresponding to one of the switches on the +// OSRFX2 Development Board +// +typedef struct _SWITCH_STATE { + + union { + struct { + // + // Individual switches starting from the + // left of the set of switches + // + UCHAR Switch1 : 1; + UCHAR Switch2 : 1; + UCHAR Switch3 : 1; + UCHAR Switch4 : 1; + UCHAR Switch5 : 1; + UCHAR Switch6 : 1; + UCHAR Switch7 : 1; + UCHAR Switch8 : 1; + }; + + // + // The state of all the switches as a single + // UCHAR + // + UCHAR SwitchesAsUChar; + + }; + + +}SWITCH_STATE, *PSWITCH_STATE; + +#include <poppack.h> + +#pragma warning(pop) + +#define IOCTL_INDEX 0x800 +#define FILE_DEVICE_OSRUSBFX2 65500U + +#define IOCTL_OSRUSBFX2_GET_CONFIG_DESCRIPTOR CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ + IOCTL_INDEX, \ + METHOD_BUFFERED, \ + FILE_READ_ACCESS) + +#define IOCTL_OSRUSBFX2_RESET_DEVICE CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ + IOCTL_INDEX + 1, \ + METHOD_BUFFERED, \ + FILE_WRITE_ACCESS) + +#define IOCTL_OSRUSBFX2_REENUMERATE_DEVICE CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ + IOCTL_INDEX + 3, \ + METHOD_BUFFERED, \ + FILE_WRITE_ACCESS) + +#define IOCTL_OSRUSBFX2_GET_BAR_GRAPH_DISPLAY CTL_CODE(FILE_DEVICE_OSRUSBFX2,\ + IOCTL_INDEX + 4, \ + METHOD_BUFFERED, \ + FILE_READ_ACCESS) + + +#define IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY CTL_CODE(FILE_DEVICE_OSRUSBFX2,\ + IOCTL_INDEX + 5, \ + METHOD_BUFFERED, \ + FILE_WRITE_ACCESS) + + +#define IOCTL_OSRUSBFX2_READ_SWITCHES CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ + IOCTL_INDEX + 6, \ + METHOD_BUFFERED, \ + FILE_READ_ACCESS) + + +#define IOCTL_OSRUSBFX2_GET_7_SEGMENT_DISPLAY CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ + IOCTL_INDEX + 7, \ + METHOD_BUFFERED, \ + FILE_READ_ACCESS) + + +#define IOCTL_OSRUSBFX2_SET_7_SEGMENT_DISPLAY CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ + IOCTL_INDEX + 8, \ + METHOD_BUFFERED, \ + FILE_WRITE_ACCESS) + +#define IOCTL_OSRUSBFX2_GET_INTERRUPT_MESSAGE CTL_CODE(FILE_DEVICE_OSRUSBFX2,\ + IOCTL_INDEX + 9, \ + METHOD_OUT_DIRECT, \ + FILE_READ_ACCESS) + +#endif diff --git a/usb/wdf_osrfx2_lab/kmdf/step1/osrusbfx2.inx b/usb/wdf_osrfx2_lab/kmdf/step1/osrusbfx2.inx Binary files differnew file mode 100644 index 00000000..c8678d1e --- /dev/null +++ b/usb/wdf_osrfx2_lab/kmdf/step1/osrusbfx2.inx diff --git a/usb/wdf_osrfx2_lab/kmdf/step1/osrusbfx2.vcxproj b/usb/wdf_osrfx2_lab/kmdf/step1/osrusbfx2.vcxproj new file mode 100644 index 00000000..1ec8c281 --- /dev/null +++ b/usb/wdf_osrfx2_lab/kmdf/step1/osrusbfx2.vcxproj @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{E54BDD18-FDE9-42BF-BC23-343F8764B387}</ProjectGuid> + <RootNamespace>$(MSBuildProjectName)</RootNamespace> + <KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR> + <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration> + <Platform Condition="'$(Platform)' == ''">Win32</Platform> + <SampleGuid>{60C495D1-94AA-4FFD-A487-7DB5E3C8DA67}</SampleGuid> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + <DriverType>KMDF</DriverType> + <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> + <ConfigurationType>Driver</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + <DriverType>KMDF</DriverType> + <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> + <ConfigurationType>Driver</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + <DriverType>KMDF</DriverType> + <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> + <ConfigurationType>Driver</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + <DriverType>KMDF</DriverType> + <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> + <ConfigurationType>Driver</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <OutDir>$(IntDir)</OutDir> + </PropertyGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ItemGroup Label="WrappedTaskItems" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetName>osrusbfx2</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetName>osrusbfx2</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetName>osrusbfx2</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetName>osrusbfx2</TargetName> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + </Midl> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + </Midl> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + </Midl> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + </Midl> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="step1.c" /> + </ItemGroup> + <ItemGroup> + <Inf Exclude="@(Inf)" Include="*.inf" /> + <FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" /> + </ItemGroup> + <ItemGroup> + <None Exclude="@(None)" Include="*.txt;*.htm;*.html" /> + <None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" /> + <None Exclude="@(None)" Include="*.def;*.bat;*.hpj;*.asmx" /> + </ItemGroup> + <ItemGroup> + <ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> +</Project>
\ No newline at end of file diff --git a/usb/wdf_osrfx2_lab/kmdf/step1/osrusbfx2.vcxproj.Filters b/usb/wdf_osrfx2_lab/kmdf/step1/osrusbfx2.vcxproj.Filters new file mode 100644 index 00000000..9b8ef1e8 --- /dev/null +++ b/usb/wdf_osrfx2_lab/kmdf/step1/osrusbfx2.vcxproj.Filters @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions> + <UniqueIdentifier>{BED1DDD4-3545-4D39-9B61-3B5A2AC49363}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files"> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + <UniqueIdentifier>{30F67E72-22AB-4E8A-A7AB-958D2BE78832}</UniqueIdentifier> + </Filter> + <Filter Include="Resource Files"> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions> + <UniqueIdentifier>{E4F82714-096C-4872-9B1A-8927A9E53160}</UniqueIdentifier> + </Filter> + <Filter Include="Driver Files"> + <Extensions>inf;inv;inx;mof;mc;</Extensions> + <UniqueIdentifier>{F0878992-99C3-4BA1-8031-6537BC959387}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="step1.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/usb/wdf_osrfx2_lab/kmdf/step1/step1.c b/usb/wdf_osrfx2_lab/kmdf/step1/step1.c new file mode 100644 index 00000000..c37ade2c --- /dev/null +++ b/usb/wdf_osrfx2_lab/kmdf/step1/step1.c @@ -0,0 +1,58 @@ +/*++ + +Step1: This step shows how to create a simplest functional driver. + It only registers DriverEntry and EvtDeviceAdd callback. + Framework provides default behaviour for everything else. + This allows you to install and uninstall this driver. +--*/ + +#include "ntddk.h" +#include "wdf.h" +#include "prototypes.h" + +NTSTATUS +DriverEntry( + IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegistryPath + ) +{ + WDF_DRIVER_CONFIG config; + NTSTATUS status; + + KdPrint(("DriverEntry of Step1\n")); + + WDF_DRIVER_CONFIG_INIT(&config, EvtDeviceAdd); + + status = WdfDriverCreate(DriverObject, + RegistryPath, + WDF_NO_OBJECT_ATTRIBUTES, + &config, + WDF_NO_HANDLE + ); + + if (!NT_SUCCESS(status)) { + KdPrint(("WdfDriverCreate failed 0x%x\n", status)); + } + + return status; +} + +NTSTATUS +EvtDeviceAdd( + IN WDFDRIVER Driver, + IN PWDFDEVICE_INIT DeviceInit + ) +{ + NTSTATUS status; + WDFDEVICE device; + + UNREFERENCED_PARAMETER(Driver); + + status = WdfDeviceCreate(&DeviceInit, WDF_NO_OBJECT_ATTRIBUTES, &device); + if (!NT_SUCCESS(status)) { + KdPrint(("WdfDeviceCreate failed 0x%x\n", status)); + return status; + } + + return status; +} diff --git a/usb/wdf_osrfx2_lab/kmdf/step2/osrusbfx2.inx b/usb/wdf_osrfx2_lab/kmdf/step2/osrusbfx2.inx Binary files differnew file mode 100644 index 00000000..c8678d1e --- /dev/null +++ b/usb/wdf_osrfx2_lab/kmdf/step2/osrusbfx2.inx diff --git a/usb/wdf_osrfx2_lab/kmdf/step2/osrusbfx2.vcxproj b/usb/wdf_osrfx2_lab/kmdf/step2/osrusbfx2.vcxproj new file mode 100644 index 00000000..5a1b9666 --- /dev/null +++ b/usb/wdf_osrfx2_lab/kmdf/step2/osrusbfx2.vcxproj @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{CE2CAF81-E96B-4C32-9BE9-58238742D295}</ProjectGuid> + <RootNamespace>$(MSBuildProjectName)</RootNamespace> + <KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR> + <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration> + <Platform Condition="'$(Platform)' == ''">Win32</Platform> + <SampleGuid>{47AD8CFF-8591-4F5C-950D-A2708702F151}</SampleGuid> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + <DriverType>KMDF</DriverType> + <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> + <ConfigurationType>Driver</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + <DriverType>KMDF</DriverType> + <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> + <ConfigurationType>Driver</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + <DriverType>KMDF</DriverType> + <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> + <ConfigurationType>Driver</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + <DriverType>KMDF</DriverType> + <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> + <ConfigurationType>Driver</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <OutDir>$(IntDir)</OutDir> + </PropertyGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ItemGroup Label="WrappedTaskItems" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetName>osrusbfx2</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetName>osrusbfx2</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetName>osrusbfx2</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetName>osrusbfx2</TargetName> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + </Midl> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + </Midl> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + </Midl> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + </Midl> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="step2.c" /> + </ItemGroup> + <ItemGroup> + <Inf Exclude="@(Inf)" Include="*.inf" /> + <FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" /> + </ItemGroup> + <ItemGroup> + <None Exclude="@(None)" Include="*.txt;*.htm;*.html" /> + <None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" /> + <None Exclude="@(None)" Include="*.def;*.bat;*.hpj;*.asmx" /> + </ItemGroup> + <ItemGroup> + <ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> +</Project>
\ No newline at end of file diff --git a/usb/wdf_osrfx2_lab/kmdf/step2/osrusbfx2.vcxproj.Filters b/usb/wdf_osrfx2_lab/kmdf/step2/osrusbfx2.vcxproj.Filters new file mode 100644 index 00000000..3cc55084 --- /dev/null +++ b/usb/wdf_osrfx2_lab/kmdf/step2/osrusbfx2.vcxproj.Filters @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions> + <UniqueIdentifier>{D36AF80E-1855-441C-BE2F-564D415C1B62}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files"> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + <UniqueIdentifier>{75E022B4-EDE7-4377-A4F3-1B07F77957F4}</UniqueIdentifier> + </Filter> + <Filter Include="Resource Files"> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions> + <UniqueIdentifier>{F6D64C52-0E89-4F9D-BBFC-6653A1D5363C}</UniqueIdentifier> + </Filter> + <Filter Include="Driver Files"> + <Extensions>inf;inv;inx;mof;mc;</Extensions> + <UniqueIdentifier>{F80B0B44-D7FF-4B47-8DB6-2794F659E51E}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="step2.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/usb/wdf_osrfx2_lab/kmdf/step2/step2.c b/usb/wdf_osrfx2_lab/kmdf/step2/step2.c new file mode 100644 index 00000000..390f76ee --- /dev/null +++ b/usb/wdf_osrfx2_lab/kmdf/step2/step2.c @@ -0,0 +1,144 @@ +/*++ + +Step2: This steps shows: + 1) How to create a context with the WDFDEVICE object + 2) How to initialize the USB device. + 3) How to register an interface so that app can open + an handle to the device. +--*/ + +#include "ntddk.h" +#include "wdf.h" +#include "prototypes.h" +#include "usbdi.h" +#include "usbdlib.h" +#include "wdfusb.h" +#include "initguid.h" + +DEFINE_GUID(GUID_DEVINTERFACE_OSRUSBFX2, // Generated using guidgen.exe + 0x573e8c73, 0xcb4, 0x4471, 0xa1, 0xbf, 0xfa, 0xb2, 0x6c, 0x31, 0xd3, 0x84); +// {573E8C73-0CB4-4471-A1BF-FAB26C31D384} + +typedef struct _DEVICE_CONTEXT { + WDFUSBDEVICE UsbDevice; + WDFUSBINTERFACE UsbInterface; +} DEVICE_CONTEXT, *PDEVICE_CONTEXT; + +WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DEVICE_CONTEXT, GetDeviceContext) + + +NTSTATUS +DriverEntry( + IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegistryPath + ) +{ + WDF_DRIVER_CONFIG config; + NTSTATUS status; + + KdPrint(("DriverEntry of Step2\n")); + + WDF_DRIVER_CONFIG_INIT(&config, EvtDeviceAdd); + + status = WdfDriverCreate(DriverObject, + RegistryPath, + WDF_NO_OBJECT_ATTRIBUTES, + &config, + WDF_NO_HANDLE + ); + + if (!NT_SUCCESS(status)) { + KdPrint(("WdfDriverCreate failed 0x%x\n", status)); + } + + return status; +} + +NTSTATUS +EvtDeviceAdd( + IN WDFDRIVER Driver, + IN PWDFDEVICE_INIT DeviceInit + ) +{ + WDF_OBJECT_ATTRIBUTES attributes; + NTSTATUS status; + WDFDEVICE device; + WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks; + + UNREFERENCED_PARAMETER(Driver); + + WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks); + pnpPowerCallbacks.EvtDevicePrepareHardware = EvtDevicePrepareHardware; + WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks); + + WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, DEVICE_CONTEXT); + + status = WdfDeviceCreate(&DeviceInit, &attributes, &device); + if (!NT_SUCCESS(status)) { + KdPrint(("WdfDeviceCreate failed 0x%x\n", status)); + return status; + } + + status = WdfDeviceCreateDeviceInterface(device, + (LPGUID) &GUID_DEVINTERFACE_OSRUSBFX2, + NULL);// Reference String + if (!NT_SUCCESS(status)) { + KdPrint(("WdfDeviceCreateDeviceInterface failed 0x%x\n", status)); + return status; + } + + return status; +} + + +NTSTATUS +EvtDevicePrepareHardware( + IN WDFDEVICE Device, + IN WDFCMRESLIST ResourceList, + IN WDFCMRESLIST ResourceListTranslated + ) +{ + NTSTATUS status; + PDEVICE_CONTEXT pDeviceContext; + WDF_USB_DEVICE_SELECT_CONFIG_PARAMS configParams; + + UNREFERENCED_PARAMETER(ResourceList); + UNREFERENCED_PARAMETER(ResourceListTranslated); + + pDeviceContext = GetDeviceContext(Device); + + // + // Create the USB device if it is not already created. + // + if (pDeviceContext->UsbDevice == NULL) { + WDF_USB_DEVICE_CREATE_CONFIG config; + + WDF_USB_DEVICE_CREATE_CONFIG_INIT(&config, + USBD_CLIENT_CONTRACT_VERSION_602); + + status = WdfUsbTargetDeviceCreateWithParameters(Device, + &config, + WDF_NO_OBJECT_ATTRIBUTES, + &pDeviceContext->UsbDevice); + + if (!NT_SUCCESS(status)) { + KdPrint(("WdfUsbTargetDeviceCreateWithParameters failed 0x%x\n", status)); + return status; + } + } + + WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_SINGLE_INTERFACE(&configParams); + + status = WdfUsbTargetDeviceSelectConfig(pDeviceContext->UsbDevice, + WDF_NO_OBJECT_ATTRIBUTES, + &configParams); + if(!NT_SUCCESS(status)) { + KdPrint(("WdfUsbTargetDeviceSelectConfig failed 0x%x\n", status)); + return status; + } + + pDeviceContext->UsbInterface = + configParams.Types.SingleInterface.ConfiguredUsbInterface; + + return status; +} diff --git a/usb/wdf_osrfx2_lab/kmdf/step3/osrusbfx2.inx b/usb/wdf_osrfx2_lab/kmdf/step3/osrusbfx2.inx Binary files differnew file mode 100644 index 00000000..c8678d1e --- /dev/null +++ b/usb/wdf_osrfx2_lab/kmdf/step3/osrusbfx2.inx diff --git a/usb/wdf_osrfx2_lab/kmdf/step3/osrusbfx2.vcxproj b/usb/wdf_osrfx2_lab/kmdf/step3/osrusbfx2.vcxproj new file mode 100644 index 00000000..569cda97 --- /dev/null +++ b/usb/wdf_osrfx2_lab/kmdf/step3/osrusbfx2.vcxproj @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{70D6E15B-26A9-444C-B4DE-93504AD529E1}</ProjectGuid> + <RootNamespace>$(MSBuildProjectName)</RootNamespace> + <KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR> + <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration> + <Platform Condition="'$(Platform)' == ''">Win32</Platform> + <SampleGuid>{A1115183-27F7-454E-A88D-27C7EBA807CC}</SampleGuid> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + <DriverType>KMDF</DriverType> + <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> + <ConfigurationType>Driver</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + <DriverType>KMDF</DriverType> + <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> + <ConfigurationType>Driver</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + <DriverType>KMDF</DriverType> + <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> + <ConfigurationType>Driver</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + <DriverType>KMDF</DriverType> + <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> + <ConfigurationType>Driver</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <OutDir>$(IntDir)</OutDir> + </PropertyGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ItemGroup Label="WrappedTaskItems" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetName>osrusbfx2</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetName>osrusbfx2</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetName>osrusbfx2</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetName>osrusbfx2</TargetName> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + </Midl> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + </Midl> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + </Midl> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + </Midl> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="step3.c" /> + </ItemGroup> + <ItemGroup> + <Inf Exclude="@(Inf)" Include="*.inf" /> + <FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" /> + </ItemGroup> + <ItemGroup> + <None Exclude="@(None)" Include="*.txt;*.htm;*.html" /> + <None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" /> + <None Exclude="@(None)" Include="*.def;*.bat;*.hpj;*.asmx" /> + </ItemGroup> + <ItemGroup> + <ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> +</Project>
\ No newline at end of file diff --git a/usb/wdf_osrfx2_lab/kmdf/step3/osrusbfx2.vcxproj.Filters b/usb/wdf_osrfx2_lab/kmdf/step3/osrusbfx2.vcxproj.Filters new file mode 100644 index 00000000..0d14586f --- /dev/null +++ b/usb/wdf_osrfx2_lab/kmdf/step3/osrusbfx2.vcxproj.Filters @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions> + <UniqueIdentifier>{5BF7E536-8A26-4E35-8B5D-EE0082DCD5D2}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files"> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + <UniqueIdentifier>{66E05EC9-8971-4AF6-B10B-4D6C0AE3164E}</UniqueIdentifier> + </Filter> + <Filter Include="Resource Files"> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions> + <UniqueIdentifier>{CD3C54A3-295B-49F4-87D8-7F0497433AB2}</UniqueIdentifier> + </Filter> + <Filter Include="Driver Files"> + <Extensions>inf;inv;inx;mof;mc;</Extensions> + <UniqueIdentifier>{3320168B-C354-4EB4-8399-5967E25E2B70}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="step3.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/usb/wdf_osrfx2_lab/kmdf/step3/step3.c b/usb/wdf_osrfx2_lab/kmdf/step3/step3.c new file mode 100644 index 00000000..678ca371 --- /dev/null +++ b/usb/wdf_osrfx2_lab/kmdf/step3/step3.c @@ -0,0 +1,266 @@ +/*++ + +Step3: This steps shows: + 1) How to create a default parallel queue to receive a IOCTL requests to + set bar graph display. + 2) How to retreive memory handle from the requests and use that to send + a vendor command to the USB device. +--*/ + +#include "ntddk.h" +#include "wdf.h" +#include "prototypes.h" +#include "usbdi.h" +#include "usbdlib.h" +#include "wdfusb.h" +#include "initguid.h" + +DEFINE_GUID(GUID_DEVINTERFACE_OSRUSBFX2, // Generated using guidgen.exe + 0x573e8c73, 0xcb4, 0x4471, 0xa1, 0xbf, 0xfa, 0xb2, 0x6c, 0x31, 0xd3, 0x84); +// {573E8C73-0CB4-4471-A1BF-FAB26C31D384} + +#define IOCTL_INDEX 0x800 +#define FILE_DEVICE_OSRUSBFX2 65500U +#define USBFX2LK_SET_BARGRAPH_DISPLAY 0xD8 +#define IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY CTL_CODE(FILE_DEVICE_OSRUSBFX2,\ + IOCTL_INDEX + 5, \ + METHOD_BUFFERED, \ + FILE_WRITE_ACCESS) +typedef struct _DEVICE_CONTEXT { + WDFUSBDEVICE UsbDevice; + WDFUSBINTERFACE UsbInterface; +} DEVICE_CONTEXT, *PDEVICE_CONTEXT; + +WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DEVICE_CONTEXT, GetDeviceContext) + + +NTSTATUS +DriverEntry( + IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegistryPath + ) +{ + WDF_DRIVER_CONFIG config; + NTSTATUS status; + + KdPrint(("DriverEntry of Step3\n")); + + WDF_DRIVER_CONFIG_INIT(&config, EvtDeviceAdd); + + status = WdfDriverCreate(DriverObject, + RegistryPath, + WDF_NO_OBJECT_ATTRIBUTES, + &config, + WDF_NO_HANDLE + ); + + if (!NT_SUCCESS(status)) { + KdPrint(("WdfDriverCreate failed 0x%x\n", status)); + } + + return status; +} + +NTSTATUS +EvtDeviceAdd( + IN WDFDRIVER Driver, + IN PWDFDEVICE_INIT DeviceInit + ) +{ + WDF_OBJECT_ATTRIBUTES attributes; + NTSTATUS status; + WDFDEVICE device; + WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks; + WDF_IO_QUEUE_CONFIG ioQueueConfig; + + UNREFERENCED_PARAMETER(Driver); + + WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks); + pnpPowerCallbacks.EvtDevicePrepareHardware = EvtDevicePrepareHardware; + WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks); + + WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, DEVICE_CONTEXT); + + status = WdfDeviceCreate(&DeviceInit, &attributes, &device); + if (!NT_SUCCESS(status)) { + KdPrint(("WdfDeviceCreate failed 0x%x\n", status)); + return status; + } + + status = WdfDeviceCreateDeviceInterface(device, + (LPGUID) &GUID_DEVINTERFACE_OSRUSBFX2, + NULL);// Reference String + if (!NT_SUCCESS(status)) { + KdPrint(("WdfDeviceCreateDeviceInterface failed 0x%x\n", status)); + return status; + } + + WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&ioQueueConfig, + WdfIoQueueDispatchParallel); + + ioQueueConfig.EvtIoDeviceControl = EvtIoDeviceControl; + + // + // By default, Static Driver Verifier (SDV) displays a warning if it + // doesn't find the EvtIoStop callback on a power-managed queue. + // The 'assume' below causes SDV to suppress this warning. If the driver + // has not explicitly set PowerManaged to WdfFalse, the framework creates + // power-managed queues when the device is not a filter driver. Normally + // the EvtIoStop is required for power-managed queues, but for this driver + // it is not needed b/c the driver doesn't hold on to the requests for + // long time or forward them to other drivers. + // If the EvtIoStop callback is not implemented, the framework waits for + // all driver-owned requests to be done before moving in the Dx/sleep + // states or before removing the device, which is the correct behavior + // for this type of driver. If the requests were taking an indeterminate + // amount of time to complete, or if the driver forwarded the requests + // to a lower driver/another stack, the queue should have an + // EvtIoStop/EvtIoResume. + // + __analysis_assume(ioQueueConfig.EvtIoStop != 0); + status = WdfIoQueueCreate(device, + &ioQueueConfig, + WDF_NO_OBJECT_ATTRIBUTES, + WDF_NO_HANDLE); + __analysis_assume(ioQueueConfig.EvtIoStop == 0); + + if (!NT_SUCCESS(status)) { + KdPrint(("WdfIoQueueCreate failed 0x%x\n", status)); + return status; + } + + return status; +} + + +NTSTATUS +EvtDevicePrepareHardware( + IN WDFDEVICE Device, + IN WDFCMRESLIST ResourceList, + IN WDFCMRESLIST ResourceListTranslated + ) +{ + NTSTATUS status; + PDEVICE_CONTEXT pDeviceContext; + WDF_USB_DEVICE_SELECT_CONFIG_PARAMS configParams; + + UNREFERENCED_PARAMETER(ResourceList); + UNREFERENCED_PARAMETER(ResourceListTranslated); + + pDeviceContext = GetDeviceContext(Device); + + // + // Create the USB device if it is not already created. + // + if (pDeviceContext->UsbDevice == NULL) { + WDF_USB_DEVICE_CREATE_CONFIG config; + + WDF_USB_DEVICE_CREATE_CONFIG_INIT(&config, + USBD_CLIENT_CONTRACT_VERSION_602); + + status = WdfUsbTargetDeviceCreateWithParameters(Device, + &config, + WDF_NO_OBJECT_ATTRIBUTES, + &pDeviceContext->UsbDevice); + + if (!NT_SUCCESS(status)) { + KdPrint(("WdfUsbTargetDeviceCreateWithParameters failed 0x%x\n", status)); + return status; + } + } + + WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_SINGLE_INTERFACE(&configParams); + + status = WdfUsbTargetDeviceSelectConfig(pDeviceContext->UsbDevice, + WDF_NO_OBJECT_ATTRIBUTES, + &configParams); + if(!NT_SUCCESS(status)) { + KdPrint(("WdfUsbTargetDeviceSelectConfig failed 0x%x\n", status)); + return status; + } + + pDeviceContext->UsbInterface = + configParams.Types.SingleInterface.ConfiguredUsbInterface; + return status; +} + +VOID +EvtIoDeviceControl( + IN WDFQUEUE Queue, + IN WDFREQUEST Request, + IN size_t OutputBufferLength, + IN size_t InputBufferLength, + IN ULONG IoControlCode + ) +{ + WDFDEVICE device; + PDEVICE_CONTEXT pDevContext; + size_t bytesTransferred = 0; + NTSTATUS status; + WDF_USB_CONTROL_SETUP_PACKET controlSetupPacket; + WDF_MEMORY_DESCRIPTOR memDesc; + WDFMEMORY memory; + WDF_REQUEST_SEND_OPTIONS sendOptions; + + UNREFERENCED_PARAMETER(InputBufferLength); + UNREFERENCED_PARAMETER(OutputBufferLength); + + device = WdfIoQueueGetDevice(Queue); + pDevContext = GetDeviceContext(device); + + switch(IoControlCode) { + + case IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY: + + if(InputBufferLength < sizeof(UCHAR)) { + status = STATUS_BUFFER_OVERFLOW; + bytesTransferred = sizeof(UCHAR); + break; + } + + status = WdfRequestRetrieveInputMemory(Request, &memory); + if (!NT_SUCCESS(status)) { + KdPrint(("WdfRequestRetrieveMemory failed 0x%x", status)); + break; + } + + WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(&controlSetupPacket, + BmRequestHostToDevice, + BmRequestToDevice, + USBFX2LK_SET_BARGRAPH_DISPLAY, // Request + 0, // Value + 0); // Index + + WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(&memDesc, memory, NULL); + + // + // Send the I/O with a timeout to avoid hanging the calling + // thread indefinitely. + // + WDF_REQUEST_SEND_OPTIONS_INIT(&sendOptions, + WDF_REQUEST_SEND_OPTION_TIMEOUT); + + WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&sendOptions, + WDF_REL_TIMEOUT_IN_MS(100)); + status = WdfUsbTargetDeviceSendControlTransferSynchronously( + pDevContext->UsbDevice, + NULL, // Optional WDFREQUEST + &sendOptions, // PWDF_REQUEST_SEND_OPTIONS + &controlSetupPacket, + &memDesc, + (PULONG)&bytesTransferred); + if (!NT_SUCCESS(status)) { + KdPrint(("SendControlTransfer failed 0x%x", status)); + break; + } + break; + + default: + status = STATUS_INVALID_DEVICE_REQUEST; + break; + } + + WdfRequestCompleteWithInformation(Request, status, bytesTransferred); + + return; +} diff --git a/usb/wdf_osrfx2_lab/kmdf/step4/osrusbfx2.inx b/usb/wdf_osrfx2_lab/kmdf/step4/osrusbfx2.inx Binary files differnew file mode 100644 index 00000000..c8678d1e --- /dev/null +++ b/usb/wdf_osrfx2_lab/kmdf/step4/osrusbfx2.inx diff --git a/usb/wdf_osrfx2_lab/kmdf/step4/osrusbfx2.vcxproj b/usb/wdf_osrfx2_lab/kmdf/step4/osrusbfx2.vcxproj new file mode 100644 index 00000000..13904fea --- /dev/null +++ b/usb/wdf_osrfx2_lab/kmdf/step4/osrusbfx2.vcxproj @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{AE6270A1-FAC6-45B2-A641-9BFAF534DD01}</ProjectGuid> + <RootNamespace>$(MSBuildProjectName)</RootNamespace> + <KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR> + <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration> + <Platform Condition="'$(Platform)' == ''">Win32</Platform> + <SampleGuid>{49753364-1AEB-4246-8F48-049FA30602EC}</SampleGuid> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + <DriverType>KMDF</DriverType> + <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> + <ConfigurationType>Driver</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + <DriverType>KMDF</DriverType> + <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> + <ConfigurationType>Driver</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + <DriverType>KMDF</DriverType> + <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> + <ConfigurationType>Driver</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + <DriverType>KMDF</DriverType> + <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> + <ConfigurationType>Driver</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <OutDir>$(IntDir)</OutDir> + </PropertyGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ItemGroup Label="WrappedTaskItems" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetName>osrusbfx2</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetName>osrusbfx2</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetName>osrusbfx2</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetName>osrusbfx2</TargetName> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + </Midl> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + </Midl> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + </Midl> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + </Midl> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="step4.c" /> + </ItemGroup> + <ItemGroup> + <Inf Exclude="@(Inf)" Include="*.inf" /> + <FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" /> + </ItemGroup> + <ItemGroup> + <None Exclude="@(None)" Include="*.txt;*.htm;*.html" /> + <None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" /> + <None Exclude="@(None)" Include="*.def;*.bat;*.hpj;*.asmx" /> + </ItemGroup> + <ItemGroup> + <ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> +</Project>
\ No newline at end of file diff --git a/usb/wdf_osrfx2_lab/kmdf/step4/osrusbfx2.vcxproj.Filters b/usb/wdf_osrfx2_lab/kmdf/step4/osrusbfx2.vcxproj.Filters new file mode 100644 index 00000000..82768de6 --- /dev/null +++ b/usb/wdf_osrfx2_lab/kmdf/step4/osrusbfx2.vcxproj.Filters @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions> + <UniqueIdentifier>{B8F267D1-1E1A-4715-899B-E0F7EBAD509B}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files"> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + <UniqueIdentifier>{787F7F45-CEE6-493E-A8C0-3F0E05208702}</UniqueIdentifier> + </Filter> + <Filter Include="Resource Files"> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions> + <UniqueIdentifier>{670B478D-254C-4710-B55F-7F6A0AD76611}</UniqueIdentifier> + </Filter> + <Filter Include="Driver Files"> + <Extensions>inf;inv;inx;mof;mc;</Extensions> + <UniqueIdentifier>{DC0E7ADD-EBB5-42B3-9937-9853FB7ED512}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="step4.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/usb/wdf_osrfx2_lab/kmdf/step4/step4.c b/usb/wdf_osrfx2_lab/kmdf/step4/step4.c new file mode 100644 index 00000000..9b156166 --- /dev/null +++ b/usb/wdf_osrfx2_lab/kmdf/step4/step4.c @@ -0,0 +1,448 @@ +/*++ + +Step4: This steps shows: + 1) How to register Read and Write events on the default queue. + 2) Retrieve memory from read and write request, format the + requests and send it to USB target. +--*/ + +#include "ntddk.h" +#include "wdf.h" +#include "prototypes.h" +#include "usbdi.h" +#include "usbdlib.h" +#include "wdfusb.h" +#include "initguid.h" + +DEFINE_GUID(GUID_DEVINTERFACE_OSRUSBFX2, // Generated using guidgen.exe + 0x573e8c73, 0xcb4, 0x4471, 0xa1, 0xbf, 0xfa, 0xb2, 0x6c, 0x31, 0xd3, 0x84); +// {573E8C73-0CB4-4471-A1BF-FAB26C31D384} + +#define IOCTL_INDEX 0x800 +#define FILE_DEVICE_OSRUSBFX2 65500U +#define USBFX2LK_SET_BARGRAPH_DISPLAY 0xD8 +#define BULK_OUT_ENDPOINT_INDEX 1 +#define BULK_IN_ENDPOINT_INDEX 2 +#define IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY CTL_CODE(FILE_DEVICE_OSRUSBFX2,\ + IOCTL_INDEX + 5, \ + METHOD_BUFFERED, \ + FILE_WRITE_ACCESS) +typedef struct _DEVICE_CONTEXT { + WDFUSBDEVICE UsbDevice; + WDFUSBINTERFACE UsbInterface; + WDFUSBPIPE BulkReadPipe; + WDFUSBPIPE BulkWritePipe; +} DEVICE_CONTEXT, *PDEVICE_CONTEXT; + +WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DEVICE_CONTEXT, GetDeviceContext) + + +NTSTATUS +DriverEntry( + IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegistryPath + ) +{ + WDF_DRIVER_CONFIG config; + NTSTATUS status; + + KdPrint(("DriverEntry of Step4\n")); + + WDF_DRIVER_CONFIG_INIT(&config, EvtDeviceAdd); + + status = WdfDriverCreate(DriverObject, + RegistryPath, + WDF_NO_OBJECT_ATTRIBUTES, + &config, + WDF_NO_HANDLE + ); + + if (!NT_SUCCESS(status)) { + KdPrint(("WdfDriverCreate failed 0x%x\n", status)); + } + + return status; +} + +NTSTATUS +EvtDeviceAdd( + IN WDFDRIVER Driver, + IN PWDFDEVICE_INIT DeviceInit + ) +{ + WDF_OBJECT_ATTRIBUTES attributes; + NTSTATUS status; + WDFDEVICE device; + WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks; + WDF_IO_QUEUE_CONFIG ioQueueConfig; + + UNREFERENCED_PARAMETER(Driver); + + WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks); + pnpPowerCallbacks.EvtDevicePrepareHardware = EvtDevicePrepareHardware; + WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks); + + WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, DEVICE_CONTEXT); + + status = WdfDeviceCreate(&DeviceInit, &attributes, &device); + if (!NT_SUCCESS(status)) { + KdPrint(("WdfDeviceCreate failed 0x%x\n", status)); + return status; + } + + status = WdfDeviceCreateDeviceInterface(device, + (LPGUID) &GUID_DEVINTERFACE_OSRUSBFX2, + NULL);// Reference String + if (!NT_SUCCESS(status)) { + KdPrint(("WdfDeviceCreateDeviceInterface failed 0x%x\n", status)); + return status; + } + + WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&ioQueueConfig, + WdfIoQueueDispatchParallel); + + ioQueueConfig.EvtIoDeviceControl = EvtIoDeviceControl; + ioQueueConfig.EvtIoRead = EvtIoRead; + ioQueueConfig.EvtIoWrite = EvtIoWrite; + + // + // By default, Static Driver Verifier (SDV) displays a warning if it + // doesn't find the EvtIoStop callback on a power-managed queue. + // The 'assume' below causes SDV to suppress this warning. + // Please see 'final' step for implementation of EvtIoStop. + // + __analysis_assume(ioQueueConfig.EvtIoStop != 0); + status = WdfIoQueueCreate(device, + &ioQueueConfig, + WDF_NO_OBJECT_ATTRIBUTES, + WDF_NO_HANDLE); + __analysis_assume(ioQueueConfig.EvtIoStop == 0); + + if (!NT_SUCCESS(status)) { + KdPrint(("WdfIoQueueCreate failed 0x%x\n", status)); + return status; + } + + return status; +} + + +NTSTATUS +EvtDevicePrepareHardware( + IN WDFDEVICE Device, + IN WDFCMRESLIST ResourceList, + IN WDFCMRESLIST ResourceListTranslated + ) +{ + NTSTATUS status; + PDEVICE_CONTEXT pDeviceContext; + WDF_USB_DEVICE_SELECT_CONFIG_PARAMS configParams; + + UNREFERENCED_PARAMETER(ResourceList); + UNREFERENCED_PARAMETER(ResourceListTranslated); + + pDeviceContext = GetDeviceContext(Device); + + // + // Create the USB device if it is not already created. + // + if (pDeviceContext->UsbDevice == NULL) { + WDF_USB_DEVICE_CREATE_CONFIG config; + + WDF_USB_DEVICE_CREATE_CONFIG_INIT(&config, + USBD_CLIENT_CONTRACT_VERSION_602); + + status = WdfUsbTargetDeviceCreateWithParameters(Device, + &config, + WDF_NO_OBJECT_ATTRIBUTES, + &pDeviceContext->UsbDevice); + + if (!NT_SUCCESS(status)) { + KdPrint(("WdfUsbTargetDeviceCreateWithParameters failed 0x%x\n", status)); + return status; + } + } + + WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_SINGLE_INTERFACE(&configParams); + + status = WdfUsbTargetDeviceSelectConfig(pDeviceContext->UsbDevice, + WDF_NO_OBJECT_ATTRIBUTES, + &configParams); + if(!NT_SUCCESS(status)) { + KdPrint(("WdfUsbTargetDeviceSelectConfig failed 0x%x\n", status)); + return status; + } + + pDeviceContext->UsbInterface = + configParams.Types.SingleInterface.ConfiguredUsbInterface; + + pDeviceContext->BulkReadPipe = WdfUsbInterfaceGetConfiguredPipe( + pDeviceContext->UsbInterface, + BULK_IN_ENDPOINT_INDEX, + NULL);// pipeInfo + + WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(pDeviceContext->BulkReadPipe); + + pDeviceContext->BulkWritePipe = WdfUsbInterfaceGetConfiguredPipe( + pDeviceContext->UsbInterface, + BULK_OUT_ENDPOINT_INDEX, + NULL);// pipeInfo + + WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(pDeviceContext->BulkWritePipe); + + return status; +} + +VOID +EvtIoDeviceControl( + IN WDFQUEUE Queue, + IN WDFREQUEST Request, + IN size_t OutputBufferLength, + IN size_t InputBufferLength, + IN ULONG IoControlCode + ) +{ + WDFDEVICE device; + PDEVICE_CONTEXT pDevContext; + size_t bytesTransferred = 0; + NTSTATUS status; + WDF_USB_CONTROL_SETUP_PACKET controlSetupPacket; + WDF_MEMORY_DESCRIPTOR memDesc; + WDFMEMORY memory; + WDF_REQUEST_SEND_OPTIONS sendOptions; + + UNREFERENCED_PARAMETER(InputBufferLength); + UNREFERENCED_PARAMETER(OutputBufferLength); + + device = WdfIoQueueGetDevice(Queue); + pDevContext = GetDeviceContext(device); + + switch(IoControlCode) { + + case IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY: + + if(InputBufferLength < sizeof(UCHAR)) { + status = STATUS_BUFFER_OVERFLOW; + bytesTransferred = sizeof(UCHAR); + break; + } + + status = WdfRequestRetrieveInputMemory(Request, &memory); + if (!NT_SUCCESS(status)) { + KdPrint(("WdfRequestRetrieveMemory failed 0x%x", status)); + break; + } + + WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(&controlSetupPacket, + BmRequestHostToDevice, + BmRequestToDevice, + USBFX2LK_SET_BARGRAPH_DISPLAY, // Request + 0, // Value + 0); // Index + + WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(&memDesc, memory, NULL); + + // + // Send the I/O with a timeout to avoid hanging the calling + // thread indefinitely. + // + WDF_REQUEST_SEND_OPTIONS_INIT(&sendOptions, + WDF_REQUEST_SEND_OPTION_TIMEOUT); + + WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&sendOptions, + WDF_REL_TIMEOUT_IN_MS(100)); + + status = WdfUsbTargetDeviceSendControlTransferSynchronously( + pDevContext->UsbDevice, + NULL, // Optional WDFREQUEST + &sendOptions, // PWDF_REQUEST_SEND_OPTIONS + &controlSetupPacket, + &memDesc, + (PULONG)&bytesTransferred); + if (!NT_SUCCESS(status)) { + KdPrint(("SendControlTransfer failed 0x%x", status)); + break; + } + break; + + default: + status = STATUS_INVALID_DEVICE_REQUEST; + break; + } + + WdfRequestCompleteWithInformation(Request, status, bytesTransferred); + + return; +} + +VOID +EvtIoRead( + IN WDFQUEUE Queue, + IN WDFREQUEST Request, + IN size_t Length + ) +{ + WDFUSBPIPE pipe; + NTSTATUS status; + WDFMEMORY reqMemory; + PDEVICE_CONTEXT pDeviceContext; + BOOLEAN ret; + + UNREFERENCED_PARAMETER(Length); + + pDeviceContext = GetDeviceContext(WdfIoQueueGetDevice(Queue)); + + pipe = pDeviceContext->BulkReadPipe; + + status = WdfRequestRetrieveOutputMemory(Request, &reqMemory); + if(!NT_SUCCESS(status)){ + goto Exit; + } + + status = WdfUsbTargetPipeFormatRequestForRead(pipe, + Request, + reqMemory, + NULL // Offsets + ); + if (!NT_SUCCESS(status)) { + goto Exit; + } + + WdfRequestSetCompletionRoutine(Request, + EvtRequestReadCompletionRoutine, + pipe); + ret = WdfRequestSend(Request, + WdfUsbTargetPipeGetIoTarget(pipe), + WDF_NO_SEND_OPTIONS); + + if (ret == FALSE) { + status = WdfRequestGetStatus(Request); + goto Exit; + } else { + return; + } + +Exit: + WdfRequestCompleteWithInformation(Request, status, 0); + + return; +} + +VOID +EvtRequestReadCompletionRoutine( + IN WDFREQUEST Request, + IN WDFIOTARGET Target, + PWDF_REQUEST_COMPLETION_PARAMS CompletionParams, + IN WDFCONTEXT Context + ) +{ + NTSTATUS status; + size_t bytesRead = 0; + PWDF_USB_REQUEST_COMPLETION_PARAMS usbCompletionParams; + + UNREFERENCED_PARAMETER(Target); + UNREFERENCED_PARAMETER(Context); + + status = CompletionParams->IoStatus.Status; + + usbCompletionParams = CompletionParams->Parameters.Usb.Completion; + + bytesRead = usbCompletionParams->Parameters.PipeRead.Length; + + if (NT_SUCCESS(status)){ + KdPrint(("Number of bytes read: %I64d\n", (INT64)bytesRead)); + } else { + KdPrint(("Read failed - request status 0x%x UsbdStatus 0x%x\n", + status, usbCompletionParams->UsbdStatus)); + + } + + WdfRequestCompleteWithInformation(Request, status, bytesRead); + + return; +} + +VOID +EvtIoWrite( + IN WDFQUEUE Queue, + IN WDFREQUEST Request, + IN size_t Length + ) +{ + NTSTATUS status; + WDFUSBPIPE pipe; + WDFMEMORY reqMemory; + PDEVICE_CONTEXT pDeviceContext; + BOOLEAN ret; + + UNREFERENCED_PARAMETER(Length); + + pDeviceContext = GetDeviceContext(WdfIoQueueGetDevice(Queue)); + + pipe = pDeviceContext->BulkWritePipe; + + status = WdfRequestRetrieveInputMemory(Request, &reqMemory); + if(!NT_SUCCESS(status)){ + goto Exit; + } + + status = WdfUsbTargetPipeFormatRequestForWrite(pipe, + Request, + reqMemory, + NULL); // Offset + if (!NT_SUCCESS(status)) { + goto Exit; + } + + WdfRequestSetCompletionRoutine( + Request, + EvtRequestWriteCompletionRoutine, + pipe); + ret = WdfRequestSend(Request, + WdfUsbTargetPipeGetIoTarget(pipe), + WDF_NO_SEND_OPTIONS); + if (ret == FALSE) { + status = WdfRequestGetStatus(Request); + goto Exit; + } else { + return; + } + +Exit: + WdfRequestCompleteWithInformation(Request, status, 0); + + return; +} + +VOID +EvtRequestWriteCompletionRoutine( + IN WDFREQUEST Request, + IN WDFIOTARGET Target, + PWDF_REQUEST_COMPLETION_PARAMS CompletionParams, + IN WDFCONTEXT Context + ) +{ + NTSTATUS status; + size_t bytesWritten = 0; + PWDF_USB_REQUEST_COMPLETION_PARAMS usbCompletionParams; + + UNREFERENCED_PARAMETER(Target); + UNREFERENCED_PARAMETER(Context); + + status = CompletionParams->IoStatus.Status; + + usbCompletionParams = CompletionParams->Parameters.Usb.Completion; + + bytesWritten = usbCompletionParams->Parameters.PipeWrite.Length; + + if (NT_SUCCESS(status)){ + KdPrint(("Number of bytes written: %I64d\n", (INT64)bytesWritten)); + } else { + KdPrint(("Write failed: request Status 0x%x UsbdStatus 0x%x\n", + status, usbCompletionParams->UsbdStatus)); + } + + WdfRequestCompleteWithInformation(Request, status, bytesWritten); + + return; +} diff --git a/usb/wdf_osrfx2_lab/kmdf/step5/osrusbfx2.inx b/usb/wdf_osrfx2_lab/kmdf/step5/osrusbfx2.inx Binary files differnew file mode 100644 index 00000000..c8678d1e --- /dev/null +++ b/usb/wdf_osrfx2_lab/kmdf/step5/osrusbfx2.inx diff --git a/usb/wdf_osrfx2_lab/kmdf/step5/osrusbfx2.vcxproj b/usb/wdf_osrfx2_lab/kmdf/step5/osrusbfx2.vcxproj new file mode 100644 index 00000000..38f8d8e4 --- /dev/null +++ b/usb/wdf_osrfx2_lab/kmdf/step5/osrusbfx2.vcxproj @@ -0,0 +1,184 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{EEB5FBCF-333A-4D54-B937-C24FB0CC10EB}</ProjectGuid> + <RootNamespace>$(MSBuildProjectName)</RootNamespace> + <KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR> + <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration> + <Platform Condition="'$(Platform)' == ''">Win32</Platform> + <SampleGuid>{431021B1-C043-4ACE-A0F0-46ACD36C675E}</SampleGuid> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + <DriverType>KMDF</DriverType> + <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> + <ConfigurationType>Driver</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + <DriverType>KMDF</DriverType> + <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> + <ConfigurationType>Driver</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + <DriverType>KMDF</DriverType> + <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> + <ConfigurationType>Driver</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + <DriverType>KMDF</DriverType> + <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> + <ConfigurationType>Driver</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <OutDir>$(IntDir)</OutDir> + </PropertyGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ItemGroup Label="WrappedTaskItems"> + <ClCompile Include="step5.c"> + <WppEnabled>true</WppEnabled> + <WppKernelMode>true</WppKernelMode> + <WppAddControlGuid>d23a0c5a-d307-4f0e-ae8e-E2A355AD5DAB</WppAddControlGuid> + <WppTraceFunction>KdPrint((MSG,...))</WppTraceFunction> + <WppGenerateUsingTemplateFile>{km-WdfDefault.tpl}*.tmh</WppGenerateUsingTemplateFile> + </ClCompile> + </ItemGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetName>osrusbfx2</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetName>osrusbfx2</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetName>osrusbfx2</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetName>osrusbfx2</TargetName> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\ntstrsafe.lib</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\ntstrsafe.lib</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\ntstrsafe.lib</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc</AdditionalIncludeDirectories> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);$(DDK_LIB_PATH)\ntstrsafe.lib</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <Inf Exclude="@(Inf)" Include="*.inf" /> + <FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" /> + </ItemGroup> + <ItemGroup> + <None Exclude="@(None)" Include="*.txt;*.htm;*.html" /> + <None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" /> + <None Exclude="@(None)" Include="*.def;*.bat;*.hpj;*.asmx" /> + </ItemGroup> + <ItemGroup> + <ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> +</Project>
\ No newline at end of file diff --git a/usb/wdf_osrfx2_lab/kmdf/step5/osrusbfx2.vcxproj.Filters b/usb/wdf_osrfx2_lab/kmdf/step5/osrusbfx2.vcxproj.Filters new file mode 100644 index 00000000..2d70405d --- /dev/null +++ b/usb/wdf_osrfx2_lab/kmdf/step5/osrusbfx2.vcxproj.Filters @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions> + <UniqueIdentifier>{ACC2636B-CF0E-48A5-A06D-448ECCE13485}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files"> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + <UniqueIdentifier>{FC8D5530-0758-47BE-92EC-375BF53D1CCF}</UniqueIdentifier> + </Filter> + <Filter Include="Resource Files"> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions> + <UniqueIdentifier>{56863D00-8550-4BAB-8E65-74AD21E21437}</UniqueIdentifier> + </Filter> + <Filter Include="Driver Files"> + <Extensions>inf;inv;inx;mof;mc;</Extensions> + <UniqueIdentifier>{D7A044A6-5335-48DA-B30C-460EEA63C852}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="step5.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/usb/wdf_osrfx2_lab/kmdf/step5/step5.c b/usb/wdf_osrfx2_lab/kmdf/step5/step5.c new file mode 100644 index 00000000..fa580741 --- /dev/null +++ b/usb/wdf_osrfx2_lab/kmdf/step5/step5.c @@ -0,0 +1,479 @@ +/*++ + +Step4: This steps shows: + 1) How to map KdPrint function to do WPP tracing +--*/ + +#include <stdarg.h> // To avoid build errors on Win2K due to WPP +#include "ntddk.h" +#include "wdf.h" +#include "prototypes.h" +#include "usbdi.h" +#include "usbdlib.h" +#include "wdfusb.h" +#include "initguid.h" + +#include "step5.tmh" + +DEFINE_GUID(GUID_DEVINTERFACE_OSRUSBFX2, // Generated using guidgen.exe + 0x573e8c73, 0xcb4, 0x4471, 0xa1, 0xbf, 0xfa, 0xb2, 0x6c, 0x31, 0xd3, 0x84); +// {573E8C73-0CB4-4471-A1BF-FAB26C31D384} + +#define IOCTL_INDEX 0x800 +#define FILE_DEVICE_OSRUSBFX2 65500U +#define USBFX2LK_SET_BARGRAPH_DISPLAY 0xD8 +#define BULK_OUT_ENDPOINT_INDEX 1 +#define BULK_IN_ENDPOINT_INDEX 2 +#define IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY CTL_CODE(FILE_DEVICE_OSRUSBFX2,\ + IOCTL_INDEX + 5, \ + METHOD_BUFFERED, \ + FILE_WRITE_ACCESS) +typedef struct _DEVICE_CONTEXT { + WDFUSBDEVICE UsbDevice; + WDFUSBINTERFACE UsbInterface; + WDFUSBPIPE BulkReadPipe; + WDFUSBPIPE BulkWritePipe; +} DEVICE_CONTEXT, *PDEVICE_CONTEXT; + +WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DEVICE_CONTEXT, GetDeviceContext) + + +NTSTATUS +DriverEntry( + IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegistryPath + ) +{ + WDF_DRIVER_CONFIG config; + NTSTATUS status; + WDF_OBJECT_ATTRIBUTES attributes; + + WPP_INIT_TRACING( DriverObject, RegistryPath ); + + KdPrint(("DriverEntry of Step5\n")); + + WDF_DRIVER_CONFIG_INIT(&config, EvtDeviceAdd); + + // + // Register a cleanup callback so that we can call WPP_CLEANUP when + // the framework driver object is deleted during driver unload. + // + WDF_OBJECT_ATTRIBUTES_INIT(&attributes); + attributes.EvtCleanupCallback = EvtDriverContextCleanup; + + status = WdfDriverCreate(DriverObject, + RegistryPath, + &attributes, + &config, + WDF_NO_HANDLE + ); + + if (!NT_SUCCESS(status)) { + KdPrint(("WdfDriverCreate failed %!STATUS!\n", status)); + // + // Cleanup tracing here because DriverContextCleanup will not be called + // as we have failed to create WDFDRIVER object itself. + // Please note that if your return failure from DriverEntry after the + // WDFDRIVER object is created successfully, you don't have to + // call WPP cleanup because in those cases DriverContextCleanup + // will be executed when the framework deletes the DriverObject. + // + WPP_CLEANUP(DriverObject); + } + + return status; +} + +VOID +EvtDriverContextCleanup( + IN WDFOBJECT Driver + ) +{ + WPP_CLEANUP(WdfDriverWdmGetDriverObject((WDFDRIVER)Driver )); +} + +NTSTATUS +EvtDeviceAdd( + IN WDFDRIVER Driver, + IN PWDFDEVICE_INIT DeviceInit + ) +{ + WDF_OBJECT_ATTRIBUTES attributes; + NTSTATUS status; + WDFDEVICE device; + WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks; + WDF_IO_QUEUE_CONFIG ioQueueConfig; + + UNREFERENCED_PARAMETER(Driver); + + WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks); + pnpPowerCallbacks.EvtDevicePrepareHardware = EvtDevicePrepareHardware; + WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks); + + WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, DEVICE_CONTEXT); + + status = WdfDeviceCreate(&DeviceInit, &attributes, &device); + if (!NT_SUCCESS(status)) { + KdPrint(("WdfDeviceCreate failed %!STATUS!\n", status)); + return status; + } + + status = WdfDeviceCreateDeviceInterface(device, + (LPGUID) &GUID_DEVINTERFACE_OSRUSBFX2, + NULL);// Reference String + if (!NT_SUCCESS(status)) { + KdPrint(("WdfDeviceCreateDeviceInterface failed %!STATUS!\n", status)); + return status; + } + + WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&ioQueueConfig, + WdfIoQueueDispatchParallel); + + ioQueueConfig.EvtIoDeviceControl = EvtIoDeviceControl; + ioQueueConfig.EvtIoRead = EvtIoRead; + ioQueueConfig.EvtIoWrite = EvtIoWrite; + + // + // By default, Static Driver Verifier (SDV) displays a warning if it + // doesn't find the EvtIoStop callback on a power-managed queue. + // The 'assume' below causes SDV to suppress this warning. + // Please see 'final' step for implementation of EvtIoStop. + // + __analysis_assume(ioQueueConfig.EvtIoStop != 0); + status = WdfIoQueueCreate(device, + &ioQueueConfig, + WDF_NO_OBJECT_ATTRIBUTES, + WDF_NO_HANDLE); + __analysis_assume(ioQueueConfig.EvtIoStop == 0); + + if (!NT_SUCCESS(status)) { + KdPrint(("WdfIoQueueCreate failed %!STATUS!\n", status)); + return status; + } + + return status; +} + + +NTSTATUS +EvtDevicePrepareHardware( + IN WDFDEVICE Device, + IN WDFCMRESLIST ResourceList, + IN WDFCMRESLIST ResourceListTranslated + ) +{ + NTSTATUS status; + PDEVICE_CONTEXT pDeviceContext; + WDF_USB_DEVICE_SELECT_CONFIG_PARAMS configParams; + + UNREFERENCED_PARAMETER(ResourceList); + UNREFERENCED_PARAMETER(ResourceListTranslated); + + pDeviceContext = GetDeviceContext(Device); + + // + // Create the USB device if it is not already created. + // + if (pDeviceContext->UsbDevice == NULL) { + WDF_USB_DEVICE_CREATE_CONFIG config; + + WDF_USB_DEVICE_CREATE_CONFIG_INIT(&config, + USBD_CLIENT_CONTRACT_VERSION_602); + + status = WdfUsbTargetDeviceCreateWithParameters(Device, + &config, + WDF_NO_OBJECT_ATTRIBUTES, + &pDeviceContext->UsbDevice); + + if (!NT_SUCCESS(status)) { + KdPrint(("WdfUsbTargetDeviceCreateWithParameters failed 0x%x\n", status)); + return status; + } + } + + WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_SINGLE_INTERFACE(&configParams); + + status = WdfUsbTargetDeviceSelectConfig(pDeviceContext->UsbDevice, + WDF_NO_OBJECT_ATTRIBUTES, + &configParams); + if(!NT_SUCCESS(status)) { + KdPrint(("WdfUsbTargetDeviceSelectConfig failed %!STATUS!\n", status)); + return status; + } + + pDeviceContext->UsbInterface = + configParams.Types.SingleInterface.ConfiguredUsbInterface; + + + pDeviceContext->BulkReadPipe = WdfUsbInterfaceGetConfiguredPipe( + pDeviceContext->UsbInterface, + BULK_IN_ENDPOINT_INDEX, + NULL);// pipeInfo + + WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(pDeviceContext->BulkReadPipe); + + pDeviceContext->BulkWritePipe = WdfUsbInterfaceGetConfiguredPipe( + pDeviceContext->UsbInterface, + BULK_OUT_ENDPOINT_INDEX, + NULL);// pipeInfo + + WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(pDeviceContext->BulkWritePipe); + + return status; +} + +VOID +EvtIoDeviceControl( + IN WDFQUEUE Queue, + IN WDFREQUEST Request, + IN size_t OutputBufferLength, + IN size_t InputBufferLength, + IN ULONG IoControlCode + ) +{ + WDFDEVICE device; + PDEVICE_CONTEXT pDevContext; + size_t bytesTransferred = 0; + NTSTATUS status; + WDF_USB_CONTROL_SETUP_PACKET controlSetupPacket; + WDF_MEMORY_DESCRIPTOR memDesc; + WDFMEMORY memory; + WDF_REQUEST_SEND_OPTIONS sendOptions; + + UNREFERENCED_PARAMETER(InputBufferLength); + UNREFERENCED_PARAMETER(OutputBufferLength); + + device = WdfIoQueueGetDevice(Queue); + pDevContext = GetDeviceContext(device); + + switch(IoControlCode) { + + case IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY: + + if(InputBufferLength < sizeof(UCHAR)) { + status = STATUS_BUFFER_OVERFLOW; + bytesTransferred = sizeof(UCHAR); + break; + } + + status = WdfRequestRetrieveInputMemory(Request, &memory); + if (!NT_SUCCESS(status)) { + KdPrint(("WdfRequestRetrieveMemory failed %!STATUS!", status)); + break; + } + + WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(&controlSetupPacket, + BmRequestHostToDevice, + BmRequestToDevice, + USBFX2LK_SET_BARGRAPH_DISPLAY, // Request + 0, // Value + 0); // Index + + WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(&memDesc, memory, NULL); + + // + // Send the I/O with a timeout to avoid hanging the calling + // thread indefinitely. + // + WDF_REQUEST_SEND_OPTIONS_INIT(&sendOptions, + WDF_REQUEST_SEND_OPTION_TIMEOUT); + + WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&sendOptions, + WDF_REL_TIMEOUT_IN_MS(100)); + + status = WdfUsbTargetDeviceSendControlTransferSynchronously( + pDevContext->UsbDevice, + NULL, // Optional WDFREQUEST + &sendOptions, // PWDF_REQUEST_SEND_OPTIONS + &controlSetupPacket, + &memDesc, + (PULONG)&bytesTransferred); + if (!NT_SUCCESS(status)) { + KdPrint(("SendControlTransfer failed %!STATUS!", status)); + break; + } + break; + + default: + status = STATUS_INVALID_DEVICE_REQUEST; + break; + } + + WdfRequestCompleteWithInformation(Request, status, bytesTransferred); + + return; +} + +VOID +EvtIoRead( + IN WDFQUEUE Queue, + IN WDFREQUEST Request, + IN size_t Length + ) +{ + WDFUSBPIPE pipe; + NTSTATUS status; + WDFMEMORY reqMemory; + PDEVICE_CONTEXT pDeviceContext; + BOOLEAN ret; + + UNREFERENCED_PARAMETER(Length); + + pDeviceContext = GetDeviceContext(WdfIoQueueGetDevice(Queue)); + + pipe = pDeviceContext->BulkReadPipe; + + status = WdfRequestRetrieveOutputMemory(Request, &reqMemory); + if(!NT_SUCCESS(status)){ + goto Exit; + } + + status = WdfUsbTargetPipeFormatRequestForRead(pipe, + Request, + reqMemory, + NULL // Offsets + ); + if (!NT_SUCCESS(status)) { + goto Exit; + } + + WdfRequestSetCompletionRoutine( + Request, + EvtRequestReadCompletionRoutine, + pipe); + + ret = WdfRequestSend(Request, + WdfUsbTargetPipeGetIoTarget(pipe), + WDF_NO_SEND_OPTIONS); + if (ret == FALSE) { + status = WdfRequestGetStatus(Request); + goto Exit; + } else { + return; + } + +Exit: + WdfRequestCompleteWithInformation(Request, status, 0); + + return; +} + +VOID +EvtRequestReadCompletionRoutine( + IN WDFREQUEST Request, + IN WDFIOTARGET Target, + PWDF_REQUEST_COMPLETION_PARAMS CompletionParams, + IN WDFCONTEXT Context + ) +{ + NTSTATUS status; + size_t bytesRead = 0; + PWDF_USB_REQUEST_COMPLETION_PARAMS usbCompletionParams; + + UNREFERENCED_PARAMETER(Target); + UNREFERENCED_PARAMETER(Context); + + status = CompletionParams->IoStatus.Status; + + usbCompletionParams = CompletionParams->Parameters.Usb.Completion; + + bytesRead = usbCompletionParams->Parameters.PipeRead.Length; + + if (NT_SUCCESS(status)){ + KdPrint(("Number of bytes read: %I64d\n", (INT64)bytesRead)); + } else { + KdPrint(("Read failed - request status %!STATUS! UsbdStatus %!STATUS!\n", + status, usbCompletionParams->UsbdStatus)); + + } + + WdfRequestCompleteWithInformation(Request, status, bytesRead); + + return; +} + +VOID +EvtIoWrite( + IN WDFQUEUE Queue, + IN WDFREQUEST Request, + IN size_t Length + ) +{ + NTSTATUS status; + WDFUSBPIPE pipe; + WDFMEMORY reqMemory; + PDEVICE_CONTEXT pDeviceContext; + BOOLEAN ret; + + UNREFERENCED_PARAMETER(Length); + + pDeviceContext = GetDeviceContext(WdfIoQueueGetDevice(Queue)); + + pipe = pDeviceContext->BulkWritePipe; + + status = WdfRequestRetrieveInputMemory(Request, &reqMemory); + if(!NT_SUCCESS(status)){ + goto Exit; + } + + status = WdfUsbTargetPipeFormatRequestForWrite(pipe, + Request, + reqMemory, + NULL); // Offset + if (!NT_SUCCESS(status)) { + goto Exit; + } + + WdfRequestSetCompletionRoutine( + Request, + EvtRequestWriteCompletionRoutine, + pipe); + + ret = WdfRequestSend(Request, + WdfUsbTargetPipeGetIoTarget(pipe), + WDF_NO_SEND_OPTIONS); + if (ret == FALSE) { + status = WdfRequestGetStatus(Request); + goto Exit; + } else { + return; + } + +Exit: + WdfRequestCompleteWithInformation(Request, status, 0); + + return; +} + +VOID +EvtRequestWriteCompletionRoutine( + IN WDFREQUEST Request, + IN WDFIOTARGET Target, + PWDF_REQUEST_COMPLETION_PARAMS CompletionParams, + IN WDFCONTEXT Context + ) +{ + NTSTATUS status; + size_t bytesWritten = 0; + PWDF_USB_REQUEST_COMPLETION_PARAMS usbCompletionParams; + + UNREFERENCED_PARAMETER(Target); + UNREFERENCED_PARAMETER(Context); + + status = CompletionParams->IoStatus.Status; + + usbCompletionParams = CompletionParams->Parameters.Usb.Completion; + + bytesWritten = usbCompletionParams->Parameters.PipeWrite.Length; + + if (NT_SUCCESS(status)){ + KdPrint(("Number of bytes written: %I64d\n", (INT64)bytesWritten)); + } else { + KdPrint(("Write failed: request Status %!STATUS! UsbdStatus %!STATUS!\n", + status, usbCompletionParams->UsbdStatus)); + } + + WdfRequestCompleteWithInformation(Request, status, bytesWritten); + + return; +} diff --git a/usb/wdf_osrfx2_lab/umdf/exe/WudfOsrUsbFx2Test.vcxproj b/usb/wdf_osrfx2_lab/umdf/exe/WudfOsrUsbFx2Test.vcxproj new file mode 100644 index 00000000..e594febf --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/exe/WudfOsrUsbFx2Test.vcxproj @@ -0,0 +1,211 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{B4244D54-7EBF-43D4-BB6D-C994C182C572}</ProjectGuid> + <RootNamespace>$(MSBuildProjectName)</RootNamespace> + <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration> + <Platform Condition="'$(Platform)' == ''">Win32</Platform> + <SampleGuid>{6A99CFCE-4C34-4F5D-B7D4-D810AE496B95}</SampleGuid> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType /> + <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType /> + <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType /> + <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType /> + <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <OutDir>$(IntDir)</OutDir> + </PropertyGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ItemGroup Label="WrappedTaskItems" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetName>WudfOsrUsbFx2Test</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetName>WudfOsrUsbFx2Test</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetName>WudfOsrUsbFx2Test</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetName>WudfOsrUsbFx2Test</TargetName> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);BUILT_IN_DDK=1;UNICODE=1;_UNICODE=1</PreprocessorDefinitions> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc;..\..\inc;$(DDK_INC_PATH)</AdditionalIncludeDirectories> + </ClCompile> + <Midl> + <PreprocessorDefinitions>%(PreprocessorDefinitions);BUILT_IN_DDK=1;UNICODE=1;_UNICODE=1</PreprocessorDefinitions> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc;..\..\inc;$(DDK_INC_PATH)</AdditionalIncludeDirectories> + </Midl> + <ResourceCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);BUILT_IN_DDK=1;UNICODE=1;_UNICODE=1</PreprocessorDefinitions> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc;..\..\inc;$(DDK_INC_PATH)</AdditionalIncludeDirectories> + </ResourceCompile> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);setupapi.lib</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);BUILT_IN_DDK=1;UNICODE=1;_UNICODE=1</PreprocessorDefinitions> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc;..\..\inc;$(DDK_INC_PATH)</AdditionalIncludeDirectories> + </ClCompile> + <Midl> + <PreprocessorDefinitions>%(PreprocessorDefinitions);BUILT_IN_DDK=1;UNICODE=1;_UNICODE=1</PreprocessorDefinitions> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc;..\..\inc;$(DDK_INC_PATH)</AdditionalIncludeDirectories> + </Midl> + <ResourceCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);BUILT_IN_DDK=1;UNICODE=1;_UNICODE=1</PreprocessorDefinitions> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc;..\..\inc;$(DDK_INC_PATH)</AdditionalIncludeDirectories> + </ResourceCompile> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);setupapi.lib</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);BUILT_IN_DDK=1;UNICODE=1;_UNICODE=1</PreprocessorDefinitions> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc;..\..\inc;$(DDK_INC_PATH)</AdditionalIncludeDirectories> + </ClCompile> + <Midl> + <PreprocessorDefinitions>%(PreprocessorDefinitions);BUILT_IN_DDK=1;UNICODE=1;_UNICODE=1</PreprocessorDefinitions> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc;..\..\inc;$(DDK_INC_PATH)</AdditionalIncludeDirectories> + </Midl> + <ResourceCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);BUILT_IN_DDK=1;UNICODE=1;_UNICODE=1</PreprocessorDefinitions> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc;..\..\inc;$(DDK_INC_PATH)</AdditionalIncludeDirectories> + </ResourceCompile> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);setupapi.lib</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);BUILT_IN_DDK=1;UNICODE=1;_UNICODE=1</PreprocessorDefinitions> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc;..\..\inc;$(DDK_INC_PATH)</AdditionalIncludeDirectories> + </ClCompile> + <Midl> + <PreprocessorDefinitions>%(PreprocessorDefinitions);BUILT_IN_DDK=1;UNICODE=1;_UNICODE=1</PreprocessorDefinitions> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc;..\..\inc;$(DDK_INC_PATH)</AdditionalIncludeDirectories> + </Midl> + <ResourceCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);BUILT_IN_DDK=1;UNICODE=1;_UNICODE=1</PreprocessorDefinitions> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\inc;..\..\inc;$(DDK_INC_PATH)</AdditionalIncludeDirectories> + </ResourceCompile> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);setupapi.lib</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <FilesToPackage Include="$(OutDir)WudfOsrUsbFx2Test.exe" /> + </ItemGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="dump.c" /> + <ClCompile Include="testapp.c" /> + <ResourceCompile Include="testapp.rc" /> + </ItemGroup> + <ItemGroup> + <Inf Exclude="@(Inf)" Include="*.inf" /> + <FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" /> + </ItemGroup> + <ItemGroup> + <None Exclude="@(None)" Include="*.txt;*.htm;*.html" /> + <None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" /> + <None Exclude="@(None)" Include="*.def;*.bat;*.hpj;*.asmx" /> + </ItemGroup> + <ItemGroup> + <ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> +</Project>
\ No newline at end of file diff --git a/usb/wdf_osrfx2_lab/umdf/exe/WudfOsrUsbFx2Test.vcxproj.Filters b/usb/wdf_osrfx2_lab/umdf/exe/WudfOsrUsbFx2Test.vcxproj.Filters new file mode 100644 index 00000000..a430f986 --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/exe/WudfOsrUsbFx2Test.vcxproj.Filters @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions> + <UniqueIdentifier>{047255FC-568B-4968-9167-306B7BC95B6D}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files"> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + <UniqueIdentifier>{4B1DCCF4-7F0A-4571-BA4F-DF378E24BD68}</UniqueIdentifier> + </Filter> + <Filter Include="Resource Files"> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions> + <UniqueIdentifier>{AC1DECB1-7996-4C71-8D32-0543B4C57AD4}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="dump.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="testapp.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="testapp.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/usb/wdf_osrfx2_lab/umdf/exe/dump.c b/usb/wdf_osrfx2_lab/umdf/exe/dump.c new file mode 100644 index 00000000..aef55116 --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/exe/dump.c @@ -0,0 +1,444 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + + THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR + PURPOSE. + +Module Name: + + DUMP.C + +Abstract: + + Routines to dump the descriptors information in a human readable form. + +Environment: + + user mode only + +--*/ + +#include <windows.h> +#include <stdio.h> +#include <stdlib.h> +#include "devioctl.h" + +#pragma warning(disable:4200) // +#pragma warning(disable:4201) // nameless struct/union +#pragma warning(disable:4214) // bit field types other than int + +#include <basetyps.h> +#include "usbdi.h" +#include "public.h" + +#pragma warning(default:4200) +#pragma warning(default:4201) +#pragma warning(default:4214) + +HANDLE +OpenDevice( + _In_ BOOL Synchronous + ); + + +char* +usbDescriptorTypeString(UCHAR bDescriptorType ) +/*++ +Routine Description: + + Called to get ascii string of USB descriptor + +Arguments: + + PUSB_ENDPOINT_DESCRIPTOR->bDescriptorType or + PUSB_DEVICE_DESCRIPTOR->bDescriptorType or + PUSB_INTERFACE_DESCRIPTOR->bDescriptorType or + PUSB_STRING_DESCRIPTOR->bDescriptorType or + PUSB_POWER_DESCRIPTOR->bDescriptorType or + PUSB_CONFIGURATION_DESCRIPTOR->bDescriptorType + +Return Value: + + ptr to string + +--*/ +{ + + switch(bDescriptorType) { + + case USB_DEVICE_DESCRIPTOR_TYPE: + return "USB_DEVICE_DESCRIPTOR_TYPE"; + + case USB_CONFIGURATION_DESCRIPTOR_TYPE: + return "USB_CONFIGURATION_DESCRIPTOR_TYPE"; + + + case USB_STRING_DESCRIPTOR_TYPE: + return "USB_STRING_DESCRIPTOR_TYPE"; + + + case USB_INTERFACE_DESCRIPTOR_TYPE: + return "USB_INTERFACE_DESCRIPTOR_TYPE"; + + + case USB_ENDPOINT_DESCRIPTOR_TYPE: + return "USB_ENDPOINT_DESCRIPTOR_TYPE"; + + +#ifdef USB_POWER_DESCRIPTOR_TYPE // this is the older definintion which is actually obsolete + // workaround for temporary bug in 98ddk, older USB100.h file + case USB_POWER_DESCRIPTOR_TYPE: + return "USB_POWER_DESCRIPTOR_TYPE"; +#endif + +#ifdef USB_RESERVED_DESCRIPTOR_TYPE // this is the current version of USB100.h as in NT5DDK + + case USB_RESERVED_DESCRIPTOR_TYPE: + return "USB_RESERVED_DESCRIPTOR_TYPE"; + + case USB_CONFIG_POWER_DESCRIPTOR_TYPE: + return "USB_CONFIG_POWER_DESCRIPTOR_TYPE"; + + case USB_INTERFACE_POWER_DESCRIPTOR_TYPE: + return "USB_INTERFACE_POWER_DESCRIPTOR_TYPE"; +#endif // for current nt5ddk version of USB100.h + + default: + return "??? UNKNOWN!!"; + } +} + + +char * +usbEndPointTypeString(UCHAR bmAttributes) +/*++ +Routine Description: + + Called to get ascii string of endpt descriptor type + +Arguments: + + PUSB_ENDPOINT_DESCRIPTOR->bmAttributes + +Return Value: + + ptr to string + +--*/ +{ + UINT typ = bmAttributes & USB_ENDPOINT_TYPE_MASK; + + + switch( typ) { + case USB_ENDPOINT_TYPE_INTERRUPT: + return "USB_ENDPOINT_TYPE_INTERRUPT"; + + case USB_ENDPOINT_TYPE_BULK: + return "USB_ENDPOINT_TYPE_BULK"; + + case USB_ENDPOINT_TYPE_ISOCHRONOUS: + return "USB_ENDPOINT_TYPE_ISOCHRONOUS"; + + case USB_ENDPOINT_TYPE_CONTROL: + return "USB_ENDPOINT_TYPE_CONTROL"; + + default: + return "??? UNKNOWN!!"; + } +} + + +char * +usbConfigAttributesString(UCHAR bmAttributes) +/*++ +Routine Description: + + Called to get ascii string of USB_CONFIGURATION_DESCRIPTOR attributes + +Arguments: + + PUSB_CONFIGURATION_DESCRIPTOR->bmAttributes + +Return Value: + + ptr to string + +--*/ +{ + UINT typ = bmAttributes & USB_CONFIG_POWERED_MASK; + + + switch( typ) { + + case USB_CONFIG_BUS_POWERED: + return "USB_CONFIG_BUS_POWERED"; + + case USB_CONFIG_SELF_POWERED: + return "USB_CONFIG_SELF_POWERED"; + + case USB_CONFIG_REMOTE_WAKEUP: + return "USB_CONFIG_REMOTE_WAKEUP"; + + + default: + return "??? UNKNOWN!!"; + } +} + + +void +print_USB_CONFIGURATION_DESCRIPTOR(PUSB_CONFIGURATION_DESCRIPTOR cd) +/*++ +Routine Description: + + Called to do formatted ascii dump to console of a USB config descriptor + +Arguments: + + ptr to USB configuration descriptor + +Return Value: + + none + +--*/ +{ + printf("\n===================\nUSB_CONFIGURATION_DESCRIPTOR\n"); + + printf( + "bLength = 0x%x, decimal %u\n", cd->bLength, cd->bLength + ); + + printf( + "bDescriptorType = 0x%x ( %s )\n", cd->bDescriptorType, + usbDescriptorTypeString( cd->bDescriptorType ) + ); + + printf( + "wTotalLength = 0x%x, decimal %u\n", cd->wTotalLength, cd->wTotalLength + ); + + printf( + "bNumInterfaces = 0x%x, decimal %u\n", cd->bNumInterfaces, cd->bNumInterfaces + ); + + printf( + "bConfigurationValue = 0x%x, decimal %u\n", + cd->bConfigurationValue, cd->bConfigurationValue + ); + + printf( + "iConfiguration = 0x%x, decimal %u\n", cd->iConfiguration, cd->iConfiguration + ); + + printf( + "bmAttributes = 0x%x ( %s )\n", cd->bmAttributes, + usbConfigAttributesString( cd->bmAttributes ) + ); + + printf( + "MaxPower = 0x%x, decimal %u\n", cd->MaxPower, cd->MaxPower + ); +} + + +void +print_USB_INTERFACE_DESCRIPTOR(PUSB_INTERFACE_DESCRIPTOR id, UINT ix) +/*++ +Routine Description: + + Called to do formatted ascii dump to console of a USB interface descriptor + +Arguments: + + ptr to USB interface descriptor + +Return Value: + + none + +--*/ +{ + printf("\n-----------------------------\nUSB_INTERFACE_DESCRIPTOR #%u\n", ix); + + + printf( + "bLength = 0x%x\n", id->bLength + ); + + + printf( + "bDescriptorType = 0x%x ( %s )\n", id->bDescriptorType, + usbDescriptorTypeString( id->bDescriptorType ) + ); + + + printf( + "bInterfaceNumber = 0x%x\n", id->bInterfaceNumber + ); + printf( + "bAlternateSetting = 0x%x\n", id->bAlternateSetting + ); + printf( + "bNumEndpoints = 0x%x\n", id->bNumEndpoints + ); + printf( + "bInterfaceClass = 0x%x\n", id->bInterfaceClass + ); + printf( + "bInterfaceSubClass = 0x%x\n", id->bInterfaceSubClass + ); + printf( + "bInterfaceProtocol = 0x%x\n", id->bInterfaceProtocol + ); + printf( + "bInterface = 0x%x\n", id->iInterface + ); +} + + +void +print_USB_ENDPOINT_DESCRIPTOR(PUSB_ENDPOINT_DESCRIPTOR ed, int i) +/*++ +Routine Description: + + Called to do formatted ascii dump to console of a USB endpoint descriptor + +Arguments: + + ptr to USB endpoint descriptor, + index of this endpt in interface desc + +Return Value: + + none + +--*/ +{ + printf( + "------------------------------\nUSB_ENDPOINT_DESCRIPTOR for Pipe%02d\n", i + ); + + printf( + "bLength = 0x%x\n", ed->bLength + ); + + printf( + "bDescriptorType = 0x%x ( %s )\n", ed->bDescriptorType, + usbDescriptorTypeString( ed->bDescriptorType ) + ); + + if ( USB_ENDPOINT_DIRECTION_IN( ed->bEndpointAddress ) ) { + printf( + "bEndpointAddress= 0x%x ( INPUT )\n", ed->bEndpointAddress + ); + } else { + printf( + "bEndpointAddress= 0x%x ( OUTPUT )\n", ed->bEndpointAddress + ); + } + + printf( + "bmAttributes= 0x%x ( %s )\n", ed->bmAttributes, + usbEndPointTypeString ( ed->bmAttributes ) + ); + + printf( + "wMaxPacketSize= 0x%x, decimal %u\n", ed->wMaxPacketSize, + ed->wMaxPacketSize + ); + + printf( + "bInterval = 0x%x, decimal %u\n", ed->bInterval, ed->bInterval + ); +} + + +BOOL +DumpUsbConfig() +/*++ +Routine Description: + + Called to do formatted ascii dump to console of USB + configuration, interface, and endpoint descriptors. + +Arguments: + + none + +Return Value: + + TRUE or FALSE + +--*/ +{ + HANDLE hDev; + UINT success; + int siz, nBytes; + char buf[256] = {0}; + + hDev = OpenDevice(TRUE); + if(hDev == INVALID_HANDLE_VALUE) + { + return FALSE; + } + + siz = sizeof(buf); + + success = DeviceIoControl(hDev, + IOCTL_OSRUSBFX2_GET_CONFIG_DESCRIPTOR, + NULL, + 0, + buf, + siz, + (PULONG) &nBytes, + NULL); + + if(success == FALSE) { + printf("Ioct - GetConfigDesc failed %u\n", GetLastError()); + } else { + + ULONG i; + UINT j, n; + char *pch; + PUSB_CONFIGURATION_DESCRIPTOR cd; + PUSB_INTERFACE_DESCRIPTOR id; + PUSB_ENDPOINT_DESCRIPTOR ed; + + pch = buf; + n = 0; + + cd = (PUSB_CONFIGURATION_DESCRIPTOR) pch; + + print_USB_CONFIGURATION_DESCRIPTOR( cd ); + + pch += cd->bLength; + + do { + id = (PUSB_INTERFACE_DESCRIPTOR) pch; + + print_USB_INTERFACE_DESCRIPTOR(id, n++); + + pch += id->bLength; + for (j=0; j<id->bNumEndpoints; j++) { + + ed = (PUSB_ENDPOINT_DESCRIPTOR) pch; + + print_USB_ENDPOINT_DESCRIPTOR(ed,j); + + pch += ed->bLength; + } + i = (ULONG)(pch - buf); + + } while (i<cd->wTotalLength); + } + + CloseHandle(hDev); + + return success; + +} + diff --git a/usb/wdf_osrfx2_lab/umdf/exe/testapp.c b/usb/wdf_osrfx2_lab/umdf/exe/testapp.c new file mode 100644 index 00000000..4aecf4c7 --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/exe/testapp.c @@ -0,0 +1,1360 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + + THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR + PURPOSE. + +Module Name: + + TESTAPP.C + +Abstract: + + Console test app for osrusbfx2 driver. + +Environment: + + user mode only + +--*/ + +#include <driverspecs.h> +_Analysis_mode_(_Analysis_code_type_user_code_); + +#include <windows.h> +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> + +#include "devioctl.h" +#include "strsafe.h" + +#pragma warning(push) +#pragma warning(disable:4200) // +#pragma warning(disable:4201) // nameless struct/union +#pragma warning(disable:4214) // bit field types other than int + +#include <setupapi.h> +#include <basetyps.h> +#include "usbdi.h" +#include "public.h" + +#pragma warning(pop) + +#define WHILE(a) \ +while(__pragma(warning(disable:4127)) a __pragma(warning(disable:4127))) + +#define countof(x) (sizeof(x) / sizeof(x[0])) + +#define MAX_DEVPATH_LENGTH 256 +#define NUM_ASYNCH_IO 100 +#define BUFFER_SIZE 1024 +#define READER_TYPE 1 +#define WRITER_TYPE 2 + +BOOL G_fDumpUsbConfig = FALSE; // flags set in response to console command line switches +BOOL G_fDumpReadData = FALSE; +BOOL G_fRead = FALSE; +BOOL G_fWrite = FALSE; +BOOL G_fPlayWithDevice = FALSE; +BOOL G_fPerformAsyncIo = FALSE; +ULONG G_IterationCount = 1; //count of iterations of the test we are to perform +int G_WriteLen = 512; // #bytes to write +int G_ReadLen = 512; // #bytes to read +PCWSTR G_SendFileName = NULL; +ULONG G_SendFileInterval = 1; + +BOOL +DumpUsbConfig( // defined in dump.c + ); + +typedef enum _INPUT_FUNCTION { + LIGHT_ONE_BAR = 1, + CLEAR_ONE_BAR, + LIGHT_ALL_BARS, + CLEAR_ALL_BARS, + GET_BAR_GRAPH_LIGHT_STATE, + GET_SWITCH_STATE, + GET_SWITCH_STATE_AS_INTERRUPT_MESSAGE, + GET_7_SEGEMENT_STATE, + SET_7_SEGEMENT_STATE, + RESET_DEVICE, + REENUMERATE_DEVICE, +} INPUT_FUNCTION; + +_Success_ (return != FALSE) +BOOL +GetDevicePath( + IN LPGUID InterfaceGuid, + _Out_writes_(BufLen) PWSTR DevicePath, + _In_ size_t BufLen + ) +{ + HDEVINFO HardwareDeviceInfo; + SP_DEVICE_INTERFACE_DATA DeviceInterfaceData; + PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData = NULL; + ULONG Length, RequiredLength = 0; + BOOL bResult; + HRESULT hr; + + HardwareDeviceInfo = SetupDiGetClassDevs( + InterfaceGuid, + NULL, + NULL, + (DIGCF_PRESENT | DIGCF_DEVICEINTERFACE)); + + if (HardwareDeviceInfo == INVALID_HANDLE_VALUE) { + wprintf(L"SetupDiGetClassDevs failed!\n"); + return FALSE; + } + + DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); + + bResult = SetupDiEnumDeviceInterfaces(HardwareDeviceInfo, + 0, + InterfaceGuid, + 0, + &DeviceInterfaceData); + + if (bResult == FALSE) { + + LPVOID lpMsgBuf; + + if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPWSTR) &lpMsgBuf, + 0, + NULL + )) { + + printf("SetupDiEnumDeviceInterfaces failed: %s", (LPSTR)lpMsgBuf); + LocalFree(lpMsgBuf); + } + + SetupDiDestroyDeviceInfoList(HardwareDeviceInfo); + return FALSE; + } + + SetupDiGetDeviceInterfaceDetail( + HardwareDeviceInfo, + &DeviceInterfaceData, + NULL, + 0, + &RequiredLength, + NULL + ); + + DeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) + LocalAlloc(LMEM_FIXED, RequiredLength); + + if (DeviceInterfaceDetailData == NULL) { + SetupDiDestroyDeviceInfoList(HardwareDeviceInfo); + wprintf(L"Failed to allocate memory.\n"); + return FALSE; + } + + DeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); + + Length = RequiredLength; + + bResult = SetupDiGetDeviceInterfaceDetail( + HardwareDeviceInfo, + &DeviceInterfaceData, + DeviceInterfaceDetailData, + Length, + &RequiredLength, + NULL); + + if (bResult == FALSE) { + + LPVOID lpMsgBuf; + + if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPWSTR) &lpMsgBuf, + 0, + NULL)) { + + printf("Error in SetupDiGetDeviceInterfaceDetail: %s\n", (LPSTR)lpMsgBuf); + LocalFree(lpMsgBuf); + } + + SetupDiDestroyDeviceInfoList(HardwareDeviceInfo); + LocalFree(DeviceInterfaceDetailData); + return FALSE; + } + + hr = StringCchCopy(DevicePath, + BufLen, + DeviceInterfaceDetailData->DevicePath); + if (FAILED(hr)) { + SetupDiDestroyDeviceInfoList(HardwareDeviceInfo); + LocalFree(DeviceInterfaceDetailData); + return FALSE; + } + + SetupDiDestroyDeviceInfoList(HardwareDeviceInfo); + LocalFree(DeviceInterfaceDetailData); + + return TRUE; + +} + + +HANDLE +OpenDevice( + _In_ BOOL Synchronous + ) + +/*++ +Routine Description: + + Called by main() to open an instance of our device after obtaining its name + +Arguments: + + Synchronous - TRUE, if Device is to be opened for synchronous access. + FALSE, otherwise. + +Return Value: + + Device handle on success else INVALID_HANDLE_VALUE + +--*/ + +{ + HANDLE hDev; + WCHAR completeDeviceName[MAX_DEVPATH_LENGTH]; + + if ( !GetDevicePath( + (LPGUID) &GUID_DEVINTERFACE_OSRUSBFX2, + completeDeviceName, + countof(completeDeviceName)) ) + { + return INVALID_HANDLE_VALUE; + } + + wprintf(L"DeviceName = (%s)\n", completeDeviceName); + + hDev = CreateFile(completeDeviceName, + GENERIC_WRITE | GENERIC_READ, + FILE_SHARE_WRITE | FILE_SHARE_READ, + NULL, // default security + OPEN_EXISTING, + ((Synchronous ? FILE_ATTRIBUTE_NORMAL : FILE_FLAG_OVERLAPPED) | SECURITY_IMPERSONATION), + NULL); + + if (hDev == INVALID_HANDLE_VALUE) { + wprintf(L"Failed to open the device, error - %d", GetLastError()); + } else { + wprintf(L"Opened the device successfully.\n"); + } + + return hDev; +} + + + +VOID +Usage() + +/*++ +Routine Description: + + Called by main() to dump usage info to the console when + the app is called with no parms or with an invalid parm + +Arguments: + + None + +Return Value: + + None + +--*/ + +{ + wprintf(L"Usage for osrusbfx2 testapp:\n"); + wprintf(L"-r <n> where n is number of bytes to read\n"); + wprintf(L"-w <n> where n is number of bytes to write\n"); + wprintf(L"-c <n> where n is number of iterations (default = 1)\n"); + wprintf(L"-v <verbose> -- dumps read data\n"); + wprintf(L"-p to control bar LEDs, seven segment, and dip switch\n"); + wprintf(L"-a to perform asynchronous I/O\n"); + wprintf(L"-u to dump USB configuration and pipe info \n"); + wprintf(L"-f <filename> [interval-seconds] to send a text file to the seven-segment display (UMDF only)\n"); + + return; +} + + +void +Parse( + _In_ int argc, + _In_reads_(argc) LPWSTR *argv + ) + +/*++ +Routine Description: + + Called by main() to parse command line parms + +Arguments: + + argc and argv that was passed to main() + +Return Value: + + Sets global flags as per user function request + +--*/ + +{ + int i; + PWSTR endchar; + + if ( argc < 2 ) // give usage if invoked with no parms + Usage(); + + for (i=0; i<argc; i++) { + if (argv[i][0] == L'-' || + argv[i][0] == L'/') { + switch(argv[i][1]) { + case L'r': + case L'R': + if (i+1 >= argc) { + Usage(); + exit(1); + } + else { + G_ReadLen = wcstoul(&argv[i+1][0], &endchar, 10); + G_fRead = TRUE; + } + i++; + break; + case L'w': + case L'W': + if (i+1 >= argc) { + Usage(); + exit(1); + } + else { + G_WriteLen = wcstoul(&argv[i+1][0], &endchar, 10); + G_fWrite = TRUE; + } + i++; + break; + case L'c': + case L'C': + if (i+1 >= argc) { + Usage(); + exit(1); + } + else { + G_IterationCount = wcstoul(&argv[i+1][0], &endchar, 10); + } + i++; + break; + case L'f': + case L'F': + if (i+1 >= argc) { + Usage(); + exit(1); + } + else { + G_SendFileName = argv[i+1]; + } + + i++; + + if (i+1 < argc) { + G_SendFileInterval = wcstoul(&argv[i+1][0], &endchar, 10); + } + i++; + + break; + case L'u': + case L'U': + G_fDumpUsbConfig = TRUE; + break; + case L'p': + case L'P': + G_fPlayWithDevice = TRUE; + break; + case L'a': + case L'A': + G_fPerformAsyncIo = TRUE; + break; + case L'v': + case L'V': + G_fDumpReadData = TRUE; + break; + default: + Usage(); + } + } + } +} + +BOOL +Compare_Buffs( + _In_reads_bytes_(length) PVOID *buff1, + _In_reads_bytes_(length) PVOID *buff2, + _In_ int length + ) +/*++ +Routine Description: + + Called to verify read and write buffers match for loopback test + +Arguments: + + buffers to compare and length + +Return Value: + + TRUE if buffers match, else FALSE + +--*/ +{ + int ok = 1; + + if (memcmp(buff1, buff2, length )) { + // Edi, and Esi point to the mismatching char and ecx indicates the + // remaining length. + ok = 0; + } + + return ok; +} + +#define NPERLN 8 + +VOID +Dump( + UCHAR *b, + int len +) + +/*++ +Routine Description: + + Called to do formatted ascii dump to console of the io buffer + +Arguments: + + buffer and length + +Return Value: + + none + +--*/ + +{ + ULONG i; + ULONG longLen = (ULONG)len / sizeof( ULONG ); + PULONG pBuf = (PULONG) b; + + // dump an ordinal ULONG for each sizeof(ULONG)'th byte + wprintf(L"\n****** BEGIN DUMP LEN decimal %d, 0x%x\n", len,len); + for (i=0; i<longLen; i++) { + wprintf(L"%04X ", *pBuf++); + if (i % NPERLN == (NPERLN - 1)) { + wprintf(L"\n"); + } + } + if (i % NPERLN != 0) { + wprintf(L"\n"); + } + wprintf(L"\n****** END DUMP LEN decimal %d, 0x%x\n", len,len); +} + + +BOOL +PlayWithDevice() +{ + HANDLE deviceHandle; + DWORD code; + ULONG index; + INPUT_FUNCTION function; + BAR_GRAPH_STATE barGraphState; + ULONG bar; + SWITCH_STATE switchState; + UCHAR sevenSegment = 0; + UCHAR i; + BOOL result = FALSE; + + deviceHandle = OpenDevice(FALSE); + + if (deviceHandle == INVALID_HANDLE_VALUE) { + + wprintf(L"Unable to find any OSR FX2 devices!\n"); + + return FALSE; + + } + + // + // Infinitely print out the list of choices, ask for input, process + // the request + // + WHILE(TRUE) { + + printf ("\nUSBFX TEST -- Functions:\n\n"); + printf ("\t1. Light Bar\n"); + printf ("\t2. Clear Bar\n"); + printf ("\t3. Light entire Bar graph\n"); + printf ("\t4. Clear entire Bar graph\n"); + printf ("\t5. Get bar graph state\n"); + printf ("\t6. Get Switch state\n"); + printf ("\t7. Get Switch Interrupt Message\n"); + printf ("\t8. Get 7 segment state\n"); + printf ("\t9. Set 7 segment state\n"); + printf ("\t10. Reset the device\n"); + printf ("\t11. Reenumerate the device\n"); + printf ("\n\t0. Exit\n"); + printf ("\n\tSelection: "); + + if (scanf_s ("%d", &function) <= 0) { + + wprintf(L"Error reading input!\n"); + goto Error; + + } + + switch(function) { + + case LIGHT_ONE_BAR: + + wprintf(L"Which Bar (input number 1 thru 8)?\n"); + if (scanf_s ("%d", &bar) <= 0) { + + wprintf(L"Error reading input!\n"); + goto Error; + + } + + if(bar == 0 || bar > 8){ + wprintf(L"Invalid bar number!\n"); + goto Error; + } + + bar--; // normalize to 0 to 7 + + barGraphState.BarsAsUChar = 1 << (UCHAR)bar; + + if (!DeviceIoControl(deviceHandle, + IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY, + &barGraphState, // Ptr to InBuffer + sizeof(BAR_GRAPH_STATE), // Length of InBuffer + NULL, // Ptr to OutBuffer + 0, // Length of OutBuffer + &index, // BytesReturned + 0)) { // Ptr to Overlapped structure + + code = GetLastError(); + + wprintf(L"DeviceIoControl failed with error 0x%x\n", code); + + goto Error; + } + + break; + + case CLEAR_ONE_BAR: + + + wprintf(L"Which Bar (input number 1 thru 8)?\n"); + if (scanf_s ("%d", &bar) <= 0) { + + wprintf(L"Error reading input!\n"); + goto Error; + + } + + if(bar == 0 || bar > 8){ + wprintf(L"Invalid bar number!\n"); + goto Error; + } + + bar--; + + // + // Read the current state + // + if (!DeviceIoControl(deviceHandle, + IOCTL_OSRUSBFX2_GET_BAR_GRAPH_DISPLAY, + NULL, // Ptr to InBuffer + 0, // Length of InBuffer + &barGraphState, // Ptr to OutBuffer + sizeof(BAR_GRAPH_STATE), // Length of OutBuffer + &index, // BytesReturned + 0)) { // Ptr to Overlapped structure + + code = GetLastError(); + + wprintf(L"DeviceIoControl failed with error 0x%x\n", code); + + goto Error; + } + + if (barGraphState.BarsAsUChar & (1 << bar)) { + + wprintf(L"Bar is set...Clearing it\n"); + barGraphState.BarsAsUChar &= ~(1 << bar); + + if (!DeviceIoControl(deviceHandle, + IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY, + &barGraphState, // Ptr to InBuffer + sizeof(BAR_GRAPH_STATE), // Length of InBuffer + NULL, // Ptr to OutBuffer + 0, // Length of OutBuffer + &index, // BytesReturned + 0)) { // Ptr to Overlapped structure + + code = GetLastError(); + + wprintf(L"DeviceIoControl failed with error 0x%x\n", code); + + goto Error; + + } + + } else { + + wprintf(L"Bar not set.\n"); + + } + + break; + + case LIGHT_ALL_BARS: + + barGraphState.BarsAsUChar = 0xFF; + + if (!DeviceIoControl(deviceHandle, + IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY, + &barGraphState, // Ptr to InBuffer + sizeof(BAR_GRAPH_STATE), // Length of InBuffer + NULL, // Ptr to OutBuffer + 0, // Length of OutBuffer + &index, // BytesReturned + 0)) { // Ptr to Overlapped structure + + code = GetLastError(); + + wprintf(L"DeviceIoControl failed with error 0x%x\n", code); + + goto Error; + } + + break; + + case CLEAR_ALL_BARS: + + barGraphState.BarsAsUChar = 0; + + if (!DeviceIoControl(deviceHandle, + IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY, + &barGraphState, // Ptr to InBuffer + sizeof(BAR_GRAPH_STATE), // Length of InBuffer + NULL, // Ptr to OutBuffer + 0, // Length of OutBuffer + &index, // BytesReturned + 0)) { // Ptr to Overlapped structure + + code = GetLastError(); + + wprintf(L"DeviceIoControl failed with error 0x%x\n", code); + + goto Error; + } + + break; + + + case GET_BAR_GRAPH_LIGHT_STATE: + + barGraphState.BarsAsUChar = 0; + + if (!DeviceIoControl(deviceHandle, + IOCTL_OSRUSBFX2_GET_BAR_GRAPH_DISPLAY, + NULL, // Ptr to InBuffer + 0, // Length of InBuffer + &barGraphState, // Ptr to OutBuffer + sizeof(BAR_GRAPH_STATE), // Length of OutBuffer + &index, // BytesReturned + 0)) { // Ptr to Overlapped structure + + code = GetLastError(); + + wprintf(L"DeviceIoControl failed with error 0x%x\n", code); + + goto Error; + } + + wprintf(L"Bar Graph: \n"); + wprintf(L" Bar8 is %s\n", barGraphState.Bar8 ? L"ON" : L"OFF"); + wprintf(L" Bar7 is %s\n", barGraphState.Bar7 ? L"ON" : L"OFF"); + wprintf(L" Bar6 is %s\n", barGraphState.Bar6 ? L"ON" : L"OFF"); + wprintf(L" Bar5 is %s\n", barGraphState.Bar5 ? L"ON" : L"OFF"); + wprintf(L" Bar4 is %s\n", barGraphState.Bar4 ? L"ON" : L"OFF"); + wprintf(L" Bar3 is %s\n", barGraphState.Bar3 ? L"ON" : L"OFF"); + wprintf(L" Bar2 is %s\n", barGraphState.Bar2 ? L"ON" : L"OFF"); + wprintf(L" Bar1 is %s\n", barGraphState.Bar1 ? L"ON" : L"OFF"); + + break; + + case GET_SWITCH_STATE: + + switchState.SwitchesAsUChar = 0; + + if (!DeviceIoControl(deviceHandle, + IOCTL_OSRUSBFX2_READ_SWITCHES, + NULL, // Ptr to InBuffer + 0, // Length of InBuffer + &switchState, // Ptr to OutBuffer + sizeof(SWITCH_STATE), // Length of OutBuffer + &index, // BytesReturned + 0)) { // Ptr to Overlapped structure + + code = GetLastError(); + + wprintf(L"DeviceIoControl failed with error 0x%x\n", code); + + goto Error; + } + + wprintf(L"Switches: \n"); + wprintf(L" Switch8 is %s\n", switchState.Switch8 ? L"ON" : L"OFF"); + wprintf(L" Switch7 is %s\n", switchState.Switch7 ? L"ON" : L"OFF"); + wprintf(L" Switch6 is %s\n", switchState.Switch6 ? L"ON" : L"OFF"); + wprintf(L" Switch5 is %s\n", switchState.Switch5 ? L"ON" : L"OFF"); + wprintf(L" Switch4 is %s\n", switchState.Switch4 ? L"ON" : L"OFF"); + wprintf(L" Switch3 is %s\n", switchState.Switch3 ? L"ON" : L"OFF"); + wprintf(L" Switch2 is %s\n", switchState.Switch2 ? L"ON" : L"OFF"); + wprintf(L" Switch1 is %s\n", switchState.Switch1 ? L"ON" : L"OFF"); + + break; + + case GET_SWITCH_STATE_AS_INTERRUPT_MESSAGE: + + switchState.SwitchesAsUChar = 0; + + if (!DeviceIoControl(deviceHandle, + IOCTL_OSRUSBFX2_GET_INTERRUPT_MESSAGE, + NULL, // Ptr to InBuffer + 0, // Length of InBuffer + &switchState, // Ptr to OutBuffer + sizeof(switchState), // Length of OutBuffer + &index, // BytesReturned + 0)) { // Ptr to Overlapped structure + + code = GetLastError(); + + wprintf(L"DeviceIoControl failed with error 0x%x\n", code); + + goto Error; + } + + wprintf(L"Switches: %d\n",index); + wprintf(L" Switch8 is %s\n", switchState.Switch8 ? L"ON" : L"OFF"); + wprintf(L" Switch7 is %s\n", switchState.Switch7 ? L"ON" : L"OFF"); + wprintf(L" Switch6 is %s\n", switchState.Switch6 ? L"ON" : L"OFF"); + wprintf(L" Switch5 is %s\n", switchState.Switch5 ? L"ON" : L"OFF"); + wprintf(L" Switch4 is %s\n", switchState.Switch4 ? L"ON" : L"OFF"); + wprintf(L" Switch3 is %s\n", switchState.Switch3 ? L"ON" : L"OFF"); + wprintf(L" Switch2 is %s\n", switchState.Switch2 ? L"ON" : L"OFF"); + wprintf(L" Switch1 is %s\n", switchState.Switch1 ? L"ON" : L"OFF"); + + break; + + case GET_7_SEGEMENT_STATE: + + sevenSegment = 0; + + if (!DeviceIoControl(deviceHandle, + IOCTL_OSRUSBFX2_GET_7_SEGMENT_DISPLAY, + NULL, // Ptr to InBuffer + 0, // Length of InBuffer + &sevenSegment, // Ptr to OutBuffer + sizeof(UCHAR), // Length of OutBuffer + &index, // BytesReturned + 0)) { // Ptr to Overlapped structure + + code = GetLastError(); + + wprintf(L"DeviceIoControl failed with error 0x%x\n", code); + + goto Error; + } + + wprintf(L"7 Segment mask: 0x%x\n", sevenSegment); + break; + + case SET_7_SEGEMENT_STATE: + + for (i = 0; i < 8; i++) { + + sevenSegment = 1 << i; + + if (!DeviceIoControl(deviceHandle, + IOCTL_OSRUSBFX2_SET_7_SEGMENT_DISPLAY, + &sevenSegment, // Ptr to InBuffer + sizeof(UCHAR), // Length of InBuffer + NULL, // Ptr to OutBuffer + 0, // Length of OutBuffer + &index, // BytesReturned + 0)) { // Ptr to Overlapped structure + + code = GetLastError(); + + wprintf(L"DeviceIoControl failed with error 0x%x\n", code); + + goto Error; + } + + wprintf(L"This is %d\n", i); + Sleep(500); + + } + + wprintf(L"7 Segment mask: 0x%x\n", sevenSegment); + break; + + case RESET_DEVICE: + + wprintf(L"Reset the device\n"); + + if (!DeviceIoControl(deviceHandle, + IOCTL_OSRUSBFX2_RESET_DEVICE, + NULL, // Ptr to InBuffer + 0, // Length of InBuffer + NULL, // Ptr to OutBuffer + 0, // Length of OutBuffer + &index, // BytesReturned + NULL)) { // Ptr to Overlapped structure + + code = GetLastError(); + + wprintf(L"DeviceIoControl failed with error 0x%x\n", code); + + goto Error; + } + + break; + + case REENUMERATE_DEVICE: + + wprintf(L"Re-enumerate the device\n"); + + if (!DeviceIoControl(deviceHandle, + IOCTL_OSRUSBFX2_REENUMERATE_DEVICE, + NULL, // Ptr to InBuffer + 0, // Length of InBuffer + NULL, // Ptr to OutBuffer + 0, // Length of OutBuffer + &index, // BytesReturned + NULL)) { // Ptr to Overlapped structure + + code = GetLastError(); + + wprintf(L"DeviceIoControl failed with error 0x%x\n", code); + + goto Error; + } + + // + // Close the handle to the device and exit out so that + // the driver can unload when the device is surprise-removed + // and reenumerated. + // + default: + + result = TRUE; + goto Error; + + } + + } // end of while loop + +Error: + + CloseHandle(deviceHandle); + return result; + +} + +BOOL +SendFileToDevice( + _In_ PCWSTR FileName + ) +{ + HANDLE deviceHandle; + + struct + { + USHORT delay; + WCHAR buffer[MAX_PATH + 1]; + } playback; + + ULONG bufferCch; + + DWORD code; + BOOL result = FALSE; + + // + // Open a handle to the device. + // + + deviceHandle = OpenDevice(FALSE); + + if (deviceHandle == INVALID_HANDLE_VALUE) { + + wprintf(L"Unable to find any OSR FX2 devices!\n"); + + return FALSE; + + } + + // + // Convert the file name from relative to absolute. + // + + bufferCch = GetFullPathName(FileName, + countof(playback.buffer), + playback.buffer, + NULL); + + if (bufferCch == 0) + { + wprintf(L"Error getting full path name for %s - %d\n", + FileName, + GetLastError()); + goto Error; + } + + if ((G_SendFileInterval * 1000) >= ((USHORT) 0xffff)) + { + wprintf(L"Error - delay is too large. Remember that it's in terms of seconds.\n"); + goto Error; + } + + playback.delay = (USHORT) (G_SendFileInterval * 1000); + + if (!DeviceIoControl(deviceHandle, + IOCTL_OSRUSBFX2_PLAY_FILE, + &playback, + sizeof(playback), + NULL, + 0, + &bufferCch, + 0)) { + + code = GetLastError(); + + wprintf(L"DeviceIoControl failed with error 0x%x\n", code); + + goto Error; + } + + result = TRUE; + +Error: + + CloseHandle(deviceHandle); + return result; +} + +ULONG +AsyncIo( + PVOID ThreadParameter + ) +{ + HANDLE hDevice = INVALID_HANDLE_VALUE; + HANDLE hCompletionPort = NULL; + OVERLAPPED *pOvList = NULL; + PUCHAR buf = NULL; + ULONG_PTR i; + ULONG ioType = (ULONG)(ULONG_PTR)ThreadParameter; + ULONG error; + + hDevice = OpenDevice(FALSE); + + if (hDevice == INVALID_HANDLE_VALUE) { + wprintf(L"Cannot open device %d\n", GetLastError()); + goto Error; + } + + hCompletionPort = CreateIoCompletionPort(hDevice, NULL, 1, 0); + + if (hCompletionPort == NULL) { + wprintf(L"Cannot open completion port %d \n",GetLastError()); + goto Error; + } + + pOvList = (OVERLAPPED *)malloc(NUM_ASYNCH_IO * sizeof(OVERLAPPED)); + + if (pOvList == NULL) { + wprintf(L"Cannot allocate overlapped array \n"); + goto Error; + } + + buf = (PUCHAR)malloc(NUM_ASYNCH_IO * BUFFER_SIZE); + + if (buf == NULL) { + wprintf(L"Cannot allocate buffer \n"); + goto Error; + } + + ZeroMemory(pOvList, NUM_ASYNCH_IO * sizeof(OVERLAPPED)); + ZeroMemory(buf, NUM_ASYNCH_IO * BUFFER_SIZE); + + // + // Issue asynch I/O + // + + for (i = 0; i < NUM_ASYNCH_IO; i++) { + if (ioType == READER_TYPE) { + if ( ReadFile( hDevice, + buf + (i* BUFFER_SIZE), + BUFFER_SIZE, + NULL, + &pOvList[i]) == 0) { + + error = GetLastError(); + if (error != ERROR_IO_PENDING) { + wprintf(L" %Iu th read failed %d \n",i, GetLastError()); + goto Error; + } + } + + } else { + if ( WriteFile( hDevice, + buf + (i* BUFFER_SIZE), + BUFFER_SIZE, + NULL, + &pOvList[i]) == 0) { + error = GetLastError(); + if (error != ERROR_IO_PENDING) { + wprintf(L" %Iu th write failed %d \n",i, GetLastError()); + goto Error; + } + } + } + } + + // + // Wait for the I/Os to complete. If one completes then reissue the I/O + // + + WHILE (1) { + OVERLAPPED *completedOv; + ULONG_PTR key; + ULONG numberOfBytesTransferred; + + if ( GetQueuedCompletionStatus(hCompletionPort, &numberOfBytesTransferred, + &key, &completedOv, INFINITE) == 0) { + wprintf(L"GetQueuedCompletionStatus failed %d\n", GetLastError()); + goto Error; + } + + // + // Read successfully completed. Issue another one. + // + + if (ioType == READER_TYPE) { + + i = completedOv - pOvList; + + wprintf(L"Number of bytes read by request number %Iu is %d\n", + i, numberOfBytesTransferred); + + if ( ReadFile( hDevice, + buf + (i * BUFFER_SIZE), + BUFFER_SIZE, + NULL, + completedOv) == 0) { + error = GetLastError(); + if (error != ERROR_IO_PENDING) { + wprintf(L"%Iu th Read failed %d \n", i, GetLastError()); + goto Error; + } + } + } else { + + i = completedOv - pOvList; + + wprintf(L"Number of bytes written by request number %Iu is %d\n", + i, numberOfBytesTransferred); + + if ( WriteFile( hDevice, + buf + (i * BUFFER_SIZE), + BUFFER_SIZE, + NULL, + completedOv) == 0) { + error = GetLastError(); + if (error != ERROR_IO_PENDING) { + wprintf(L"%Iu th write failed %d \n", i, GetLastError()); + goto Error; + } + } + } + } + +Error: + if (hDevice != INVALID_HANDLE_VALUE) { + CloseHandle(hDevice); + } + + if (hCompletionPort) { + CloseHandle(hCompletionPort); + } + + if (pOvList) { + free(pOvList); + } + if (buf) { + free(buf); + } + + return 1; + +} + + +int +_cdecl +wmain( + _In_ int argc, + _In_reads_(argc) LPWSTR *argv + ) +/*++ +Routine Description: + + Entry point to rwbulk.exe + Parses cmdline, performs user-requested tests + +Arguments: + + argc, argv standard console 'c' app arguments + +Return Value: + + Zero + +--*/ + +{ + PWSTR * pinBuf = NULL; + PWSTR * poutBuf = NULL; + int nBytesRead; + int nBytesWrite; + int ok; + int retValue = 0; + UINT success; + HANDLE hRead = INVALID_HANDLE_VALUE; + HANDLE hWrite = INVALID_HANDLE_VALUE; + ULONG fail = 0L; + ULONG i; + + + Parse(argc, argv ); + + // + // dump USB configuation and pipe info + // + if (G_fDumpUsbConfig) { + DumpUsbConfig(); + } + + if (G_fPlayWithDevice) { + PlayWithDevice(); + goto exit; + } + + if (G_SendFileName != NULL) + { + SendFileToDevice(G_SendFileName); + goto exit; + } + + if (G_fPerformAsyncIo) { + HANDLE th1; + + // + // Create a reader thread + // + th1 = CreateThread( NULL, // Default Security Attrib. + 0, // Initial Stack Size, + AsyncIo, // Thread Func + (LPVOID)READER_TYPE, + 0, // Creation Flags + NULL ); // Don't need the Thread Id. + + if (th1 == NULL) { + wprintf(L"Couldn't create reader thread - error %d\n", GetLastError()); + retValue = 1; + goto exit; + } + + // + // Use this thread for peforming write. + // + AsyncIo((PVOID)WRITER_TYPE); + + goto exit; + } + + // + // doing a read, write, or both test + // + if ((G_fRead) || (G_fWrite)) { + + if (G_fRead) { + if ( G_fDumpReadData ) { // round size to sizeof ULONG for readable dumping + while( G_ReadLen % sizeof( ULONG ) ) { + G_ReadLen++; + } + } + + // + // open the output file + // + hRead = OpenDevice(TRUE); + if(hRead == INVALID_HANDLE_VALUE) { + retValue = 1; + goto exit; + } + + pinBuf = malloc(G_ReadLen); + } + + if (G_fWrite) { + if ( G_fDumpReadData ) { // round size to sizeof ULONG for readable dumping + while( G_WriteLen % sizeof( ULONG ) ) { + G_WriteLen++; + } + } + + // + // open the output file + // + hWrite = OpenDevice(TRUE); + if(hWrite == INVALID_HANDLE_VALUE) { + retValue = 1; + goto exit; + } + + poutBuf = malloc(G_WriteLen); + } + + for (i = 0; i < G_IterationCount; i++) { + ULONG j; + + if (G_fWrite && poutBuf && hWrite != INVALID_HANDLE_VALUE) { + + PULONG pOut = (PULONG) poutBuf; + ULONG numLongs = G_WriteLen / sizeof( ULONG ); + + // + // put some data in the output buffer + // + for (j=0; j<numLongs; j++) { + *(pOut+j) = j; + } + + // + // send the write + // + success = WriteFile(hWrite, poutBuf, G_WriteLen, (PULONG) &nBytesWrite, NULL); + if(success == 0) { + wprintf(L"WriteFile failed - error %d\n", GetLastError()); + retValue = 1; + goto exit; + } + wprintf(L"Write (%04.4d) : request %06.6d bytes -- %06.6d bytes written\n", + i, G_WriteLen, nBytesWrite); + + assert(nBytesWrite == G_WriteLen); + } + + if (G_fRead && pinBuf) { + + success = ReadFile(hRead, pinBuf, G_ReadLen, (PULONG) &nBytesRead, NULL); + if(success == 0) { + wprintf(L"ReadFile failed - error %d\n", GetLastError()); + retValue = 1; + goto exit; + } + + wprintf(L"Read (%04.4d) : request %06.6d bytes -- %06.6d bytes read\n", + i, G_ReadLen, nBytesRead); + + if (G_fWrite) { + + // + // validate the input buffer against what + // we sent to the 82930 (loopback test) + // + + ok = Compare_Buffs(pinBuf, poutBuf, nBytesRead); + + if( G_fDumpReadData ) { + wprintf(L"Dumping read buffer\n"); + Dump( (PUCHAR) pinBuf, nBytesRead ); + wprintf(L"Dumping write buffer\n"); + Dump( (PUCHAR) poutBuf, nBytesRead ); + } + assert(ok); + + if(ok != 1) { + fail++; + } + + assert(G_ReadLen == G_WriteLen); + assert(nBytesRead == G_ReadLen); + } + } + } + + } + +exit: + + if (pinBuf) { + free(pinBuf); + } + + if (poutBuf) { + free(poutBuf); + } + + // close devices if needed + if (hRead != INVALID_HANDLE_VALUE) { + CloseHandle(hRead); + } + + if (hWrite != INVALID_HANDLE_VALUE) { + CloseHandle(hWrite); + } + + return retValue; +} + + + + diff --git a/usb/wdf_osrfx2_lab/umdf/exe/testapp.rc b/usb/wdf_osrfx2_lab/umdf/exe/testapp.rc new file mode 100644 index 00000000..28dd29d7 --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/exe/testapp.rc @@ -0,0 +1,13 @@ +#include <windows.h> + +#include <ntverp.h> + +#define VER_FILETYPE VFT_DLL +#define VER_FILESUBTYPE VFT2_UNKNOWN +#define VER_FILEDESCRIPTION_STR "OSRUSBFX2 Bulk & Isoch Read and Write test App for UMDF" +#define VER_INTERNALNAME_STR "WudfOsrUsbFx2Test.exe" +#define VER_ORIGINALFILENAME_STR "WudfOsrUsbFx2Test.exe" + +#include <common.ver> + + diff --git a/usb/wdf_osrfx2_lab/umdf/inc/WUDFOsrUsbPublic.h b/usb/wdf_osrfx2_lab/umdf/inc/WUDFOsrUsbPublic.h new file mode 100644 index 00000000..6681fa14 --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/inc/WUDFOsrUsbPublic.h @@ -0,0 +1,32 @@ +/*++ + +Copyright (c) Microsoft Corporation, All Rights Reserved + +Module Name: + + WUDFOsrUsbPublic.h + +Abstract: + + This module contains the common declarations shared by driver + and user applications for the UMDF OSR device sample. + + Note that this driver does NOT use the same device interface GUID + as the KMDF OSR USB sample. + +Environment: + + user and kernel + +--*/ + +#pragma once + +// +// Define an Interface Guid so that app can find the device and talk to it. +// + +// {573E8C73-0CB4-4471-A1BF-FAB26C31D384} +DEFINE_GUID(GUID_DEVINTERFACE_OSRUSBFX2, + 0x573e8c73, 0xcb4, 0x4471, 0xa1, 0xbf, 0xfa, 0xb2, 0x6c, 0x31, 0xd3, 0x84); + diff --git a/usb/wdf_osrfx2_lab/umdf/inc/list.h b/usb/wdf_osrfx2_lab/umdf/inc/list.h new file mode 100644 index 00000000..38d0b1e9 --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/inc/list.h @@ -0,0 +1,77 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + list.h + +Abstract: + + This module contains doubly linked list macros + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once + + +FORCEINLINE +VOID +InitializeListHead( + IN PLIST_ENTRY ListHead + ) +{ + ListHead->Flink = ListHead->Blink = ListHead; +} + +FORCEINLINE +BOOLEAN +RemoveEntryList( + IN PLIST_ENTRY Entry + ) +{ + PLIST_ENTRY Blink; + PLIST_ENTRY Flink; + + Flink = Entry->Flink; + Blink = Entry->Blink; + Blink->Flink = Flink; + Flink->Blink = Blink; + return (BOOLEAN)(Flink == Blink); +} + +FORCEINLINE +VOID +InsertHeadList( + IN PLIST_ENTRY ListHead, + IN PLIST_ENTRY Entry + ) +{ + PLIST_ENTRY Flink; + + Flink = ListHead->Flink; + Entry->Flink = Flink; + Entry->Blink = ListHead; + Flink->Blink = Entry; + ListHead->Flink = Entry; +} + +FORCEINLINE +VOID +InsertTailList( + IN PLIST_ENTRY ListHead, + IN PLIST_ENTRY Entry + ) +{ + PLIST_ENTRY Blink; + + Blink = ListHead->Blink; + Entry->Flink = ListHead; + Entry->Blink = Blink; + Blink->Flink = Entry; + ListHead->Blink = Entry; +} diff --git a/usb/wdf_osrfx2_lab/umdf/inc/public.h b/usb/wdf_osrfx2_lab/umdf/inc/public.h new file mode 100644 index 00000000..2c3f6805 --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/inc/public.h @@ -0,0 +1,217 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + public.h + +Abstract: + + Public definitions for the OSR_FX2 device operations. + +Environment: + + User & Kernel mode + +--*/ + +#ifndef _PUBLIC_H +#define _PUBLIC_H + +#include <initguid.h> + +#include "WudfOsrUsbPublic.h" + + +// +// Define the structures that will be used by the IOCTL +// interface to the driver +// + +// +// BAR_GRAPH_STATE +// +// BAR_GRAPH_STATE is a bit field structure with each +// bit corresponding to one of the bar graph on the +// OSRFX2 Development Board +// +#include <pshpack1.h> + +#pragma warning( push ) +#pragma warning( disable : 4201 ) // nameless struct/union +#pragma warning( disable : 4214 ) // bit-field type other than int + +typedef struct _BAR_GRAPH_STATE { + + union { + + struct { + // + // Individual bars starting from the + // top of the stack of bars + // + // NOTE: There are actually 10 bars, + // but the very top two do not light + // and are not counted here + // + UCHAR Bar1 : 1; + UCHAR Bar2 : 1; + UCHAR Bar3 : 1; + UCHAR Bar4 : 1; + UCHAR Bar5 : 1; + UCHAR Bar6 : 1; + UCHAR Bar7 : 1; + UCHAR Bar8 : 1; + }; + + // + // The state of all the bar graph as a single + // UCHAR + // + UCHAR BarsAsUChar; + + }; + +}BAR_GRAPH_STATE, *PBAR_GRAPH_STATE; + +// +// SWITCH_STATE +// +// SWITCH_STATE is a bit field structure with each +// bit corresponding to one of the switches on the +// OSRFX2 Development Board +// +typedef struct _SWITCH_STATE { + + union { + struct { + // + // Individual switches starting from the + // left of the set of switches + // + UCHAR Switch1 : 1; + UCHAR Switch2 : 1; + UCHAR Switch3 : 1; + UCHAR Switch4 : 1; + UCHAR Switch5 : 1; + UCHAR Switch6 : 1; + UCHAR Switch7 : 1; + UCHAR Switch8 : 1; + }; + + // + // The state of all the switches as a single + // UCHAR + // + UCHAR SwitchesAsUChar; + + }; + + +}SWITCH_STATE, *PSWITCH_STATE; + +// +// Seven segment display bit values. +// + +// +// Undefine conflicting MFC constant +// +#undef SS_CENTER +#undef SS_LEFT +#undef SS_RIGHT + +#define SS_TOP 0x01 +#define SS_TOP_LEFT 0x40 +#define SS_TOP_RIGHT 0x02 +#define SS_CENTER 0x20 +#define SS_BOTTOM_LEFT 0x10 +#define SS_BOTTOM_RIGHT 0x04 +#define SS_BOTTOM 0x80 +#define SS_DOT 0x08 + +// +// FILE_PLAYBACK +// +// FILE_PLAYBACK structure contains the parameters for the PLAY_FILE I/O Control. +// + +typedef struct _FILE_PLAYBACK +{ + // + // The delay between changes in the display, in milliseconds. + // + + USHORT Delay; + + // + // The data file path. + // + + WCHAR Path[1]; +} FILE_PLAYBACK, *PFILE_PLAYBACK; + +#include <poppack.h> + +#define IOCTL_INDEX 0x800 +#define FILE_DEVICE_OSRUSBFX2 65500U + +#define IOCTL_OSRUSBFX2_GET_CONFIG_DESCRIPTOR CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ + IOCTL_INDEX, \ + METHOD_BUFFERED, \ + FILE_READ_ACCESS) + +#define IOCTL_OSRUSBFX2_RESET_DEVICE CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ + IOCTL_INDEX + 1, \ + METHOD_BUFFERED, \ + FILE_WRITE_ACCESS) + +#define IOCTL_OSRUSBFX2_REENUMERATE_DEVICE CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ + IOCTL_INDEX + 3, \ + METHOD_BUFFERED, \ + FILE_WRITE_ACCESS) + +#define IOCTL_OSRUSBFX2_GET_BAR_GRAPH_DISPLAY CTL_CODE(FILE_DEVICE_OSRUSBFX2,\ + IOCTL_INDEX + 4, \ + METHOD_BUFFERED, \ + FILE_READ_ACCESS) + + +#define IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY CTL_CODE(FILE_DEVICE_OSRUSBFX2,\ + IOCTL_INDEX + 5, \ + METHOD_BUFFERED, \ + FILE_WRITE_ACCESS) + + +#define IOCTL_OSRUSBFX2_READ_SWITCHES CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ + IOCTL_INDEX + 6, \ + METHOD_BUFFERED, \ + FILE_READ_ACCESS) + + +#define IOCTL_OSRUSBFX2_GET_7_SEGMENT_DISPLAY CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ + IOCTL_INDEX + 7, \ + METHOD_BUFFERED, \ + FILE_READ_ACCESS) + + +#define IOCTL_OSRUSBFX2_SET_7_SEGMENT_DISPLAY CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ + IOCTL_INDEX + 8, \ + METHOD_BUFFERED, \ + FILE_WRITE_ACCESS) + +#define IOCTL_OSRUSBFX2_GET_INTERRUPT_MESSAGE CTL_CODE(FILE_DEVICE_OSRUSBFX2,\ + IOCTL_INDEX + 9, \ + METHOD_OUT_DIRECT, \ + FILE_READ_ACCESS) + +#define IOCTL_OSRUSBFX2_PLAY_FILE CTL_CODE(FILE_DEVICE_OSRUSBFX2, \ + IOCTL_INDEX + 10, \ + METHOD_BUFFERED, \ + FILE_WRITE_ACCESS) + +#pragma warning(pop) + +#endif + diff --git a/usb/wdf_osrfx2_lab/umdf/inc/usb_hw.h b/usb/wdf_osrfx2_lab/umdf/inc/usb_hw.h new file mode 100644 index 00000000..d6e983f1 --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/inc/usb_hw.h @@ -0,0 +1,233 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + Usb.h + +Abstract: + + Contains prototypes for interfacing with a USB connected device. These + are copied from the KMDF WDFUSB.H header file (but with the WDF specific + portions removed) + +Environment: + + kernel mode only + +--*/ + +#pragma once + +typedef enum _WINUSB_BMREQUEST_DIRECTION { + BmRequestHostToDevice = BMREQUEST_HOST_TO_DEVICE, + BmRequestDeviceToHost = BMREQUEST_DEVICE_TO_HOST, +} WINUSB_BMREQUEST_DIRECTION; + +typedef enum _WINUSB_BMREQUEST_TYPE { + BmRequestStandard = BMREQUEST_STANDARD, + BmRequestClass = BMREQUEST_CLASS, + BmRequestVendor = BMREQUEST_VENDOR, +} WINUSB_BMREQUEST_TYPE; + +typedef enum _WINUSB_BMREQUEST_RECIPIENT { + BmRequestToDevice = BMREQUEST_TO_DEVICE, + BmRequestToInterface = BMREQUEST_TO_INTERFACE, + BmRequestToEndpoint = BMREQUEST_TO_ENDPOINT, + BmRequestToOther = BMREQUEST_TO_OTHER, +} WINUSB_BMREQUEST_RECIPIENT; + +typedef enum _WINUSB_DEVICE_TRAITS { + WINUSB_DEVICE_TRAIT_SELF_POWERED = 0x00000001, + WINUSB_DEVICE_TRAIT_REMOTE_WAKE_CAPABLE = 0x00000002, + WINUSB_DEVICE_TRAIT_AT_HIGH_SPEED = 0x00000004, +} WINUSB_DEVICE_TRAITS; + +typedef enum _WdfUsbTargetDeviceSelectInterfaceType { + WdfUsbTargetDeviceSelectInterfaceTypeInterface = 0x10, + WdfUsbTargetDeviceSelectInterfaceTypeUrb = 0x11, +} WdfUsbTargetDeviceSelectInterfaceType; + + + +typedef union _WINUSB_CONTROL_SETUP_PACKET { + struct { + union { + #pragma warning(disable:4214) // bit field types other than int + struct { + // + // Valid values are BMREQUEST_TO_DEVICE, BMREQUEST_TO_INTERFACE, + // BMREQUEST_TO_ENDPOINT, BMREQUEST_TO_OTHER + // + BYTE Recipient:2; + + BYTE Reserved:3; + + // + // Valid values are BMREQUEST_STANDARD, BMREQUEST_CLASS, + // BMREQUEST_VENDOR + // + BYTE Type:2; + + // + // Valid values are BMREQUEST_HOST_TO_DEVICE, + // BMREQUEST_DEVICE_TO_HOST + // + BYTE Dir:1; + } Request; + #pragma warning(default:4214) // bit field types other than int + BYTE Byte; + } bm; + + BYTE bRequest; + + union { + struct { + BYTE LowByte; + BYTE HiByte; + } Bytes; + USHORT Value; + } wValue; + + union { + struct { + BYTE LowByte; + BYTE HiByte; + } Bytes; + USHORT Value; + } wIndex; + + USHORT wLength; + } Packet; + + struct { + BYTE Bytes[8]; + } Generic; + + WINUSB_SETUP_PACKET WinUsb; + +} WINUSB_CONTROL_SETUP_PACKET, *PWINUSB_CONTROL_SETUP_PACKET; + +VOID +FORCEINLINE +WINUSB_CONTROL_SETUP_PACKET_INIT( + PWINUSB_CONTROL_SETUP_PACKET Packet, + WINUSB_BMREQUEST_DIRECTION Direction, + WINUSB_BMREQUEST_RECIPIENT Recipient, + BYTE Request, + USHORT Value, + USHORT Index + ) +{ + RtlZeroMemory(Packet, sizeof(WINUSB_CONTROL_SETUP_PACKET)); + + Packet->Packet.bm.Request.Dir = (BYTE) Direction; + Packet->Packet.bm.Request.Type = (BYTE) BmRequestStandard; + Packet->Packet.bm.Request.Recipient = (BYTE) Recipient; + + Packet->Packet.bRequest = Request; + Packet->Packet.wValue.Value = Value; + Packet->Packet.wIndex.Value = Index; + + // Packet->Packet.wLength will be set by the formatting function +} + +VOID +FORCEINLINE +WINUSB_CONTROL_SETUP_PACKET_INIT_CLASS( + PWINUSB_CONTROL_SETUP_PACKET Packet, + WINUSB_BMREQUEST_DIRECTION Direction, + WINUSB_BMREQUEST_RECIPIENT Recipient, + BYTE Request, + USHORT Value, + USHORT Index + ) +{ + RtlZeroMemory(Packet, sizeof(WINUSB_CONTROL_SETUP_PACKET)); + + Packet->Packet.bm.Request.Dir = (BYTE) Direction; + Packet->Packet.bm.Request.Type = (BYTE) BmRequestClass; + Packet->Packet.bm.Request.Recipient = (BYTE) Recipient; + + Packet->Packet.bRequest = Request; + Packet->Packet.wValue.Value = Value; + Packet->Packet.wIndex.Value = Index; + + // Packet->Packet.wLength will be set by the formatting function +} + +VOID +FORCEINLINE +WINUSB_CONTROL_SETUP_PACKET_INIT_VENDOR( + PWINUSB_CONTROL_SETUP_PACKET Packet, + WINUSB_BMREQUEST_DIRECTION Direction, + WINUSB_BMREQUEST_RECIPIENT Recipient, + BYTE Request, + USHORT Value, + USHORT Index + ) +{ + RtlZeroMemory(Packet, sizeof(WINUSB_CONTROL_SETUP_PACKET)); + + Packet->Packet.bm.Request.Dir = (BYTE) Direction; + Packet->Packet.bm.Request.Type = (BYTE) BmRequestVendor; + Packet->Packet.bm.Request.Recipient = (BYTE) Recipient; + + Packet->Packet.bRequest = Request; + Packet->Packet.wValue.Value = Value; + Packet->Packet.wIndex.Value = Index; + + // Packet->Packet.wLength will be set by the formatting function +} + +VOID +FORCEINLINE +WINUSB_CONTROL_SETUP_PACKET_INIT_FEATURE( + PWINUSB_CONTROL_SETUP_PACKET Packet, + WINUSB_BMREQUEST_RECIPIENT BmRequestRecipient, + USHORT FeatureSelector, + USHORT Index, + BOOLEAN SetFeature + ) +{ + RtlZeroMemory(Packet, sizeof(WINUSB_CONTROL_SETUP_PACKET)); + + Packet->Packet.bm.Request.Dir = (BYTE) BmRequestHostToDevice; + Packet->Packet.bm.Request.Type = (BYTE) BmRequestStandard; + Packet->Packet.bm.Request.Recipient = (BYTE) BmRequestRecipient; + + if (SetFeature) { + Packet->Packet.bRequest = USB_REQUEST_SET_FEATURE; + } + else { + Packet->Packet.bRequest = USB_REQUEST_CLEAR_FEATURE; + } + + Packet->Packet.wValue.Value = FeatureSelector; + Packet->Packet.wIndex.Value = Index; + + // Packet->Packet.wLength will be set by the formatting function +} + +VOID +FORCEINLINE +WINUSB_CONTROL_SETUP_PACKET_INIT_GET_STATUS( + PWINUSB_CONTROL_SETUP_PACKET Packet, + WINUSB_BMREQUEST_RECIPIENT BmRequestRecipient, + USHORT Index + ) +{ + RtlZeroMemory(Packet, sizeof(WINUSB_CONTROL_SETUP_PACKET)); + + Packet->Packet.bm.Request.Dir = (BYTE) BmRequestDeviceToHost; + Packet->Packet.bm.Request.Type = (BYTE) BmRequestStandard; + Packet->Packet.bm.Request.Recipient = (BYTE) BmRequestRecipient; + + Packet->Packet.bRequest = USB_REQUEST_GET_STATUS; + Packet->Packet.wIndex.Value = Index; + Packet->Packet.wValue.Value = 0; + + // Packet->Packet.wLength will be set by the formatting function +} + diff --git a/usb/wdf_osrfx2_lab/umdf/step1/Device.cpp b/usb/wdf_osrfx2_lab/umdf/step1/Device.cpp new file mode 100644 index 00000000..68c1245c --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step1/Device.cpp @@ -0,0 +1,235 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved. + +Module Name: + + Device.cpp + +Abstract: + + This module contains the implementation of the UMDF Skeleton sample driver's + device callback object. + + The skeleton sample device does very little. It does not implement either + of the PNP interfaces so once the device is setup, it won't ever get any + callbacks until the device is removed. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#include "internal.h" +#include "initguid.h" +#include "usb_hw.h" + +#include "device.tmh" + + +HRESULT +CMyDevice::CreateInstance( + _In_ IWDFDriver *FxDriver, + _In_ IWDFDeviceInitialize * FxDeviceInit, + _Out_ PCMyDevice *Device + ) +/*++ + + Routine Description: + + This method creates and initializs an instance of the skeleton driver's + device callback object. + + Arguments: + + FxDeviceInit - the settings for the device. + + Device - a location to store the referenced pointer to the device object. + + Return Value: + + Status + +--*/ +{ + PCMyDevice device; + HRESULT hr; + + // + // Allocate a new instance of the device class. + // + + device = new CMyDevice(); + + if (NULL == device) + { + return E_OUTOFMEMORY; + } + + // + // Initialize the instance. + // + + hr = device->Initialize(FxDriver, FxDeviceInit); + + if (SUCCEEDED(hr)) + { + *Device = device; + } + else + { + device->Release(); + } + + return hr; +} + +HRESULT +CMyDevice::Initialize( + _In_ IWDFDriver * FxDriver, + _In_ IWDFDeviceInitialize * FxDeviceInit + ) +/*++ + + Routine Description: + + This method initializes the device callback object and creates the + partner device object. + + The method should perform any device-specific configuration that: + * could fail (these can't be done in the constructor) + * must be done before the partner object is created -or- + * can be done after the partner object is created and which aren't + influenced by any device-level parameters the parent (the driver + in this case) might set. + + Arguments: + + FxDeviceInit - the settings for this device. + + Return Value: + + status. + +--*/ +{ + IWDFDevice *fxDevice = NULL; + + HRESULT hr = S_OK; + + // + // TODO: If you're writing a filter driver then indicate that here. + // + // FxDeviceInit->SetFilter(); + // + + // + // Set no locking unless you need an automatic callbacks synchronization + // + + FxDeviceInit->SetLockingConstraint(None); + + // + // TODO: Any per-device initialization which must be done before + // creating the partner object. + // + + // + // Create a new FX device object and assign the new callback object to + // handle any device level events that occur. + // + + // + // QueryIUnknown references the IUnknown interface that it returns + // (which is the same as referencing the device). We pass that to + // CreateDevice, which takes its own reference if everything works. + // + + if (SUCCEEDED(hr)) + { + IUnknown *unknown = this->QueryIUnknown(); + + hr = FxDriver->CreateDevice(FxDeviceInit, unknown, &fxDevice); + + unknown->Release(); + } + + // + // If that succeeded then set our FxDevice member variable. + // + + if (SUCCEEDED(hr)) + { + m_FxDevice = fxDevice; + + // + // Drop the reference we got from CreateDevice. Since this object + // is partnered with the framework object they have the same + // lifespan - there is no need for an additional reference. + // + + fxDevice->Release(); + } + + return hr; +} + +HRESULT +CMyDevice::Configure( + VOID + ) +/*++ + + Routine Description: + + This method is called after the device callback object has been initialized + and returned to the driver. It would setup the device's queues and their + corresponding callback objects. + + Arguments: + + FxDevice - the framework device object for which we're handling events. + + Return Value: + + status + +--*/ +{ + return S_OK; +} + +HRESULT +CMyDevice::QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ) +/*++ + + Routine Description: + + This method is called to get a pointer to one of the object's callback + interfaces. + + Since the skeleton driver doesn't support any of the device events, this + method simply calls the base class's BaseQueryInterface. + + If the skeleton is extended to include device event interfaces then this + method must be changed to check the IID and return pointers to them as + appropriate. + + Arguments: + + InterfaceId - the interface being requested + + Object - a location to store the interface pointer if successful + + Return Value: + + S_OK or E_NOINTERFACE + +--*/ +{ + return CUnknown::QueryInterface(InterfaceId, Object); +} diff --git a/usb/wdf_osrfx2_lab/umdf/step1/Device.h b/usb/wdf_osrfx2_lab/umdf/step1/Device.h new file mode 100644 index 00000000..24954a6b --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step1/Device.h @@ -0,0 +1,128 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + Device.h + +Abstract: + + This module contains the type definitions for the UMDF Skeleton sample + driver's device callback class. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once +#include "internal.h" + +// +// Class for the iotrace driver. +// + +class CMyDevice : + public CUnknown +{ + +// +// Private data members. +// +private: + // + // Weak reference to framework device + // + + IWDFDevice *m_FxDevice; + +// +// Private methods. +// + +private: + + CMyDevice( + VOID + ) : + m_FxDevice(NULL) + { + } + + HRESULT + Initialize( + _In_ IWDFDriver *FxDriver, + _In_ IWDFDeviceInitialize *FxDeviceInit + ); + + +// +// Public methods +// +public: + + // + // The factory method used to create an instance of this driver. + // + + static + HRESULT + CreateInstance( + _In_ IWDFDriver *FxDriver, + _In_ IWDFDeviceInitialize *FxDeviceInit, + _Out_ PCMyDevice *Device + ); + + IWDFDevice * + GetFxDevice( + VOID + ) + { + return m_FxDevice; + } + + HRESULT + Configure( + VOID + ); + +// +// COM methods +// +public: + + // + // IUnknown methods. + // + + virtual + ULONG + STDMETHODCALLTYPE + AddRef( + VOID + ) + { + return __super::AddRef(); + } + + _At_(this, __drv_freesMem(object)) + virtual + ULONG + STDMETHODCALLTYPE + Release( + VOID + ) + { + return __super::Release(); + } + + virtual + HRESULT + STDMETHODCALLTYPE + QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ); +}; diff --git a/usb/wdf_osrfx2_lab/umdf/step1/Driver.cpp b/usb/wdf_osrfx2_lab/umdf/step1/Driver.cpp new file mode 100644 index 00000000..bac5caca --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step1/Driver.cpp @@ -0,0 +1,220 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved. + +Module Name: + + Driver.cpp + +Abstract: + + This module contains the implementation of the UMDF Skeleton Sample's + core driver callback object. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#include "internal.h" +#include "driver.tmh" + +HRESULT +CMyDriver::CreateInstance( + _Out_ PCMyDriver *Driver + ) +/*++ + + Routine Description: + + This static method is invoked in order to create and initialize a new + instance of the driver class. The caller should arrange for the object + to be released when it is no longer in use. + + Arguments: + + Driver - a location to store a referenced pointer to the new instance + + Return Value: + + S_OK if successful, or error otherwise. + +--*/ +{ + PCMyDriver driver; + HRESULT hr; + + // + // Allocate the callback object. + // + + driver = new CMyDriver(); + + if (NULL == driver) + { + return E_OUTOFMEMORY; + } + + // + // Initialize the callback object. + // + + hr = driver->Initialize(); + + if (SUCCEEDED(hr)) + { + // + // Store a pointer to the new, initialized object in the output + // parameter. + // + + *Driver = driver; + } + else + { + + // + // Release the reference on the driver object to get it to delete + // itself. + // + + driver->Release(); + } + + return hr; +} + +HRESULT +CMyDriver::Initialize( + VOID + ) +/*++ + + Routine Description: + + This method is called to initialize a newly created driver callback object + before it is returned to the creator. Unlike the constructor, the + Initialize method contains operations which could potentially fail. + + Arguments: + + None + + Return Value: + + None + +--*/ +{ + return S_OK; +} + +HRESULT +CMyDriver::QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Interface + ) +/*++ + + Routine Description: + + This method returns a pointer to the requested interface on the callback + object.. + + Arguments: + + InterfaceId - the IID of the interface to query/reference + + Interface - a location to store the interface pointer. + + Return Value: + + S_OK if the interface is supported. + E_NOINTERFACE if it is not supported. + +--*/ +{ + if (IsEqualIID(InterfaceId, __uuidof(IDriverEntry))) + { + *Interface = QueryIDriverEntry(); + return S_OK; + } + else + { + return CUnknown::QueryInterface(InterfaceId, Interface); + } +} + +HRESULT +CMyDriver::OnDeviceAdd( + _In_ IWDFDriver *FxWdfDriver, + _In_ IWDFDeviceInitialize *FxDeviceInit + ) +/*++ + + Routine Description: + + The FX invokes this method when it wants to install our driver on a device + stack. This method creates a device callback object, then calls the Fx + to create an Fx device object and associate the new callback object with + it. + + Arguments: + + FxWdfDriver - the Fx driver object. + + FxDeviceInit - the initialization information for the device. + + Return Value: + + status + +--*/ +{ + HRESULT hr; + + PCMyDevice device = NULL; + + // + // TODO: Do any per-device initialization (reading settings from the + // registry for example) that's necessary before creating your + // device callback object here. Otherwise you can leave such + // initialization to the initialization of the device event + // handler. + // + + // + // Create a new instance of our device callback object + // + + hr = CMyDevice::CreateInstance(FxWdfDriver, FxDeviceInit, &device); + + // + // TODO: Change any per-device settings that the object exposes before + // calling Configure to let it complete its initialization. + // + + // + // If that succeeded then call the device's construct method. This + // allows the device to create any queues or other structures that it + // needs now that the corresponding fx device object has been created. + // + + if (SUCCEEDED(hr)) + { + hr = device->Configure(); + } + + // + // Release the reference on the device callback object now that it's been + // associated with an fx device object. + // + + if (NULL != device) + { + device->Release(); + } + + return hr; +} diff --git a/usb/wdf_osrfx2_lab/umdf/step1/Driver.h b/usb/wdf_osrfx2_lab/umdf/step1/Driver.h new file mode 100644 index 00000000..800ab1d9 --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step1/Driver.h @@ -0,0 +1,149 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + Driver.h + +Abstract: + + This module contains the type definitions for the UMDF Skeleton sample's + driver callback class. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once + +// +// This class handles driver events for the skeleton sample. In particular +// it supports the OnDeviceAdd event, which occurs when the driver is called +// to setup per-device handlers for a new device stack. +// + +class CMyDriver : public CUnknown, public IDriverEntry +{ +// +// Private data members. +// +private: + +// +// Private methods. +// +private: + + // + // Returns a refernced pointer to the IDriverEntry interface. + // + + IDriverEntry * + QueryIDriverEntry( + VOID + ) + { + AddRef(); + return static_cast<IDriverEntry*>(this); + } + + HRESULT + Initialize( + VOID + ); + +// +// Public methods +// +public: + + // + // The factory method used to create an instance of this driver. + // + + static + HRESULT + CreateInstance( + _Out_ PCMyDriver *Driver + ); + +// +// COM methods +// +public: + + // + // IDriverEntry methods + // + + virtual + HRESULT + STDMETHODCALLTYPE + OnInitialize( + _In_ IWDFDriver *FxWdfDriver + ) + { + UNREFERENCED_PARAMETER(FxWdfDriver); + + return S_OK; + } + + virtual + HRESULT + STDMETHODCALLTYPE + OnDeviceAdd( + _In_ IWDFDriver *FxWdfDriver, + _In_ IWDFDeviceInitialize *FxDeviceInit + ); + + virtual + VOID + STDMETHODCALLTYPE + OnDeinitialize( + _In_ IWDFDriver *FxWdfDriver + ) + { + UNREFERENCED_PARAMETER(FxWdfDriver); + + return; + } + + // + // IUnknown methods. + // + // We have to implement basic ones here that redirect to the + // base class becuase of the multiple inheritance. + // + + virtual + ULONG + STDMETHODCALLTYPE + AddRef( + VOID + ) + { + return __super::AddRef(); + } + + _At_(this, __drv_freesMem(object)) + virtual + ULONG + STDMETHODCALLTYPE + Release( + VOID + ) + { + return __super::Release(); + } + + virtual + HRESULT + STDMETHODCALLTYPE + QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ); +}; diff --git a/usb/wdf_osrfx2_lab/umdf/step1/OsrUsbFx2.ctl b/usb/wdf_osrfx2_lab/umdf/step1/OsrUsbFx2.ctl new file mode 100644 index 00000000..4dab56ae --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step1/OsrUsbFx2.ctl @@ -0,0 +1 @@ +da5fbdfd-1eae-4ecf-b426-a3818f325ddb WudfOsrUsbFx2TraceGuid diff --git a/usb/wdf_osrfx2_lab/umdf/step1/OsrUsbFx2.rc b/usb/wdf_osrfx2_lab/umdf/step1/OsrUsbFx2.rc new file mode 100644 index 00000000..36f10ea9 --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step1/OsrUsbFx2.rc @@ -0,0 +1,21 @@ +//--------------------------------------------------------------------------- +// OsrUsbDevice.rc +// +// Copyright (c) Microsoft Corporation, All Rights Reserved +//--------------------------------------------------------------------------- + + +#include <windows.h> +#include <ntverp.h> + +// +// TODO: Change the file description and file names to match your binary. +// + +#define VER_FILETYPE VFT_DLL +#define VER_FILESUBTYPE VFT_UNKNOWN +#define VER_FILEDESCRIPTION_STR "WDF:UMDF OSR USB Fx2 User-Mode Driver Sample" +#define VER_INTERNALNAME_STR "WUDFOsrUsbFx2" +#define VER_ORIGINALFILENAME_STR "WUDFOsrUsbFx2.dll" + +#include "common.ver" diff --git a/usb/wdf_osrfx2_lab/umdf/step1/WUDFOsrUsbFx2_1.inx b/usb/wdf_osrfx2_lab/umdf/step1/WUDFOsrUsbFx2_1.inx Binary files differnew file mode 100644 index 00000000..dea03ff6 --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step1/WUDFOsrUsbFx2_1.inx diff --git a/usb/wdf_osrfx2_lab/umdf/step1/WUDFOsrUsbFx2_1.vcxproj b/usb/wdf_osrfx2_lab/umdf/step1/WUDFOsrUsbFx2_1.vcxproj new file mode 100644 index 00000000..aef4ae60 --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step1/WUDFOsrUsbFx2_1.vcxproj @@ -0,0 +1,267 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{94BDC8D1-B62F-4200-9873-D403B6D30301}</ProjectGuid> + <RootNamespace>$(MSBuildProjectName)</RootNamespace> + <UMDF_VERSION_MAJOR>1</UMDF_VERSION_MAJOR> + <KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR> + <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration> + <Platform Condition="'$(Platform)' == ''">Win32</Platform> + <SampleGuid>{A2C76CA1-1B47-420E-9768-93D69A3266B6}</SampleGuid> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType>UMDF</DriverType> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType>UMDF</DriverType> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType>UMDF</DriverType> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType>UMDF</DriverType> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <OutDir>$(IntDir)</OutDir> + </PropertyGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ItemGroup Label="WrappedTaskItems"> + <ClCompile Include="dllsup.cpp; comsup.cpp; driver.cpp; device.cpp"> + <WppEnabled>true</WppEnabled> + <WppDllMacro>true</WppDllMacro> + <WppScanConfigurationData>internal.h</WppScanConfigurationData> + </ClCompile> + <OtherWpp Include="OsrUsbFx2.rc"> + <WppEnabled>true</WppEnabled> + <WppDllMacro>true</WppDllMacro> + <WppScanConfigurationData>internal.h</WppScanConfigurationData> + </OtherWpp> + </ItemGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetName>WUDFOsrUsbFx2_1</TargetName> + <WIN32_WINNT_VERSION>0x0A00</WIN32_WINNT_VERSION> + <NTDDI_VERSION>0x0A000000</NTDDI_VERSION> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetName>WUDFOsrUsbFx2_1</TargetName> + <WIN32_WINNT_VERSION>0x0A00</WIN32_WINNT_VERSION> + <NTDDI_VERSION>0x0A000000</NTDDI_VERSION> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetName>WUDFOsrUsbFx2_1</TargetName> + <WIN32_WINNT_VERSION>0x0A00</WIN32_WINNT_VERSION> + <NTDDI_VERSION>0x0A000000</NTDDI_VERSION> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetName>WUDFOsrUsbFx2_1</TargetName> + <WIN32_WINNT_VERSION>0x0A00</WIN32_WINNT_VERSION> + <NTDDI_VERSION>0x0A000000</NTDDI_VERSION> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <DisableSpecificWarnings>%(DisableSpecificWarnings);4201</DisableSpecificWarnings> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ClCompile> + <Midl> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </Midl> + <ResourceCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ResourceCompile> + <Link> + <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol> + <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <DisableSpecificWarnings>%(DisableSpecificWarnings);4201</DisableSpecificWarnings> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ClCompile> + <Midl> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </Midl> + <ResourceCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ResourceCompile> + <Link> + <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol> + <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <DisableSpecificWarnings>%(DisableSpecificWarnings);4201</DisableSpecificWarnings> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ClCompile> + <Midl> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </Midl> + <ResourceCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ResourceCompile> + <Link> + <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol> + <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <DisableSpecificWarnings>%(DisableSpecificWarnings);4201</DisableSpecificWarnings> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ClCompile> + <Midl> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </Midl> + <ResourceCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ResourceCompile> + <Link> + <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol> + <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\kernel32.lib;$(SDK_LIB_PATH)\advapi32.lib</AdditionalDependencies> + <ModuleDefinitionFile>exports.def</ModuleDefinitionFile> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\kernel32.lib;$(SDK_LIB_PATH)\advapi32.lib</AdditionalDependencies> + <ModuleDefinitionFile>exports.def</ModuleDefinitionFile> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\kernel32.lib;$(SDK_LIB_PATH)\advapi32.lib</AdditionalDependencies> + <ModuleDefinitionFile>exports.def</ModuleDefinitionFile> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\kernel32.lib;$(SDK_LIB_PATH)\advapi32.lib</AdditionalDependencies> + <ModuleDefinitionFile>exports.def</ModuleDefinitionFile> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ResourceCompile Include="OsrUsbFx2.rc" /> + </ItemGroup> + <ItemGroup> + <Inf Exclude="@(Inf)" Include="*.inf" /> + <FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" /> + </ItemGroup> + <ItemGroup> + <None Exclude="@(None)" Include="*.txt;*.htm;*.html" /> + <None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" /> + <None Exclude="@(None)" Include="*.def;*.bat;*.hpj;*.asmx" /> + </ItemGroup> + <ItemGroup> + <ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> +</Project>
\ No newline at end of file diff --git a/usb/wdf_osrfx2_lab/umdf/step1/WUDFOsrUsbFx2_1.vcxproj.Filters b/usb/wdf_osrfx2_lab/umdf/step1/WUDFOsrUsbFx2_1.vcxproj.Filters new file mode 100644 index 00000000..6b21dc4a --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step1/WUDFOsrUsbFx2_1.vcxproj.Filters @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions> + <UniqueIdentifier>{83D4660B-A09F-4A40-A1FD-237876304103}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files"> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + <UniqueIdentifier>{3C16D1C8-B1DE-467D-9DF0-AE732A9B8915}</UniqueIdentifier> + </Filter> + <Filter Include="Resource Files"> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions> + <UniqueIdentifier>{E23C96E3-DE9A-457A-A1D4-DA476B16AD08}</UniqueIdentifier> + </Filter> + <Filter Include="Driver Files"> + <Extensions>inf;inv;inx;mof;mc;</Extensions> + <UniqueIdentifier>{C71DC5A8-0692-4670-A5B8-B6706FA885E7}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="comsup.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="device.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="dllsup.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="driver.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <None Include="exports.def"> + <Filter>Source Files</Filter> + </None> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="OsrUsbFx2.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/usb/wdf_osrfx2_lab/umdf/step1/comsup.cpp b/usb/wdf_osrfx2_lab/umdf/step1/comsup.cpp new file mode 100644 index 00000000..9c9aec3b --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step1/comsup.cpp @@ -0,0 +1,344 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + ComSup.cpp + +Abstract: + + This module contains implementations for the functions and methods + used for providing COM support. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#include "internal.h" + +#include "comsup.tmh" + +// +// Implementation of CUnknown methods. +// + +CUnknown::CUnknown( + VOID + ) : m_ReferenceCount(1) +/*++ + + Routine Description: + + Constructor for an instance of the CUnknown class. This simply initializes + the reference count of the object to 1. The caller is expected to + call Release() if it wants to delete the object once it has been allocated. + + Arguments: + + None + + Return Value: + + None + +--*/ +{ + // do nothing. +} + +HRESULT +STDMETHODCALLTYPE +CUnknown::QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ) +/*++ + + Routine Description: + + This method provides the basic support for query interface on CUnknown. + If the interface requested is IUnknown it references the object and + returns an interface pointer. Otherwise it returns an error. + + Arguments: + + InterfaceId - the IID being requested + + Object - a location to store the interface pointer to return. + + Return Value: + + S_OK or E_NOINTERFACE + +--*/ +{ + if (IsEqualIID(InterfaceId, __uuidof(IUnknown))) + { + *Object = QueryIUnknown(); + return S_OK; + } + else + { + *Object = NULL; + return E_NOINTERFACE; + } +} + +IUnknown * +CUnknown::QueryIUnknown( + VOID + ) +/*++ + + Routine Description: + + This helper method references the object and returns a pointer to the + object's IUnknown interface. + + This allows other methods to convert a CUnknown pointer into an IUnknown + pointer without a typecast and without calling QueryInterface and dealing + with the return value. + + Arguments: + + None + + Return Value: + + A pointer to the object's IUnknown interface. + +--*/ +{ + AddRef(); + return static_cast<IUnknown *>(this); +} + +ULONG +STDMETHODCALLTYPE +CUnknown::AddRef( + VOID + ) +/*++ + + Routine Description: + + This method adds one to the object's reference count. + + Arguments: + + None + + Return Value: + + The new reference count. The caller should only use this for debugging + as the object's actual reference count can change while the caller + examines the return value. + +--*/ +{ + return InterlockedIncrement(&m_ReferenceCount); +} + +ULONG +STDMETHODCALLTYPE +CUnknown::Release( + VOID + ) +/*++ + + Routine Description: + + This method subtracts one to the object's reference count. If the count + goes to zero, this method deletes the object. + + Arguments: + + None + + Return Value: + + The new reference count. If the caller uses this value it should only be + to check for zero (i.e. this call caused or will cause deletion) or + non-zero (i.e. some other call may have caused deletion, but this one + didn't). + +--*/ +{ + ULONG count = InterlockedDecrement(&m_ReferenceCount); + + if (count == 0) + { + delete this; + } + return count; +} + +// +// Implementation of CClassFactory methods. +// + +// +// Define storage for the factory's static lock count variable. +// + +LONG CClassFactory::s_LockCount = 0; + +IClassFactory * +CClassFactory::QueryIClassFactory( + VOID + ) +/*++ + + Routine Description: + + This helper method references the object and returns a pointer to the + object's IClassFactory interface. + + This allows other methods to convert a CClassFactory pointer into an + IClassFactory pointer without a typecast and without dealing with the + return value QueryInterface. + + Arguments: + + None + + Return Value: + + A referenced pointer to the object's IClassFactory interface. + +--*/ +{ + AddRef(); + return static_cast<IClassFactory *>(this); +} + +HRESULT +CClassFactory::QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ) +/*++ + + Routine Description: + + This method attempts to retrieve the requested interface from the object. + + If the interface is found then the reference count on that interface (and + thus the object itself) is incremented. + + Arguments: + + InterfaceId - the interface the caller is requesting. + + Object - a location to store the interface pointer. + + Return Value: + + S_OK or E_NOINTERFACE + +--*/ +{ + // + // This class only supports IClassFactory so check for that. + // + + if (IsEqualIID(InterfaceId, __uuidof(IClassFactory))) + { + *Object = QueryIClassFactory(); + return S_OK; + } + else + { + // + // See if the base class supports the interface. + // + + return CUnknown::QueryInterface(InterfaceId, Object); + } +} + +HRESULT +STDMETHODCALLTYPE +CClassFactory::CreateInstance( + _In_opt_ IUnknown * /* OuterObject */, + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ) +/*++ + + Routine Description: + + This COM method is the factory routine - it creates instances of the driver + callback class and returns the specified interface on them. + + Arguments: + + OuterObject - only used for aggregation, which our driver callback class + does not support. + + InterfaceId - the interface ID the caller would like to get from our + new object. + + Object - a location to store the referenced interface pointer to the new + object. + + Return Value: + + Status. + +--*/ +{ + HRESULT hr; + + PCMyDriver driver; + + *Object = NULL; + + hr = CMyDriver::CreateInstance(&driver); + + if (SUCCEEDED(hr)) + { + hr = driver->QueryInterface(InterfaceId, Object); + driver->Release(); + } + + return hr; +} + +HRESULT +STDMETHODCALLTYPE +CClassFactory::LockServer( + _In_ BOOL Lock + ) +/*++ + + Routine Description: + + This COM method can be used to keep the DLL in memory. However since the + driver's DllCanUnloadNow function always returns false, this has little + effect. Still it tracks the number of lock and unlock operations. + + Arguments: + + Lock - Whether the caller wants to lock or unlock the "server" + + Return Value: + + S_OK + +--*/ +{ + if (Lock) + { + InterlockedIncrement(&s_LockCount); + } + else + { + InterlockedDecrement(&s_LockCount); + } + return S_OK; +} + diff --git a/usb/wdf_osrfx2_lab/umdf/step1/comsup.h b/usb/wdf_osrfx2_lab/umdf/step1/comsup.h new file mode 100644 index 00000000..dedf78c8 --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step1/comsup.h @@ -0,0 +1,215 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + ComSup.h + +Abstract: + + This module contains classes and functions use for providing COM support + code. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once + +// +// Forward type declarations. They are here rather than in internal.h as +// you only need them if you choose to use these support classes. +// + +typedef class CUnknown *PCUnknown; +typedef class CClassFactory *PCClassFactory; + +// +// Base class to implement IUnknown. You can choose to derive your COM +// classes from this class, or simply implement IUnknown in each of your +// classes. +// + +class CUnknown : public IUnknown +{ + +// +// Private data members and methods. These are only accessible by the methods +// of this class. +// +private: + + // + // The reference count for this object. Initialized to 1 in the + // constructor. + // + + LONG m_ReferenceCount; + +// +// Protected data members and methods. These are accessible by the subclasses +// but not by other classes. +// +protected: + + // + // The constructor and destructor are protected to ensure that only the + // subclasses of CUnknown can create and destroy instances. + // + + CUnknown( + VOID + ); + + // + // The destructor MUST be virtual. Since any instance of a CUnknown + // derived class should only be deleted from within CUnknown::Release, + // the destructor MUST be virtual or only CUnknown::~CUnknown will get + // invoked on deletion. + // + // If you see that your CMyDevice specific destructor is never being + // called, make sure you haven't deleted the virtual destructor here. + // + + virtual + ~CUnknown( + VOID + ) + { + // Do nothing + } + +// +// Public Methods. These are accessible by any class. +// +public: + + IUnknown * + QueryIUnknown( + VOID + ); + +// +// COM Methods. +// +public: + + // + // IUnknown methods + // + + virtual + ULONG + STDMETHODCALLTYPE + AddRef( + VOID + ); + + virtual + ULONG + STDMETHODCALLTYPE + Release( + VOID + ); + + virtual + HRESULT + STDMETHODCALLTYPE + QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ); +}; + +// +// Class factory support class. Create an instance of this from your +// DllGetClassObject method and modify the implementation to create +// an instance of your driver event handler class. +// + +class CClassFactory : public CUnknown, public IClassFactory +{ +// +// Private data members and methods. These are only accessible by the methods +// of this class. +// +private: + + // + // The lock count. This is shared across all instances of IClassFactory + // and can be queried through the public IsLocked method. + // + + static LONG s_LockCount; + +// +// Public Methods. These are accessible by any class. +// +public: + + IClassFactory * + QueryIClassFactory( + VOID + ); + +// +// COM Methods. +// +public: + + // + // IUnknown methods + // + + virtual + ULONG + STDMETHODCALLTYPE + AddRef( + VOID + ) + { + return __super::AddRef(); + } + + _At_(this, __drv_freesMem(object)) + virtual + ULONG + STDMETHODCALLTYPE + Release( + VOID + ) + { + return __super::Release(); + } + + virtual + HRESULT + STDMETHODCALLTYPE + QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ); + + // + // IClassFactory methods. + // + + virtual + HRESULT + STDMETHODCALLTYPE + CreateInstance( + _In_opt_ IUnknown *OuterObject, + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ); + + virtual + HRESULT + STDMETHODCALLTYPE + LockServer( + _In_ BOOL Lock + ); +}; diff --git a/usb/wdf_osrfx2_lab/umdf/step1/dllsup.cpp b/usb/wdf_osrfx2_lab/umdf/step1/dllsup.cpp new file mode 100644 index 00000000..e8bad81b --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step1/dllsup.cpp @@ -0,0 +1,202 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved. + +Module Name: + + dllsup.cpp + +Abstract: + + This module contains the implementation of the UMDF Skeleton Sample + Driver's entry point and its exported functions for providing COM support. + + This module can be copied without modification to a new UMDF driver. It + depends on some of the code in comsup.cpp & comsup.h to handle DLL + registration and creating the first class factory. + + This module is dependent on the following defines: + + MYDRIVER_TRACING_ID - A wide string passed to WPP when initializing + tracing. For example the skeleton uses + L"Microsoft\\UMDF\\Skeleton" + + MYDRIVER_CLASS_ID - A GUID encoded in struct format used to + initialize the driver's ClassID. + + These are defined in internal.h for the skeleton sample. If you choose + to use a different primary include file, you should ensure they are + defined there as well. + +Environment: + + WDF User-Mode Driver Framework (WDF:UMDF) + +--*/ + +#include "internal.h" +#include "dllsup.tmh" + +const GUID CLSID_MyDriverCoClass = MYDRIVER_CLASS_ID; + +BOOL +WINAPI +DllMain( + HINSTANCE ModuleHandle, + DWORD Reason, + PVOID /* Reserved */ + ) +/*++ + + Routine Description: + + This is the entry point and exit point for the I/O trace driver. This + does very little as the I/O trace driver has minimal global data. + + This method initializes tracing, and saves the module handle away in a + global variable so that it can be referenced should the COM registration + code (Dll[Un]RegisterServer) be called. + + Arguments: + + ModuleHandle - the DLL handle for this module. + + Reason - the reason this entry point was called. + + Reserved - unused + + Return Value: + + TRUE + +--*/ +{ + UNREFERENCED_PARAMETER(ModuleHandle); + + if (DLL_PROCESS_ATTACH == Reason) + { + // + // Initialize tracing. + // + + WPP_INIT_TRACING(MYDRIVER_TRACING_ID); + } + else if (DLL_PROCESS_DETACH == Reason) + { + // + // Cleanup tracing. + // + + WPP_CLEANUP(); + } + + return TRUE; +} + +HRESULT +STDAPICALLTYPE +DllCanUnloadNow( + VOID + ) +/*++ + + Routine Description: + + Called by the COM runtime when determining whether or not this module + can be unloaded. Our answer is always "no". + + Arguments: + + None + + Return Value: + + S_FALSE + +--*/ +{ + return S_FALSE; +} + +HRESULT +STDAPICALLTYPE +DllGetClassObject( + _In_ REFCLSID ClassId, + _In_ REFIID InterfaceId, + _Outptr_ LPVOID *Interface + ) +/*++ + + Routine Description: + + This routine is called by COM in order to instantiate the + skeleton driver callback object and do an initial query interface on it. + + This method only creates an instance of the driver's class factory, as this + is the minimum required to support UMDF. + + Arguments: + + ClassId - the CLSID of the object being "gotten" + + InterfaceId - the interface the caller wants from that object. + + Interface - a location to store the referenced interface pointer + + Return Value: + + S_OK if the function succeeds or error indicating the cause of the + failure. + +--*/ +{ + PCClassFactory factory; + + HRESULT hr = S_OK; + + *Interface = NULL; + + // + // If the CLSID doesn't match that of our "coclass" (defined in the IDL + // file) then we can't create the object the caller wants. This may + // indicate that the COM registration is incorrect, and another CLSID + // is referencing this drvier. + // + + if (IsEqualCLSID(ClassId, CLSID_MyDriverCoClass) == false) + { + Trace( + TRACE_LEVEL_ERROR, + L"ERROR: Called to create instance of unrecognized class (%!GUID!)", + &ClassId + ); + + return CLASS_E_CLASSNOTAVAILABLE; + } + + // + // Create an instance of the class factory for the caller. + // + + factory = new CClassFactory(); + + if (NULL == factory) + { + hr = E_OUTOFMEMORY; + } + + // + // Query the object we created for the interface the caller wants. After + // that we release the object. This will drive the reference count to + // 1 (if the QI succeeded an referenced the object) or 0 (if the QI failed). + // In the later case the object is automatically deleted. + // + + if (SUCCEEDED(hr)) + { + hr = factory->QueryInterface(InterfaceId, Interface); + factory->Release(); + } + + return hr; +} diff --git a/usb/wdf_osrfx2_lab/umdf/step1/exports.def b/usb/wdf_osrfx2_lab/umdf/step1/exports.def new file mode 100644 index 00000000..15f923d3 --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step1/exports.def @@ -0,0 +1,4 @@ +; WudfOsrUsbDriver.def : Declares the module parameters. + +EXPORTS + DllGetClassObject PRIVATE diff --git a/usb/wdf_osrfx2_lab/umdf/step1/internal.h b/usb/wdf_osrfx2_lab/umdf/step1/internal.h new file mode 100644 index 00000000..374931e0 --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step1/internal.h @@ -0,0 +1,150 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + Internal.h + +Abstract: + + This module contains the local type definitions for the UMDF Skeleton + driver sample. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) +#endif + +// +// Include the WUDF Headers +// + +#include "wudfddi.h" + +// +// Use specstrings for in/out annotation of function parameters. +// + +#include "specstrings.h" + +// +// Get limits on common data types (ULONG_MAX for example) +// + +#include "limits.h" + +// +// We need usb I/O targets to talk to the OSR device. +// + +#include "wudfusb.h" + +// +// Include the header shared between the drivers and the test applications. +// + +#include "public.h" + +// +// Include the header shared between the drivers and the test applications. +// + +#include "WUDFOsrUsbPublic.h" + +// +// Forward definitions of classes in the other header files. +// + +typedef class CMyDriver *PCMyDriver; +typedef class CMyDevice *PCMyDevice; +typedef class CMyQueue *PCMyQueue; + +typedef class CMyControlQueue *PCMyControlQueue; + +// +// Define the tracing flags. +// +// TODO: Choose a different trace control GUID +// + +#define WPP_CONTROL_GUIDS \ + WPP_DEFINE_CONTROL_GUID( \ + WudfOsrUsbFx2TraceGuid, (da5fbdfd,1eae,4ecf,b426,a3818f325ddb), \ + \ + WPP_DEFINE_BIT(MYDRIVER_ALL_INFO) \ + WPP_DEFINE_BIT(TEST_TRACE_DRIVER) \ + WPP_DEFINE_BIT(TEST_TRACE_DEVICE) \ + WPP_DEFINE_BIT(TEST_TRACE_QUEUE) \ + ) + +#define WPP_FLAG_LEVEL_LOGGER(flag, level) \ + WPP_LEVEL_LOGGER(flag) + +#define WPP_FLAG_LEVEL_ENABLED(flag, level) \ + (WPP_LEVEL_ENABLED(flag) && \ + WPP_CONTROL(WPP_BIT_ ## flag).Level >= level) + +#define WPP_LEVEL_FLAGS_LOGGER(lvl,flags) \ + WPP_LEVEL_LOGGER(flags) + +#define WPP_LEVEL_FLAGS_ENABLED(lvl, flags) \ + (WPP_LEVEL_ENABLED(flags) && WPP_CONTROL(WPP_BIT_ ## flags).Level >= lvl) + +// +// This comment block is scanned by the trace preprocessor to define our +// Trace function. +// +// begin_wpp config +// FUNC Trace{FLAG=MYDRIVER_ALL_INFO}(LEVEL, MSG, ...); +// FUNC TraceEvents(LEVEL, FLAGS, MSG, ...); +// end_wpp +// + +// +// Driver specific #defines +// +// TODO: Change these values to be appropriate for your driver. +// + +#define MYDRIVER_TRACING_ID L"Microsoft\\UMDF\\OsrUsb" +#define MYDRIVER_CLASS_ID {0x0865b2b0, 0x6b73, 0x428f, {0xa3, 0xea, 0x21, 0x72, 0x83, 0x2d, 0x6b, 0xfc}} + +// +// Include the type specific headers. +// + +#include "comsup.h" +#include "driver.h" +#include "device.h" +#include "list.h" + +__forceinline +#ifdef _PREFAST_ +__declspec(noreturn) +#endif +VOID +WdfTestNoReturn( + VOID + ) +{ + // do nothing. +} + +#define WUDF_TEST_DRIVER_ASSERT(p) \ +{ \ + if ( !(p) ) \ + { \ + DebugBreak(); \ + WdfTestNoReturn(); \ + } \ +} + +#define SAFE_RELEASE(p) {if ((p)) { (p)->Release(); (p) = NULL; }} diff --git a/usb/wdf_osrfx2_lab/umdf/step2/Device.cpp b/usb/wdf_osrfx2_lab/umdf/step2/Device.cpp new file mode 100644 index 00000000..433309ca --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step2/Device.cpp @@ -0,0 +1,483 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved. + +Module Name: + + Device.cpp + +Abstract: + + This module contains the implementation of the UMDF Skeleton sample driver's + device callback object. + + The skeleton sample device does very little. It does not implement either + of the PNP interfaces so once the device is setup, it won't ever get any + callbacks until the device is removed. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#include "internal.h" +#include "initguid.h" +#include "usb_hw.h" + +#include "device.tmh" + +CMyDevice::~CMyDevice( + ) +{ +} + +HRESULT +CMyDevice::CreateInstance( + _In_ IWDFDriver *FxDriver, + _In_ IWDFDeviceInitialize * FxDeviceInit, + _Out_ PCMyDevice *Device + ) +/*++ + + Routine Description: + + This method creates and initializs an instance of the skeleton driver's + device callback object. + + Arguments: + + FxDeviceInit - the settings for the device. + + Device - a location to store the referenced pointer to the device object. + + Return Value: + + Status + +--*/ +{ + PCMyDevice device; + HRESULT hr; + + // + // Allocate a new instance of the device class. + // + + device = new CMyDevice(); + + if (NULL == device) + { + return E_OUTOFMEMORY; + } + + // + // Initialize the instance. + // + + hr = device->Initialize(FxDriver, FxDeviceInit); + + if (SUCCEEDED(hr)) + { + *Device = device; + } + else + { + device->Release(); + } + + return hr; +} + +HRESULT +CMyDevice::Initialize( + _In_ IWDFDriver * FxDriver, + _In_ IWDFDeviceInitialize * FxDeviceInit + ) +/*++ + + Routine Description: + + This method initializes the device callback object and creates the + partner device object. + + The method should perform any device-specific configuration that: + * could fail (these can't be done in the constructor) + * must be done before the partner object is created -or- + * can be done after the partner object is created and which aren't + influenced by any device-level parameters the parent (the driver + in this case) might set. + + Arguments: + + FxDeviceInit - the settings for this device. + + Return Value: + + status. + +--*/ +{ + IWDFDevice *fxDevice = NULL; + + HRESULT hr = S_OK; + + // + // TODO: If you're writing a filter driver then indicate that here. + // + // FxDeviceInit->SetFilter(); + // + + // + // Set no locking unless you need an automatic callbacks synchronization + // + + FxDeviceInit->SetLockingConstraint(None); + + // + // TODO: Any per-device initialization which must be done before + // creating the partner object. + // + + + // + // Create a new FX device object and assign the new callback object to + // handle any device level events that occur. + // + + // + // QueryIUnknown references the IUnknown interface that it returns + // (which is the same as referencing the device). We pass that to + // CreateDevice, which takes its own reference if everything works. + // + + if (SUCCEEDED(hr)) + { + IUnknown *unknown = this->QueryIUnknown(); + + hr = FxDriver->CreateDevice(FxDeviceInit, unknown, &fxDevice); + + unknown->Release(); + } + + // + // If that succeeded then set our FxDevice member variable. + // + + if (SUCCEEDED(hr)) + { + m_FxDevice = fxDevice; + + // + // Drop the reference we got from CreateDevice. Since this object + // is partnered with the framework object they have the same + // lifespan - there is no need for an additional reference. + // + + fxDevice->Release(); + } + + return hr; +} + +HRESULT +CMyDevice::Configure( + VOID + ) +/*++ + + Routine Description: + + This method is called after the device callback object has been initialized + and returned to the driver. It would setup the device's queues and their + corresponding callback objects. + + Arguments: + + FxDevice - the framework device object for which we're handling events. + + Return Value: + + status + +--*/ +{ + HRESULT hr = S_OK; + + if (SUCCEEDED(hr)) + { + hr = m_FxDevice->CreateDeviceInterface(&GUID_DEVINTERFACE_OSRUSBFX2, + NULL); + } + + return hr; +} + +HRESULT +CMyDevice::QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ) +/*++ + + Routine Description: + + This method is called to get a pointer to one of the object's callback + interfaces. + + Since the skeleton driver doesn't support any of the device events, this + method simply calls the base class's BaseQueryInterface. + + If the skeleton is extended to include device event interfaces then this + method must be changed to check the IID and return pointers to them as + appropriate. + + Arguments: + + InterfaceId - the interface being requested + + Object - a location to store the interface pointer if successful + + Return Value: + + S_OK or E_NOINTERFACE + +--*/ +{ + HRESULT hr; + + if (IsEqualIID(InterfaceId, __uuidof(IPnpCallbackHardware))) + { + *Object = QueryIPnpCallbackHardware(); + hr = S_OK; + } + else + { + hr = CUnknown::QueryInterface(InterfaceId, Object); + } + + return hr; +} + +HRESULT +CMyDevice::OnPrepareHardware( + _In_ IWDFDevice * /* FxDevice */ + ) +/*++ + +Routine Description: + + This routine is invoked to ready the driver + to talk to hardware. It opens the handle to the + device and talks to it using the WINUSB interface. + It invokes WINUSB to discver the interfaces and stores + the information related to bulk endpoints. + +Arguments: + + FxDevice : Pointer to the WDF device interface + +Return Value: + + HRESULT + +--*/ +{ + PWSTR deviceName = NULL; + DWORD deviceNameCch = 0; + + HRESULT hr; + + // + // Get the device name. + // Get the length to allocate first + // + + hr = m_FxDevice->RetrieveDeviceName(NULL, &deviceNameCch); + + if (FAILED(hr)) + { + TraceEvents(TRACE_LEVEL_ERROR, + TEST_TRACE_DEVICE, + "%!FUNC! Cannot get device name %!hresult!", + hr + ); + } + + // + // Allocate the buffer + // + + if (SUCCEEDED(hr)) + { + deviceName = new WCHAR[deviceNameCch]; + + if (deviceName == NULL) + { + hr = E_OUTOFMEMORY; + } + } + + // + // Get the actual name + // + + if (SUCCEEDED(hr)) + { + hr = m_FxDevice->RetrieveDeviceName(deviceName, &deviceNameCch); + + if (FAILED(hr)) + { + TraceEvents(TRACE_LEVEL_ERROR, + TEST_TRACE_DEVICE, + "%!FUNC! Cannot get device name %!hresult!", + hr + ); + } + } + + if (SUCCEEDED(hr)) + { + TraceEvents(TRACE_LEVEL_INFORMATION, + TEST_TRACE_DEVICE, + "%!FUNC! Device name %S", + deviceName + ); + } + + // + // Create USB I/O Targets and configure them + // + + if (SUCCEEDED(hr)) + { + hr = CreateUsbIoTargets(); + } + + if (SUCCEEDED(hr)) + { + ULONG length = sizeof(m_Speed); + + hr = m_pIUsbTargetDevice->RetrieveDeviceInformation(DEVICE_SPEED, + &length, + &m_Speed); + if (FAILED(hr)) + { + TraceEvents(TRACE_LEVEL_ERROR, + TEST_TRACE_DEVICE, + "%!FUNC! Cannot get usb device speed information %!HRESULT!", + hr + ); + } + } + + if (SUCCEEDED(hr)) + { + TraceEvents(TRACE_LEVEL_INFORMATION, + TEST_TRACE_DEVICE, + "%!FUNC! Speed - %x\n", + m_Speed + ); + } + + delete[] deviceName; + + return hr; +} + +HRESULT +CMyDevice::OnReleaseHardware( + _In_ IWDFDevice * /* FxDevice */ + ) +/*++ + +Routine Description: + + This routine is invoked when the device is being removed or stopped + It releases all resources allocated for this device. + +Arguments: + + FxDevice - Pointer to the Device object. + +Return Value: + + HRESULT - Always succeeds. + +--*/ +{ + // + // Remove I/O target from object tree before any potential subsequent + // OnPrepareHardware creates a new one + // + + if (m_pIUsbTargetDevice) + { + m_pIUsbTargetDevice->DeleteWdfObject(); + } + + return S_OK; +} + +HRESULT +CMyDevice::CreateUsbIoTargets( + ) +/*++ + +Routine Description: + + This routine creates Usb device, interface and pipe objects + +Arguments: + + None + +Return Value: + + HRESULT +--*/ +{ + HRESULT hr; + IWDFUsbTargetFactory * pIUsbTargetFactory = NULL; + IWDFUsbTargetDevice * pIUsbTargetDevice = NULL; + + hr = m_FxDevice->QueryInterface(IID_PPV_ARGS(&pIUsbTargetFactory)); + + if (FAILED(hr)) + { + TraceEvents(TRACE_LEVEL_ERROR, + TEST_TRACE_DEVICE, + "%!FUNC! Cannot get usb target factory %!HRESULT!", + hr + ); + } + + if (SUCCEEDED(hr)) + { + hr = pIUsbTargetFactory->CreateUsbTargetDevice( + &pIUsbTargetDevice); + if (FAILED(hr)) + { + TraceEvents(TRACE_LEVEL_ERROR, + TEST_TRACE_DEVICE, + "%!FUNC! Unable to create USB Device I/O Target %!HRESULT!", + hr + ); + } + } + + if (SUCCEEDED(hr)) + { + m_pIUsbTargetDevice = pIUsbTargetDevice; + + // + // Release the creation reference as object tree will maintain a reference + // + + pIUsbTargetDevice->Release(); + } + + SAFE_RELEASE(pIUsbTargetFactory); + + return hr; +} diff --git a/usb/wdf_osrfx2_lab/umdf/step2/Device.h b/usb/wdf_osrfx2_lab/umdf/step2/Device.h new file mode 100644 index 00000000..dadbfd5b --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step2/Device.h @@ -0,0 +1,180 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + Device.h + +Abstract: + + This module contains the type definitions for the UMDF Skeleton sample + driver's device callback class. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once +#include "internal.h" + +// +// Class for the iotrace driver. +// + +class CMyDevice : + public CUnknown, + public IPnpCallbackHardware +{ + +// +// Private data members. +// +private: + // + // Weak reference to framework device + // + IWDFDevice *m_FxDevice; + + // + // USB Device I/O Target + // + IWDFUsbTargetDevice * m_pIUsbTargetDevice; + + + // + // Device Speed (Low, Full, High) + // + UCHAR m_Speed; + +// +// Private methods. +// + +private: + + CMyDevice( + VOID + ) : + m_FxDevice(NULL), + m_pIUsbTargetDevice(NULL), + m_Speed(0) + { + } + + ~CMyDevice( + ); + + HRESULT + Initialize( + _In_ IWDFDriver *FxDriver, + _In_ IWDFDeviceInitialize *FxDeviceInit + ); + + // + // Helper methods + // + + HRESULT + CreateUsbIoTargets( + VOID + ); + + +// +// Public methods +// +public: + + // + // The factory method used to create an instance of this driver. + // + + static + HRESULT + CreateInstance( + _In_ IWDFDriver *FxDriver, + _In_ IWDFDeviceInitialize *FxDeviceInit, + _Out_ PCMyDevice *Device + ); + + IWDFDevice * + GetFxDevice( + VOID + ) + { + return m_FxDevice; + } + + HRESULT + Configure( + VOID + ); + + IPnpCallbackHardware * + QueryIPnpCallbackHardware( + VOID + ) + { + AddRef(); + return static_cast<IPnpCallbackHardware *>(this); + } + +// +// COM methods +// +public: + + // + // IUnknown methods. + // + + virtual + ULONG + STDMETHODCALLTYPE + AddRef( + VOID + ) + { + return __super::AddRef(); + } + + _At_(this, __drv_freesMem(object)) + virtual + ULONG + STDMETHODCALLTYPE + Release( + VOID + ) + { + return __super::Release(); + } + + virtual + HRESULT + STDMETHODCALLTYPE + QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ); + + // + // IPnpCallbackHardware + // + + virtual + HRESULT + STDMETHODCALLTYPE + OnPrepareHardware( + _In_ IWDFDevice *FxDevice + ); + + virtual + HRESULT + STDMETHODCALLTYPE + OnReleaseHardware( + _In_ IWDFDevice *FxDevice + ); +}; diff --git a/usb/wdf_osrfx2_lab/umdf/step2/Driver.cpp b/usb/wdf_osrfx2_lab/umdf/step2/Driver.cpp new file mode 100644 index 00000000..bac5caca --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step2/Driver.cpp @@ -0,0 +1,220 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved. + +Module Name: + + Driver.cpp + +Abstract: + + This module contains the implementation of the UMDF Skeleton Sample's + core driver callback object. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#include "internal.h" +#include "driver.tmh" + +HRESULT +CMyDriver::CreateInstance( + _Out_ PCMyDriver *Driver + ) +/*++ + + Routine Description: + + This static method is invoked in order to create and initialize a new + instance of the driver class. The caller should arrange for the object + to be released when it is no longer in use. + + Arguments: + + Driver - a location to store a referenced pointer to the new instance + + Return Value: + + S_OK if successful, or error otherwise. + +--*/ +{ + PCMyDriver driver; + HRESULT hr; + + // + // Allocate the callback object. + // + + driver = new CMyDriver(); + + if (NULL == driver) + { + return E_OUTOFMEMORY; + } + + // + // Initialize the callback object. + // + + hr = driver->Initialize(); + + if (SUCCEEDED(hr)) + { + // + // Store a pointer to the new, initialized object in the output + // parameter. + // + + *Driver = driver; + } + else + { + + // + // Release the reference on the driver object to get it to delete + // itself. + // + + driver->Release(); + } + + return hr; +} + +HRESULT +CMyDriver::Initialize( + VOID + ) +/*++ + + Routine Description: + + This method is called to initialize a newly created driver callback object + before it is returned to the creator. Unlike the constructor, the + Initialize method contains operations which could potentially fail. + + Arguments: + + None + + Return Value: + + None + +--*/ +{ + return S_OK; +} + +HRESULT +CMyDriver::QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Interface + ) +/*++ + + Routine Description: + + This method returns a pointer to the requested interface on the callback + object.. + + Arguments: + + InterfaceId - the IID of the interface to query/reference + + Interface - a location to store the interface pointer. + + Return Value: + + S_OK if the interface is supported. + E_NOINTERFACE if it is not supported. + +--*/ +{ + if (IsEqualIID(InterfaceId, __uuidof(IDriverEntry))) + { + *Interface = QueryIDriverEntry(); + return S_OK; + } + else + { + return CUnknown::QueryInterface(InterfaceId, Interface); + } +} + +HRESULT +CMyDriver::OnDeviceAdd( + _In_ IWDFDriver *FxWdfDriver, + _In_ IWDFDeviceInitialize *FxDeviceInit + ) +/*++ + + Routine Description: + + The FX invokes this method when it wants to install our driver on a device + stack. This method creates a device callback object, then calls the Fx + to create an Fx device object and associate the new callback object with + it. + + Arguments: + + FxWdfDriver - the Fx driver object. + + FxDeviceInit - the initialization information for the device. + + Return Value: + + status + +--*/ +{ + HRESULT hr; + + PCMyDevice device = NULL; + + // + // TODO: Do any per-device initialization (reading settings from the + // registry for example) that's necessary before creating your + // device callback object here. Otherwise you can leave such + // initialization to the initialization of the device event + // handler. + // + + // + // Create a new instance of our device callback object + // + + hr = CMyDevice::CreateInstance(FxWdfDriver, FxDeviceInit, &device); + + // + // TODO: Change any per-device settings that the object exposes before + // calling Configure to let it complete its initialization. + // + + // + // If that succeeded then call the device's construct method. This + // allows the device to create any queues or other structures that it + // needs now that the corresponding fx device object has been created. + // + + if (SUCCEEDED(hr)) + { + hr = device->Configure(); + } + + // + // Release the reference on the device callback object now that it's been + // associated with an fx device object. + // + + if (NULL != device) + { + device->Release(); + } + + return hr; +} diff --git a/usb/wdf_osrfx2_lab/umdf/step2/Driver.h b/usb/wdf_osrfx2_lab/umdf/step2/Driver.h new file mode 100644 index 00000000..800ab1d9 --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step2/Driver.h @@ -0,0 +1,149 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + Driver.h + +Abstract: + + This module contains the type definitions for the UMDF Skeleton sample's + driver callback class. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once + +// +// This class handles driver events for the skeleton sample. In particular +// it supports the OnDeviceAdd event, which occurs when the driver is called +// to setup per-device handlers for a new device stack. +// + +class CMyDriver : public CUnknown, public IDriverEntry +{ +// +// Private data members. +// +private: + +// +// Private methods. +// +private: + + // + // Returns a refernced pointer to the IDriverEntry interface. + // + + IDriverEntry * + QueryIDriverEntry( + VOID + ) + { + AddRef(); + return static_cast<IDriverEntry*>(this); + } + + HRESULT + Initialize( + VOID + ); + +// +// Public methods +// +public: + + // + // The factory method used to create an instance of this driver. + // + + static + HRESULT + CreateInstance( + _Out_ PCMyDriver *Driver + ); + +// +// COM methods +// +public: + + // + // IDriverEntry methods + // + + virtual + HRESULT + STDMETHODCALLTYPE + OnInitialize( + _In_ IWDFDriver *FxWdfDriver + ) + { + UNREFERENCED_PARAMETER(FxWdfDriver); + + return S_OK; + } + + virtual + HRESULT + STDMETHODCALLTYPE + OnDeviceAdd( + _In_ IWDFDriver *FxWdfDriver, + _In_ IWDFDeviceInitialize *FxDeviceInit + ); + + virtual + VOID + STDMETHODCALLTYPE + OnDeinitialize( + _In_ IWDFDriver *FxWdfDriver + ) + { + UNREFERENCED_PARAMETER(FxWdfDriver); + + return; + } + + // + // IUnknown methods. + // + // We have to implement basic ones here that redirect to the + // base class becuase of the multiple inheritance. + // + + virtual + ULONG + STDMETHODCALLTYPE + AddRef( + VOID + ) + { + return __super::AddRef(); + } + + _At_(this, __drv_freesMem(object)) + virtual + ULONG + STDMETHODCALLTYPE + Release( + VOID + ) + { + return __super::Release(); + } + + virtual + HRESULT + STDMETHODCALLTYPE + QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ); +}; diff --git a/usb/wdf_osrfx2_lab/umdf/step2/OsrUsbFx2.ctl b/usb/wdf_osrfx2_lab/umdf/step2/OsrUsbFx2.ctl new file mode 100644 index 00000000..4dab56ae --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step2/OsrUsbFx2.ctl @@ -0,0 +1 @@ +da5fbdfd-1eae-4ecf-b426-a3818f325ddb WudfOsrUsbFx2TraceGuid diff --git a/usb/wdf_osrfx2_lab/umdf/step2/OsrUsbFx2.rc b/usb/wdf_osrfx2_lab/umdf/step2/OsrUsbFx2.rc new file mode 100644 index 00000000..36f10ea9 --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step2/OsrUsbFx2.rc @@ -0,0 +1,21 @@ +//--------------------------------------------------------------------------- +// OsrUsbDevice.rc +// +// Copyright (c) Microsoft Corporation, All Rights Reserved +//--------------------------------------------------------------------------- + + +#include <windows.h> +#include <ntverp.h> + +// +// TODO: Change the file description and file names to match your binary. +// + +#define VER_FILETYPE VFT_DLL +#define VER_FILESUBTYPE VFT_UNKNOWN +#define VER_FILEDESCRIPTION_STR "WDF:UMDF OSR USB Fx2 User-Mode Driver Sample" +#define VER_INTERNALNAME_STR "WUDFOsrUsbFx2" +#define VER_ORIGINALFILENAME_STR "WUDFOsrUsbFx2.dll" + +#include "common.ver" diff --git a/usb/wdf_osrfx2_lab/umdf/step2/WUDFOsrUsbFx2_2.inx b/usb/wdf_osrfx2_lab/umdf/step2/WUDFOsrUsbFx2_2.inx Binary files differnew file mode 100644 index 00000000..17baa44d --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step2/WUDFOsrUsbFx2_2.inx diff --git a/usb/wdf_osrfx2_lab/umdf/step2/WUDFOsrUsbFx2_2.vcxproj b/usb/wdf_osrfx2_lab/umdf/step2/WUDFOsrUsbFx2_2.vcxproj new file mode 100644 index 00000000..ee7c654f --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step2/WUDFOsrUsbFx2_2.vcxproj @@ -0,0 +1,267 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{808B6774-93FA-4ABF-A23F-35C55FA80B80}</ProjectGuid> + <RootNamespace>$(MSBuildProjectName)</RootNamespace> + <UMDF_VERSION_MAJOR>1</UMDF_VERSION_MAJOR> + <KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR> + <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration> + <Platform Condition="'$(Platform)' == ''">Win32</Platform> + <SampleGuid>{A944547C-61E9-47C5-82EC-797D95019735}</SampleGuid> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType>UMDF</DriverType> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType>UMDF</DriverType> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType>UMDF</DriverType> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType>UMDF</DriverType> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <OutDir>$(IntDir)</OutDir> + </PropertyGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ItemGroup Label="WrappedTaskItems"> + <ClCompile Include="dllsup.cpp; comsup.cpp; driver.cpp; device.cpp"> + <WppEnabled>true</WppEnabled> + <WppDllMacro>true</WppDllMacro> + <WppScanConfigurationData>internal.h</WppScanConfigurationData> + </ClCompile> + <OtherWpp Include="OsrUsbFx2.rc"> + <WppEnabled>true</WppEnabled> + <WppDllMacro>true</WppDllMacro> + <WppScanConfigurationData>internal.h</WppScanConfigurationData> + </OtherWpp> + </ItemGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetName>WUDFOsrUsbFx2_2</TargetName> + <WIN32_WINNT_VERSION>0x0A00</WIN32_WINNT_VERSION> + <NTDDI_VERSION>0x0A000000</NTDDI_VERSION> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetName>WUDFOsrUsbFx2_2</TargetName> + <WIN32_WINNT_VERSION>0x0A00</WIN32_WINNT_VERSION> + <NTDDI_VERSION>0x0A000000</NTDDI_VERSION> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetName>WUDFOsrUsbFx2_2</TargetName> + <WIN32_WINNT_VERSION>0x0A00</WIN32_WINNT_VERSION> + <NTDDI_VERSION>0x0A000000</NTDDI_VERSION> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetName>WUDFOsrUsbFx2_2</TargetName> + <WIN32_WINNT_VERSION>0x0A00</WIN32_WINNT_VERSION> + <NTDDI_VERSION>0x0A000000</NTDDI_VERSION> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <DisableSpecificWarnings>%(DisableSpecificWarnings);4201</DisableSpecificWarnings> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ClCompile> + <Midl> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </Midl> + <ResourceCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ResourceCompile> + <Link> + <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol> + <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <DisableSpecificWarnings>%(DisableSpecificWarnings);4201</DisableSpecificWarnings> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ClCompile> + <Midl> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </Midl> + <ResourceCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ResourceCompile> + <Link> + <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol> + <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <DisableSpecificWarnings>%(DisableSpecificWarnings);4201</DisableSpecificWarnings> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ClCompile> + <Midl> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </Midl> + <ResourceCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ResourceCompile> + <Link> + <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol> + <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <DisableSpecificWarnings>%(DisableSpecificWarnings);4201</DisableSpecificWarnings> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ClCompile> + <Midl> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </Midl> + <ResourceCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ResourceCompile> + <Link> + <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol> + <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\kernel32.lib;$(SDK_LIB_PATH)\advapi32.lib</AdditionalDependencies> + <ModuleDefinitionFile>exports.def</ModuleDefinitionFile> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\kernel32.lib;$(SDK_LIB_PATH)\advapi32.lib</AdditionalDependencies> + <ModuleDefinitionFile>exports.def</ModuleDefinitionFile> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\kernel32.lib;$(SDK_LIB_PATH)\advapi32.lib</AdditionalDependencies> + <ModuleDefinitionFile>exports.def</ModuleDefinitionFile> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\kernel32.lib;$(SDK_LIB_PATH)\advapi32.lib</AdditionalDependencies> + <ModuleDefinitionFile>exports.def</ModuleDefinitionFile> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ResourceCompile Include="OsrUsbFx2.rc" /> + </ItemGroup> + <ItemGroup> + <Inf Exclude="@(Inf)" Include="*.inf" /> + <FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" /> + </ItemGroup> + <ItemGroup> + <None Exclude="@(None)" Include="*.txt;*.htm;*.html" /> + <None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" /> + <None Exclude="@(None)" Include="*.def;*.bat;*.hpj;*.asmx" /> + </ItemGroup> + <ItemGroup> + <ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> +</Project>
\ No newline at end of file diff --git a/usb/wdf_osrfx2_lab/umdf/step2/WUDFOsrUsbFx2_2.vcxproj.Filters b/usb/wdf_osrfx2_lab/umdf/step2/WUDFOsrUsbFx2_2.vcxproj.Filters new file mode 100644 index 00000000..228729fe --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step2/WUDFOsrUsbFx2_2.vcxproj.Filters @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions> + <UniqueIdentifier>{CAFDA06D-52D2-4C5B-B355-1D19E80B1C72}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files"> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + <UniqueIdentifier>{2C5F0467-9539-41AD-95E0-0BD835F2F9EE}</UniqueIdentifier> + </Filter> + <Filter Include="Resource Files"> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions> + <UniqueIdentifier>{310FFCBB-E46B-43FA-B790-61A981127DBF}</UniqueIdentifier> + </Filter> + <Filter Include="Driver Files"> + <Extensions>inf;inv;inx;mof;mc;</Extensions> + <UniqueIdentifier>{04E87A31-118A-4F72-8349-D26123A6EE71}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="comsup.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="device.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="dllsup.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="driver.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <None Include="exports.def"> + <Filter>Source Files</Filter> + </None> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="OsrUsbFx2.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/usb/wdf_osrfx2_lab/umdf/step2/comsup.cpp b/usb/wdf_osrfx2_lab/umdf/step2/comsup.cpp new file mode 100644 index 00000000..9c9aec3b --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step2/comsup.cpp @@ -0,0 +1,344 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + ComSup.cpp + +Abstract: + + This module contains implementations for the functions and methods + used for providing COM support. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#include "internal.h" + +#include "comsup.tmh" + +// +// Implementation of CUnknown methods. +// + +CUnknown::CUnknown( + VOID + ) : m_ReferenceCount(1) +/*++ + + Routine Description: + + Constructor for an instance of the CUnknown class. This simply initializes + the reference count of the object to 1. The caller is expected to + call Release() if it wants to delete the object once it has been allocated. + + Arguments: + + None + + Return Value: + + None + +--*/ +{ + // do nothing. +} + +HRESULT +STDMETHODCALLTYPE +CUnknown::QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ) +/*++ + + Routine Description: + + This method provides the basic support for query interface on CUnknown. + If the interface requested is IUnknown it references the object and + returns an interface pointer. Otherwise it returns an error. + + Arguments: + + InterfaceId - the IID being requested + + Object - a location to store the interface pointer to return. + + Return Value: + + S_OK or E_NOINTERFACE + +--*/ +{ + if (IsEqualIID(InterfaceId, __uuidof(IUnknown))) + { + *Object = QueryIUnknown(); + return S_OK; + } + else + { + *Object = NULL; + return E_NOINTERFACE; + } +} + +IUnknown * +CUnknown::QueryIUnknown( + VOID + ) +/*++ + + Routine Description: + + This helper method references the object and returns a pointer to the + object's IUnknown interface. + + This allows other methods to convert a CUnknown pointer into an IUnknown + pointer without a typecast and without calling QueryInterface and dealing + with the return value. + + Arguments: + + None + + Return Value: + + A pointer to the object's IUnknown interface. + +--*/ +{ + AddRef(); + return static_cast<IUnknown *>(this); +} + +ULONG +STDMETHODCALLTYPE +CUnknown::AddRef( + VOID + ) +/*++ + + Routine Description: + + This method adds one to the object's reference count. + + Arguments: + + None + + Return Value: + + The new reference count. The caller should only use this for debugging + as the object's actual reference count can change while the caller + examines the return value. + +--*/ +{ + return InterlockedIncrement(&m_ReferenceCount); +} + +ULONG +STDMETHODCALLTYPE +CUnknown::Release( + VOID + ) +/*++ + + Routine Description: + + This method subtracts one to the object's reference count. If the count + goes to zero, this method deletes the object. + + Arguments: + + None + + Return Value: + + The new reference count. If the caller uses this value it should only be + to check for zero (i.e. this call caused or will cause deletion) or + non-zero (i.e. some other call may have caused deletion, but this one + didn't). + +--*/ +{ + ULONG count = InterlockedDecrement(&m_ReferenceCount); + + if (count == 0) + { + delete this; + } + return count; +} + +// +// Implementation of CClassFactory methods. +// + +// +// Define storage for the factory's static lock count variable. +// + +LONG CClassFactory::s_LockCount = 0; + +IClassFactory * +CClassFactory::QueryIClassFactory( + VOID + ) +/*++ + + Routine Description: + + This helper method references the object and returns a pointer to the + object's IClassFactory interface. + + This allows other methods to convert a CClassFactory pointer into an + IClassFactory pointer without a typecast and without dealing with the + return value QueryInterface. + + Arguments: + + None + + Return Value: + + A referenced pointer to the object's IClassFactory interface. + +--*/ +{ + AddRef(); + return static_cast<IClassFactory *>(this); +} + +HRESULT +CClassFactory::QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ) +/*++ + + Routine Description: + + This method attempts to retrieve the requested interface from the object. + + If the interface is found then the reference count on that interface (and + thus the object itself) is incremented. + + Arguments: + + InterfaceId - the interface the caller is requesting. + + Object - a location to store the interface pointer. + + Return Value: + + S_OK or E_NOINTERFACE + +--*/ +{ + // + // This class only supports IClassFactory so check for that. + // + + if (IsEqualIID(InterfaceId, __uuidof(IClassFactory))) + { + *Object = QueryIClassFactory(); + return S_OK; + } + else + { + // + // See if the base class supports the interface. + // + + return CUnknown::QueryInterface(InterfaceId, Object); + } +} + +HRESULT +STDMETHODCALLTYPE +CClassFactory::CreateInstance( + _In_opt_ IUnknown * /* OuterObject */, + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ) +/*++ + + Routine Description: + + This COM method is the factory routine - it creates instances of the driver + callback class and returns the specified interface on them. + + Arguments: + + OuterObject - only used for aggregation, which our driver callback class + does not support. + + InterfaceId - the interface ID the caller would like to get from our + new object. + + Object - a location to store the referenced interface pointer to the new + object. + + Return Value: + + Status. + +--*/ +{ + HRESULT hr; + + PCMyDriver driver; + + *Object = NULL; + + hr = CMyDriver::CreateInstance(&driver); + + if (SUCCEEDED(hr)) + { + hr = driver->QueryInterface(InterfaceId, Object); + driver->Release(); + } + + return hr; +} + +HRESULT +STDMETHODCALLTYPE +CClassFactory::LockServer( + _In_ BOOL Lock + ) +/*++ + + Routine Description: + + This COM method can be used to keep the DLL in memory. However since the + driver's DllCanUnloadNow function always returns false, this has little + effect. Still it tracks the number of lock and unlock operations. + + Arguments: + + Lock - Whether the caller wants to lock or unlock the "server" + + Return Value: + + S_OK + +--*/ +{ + if (Lock) + { + InterlockedIncrement(&s_LockCount); + } + else + { + InterlockedDecrement(&s_LockCount); + } + return S_OK; +} + diff --git a/usb/wdf_osrfx2_lab/umdf/step2/comsup.h b/usb/wdf_osrfx2_lab/umdf/step2/comsup.h new file mode 100644 index 00000000..dedf78c8 --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step2/comsup.h @@ -0,0 +1,215 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + ComSup.h + +Abstract: + + This module contains classes and functions use for providing COM support + code. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once + +// +// Forward type declarations. They are here rather than in internal.h as +// you only need them if you choose to use these support classes. +// + +typedef class CUnknown *PCUnknown; +typedef class CClassFactory *PCClassFactory; + +// +// Base class to implement IUnknown. You can choose to derive your COM +// classes from this class, or simply implement IUnknown in each of your +// classes. +// + +class CUnknown : public IUnknown +{ + +// +// Private data members and methods. These are only accessible by the methods +// of this class. +// +private: + + // + // The reference count for this object. Initialized to 1 in the + // constructor. + // + + LONG m_ReferenceCount; + +// +// Protected data members and methods. These are accessible by the subclasses +// but not by other classes. +// +protected: + + // + // The constructor and destructor are protected to ensure that only the + // subclasses of CUnknown can create and destroy instances. + // + + CUnknown( + VOID + ); + + // + // The destructor MUST be virtual. Since any instance of a CUnknown + // derived class should only be deleted from within CUnknown::Release, + // the destructor MUST be virtual or only CUnknown::~CUnknown will get + // invoked on deletion. + // + // If you see that your CMyDevice specific destructor is never being + // called, make sure you haven't deleted the virtual destructor here. + // + + virtual + ~CUnknown( + VOID + ) + { + // Do nothing + } + +// +// Public Methods. These are accessible by any class. +// +public: + + IUnknown * + QueryIUnknown( + VOID + ); + +// +// COM Methods. +// +public: + + // + // IUnknown methods + // + + virtual + ULONG + STDMETHODCALLTYPE + AddRef( + VOID + ); + + virtual + ULONG + STDMETHODCALLTYPE + Release( + VOID + ); + + virtual + HRESULT + STDMETHODCALLTYPE + QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ); +}; + +// +// Class factory support class. Create an instance of this from your +// DllGetClassObject method and modify the implementation to create +// an instance of your driver event handler class. +// + +class CClassFactory : public CUnknown, public IClassFactory +{ +// +// Private data members and methods. These are only accessible by the methods +// of this class. +// +private: + + // + // The lock count. This is shared across all instances of IClassFactory + // and can be queried through the public IsLocked method. + // + + static LONG s_LockCount; + +// +// Public Methods. These are accessible by any class. +// +public: + + IClassFactory * + QueryIClassFactory( + VOID + ); + +// +// COM Methods. +// +public: + + // + // IUnknown methods + // + + virtual + ULONG + STDMETHODCALLTYPE + AddRef( + VOID + ) + { + return __super::AddRef(); + } + + _At_(this, __drv_freesMem(object)) + virtual + ULONG + STDMETHODCALLTYPE + Release( + VOID + ) + { + return __super::Release(); + } + + virtual + HRESULT + STDMETHODCALLTYPE + QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ); + + // + // IClassFactory methods. + // + + virtual + HRESULT + STDMETHODCALLTYPE + CreateInstance( + _In_opt_ IUnknown *OuterObject, + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ); + + virtual + HRESULT + STDMETHODCALLTYPE + LockServer( + _In_ BOOL Lock + ); +}; diff --git a/usb/wdf_osrfx2_lab/umdf/step2/dllsup.cpp b/usb/wdf_osrfx2_lab/umdf/step2/dllsup.cpp new file mode 100644 index 00000000..e8bad81b --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step2/dllsup.cpp @@ -0,0 +1,202 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved. + +Module Name: + + dllsup.cpp + +Abstract: + + This module contains the implementation of the UMDF Skeleton Sample + Driver's entry point and its exported functions for providing COM support. + + This module can be copied without modification to a new UMDF driver. It + depends on some of the code in comsup.cpp & comsup.h to handle DLL + registration and creating the first class factory. + + This module is dependent on the following defines: + + MYDRIVER_TRACING_ID - A wide string passed to WPP when initializing + tracing. For example the skeleton uses + L"Microsoft\\UMDF\\Skeleton" + + MYDRIVER_CLASS_ID - A GUID encoded in struct format used to + initialize the driver's ClassID. + + These are defined in internal.h for the skeleton sample. If you choose + to use a different primary include file, you should ensure they are + defined there as well. + +Environment: + + WDF User-Mode Driver Framework (WDF:UMDF) + +--*/ + +#include "internal.h" +#include "dllsup.tmh" + +const GUID CLSID_MyDriverCoClass = MYDRIVER_CLASS_ID; + +BOOL +WINAPI +DllMain( + HINSTANCE ModuleHandle, + DWORD Reason, + PVOID /* Reserved */ + ) +/*++ + + Routine Description: + + This is the entry point and exit point for the I/O trace driver. This + does very little as the I/O trace driver has minimal global data. + + This method initializes tracing, and saves the module handle away in a + global variable so that it can be referenced should the COM registration + code (Dll[Un]RegisterServer) be called. + + Arguments: + + ModuleHandle - the DLL handle for this module. + + Reason - the reason this entry point was called. + + Reserved - unused + + Return Value: + + TRUE + +--*/ +{ + UNREFERENCED_PARAMETER(ModuleHandle); + + if (DLL_PROCESS_ATTACH == Reason) + { + // + // Initialize tracing. + // + + WPP_INIT_TRACING(MYDRIVER_TRACING_ID); + } + else if (DLL_PROCESS_DETACH == Reason) + { + // + // Cleanup tracing. + // + + WPP_CLEANUP(); + } + + return TRUE; +} + +HRESULT +STDAPICALLTYPE +DllCanUnloadNow( + VOID + ) +/*++ + + Routine Description: + + Called by the COM runtime when determining whether or not this module + can be unloaded. Our answer is always "no". + + Arguments: + + None + + Return Value: + + S_FALSE + +--*/ +{ + return S_FALSE; +} + +HRESULT +STDAPICALLTYPE +DllGetClassObject( + _In_ REFCLSID ClassId, + _In_ REFIID InterfaceId, + _Outptr_ LPVOID *Interface + ) +/*++ + + Routine Description: + + This routine is called by COM in order to instantiate the + skeleton driver callback object and do an initial query interface on it. + + This method only creates an instance of the driver's class factory, as this + is the minimum required to support UMDF. + + Arguments: + + ClassId - the CLSID of the object being "gotten" + + InterfaceId - the interface the caller wants from that object. + + Interface - a location to store the referenced interface pointer + + Return Value: + + S_OK if the function succeeds or error indicating the cause of the + failure. + +--*/ +{ + PCClassFactory factory; + + HRESULT hr = S_OK; + + *Interface = NULL; + + // + // If the CLSID doesn't match that of our "coclass" (defined in the IDL + // file) then we can't create the object the caller wants. This may + // indicate that the COM registration is incorrect, and another CLSID + // is referencing this drvier. + // + + if (IsEqualCLSID(ClassId, CLSID_MyDriverCoClass) == false) + { + Trace( + TRACE_LEVEL_ERROR, + L"ERROR: Called to create instance of unrecognized class (%!GUID!)", + &ClassId + ); + + return CLASS_E_CLASSNOTAVAILABLE; + } + + // + // Create an instance of the class factory for the caller. + // + + factory = new CClassFactory(); + + if (NULL == factory) + { + hr = E_OUTOFMEMORY; + } + + // + // Query the object we created for the interface the caller wants. After + // that we release the object. This will drive the reference count to + // 1 (if the QI succeeded an referenced the object) or 0 (if the QI failed). + // In the later case the object is automatically deleted. + // + + if (SUCCEEDED(hr)) + { + hr = factory->QueryInterface(InterfaceId, Interface); + factory->Release(); + } + + return hr; +} diff --git a/usb/wdf_osrfx2_lab/umdf/step2/exports.def b/usb/wdf_osrfx2_lab/umdf/step2/exports.def new file mode 100644 index 00000000..15f923d3 --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step2/exports.def @@ -0,0 +1,4 @@ +; WudfOsrUsbDriver.def : Declares the module parameters. + +EXPORTS + DllGetClassObject PRIVATE diff --git a/usb/wdf_osrfx2_lab/umdf/step2/internal.h b/usb/wdf_osrfx2_lab/umdf/step2/internal.h new file mode 100644 index 00000000..374931e0 --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step2/internal.h @@ -0,0 +1,150 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + Internal.h + +Abstract: + + This module contains the local type definitions for the UMDF Skeleton + driver sample. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) +#endif + +// +// Include the WUDF Headers +// + +#include "wudfddi.h" + +// +// Use specstrings for in/out annotation of function parameters. +// + +#include "specstrings.h" + +// +// Get limits on common data types (ULONG_MAX for example) +// + +#include "limits.h" + +// +// We need usb I/O targets to talk to the OSR device. +// + +#include "wudfusb.h" + +// +// Include the header shared between the drivers and the test applications. +// + +#include "public.h" + +// +// Include the header shared between the drivers and the test applications. +// + +#include "WUDFOsrUsbPublic.h" + +// +// Forward definitions of classes in the other header files. +// + +typedef class CMyDriver *PCMyDriver; +typedef class CMyDevice *PCMyDevice; +typedef class CMyQueue *PCMyQueue; + +typedef class CMyControlQueue *PCMyControlQueue; + +// +// Define the tracing flags. +// +// TODO: Choose a different trace control GUID +// + +#define WPP_CONTROL_GUIDS \ + WPP_DEFINE_CONTROL_GUID( \ + WudfOsrUsbFx2TraceGuid, (da5fbdfd,1eae,4ecf,b426,a3818f325ddb), \ + \ + WPP_DEFINE_BIT(MYDRIVER_ALL_INFO) \ + WPP_DEFINE_BIT(TEST_TRACE_DRIVER) \ + WPP_DEFINE_BIT(TEST_TRACE_DEVICE) \ + WPP_DEFINE_BIT(TEST_TRACE_QUEUE) \ + ) + +#define WPP_FLAG_LEVEL_LOGGER(flag, level) \ + WPP_LEVEL_LOGGER(flag) + +#define WPP_FLAG_LEVEL_ENABLED(flag, level) \ + (WPP_LEVEL_ENABLED(flag) && \ + WPP_CONTROL(WPP_BIT_ ## flag).Level >= level) + +#define WPP_LEVEL_FLAGS_LOGGER(lvl,flags) \ + WPP_LEVEL_LOGGER(flags) + +#define WPP_LEVEL_FLAGS_ENABLED(lvl, flags) \ + (WPP_LEVEL_ENABLED(flags) && WPP_CONTROL(WPP_BIT_ ## flags).Level >= lvl) + +// +// This comment block is scanned by the trace preprocessor to define our +// Trace function. +// +// begin_wpp config +// FUNC Trace{FLAG=MYDRIVER_ALL_INFO}(LEVEL, MSG, ...); +// FUNC TraceEvents(LEVEL, FLAGS, MSG, ...); +// end_wpp +// + +// +// Driver specific #defines +// +// TODO: Change these values to be appropriate for your driver. +// + +#define MYDRIVER_TRACING_ID L"Microsoft\\UMDF\\OsrUsb" +#define MYDRIVER_CLASS_ID {0x0865b2b0, 0x6b73, 0x428f, {0xa3, 0xea, 0x21, 0x72, 0x83, 0x2d, 0x6b, 0xfc}} + +// +// Include the type specific headers. +// + +#include "comsup.h" +#include "driver.h" +#include "device.h" +#include "list.h" + +__forceinline +#ifdef _PREFAST_ +__declspec(noreturn) +#endif +VOID +WdfTestNoReturn( + VOID + ) +{ + // do nothing. +} + +#define WUDF_TEST_DRIVER_ASSERT(p) \ +{ \ + if ( !(p) ) \ + { \ + DebugBreak(); \ + WdfTestNoReturn(); \ + } \ +} + +#define SAFE_RELEASE(p) {if ((p)) { (p)->Release(); (p) = NULL; }} diff --git a/usb/wdf_osrfx2_lab/umdf/step3/ControlQueue.cpp b/usb/wdf_osrfx2_lab/umdf/step3/ControlQueue.cpp new file mode 100644 index 00000000..48de237d --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step3/ControlQueue.cpp @@ -0,0 +1,246 @@ +/*++ + +Copyright (c) Microsoft Corporation, All Rights Reserved + +Module Name: + + ControlQueue.cpp + +Abstract: + + This file implements the I/O queue interface and performs + the ioctl operations. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#include "internal.h" + +#include "winioctl.h" + +#include "ControlQueue.tmh" + +CMyControlQueue::CMyControlQueue( + _In_ PCMyDevice Device + ) : CMyQueue(Device) +{ + +} + +HRESULT +STDMETHODCALLTYPE +CMyControlQueue::QueryInterface( + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ) +/*++ + +Routine Description: + + + Query Interface + +Aruments: + + Follows COM specifications + +Return Value: + + HRESULT indicatin success or failure + +--*/ +{ + HRESULT hr; + + + if (IsEqualIID(InterfaceId, __uuidof(IQueueCallbackDeviceIoControl))) + { + hr = S_OK; + *Object = QueryIQueueCallbackDeviceIoControl(); + + } + else + { + hr = CMyQueue::QueryInterface(InterfaceId, Object); + } + + return hr; +} + +// +// Initialize +// + +HRESULT +CMyControlQueue::CreateInstance( + _In_ PCMyDevice Device, + _Out_ PCMyControlQueue *Queue + ) +/*++ + +Routine Description: + + + CreateInstance creates an instance of the queue object. + +Aruments: + + ppUkwn - OUT parameter is an IUnknown interface to the queue object + +Return Value: + + HRESULT indicatin success or failure + +--*/ +{ + PCMyControlQueue queue = NULL; + HRESULT hr = S_OK; + + queue = new CMyControlQueue(Device); + + if (NULL == queue) + { + hr = E_OUTOFMEMORY; + } + + // + // Call the queue callback object to initialize itself. This will create + // its partner queue framework object. + // + + if (SUCCEEDED(hr)) + { + hr = queue->Initialize(); + } + + if (SUCCEEDED(hr)) + { + *Queue = queue; + } + else + { + SAFE_RELEASE(queue); + } + + return hr; +} + +HRESULT +CMyControlQueue::Initialize( + VOID + ) +{ + HRESULT hr; + + // + // First initialize the base class. This will create the partner FxIoQueue + // object and setup automatic forwarding of I/O controls. + // + + hr = __super::Initialize(WdfIoQueueDispatchSequential, + false, + true); + + // + // return the status. + // + + return hr; +} + +VOID +STDMETHODCALLTYPE +CMyControlQueue::OnDeviceIoControl( + _In_ IWDFIoQueue *FxQueue, + _In_ IWDFIoRequest *FxRequest, + _In_ ULONG ControlCode, + _In_ SIZE_T InputBufferSizeInBytes, + _In_ SIZE_T OutputBufferSizeInBytes + ) +/*++ + +Routine Description: + + + DeviceIoControl dispatch routine + +Aruments: + + FxQueue - Framework Queue instance + FxRequest - Framework Request instance + ControlCode - IO Control Code + InputBufferSizeInBytes - Lenth of input buffer + OutputBufferSizeInBytes - Lenth of output buffer + + Always succeeds DeviceIoIoctl +Return Value: + + VOID + +--*/ +{ + UNREFERENCED_PARAMETER(FxQueue); + UNREFERENCED_PARAMETER(OutputBufferSizeInBytes); + + IWDFMemory *memory = NULL; + PVOID buffer; + + SIZE_T bigBufferCb; + + ULONG information = 0; + + bool completeRequest = true; + + HRESULT hr = S_OK; + + switch (ControlCode) + { + case IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY: + { + // + // Make sure the buffer is big enough to hold the input for the + // control transfer. + // + + if (InputBufferSizeInBytes < sizeof(BAR_GRAPH_STATE)) + { + hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); + } + else + { + FxRequest->GetInputMemory(&memory); + } + + // + // Get the data buffer and use it to set the bar graph on the + // device. + // + + if (SUCCEEDED(hr)) + { + buffer = memory->GetDataBuffer(&bigBufferCb); + memory->Release(); + + hr = m_Device->SetBarGraphDisplay((PBAR_GRAPH_STATE) buffer); + } + + break; + } + + default: + { + hr = HRESULT_FROM_WIN32(ERROR_INVALID_FUNCTION); + break; + } + } + + if (completeRequest) + { + FxRequest->CompleteWithInformation(hr, information); + } + + return; +} diff --git a/usb/wdf_osrfx2_lab/umdf/step3/ControlQueue.h b/usb/wdf_osrfx2_lab/umdf/step3/ControlQueue.h new file mode 100644 index 00000000..251521e1 --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step3/ControlQueue.h @@ -0,0 +1,101 @@ +/*++ + +Copyright (c) Microsoft Corporation, All Rights Reserved + +Module Name: + + ControlQueue.h + +Abstract: + + This file defines the queue callback object for handling device I/O + control requests. This is a serialized queue. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once + +// +// Queue Callback Object. +// + +class CMyControlQueue : public IQueueCallbackDeviceIoControl, + public CMyQueue +{ + HRESULT + Initialize( + VOID + ); + +public: + + CMyControlQueue( + _In_ PCMyDevice Device + ); + + virtual + ~CMyControlQueue( + VOID + ) + { + return; + } + + static + HRESULT + CreateInstance( + _In_ PCMyDevice Device, + _Out_ PCMyControlQueue *Queue + ); + + HRESULT + Configure( + VOID + ) + { + return S_OK; + } + + IQueueCallbackDeviceIoControl * + QueryIQueueCallbackDeviceIoControl( + VOID + ) + { + AddRef(); + return static_cast<IQueueCallbackDeviceIoControl *>(this); + } + + // + // IUnknown + // + + STDMETHOD_(ULONG,AddRef) (VOID) {return CUnknown::AddRef();} + + _At_(this, __drv_freesMem(object)) + STDMETHOD_(ULONG,Release) (VOID) {return CUnknown::Release();} + + STDMETHOD_(HRESULT, QueryInterface)( + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ); + + // + // Wdf Callbacks + // + + // + // IQueueCallbackDeviceIoControl + // + STDMETHOD_ (void, OnDeviceIoControl)( + _In_ IWDFIoQueue *pWdfQueue, + _In_ IWDFIoRequest *pWdfRequest, + _In_ ULONG ControlCode, + _In_ SIZE_T InputBufferSizeInBytes, + _In_ SIZE_T OutputBufferSizeInBytes + ); +}; + diff --git a/usb/wdf_osrfx2_lab/umdf/step3/Device.cpp b/usb/wdf_osrfx2_lab/umdf/step3/Device.cpp new file mode 100644 index 00000000..20c997c5 --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step3/Device.cpp @@ -0,0 +1,644 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved. + +Module Name: + + Device.cpp + +Abstract: + + This module contains the implementation of the UMDF Skeleton sample driver's + device callback object. + + The skeleton sample device does very little. It does not implement either + of the PNP interfaces so once the device is setup, it won't ever get any + callbacks until the device is removed. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#include "internal.h" +#include "initguid.h" +#include "usb_hw.h" + +#include "device.tmh" + +CMyDevice::~CMyDevice( + ) +{ +} + +HRESULT +CMyDevice::CreateInstance( + _In_ IWDFDriver *FxDriver, + _In_ IWDFDeviceInitialize * FxDeviceInit, + _Out_ PCMyDevice *Device + ) +/*++ + + Routine Description: + + This method creates and initializs an instance of the skeleton driver's + device callback object. + + Arguments: + + FxDeviceInit - the settings for the device. + + Device - a location to store the referenced pointer to the device object. + + Return Value: + + Status + +--*/ +{ + PCMyDevice device; + HRESULT hr; + + // + // Allocate a new instance of the device class. + // + + device = new CMyDevice(); + + if (NULL == device) + { + return E_OUTOFMEMORY; + } + + // + // Initialize the instance. + // + + hr = device->Initialize(FxDriver, FxDeviceInit); + + if (SUCCEEDED(hr)) + { + *Device = device; + } + else + { + device->Release(); + } + + return hr; +} + +HRESULT +CMyDevice::Initialize( + _In_ IWDFDriver * FxDriver, + _In_ IWDFDeviceInitialize * FxDeviceInit + ) +/*++ + + Routine Description: + + This method initializes the device callback object and creates the + partner device object. + + The method should perform any device-specific configuration that: + * could fail (these can't be done in the constructor) + * must be done before the partner object is created -or- + * can be done after the partner object is created and which aren't + influenced by any device-level parameters the parent (the driver + in this case) might set. + + Arguments: + + FxDeviceInit - the settings for this device. + + Return Value: + + status. + +--*/ +{ + IWDFDevice *fxDevice = NULL; + + HRESULT hr = S_OK; + + // + // TODO: If you're writing a filter driver then indicate that here. + // + // FxDeviceInit->SetFilter(); + // + + // + // Set no locking unless you need an automatic callbacks synchronization + // + + FxDeviceInit->SetLockingConstraint(None); + + // + // TODO: Any per-device initialization which must be done before + // creating the partner object. + // + + // + // Create a new FX device object and assign the new callback object to + // handle any device level events that occur. + // + + // + // QueryIUnknown references the IUnknown interface that it returns + // (which is the same as referencing the device). We pass that to + // CreateDevice, which takes its own reference if everything works. + // + + if (SUCCEEDED(hr)) + { + IUnknown *unknown = this->QueryIUnknown(); + + hr = FxDriver->CreateDevice(FxDeviceInit, unknown, &fxDevice); + + unknown->Release(); + } + + // + // If that succeeded then set our FxDevice member variable. + // + + if (SUCCEEDED(hr)) + { + m_FxDevice = fxDevice; + + // + // Drop the reference we got from CreateDevice. Since this object + // is partnered with the framework object they have the same + // lifespan - there is no need for an additional reference. + // + + fxDevice->Release(); + } + + return hr; +} + +HRESULT +CMyDevice::Configure( + VOID + ) +/*++ + + Routine Description: + + This method is called after the device callback object has been initialized + and returned to the driver. It would setup the device's queues and their + corresponding callback objects. + + Arguments: + + FxDevice - the framework device object for which we're handling events. + + Return Value: + + status + +--*/ +{ + HRESULT hr = S_OK; + + + // + // Create the control queue and configure forwarding for IOCTL requests. + // + + if (SUCCEEDED(hr)) + { + hr = CMyControlQueue::CreateInstance(this, &m_ControlQueue); + + if (SUCCEEDED(hr)) + { + hr = m_ControlQueue->Configure(); + if (SUCCEEDED(hr)) + { + hr = m_FxDevice->ConfigureRequestDispatching( + m_ControlQueue->GetFxQueue(), + WdfRequestDeviceIoControl, + true + ); + } + m_ControlQueue->Release(); + } + } + + if (SUCCEEDED(hr)) + { + hr = m_FxDevice->CreateDeviceInterface(&GUID_DEVINTERFACE_OSRUSBFX2, + NULL); + } + + return hr; +} + +HRESULT +CMyDevice::QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ) +/*++ + + Routine Description: + + This method is called to get a pointer to one of the object's callback + interfaces. + + Since the skeleton driver doesn't support any of the device events, this + method simply calls the base class's BaseQueryInterface. + + If the skeleton is extended to include device event interfaces then this + method must be changed to check the IID and return pointers to them as + appropriate. + + Arguments: + + InterfaceId - the interface being requested + + Object - a location to store the interface pointer if successful + + Return Value: + + S_OK or E_NOINTERFACE + +--*/ +{ + HRESULT hr; + + if (IsEqualIID(InterfaceId, __uuidof(IPnpCallbackHardware))) + { + *Object = QueryIPnpCallbackHardware(); + hr = S_OK; + } + else + { + hr = CUnknown::QueryInterface(InterfaceId, Object); + } + + return hr; +} + +HRESULT +CMyDevice::OnPrepareHardware( + _In_ IWDFDevice * /* FxDevice */ + ) +/*++ + +Routine Description: + + This routine is invoked to ready the driver + to talk to hardware. It opens the handle to the + device and talks to it using the WINUSB interface. + It invokes WINUSB to discver the interfaces and stores + the information related to bulk endpoints. + +Arguments: + + FxDevice : Pointer to the WDF device interface + +Return Value: + + HRESULT + +--*/ +{ + PWSTR deviceName = NULL; + DWORD deviceNameCch = 0; + + HRESULT hr; + + // + // Get the device name. + // Get the length to allocate first + // + + hr = m_FxDevice->RetrieveDeviceName(NULL, &deviceNameCch); + + if (FAILED(hr)) + { + TraceEvents(TRACE_LEVEL_ERROR, + TEST_TRACE_DEVICE, + "%!FUNC! Cannot get device name %!hresult!", + hr + ); + } + + // + // Allocate the buffer + // + + if (SUCCEEDED(hr)) + { + deviceName = new WCHAR[deviceNameCch]; + + if (deviceName == NULL) + { + hr = E_OUTOFMEMORY; + } + } + + // + // Get the actual name + // + + if (SUCCEEDED(hr)) + { + hr = m_FxDevice->RetrieveDeviceName(deviceName, &deviceNameCch); + + if (FAILED(hr)) + { + TraceEvents(TRACE_LEVEL_ERROR, + TEST_TRACE_DEVICE, + "%!FUNC! Cannot get device name %!hresult!", + hr + ); + } + } + + if (SUCCEEDED(hr)) + { + TraceEvents(TRACE_LEVEL_INFORMATION, + TEST_TRACE_DEVICE, + "%!FUNC! Device name %S", + deviceName + ); + } + + // + // Create USB I/O Targets and configure them + // + + if (SUCCEEDED(hr)) + { + hr = CreateUsbIoTargets(); + } + + if (SUCCEEDED(hr)) + { + ULONG length = sizeof(m_Speed); + + hr = m_pIUsbTargetDevice->RetrieveDeviceInformation(DEVICE_SPEED, + &length, + &m_Speed); + if (FAILED(hr)) + { + TraceEvents(TRACE_LEVEL_ERROR, + TEST_TRACE_DEVICE, + "%!FUNC! Cannot get usb device speed information %!HRESULT!", + hr + ); + } + } + + if (SUCCEEDED(hr)) + { + TraceEvents(TRACE_LEVEL_INFORMATION, + TEST_TRACE_DEVICE, + "%!FUNC! Speed - %x\n", + m_Speed + ); + } + + delete[] deviceName; + + return hr; +} + +HRESULT +CMyDevice::OnReleaseHardware( + _In_ IWDFDevice * /* FxDevice */ + ) +/*++ + +Routine Description: + + This routine is invoked when the device is being removed or stopped + It releases all resources allocated for this device. + +Arguments: + + FxDevice - Pointer to the Device object. + +Return Value: + + HRESULT - Always succeeds. + +--*/ +{ + // + // Remove I/O target from object tree before any potential subsequent + // OnPrepareHardware creates a new one + // + + if (m_pIUsbTargetDevice) + { + m_pIUsbTargetDevice->DeleteWdfObject(); + } + + return S_OK; +} + +HRESULT +CMyDevice::CreateUsbIoTargets( + ) +/*++ + +Routine Description: + + This routine creates Usb device, interface and pipe objects + +Arguments: + + None + +Return Value: + + HRESULT +--*/ +{ + HRESULT hr; + IWDFUsbTargetFactory * pIUsbTargetFactory = NULL; + IWDFUsbTargetDevice * pIUsbTargetDevice = NULL; + + hr = m_FxDevice->QueryInterface(IID_PPV_ARGS(&pIUsbTargetFactory)); + + if (FAILED(hr)) + { + TraceEvents(TRACE_LEVEL_ERROR, + TEST_TRACE_DEVICE, + "%!FUNC! Cannot get usb target factory %!HRESULT!", + hr + ); + } + + if (SUCCEEDED(hr)) + { + hr = pIUsbTargetFactory->CreateUsbTargetDevice( + &pIUsbTargetDevice); + if (FAILED(hr)) + { + TraceEvents(TRACE_LEVEL_ERROR, + TEST_TRACE_DEVICE, + "%!FUNC! Unable to create USB Device I/O Target %!HRESULT!", + hr + ); + } + } + + if (SUCCEEDED(hr)) + { + m_pIUsbTargetDevice = pIUsbTargetDevice; + + // + // Release the creation reference as object tree will maintain a reference + // + + pIUsbTargetDevice->Release(); + } + + SAFE_RELEASE(pIUsbTargetFactory); + + return hr; +} + +HRESULT +CMyDevice::SetBarGraphDisplay( + _In_ PBAR_GRAPH_STATE BarGraphState + ) +/*++ + + Routine Description: + + This method synchronously sets the bar graph display on the OSR USB-FX2 + device using the buffers in the FxRequest as input. + + Arguments: + + FxRequest - the request to set the bar-graph info. + + Return Value: + + Status + +--*/ +{ + WINUSB_CONTROL_SETUP_PACKET setupPacket; + + ULONG bytesTransferred; + + HRESULT hr = S_OK; + + // + // Setup the control packet. + // + + WINUSB_CONTROL_SETUP_PACKET_INIT( &setupPacket, + BmRequestHostToDevice, + BmRequestToDevice, + USBFX2LK_SET_BARGRAPH_DISPLAY, + 0, + 0 ); + + // + // Issue the request to WinUsb. + // + + hr = SendControlTransferSynchronously( + &(setupPacket.WinUsb), + (PUCHAR) BarGraphState, + sizeof(BAR_GRAPH_STATE), + &bytesTransferred + ); + + + return hr; +} + +HRESULT +CMyDevice::SendControlTransferSynchronously( + _In_ PWINUSB_SETUP_PACKET SetupPacket, + _Inout_updates_(BufferLength) PBYTE Buffer, + _In_ ULONG BufferLength, + _Out_ PULONG LengthTransferred + ) +{ + HRESULT hr = S_OK; + HRESULT hrRequest = S_OK; + IWDFIoRequest *pWdfRequest = NULL; + IWDFDriver * FxDriver = NULL; + IWDFMemory * FxMemory = NULL; + IWDFRequestCompletionParams * FxComplParams = NULL; + IWDFUsbRequestCompletionParams * FxUsbComplParams = NULL; + + *LengthTransferred = 0; + + hr = m_FxDevice->CreateRequest( NULL, //pCallbackInterface + NULL, //pParentObject + &pWdfRequest); + hrRequest = hr; + + if (SUCCEEDED(hr)) + { + m_FxDevice->GetDriver(&FxDriver); + + hr = FxDriver->CreatePreallocatedWdfMemory( Buffer, + BufferLength, + NULL, //pCallbackInterface + pWdfRequest, //pParetObject + &FxMemory ); + } + + if (SUCCEEDED(hr)) + { + hr = m_pIUsbTargetDevice->FormatRequestForControlTransfer( pWdfRequest, + SetupPacket, + FxMemory, + NULL); //TransferOffset + } + + if (SUCCEEDED(hr)) + { + hr = pWdfRequest->Send( m_pIUsbTargetDevice, + WDF_REQUEST_SEND_OPTION_SYNCHRONOUS, + 0); //Timeout + } + + if (SUCCEEDED(hr)) + { + pWdfRequest->GetCompletionParams(&FxComplParams); + + hr = FxComplParams->GetCompletionStatus(); + } + + if (SUCCEEDED(hr)) + { + HRESULT hrQI = FxComplParams->QueryInterface(IID_PPV_ARGS(&FxUsbComplParams)); + WUDF_TEST_DRIVER_ASSERT(SUCCEEDED(hrQI)); + + WUDF_TEST_DRIVER_ASSERT( WdfUsbRequestTypeDeviceControlTransfer == + FxUsbComplParams->GetCompletedUsbRequestType() ); + + FxUsbComplParams->GetDeviceControlTransferParameters( NULL, + LengthTransferred, + NULL, + NULL ); + } + + SAFE_RELEASE(FxUsbComplParams); + SAFE_RELEASE(FxComplParams); + SAFE_RELEASE(FxMemory); + + if (SUCCEEDED(hrRequest)) + { + pWdfRequest->DeleteWdfObject(); + } + SAFE_RELEASE(pWdfRequest); + + SAFE_RELEASE(FxDriver); + + return hr; +} diff --git a/usb/wdf_osrfx2_lab/umdf/step3/Device.h b/usb/wdf_osrfx2_lab/umdf/step3/Device.h new file mode 100644 index 00000000..6d343582 --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step3/Device.h @@ -0,0 +1,203 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + Device.h + +Abstract: + + This module contains the type definitions for the UMDF Skeleton sample + driver's device callback class. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once +#include "internal.h" + +// +// Define the vendor commands supported by our device +// +#define USBFX2LK_SET_BARGRAPH_DISPLAY 0xD8 + +// +// Class for the iotrace driver. +// + +class CMyDevice : + public CUnknown, + public IPnpCallbackHardware +{ + +// +// Private data members. +// +private: + // + // Weak reference to framework device + // + IWDFDevice *m_FxDevice; + + // + // Weak reference to the control queue + // + PCMyControlQueue m_ControlQueue; + + // + // USB Device I/O Target + // + IWDFUsbTargetDevice * m_pIUsbTargetDevice; + + + // + // Device Speed (Low, Full, High) + // + UCHAR m_Speed; + +// +// Private methods. +// + +private: + + CMyDevice( + VOID + ) : + m_FxDevice(NULL), + m_ControlQueue(NULL), + m_pIUsbTargetDevice(NULL), + m_Speed(0) + { + } + + ~CMyDevice( + ); + + HRESULT + Initialize( + _In_ IWDFDriver *FxDriver, + _In_ IWDFDeviceInitialize *FxDeviceInit + ); + + // + // Helper methods + // + + HRESULT + CreateUsbIoTargets( + VOID + ); + + HRESULT + SendControlTransferSynchronously( + _In_ PWINUSB_SETUP_PACKET SetupPacket, + _Inout_updates_(BufferLength) PBYTE Buffer, + _In_ ULONG BufferLength, + _Out_ PULONG LengthTransferred + ); + +// +// Public methods +// +public: + + // + // The factory method used to create an instance of this driver. + // + + static + HRESULT + CreateInstance( + _In_ IWDFDriver *FxDriver, + _In_ IWDFDeviceInitialize *FxDeviceInit, + _Out_ PCMyDevice *Device + ); + + IWDFDevice * + GetFxDevice( + VOID + ) + { + return m_FxDevice; + } + + HRESULT + Configure( + VOID + ); + + IPnpCallbackHardware * + QueryIPnpCallbackHardware( + VOID + ) + { + AddRef(); + return static_cast<IPnpCallbackHardware *>(this); + } + + HRESULT + SetBarGraphDisplay( + _In_ PBAR_GRAPH_STATE BarGraphState + ); + +// +// COM methods +// +public: + + // + // IUnknown methods. + // + + virtual + ULONG + STDMETHODCALLTYPE + AddRef( + VOID + ) + { + return __super::AddRef(); + } + + _At_(this, __drv_freesMem(object)) + virtual + ULONG + STDMETHODCALLTYPE + Release( + VOID + ) + { + return __super::Release(); + } + + virtual + HRESULT + STDMETHODCALLTYPE + QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ); + + // + // IPnpCallbackHardware + // + + virtual + HRESULT + STDMETHODCALLTYPE + OnPrepareHardware( + _In_ IWDFDevice *FxDevice + ); + + virtual + HRESULT + STDMETHODCALLTYPE + OnReleaseHardware( + _In_ IWDFDevice *FxDevice + ); +}; diff --git a/usb/wdf_osrfx2_lab/umdf/step3/Driver.cpp b/usb/wdf_osrfx2_lab/umdf/step3/Driver.cpp new file mode 100644 index 00000000..bac5caca --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step3/Driver.cpp @@ -0,0 +1,220 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved. + +Module Name: + + Driver.cpp + +Abstract: + + This module contains the implementation of the UMDF Skeleton Sample's + core driver callback object. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#include "internal.h" +#include "driver.tmh" + +HRESULT +CMyDriver::CreateInstance( + _Out_ PCMyDriver *Driver + ) +/*++ + + Routine Description: + + This static method is invoked in order to create and initialize a new + instance of the driver class. The caller should arrange for the object + to be released when it is no longer in use. + + Arguments: + + Driver - a location to store a referenced pointer to the new instance + + Return Value: + + S_OK if successful, or error otherwise. + +--*/ +{ + PCMyDriver driver; + HRESULT hr; + + // + // Allocate the callback object. + // + + driver = new CMyDriver(); + + if (NULL == driver) + { + return E_OUTOFMEMORY; + } + + // + // Initialize the callback object. + // + + hr = driver->Initialize(); + + if (SUCCEEDED(hr)) + { + // + // Store a pointer to the new, initialized object in the output + // parameter. + // + + *Driver = driver; + } + else + { + + // + // Release the reference on the driver object to get it to delete + // itself. + // + + driver->Release(); + } + + return hr; +} + +HRESULT +CMyDriver::Initialize( + VOID + ) +/*++ + + Routine Description: + + This method is called to initialize a newly created driver callback object + before it is returned to the creator. Unlike the constructor, the + Initialize method contains operations which could potentially fail. + + Arguments: + + None + + Return Value: + + None + +--*/ +{ + return S_OK; +} + +HRESULT +CMyDriver::QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Interface + ) +/*++ + + Routine Description: + + This method returns a pointer to the requested interface on the callback + object.. + + Arguments: + + InterfaceId - the IID of the interface to query/reference + + Interface - a location to store the interface pointer. + + Return Value: + + S_OK if the interface is supported. + E_NOINTERFACE if it is not supported. + +--*/ +{ + if (IsEqualIID(InterfaceId, __uuidof(IDriverEntry))) + { + *Interface = QueryIDriverEntry(); + return S_OK; + } + else + { + return CUnknown::QueryInterface(InterfaceId, Interface); + } +} + +HRESULT +CMyDriver::OnDeviceAdd( + _In_ IWDFDriver *FxWdfDriver, + _In_ IWDFDeviceInitialize *FxDeviceInit + ) +/*++ + + Routine Description: + + The FX invokes this method when it wants to install our driver on a device + stack. This method creates a device callback object, then calls the Fx + to create an Fx device object and associate the new callback object with + it. + + Arguments: + + FxWdfDriver - the Fx driver object. + + FxDeviceInit - the initialization information for the device. + + Return Value: + + status + +--*/ +{ + HRESULT hr; + + PCMyDevice device = NULL; + + // + // TODO: Do any per-device initialization (reading settings from the + // registry for example) that's necessary before creating your + // device callback object here. Otherwise you can leave such + // initialization to the initialization of the device event + // handler. + // + + // + // Create a new instance of our device callback object + // + + hr = CMyDevice::CreateInstance(FxWdfDriver, FxDeviceInit, &device); + + // + // TODO: Change any per-device settings that the object exposes before + // calling Configure to let it complete its initialization. + // + + // + // If that succeeded then call the device's construct method. This + // allows the device to create any queues or other structures that it + // needs now that the corresponding fx device object has been created. + // + + if (SUCCEEDED(hr)) + { + hr = device->Configure(); + } + + // + // Release the reference on the device callback object now that it's been + // associated with an fx device object. + // + + if (NULL != device) + { + device->Release(); + } + + return hr; +} diff --git a/usb/wdf_osrfx2_lab/umdf/step3/Driver.h b/usb/wdf_osrfx2_lab/umdf/step3/Driver.h new file mode 100644 index 00000000..800ab1d9 --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step3/Driver.h @@ -0,0 +1,149 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + Driver.h + +Abstract: + + This module contains the type definitions for the UMDF Skeleton sample's + driver callback class. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once + +// +// This class handles driver events for the skeleton sample. In particular +// it supports the OnDeviceAdd event, which occurs when the driver is called +// to setup per-device handlers for a new device stack. +// + +class CMyDriver : public CUnknown, public IDriverEntry +{ +// +// Private data members. +// +private: + +// +// Private methods. +// +private: + + // + // Returns a refernced pointer to the IDriverEntry interface. + // + + IDriverEntry * + QueryIDriverEntry( + VOID + ) + { + AddRef(); + return static_cast<IDriverEntry*>(this); + } + + HRESULT + Initialize( + VOID + ); + +// +// Public methods +// +public: + + // + // The factory method used to create an instance of this driver. + // + + static + HRESULT + CreateInstance( + _Out_ PCMyDriver *Driver + ); + +// +// COM methods +// +public: + + // + // IDriverEntry methods + // + + virtual + HRESULT + STDMETHODCALLTYPE + OnInitialize( + _In_ IWDFDriver *FxWdfDriver + ) + { + UNREFERENCED_PARAMETER(FxWdfDriver); + + return S_OK; + } + + virtual + HRESULT + STDMETHODCALLTYPE + OnDeviceAdd( + _In_ IWDFDriver *FxWdfDriver, + _In_ IWDFDeviceInitialize *FxDeviceInit + ); + + virtual + VOID + STDMETHODCALLTYPE + OnDeinitialize( + _In_ IWDFDriver *FxWdfDriver + ) + { + UNREFERENCED_PARAMETER(FxWdfDriver); + + return; + } + + // + // IUnknown methods. + // + // We have to implement basic ones here that redirect to the + // base class becuase of the multiple inheritance. + // + + virtual + ULONG + STDMETHODCALLTYPE + AddRef( + VOID + ) + { + return __super::AddRef(); + } + + _At_(this, __drv_freesMem(object)) + virtual + ULONG + STDMETHODCALLTYPE + Release( + VOID + ) + { + return __super::Release(); + } + + virtual + HRESULT + STDMETHODCALLTYPE + QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ); +}; diff --git a/usb/wdf_osrfx2_lab/umdf/step3/OsrUsbFx2.ctl b/usb/wdf_osrfx2_lab/umdf/step3/OsrUsbFx2.ctl new file mode 100644 index 00000000..4dab56ae --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step3/OsrUsbFx2.ctl @@ -0,0 +1 @@ +da5fbdfd-1eae-4ecf-b426-a3818f325ddb WudfOsrUsbFx2TraceGuid diff --git a/usb/wdf_osrfx2_lab/umdf/step3/OsrUsbFx2.rc b/usb/wdf_osrfx2_lab/umdf/step3/OsrUsbFx2.rc new file mode 100644 index 00000000..36f10ea9 --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step3/OsrUsbFx2.rc @@ -0,0 +1,21 @@ +//--------------------------------------------------------------------------- +// OsrUsbDevice.rc +// +// Copyright (c) Microsoft Corporation, All Rights Reserved +//--------------------------------------------------------------------------- + + +#include <windows.h> +#include <ntverp.h> + +// +// TODO: Change the file description and file names to match your binary. +// + +#define VER_FILETYPE VFT_DLL +#define VER_FILESUBTYPE VFT_UNKNOWN +#define VER_FILEDESCRIPTION_STR "WDF:UMDF OSR USB Fx2 User-Mode Driver Sample" +#define VER_INTERNALNAME_STR "WUDFOsrUsbFx2" +#define VER_ORIGINALFILENAME_STR "WUDFOsrUsbFx2.dll" + +#include "common.ver" diff --git a/usb/wdf_osrfx2_lab/umdf/step3/Queue.cpp b/usb/wdf_osrfx2_lab/umdf/step3/Queue.cpp new file mode 100644 index 00000000..c56b38bb --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step3/Queue.cpp @@ -0,0 +1,147 @@ +/*++ + +Copyright (c) Microsoft Corporation, All Rights Reserved + +Module Name: + + queue.cpp + +Abstract: + + This file implements the I/O queue interface and performs + the read/write/ioctl operations. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#include "internal.h" +#include "queue.tmh" + +CMyQueue::CMyQueue( + _In_ PCMyDevice Device + ) : + m_FxQueue(NULL), + m_Device(Device) +{ +} + +// +// Queue destructor. +// Free up the buffer, wait for thread to terminate and +// + +CMyQueue::~CMyQueue( + VOID + ) +/*++ + +Routine Description: + + + IUnknown implementation of Release + +Aruments: + + +Return Value: + + ULONG (reference count after Release) + +--*/ +{ + TraceEvents(TRACE_LEVEL_INFORMATION, + TEST_TRACE_QUEUE, + "%!FUNC! Entry" + ); + +} + + +HRESULT +STDMETHODCALLTYPE +CMyQueue::QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ) +/*++ + +Routine Description: + + + Query Interface + +Aruments: + + Follows COM specifications + +Return Value: + + HRESULT indicatin success or failure + +--*/ +{ + HRESULT hr; + + hr = CUnknown::QueryInterface(InterfaceId, Object); + + return hr; +} + +// +// Initialize +// + +HRESULT +CMyQueue::Initialize( + _In_ WDF_IO_QUEUE_DISPATCH_TYPE DispatchType, + _In_ bool Default, + _In_ bool PowerManaged + ) +{ + IWDFIoQueue *fxQueue; + HRESULT hr; + + // + // Create the I/O Queue object. + // + + { + IUnknown *callback = QueryIUnknown(); + + hr = m_Device->GetFxDevice()->CreateIoQueue( + callback, + Default, + DispatchType, + PowerManaged, + FALSE, + &fxQueue + ); + callback->Release(); + } + + if (SUCCEEDED(hr)) + { + m_FxQueue = fxQueue; + + // + // Release the creation reference on the queue. This object will be + // destroyed before the queue so we don't need to have a reference out + // on it. + // + + fxQueue->Release(); + } + + return hr; +} + +HRESULT +CMyQueue::Configure( + VOID + ) +{ + return S_OK; +} diff --git a/usb/wdf_osrfx2_lab/umdf/step3/Queue.h b/usb/wdf_osrfx2_lab/umdf/step3/Queue.h new file mode 100644 index 00000000..5659224b --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step3/Queue.h @@ -0,0 +1,93 @@ +/*++ + +Copyright (c) Microsoft Corporation, All Rights Reserved + +Module Name: + + queue.h + +Abstract: + + This file defines the queue callback interface. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once + +// +// Queue Callback Object. +// + +class CMyQueue : + public CUnknown +{ +protected: + // + // Unreferenced pointer to the partner Fx device. + // + + IWDFIoQueue *m_FxQueue; + + // + // Unreferenced pointer to the parent device. + // + + PCMyDevice m_Device; + + HRESULT + Initialize( + _In_ WDF_IO_QUEUE_DISPATCH_TYPE DispatchType, + _In_ bool Default, + _In_ bool PowerManaged + ); + +protected: + + CMyQueue( + _In_ PCMyDevice Device + ); + + virtual ~CMyQueue(); + + HRESULT + Configure( + VOID + ); + +public: + + IWDFIoQueue * + GetFxQueue( + VOID + ) + { + return m_FxQueue; + } + + + PCMyDevice + GetDevice( + VOID + ) + { + return m_Device; + } + + // + // IUnknown + // + + STDMETHOD_(ULONG,AddRef) (VOID) {return CUnknown::AddRef();} + + _At_(this, __drv_freesMem(object)) + STDMETHOD_(ULONG,Release) (VOID) {return CUnknown::Release();} + + STDMETHOD_(HRESULT, QueryInterface)( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ); +}; diff --git a/usb/wdf_osrfx2_lab/umdf/step3/WUDFOsrUsbFx2_3.inx b/usb/wdf_osrfx2_lab/umdf/step3/WUDFOsrUsbFx2_3.inx Binary files differnew file mode 100644 index 00000000..729c6aef --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step3/WUDFOsrUsbFx2_3.inx diff --git a/usb/wdf_osrfx2_lab/umdf/step3/WUDFOsrUsbFx2_3.vcxproj b/usb/wdf_osrfx2_lab/umdf/step3/WUDFOsrUsbFx2_3.vcxproj new file mode 100644 index 00000000..25e7b78b --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step3/WUDFOsrUsbFx2_3.vcxproj @@ -0,0 +1,267 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{4BED411D-1B55-4A64-84C9-36EC25F083D2}</ProjectGuid> + <RootNamespace>$(MSBuildProjectName)</RootNamespace> + <UMDF_VERSION_MAJOR>1</UMDF_VERSION_MAJOR> + <KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR> + <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration> + <Platform Condition="'$(Platform)' == ''">Win32</Platform> + <SampleGuid>{9EBE799A-093D-4C8A-9CDC-63244A61D166}</SampleGuid> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType>UMDF</DriverType> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType>UMDF</DriverType> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType>UMDF</DriverType> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType>UMDF</DriverType> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <OutDir>$(IntDir)</OutDir> + </PropertyGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ItemGroup Label="WrappedTaskItems"> + <ClCompile Include="dllsup.cpp; comsup.cpp; driver.cpp; device.cpp; queue.cpp; ControlQueue.cpp"> + <WppEnabled>true</WppEnabled> + <WppDllMacro>true</WppDllMacro> + <WppScanConfigurationData>internal.h</WppScanConfigurationData> + </ClCompile> + <OtherWpp Include="OsrUsbFx2.rc"> + <WppEnabled>true</WppEnabled> + <WppDllMacro>true</WppDllMacro> + <WppScanConfigurationData>internal.h</WppScanConfigurationData> + </OtherWpp> + </ItemGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetName>WUDFOsrUsbFx2_3</TargetName> + <WIN32_WINNT_VERSION>0x0A00</WIN32_WINNT_VERSION> + <NTDDI_VERSION>0x0A000000</NTDDI_VERSION> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetName>WUDFOsrUsbFx2_3</TargetName> + <WIN32_WINNT_VERSION>0x0A00</WIN32_WINNT_VERSION> + <NTDDI_VERSION>0x0A000000</NTDDI_VERSION> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetName>WUDFOsrUsbFx2_3</TargetName> + <WIN32_WINNT_VERSION>0x0A00</WIN32_WINNT_VERSION> + <NTDDI_VERSION>0x0A000000</NTDDI_VERSION> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetName>WUDFOsrUsbFx2_3</TargetName> + <WIN32_WINNT_VERSION>0x0A00</WIN32_WINNT_VERSION> + <NTDDI_VERSION>0x0A000000</NTDDI_VERSION> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <DisableSpecificWarnings>%(DisableSpecificWarnings);4201</DisableSpecificWarnings> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ClCompile> + <Midl> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </Midl> + <ResourceCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ResourceCompile> + <Link> + <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol> + <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <DisableSpecificWarnings>%(DisableSpecificWarnings);4201</DisableSpecificWarnings> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ClCompile> + <Midl> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </Midl> + <ResourceCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ResourceCompile> + <Link> + <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol> + <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <DisableSpecificWarnings>%(DisableSpecificWarnings);4201</DisableSpecificWarnings> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ClCompile> + <Midl> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </Midl> + <ResourceCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ResourceCompile> + <Link> + <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol> + <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <DisableSpecificWarnings>%(DisableSpecificWarnings);4201</DisableSpecificWarnings> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ClCompile> + <Midl> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </Midl> + <ResourceCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ResourceCompile> + <Link> + <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol> + <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\kernel32.lib;$(SDK_LIB_PATH)\advapi32.lib</AdditionalDependencies> + <ModuleDefinitionFile>exports.def</ModuleDefinitionFile> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\kernel32.lib;$(SDK_LIB_PATH)\advapi32.lib</AdditionalDependencies> + <ModuleDefinitionFile>exports.def</ModuleDefinitionFile> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\kernel32.lib;$(SDK_LIB_PATH)\advapi32.lib</AdditionalDependencies> + <ModuleDefinitionFile>exports.def</ModuleDefinitionFile> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\kernel32.lib;$(SDK_LIB_PATH)\advapi32.lib</AdditionalDependencies> + <ModuleDefinitionFile>exports.def</ModuleDefinitionFile> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ResourceCompile Include="OsrUsbFx2.rc" /> + </ItemGroup> + <ItemGroup> + <Inf Exclude="@(Inf)" Include="*.inf" /> + <FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" /> + </ItemGroup> + <ItemGroup> + <None Exclude="@(None)" Include="*.txt;*.htm;*.html" /> + <None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" /> + <None Exclude="@(None)" Include="*.def;*.bat;*.hpj;*.asmx" /> + </ItemGroup> + <ItemGroup> + <ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> +</Project>
\ No newline at end of file diff --git a/usb/wdf_osrfx2_lab/umdf/step3/WUDFOsrUsbFx2_3.vcxproj.Filters b/usb/wdf_osrfx2_lab/umdf/step3/WUDFOsrUsbFx2_3.vcxproj.Filters new file mode 100644 index 00000000..1007a353 --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step3/WUDFOsrUsbFx2_3.vcxproj.Filters @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions> + <UniqueIdentifier>{275FF43B-A34B-4413-A946-DB6C89B85700}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files"> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + <UniqueIdentifier>{3E57B132-7C76-4977-9406-304A1D0E3E93}</UniqueIdentifier> + </Filter> + <Filter Include="Resource Files"> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions> + <UniqueIdentifier>{9A62ABB9-1665-44C3-A018-B30C085A8EC5}</UniqueIdentifier> + </Filter> + <Filter Include="Driver Files"> + <Extensions>inf;inv;inx;mof;mc;</Extensions> + <UniqueIdentifier>{6FE8DFE2-D3E3-4713-9FD8-A937B598C72C}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="comsup.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ControlQueue.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="device.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="dllsup.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="driver.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="queue.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <None Include="exports.def"> + <Filter>Source Files</Filter> + </None> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="OsrUsbFx2.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/usb/wdf_osrfx2_lab/umdf/step3/comsup.cpp b/usb/wdf_osrfx2_lab/umdf/step3/comsup.cpp new file mode 100644 index 00000000..9c9aec3b --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step3/comsup.cpp @@ -0,0 +1,344 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + ComSup.cpp + +Abstract: + + This module contains implementations for the functions and methods + used for providing COM support. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#include "internal.h" + +#include "comsup.tmh" + +// +// Implementation of CUnknown methods. +// + +CUnknown::CUnknown( + VOID + ) : m_ReferenceCount(1) +/*++ + + Routine Description: + + Constructor for an instance of the CUnknown class. This simply initializes + the reference count of the object to 1. The caller is expected to + call Release() if it wants to delete the object once it has been allocated. + + Arguments: + + None + + Return Value: + + None + +--*/ +{ + // do nothing. +} + +HRESULT +STDMETHODCALLTYPE +CUnknown::QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ) +/*++ + + Routine Description: + + This method provides the basic support for query interface on CUnknown. + If the interface requested is IUnknown it references the object and + returns an interface pointer. Otherwise it returns an error. + + Arguments: + + InterfaceId - the IID being requested + + Object - a location to store the interface pointer to return. + + Return Value: + + S_OK or E_NOINTERFACE + +--*/ +{ + if (IsEqualIID(InterfaceId, __uuidof(IUnknown))) + { + *Object = QueryIUnknown(); + return S_OK; + } + else + { + *Object = NULL; + return E_NOINTERFACE; + } +} + +IUnknown * +CUnknown::QueryIUnknown( + VOID + ) +/*++ + + Routine Description: + + This helper method references the object and returns a pointer to the + object's IUnknown interface. + + This allows other methods to convert a CUnknown pointer into an IUnknown + pointer without a typecast and without calling QueryInterface and dealing + with the return value. + + Arguments: + + None + + Return Value: + + A pointer to the object's IUnknown interface. + +--*/ +{ + AddRef(); + return static_cast<IUnknown *>(this); +} + +ULONG +STDMETHODCALLTYPE +CUnknown::AddRef( + VOID + ) +/*++ + + Routine Description: + + This method adds one to the object's reference count. + + Arguments: + + None + + Return Value: + + The new reference count. The caller should only use this for debugging + as the object's actual reference count can change while the caller + examines the return value. + +--*/ +{ + return InterlockedIncrement(&m_ReferenceCount); +} + +ULONG +STDMETHODCALLTYPE +CUnknown::Release( + VOID + ) +/*++ + + Routine Description: + + This method subtracts one to the object's reference count. If the count + goes to zero, this method deletes the object. + + Arguments: + + None + + Return Value: + + The new reference count. If the caller uses this value it should only be + to check for zero (i.e. this call caused or will cause deletion) or + non-zero (i.e. some other call may have caused deletion, but this one + didn't). + +--*/ +{ + ULONG count = InterlockedDecrement(&m_ReferenceCount); + + if (count == 0) + { + delete this; + } + return count; +} + +// +// Implementation of CClassFactory methods. +// + +// +// Define storage for the factory's static lock count variable. +// + +LONG CClassFactory::s_LockCount = 0; + +IClassFactory * +CClassFactory::QueryIClassFactory( + VOID + ) +/*++ + + Routine Description: + + This helper method references the object and returns a pointer to the + object's IClassFactory interface. + + This allows other methods to convert a CClassFactory pointer into an + IClassFactory pointer without a typecast and without dealing with the + return value QueryInterface. + + Arguments: + + None + + Return Value: + + A referenced pointer to the object's IClassFactory interface. + +--*/ +{ + AddRef(); + return static_cast<IClassFactory *>(this); +} + +HRESULT +CClassFactory::QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ) +/*++ + + Routine Description: + + This method attempts to retrieve the requested interface from the object. + + If the interface is found then the reference count on that interface (and + thus the object itself) is incremented. + + Arguments: + + InterfaceId - the interface the caller is requesting. + + Object - a location to store the interface pointer. + + Return Value: + + S_OK or E_NOINTERFACE + +--*/ +{ + // + // This class only supports IClassFactory so check for that. + // + + if (IsEqualIID(InterfaceId, __uuidof(IClassFactory))) + { + *Object = QueryIClassFactory(); + return S_OK; + } + else + { + // + // See if the base class supports the interface. + // + + return CUnknown::QueryInterface(InterfaceId, Object); + } +} + +HRESULT +STDMETHODCALLTYPE +CClassFactory::CreateInstance( + _In_opt_ IUnknown * /* OuterObject */, + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ) +/*++ + + Routine Description: + + This COM method is the factory routine - it creates instances of the driver + callback class and returns the specified interface on them. + + Arguments: + + OuterObject - only used for aggregation, which our driver callback class + does not support. + + InterfaceId - the interface ID the caller would like to get from our + new object. + + Object - a location to store the referenced interface pointer to the new + object. + + Return Value: + + Status. + +--*/ +{ + HRESULT hr; + + PCMyDriver driver; + + *Object = NULL; + + hr = CMyDriver::CreateInstance(&driver); + + if (SUCCEEDED(hr)) + { + hr = driver->QueryInterface(InterfaceId, Object); + driver->Release(); + } + + return hr; +} + +HRESULT +STDMETHODCALLTYPE +CClassFactory::LockServer( + _In_ BOOL Lock + ) +/*++ + + Routine Description: + + This COM method can be used to keep the DLL in memory. However since the + driver's DllCanUnloadNow function always returns false, this has little + effect. Still it tracks the number of lock and unlock operations. + + Arguments: + + Lock - Whether the caller wants to lock or unlock the "server" + + Return Value: + + S_OK + +--*/ +{ + if (Lock) + { + InterlockedIncrement(&s_LockCount); + } + else + { + InterlockedDecrement(&s_LockCount); + } + return S_OK; +} + diff --git a/usb/wdf_osrfx2_lab/umdf/step3/comsup.h b/usb/wdf_osrfx2_lab/umdf/step3/comsup.h new file mode 100644 index 00000000..dedf78c8 --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step3/comsup.h @@ -0,0 +1,215 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + ComSup.h + +Abstract: + + This module contains classes and functions use for providing COM support + code. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once + +// +// Forward type declarations. They are here rather than in internal.h as +// you only need them if you choose to use these support classes. +// + +typedef class CUnknown *PCUnknown; +typedef class CClassFactory *PCClassFactory; + +// +// Base class to implement IUnknown. You can choose to derive your COM +// classes from this class, or simply implement IUnknown in each of your +// classes. +// + +class CUnknown : public IUnknown +{ + +// +// Private data members and methods. These are only accessible by the methods +// of this class. +// +private: + + // + // The reference count for this object. Initialized to 1 in the + // constructor. + // + + LONG m_ReferenceCount; + +// +// Protected data members and methods. These are accessible by the subclasses +// but not by other classes. +// +protected: + + // + // The constructor and destructor are protected to ensure that only the + // subclasses of CUnknown can create and destroy instances. + // + + CUnknown( + VOID + ); + + // + // The destructor MUST be virtual. Since any instance of a CUnknown + // derived class should only be deleted from within CUnknown::Release, + // the destructor MUST be virtual or only CUnknown::~CUnknown will get + // invoked on deletion. + // + // If you see that your CMyDevice specific destructor is never being + // called, make sure you haven't deleted the virtual destructor here. + // + + virtual + ~CUnknown( + VOID + ) + { + // Do nothing + } + +// +// Public Methods. These are accessible by any class. +// +public: + + IUnknown * + QueryIUnknown( + VOID + ); + +// +// COM Methods. +// +public: + + // + // IUnknown methods + // + + virtual + ULONG + STDMETHODCALLTYPE + AddRef( + VOID + ); + + virtual + ULONG + STDMETHODCALLTYPE + Release( + VOID + ); + + virtual + HRESULT + STDMETHODCALLTYPE + QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ); +}; + +// +// Class factory support class. Create an instance of this from your +// DllGetClassObject method and modify the implementation to create +// an instance of your driver event handler class. +// + +class CClassFactory : public CUnknown, public IClassFactory +{ +// +// Private data members and methods. These are only accessible by the methods +// of this class. +// +private: + + // + // The lock count. This is shared across all instances of IClassFactory + // and can be queried through the public IsLocked method. + // + + static LONG s_LockCount; + +// +// Public Methods. These are accessible by any class. +// +public: + + IClassFactory * + QueryIClassFactory( + VOID + ); + +// +// COM Methods. +// +public: + + // + // IUnknown methods + // + + virtual + ULONG + STDMETHODCALLTYPE + AddRef( + VOID + ) + { + return __super::AddRef(); + } + + _At_(this, __drv_freesMem(object)) + virtual + ULONG + STDMETHODCALLTYPE + Release( + VOID + ) + { + return __super::Release(); + } + + virtual + HRESULT + STDMETHODCALLTYPE + QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ); + + // + // IClassFactory methods. + // + + virtual + HRESULT + STDMETHODCALLTYPE + CreateInstance( + _In_opt_ IUnknown *OuterObject, + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ); + + virtual + HRESULT + STDMETHODCALLTYPE + LockServer( + _In_ BOOL Lock + ); +}; diff --git a/usb/wdf_osrfx2_lab/umdf/step3/dllsup.cpp b/usb/wdf_osrfx2_lab/umdf/step3/dllsup.cpp new file mode 100644 index 00000000..e8bad81b --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step3/dllsup.cpp @@ -0,0 +1,202 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved. + +Module Name: + + dllsup.cpp + +Abstract: + + This module contains the implementation of the UMDF Skeleton Sample + Driver's entry point and its exported functions for providing COM support. + + This module can be copied without modification to a new UMDF driver. It + depends on some of the code in comsup.cpp & comsup.h to handle DLL + registration and creating the first class factory. + + This module is dependent on the following defines: + + MYDRIVER_TRACING_ID - A wide string passed to WPP when initializing + tracing. For example the skeleton uses + L"Microsoft\\UMDF\\Skeleton" + + MYDRIVER_CLASS_ID - A GUID encoded in struct format used to + initialize the driver's ClassID. + + These are defined in internal.h for the skeleton sample. If you choose + to use a different primary include file, you should ensure they are + defined there as well. + +Environment: + + WDF User-Mode Driver Framework (WDF:UMDF) + +--*/ + +#include "internal.h" +#include "dllsup.tmh" + +const GUID CLSID_MyDriverCoClass = MYDRIVER_CLASS_ID; + +BOOL +WINAPI +DllMain( + HINSTANCE ModuleHandle, + DWORD Reason, + PVOID /* Reserved */ + ) +/*++ + + Routine Description: + + This is the entry point and exit point for the I/O trace driver. This + does very little as the I/O trace driver has minimal global data. + + This method initializes tracing, and saves the module handle away in a + global variable so that it can be referenced should the COM registration + code (Dll[Un]RegisterServer) be called. + + Arguments: + + ModuleHandle - the DLL handle for this module. + + Reason - the reason this entry point was called. + + Reserved - unused + + Return Value: + + TRUE + +--*/ +{ + UNREFERENCED_PARAMETER(ModuleHandle); + + if (DLL_PROCESS_ATTACH == Reason) + { + // + // Initialize tracing. + // + + WPP_INIT_TRACING(MYDRIVER_TRACING_ID); + } + else if (DLL_PROCESS_DETACH == Reason) + { + // + // Cleanup tracing. + // + + WPP_CLEANUP(); + } + + return TRUE; +} + +HRESULT +STDAPICALLTYPE +DllCanUnloadNow( + VOID + ) +/*++ + + Routine Description: + + Called by the COM runtime when determining whether or not this module + can be unloaded. Our answer is always "no". + + Arguments: + + None + + Return Value: + + S_FALSE + +--*/ +{ + return S_FALSE; +} + +HRESULT +STDAPICALLTYPE +DllGetClassObject( + _In_ REFCLSID ClassId, + _In_ REFIID InterfaceId, + _Outptr_ LPVOID *Interface + ) +/*++ + + Routine Description: + + This routine is called by COM in order to instantiate the + skeleton driver callback object and do an initial query interface on it. + + This method only creates an instance of the driver's class factory, as this + is the minimum required to support UMDF. + + Arguments: + + ClassId - the CLSID of the object being "gotten" + + InterfaceId - the interface the caller wants from that object. + + Interface - a location to store the referenced interface pointer + + Return Value: + + S_OK if the function succeeds or error indicating the cause of the + failure. + +--*/ +{ + PCClassFactory factory; + + HRESULT hr = S_OK; + + *Interface = NULL; + + // + // If the CLSID doesn't match that of our "coclass" (defined in the IDL + // file) then we can't create the object the caller wants. This may + // indicate that the COM registration is incorrect, and another CLSID + // is referencing this drvier. + // + + if (IsEqualCLSID(ClassId, CLSID_MyDriverCoClass) == false) + { + Trace( + TRACE_LEVEL_ERROR, + L"ERROR: Called to create instance of unrecognized class (%!GUID!)", + &ClassId + ); + + return CLASS_E_CLASSNOTAVAILABLE; + } + + // + // Create an instance of the class factory for the caller. + // + + factory = new CClassFactory(); + + if (NULL == factory) + { + hr = E_OUTOFMEMORY; + } + + // + // Query the object we created for the interface the caller wants. After + // that we release the object. This will drive the reference count to + // 1 (if the QI succeeded an referenced the object) or 0 (if the QI failed). + // In the later case the object is automatically deleted. + // + + if (SUCCEEDED(hr)) + { + hr = factory->QueryInterface(InterfaceId, Interface); + factory->Release(); + } + + return hr; +} diff --git a/usb/wdf_osrfx2_lab/umdf/step3/exports.def b/usb/wdf_osrfx2_lab/umdf/step3/exports.def new file mode 100644 index 00000000..15f923d3 --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step3/exports.def @@ -0,0 +1,4 @@ +; WudfOsrUsbDriver.def : Declares the module parameters. + +EXPORTS + DllGetClassObject PRIVATE diff --git a/usb/wdf_osrfx2_lab/umdf/step3/internal.h b/usb/wdf_osrfx2_lab/umdf/step3/internal.h new file mode 100644 index 00000000..7db8f1c4 --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step3/internal.h @@ -0,0 +1,152 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + Internal.h + +Abstract: + + This module contains the local type definitions for the UMDF Skeleton + driver sample. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) +#endif + +// +// Include the WUDF Headers +// + +#include "wudfddi.h" + +// +// Use specstrings for in/out annotation of function parameters. +// + +#include "specstrings.h" + +// +// Get limits on common data types (ULONG_MAX for example) +// + +#include "limits.h" + +// +// We need usb I/O targets to talk to the OSR device. +// + +#include "wudfusb.h" + +// +// Include the header shared between the drivers and the test applications. +// + +#include "public.h" + +// +// Include the header shared between the drivers and the test applications. +// + +#include "WUDFOsrUsbPublic.h" + +// +// Forward definitions of classes in the other header files. +// + +typedef class CMyDriver *PCMyDriver; +typedef class CMyDevice *PCMyDevice; +typedef class CMyQueue *PCMyQueue; + +typedef class CMyControlQueue *PCMyControlQueue; + +// +// Define the tracing flags. +// +// TODO: Choose a different trace control GUID +// + +#define WPP_CONTROL_GUIDS \ + WPP_DEFINE_CONTROL_GUID( \ + WudfOsrUsbFx2TraceGuid, (da5fbdfd,1eae,4ecf,b426,a3818f325ddb), \ + \ + WPP_DEFINE_BIT(MYDRIVER_ALL_INFO) \ + WPP_DEFINE_BIT(TEST_TRACE_DRIVER) \ + WPP_DEFINE_BIT(TEST_TRACE_DEVICE) \ + WPP_DEFINE_BIT(TEST_TRACE_QUEUE) \ + ) + +#define WPP_FLAG_LEVEL_LOGGER(flag, level) \ + WPP_LEVEL_LOGGER(flag) + +#define WPP_FLAG_LEVEL_ENABLED(flag, level) \ + (WPP_LEVEL_ENABLED(flag) && \ + WPP_CONTROL(WPP_BIT_ ## flag).Level >= level) + +#define WPP_LEVEL_FLAGS_LOGGER(lvl,flags) \ + WPP_LEVEL_LOGGER(flags) + +#define WPP_LEVEL_FLAGS_ENABLED(lvl, flags) \ + (WPP_LEVEL_ENABLED(flags) && WPP_CONTROL(WPP_BIT_ ## flags).Level >= lvl) + +// +// This comment block is scanned by the trace preprocessor to define our +// Trace function. +// +// begin_wpp config +// FUNC Trace{FLAG=MYDRIVER_ALL_INFO}(LEVEL, MSG, ...); +// FUNC TraceEvents(LEVEL, FLAGS, MSG, ...); +// end_wpp +// + +// +// Driver specific #defines +// +// TODO: Change these values to be appropriate for your driver. +// + +#define MYDRIVER_TRACING_ID L"Microsoft\\UMDF\\OsrUsb" +#define MYDRIVER_CLASS_ID {0x0865b2b0, 0x6b73, 0x428f, {0xa3, 0xea, 0x21, 0x72, 0x83, 0x2d, 0x6b, 0xfc}} + +// +// Include the type specific headers. +// + +#include "comsup.h" +#include "driver.h" +#include "device.h" +#include "queue.h" +#include "ControlQueue.h" +#include "list.h" + +__forceinline +#ifdef _PREFAST_ +__declspec(noreturn) +#endif +VOID +WdfTestNoReturn( + VOID + ) +{ + // do nothing. +} + +#define WUDF_TEST_DRIVER_ASSERT(p) \ +{ \ + if ( !(p) ) \ + { \ + DebugBreak(); \ + WdfTestNoReturn(); \ + } \ +} + +#define SAFE_RELEASE(p) {if ((p)) { (p)->Release(); (p) = NULL; }} diff --git a/usb/wdf_osrfx2_lab/umdf/step4/ControlQueue.cpp b/usb/wdf_osrfx2_lab/umdf/step4/ControlQueue.cpp new file mode 100644 index 00000000..48de237d --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step4/ControlQueue.cpp @@ -0,0 +1,246 @@ +/*++ + +Copyright (c) Microsoft Corporation, All Rights Reserved + +Module Name: + + ControlQueue.cpp + +Abstract: + + This file implements the I/O queue interface and performs + the ioctl operations. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#include "internal.h" + +#include "winioctl.h" + +#include "ControlQueue.tmh" + +CMyControlQueue::CMyControlQueue( + _In_ PCMyDevice Device + ) : CMyQueue(Device) +{ + +} + +HRESULT +STDMETHODCALLTYPE +CMyControlQueue::QueryInterface( + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ) +/*++ + +Routine Description: + + + Query Interface + +Aruments: + + Follows COM specifications + +Return Value: + + HRESULT indicatin success or failure + +--*/ +{ + HRESULT hr; + + + if (IsEqualIID(InterfaceId, __uuidof(IQueueCallbackDeviceIoControl))) + { + hr = S_OK; + *Object = QueryIQueueCallbackDeviceIoControl(); + + } + else + { + hr = CMyQueue::QueryInterface(InterfaceId, Object); + } + + return hr; +} + +// +// Initialize +// + +HRESULT +CMyControlQueue::CreateInstance( + _In_ PCMyDevice Device, + _Out_ PCMyControlQueue *Queue + ) +/*++ + +Routine Description: + + + CreateInstance creates an instance of the queue object. + +Aruments: + + ppUkwn - OUT parameter is an IUnknown interface to the queue object + +Return Value: + + HRESULT indicatin success or failure + +--*/ +{ + PCMyControlQueue queue = NULL; + HRESULT hr = S_OK; + + queue = new CMyControlQueue(Device); + + if (NULL == queue) + { + hr = E_OUTOFMEMORY; + } + + // + // Call the queue callback object to initialize itself. This will create + // its partner queue framework object. + // + + if (SUCCEEDED(hr)) + { + hr = queue->Initialize(); + } + + if (SUCCEEDED(hr)) + { + *Queue = queue; + } + else + { + SAFE_RELEASE(queue); + } + + return hr; +} + +HRESULT +CMyControlQueue::Initialize( + VOID + ) +{ + HRESULT hr; + + // + // First initialize the base class. This will create the partner FxIoQueue + // object and setup automatic forwarding of I/O controls. + // + + hr = __super::Initialize(WdfIoQueueDispatchSequential, + false, + true); + + // + // return the status. + // + + return hr; +} + +VOID +STDMETHODCALLTYPE +CMyControlQueue::OnDeviceIoControl( + _In_ IWDFIoQueue *FxQueue, + _In_ IWDFIoRequest *FxRequest, + _In_ ULONG ControlCode, + _In_ SIZE_T InputBufferSizeInBytes, + _In_ SIZE_T OutputBufferSizeInBytes + ) +/*++ + +Routine Description: + + + DeviceIoControl dispatch routine + +Aruments: + + FxQueue - Framework Queue instance + FxRequest - Framework Request instance + ControlCode - IO Control Code + InputBufferSizeInBytes - Lenth of input buffer + OutputBufferSizeInBytes - Lenth of output buffer + + Always succeeds DeviceIoIoctl +Return Value: + + VOID + +--*/ +{ + UNREFERENCED_PARAMETER(FxQueue); + UNREFERENCED_PARAMETER(OutputBufferSizeInBytes); + + IWDFMemory *memory = NULL; + PVOID buffer; + + SIZE_T bigBufferCb; + + ULONG information = 0; + + bool completeRequest = true; + + HRESULT hr = S_OK; + + switch (ControlCode) + { + case IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY: + { + // + // Make sure the buffer is big enough to hold the input for the + // control transfer. + // + + if (InputBufferSizeInBytes < sizeof(BAR_GRAPH_STATE)) + { + hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); + } + else + { + FxRequest->GetInputMemory(&memory); + } + + // + // Get the data buffer and use it to set the bar graph on the + // device. + // + + if (SUCCEEDED(hr)) + { + buffer = memory->GetDataBuffer(&bigBufferCb); + memory->Release(); + + hr = m_Device->SetBarGraphDisplay((PBAR_GRAPH_STATE) buffer); + } + + break; + } + + default: + { + hr = HRESULT_FROM_WIN32(ERROR_INVALID_FUNCTION); + break; + } + } + + if (completeRequest) + { + FxRequest->CompleteWithInformation(hr, information); + } + + return; +} diff --git a/usb/wdf_osrfx2_lab/umdf/step4/ControlQueue.h b/usb/wdf_osrfx2_lab/umdf/step4/ControlQueue.h new file mode 100644 index 00000000..251521e1 --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step4/ControlQueue.h @@ -0,0 +1,101 @@ +/*++ + +Copyright (c) Microsoft Corporation, All Rights Reserved + +Module Name: + + ControlQueue.h + +Abstract: + + This file defines the queue callback object for handling device I/O + control requests. This is a serialized queue. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once + +// +// Queue Callback Object. +// + +class CMyControlQueue : public IQueueCallbackDeviceIoControl, + public CMyQueue +{ + HRESULT + Initialize( + VOID + ); + +public: + + CMyControlQueue( + _In_ PCMyDevice Device + ); + + virtual + ~CMyControlQueue( + VOID + ) + { + return; + } + + static + HRESULT + CreateInstance( + _In_ PCMyDevice Device, + _Out_ PCMyControlQueue *Queue + ); + + HRESULT + Configure( + VOID + ) + { + return S_OK; + } + + IQueueCallbackDeviceIoControl * + QueryIQueueCallbackDeviceIoControl( + VOID + ) + { + AddRef(); + return static_cast<IQueueCallbackDeviceIoControl *>(this); + } + + // + // IUnknown + // + + STDMETHOD_(ULONG,AddRef) (VOID) {return CUnknown::AddRef();} + + _At_(this, __drv_freesMem(object)) + STDMETHOD_(ULONG,Release) (VOID) {return CUnknown::Release();} + + STDMETHOD_(HRESULT, QueryInterface)( + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ); + + // + // Wdf Callbacks + // + + // + // IQueueCallbackDeviceIoControl + // + STDMETHOD_ (void, OnDeviceIoControl)( + _In_ IWDFIoQueue *pWdfQueue, + _In_ IWDFIoRequest *pWdfRequest, + _In_ ULONG ControlCode, + _In_ SIZE_T InputBufferSizeInBytes, + _In_ SIZE_T OutputBufferSizeInBytes + ); +}; + diff --git a/usb/wdf_osrfx2_lab/umdf/step4/Device.cpp b/usb/wdf_osrfx2_lab/umdf/step4/Device.cpp new file mode 100644 index 00000000..bc6700c5 --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step4/Device.cpp @@ -0,0 +1,812 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved. + +Module Name: + + Device.cpp + +Abstract: + + This module contains the implementation of the UMDF Skeleton sample driver's + device callback object. + + The skeleton sample device does very little. It does not implement either + of the PNP interfaces so once the device is setup, it won't ever get any + callbacks until the device is removed. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#include "internal.h" +#include "initguid.h" +#include "usb_hw.h" + +#include "device.tmh" + +CMyDevice::~CMyDevice( + ) +{ +} + +HRESULT +CMyDevice::CreateInstance( + _In_ IWDFDriver *FxDriver, + _In_ IWDFDeviceInitialize * FxDeviceInit, + _Out_ PCMyDevice *Device + ) +/*++ + + Routine Description: + + This method creates and initializs an instance of the skeleton driver's + device callback object. + + Arguments: + + FxDeviceInit - the settings for the device. + + Device - a location to store the referenced pointer to the device object. + + Return Value: + + Status + +--*/ +{ + PCMyDevice device; + HRESULT hr; + + // + // Allocate a new instance of the device class. + // + + device = new CMyDevice(); + + if (NULL == device) + { + return E_OUTOFMEMORY; + } + + // + // Initialize the instance. + // + + hr = device->Initialize(FxDriver, FxDeviceInit); + + if (SUCCEEDED(hr)) + { + *Device = device; + } + else + { + device->Release(); + } + + return hr; +} + +HRESULT +CMyDevice::Initialize( + _In_ IWDFDriver * FxDriver, + _In_ IWDFDeviceInitialize * FxDeviceInit + ) +/*++ + + Routine Description: + + This method initializes the device callback object and creates the + partner device object. + + The method should perform any device-specific configuration that: + * could fail (these can't be done in the constructor) + * must be done before the partner object is created -or- + * can be done after the partner object is created and which aren't + influenced by any device-level parameters the parent (the driver + in this case) might set. + + Arguments: + + FxDeviceInit - the settings for this device. + + Return Value: + + status. + +--*/ +{ + IWDFDevice *fxDevice = NULL; + + HRESULT hr = S_OK; + + // + // TODO: If you're writing a filter driver then indicate that here. + // + // FxDeviceInit->SetFilter(); + // + + // + // Set no locking unless you need an automatic callbacks synchronization + // + + FxDeviceInit->SetLockingConstraint(None); + + // + // TODO: Any per-device initialization which must be done before + // creating the partner object. + // + + // + // Create a new FX device object and assign the new callback object to + // handle any device level events that occur. + // + + // + // QueryIUnknown references the IUnknown interface that it returns + // (which is the same as referencing the device). We pass that to + // CreateDevice, which takes its own reference if everything works. + // + + if (SUCCEEDED(hr)) + { + IUnknown *unknown = this->QueryIUnknown(); + + hr = FxDriver->CreateDevice(FxDeviceInit, unknown, &fxDevice); + + unknown->Release(); + } + + // + // If that succeeded then set our FxDevice member variable. + // + + if (SUCCEEDED(hr)) + { + m_FxDevice = fxDevice; + + // + // Drop the reference we got from CreateDevice. Since this object + // is partnered with the framework object they have the same + // lifespan - there is no need for an additional reference. + // + + fxDevice->Release(); + } + + return hr; +} + +HRESULT +CMyDevice::Configure( + VOID + ) +/*++ + + Routine Description: + + This method is called after the device callback object has been initialized + and returned to the driver. It would setup the device's queues and their + corresponding callback objects. + + Arguments: + + FxDevice - the framework device object for which we're handling events. + + Return Value: + + status + +--*/ +{ + HRESULT hr = S_OK; + + hr = CMyReadWriteQueue::CreateInstance(this, &m_ReadWriteQueue); + + if (FAILED(hr)) + { + return hr; + } + + // + // We use default queue for read/write + // + + hr = m_ReadWriteQueue->Configure(); + + m_ReadWriteQueue->Release(); + + // + // Create the control queue and configure forwarding for IOCTL requests. + // + + if (SUCCEEDED(hr)) + { + hr = CMyControlQueue::CreateInstance(this, &m_ControlQueue); + + if (SUCCEEDED(hr)) + { + hr = m_ControlQueue->Configure(); + if (SUCCEEDED(hr)) + { + hr = m_FxDevice->ConfigureRequestDispatching( + m_ControlQueue->GetFxQueue(), + WdfRequestDeviceIoControl, + true + ); + } + m_ControlQueue->Release(); + } + } + + if (SUCCEEDED(hr)) + { + hr = m_FxDevice->CreateDeviceInterface(&GUID_DEVINTERFACE_OSRUSBFX2, + NULL); + } + + return hr; +} + +HRESULT +CMyDevice::QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ) +/*++ + + Routine Description: + + This method is called to get a pointer to one of the object's callback + interfaces. + + Since the skeleton driver doesn't support any of the device events, this + method simply calls the base class's BaseQueryInterface. + + If the skeleton is extended to include device event interfaces then this + method must be changed to check the IID and return pointers to them as + appropriate. + + Arguments: + + InterfaceId - the interface being requested + + Object - a location to store the interface pointer if successful + + Return Value: + + S_OK or E_NOINTERFACE + +--*/ +{ + HRESULT hr; + + if (IsEqualIID(InterfaceId, __uuidof(IPnpCallbackHardware))) + { + *Object = QueryIPnpCallbackHardware(); + hr = S_OK; + } + else + { + hr = CUnknown::QueryInterface(InterfaceId, Object); + } + + return hr; +} + +HRESULT +CMyDevice::OnPrepareHardware( + _In_ IWDFDevice * /* FxDevice */ + ) +/*++ + +Routine Description: + + This routine is invoked to ready the driver + to talk to hardware. It opens the handle to the + device and talks to it using the WINUSB interface. + It invokes WINUSB to discver the interfaces and stores + the information related to bulk endpoints. + +Arguments: + + FxDevice : Pointer to the WDF device interface + +Return Value: + + HRESULT + +--*/ +{ + PWSTR deviceName = NULL; + DWORD deviceNameCch = 0; + + HRESULT hr; + + // + // Get the device name. + // Get the length to allocate first + // + + hr = m_FxDevice->RetrieveDeviceName(NULL, &deviceNameCch); + + if (FAILED(hr)) + { + TraceEvents(TRACE_LEVEL_ERROR, + TEST_TRACE_DEVICE, + "%!FUNC! Cannot get device name %!hresult!", + hr + ); + } + + // + // Allocate the buffer + // + + if (SUCCEEDED(hr)) + { + deviceName = new WCHAR[deviceNameCch]; + + if (deviceName == NULL) + { + hr = E_OUTOFMEMORY; + } + } + + // + // Get the actual name + // + + if (SUCCEEDED(hr)) + { + hr = m_FxDevice->RetrieveDeviceName(deviceName, &deviceNameCch); + + if (FAILED(hr)) + { + TraceEvents(TRACE_LEVEL_ERROR, + TEST_TRACE_DEVICE, + "%!FUNC! Cannot get device name %!hresult!", + hr + ); + } + } + + if (SUCCEEDED(hr)) + { + TraceEvents(TRACE_LEVEL_INFORMATION, + TEST_TRACE_DEVICE, + "%!FUNC! Device name %S", + deviceName + ); + } + + // + // Create USB I/O Targets and configure them + // + + if (SUCCEEDED(hr)) + { + hr = CreateUsbIoTargets(); + } + + if (SUCCEEDED(hr)) + { + ULONG length = sizeof(m_Speed); + + hr = m_pIUsbTargetDevice->RetrieveDeviceInformation(DEVICE_SPEED, + &length, + &m_Speed); + if (FAILED(hr)) + { + TraceEvents(TRACE_LEVEL_ERROR, + TEST_TRACE_DEVICE, + "%!FUNC! Cannot get usb device speed information %!HRESULT!", + hr + ); + } + } + + if (SUCCEEDED(hr)) + { + TraceEvents(TRACE_LEVEL_INFORMATION, + TEST_TRACE_DEVICE, + "%!FUNC! Speed - %x\n", + m_Speed + ); + } + + if (SUCCEEDED(hr)) + { + hr = ConfigureUsbPipes(); + } + + delete[] deviceName; + + return hr; +} + +HRESULT +CMyDevice::OnReleaseHardware( + _In_ IWDFDevice * /* FxDevice */ + ) +/*++ + +Routine Description: + + This routine is invoked when the device is being removed or stopped + It releases all resources allocated for this device. + +Arguments: + + FxDevice - Pointer to the Device object. + +Return Value: + + HRESULT - Always succeeds. + +--*/ +{ + // + // Remove I/O target from object tree before any potential subsequent + // OnPrepareHardware creates a new one + // + + if (m_pIUsbTargetDevice) + { + m_pIUsbTargetDevice->DeleteWdfObject(); + } + + return S_OK; +} + +HRESULT +CMyDevice::CreateUsbIoTargets( + ) +/*++ + +Routine Description: + + This routine creates Usb device, interface and pipe objects + +Arguments: + + None + +Return Value: + + HRESULT +--*/ +{ + HRESULT hr; + UCHAR NumEndPoints = 0; + IWDFUsbTargetFactory * pIUsbTargetFactory = NULL; + IWDFUsbTargetDevice * pIUsbTargetDevice = NULL; + IWDFUsbInterface * pIUsbInterface = NULL; + IWDFUsbTargetPipe * pIUsbPipe = NULL; + + hr = m_FxDevice->QueryInterface(IID_PPV_ARGS(&pIUsbTargetFactory)); + + if (FAILED(hr)) + { + TraceEvents(TRACE_LEVEL_ERROR, + TEST_TRACE_DEVICE, + "%!FUNC! Cannot get usb target factory %!HRESULT!", + hr + ); + } + + if (SUCCEEDED(hr)) + { + hr = pIUsbTargetFactory->CreateUsbTargetDevice( + &pIUsbTargetDevice); + if (FAILED(hr)) + { + TraceEvents(TRACE_LEVEL_ERROR, + TEST_TRACE_DEVICE, + "%!FUNC! Unable to create USB Device I/O Target %!HRESULT!", + hr + ); + } + else + { + m_pIUsbTargetDevice = pIUsbTargetDevice; + + // + // Release the creation reference as object tree will maintain a reference + // + + pIUsbTargetDevice->Release(); + } + } + + if (SUCCEEDED(hr)) + { + UCHAR NumInterfaces = pIUsbTargetDevice->GetNumInterfaces(); + + WUDF_TEST_DRIVER_ASSERT(1 == NumInterfaces); + + hr = pIUsbTargetDevice->RetrieveUsbInterface(0, &pIUsbInterface); + if (FAILED(hr)) + { + TraceEvents(TRACE_LEVEL_ERROR, + TEST_TRACE_DEVICE, + "%!FUNC! Unable to retrieve USB interface from USB Device I/O Target %!HRESULT!", + hr + ); + } + else + { + m_pIUsbInterface = pIUsbInterface; + + pIUsbInterface->Release(); //release creation reference + } + } + + if (SUCCEEDED(hr)) + { + NumEndPoints = pIUsbInterface->GetNumEndPoints(); + + if (NumEndPoints != NUM_OSRUSB_ENDPOINTS) { + hr = E_UNEXPECTED; + TraceEvents(TRACE_LEVEL_ERROR, + TEST_TRACE_DEVICE, + "%!FUNC! Has %d endpoints, expected %d, returning %!HRESULT! ", + NumEndPoints, + NUM_OSRUSB_ENDPOINTS, + hr + ); + } + } + + if (SUCCEEDED(hr)) + { + for (UCHAR PipeIndex = 0; PipeIndex < NumEndPoints; PipeIndex++) + { + hr = pIUsbInterface->RetrieveUsbPipeObject(PipeIndex, + &pIUsbPipe); + + if (FAILED(hr)) + { + TraceEvents(TRACE_LEVEL_ERROR, + TEST_TRACE_DEVICE, + "%!FUNC! Unable to retrieve USB Pipe for PipeIndex %d, %!HRESULT!", + PipeIndex, + hr + ); + } + else + { + if ( pIUsbPipe->IsInEndPoint() && (UsbdPipeTypeBulk == pIUsbPipe->GetType()) ) + { + m_pIUsbInputPipe = pIUsbPipe; + } + else if ( pIUsbPipe->IsOutEndPoint() && (UsbdPipeTypeBulk == pIUsbPipe->GetType()) ) + { + m_pIUsbOutputPipe = pIUsbPipe; + } + else + { + pIUsbPipe->DeleteWdfObject(); + } + + SAFE_RELEASE(pIUsbPipe); //release creation reference + } + } + + if (NULL == m_pIUsbInputPipe || NULL == m_pIUsbOutputPipe) + { + hr = E_UNEXPECTED; + TraceEvents(TRACE_LEVEL_ERROR, + TEST_TRACE_DEVICE, + "%!FUNC! Input or output pipe not found, returning %!HRESULT!", + hr + ); + } + } + + SAFE_RELEASE(pIUsbTargetFactory); + + return hr; +} + +HRESULT +CMyDevice::ConfigureUsbPipes( + ) +/*++ + +Routine Description: + + This routine retrieves the IDs for the bulk end points of the USB device. + +Arguments: + + None + +Return Value: + + HRESULT +--*/ +{ + HRESULT hr = S_OK; + LONG timeout; + + // + // Set timeout policies for input/output pipes + // + + if (SUCCEEDED(hr)) + { + timeout = ENDPOINT_TIMEOUT; + + hr = m_pIUsbInputPipe->SetPipePolicy(PIPE_TRANSFER_TIMEOUT, + sizeof(timeout), + &timeout); + if (FAILED(hr)) + { + TraceEvents(TRACE_LEVEL_ERROR, + TEST_TRACE_DEVICE, + "%!FUNC! Unable to set timeout policy for input pipe %!HRESULT!", + hr + ); + } + } + + if (SUCCEEDED(hr)) + { + timeout = ENDPOINT_TIMEOUT; + + hr = m_pIUsbOutputPipe->SetPipePolicy(PIPE_TRANSFER_TIMEOUT, + sizeof(timeout), + &timeout); + if (FAILED(hr)) + { + TraceEvents(TRACE_LEVEL_ERROR, + TEST_TRACE_DEVICE, + "%!FUNC! Unable to set timeout policy for output pipe %!HRESULT!", + hr + ); + } + } + + return hr; +} + +HRESULT +CMyDevice::SetBarGraphDisplay( + _In_ PBAR_GRAPH_STATE BarGraphState + ) +/*++ + + Routine Description: + + This method synchronously sets the bar graph display on the OSR USB-FX2 + device using the buffers in the FxRequest as input. + + Arguments: + + FxRequest - the request to set the bar-graph info. + + Return Value: + + Status + +--*/ +{ + WINUSB_CONTROL_SETUP_PACKET setupPacket; + + ULONG bytesTransferred; + + HRESULT hr = S_OK; + + // + // Setup the control packet. + // + + WINUSB_CONTROL_SETUP_PACKET_INIT( &setupPacket, + BmRequestHostToDevice, + BmRequestToDevice, + USBFX2LK_SET_BARGRAPH_DISPLAY, + 0, + 0 ); + + // + // Issue the request to WinUsb. + // + + hr = SendControlTransferSynchronously( + &(setupPacket.WinUsb), + (PUCHAR) BarGraphState, + sizeof(BAR_GRAPH_STATE), + &bytesTransferred + ); + + + return hr; +} + +HRESULT +CMyDevice::SendControlTransferSynchronously( + _In_ PWINUSB_SETUP_PACKET SetupPacket, + _Inout_updates_(BufferLength) PBYTE Buffer, + _In_ ULONG BufferLength, + _Out_ PULONG LengthTransferred + ) +{ + HRESULT hr = S_OK; + HRESULT hrRequest = S_OK; + IWDFIoRequest *pWdfRequest = NULL; + IWDFDriver * FxDriver = NULL; + IWDFMemory * FxMemory = NULL; + IWDFRequestCompletionParams * FxComplParams = NULL; + IWDFUsbRequestCompletionParams * FxUsbComplParams = NULL; + + *LengthTransferred = 0; + + hr = m_FxDevice->CreateRequest( NULL, //pCallbackInterface + NULL, //pParentObject + &pWdfRequest); + hrRequest = hr; + + if (SUCCEEDED(hr)) + { + m_FxDevice->GetDriver(&FxDriver); + + hr = FxDriver->CreatePreallocatedWdfMemory( Buffer, + BufferLength, + NULL, //pCallbackInterface + pWdfRequest, //pParetObject + &FxMemory ); + } + + if (SUCCEEDED(hr)) + { + hr = m_pIUsbTargetDevice->FormatRequestForControlTransfer( pWdfRequest, + SetupPacket, + FxMemory, + NULL); //TransferOffset + } + + if (SUCCEEDED(hr)) + { + hr = pWdfRequest->Send( m_pIUsbTargetDevice, + WDF_REQUEST_SEND_OPTION_SYNCHRONOUS, + 0); //Timeout + } + + if (SUCCEEDED(hr)) + { + pWdfRequest->GetCompletionParams(&FxComplParams); + + hr = FxComplParams->GetCompletionStatus(); + } + + if (SUCCEEDED(hr)) + { + HRESULT hrQI = FxComplParams->QueryInterface(IID_PPV_ARGS(&FxUsbComplParams)); + WUDF_TEST_DRIVER_ASSERT(SUCCEEDED(hrQI)); + + WUDF_TEST_DRIVER_ASSERT( WdfUsbRequestTypeDeviceControlTransfer == + FxUsbComplParams->GetCompletedUsbRequestType() ); + + FxUsbComplParams->GetDeviceControlTransferParameters( NULL, + LengthTransferred, + NULL, + NULL ); + } + + SAFE_RELEASE(FxUsbComplParams); + SAFE_RELEASE(FxComplParams); + SAFE_RELEASE(FxMemory); + + if (SUCCEEDED(hrRequest)) + { + pWdfRequest->DeleteWdfObject(); + } + SAFE_RELEASE(pWdfRequest); + + SAFE_RELEASE(FxDriver); + + return hr; +} diff --git a/usb/wdf_osrfx2_lab/umdf/step4/Device.h b/usb/wdf_osrfx2_lab/umdf/step4/Device.h new file mode 100644 index 00000000..fe5acfed --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step4/Device.h @@ -0,0 +1,256 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + Device.h + +Abstract: + + This module contains the type definitions for the UMDF Skeleton sample + driver's device callback class. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once +#include "internal.h" + +#define ENDPOINT_TIMEOUT 10000 +#define NUM_OSRUSB_ENDPOINTS 3 + +// +// Define the vendor commands supported by our device +// +#define USBFX2LK_SET_BARGRAPH_DISPLAY 0xD8 + +// +// Class for the iotrace driver. +// + +class CMyDevice : + public CUnknown, + public IPnpCallbackHardware +{ + +// +// Private data members. +// +private: + // + // Weak reference to framework device + // + IWDFDevice *m_FxDevice; + + // + // Weak reference to the control queue + // + PCMyReadWriteQueue m_ReadWriteQueue; + + // + // Weak reference to the control queue + // + PCMyControlQueue m_ControlQueue; + + // + // USB Device I/O Target + // + IWDFUsbTargetDevice * m_pIUsbTargetDevice; + + // + // USB Interface + // + IWDFUsbInterface * m_pIUsbInterface; + + // + // USB Input pipe for Reads + // + IWDFUsbTargetPipe * m_pIUsbInputPipe; + + // + // USB Output pipe for writes + // + IWDFUsbTargetPipe * m_pIUsbOutputPipe; + + // + // Device Speed (Low, Full, High) + // + UCHAR m_Speed; + +// +// Private methods. +// + +private: + + CMyDevice( + VOID + ) : + m_FxDevice(NULL), + m_ControlQueue(NULL), + m_ReadWriteQueue(NULL), + m_pIUsbTargetDevice(NULL), + m_pIUsbInterface(NULL), + m_pIUsbInputPipe(NULL), + m_pIUsbOutputPipe(NULL), + m_Speed(0) + { + } + + ~CMyDevice( + ); + + HRESULT + Initialize( + _In_ IWDFDriver *FxDriver, + _In_ IWDFDeviceInitialize *FxDeviceInit + ); + + // + // Helper methods + // + + HRESULT + CreateUsbIoTargets( + VOID + ); + + + HRESULT + ConfigureUsbPipes( + ); + + HRESULT + SendControlTransferSynchronously( + _In_ PWINUSB_SETUP_PACKET SetupPacket, + _Inout_updates_(BufferLength) PBYTE Buffer, + _In_ ULONG BufferLength, + _Out_ PULONG LengthTransferred + ); + +// +// Public methods +// +public: + + // + // The factory method used to create an instance of this driver. + // + + static + HRESULT + CreateInstance( + _In_ IWDFDriver *FxDriver, + _In_ IWDFDeviceInitialize *FxDeviceInit, + _Out_ PCMyDevice *Device + ); + + IWDFDevice * + GetFxDevice( + VOID + ) + { + return m_FxDevice; + } + + HRESULT + Configure( + VOID + ); + + IPnpCallbackHardware * + QueryIPnpCallbackHardware( + VOID + ) + { + AddRef(); + return static_cast<IPnpCallbackHardware *>(this); + } + + HRESULT + SetBarGraphDisplay( + _In_ PBAR_GRAPH_STATE BarGraphState + ); + + // + //returns a weak reference to input pipe + //DO NOT release it + // + IWDFUsbTargetPipe * + GetInputPipe( + ) + { + return m_pIUsbInputPipe; + } + + // + //returns a weak reference to output pipe + //DO NOT release it + // + IWDFUsbTargetPipe * + GetOutputPipe( + ) + { + return m_pIUsbOutputPipe; + } + +// +// COM methods +// +public: + + // + // IUnknown methods. + // + + virtual + ULONG + STDMETHODCALLTYPE + AddRef( + VOID + ) + { + return __super::AddRef(); + } + + _At_(this, __drv_freesMem(object)) + virtual + ULONG + STDMETHODCALLTYPE + Release( + VOID + ) + { + return __super::Release(); + } + + virtual + HRESULT + STDMETHODCALLTYPE + QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ); + + // + // IPnpCallbackHardware + // + + virtual + HRESULT + STDMETHODCALLTYPE + OnPrepareHardware( + _In_ IWDFDevice *FxDevice + ); + + virtual + HRESULT + STDMETHODCALLTYPE + OnReleaseHardware( + _In_ IWDFDevice *FxDevice + ); +}; diff --git a/usb/wdf_osrfx2_lab/umdf/step4/Driver.cpp b/usb/wdf_osrfx2_lab/umdf/step4/Driver.cpp new file mode 100644 index 00000000..bac5caca --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step4/Driver.cpp @@ -0,0 +1,220 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved. + +Module Name: + + Driver.cpp + +Abstract: + + This module contains the implementation of the UMDF Skeleton Sample's + core driver callback object. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#include "internal.h" +#include "driver.tmh" + +HRESULT +CMyDriver::CreateInstance( + _Out_ PCMyDriver *Driver + ) +/*++ + + Routine Description: + + This static method is invoked in order to create and initialize a new + instance of the driver class. The caller should arrange for the object + to be released when it is no longer in use. + + Arguments: + + Driver - a location to store a referenced pointer to the new instance + + Return Value: + + S_OK if successful, or error otherwise. + +--*/ +{ + PCMyDriver driver; + HRESULT hr; + + // + // Allocate the callback object. + // + + driver = new CMyDriver(); + + if (NULL == driver) + { + return E_OUTOFMEMORY; + } + + // + // Initialize the callback object. + // + + hr = driver->Initialize(); + + if (SUCCEEDED(hr)) + { + // + // Store a pointer to the new, initialized object in the output + // parameter. + // + + *Driver = driver; + } + else + { + + // + // Release the reference on the driver object to get it to delete + // itself. + // + + driver->Release(); + } + + return hr; +} + +HRESULT +CMyDriver::Initialize( + VOID + ) +/*++ + + Routine Description: + + This method is called to initialize a newly created driver callback object + before it is returned to the creator. Unlike the constructor, the + Initialize method contains operations which could potentially fail. + + Arguments: + + None + + Return Value: + + None + +--*/ +{ + return S_OK; +} + +HRESULT +CMyDriver::QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Interface + ) +/*++ + + Routine Description: + + This method returns a pointer to the requested interface on the callback + object.. + + Arguments: + + InterfaceId - the IID of the interface to query/reference + + Interface - a location to store the interface pointer. + + Return Value: + + S_OK if the interface is supported. + E_NOINTERFACE if it is not supported. + +--*/ +{ + if (IsEqualIID(InterfaceId, __uuidof(IDriverEntry))) + { + *Interface = QueryIDriverEntry(); + return S_OK; + } + else + { + return CUnknown::QueryInterface(InterfaceId, Interface); + } +} + +HRESULT +CMyDriver::OnDeviceAdd( + _In_ IWDFDriver *FxWdfDriver, + _In_ IWDFDeviceInitialize *FxDeviceInit + ) +/*++ + + Routine Description: + + The FX invokes this method when it wants to install our driver on a device + stack. This method creates a device callback object, then calls the Fx + to create an Fx device object and associate the new callback object with + it. + + Arguments: + + FxWdfDriver - the Fx driver object. + + FxDeviceInit - the initialization information for the device. + + Return Value: + + status + +--*/ +{ + HRESULT hr; + + PCMyDevice device = NULL; + + // + // TODO: Do any per-device initialization (reading settings from the + // registry for example) that's necessary before creating your + // device callback object here. Otherwise you can leave such + // initialization to the initialization of the device event + // handler. + // + + // + // Create a new instance of our device callback object + // + + hr = CMyDevice::CreateInstance(FxWdfDriver, FxDeviceInit, &device); + + // + // TODO: Change any per-device settings that the object exposes before + // calling Configure to let it complete its initialization. + // + + // + // If that succeeded then call the device's construct method. This + // allows the device to create any queues or other structures that it + // needs now that the corresponding fx device object has been created. + // + + if (SUCCEEDED(hr)) + { + hr = device->Configure(); + } + + // + // Release the reference on the device callback object now that it's been + // associated with an fx device object. + // + + if (NULL != device) + { + device->Release(); + } + + return hr; +} diff --git a/usb/wdf_osrfx2_lab/umdf/step4/Driver.h b/usb/wdf_osrfx2_lab/umdf/step4/Driver.h new file mode 100644 index 00000000..800ab1d9 --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step4/Driver.h @@ -0,0 +1,149 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + Driver.h + +Abstract: + + This module contains the type definitions for the UMDF Skeleton sample's + driver callback class. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once + +// +// This class handles driver events for the skeleton sample. In particular +// it supports the OnDeviceAdd event, which occurs when the driver is called +// to setup per-device handlers for a new device stack. +// + +class CMyDriver : public CUnknown, public IDriverEntry +{ +// +// Private data members. +// +private: + +// +// Private methods. +// +private: + + // + // Returns a refernced pointer to the IDriverEntry interface. + // + + IDriverEntry * + QueryIDriverEntry( + VOID + ) + { + AddRef(); + return static_cast<IDriverEntry*>(this); + } + + HRESULT + Initialize( + VOID + ); + +// +// Public methods +// +public: + + // + // The factory method used to create an instance of this driver. + // + + static + HRESULT + CreateInstance( + _Out_ PCMyDriver *Driver + ); + +// +// COM methods +// +public: + + // + // IDriverEntry methods + // + + virtual + HRESULT + STDMETHODCALLTYPE + OnInitialize( + _In_ IWDFDriver *FxWdfDriver + ) + { + UNREFERENCED_PARAMETER(FxWdfDriver); + + return S_OK; + } + + virtual + HRESULT + STDMETHODCALLTYPE + OnDeviceAdd( + _In_ IWDFDriver *FxWdfDriver, + _In_ IWDFDeviceInitialize *FxDeviceInit + ); + + virtual + VOID + STDMETHODCALLTYPE + OnDeinitialize( + _In_ IWDFDriver *FxWdfDriver + ) + { + UNREFERENCED_PARAMETER(FxWdfDriver); + + return; + } + + // + // IUnknown methods. + // + // We have to implement basic ones here that redirect to the + // base class becuase of the multiple inheritance. + // + + virtual + ULONG + STDMETHODCALLTYPE + AddRef( + VOID + ) + { + return __super::AddRef(); + } + + _At_(this, __drv_freesMem(object)) + virtual + ULONG + STDMETHODCALLTYPE + Release( + VOID + ) + { + return __super::Release(); + } + + virtual + HRESULT + STDMETHODCALLTYPE + QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ); +}; diff --git a/usb/wdf_osrfx2_lab/umdf/step4/OsrUsbFx2.ctl b/usb/wdf_osrfx2_lab/umdf/step4/OsrUsbFx2.ctl new file mode 100644 index 00000000..4dab56ae --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step4/OsrUsbFx2.ctl @@ -0,0 +1 @@ +da5fbdfd-1eae-4ecf-b426-a3818f325ddb WudfOsrUsbFx2TraceGuid diff --git a/usb/wdf_osrfx2_lab/umdf/step4/OsrUsbFx2.rc b/usb/wdf_osrfx2_lab/umdf/step4/OsrUsbFx2.rc new file mode 100644 index 00000000..36f10ea9 --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step4/OsrUsbFx2.rc @@ -0,0 +1,21 @@ +//--------------------------------------------------------------------------- +// OsrUsbDevice.rc +// +// Copyright (c) Microsoft Corporation, All Rights Reserved +//--------------------------------------------------------------------------- + + +#include <windows.h> +#include <ntverp.h> + +// +// TODO: Change the file description and file names to match your binary. +// + +#define VER_FILETYPE VFT_DLL +#define VER_FILESUBTYPE VFT_UNKNOWN +#define VER_FILEDESCRIPTION_STR "WDF:UMDF OSR USB Fx2 User-Mode Driver Sample" +#define VER_INTERNALNAME_STR "WUDFOsrUsbFx2" +#define VER_ORIGINALFILENAME_STR "WUDFOsrUsbFx2.dll" + +#include "common.ver" diff --git a/usb/wdf_osrfx2_lab/umdf/step4/ReadWriteQueue.cpp b/usb/wdf_osrfx2_lab/umdf/step4/ReadWriteQueue.cpp new file mode 100644 index 00000000..21f42548 --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step4/ReadWriteQueue.cpp @@ -0,0 +1,423 @@ +/*++ + +Copyright (c) Microsoft Corporation, All Rights Reserved + +Module Name: + + queue.cpp + +Abstract: + + This file implements the I/O queue interface and performs + the read/write/ioctl operations. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#include "internal.h" +#include "ReadWriteQueue.tmh" + +VOID +CMyReadWriteQueue::OnCompletion( + _In_ IWDFIoRequest* pWdfRequest, + _In_ IWDFIoTarget* pIoTarget, + _In_ IWDFRequestCompletionParams* pParams, + _In_ PVOID pContext + ) +{ + UNREFERENCED_PARAMETER(pIoTarget); + UNREFERENCED_PARAMETER(pContext); + + pWdfRequest->CompleteWithInformation( + pParams->GetCompletionStatus(), + pParams->GetInformation() + ); +} + +void +CMyReadWriteQueue::ForwardFormattedRequest( + _In_ IWDFIoRequest* pRequest, + _In_ IWDFIoTarget* pIoTarget + ) +{ + // + //First set the completion callback + // + + IRequestCallbackRequestCompletion * pCompletionCallback = NULL; + HRESULT hrQI = this->QueryInterface(IID_PPV_ARGS(&pCompletionCallback)); + WUDF_TEST_DRIVER_ASSERT(SUCCEEDED(hrQI) && (NULL != pCompletionCallback)); + + pRequest->SetCompletionCallback( + pCompletionCallback, + NULL + ); + + pCompletionCallback->Release(); + pCompletionCallback = NULL; + + // + //Send down the request + // + + HRESULT hrSend = S_OK; + hrSend = pRequest->Send(pIoTarget, + 0, //flags + 0); //timeout + + if (FAILED(hrSend)) + { + pRequest->CompleteWithInformation(hrSend, 0); + } + + return; +} + + +CMyReadWriteQueue::CMyReadWriteQueue( + _In_ PCMyDevice Device + ) : + CMyQueue(Device) +{ +} + +// +// Queue destructor. +// Free up the buffer, wait for thread to terminate and +// + +CMyReadWriteQueue::~CMyReadWriteQueue( + VOID + ) +/*++ + +Routine Description: + + + IUnknown implementation of Release + +Aruments: + + +Return Value: + + ULONG (reference count after Release) + +--*/ +{ + TraceEvents(TRACE_LEVEL_INFORMATION, + TEST_TRACE_QUEUE, + "%!FUNC! Entry" + ); + +} + + +HRESULT +STDMETHODCALLTYPE +CMyReadWriteQueue::QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ) +/*++ + +Routine Description: + + + Query Interface + +Aruments: + + Follows COM specifications + +Return Value: + + HRESULT indicatin success or failure + +--*/ +{ + HRESULT hr; + + + if (IsEqualIID(InterfaceId, __uuidof(IQueueCallbackWrite))) + { + hr = S_OK; + *Object = QueryIQueueCallbackWrite(); + } + else if (IsEqualIID(InterfaceId, __uuidof(IQueueCallbackRead))) + { + hr = S_OK; + *Object = QueryIQueueCallbackRead(); + } + else if (IsEqualIID(InterfaceId, __uuidof(IRequestCallbackRequestCompletion))) + { + hr = S_OK; + *Object = QueryIRequestCallbackRequestCompletion(); + } + else if (IsEqualIID(InterfaceId, __uuidof(IQueueCallbackIoStop))) + { + hr = S_OK; + *Object = QueryIQueueCallbackIoStop(); + } + else + { + hr = CMyQueue::QueryInterface(InterfaceId, Object); + } + + return hr; +} + +// +// Initialize +// + +HRESULT +CMyReadWriteQueue::CreateInstance( + _In_ PCMyDevice Device, + _Out_ PCMyReadWriteQueue *Queue + ) +/*++ + +Routine Description: + + + CreateInstance creates an instance of the queue object. + +Aruments: + + ppUkwn - OUT parameter is an IUnknown interface to the queue object + +Return Value: + + HRESULT indicatin success or failure + +--*/ +{ + PCMyReadWriteQueue queue; + HRESULT hr = S_OK; + + queue = new CMyReadWriteQueue(Device); + + if (NULL == queue) + { + hr = E_OUTOFMEMORY; + } + + // + // Call the queue callback object to initialize itself. This will create + // its partner queue framework object. + // + + if (SUCCEEDED(hr)) + { + hr = queue->Initialize(); + } + + if (SUCCEEDED(hr)) + { + *Queue = queue; + } + else + { + SAFE_RELEASE(queue); + } + + return hr; +} + +HRESULT +CMyReadWriteQueue::Initialize( + ) +{ + HRESULT hr; + + // + // First initialize the base class. This will create the partner FxIoQueue + // object and setup automatic forwarding of I/O controls. + // + + hr = __super::Initialize(WdfIoQueueDispatchParallel, + true, + true); + + // + // return the status. + // + + return hr; +} + +STDMETHODIMP_ (void) +CMyReadWriteQueue::OnWrite( + _In_ IWDFIoQueue *pWdfQueue, + _In_ IWDFIoRequest *pWdfRequest, + _In_ SIZE_T BytesToWrite + ) +/*++ + +Routine Description: + + + Write dispatch routine + IQueueCallbackWrite + +Aruments: + + pWdfQueue - Framework Queue instance + pWdfRequest - Framework Request instance + BytesToWrite - Lenth of bytes in the write buffer + + Allocate and copy data to local buffer +Return Value: + + VOID + +--*/ +{ + UNREFERENCED_PARAMETER(pWdfQueue); + + TraceEvents(TRACE_LEVEL_INFORMATION, + TEST_TRACE_QUEUE, + "%!FUNC!: Queue %p Request %p BytesToTransfer %d\n", + this, + pWdfRequest, + (ULONG)(ULONG_PTR)BytesToWrite + ); + + HRESULT hr = S_OK; + IWDFMemory * pInputMemory = NULL; + IWDFUsbTargetPipe * pOutputPipe = m_Device->GetOutputPipe(); + + pWdfRequest->GetInputMemory(&pInputMemory); + + hr = pOutputPipe->FormatRequestForWrite( + pWdfRequest, + NULL, //pFile + pInputMemory, + NULL, //Memory offset + NULL //DeviceOffset + ); + + if (FAILED(hr)) + { + pWdfRequest->Complete(hr); + } + else + { + ForwardFormattedRequest(pWdfRequest, pOutputPipe); + } + + SAFE_RELEASE(pInputMemory); + + return; +} + +STDMETHODIMP_ (void) +CMyReadWriteQueue::OnRead( + _In_ IWDFIoQueue *pWdfQueue, + _In_ IWDFIoRequest *pWdfRequest, + _In_ SIZE_T BytesToRead + ) +/*++ + +Routine Description: + + + Read dispatch routine + IQueueCallbackRead + +Aruments: + + pWdfQueue - Framework Queue instance + pWdfRequest - Framework Request instance + BytesToRead - Lenth of bytes in the read buffer + + Copy available data into the read buffer +Return Value: + + VOID + +--*/ +{ + UNREFERENCED_PARAMETER(pWdfQueue); + + TraceEvents(TRACE_LEVEL_INFORMATION, + TEST_TRACE_QUEUE, + "%!FUNC!: Queue %p Request %p BytesToTransfer %d\n", + this, + pWdfRequest, + (ULONG)(ULONG_PTR)BytesToRead + ); + + HRESULT hr = S_OK; + IWDFMemory * pOutputMemory = NULL; + + pWdfRequest->GetOutputMemory(&pOutputMemory); + + hr = m_Device->GetInputPipe()->FormatRequestForRead( + pWdfRequest, + NULL, //pFile + pOutputMemory, + NULL, //Memory offset + NULL //DeviceOffset + ); + + if (FAILED(hr)) + { + pWdfRequest->Complete(hr); + } + else + { + ForwardFormattedRequest(pWdfRequest, m_Device->GetInputPipe()); + } + + SAFE_RELEASE(pOutputMemory); + + return; +} + +STDMETHODIMP_ (void) +CMyReadWriteQueue::OnIoStop( + _In_ IWDFIoQueue * pWdfQueue, + _In_ IWDFIoRequest * pWdfRequest, + _In_ ULONG ActionFlags + ) +{ + UNREFERENCED_PARAMETER(pWdfQueue); + + + // + // Because of device level locking we know that if our driver + // owns the request and we get here, our OnRead/OnWrite callback + // has returned and the request has been sent to I/O target + // + + if (ActionFlags == WdfRequestStopActionSuspend ) + { + // + // UMDF does not support an equivalent to WdfRequestStopAcknowledge. + // + // Cancel the request so that the power management operation can continue. + // + // NOTE: if cancelling the request would have an adverse affect and if the + // requests are expected to complete very quickly then leaving the + // request running may be a better option. + // + + pWdfRequest->CancelSentRequest(); + } + else if(ActionFlags == WdfRequestStopActionPurge) + { + // + // Cancel the sent request since we are asked to purge the request + // + + pWdfRequest->CancelSentRequest(); + } + + return; +} + diff --git a/usb/wdf_osrfx2_lab/umdf/step4/ReadWriteQueue.h b/usb/wdf_osrfx2_lab/umdf/step4/ReadWriteQueue.h new file mode 100644 index 00000000..4f1a98c1 --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step4/ReadWriteQueue.h @@ -0,0 +1,163 @@ +/*++ + +Copyright (c) Microsoft Corporation, All Rights Reserved + +Module Name: + + queue.h + +Abstract: + + This file defines the queue callback interface. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once + + +#define MAX_TRANSFER_SIZE(x) 64*1024*1024 + +// +// Queue Callback Object. +// + +class CMyReadWriteQueue : + public IQueueCallbackRead, + public IQueueCallbackWrite, + public IRequestCallbackRequestCompletion, + public IQueueCallbackIoStop, + public CMyQueue +{ +protected: + HRESULT + Initialize( + ); + + void + ForwardFormattedRequest( + _In_ IWDFIoRequest* pRequest, + _In_ IWDFIoTarget* pIoTarget + ); + +public: + + CMyReadWriteQueue( + _In_ PCMyDevice Device + ); + + virtual ~CMyReadWriteQueue(); + + static + HRESULT + CreateInstance( + _In_ PCMyDevice Device, + _Out_ PCMyReadWriteQueue *Queue + ); + + HRESULT + Configure( + VOID + ) + { + return CMyQueue::Configure(); + } + + IQueueCallbackWrite * + QueryIQueueCallbackWrite( + VOID + ) + { + AddRef(); + return static_cast<IQueueCallbackWrite *>(this); + } + + IQueueCallbackRead * + QueryIQueueCallbackRead( + VOID + ) + { + AddRef(); + return static_cast<IQueueCallbackRead *>(this); + } + + IRequestCallbackRequestCompletion * + QueryIRequestCallbackRequestCompletion( + VOID + ) + { + AddRef(); + return static_cast<IRequestCallbackRequestCompletion *>(this); + } + + IQueueCallbackIoStop* + QueryIQueueCallbackIoStop( + VOID + ) + { + AddRef(); + return static_cast<IQueueCallbackIoStop *>(this); + } + + // + // IUnknown + // + + STDMETHOD_(ULONG,AddRef) (VOID) {return CUnknown::AddRef();} + + _At_(this, __drv_freesMem(object)) + STDMETHOD_(ULONG,Release) (VOID) {return CUnknown::Release();} + + STDMETHOD_(HRESULT, QueryInterface)( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ); + + + // + // Wdf Callbacks + // + + // + // IQueueCallbackWrite + // + STDMETHOD_ (void, OnWrite)( + _In_ IWDFIoQueue *pWdfQueue, + _In_ IWDFIoRequest *pWdfRequest, + _In_ SIZE_T NumOfBytesToWrite + ); + + // + // IQueueCallbackRead + // + STDMETHOD_ (void, OnRead)( + _In_ IWDFIoQueue *pWdfQueue, + _In_ IWDFIoRequest *pWdfRequest, + _In_ SIZE_T NumOfBytesToRead + ); + + // + //IRequestCallbackRequestCompletion + // + + STDMETHOD_ (void, OnCompletion)( + _In_ IWDFIoRequest* pWdfRequest, + _In_ IWDFIoTarget* pIoTarget, + _In_ IWDFRequestCompletionParams* pParams, + _In_ PVOID pContext + ); + + // + //IQueueCallbackIoStop + // + + STDMETHOD_ (void, OnIoStop)( + _In_ IWDFIoQueue * pWdfQueue, + _In_ IWDFIoRequest * pWdfRequest, + _In_ ULONG ActionFlags + ); + +}; diff --git a/usb/wdf_osrfx2_lab/umdf/step4/WUDFOsrUsbFx2_4.inx b/usb/wdf_osrfx2_lab/umdf/step4/WUDFOsrUsbFx2_4.inx Binary files differnew file mode 100644 index 00000000..3eaae162 --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step4/WUDFOsrUsbFx2_4.inx diff --git a/usb/wdf_osrfx2_lab/umdf/step4/WUDFOsrUsbFx2_4.vcxproj b/usb/wdf_osrfx2_lab/umdf/step4/WUDFOsrUsbFx2_4.vcxproj new file mode 100644 index 00000000..725e33b5 --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step4/WUDFOsrUsbFx2_4.vcxproj @@ -0,0 +1,267 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{48343119-5771-494E-977E-0D439A45BF65}</ProjectGuid> + <RootNamespace>$(MSBuildProjectName)</RootNamespace> + <UMDF_VERSION_MAJOR>1</UMDF_VERSION_MAJOR> + <KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR> + <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration> + <Platform Condition="'$(Platform)' == ''">Win32</Platform> + <SampleGuid>{F45B07B6-EA19-4312-9BB3-5CF1BAFF50A8}</SampleGuid> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType>UMDF</DriverType> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType>UMDF</DriverType> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType>UMDF</DriverType> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType>UMDF</DriverType> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <OutDir>$(IntDir)</OutDir> + </PropertyGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ItemGroup Label="WrappedTaskItems"> + <ClCompile Include="dllsup.cpp; comsup.cpp; driver.cpp; device.cpp; queue.cpp; ControlQueue.cpp; ReadWriteQueue.cpp"> + <WppEnabled>true</WppEnabled> + <WppDllMacro>true</WppDllMacro> + <WppScanConfigurationData>internal.h</WppScanConfigurationData> + </ClCompile> + <OtherWpp Include="OsrUsbFx2.rc"> + <WppEnabled>true</WppEnabled> + <WppDllMacro>true</WppDllMacro> + <WppScanConfigurationData>internal.h</WppScanConfigurationData> + </OtherWpp> + </ItemGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetName>WUDFOsrUsbFx2_4</TargetName> + <WIN32_WINNT_VERSION>0x0A00</WIN32_WINNT_VERSION> + <NTDDI_VERSION>0x0A000000</NTDDI_VERSION> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetName>WUDFOsrUsbFx2_4</TargetName> + <WIN32_WINNT_VERSION>0x0A00</WIN32_WINNT_VERSION> + <NTDDI_VERSION>0x0A000000</NTDDI_VERSION> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetName>WUDFOsrUsbFx2_4</TargetName> + <WIN32_WINNT_VERSION>0x0A00</WIN32_WINNT_VERSION> + <NTDDI_VERSION>0x0A000000</NTDDI_VERSION> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetName>WUDFOsrUsbFx2_4</TargetName> + <WIN32_WINNT_VERSION>0x0A00</WIN32_WINNT_VERSION> + <NTDDI_VERSION>0x0A000000</NTDDI_VERSION> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <DisableSpecificWarnings>%(DisableSpecificWarnings);4201</DisableSpecificWarnings> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ClCompile> + <Midl> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </Midl> + <ResourceCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ResourceCompile> + <Link> + <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol> + <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <DisableSpecificWarnings>%(DisableSpecificWarnings);4201</DisableSpecificWarnings> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ClCompile> + <Midl> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </Midl> + <ResourceCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ResourceCompile> + <Link> + <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol> + <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <DisableSpecificWarnings>%(DisableSpecificWarnings);4201</DisableSpecificWarnings> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ClCompile> + <Midl> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </Midl> + <ResourceCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ResourceCompile> + <Link> + <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol> + <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <DisableSpecificWarnings>%(DisableSpecificWarnings);4201</DisableSpecificWarnings> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ClCompile> + <Midl> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </Midl> + <ResourceCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ResourceCompile> + <Link> + <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol> + <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\kernel32.lib;$(SDK_LIB_PATH)\advapi32.lib</AdditionalDependencies> + <ModuleDefinitionFile>exports.def</ModuleDefinitionFile> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\kernel32.lib;$(SDK_LIB_PATH)\advapi32.lib</AdditionalDependencies> + <ModuleDefinitionFile>exports.def</ModuleDefinitionFile> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\kernel32.lib;$(SDK_LIB_PATH)\advapi32.lib</AdditionalDependencies> + <ModuleDefinitionFile>exports.def</ModuleDefinitionFile> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + </ResourceCompile> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\inc</AdditionalIncludeDirectories> + </Midl> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\kernel32.lib;$(SDK_LIB_PATH)\advapi32.lib</AdditionalDependencies> + <ModuleDefinitionFile>exports.def</ModuleDefinitionFile> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ResourceCompile Include="OsrUsbFx2.rc" /> + </ItemGroup> + <ItemGroup> + <Inf Exclude="@(Inf)" Include="*.inf" /> + <FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" /> + </ItemGroup> + <ItemGroup> + <None Exclude="@(None)" Include="*.txt;*.htm;*.html" /> + <None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" /> + <None Exclude="@(None)" Include="*.def;*.bat;*.hpj;*.asmx" /> + </ItemGroup> + <ItemGroup> + <ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> +</Project>
\ No newline at end of file diff --git a/usb/wdf_osrfx2_lab/umdf/step4/WUDFOsrUsbFx2_4.vcxproj.Filters b/usb/wdf_osrfx2_lab/umdf/step4/WUDFOsrUsbFx2_4.vcxproj.Filters new file mode 100644 index 00000000..43c2d881 --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step4/WUDFOsrUsbFx2_4.vcxproj.Filters @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions> + <UniqueIdentifier>{FFDE5D69-37F8-4393-A23B-564E903D88CD}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files"> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + <UniqueIdentifier>{0B249192-6B94-4C90-BD54-09BDA2702DF1}</UniqueIdentifier> + </Filter> + <Filter Include="Resource Files"> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions> + <UniqueIdentifier>{080D7F17-64DE-4D25-95ED-5FB56D2F35D7}</UniqueIdentifier> + </Filter> + <Filter Include="Driver Files"> + <Extensions>inf;inv;inx;mof;mc;</Extensions> + <UniqueIdentifier>{71EC47E9-66DB-49A4-A668-16475FA16BB4}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="comsup.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ControlQueue.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="device.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="dllsup.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="driver.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="queue.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ReadWriteQueue.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <None Include="exports.def"> + <Filter>Source Files</Filter> + </None> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="OsrUsbFx2.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/usb/wdf_osrfx2_lab/umdf/step4/comsup.cpp b/usb/wdf_osrfx2_lab/umdf/step4/comsup.cpp new file mode 100644 index 00000000..9c9aec3b --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step4/comsup.cpp @@ -0,0 +1,344 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + ComSup.cpp + +Abstract: + + This module contains implementations for the functions and methods + used for providing COM support. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#include "internal.h" + +#include "comsup.tmh" + +// +// Implementation of CUnknown methods. +// + +CUnknown::CUnknown( + VOID + ) : m_ReferenceCount(1) +/*++ + + Routine Description: + + Constructor for an instance of the CUnknown class. This simply initializes + the reference count of the object to 1. The caller is expected to + call Release() if it wants to delete the object once it has been allocated. + + Arguments: + + None + + Return Value: + + None + +--*/ +{ + // do nothing. +} + +HRESULT +STDMETHODCALLTYPE +CUnknown::QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ) +/*++ + + Routine Description: + + This method provides the basic support for query interface on CUnknown. + If the interface requested is IUnknown it references the object and + returns an interface pointer. Otherwise it returns an error. + + Arguments: + + InterfaceId - the IID being requested + + Object - a location to store the interface pointer to return. + + Return Value: + + S_OK or E_NOINTERFACE + +--*/ +{ + if (IsEqualIID(InterfaceId, __uuidof(IUnknown))) + { + *Object = QueryIUnknown(); + return S_OK; + } + else + { + *Object = NULL; + return E_NOINTERFACE; + } +} + +IUnknown * +CUnknown::QueryIUnknown( + VOID + ) +/*++ + + Routine Description: + + This helper method references the object and returns a pointer to the + object's IUnknown interface. + + This allows other methods to convert a CUnknown pointer into an IUnknown + pointer without a typecast and without calling QueryInterface and dealing + with the return value. + + Arguments: + + None + + Return Value: + + A pointer to the object's IUnknown interface. + +--*/ +{ + AddRef(); + return static_cast<IUnknown *>(this); +} + +ULONG +STDMETHODCALLTYPE +CUnknown::AddRef( + VOID + ) +/*++ + + Routine Description: + + This method adds one to the object's reference count. + + Arguments: + + None + + Return Value: + + The new reference count. The caller should only use this for debugging + as the object's actual reference count can change while the caller + examines the return value. + +--*/ +{ + return InterlockedIncrement(&m_ReferenceCount); +} + +ULONG +STDMETHODCALLTYPE +CUnknown::Release( + VOID + ) +/*++ + + Routine Description: + + This method subtracts one to the object's reference count. If the count + goes to zero, this method deletes the object. + + Arguments: + + None + + Return Value: + + The new reference count. If the caller uses this value it should only be + to check for zero (i.e. this call caused or will cause deletion) or + non-zero (i.e. some other call may have caused deletion, but this one + didn't). + +--*/ +{ + ULONG count = InterlockedDecrement(&m_ReferenceCount); + + if (count == 0) + { + delete this; + } + return count; +} + +// +// Implementation of CClassFactory methods. +// + +// +// Define storage for the factory's static lock count variable. +// + +LONG CClassFactory::s_LockCount = 0; + +IClassFactory * +CClassFactory::QueryIClassFactory( + VOID + ) +/*++ + + Routine Description: + + This helper method references the object and returns a pointer to the + object's IClassFactory interface. + + This allows other methods to convert a CClassFactory pointer into an + IClassFactory pointer without a typecast and without dealing with the + return value QueryInterface. + + Arguments: + + None + + Return Value: + + A referenced pointer to the object's IClassFactory interface. + +--*/ +{ + AddRef(); + return static_cast<IClassFactory *>(this); +} + +HRESULT +CClassFactory::QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ) +/*++ + + Routine Description: + + This method attempts to retrieve the requested interface from the object. + + If the interface is found then the reference count on that interface (and + thus the object itself) is incremented. + + Arguments: + + InterfaceId - the interface the caller is requesting. + + Object - a location to store the interface pointer. + + Return Value: + + S_OK or E_NOINTERFACE + +--*/ +{ + // + // This class only supports IClassFactory so check for that. + // + + if (IsEqualIID(InterfaceId, __uuidof(IClassFactory))) + { + *Object = QueryIClassFactory(); + return S_OK; + } + else + { + // + // See if the base class supports the interface. + // + + return CUnknown::QueryInterface(InterfaceId, Object); + } +} + +HRESULT +STDMETHODCALLTYPE +CClassFactory::CreateInstance( + _In_opt_ IUnknown * /* OuterObject */, + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ) +/*++ + + Routine Description: + + This COM method is the factory routine - it creates instances of the driver + callback class and returns the specified interface on them. + + Arguments: + + OuterObject - only used for aggregation, which our driver callback class + does not support. + + InterfaceId - the interface ID the caller would like to get from our + new object. + + Object - a location to store the referenced interface pointer to the new + object. + + Return Value: + + Status. + +--*/ +{ + HRESULT hr; + + PCMyDriver driver; + + *Object = NULL; + + hr = CMyDriver::CreateInstance(&driver); + + if (SUCCEEDED(hr)) + { + hr = driver->QueryInterface(InterfaceId, Object); + driver->Release(); + } + + return hr; +} + +HRESULT +STDMETHODCALLTYPE +CClassFactory::LockServer( + _In_ BOOL Lock + ) +/*++ + + Routine Description: + + This COM method can be used to keep the DLL in memory. However since the + driver's DllCanUnloadNow function always returns false, this has little + effect. Still it tracks the number of lock and unlock operations. + + Arguments: + + Lock - Whether the caller wants to lock or unlock the "server" + + Return Value: + + S_OK + +--*/ +{ + if (Lock) + { + InterlockedIncrement(&s_LockCount); + } + else + { + InterlockedDecrement(&s_LockCount); + } + return S_OK; +} + diff --git a/usb/wdf_osrfx2_lab/umdf/step4/comsup.h b/usb/wdf_osrfx2_lab/umdf/step4/comsup.h new file mode 100644 index 00000000..dedf78c8 --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step4/comsup.h @@ -0,0 +1,215 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + ComSup.h + +Abstract: + + This module contains classes and functions use for providing COM support + code. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once + +// +// Forward type declarations. They are here rather than in internal.h as +// you only need them if you choose to use these support classes. +// + +typedef class CUnknown *PCUnknown; +typedef class CClassFactory *PCClassFactory; + +// +// Base class to implement IUnknown. You can choose to derive your COM +// classes from this class, or simply implement IUnknown in each of your +// classes. +// + +class CUnknown : public IUnknown +{ + +// +// Private data members and methods. These are only accessible by the methods +// of this class. +// +private: + + // + // The reference count for this object. Initialized to 1 in the + // constructor. + // + + LONG m_ReferenceCount; + +// +// Protected data members and methods. These are accessible by the subclasses +// but not by other classes. +// +protected: + + // + // The constructor and destructor are protected to ensure that only the + // subclasses of CUnknown can create and destroy instances. + // + + CUnknown( + VOID + ); + + // + // The destructor MUST be virtual. Since any instance of a CUnknown + // derived class should only be deleted from within CUnknown::Release, + // the destructor MUST be virtual or only CUnknown::~CUnknown will get + // invoked on deletion. + // + // If you see that your CMyDevice specific destructor is never being + // called, make sure you haven't deleted the virtual destructor here. + // + + virtual + ~CUnknown( + VOID + ) + { + // Do nothing + } + +// +// Public Methods. These are accessible by any class. +// +public: + + IUnknown * + QueryIUnknown( + VOID + ); + +// +// COM Methods. +// +public: + + // + // IUnknown methods + // + + virtual + ULONG + STDMETHODCALLTYPE + AddRef( + VOID + ); + + virtual + ULONG + STDMETHODCALLTYPE + Release( + VOID + ); + + virtual + HRESULT + STDMETHODCALLTYPE + QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ); +}; + +// +// Class factory support class. Create an instance of this from your +// DllGetClassObject method and modify the implementation to create +// an instance of your driver event handler class. +// + +class CClassFactory : public CUnknown, public IClassFactory +{ +// +// Private data members and methods. These are only accessible by the methods +// of this class. +// +private: + + // + // The lock count. This is shared across all instances of IClassFactory + // and can be queried through the public IsLocked method. + // + + static LONG s_LockCount; + +// +// Public Methods. These are accessible by any class. +// +public: + + IClassFactory * + QueryIClassFactory( + VOID + ); + +// +// COM Methods. +// +public: + + // + // IUnknown methods + // + + virtual + ULONG + STDMETHODCALLTYPE + AddRef( + VOID + ) + { + return __super::AddRef(); + } + + _At_(this, __drv_freesMem(object)) + virtual + ULONG + STDMETHODCALLTYPE + Release( + VOID + ) + { + return __super::Release(); + } + + virtual + HRESULT + STDMETHODCALLTYPE + QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ); + + // + // IClassFactory methods. + // + + virtual + HRESULT + STDMETHODCALLTYPE + CreateInstance( + _In_opt_ IUnknown *OuterObject, + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ); + + virtual + HRESULT + STDMETHODCALLTYPE + LockServer( + _In_ BOOL Lock + ); +}; diff --git a/usb/wdf_osrfx2_lab/umdf/step4/dllsup.cpp b/usb/wdf_osrfx2_lab/umdf/step4/dllsup.cpp new file mode 100644 index 00000000..e8bad81b --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step4/dllsup.cpp @@ -0,0 +1,202 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved. + +Module Name: + + dllsup.cpp + +Abstract: + + This module contains the implementation of the UMDF Skeleton Sample + Driver's entry point and its exported functions for providing COM support. + + This module can be copied without modification to a new UMDF driver. It + depends on some of the code in comsup.cpp & comsup.h to handle DLL + registration and creating the first class factory. + + This module is dependent on the following defines: + + MYDRIVER_TRACING_ID - A wide string passed to WPP when initializing + tracing. For example the skeleton uses + L"Microsoft\\UMDF\\Skeleton" + + MYDRIVER_CLASS_ID - A GUID encoded in struct format used to + initialize the driver's ClassID. + + These are defined in internal.h for the skeleton sample. If you choose + to use a different primary include file, you should ensure they are + defined there as well. + +Environment: + + WDF User-Mode Driver Framework (WDF:UMDF) + +--*/ + +#include "internal.h" +#include "dllsup.tmh" + +const GUID CLSID_MyDriverCoClass = MYDRIVER_CLASS_ID; + +BOOL +WINAPI +DllMain( + HINSTANCE ModuleHandle, + DWORD Reason, + PVOID /* Reserved */ + ) +/*++ + + Routine Description: + + This is the entry point and exit point for the I/O trace driver. This + does very little as the I/O trace driver has minimal global data. + + This method initializes tracing, and saves the module handle away in a + global variable so that it can be referenced should the COM registration + code (Dll[Un]RegisterServer) be called. + + Arguments: + + ModuleHandle - the DLL handle for this module. + + Reason - the reason this entry point was called. + + Reserved - unused + + Return Value: + + TRUE + +--*/ +{ + UNREFERENCED_PARAMETER(ModuleHandle); + + if (DLL_PROCESS_ATTACH == Reason) + { + // + // Initialize tracing. + // + + WPP_INIT_TRACING(MYDRIVER_TRACING_ID); + } + else if (DLL_PROCESS_DETACH == Reason) + { + // + // Cleanup tracing. + // + + WPP_CLEANUP(); + } + + return TRUE; +} + +HRESULT +STDAPICALLTYPE +DllCanUnloadNow( + VOID + ) +/*++ + + Routine Description: + + Called by the COM runtime when determining whether or not this module + can be unloaded. Our answer is always "no". + + Arguments: + + None + + Return Value: + + S_FALSE + +--*/ +{ + return S_FALSE; +} + +HRESULT +STDAPICALLTYPE +DllGetClassObject( + _In_ REFCLSID ClassId, + _In_ REFIID InterfaceId, + _Outptr_ LPVOID *Interface + ) +/*++ + + Routine Description: + + This routine is called by COM in order to instantiate the + skeleton driver callback object and do an initial query interface on it. + + This method only creates an instance of the driver's class factory, as this + is the minimum required to support UMDF. + + Arguments: + + ClassId - the CLSID of the object being "gotten" + + InterfaceId - the interface the caller wants from that object. + + Interface - a location to store the referenced interface pointer + + Return Value: + + S_OK if the function succeeds or error indicating the cause of the + failure. + +--*/ +{ + PCClassFactory factory; + + HRESULT hr = S_OK; + + *Interface = NULL; + + // + // If the CLSID doesn't match that of our "coclass" (defined in the IDL + // file) then we can't create the object the caller wants. This may + // indicate that the COM registration is incorrect, and another CLSID + // is referencing this drvier. + // + + if (IsEqualCLSID(ClassId, CLSID_MyDriverCoClass) == false) + { + Trace( + TRACE_LEVEL_ERROR, + L"ERROR: Called to create instance of unrecognized class (%!GUID!)", + &ClassId + ); + + return CLASS_E_CLASSNOTAVAILABLE; + } + + // + // Create an instance of the class factory for the caller. + // + + factory = new CClassFactory(); + + if (NULL == factory) + { + hr = E_OUTOFMEMORY; + } + + // + // Query the object we created for the interface the caller wants. After + // that we release the object. This will drive the reference count to + // 1 (if the QI succeeded an referenced the object) or 0 (if the QI failed). + // In the later case the object is automatically deleted. + // + + if (SUCCEEDED(hr)) + { + hr = factory->QueryInterface(InterfaceId, Interface); + factory->Release(); + } + + return hr; +} diff --git a/usb/wdf_osrfx2_lab/umdf/step4/exports.def b/usb/wdf_osrfx2_lab/umdf/step4/exports.def new file mode 100644 index 00000000..15f923d3 --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step4/exports.def @@ -0,0 +1,4 @@ +; WudfOsrUsbDriver.def : Declares the module parameters. + +EXPORTS + DllGetClassObject PRIVATE diff --git a/usb/wdf_osrfx2_lab/umdf/step4/internal.h b/usb/wdf_osrfx2_lab/umdf/step4/internal.h new file mode 100644 index 00000000..86487dd9 --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step4/internal.h @@ -0,0 +1,154 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + Internal.h + +Abstract: + + This module contains the local type definitions for the UMDF Skeleton + driver sample. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) +#endif + +// +// Include the WUDF Headers +// + +#include "wudfddi.h" + +// +// Use specstrings for in/out annotation of function parameters. +// + +#include "specstrings.h" + +// +// Get limits on common data types (ULONG_MAX for example) +// + +#include "limits.h" + +// +// We need usb I/O targets to talk to the OSR device. +// + +#include "wudfusb.h" + +// +// Include the header shared between the drivers and the test applications. +// + +#include "public.h" + +// +// Include the header shared between the drivers and the test applications. +// + +#include "WUDFOsrUsbPublic.h" + +// +// Forward definitions of classes in the other header files. +// + +typedef class CMyDriver *PCMyDriver; +typedef class CMyDevice *PCMyDevice; +typedef class CMyQueue *PCMyQueue; + +typedef class CMyControlQueue *PCMyControlQueue; +typedef class CMyReadWriteQueue *PCMyReadWriteQueue; + +// +// Define the tracing flags. +// +// TODO: Choose a different trace control GUID +// + +#define WPP_CONTROL_GUIDS \ + WPP_DEFINE_CONTROL_GUID( \ + WudfOsrUsbFx2TraceGuid, (da5fbdfd,1eae,4ecf,b426,a3818f325ddb), \ + \ + WPP_DEFINE_BIT(MYDRIVER_ALL_INFO) \ + WPP_DEFINE_BIT(TEST_TRACE_DRIVER) \ + WPP_DEFINE_BIT(TEST_TRACE_DEVICE) \ + WPP_DEFINE_BIT(TEST_TRACE_QUEUE) \ + ) + +#define WPP_FLAG_LEVEL_LOGGER(flag, level) \ + WPP_LEVEL_LOGGER(flag) + +#define WPP_FLAG_LEVEL_ENABLED(flag, level) \ + (WPP_LEVEL_ENABLED(flag) && \ + WPP_CONTROL(WPP_BIT_ ## flag).Level >= level) + +#define WPP_LEVEL_FLAGS_LOGGER(lvl,flags) \ + WPP_LEVEL_LOGGER(flags) + +#define WPP_LEVEL_FLAGS_ENABLED(lvl, flags) \ + (WPP_LEVEL_ENABLED(flags) && WPP_CONTROL(WPP_BIT_ ## flags).Level >= lvl) + +// +// This comment block is scanned by the trace preprocessor to define our +// Trace function. +// +// begin_wpp config +// FUNC Trace{FLAG=MYDRIVER_ALL_INFO}(LEVEL, MSG, ...); +// FUNC TraceEvents(LEVEL, FLAGS, MSG, ...); +// end_wpp +// + +// +// Driver specific #defines +// +// TODO: Change these values to be appropriate for your driver. +// + +#define MYDRIVER_TRACING_ID L"Microsoft\\UMDF\\OsrUsb" +#define MYDRIVER_CLASS_ID {0x0865b2b0, 0x6b73, 0x428f, {0xa3, 0xea, 0x21, 0x72, 0x83, 0x2d, 0x6b, 0xfc}} + +// +// Include the type specific headers. +// + +#include "comsup.h" +#include "driver.h" +#include "device.h" +#include "queue.h" +#include "ControlQueue.h" +#include "ReadWriteQueue.h" +#include "list.h" + +__forceinline +#ifdef _PREFAST_ +__declspec(noreturn) +#endif +VOID +WdfTestNoReturn( + VOID + ) +{ + // do nothing. +} + +#define WUDF_TEST_DRIVER_ASSERT(p) \ +{ \ + if ( !(p) ) \ + { \ + DebugBreak(); \ + WdfTestNoReturn(); \ + } \ +} + +#define SAFE_RELEASE(p) {if ((p)) { (p)->Release(); (p) = NULL; }} diff --git a/usb/wdf_osrfx2_lab/umdf/step4/queue.cpp b/usb/wdf_osrfx2_lab/umdf/step4/queue.cpp new file mode 100644 index 00000000..c56b38bb --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step4/queue.cpp @@ -0,0 +1,147 @@ +/*++ + +Copyright (c) Microsoft Corporation, All Rights Reserved + +Module Name: + + queue.cpp + +Abstract: + + This file implements the I/O queue interface and performs + the read/write/ioctl operations. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#include "internal.h" +#include "queue.tmh" + +CMyQueue::CMyQueue( + _In_ PCMyDevice Device + ) : + m_FxQueue(NULL), + m_Device(Device) +{ +} + +// +// Queue destructor. +// Free up the buffer, wait for thread to terminate and +// + +CMyQueue::~CMyQueue( + VOID + ) +/*++ + +Routine Description: + + + IUnknown implementation of Release + +Aruments: + + +Return Value: + + ULONG (reference count after Release) + +--*/ +{ + TraceEvents(TRACE_LEVEL_INFORMATION, + TEST_TRACE_QUEUE, + "%!FUNC! Entry" + ); + +} + + +HRESULT +STDMETHODCALLTYPE +CMyQueue::QueryInterface( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ) +/*++ + +Routine Description: + + + Query Interface + +Aruments: + + Follows COM specifications + +Return Value: + + HRESULT indicatin success or failure + +--*/ +{ + HRESULT hr; + + hr = CUnknown::QueryInterface(InterfaceId, Object); + + return hr; +} + +// +// Initialize +// + +HRESULT +CMyQueue::Initialize( + _In_ WDF_IO_QUEUE_DISPATCH_TYPE DispatchType, + _In_ bool Default, + _In_ bool PowerManaged + ) +{ + IWDFIoQueue *fxQueue; + HRESULT hr; + + // + // Create the I/O Queue object. + // + + { + IUnknown *callback = QueryIUnknown(); + + hr = m_Device->GetFxDevice()->CreateIoQueue( + callback, + Default, + DispatchType, + PowerManaged, + FALSE, + &fxQueue + ); + callback->Release(); + } + + if (SUCCEEDED(hr)) + { + m_FxQueue = fxQueue; + + // + // Release the creation reference on the queue. This object will be + // destroyed before the queue so we don't need to have a reference out + // on it. + // + + fxQueue->Release(); + } + + return hr; +} + +HRESULT +CMyQueue::Configure( + VOID + ) +{ + return S_OK; +} diff --git a/usb/wdf_osrfx2_lab/umdf/step4/queue.h b/usb/wdf_osrfx2_lab/umdf/step4/queue.h new file mode 100644 index 00000000..5659224b --- /dev/null +++ b/usb/wdf_osrfx2_lab/umdf/step4/queue.h @@ -0,0 +1,93 @@ +/*++ + +Copyright (c) Microsoft Corporation, All Rights Reserved + +Module Name: + + queue.h + +Abstract: + + This file defines the queue callback interface. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once + +// +// Queue Callback Object. +// + +class CMyQueue : + public CUnknown +{ +protected: + // + // Unreferenced pointer to the partner Fx device. + // + + IWDFIoQueue *m_FxQueue; + + // + // Unreferenced pointer to the parent device. + // + + PCMyDevice m_Device; + + HRESULT + Initialize( + _In_ WDF_IO_QUEUE_DISPATCH_TYPE DispatchType, + _In_ bool Default, + _In_ bool PowerManaged + ); + +protected: + + CMyQueue( + _In_ PCMyDevice Device + ); + + virtual ~CMyQueue(); + + HRESULT + Configure( + VOID + ); + +public: + + IWDFIoQueue * + GetFxQueue( + VOID + ) + { + return m_FxQueue; + } + + + PCMyDevice + GetDevice( + VOID + ) + { + return m_Device; + } + + // + // IUnknown + // + + STDMETHOD_(ULONG,AddRef) (VOID) {return CUnknown::AddRef();} + + _At_(this, __drv_freesMem(object)) + STDMETHOD_(ULONG,Release) (VOID) {return CUnknown::Release();} + + STDMETHOD_(HRESULT, QueryInterface)( + _In_ REFIID InterfaceId, + _Outptr_ PVOID *Object + ); +}; diff --git a/usb/wdf_osrfx2_lab/wdf_osrfx2_lab.sln b/usb/wdf_osrfx2_lab/wdf_osrfx2_lab.sln new file mode 100644 index 00000000..105c6643 --- /dev/null +++ b/usb/wdf_osrfx2_lab/wdf_osrfx2_lab.sln @@ -0,0 +1,178 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0 +MinimumVisualStudioVersion = 12.0 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Step1", "Step1", "{D00328D3-8C3F-4702-B819-5A3830E7FA70}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Kmdf", "Kmdf", "{EA42BA41-FC92-4985-80CA-B8BAC85DA33D}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Step2", "Step2", "{46FAA529-1596-416E-82DA-C7BE08A96774}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Step3", "Step3", "{DB521009-ED4B-48E6-85CE-9C5B8B6CA915}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Step4", "Step4", "{A9C9BC25-9393-405C-A366-B7F457CAD629}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Step5", "Step5", "{20339A89-50EB-4567-9AD9-BF3B2484D1EA}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Exe", "Exe", "{BC1A657D-F736-42B1-8B6F-65660268D1E4}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Step1", "Step1", "{5B8D9AE9-CD64-4BDE-924B-85E2CFF7AC6D}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Umdf", "Umdf", "{891C089F-780C-4983-8C50-1A1C9BEB0593}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Step2", "Step2", "{9C88D019-1CD4-44BD-8355-75C0F1A0D348}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Step3", "Step3", "{F9F19F6E-0B8B-4ED0-BA15-75455AC110D4}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Step4", "Step4", "{852E07AA-FE41-404F-BE25-30B5BCE596B7}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Exe", "Exe", "{CAFB7E8F-109E-4224-BD53-EE93946311DF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "osrusbfx2", "kmdf\step1\osrusbfx2.vcxproj", "{E54BDD18-FDE9-42BF-BC23-343F8764B387}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "osrusbfx2", "kmdf\step2\osrusbfx2.vcxproj", "{CE2CAF81-E96B-4C32-9BE9-58238742D295}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "osrusbfx2", "kmdf\step3\osrusbfx2.vcxproj", "{70D6E15B-26A9-444C-B4DE-93504AD529E1}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "osrusbfx2", "kmdf\step4\osrusbfx2.vcxproj", "{AE6270A1-FAC6-45B2-A641-9BFAF534DD01}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "osrusbfx2", "kmdf\step5\osrusbfx2.vcxproj", "{EEB5FBCF-333A-4D54-B937-C24FB0CC10EB}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "osrusbfx2", "kmdf\exe\osrusbfx2.vcxproj", "{6EED5CDD-5526-40DC-97F9-582857E10187}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WUDFOsrUsbFx2_1", "umdf\step1\WUDFOsrUsbFx2_1.vcxproj", "{94BDC8D1-B62F-4200-9873-D403B6D30301}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WUDFOsrUsbFx2_2", "umdf\step2\WUDFOsrUsbFx2_2.vcxproj", "{808B6774-93FA-4ABF-A23F-35C55FA80B80}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WUDFOsrUsbFx2_3", "umdf\step3\WUDFOsrUsbFx2_3.vcxproj", "{4BED411D-1B55-4A64-84C9-36EC25F083D2}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WUDFOsrUsbFx2_4", "umdf\step4\WUDFOsrUsbFx2_4.vcxproj", "{48343119-5771-494E-977E-0D439A45BF65}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WudfOsrUsbFx2Test", "umdf\exe\WudfOsrUsbFx2Test.vcxproj", "{B4244D54-7EBF-43D4-BB6D-C994C182C572}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + Debug|x64 = Debug|x64 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E54BDD18-FDE9-42BF-BC23-343F8764B387}.Debug|Win32.ActiveCfg = Debug|Win32 + {E54BDD18-FDE9-42BF-BC23-343F8764B387}.Debug|Win32.Build.0 = Debug|Win32 + {E54BDD18-FDE9-42BF-BC23-343F8764B387}.Release|Win32.ActiveCfg = Release|Win32 + {E54BDD18-FDE9-42BF-BC23-343F8764B387}.Release|Win32.Build.0 = Release|Win32 + {E54BDD18-FDE9-42BF-BC23-343F8764B387}.Debug|x64.ActiveCfg = Debug|x64 + {E54BDD18-FDE9-42BF-BC23-343F8764B387}.Debug|x64.Build.0 = Debug|x64 + {E54BDD18-FDE9-42BF-BC23-343F8764B387}.Release|x64.ActiveCfg = Release|x64 + {E54BDD18-FDE9-42BF-BC23-343F8764B387}.Release|x64.Build.0 = Release|x64 + {CE2CAF81-E96B-4C32-9BE9-58238742D295}.Debug|Win32.ActiveCfg = Debug|Win32 + {CE2CAF81-E96B-4C32-9BE9-58238742D295}.Debug|Win32.Build.0 = Debug|Win32 + {CE2CAF81-E96B-4C32-9BE9-58238742D295}.Release|Win32.ActiveCfg = Release|Win32 + {CE2CAF81-E96B-4C32-9BE9-58238742D295}.Release|Win32.Build.0 = Release|Win32 + {CE2CAF81-E96B-4C32-9BE9-58238742D295}.Debug|x64.ActiveCfg = Debug|x64 + {CE2CAF81-E96B-4C32-9BE9-58238742D295}.Debug|x64.Build.0 = Debug|x64 + {CE2CAF81-E96B-4C32-9BE9-58238742D295}.Release|x64.ActiveCfg = Release|x64 + {CE2CAF81-E96B-4C32-9BE9-58238742D295}.Release|x64.Build.0 = Release|x64 + {70D6E15B-26A9-444C-B4DE-93504AD529E1}.Debug|Win32.ActiveCfg = Debug|Win32 + {70D6E15B-26A9-444C-B4DE-93504AD529E1}.Debug|Win32.Build.0 = Debug|Win32 + {70D6E15B-26A9-444C-B4DE-93504AD529E1}.Release|Win32.ActiveCfg = Release|Win32 + {70D6E15B-26A9-444C-B4DE-93504AD529E1}.Release|Win32.Build.0 = Release|Win32 + {70D6E15B-26A9-444C-B4DE-93504AD529E1}.Debug|x64.ActiveCfg = Debug|x64 + {70D6E15B-26A9-444C-B4DE-93504AD529E1}.Debug|x64.Build.0 = Debug|x64 + {70D6E15B-26A9-444C-B4DE-93504AD529E1}.Release|x64.ActiveCfg = Release|x64 + {70D6E15B-26A9-444C-B4DE-93504AD529E1}.Release|x64.Build.0 = Release|x64 + {AE6270A1-FAC6-45B2-A641-9BFAF534DD01}.Debug|Win32.ActiveCfg = Debug|Win32 + {AE6270A1-FAC6-45B2-A641-9BFAF534DD01}.Debug|Win32.Build.0 = Debug|Win32 + {AE6270A1-FAC6-45B2-A641-9BFAF534DD01}.Release|Win32.ActiveCfg = Release|Win32 + {AE6270A1-FAC6-45B2-A641-9BFAF534DD01}.Release|Win32.Build.0 = Release|Win32 + {AE6270A1-FAC6-45B2-A641-9BFAF534DD01}.Debug|x64.ActiveCfg = Debug|x64 + {AE6270A1-FAC6-45B2-A641-9BFAF534DD01}.Debug|x64.Build.0 = Debug|x64 + {AE6270A1-FAC6-45B2-A641-9BFAF534DD01}.Release|x64.ActiveCfg = Release|x64 + {AE6270A1-FAC6-45B2-A641-9BFAF534DD01}.Release|x64.Build.0 = Release|x64 + {EEB5FBCF-333A-4D54-B937-C24FB0CC10EB}.Debug|Win32.ActiveCfg = Debug|Win32 + {EEB5FBCF-333A-4D54-B937-C24FB0CC10EB}.Debug|Win32.Build.0 = Debug|Win32 + {EEB5FBCF-333A-4D54-B937-C24FB0CC10EB}.Release|Win32.ActiveCfg = Release|Win32 + {EEB5FBCF-333A-4D54-B937-C24FB0CC10EB}.Release|Win32.Build.0 = Release|Win32 + {EEB5FBCF-333A-4D54-B937-C24FB0CC10EB}.Debug|x64.ActiveCfg = Debug|x64 + {EEB5FBCF-333A-4D54-B937-C24FB0CC10EB}.Debug|x64.Build.0 = Debug|x64 + {EEB5FBCF-333A-4D54-B937-C24FB0CC10EB}.Release|x64.ActiveCfg = Release|x64 + {EEB5FBCF-333A-4D54-B937-C24FB0CC10EB}.Release|x64.Build.0 = Release|x64 + {6EED5CDD-5526-40DC-97F9-582857E10187}.Debug|Win32.ActiveCfg = Debug|Win32 + {6EED5CDD-5526-40DC-97F9-582857E10187}.Debug|Win32.Build.0 = Debug|Win32 + {6EED5CDD-5526-40DC-97F9-582857E10187}.Release|Win32.ActiveCfg = Release|Win32 + {6EED5CDD-5526-40DC-97F9-582857E10187}.Release|Win32.Build.0 = Release|Win32 + {6EED5CDD-5526-40DC-97F9-582857E10187}.Debug|x64.ActiveCfg = Debug|x64 + {6EED5CDD-5526-40DC-97F9-582857E10187}.Debug|x64.Build.0 = Debug|x64 + {6EED5CDD-5526-40DC-97F9-582857E10187}.Release|x64.ActiveCfg = Release|x64 + {6EED5CDD-5526-40DC-97F9-582857E10187}.Release|x64.Build.0 = Release|x64 + {94BDC8D1-B62F-4200-9873-D403B6D30301}.Debug|Win32.ActiveCfg = Debug|Win32 + {94BDC8D1-B62F-4200-9873-D403B6D30301}.Debug|Win32.Build.0 = Debug|Win32 + {94BDC8D1-B62F-4200-9873-D403B6D30301}.Release|Win32.ActiveCfg = Release|Win32 + {94BDC8D1-B62F-4200-9873-D403B6D30301}.Release|Win32.Build.0 = Release|Win32 + {94BDC8D1-B62F-4200-9873-D403B6D30301}.Debug|x64.ActiveCfg = Debug|x64 + {94BDC8D1-B62F-4200-9873-D403B6D30301}.Debug|x64.Build.0 = Debug|x64 + {94BDC8D1-B62F-4200-9873-D403B6D30301}.Release|x64.ActiveCfg = Release|x64 + {94BDC8D1-B62F-4200-9873-D403B6D30301}.Release|x64.Build.0 = Release|x64 + {808B6774-93FA-4ABF-A23F-35C55FA80B80}.Debug|Win32.ActiveCfg = Debug|Win32 + {808B6774-93FA-4ABF-A23F-35C55FA80B80}.Debug|Win32.Build.0 = Debug|Win32 + {808B6774-93FA-4ABF-A23F-35C55FA80B80}.Release|Win32.ActiveCfg = Release|Win32 + {808B6774-93FA-4ABF-A23F-35C55FA80B80}.Release|Win32.Build.0 = Release|Win32 + {808B6774-93FA-4ABF-A23F-35C55FA80B80}.Debug|x64.ActiveCfg = Debug|x64 + {808B6774-93FA-4ABF-A23F-35C55FA80B80}.Debug|x64.Build.0 = Debug|x64 + {808B6774-93FA-4ABF-A23F-35C55FA80B80}.Release|x64.ActiveCfg = Release|x64 + {808B6774-93FA-4ABF-A23F-35C55FA80B80}.Release|x64.Build.0 = Release|x64 + {4BED411D-1B55-4A64-84C9-36EC25F083D2}.Debug|Win32.ActiveCfg = Debug|Win32 + {4BED411D-1B55-4A64-84C9-36EC25F083D2}.Debug|Win32.Build.0 = Debug|Win32 + {4BED411D-1B55-4A64-84C9-36EC25F083D2}.Release|Win32.ActiveCfg = Release|Win32 + {4BED411D-1B55-4A64-84C9-36EC25F083D2}.Release|Win32.Build.0 = Release|Win32 + {4BED411D-1B55-4A64-84C9-36EC25F083D2}.Debug|x64.ActiveCfg = Debug|x64 + {4BED411D-1B55-4A64-84C9-36EC25F083D2}.Debug|x64.Build.0 = Debug|x64 + {4BED411D-1B55-4A64-84C9-36EC25F083D2}.Release|x64.ActiveCfg = Release|x64 + {4BED411D-1B55-4A64-84C9-36EC25F083D2}.Release|x64.Build.0 = Release|x64 + {48343119-5771-494E-977E-0D439A45BF65}.Debug|Win32.ActiveCfg = Debug|Win32 + {48343119-5771-494E-977E-0D439A45BF65}.Debug|Win32.Build.0 = Debug|Win32 + {48343119-5771-494E-977E-0D439A45BF65}.Release|Win32.ActiveCfg = Release|Win32 + {48343119-5771-494E-977E-0D439A45BF65}.Release|Win32.Build.0 = Release|Win32 + {48343119-5771-494E-977E-0D439A45BF65}.Debug|x64.ActiveCfg = Debug|x64 + {48343119-5771-494E-977E-0D439A45BF65}.Debug|x64.Build.0 = Debug|x64 + {48343119-5771-494E-977E-0D439A45BF65}.Release|x64.ActiveCfg = Release|x64 + {48343119-5771-494E-977E-0D439A45BF65}.Release|x64.Build.0 = Release|x64 + {B4244D54-7EBF-43D4-BB6D-C994C182C572}.Debug|Win32.ActiveCfg = Debug|Win32 + {B4244D54-7EBF-43D4-BB6D-C994C182C572}.Debug|Win32.Build.0 = Debug|Win32 + {B4244D54-7EBF-43D4-BB6D-C994C182C572}.Release|Win32.ActiveCfg = Release|Win32 + {B4244D54-7EBF-43D4-BB6D-C994C182C572}.Release|Win32.Build.0 = Release|Win32 + {B4244D54-7EBF-43D4-BB6D-C994C182C572}.Debug|x64.ActiveCfg = Debug|x64 + {B4244D54-7EBF-43D4-BB6D-C994C182C572}.Debug|x64.Build.0 = Debug|x64 + {B4244D54-7EBF-43D4-BB6D-C994C182C572}.Release|x64.ActiveCfg = Release|x64 + {B4244D54-7EBF-43D4-BB6D-C994C182C572}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {E54BDD18-FDE9-42BF-BC23-343F8764B387} = {D00328D3-8C3F-4702-B819-5A3830E7FA70} + {CE2CAF81-E96B-4C32-9BE9-58238742D295} = {46FAA529-1596-416E-82DA-C7BE08A96774} + {70D6E15B-26A9-444C-B4DE-93504AD529E1} = {DB521009-ED4B-48E6-85CE-9C5B8B6CA915} + {AE6270A1-FAC6-45B2-A641-9BFAF534DD01} = {A9C9BC25-9393-405C-A366-B7F457CAD629} + {EEB5FBCF-333A-4D54-B937-C24FB0CC10EB} = {20339A89-50EB-4567-9AD9-BF3B2484D1EA} + {6EED5CDD-5526-40DC-97F9-582857E10187} = {BC1A657D-F736-42B1-8B6F-65660268D1E4} + {94BDC8D1-B62F-4200-9873-D403B6D30301} = {5B8D9AE9-CD64-4BDE-924B-85E2CFF7AC6D} + {808B6774-93FA-4ABF-A23F-35C55FA80B80} = {9C88D019-1CD4-44BD-8355-75C0F1A0D348} + {4BED411D-1B55-4A64-84C9-36EC25F083D2} = {F9F19F6E-0B8B-4ED0-BA15-75455AC110D4} + {48343119-5771-494E-977E-0D439A45BF65} = {852E07AA-FE41-404F-BE25-30B5BCE596B7} + {B4244D54-7EBF-43D4-BB6D-C994C182C572} = {CAFB7E8F-109E-4224-BD53-EE93946311DF} + {D00328D3-8C3F-4702-B819-5A3830E7FA70} = {EA42BA41-FC92-4985-80CA-B8BAC85DA33D} + {46FAA529-1596-416E-82DA-C7BE08A96774} = {EA42BA41-FC92-4985-80CA-B8BAC85DA33D} + {DB521009-ED4B-48E6-85CE-9C5B8B6CA915} = {EA42BA41-FC92-4985-80CA-B8BAC85DA33D} + {A9C9BC25-9393-405C-A366-B7F457CAD629} = {EA42BA41-FC92-4985-80CA-B8BAC85DA33D} + {20339A89-50EB-4567-9AD9-BF3B2484D1EA} = {EA42BA41-FC92-4985-80CA-B8BAC85DA33D} + {BC1A657D-F736-42B1-8B6F-65660268D1E4} = {EA42BA41-FC92-4985-80CA-B8BAC85DA33D} + {5B8D9AE9-CD64-4BDE-924B-85E2CFF7AC6D} = {891C089F-780C-4983-8C50-1A1C9BEB0593} + {9C88D019-1CD4-44BD-8355-75C0F1A0D348} = {891C089F-780C-4983-8C50-1A1C9BEB0593} + {F9F19F6E-0B8B-4ED0-BA15-75455AC110D4} = {891C089F-780C-4983-8C50-1A1C9BEB0593} + {852E07AA-FE41-404F-BE25-30B5BCE596B7} = {891C089F-780C-4983-8C50-1A1C9BEB0593} + {CAFB7E8F-109E-4224-BD53-EE93946311DF} = {891C089F-780C-4983-8C50-1A1C9BEB0593} + EndGlobalSection +EndGlobal |
