From cb0548c53a0460661517e1b4ed34856d6d345f18 Mon Sep 17 00:00:00 2001 From: Sam Tertzakian <32625754+samtertzakian@users.noreply.github.com> Date: Thu, 28 May 2020 17:06:38 -0700 Subject: [PATCH] Merge20200528 1. Fix BSOD during hibnerate path due to "PAGED" code. 2. Correct issue in BufferPool where context was not passed to callback. 3. Remove legacy event log API. 4. Correct an issue where ModuleCollectionHandle was not set early enough for all possible cases. 5. Update SpbTarget and HidTarget to use updated Protocol-Transport interface. 6. Update Unit Tests to add more tests and allow testing of specific cancel code paths. 7. Add portable version check API. --- Dmf/Framework/DmfContainer.c | 12 - Dmf/Framework/DmfDefinitions.h | 88 +- Dmf/Framework/DmfModuleCollection.c | 20 +- Dmf/Framework/DmfPortable.c | 98 ++ Dmf/Framework/DmfUtility.c | 1191 +---------------- Dmf/Framework/Modules.Core/Dmf_BufferPool.c | 8 +- .../Dmf_Tests_DeviceInterfaceMultipleTarget.c | 35 +- .../Dmf_Tests_DeviceInterfaceTarget.c | 299 +++-- .../Dmf_Tests_SelfTarget.c | 19 +- Dmf/Modules.Library/DmfModules.Library.h | 21 +- Dmf/Modules.Library/Dmf_HidTarget.c | 256 +++- Dmf/Modules.Library/Dmf_Interface_BusTarget.c | 409 ++++++ Dmf/Modules.Library/Dmf_Interface_BusTarget.h | 218 +++ Dmf/Modules.Library/Dmf_MobileBroadband.cpp | 3 +- Dmf/Modules.Library/Dmf_SpbTarget.c | 284 +++- 15 files changed, 1516 insertions(+), 1445 deletions(-) create mode 100644 Dmf/Modules.Library/Dmf_Interface_BusTarget.c create mode 100644 Dmf/Modules.Library/Dmf_Interface_BusTarget.h diff --git a/Dmf/Framework/DmfContainer.c b/Dmf/Framework/DmfContainer.c index a2bade4a..ed2cd852 100644 --- a/Dmf/Framework/DmfContainer.c +++ b/Dmf/Framework/DmfContainer.c @@ -796,7 +796,6 @@ Return Value: } #pragma code_seg() -#pragma code_seg("PAGE") _Use_decl_annotations_ NTSTATUS DmfContainerEvtDeviceSelfManagedIoSuspend( @@ -823,8 +822,6 @@ Return Value: FuncEntry(DMF_TRACE); - PAGED_CODE(); - dmfDeviceContext = DmfDeviceContextGet(Device); DmfAssert(dmfDeviceContext != NULL); @@ -836,9 +833,7 @@ Return Value: return ntStatus; } -#pragma code_seg() -#pragma code_seg("PAGE") _Use_decl_annotations_ NTSTATUS DmfContainerEvtDeviceSelfManagedIoRestart( @@ -865,8 +860,6 @@ Return Value: FuncEntry(DMF_TRACE); - PAGED_CODE(); - dmfDeviceContext = DmfDeviceContextGet(Device); DmfAssert(dmfDeviceContext != NULL); @@ -878,9 +871,7 @@ Return Value: return ntStatus; } -#pragma code_seg() -#pragma code_seg("PAGE") _Use_decl_annotations_ VOID DmfContainerEvtDeviceSurpriseRemoval( @@ -906,8 +897,6 @@ Return Value: FuncEntry(DMF_TRACE); - PAGED_CODE(); - dmfDeviceContext = DmfDeviceContextGet(Device); DmfAssert(dmfDeviceContext != NULL); @@ -917,7 +906,6 @@ Return Value: FuncExitVoid(DMF_TRACE); } -#pragma code_seg() #pragma code_seg("PAGE") _Use_decl_annotations_ diff --git a/Dmf/Framework/DmfDefinitions.h b/Dmf/Framework/DmfDefinitions.h index 4a953c22..5ee390f6 100644 --- a/Dmf/Framework/DmfDefinitions.h +++ b/Dmf/Framework/DmfDefinitions.h @@ -1266,6 +1266,16 @@ typedef struct _DMF_PORTABLE_RUNDOWN #endif // !defined(DMF_USER_MODE) } DMF_PORTABLE_RUNDOWN_REF; +// Definitions used to determine OS version to determine +// availability of some OS features. +// +#define DMF_VERSIONCHECK_BUILD_NUMBER_RS2 15063 +#define DMF_VERSIONCHECK_BUILD_NUMBER_RS3 16299 +#define DMF_VERSIONCHECK_BUILD_NUMBER_RS4 17134 +#define DMF_VERSIONCHECK_BUILD_NUMBER_RS5 17763 +#define DMF_VERSIONCHECK_BUILD_NUMBER_19H1 18362 +#define DMF_VERSIONCHECK_BUILD_NUMBER_20H1 19041 + _IRQL_requires_max_(PASSIVE_LEVEL) VOID DMF_Portable_EventCreate( @@ -1362,6 +1372,12 @@ DMF_Portable_Rundown_Completed( _Inout_ DMF_PORTABLE_RUNDOWN_REF* RundownRef ); +BOOLEAN +DMF_Portable_VersionCheck( + _In_ ULONG MinimumOsVersion, + _Out_ BOOLEAN* IsOsEqualOrGreater + ); + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// // "Invoke" API prototypes ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1466,78 +1482,6 @@ DMF_Utility_LogEmitString( ... ); -_IRQL_requires_max_(PASSIVE_LEVEL) -VOID -DMF_Utility_EventLogEntryWriteDriverObject( - _In_ PDRIVER_OBJECT DriverObject, - _In_ NTSTATUS ErrorCode, - _In_ NTSTATUS FinalNtStatus, - _In_ ULONG UniqueId, - _In_ ULONG TextLength, - _In_opt_ PCWSTR Text, - _In_ INT NumberOfFormatStrings, - _In_opt_ PWCHAR* FormatStrings, - _In_ INT NumberOfInsertionStrings, - ... - ); - -_IRQL_requires_max_(PASSIVE_LEVEL) -VOID -DMF_Utility_EventLogEntryWriteDriver( - _In_ WDFDRIVER Driver, - _In_ NTSTATUS ErrorCode, - _In_ NTSTATUS Status, - _In_ ULONG UniqueId, - _In_ ULONG TextLength, - _In_opt_ PCWSTR Text, - _In_ INT NumberOfFormatStrings, - _In_opt_ PWCHAR* FormatStrings, - _In_ INT NumberOfInsertionStrings, - ... - ); - -_IRQL_requires_max_(PASSIVE_LEVEL) -VOID -DMF_Utility_EventLogEntryWriteDevice( - _In_ WDFDEVICE Device, - _In_ NTSTATUS ErrorCode, - _In_ NTSTATUS Status, - _In_ ULONG UniqueId, - _In_ ULONG TextLength, - _In_opt_ PCWSTR Text, - _In_ INT NumberOfFormatStrings, - _In_opt_ PWCHAR* FormatStrings, - _In_ INT NumberOfInsertionStrings, - ... - ); - -_IRQL_requires_max_(PASSIVE_LEVEL) -VOID -DMF_Utility_EventLogEntryWriteDmfModule( - _In_ DMFMODULE DmfModule, - _In_ NTSTATUS ErrorCode, - _In_ NTSTATUS Status, - _In_ ULONG UniqueId, - _In_ ULONG TextLength, - _In_opt_ PCWSTR Text, - _In_ INT NumberOfFormatStrings, - _In_opt_ PWCHAR* FormatStrings, - _In_ INT NumberOfInsertionStrings, - ... - ); - -_IRQL_requires_max_(PASSIVE_LEVEL) -VOID -DMF_Utility_EventLogEntryWriteUserMode( - _In_ PWSTR Provider, - _In_ WORD EventType, - _In_ DWORD EventID, - _In_ INT NumberOfFormatStrings, - _In_opt_ PWCHAR* FormatStrings, - _In_ INT NumberOfInsertionStrings, - ... - ); - //////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // LIST_ENTRY functions for User-Mode. (These are copied as-is from Wdm.h. diff --git a/Dmf/Framework/DmfModuleCollection.c b/Dmf/Framework/DmfModuleCollection.c index e752c8a8..b1c45b6b 100644 --- a/Dmf/Framework/DmfModuleCollection.c +++ b/Dmf/Framework/DmfModuleCollection.c @@ -1717,7 +1717,6 @@ Return Value: } #pragma code_seg() -#pragma code_seg("PAGE") _IRQL_requires_max_(PASSIVE_LEVEL) NTSTATUS DMF_ModuleCollectionSelfManagedIoSuspend( @@ -1743,8 +1742,6 @@ Return Value: { NTSTATUS ntStatus; - PAGED_CODE(); - FuncEntryArguments(DMF_TRACE, "DmfCollection=0x%p", DmfCollection); DMF_MODULE_COLLECTION* moduleCollectionHandle = DMF_CollectionToHandle(DmfCollection); @@ -1772,9 +1769,7 @@ Return Value: return ntStatus; } -#pragma code_seg() -#pragma code_seg("PAGE") _IRQL_requires_max_(PASSIVE_LEVEL) NTSTATUS DMF_ModuleCollectionSelfManagedIoRestart( @@ -1800,8 +1795,6 @@ Return Value: { NTSTATUS ntStatus; - PAGED_CODE(); - FuncEntryArguments(DMF_TRACE, "DmfCollection=0x%p", DmfCollection); DMF_MODULE_COLLECTION* moduleCollectionHandle = DMF_CollectionToHandle(DmfCollection); @@ -1829,9 +1822,7 @@ Return Value: return ntStatus; } -#pragma code_seg() -#pragma code_seg("PAGE") _IRQL_requires_max_(PASSIVE_LEVEL) VOID DMF_ModuleCollectionSurpriseRemoval( @@ -1854,8 +1845,6 @@ Return Value: --*/ { - PAGED_CODE(); - FuncEntryArguments(DMF_TRACE, "DmfCollection=0x%p", DmfCollection); DMF_MODULE_COLLECTION* moduleCollectionHandle = DMF_CollectionToHandle(DmfCollection); @@ -1880,7 +1869,6 @@ Return Value: FuncExit(DMF_TRACE, "DmfCollection=0x%p", DmfCollection); } -#pragma code_seg() #pragma code_seg("PAGE") _IRQL_requires_max_(PASSIVE_LEVEL) @@ -3906,6 +3894,11 @@ Return Value: goto Exit; } + // Store the collection in Container Context. + // Do this as soon as possible because DmfCollection may be needed during DMF_ModuleCollectionPostCreate(). + // + dmfDeviceContext->DmfCollection = dmfCollection; + // Open or register for notification for OPEN_Create or NOTIFY_Create Modules. // ntStatus = DMF_ModuleCollectionPostCreate(&moduleCollectionConfig, @@ -3916,9 +3909,8 @@ Return Value: goto Exit; } - // Store the collection in Container Context. + // Remember if the Client supports DeviceAdd. // - dmfDeviceContext->DmfCollection = dmfCollection; dmfDeviceContext->ClientImplementsEvtWdfDriverDeviceAdd = DMF_DmfDeviceInitClientImplementsDeviceAdd(dmfDeviceInit); // Store information needed to automatically call DMF_Invoke_DeviceCallbacksDestroy() when the diff --git a/Dmf/Framework/DmfPortable.c b/Dmf/Framework/DmfPortable.c index 945cb7b0..c43b5809 100644 --- a/Dmf/Framework/DmfPortable.c +++ b/Dmf/Framework/DmfPortable.c @@ -29,6 +29,9 @@ Module Name: #include "DmfPortable.tmh" #endif +#define MAJOR_VERSION_WINDOWS_10 10 +#define MINOR_VERSION_WINDOWS_10 0 + _IRQL_requires_max_(PASSIVE_LEVEL) VOID DMF_Portable_EventCreate( @@ -786,5 +789,100 @@ Return Value: #endif // defined(DMF_KERNEL_MODE) } +BOOLEAN +DMF_Portable_VersionCheck( + _In_ ULONG MinimumOsVersion, + _Out_ BOOLEAN *IsOsEqualOrGreater + ) +/*++ + +Routine Description: + + Read the Windows 10 OS version to check for feature availability. + +Arguments: + + MinimumOsVersion - The minimum OS version to check for. + IsOsEqualOrGreater - Flag to indicate if the running OS is greater + than or equal to the minimum passed in. + +Return Value: + + TRUE if able to read the OS version. + +--*/ +{ + BOOLEAN returnStatus; + static ULONG s_OsBuildNumber = 0; + + returnStatus = FALSE; + *IsOsEqualOrGreater = FALSE; + + if (s_OsBuildNumber == 0) + { +#if defined(DMF_KERNEL_MODE) + NTSTATUS ntStatus; + RTL_OSVERSIONINFOW versionInfo; + + versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); + ntStatus = RtlGetVersion(&versionInfo); + if (NT_SUCCESS(ntStatus)) + { + if (versionInfo.dwMajorVersion >= MAJOR_VERSION_WINDOWS_10 && + versionInfo.dwMinorVersion == MINOR_VERSION_WINDOWS_10) + { + s_OsBuildNumber = versionInfo.dwBuildNumber; + } + } +#else + OSVERSIONINFOEXW versionInfo = { 0 }; + LONG status = 0; + + typedef LONG(WINAPI* PFN_RTL_GET_VERSION)(OSVERSIONINFOEXW*); + PFN_RTL_GET_VERSION functionRtlGetVersion = NULL; + + versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); + + HMODULE ntDll = GetModuleHandleW(L"ntdll.dll"); + if (ntDll != NULL) + { + functionRtlGetVersion = (PFN_RTL_GET_VERSION)GetProcAddress(ntDll, + "RtlGetVersion"); + if (functionRtlGetVersion) + { + status = functionRtlGetVersion(&versionInfo); + if (status == S_OK) + { + // Expecting major version 10 and minor version 0. + // Otherwise, unknown or unsupported os version. + // + if (versionInfo.dwMajorVersion >= MAJOR_VERSION_WINDOWS_10 && + versionInfo.dwMinorVersion == MINOR_VERSION_WINDOWS_10) + { + // Everything worked, so store the os build number. + // + s_OsBuildNumber = versionInfo.dwBuildNumber; + } + } + } + } +#endif // defined(DMF_KERNEL_MODE) + } + + // 0 is an unsupported OS build version. It is overloaded here to + // indicate an error in retrieving the OS version. + // + if (s_OsBuildNumber != 0) + { + returnStatus = TRUE; + if (s_OsBuildNumber >= MinimumOsVersion) + { + *IsOsEqualOrGreater = TRUE; + } + } + + return returnStatus; +} + // eof: DmfPortable.c // diff --git a/Dmf/Framework/DmfUtility.c b/Dmf/Framework/DmfUtility.c index db50e6d1..1af84ea3 100644 --- a/Dmf/Framework/DmfUtility.c +++ b/Dmf/Framework/DmfUtility.c @@ -534,354 +534,11 @@ Return Value: //////////////////////////////////////////////////////////////////////////////////////////////// // -// Definitions used by the Event Log functions. +// Definition used by the Event Log function. // //////////////////////////////////////////////////////////////////////////////////////////////// // -// Identifiers for format specifiers supported in DMF event logs. -// -typedef enum -{ - FormatSize_INVALID, - FormatSize_CHAR, - FormatSize_SHORT, - FormatSize_INT, - FormatSize_POINTER -} DMF_EventLogFormatSizeType; - -// The table of insertion strings. -// -typedef struct -{ - // The insertion string data to write to event log = null terminated 16 bit wide character strings. - // - WCHAR ArrayOfInsertionStrings[DMF_EVENTLOG_MAXIMUM_NUMBER_OF_INSERTION_STRINGS][DMF_EVENTLOG_MAXIMUM_INSERTION_STRING_LENGTH]; - // The number of insertion strings. - // - ULONG NumberOfInsertionStrings; -} EVENTLOG_INSERTION_STRING_TABLE; - -static -_IRQL_requires_max_(PASSIVE_LEVEL) -DMF_EventLogFormatSizeType -DMF_DMF_EventLogFormatSizeTypeGet( - _Inout_ PWCHAR FormatString - ) -/*++ - -Routine Description: - - This routine takes extracts the format specifier from a format string and returns a unique identifier based on it. - -Arguments: - - FormatString - The format string - -Return Value: - - DMF_EventLogFormatSizeType - A unique identifier based on the format specifier. - ---*/ -{ - DMF_EventLogFormatSizeType returnValue; - - DmfAssert(FormatString != NULL); - returnValue = FormatSize_INVALID; - while ((*FormatString != L'\0') && - (FormatSize_INVALID == returnValue)) - { - if ((L'%' == *FormatString) && - (*(FormatString + 1) != L'\0')) - { - WCHAR nextCharacter; - - nextCharacter = *(FormatString + 1); - switch (nextCharacter) - { - case L'%': - { - break; - } - case L'c': - { - returnValue = FormatSize_CHAR; - break; - } - case L'd': - case L'u': - case L'x': - case L'X': - { - returnValue = FormatSize_INT; - break; - } - case L'p': - // Support for Wide strings. - // - case L's': - // Support for ANSI strings. - // - case L'S': - { - returnValue = FormatSize_POINTER; - break; - } - default: - { - DmfAssert(FALSE); - goto Exit; - } - } - } - FormatString++; - } - -Exit: - - return returnValue; -} - -static -_IRQL_requires_max_(PASSIVE_LEVEL) -NTSTATUS -DMF_EventLogInsertionStringTableAllocate( - _Out_ EVENTLOG_INSERTION_STRING_TABLE** EventLogInsertionStringTable, - _Out_ WDFMEMORY* EventLogInsertionStringTableMemory, - _In_ INT NumberOfInsertionStrings, - _In_ va_list ArgumentList, - _In_ INT NumberOfFormatStrings, - _In_ PWCHAR* FormatStrings - ) -/*++ - -Routine Description: - - This routine allocates an event log insertion string table and assigns it with entries formed from - the Format strings and Argument list passed to it. - -Arguments: - - EventLogInsertionStringTable - Pointer to a location that receives a handle to EventLogInsertionStringTable. - EventLogInsertionStringTableMemory - Pointer to a location that receives a handle to memory associated with EventLogInsertionStringTable. - NumberOfInsertionStrings - Number of insertion strings. - ArgumentList - List of arguments (integers / characters / strings / pointers). - NumberOfFormatStrings - Number of format strings. - FormatStrings - Format strings with format specifiers for the arguments passed in ArgumentList. - -Return Value: - - NTSTATUS - ---*/ -{ - INT stringIndex; - NTSTATUS ntStatus; - WDF_OBJECT_ATTRIBUTES attributes; - EVENTLOG_INSERTION_STRING_TABLE* eventLogInsertionStringTable; - - FuncEntry(DMF_TRACE); - - ntStatus = STATUS_SUCCESS; - - DmfAssert(NumberOfFormatStrings == NumberOfInsertionStrings); - - WDF_OBJECT_ATTRIBUTES_INIT(&attributes); - ntStatus = WdfMemoryCreate(&attributes, - NonPagedPoolNx, - DMF_TAG, - sizeof(EVENTLOG_INSERTION_STRING_TABLE), - EventLogInsertionStringTableMemory, - (VOID**)EventLogInsertionStringTable); - - if (! NT_SUCCESS(ntStatus)) - { - TraceEvents(TRACE_LEVEL_ERROR, DMF_TRACE, "Unable to allocate eventLogStringTable"); - *EventLogInsertionStringTable = NULL; - *EventLogInsertionStringTableMemory = NULL; - goto Exit; - } - - DmfAssert(NULL != *EventLogInsertionStringTable); - DmfAssert(NULL != *EventLogInsertionStringTableMemory); - - eventLogInsertionStringTable = *EventLogInsertionStringTable; - - RtlZeroMemory(eventLogInsertionStringTable, - sizeof(EVENTLOG_INSERTION_STRING_TABLE)); - - DmfAssert(NumberOfInsertionStrings <= DMF_EVENTLOG_MAXIMUM_NUMBER_OF_INSERTION_STRINGS); - for (stringIndex = 0; stringIndex < NumberOfFormatStrings; stringIndex++) - { - WCHAR* formatString; - DMF_EventLogFormatSizeType formatSize; - - formatString = FormatStrings[stringIndex]; - DmfAssert(formatString != NULL); - DmfAssert(wcslen(FormatStrings[stringIndex]) < DMF_EVENTLOG_MAXIMUM_INSERTION_STRING_LENGTH); - - formatSize = DMF_DMF_EventLogFormatSizeTypeGet(formatString); - switch (formatSize) - { - case FormatSize_CHAR: - { - CHAR argument; - - argument = va_arg(ArgumentList, - CHAR); - - swprintf_s(eventLogInsertionStringTable->ArrayOfInsertionStrings[stringIndex], - DMF_EVENTLOG_MAXIMUM_INSERTION_STRING_LENGTH, - formatString, - argument); - break; - } - case FormatSize_INT: - { - INT argument; - - argument = va_arg(ArgumentList, - INT); - - swprintf_s(eventLogInsertionStringTable->ArrayOfInsertionStrings[stringIndex], - DMF_EVENTLOG_MAXIMUM_INSERTION_STRING_LENGTH, - formatString, - argument); - break; - } - case FormatSize_POINTER: - { - VOID* argument; - - argument = va_arg(ArgumentList, - VOID*); - - swprintf_s(eventLogInsertionStringTable->ArrayOfInsertionStrings[stringIndex], - DMF_EVENTLOG_MAXIMUM_INSERTION_STRING_LENGTH, - formatString, - argument); - break; - } - default: - { - DmfAssert(FALSE); - DmfAssert(0 == eventLogInsertionStringTable->NumberOfInsertionStrings); - goto Exit; - } - } - } - - eventLogInsertionStringTable->NumberOfInsertionStrings = NumberOfInsertionStrings; - DmfAssert(eventLogInsertionStringTable->NumberOfInsertionStrings <= DMF_EVENTLOG_MAXIMUM_NUMBER_OF_INSERTION_STRINGS); - -Exit: - - FuncExit(DMF_TRACE, "eventLogStringTable=0x%p", *EventLogInsertionStringTable); - - return ntStatus; -} - -static -_IRQL_requires_max_(PASSIVE_LEVEL) -VOID -DMF_EventLogInsertionStringTableDeallocate( - _In_ WDFMEMORY EventLogInsertionStringTableMemory - ) -/*++ - -Routine Description: - - This routine deallocates memory allocated to the insertion string table. - -Arguments: - - EventLogInsertionStringTableMemory - Memory handle associated with the insertion string table. - -Return Value: - - None. If there is an error, no error is logged. - ---*/ -{ - FuncEntry(DMF_TRACE); - - WdfObjectDelete(EventLogInsertionStringTableMemory); - - FuncExitNoReturn(DMF_TRACE); -} - -static -_IRQL_requires_max_(PASSIVE_LEVEL) -NTSTATUS -DMF_Utility_InsertionStringTableCreate( - _Out_ EVENTLOG_INSERTION_STRING_TABLE** EventLogInsertionStringTable, - _Out_ WDFMEMORY* EventLogInsertionStringTableMemory, - _In_ INT NumberOfInsertionStrings, - _In_ va_list ArgumentList, - _In_ INT NumberOfFormatStrings, - _In_opt_ PWCHAR* FormatStrings - ) -/*++ - -Routine Description: - - This routine creates the insertion string table. - -Arguments: - - EventLogInsertionStringTable - Pointer to a location that receives a handle to EventLogInsertionStringTable. - EventLogInsertionStringTableMemory - Pointer to a location that receives a handle to memory associated with EventLogInsertionStringTable. - NumberOfInsertionStrings - Number of insertion strings. - ArgumentList - List of arguments (integers / characters / strings / pointers). - NumberOfFormatStrings - Number of format strings. - FormatStrings - Format strings with format specifiers for the arguments passed in ArgumentList. - -Return Value: - - NTSTATUS - ---*/ -{ - NTSTATUS ntStatus; - - ntStatus = STATUS_SUCCESS; - - DmfAssert(NumberOfInsertionStrings == NumberOfFormatStrings); - DmfAssert(NumberOfInsertionStrings <= DMF_EVENTLOG_MAXIMUM_NUMBER_OF_INSERTION_STRINGS); - if (0 == NumberOfInsertionStrings) - { - DmfAssert(NULL == FormatStrings); - *EventLogInsertionStringTable = NULL; - *EventLogInsertionStringTableMemory = NULL; - goto Exit; - } - - DmfAssert(FormatStrings != NULL); - // FormatStrings must not be NULL. But it is not because we have asserted above. - // - #pragma warning(suppress:6387) - ntStatus = DMF_EventLogInsertionStringTableAllocate(EventLogInsertionStringTable, - EventLogInsertionStringTableMemory, - NumberOfInsertionStrings, - ArgumentList, - NumberOfFormatStrings, - FormatStrings); - if (NT_SUCCESS(ntStatus)) - { - DmfAssert(NULL != *EventLogInsertionStringTable); - DmfAssert(NULL != *EventLogInsertionStringTableMemory); - } - else - { - DmfAssert(NULL == *EventLogInsertionStringTable); - DmfAssert(NULL == *EventLogInsertionStringTableMemory); - } - -Exit: - - return ntStatus; -} - _IRQL_requires_max_(PASSIVE_LEVEL) VOID DMF_Utility_LogEmitString( @@ -1041,851 +698,5 @@ Return Value: FuncExitNoReturn(DMF_TRACE); } -#if defined(DMF_KERNEL_MODE) - -// Event log support for Kernel-mode Drivers. -// -static -_IRQL_requires_max_(PASSIVE_LEVEL) -VOID -DMF_Utility_EventLogEntryWriteToEventLogFile( - _In_ PDRIVER_OBJECT DriverObject, - _In_ NTSTATUS ErrorCode, - _In_ NTSTATUS FinalNtStatus, - _In_ ULONG UniqueId, - _In_ ULONG TextLength, - _In_opt_ PCWSTR Text, - _In_opt_ EVENTLOG_INSERTION_STRING_TABLE* EventLogInsertionStringTable - ) -/*++ - -Routine Description: - - This routine allocates an error log entry, copies the supplied data - to it, and requests that it be written to the event log file. This is the root - function that writes all logging entries. - -Arguments: - - DriverObject - WDM Driver object. - - ErrorCode - ErrorCode from header generated by mc compiler. - FinalNtStatus - The final NTSTATUS for the error being logged. - UniqueId - A unique long word that identifies the particular - call to this function. - NumberOfInsertionStrings - Number of insertion strings. - TextLength - The length in bytes (including the terminating NULL) - of the Text string. - Text - Additional data to add to be included in the error log. - EventLogInsertionStringTable - A structure containing a table of insertion strings - and the number of insertion strings. - -Return Value: - - None. If there is an error, no error is logged. - ---*/ -{ - PIO_ERROR_LOG_PACKET errorLogEntry; - SIZE_T totalLength; - SIZE_T textOffset; - SIZE_T insertionStringOffset; - ULONG stringIndex; - ULONG numberOfInsertionStrings; - - FuncEntry(DMF_TRACE); - - DmfAssert(DriverObject != NULL); - - textOffset = 0; - insertionStringOffset = 0; - numberOfInsertionStrings = 0; - - totalLength = sizeof(IO_ERROR_LOG_PACKET); - - // Determine if we need space for the text. - // - if (NULL != Text) - { - DmfAssert(TextLength > 0); - // Calculate how big the error log packet needs to be to hold everything. - // Get offset for text data. - // - textOffset = totalLength; - - // Add one for NULL terminating character. - // - totalLength += ((TextLength + 1) * sizeof(WCHAR)); - } - else - { - DmfAssert(TextLength == 0); - } - - if (EventLogInsertionStringTable != NULL) - { - insertionStringOffset = totalLength; - numberOfInsertionStrings = EventLogInsertionStringTable->NumberOfInsertionStrings; - - DmfAssert(numberOfInsertionStrings > 0); - DmfAssert(numberOfInsertionStrings <= DMF_EVENTLOG_MAXIMUM_NUMBER_OF_INSERTION_STRINGS); - for (stringIndex = 0; stringIndex < numberOfInsertionStrings; stringIndex++) - { - // Add one for NULL terminating character. - // - totalLength += (wcslen(EventLogInsertionStringTable->ArrayOfInsertionStrings[stringIndex]) + 1) * (sizeof(WCHAR)); - } - } - - // Determine if the text will fit into the error log packet. - // - if (totalLength > ERROR_LOG_MAXIMUM_SIZE) - { - DmfAssert(FALSE); - totalLength = sizeof(IO_ERROR_LOG_PACKET); - } - - errorLogEntry = (PIO_ERROR_LOG_PACKET)IoAllocateErrorLogEntry(DriverObject, - (UCHAR)totalLength); - - // If errorLogEntry in NULL, this is not considered an error situation. Just return. - // - if (errorLogEntry != NULL) - { - // Initialize the error log packet. - // - errorLogEntry->MajorFunctionCode = 0; - errorLogEntry->RetryCount = 0; - errorLogEntry->EventCategory = 0; - errorLogEntry->ErrorCode = ErrorCode; - errorLogEntry->UniqueErrorValue = UniqueId; - errorLogEntry->FinalStatus = FinalNtStatus; - errorLogEntry->SequenceNumber = 0; - errorLogEntry->IoControlCode = 0; - - if ((totalLength > textOffset) && (NULL != Text)) - { - // Able to include text - // - errorLogEntry->DumpDataSize = (USHORT)TextLength; - - RtlCopyMemory(errorLogEntry->DumpData, - Text, - (totalLength - textOffset)); - } - - // Write the insertion strings. - // - if ((totalLength > insertionStringOffset) && (numberOfInsertionStrings > 0)) - { - DmfAssert(numberOfInsertionStrings <= DMF_EVENTLOG_MAXIMUM_NUMBER_OF_INSERTION_STRINGS); - // Able to include insertion strings. - // - errorLogEntry->NumberOfStrings = (USHORT)numberOfInsertionStrings; - errorLogEntry->StringOffset = (USHORT)insertionStringOffset; - - for (stringIndex = 0; stringIndex < numberOfInsertionStrings; stringIndex++) - { - size_t stringLength; - UCHAR* targetAddress; - WCHAR* sourceString; - - // Add one for NULL terminator. - // - sourceString = EventLogInsertionStringTable->ArrayOfInsertionStrings[stringIndex]; - stringLength = (wcslen(sourceString) + 1) * (sizeof(WCHAR)); - targetAddress = (UCHAR*)errorLogEntry + insertionStringOffset; - RtlCopyMemory(targetAddress, - sourceString, - stringLength); - insertionStringOffset += stringLength; - } - } - else - { - // Couldn't include or caller didn't specify a text string. - // - errorLogEntry->NumberOfStrings = 0; - errorLogEntry->StringOffset = 0; - } - - // Request that the error log packet be written to the error log file. - // - IoWriteErrorLogEntry(errorLogEntry); - } - - FuncExitNoReturn(DMF_TRACE); -} - -_IRQL_requires_max_(PASSIVE_LEVEL) -VOID -DMF_Utility_EventLogEntryWriteDriverObject( - _In_ PDRIVER_OBJECT DriverObject, - _In_ NTSTATUS ErrorCode, - _In_ NTSTATUS FinalNtStatus, - _In_ ULONG UniqueId, - _In_ ULONG TextLength, - _In_opt_ PCWSTR Text, - _In_ INT NumberOfFormatStrings, - _In_opt_ PWCHAR* FormatStrings, - _In_ INT NumberOfInsertionStrings, - ... - ) -/*++ - -Routine Description: - - This routine creates an insertion string table and requests the arguments and the table be written to event log file. - -Arguments: - - DriverObject - WDM Driver object. - ErrorCode - ErrorCode from header generated by mc compiler. - FinalNtStatus - The final NTSTATUS for the error being logged. - UniqueId - A unique long word that identifies the particular - call to this function. - TextLength - The length in bytes (including the terminating NULL) - of the Text string. - Text - Additional data to add to be included in the error log. - NumberOfFormatStrings - Number of format strings. - FormatStrings - An array of format specifiers for each argument passed below. - NumberOfInsertionStrings - Number of insertion strings. - ... - Variable list of insertion strings. - -Return Value: - - None. If there is an error, no error is logged. - ---*/ -{ - EVENTLOG_INSERTION_STRING_TABLE* eventLogStringTable; - va_list argumentList; - WDFMEMORY eventLogStringTableMemory; - NTSTATUS ntStatus; - - FuncEntry(DMF_TRACE); - - ntStatus = STATUS_SUCCESS; - eventLogStringTable = NULL; - eventLogStringTableMemory = NULL; - - DmfAssert(NumberOfInsertionStrings <= DMF_EVENTLOG_MAXIMUM_NUMBER_OF_INSERTION_STRINGS); - - va_start(argumentList, - NumberOfInsertionStrings); - - ntStatus = DMF_Utility_InsertionStringTableCreate(&eventLogStringTable, - &eventLogStringTableMemory, - NumberOfInsertionStrings, - argumentList, - NumberOfFormatStrings, - FormatStrings); - - va_end(argumentList); - - DMF_Utility_EventLogEntryWriteToEventLogFile(DriverObject, - ErrorCode, - FinalNtStatus, - UniqueId, - TextLength, - Text, - eventLogStringTable); - - if (eventLogStringTableMemory) - { - DMF_EventLogInsertionStringTableDeallocate(eventLogStringTableMemory); - eventLogStringTableMemory = NULL; - eventLogStringTable = NULL; - } - - FuncExitNoReturn(DMF_TRACE); -} - -_IRQL_requires_max_(PASSIVE_LEVEL) -VOID -DMF_Utility_EventLogEntryWriteDriver( - _In_ WDFDRIVER Driver, - _In_ NTSTATUS ErrorCode, - _In_ NTSTATUS FinalNtStatus, - _In_ ULONG UniqueId, - _In_ ULONG TextLength, - _In_opt_ PCWSTR Text, - _In_ INT NumberOfFormatStrings, - _In_opt_ PWCHAR* FormatStrings, - _In_ INT NumberOfInsertionStrings, - ... - ) -/*++ - -Routine Description: - - This routine creates an insertion string table and requests the arguments and the table be - written to event log file. - This function requires a WDFDRIVER object. It is designed to be called from Client Driver - when a WDFDEVICE object is not available. - -Arguments: - - Driver - WDF Driver. - ErrorCode - ErrorCode from header generated by mc compiler. - FinalNtStatus - The final NTSTATUS for the error being logged. - UniqueId - A unique long word that identifies the particular - call to this function. - TextLength - The length in bytes (including the terminating NULL) - of the Text string. - Text - Additional data to add to be included in the error log. - NumberOfFormatStrings - Number of format strings. - FormatStrings - An array of format specifiers for each argument passed below. - NumberOfInsertionStrings - Number of insertion strings. - ... - Variable list of insertion strings. - -Return Value: - - None. If there is an error, no error is logged. - ---*/ -{ - PDRIVER_OBJECT driverObject; - EVENTLOG_INSERTION_STRING_TABLE* eventLogStringTable; - va_list argumentList; - WDFMEMORY eventLogStringTableMemory; - NTSTATUS ntStatus; - - FuncEntry(DMF_TRACE); - - ntStatus = STATUS_SUCCESS; - eventLogStringTable = NULL; - eventLogStringTableMemory = NULL; - - DmfAssert(NumberOfInsertionStrings <= DMF_EVENTLOG_MAXIMUM_NUMBER_OF_INSERTION_STRINGS); - - va_start(argumentList, - NumberOfInsertionStrings); - - ntStatus = DMF_Utility_InsertionStringTableCreate(&eventLogStringTable, - &eventLogStringTableMemory, - NumberOfInsertionStrings, - argumentList, - NumberOfFormatStrings, - FormatStrings); - - va_end(argumentList); - - // Get the associated WDM Driver Object. - // - driverObject = WdfDriverWdmGetDriverObject(Driver); - - DMF_Utility_EventLogEntryWriteToEventLogFile(driverObject, - ErrorCode, - FinalNtStatus, - UniqueId, - TextLength, - Text, - eventLogStringTable); - - if (eventLogStringTableMemory) - { - DMF_EventLogInsertionStringTableDeallocate(eventLogStringTableMemory); - eventLogStringTableMemory = NULL; - eventLogStringTable = NULL; - } - - FuncExitNoReturn(DMF_TRACE); -} - -_IRQL_requires_max_(PASSIVE_LEVEL) -VOID -DMF_Utility_EventLogEntryWriteDevice( - _In_ WDFDEVICE Device, - _In_ NTSTATUS ErrorCode, - _In_ NTSTATUS Status, - _In_ ULONG UniqueId, - _In_ ULONG TextLength, - _In_opt_ PCWSTR Text, - _In_ INT NumberOfFormatStrings, - _In_opt_ PWCHAR* FormatStrings, - _In_ INT NumberOfInsertionStrings, - ... - ) -/*++ - -Routine Description: - - This routine creates an insertion string table and requests - the arguments and the table be written to event log file. - This function requires a WDFDEVICE object. - -Arguments: - - Device - WDF Device. - ErrorCode - ErrorCode from header generated by mc compiler. - FinalNtStatus - The final NTSTATUS for the error being logged. - UniqueId - A unique long word that identifies the particular - call to this function. - TextLength - The length in bytes (including the terminating NULL) - of the Text string. - Text - Additional data to add to be included in the error log. - NumberOfFormatStrings - Number of format strings. - FormatStrings - An array of format specifiers for each argument passed below. - NumberOfInsertionStrings - The number of insertion string arguments that follow. - ... - Variable list of insertion strings. - -Return Value: - - None. If there is an error, no error is logged. - ---*/ -{ - EVENTLOG_INSERTION_STRING_TABLE* eventLogStringTable; - va_list argumentList; - WDFDRIVER driver; - PDRIVER_OBJECT driverObject; - WDFMEMORY eventLogStringTableMemory; - NTSTATUS ntStatus; - - FuncEntry(DMF_TRACE); - - ntStatus = STATUS_SUCCESS; - eventLogStringTable = NULL; - eventLogStringTableMemory = NULL; - - DmfAssert(NumberOfInsertionStrings <= DMF_EVENTLOG_MAXIMUM_NUMBER_OF_INSERTION_STRINGS); - DmfAssert(Device != NULL); - - va_start(argumentList, - NumberOfInsertionStrings); - - ntStatus = DMF_Utility_InsertionStringTableCreate(&eventLogStringTable, - &eventLogStringTableMemory, - NumberOfInsertionStrings, - argumentList, - NumberOfFormatStrings, - FormatStrings); - - va_end(argumentList); - - // Get the associated WDF Driver. - // - driver = WdfDeviceGetDriver(Device); - DmfAssert(driver != NULL); - // Get the associated WDM Driver Object. - // - driverObject = WdfDriverWdmGetDriverObject(driver); - - DMF_Utility_EventLogEntryWriteToEventLogFile(driverObject, - ErrorCode, - Status, - UniqueId, - TextLength, - Text, - eventLogStringTable); - - if (eventLogStringTableMemory) - { - DMF_EventLogInsertionStringTableDeallocate(eventLogStringTableMemory); - eventLogStringTableMemory = NULL; - eventLogStringTable = NULL; - } - - FuncExitNoReturn(DMF_TRACE); -} - -_IRQL_requires_max_(PASSIVE_LEVEL) -VOID -DMF_Utility_EventLogEntryWriteDmfModule( - _In_ DMFMODULE DmfModule, - _In_ NTSTATUS ErrorCode, - _In_ NTSTATUS FinalNtStatus, - _In_ ULONG UniqueId, - _In_ ULONG TextLength, - _In_opt_ PCWSTR Text, - _In_ INT NumberOfFormatStrings, - _In_opt_ PWCHAR* FormatStrings, - _In_ INT NumberOfInsertionStrings, - ... - ) -/*++ - -Routine Description: - - This routine creates an insertion string table and requests - the arguments and the table be written to event log file. - This function requires a DMF_OBJECT* object. - -Arguments: - - DmfModule - This Module's handle. - ErrorCode - ErrorCode from header generated by Message Compiler (MC.exe). - FinalNtStatus - The final NTSTATUS for the error being logged. - UniqueId - A unique long word that identifies the particular - call to this function. - TextLength - The length in bytes (including the terminating NULL) - of the Text string. - Text - Additional data to add to be included in the error log. - NumberOfFormatStrings - Number of format strings. - FormatStrings - An array of format specifiers for each argument passed below. - NumberOfInsertionStrings - Number of insertion strings. - ... - Variable list of insertion strings. - -Return Value: - - None. If there is an error, no error is logged. - ---*/ -{ - WDFDEVICE device; - WDFDRIVER driver; - PDRIVER_OBJECT driverObject; - EVENTLOG_INSERTION_STRING_TABLE* eventLogStringTable; - va_list argumentList; - WDFMEMORY eventLogStringTableMemory; - NTSTATUS ntStatus; - - FuncEntry(DMF_TRACE); - - ntStatus = STATUS_SUCCESS; - eventLogStringTable = NULL; - eventLogStringTableMemory = NULL; - - DmfAssert(NumberOfInsertionStrings <= DMF_EVENTLOG_MAXIMUM_NUMBER_OF_INSERTION_STRINGS); - DmfAssert(NumberOfInsertionStrings == NumberOfFormatStrings); - - va_start(argumentList, - NumberOfInsertionStrings); - - ntStatus = DMF_Utility_InsertionStringTableCreate(&eventLogStringTable, - &eventLogStringTableMemory, - NumberOfInsertionStrings, - argumentList, - NumberOfFormatStrings, - FormatStrings); - - va_end(argumentList); - - // Get the associated WDM Device. - // - device = DMF_ParentDeviceGet(DmfModule); - // Get the associated WDM Driver. - // - driver = WdfDeviceGetDriver(device); - DmfAssert(driver != NULL); - // Get the associated WDM Driver Object. - // - driverObject = WdfDriverWdmGetDriverObject(driver); - - DMF_Utility_EventLogEntryWriteToEventLogFile(driverObject, - ErrorCode, - FinalNtStatus, - UniqueId, - TextLength, - Text, - eventLogStringTable); - - if (eventLogStringTableMemory) - { - DMF_EventLogInsertionStringTableDeallocate(eventLogStringTableMemory); - eventLogStringTableMemory = NULL; - eventLogStringTable = NULL; - } - - FuncExitNoReturn(DMF_TRACE); -} - -#else - -// Event log support for User-mode Drivers. -// - -// The table of insertion strings. -// -typedef struct -{ - // The insertion string data to write to event log = null terminated 16 bit wide character strings. - // - LPWSTR* InsertionStrings; - // The number of insertion strings. - // - ULONG NumberOfInsertionStrings; -} DMF_INSERTION_STRING_LIST; - -NTSTATUS -DMF_Utility_InsertionStringListCreate( - _In_ EVENTLOG_INSERTION_STRING_TABLE* EventLogInsertionStringTable, - _Out_ DMF_INSERTION_STRING_LIST** InsertionStringList - ) -/*++ - -Routine Description: - - This routine creates a closely packed insertion string list. - -Arguments: - - EventLogInsertionStringTable - the insertion string table containing the insertion strings that will be part of the list. - InsertionStringList - Pointer to a location that receives a handle to DMF_INSERTION_STRING_LIST. - -Return Value: - - NTSTATUS - status of the Create operation. - ---*/ -{ - ULONG stringIndex; - ULONG numberOfInsertionStrings; - NTSTATUS ntStatus; - - FuncEntry(DMF_TRACE); - - ntStatus = STATUS_SUCCESS; - *InsertionStringList = NULL; - - if (NULL == EventLogInsertionStringTable) - { - goto Exit; - } - - numberOfInsertionStrings = EventLogInsertionStringTable->NumberOfInsertionStrings; - - DmfAssert(numberOfInsertionStrings > 0); - DmfAssert(numberOfInsertionStrings <= DMF_EVENTLOG_MAXIMUM_NUMBER_OF_INSERTION_STRINGS); - - // Allocate memory for the DMF_INSERTION_STRING_LIST structure. - // - *InsertionStringList = (DMF_INSERTION_STRING_LIST*)malloc(sizeof(DMF_INSERTION_STRING_LIST)); - if (NULL == *InsertionStringList) - { - ntStatus = STATUS_INSUFFICIENT_RESOURCES; - goto Exit; - } - - (*InsertionStringList)->InsertionStrings = NULL; - (*InsertionStringList)->NumberOfInsertionStrings = 0; - - // Allocate memory to store a pointer to each Insertion String. - // - (*InsertionStringList)->InsertionStrings = (LPWSTR*)malloc(sizeof(LPWSTR) * numberOfInsertionStrings); - if (NULL == (*InsertionStringList)->InsertionStrings) - { - ntStatus = STATUS_INSUFFICIENT_RESOURCES; - free(*InsertionStringList); - *InsertionStringList = NULL; - goto Exit; - } - - for (stringIndex = 0; stringIndex < numberOfInsertionStrings; stringIndex++) - { - // Allocate memory for each insertion string to NULL. - // - // 'warning C6386: Buffer overrun while writing to '((*InsertionStringList))->InsertionStrings': the writable size is 'sizeof(WCHAR *)*numberOfInsertionStrings' bytes, but '16' bytes might be written.' - // - #pragma warning(suppress:6386) - (*InsertionStringList)->InsertionStrings[stringIndex] = (LPWSTR)malloc(sizeof(WCHAR) * (wcslen(EventLogInsertionStringTable->ArrayOfInsertionStrings[stringIndex]) + 1)); - } - - // Copy the insertion strings from the table to the memory allocated. - // - for (stringIndex = 0; stringIndex < numberOfInsertionStrings; stringIndex++) - { - size_t stringLength; - WCHAR* sourceString; - - // Add one for NULL terminator. - // - sourceString = EventLogInsertionStringTable->ArrayOfInsertionStrings[stringIndex]; - stringLength = (wcslen(sourceString) + 1) * (sizeof(WCHAR)); - // 'warning C6386: Buffer overrun while writing to '((*InsertionStringList))->InsertionStrings': the writable size is 'sizeof(WCHAR *)*numberOfInsertionStrings' bytes, but '16' bytes might be written.' - // - #pragma warning(suppress:6385) - RtlCopyMemory((*InsertionStringList)->InsertionStrings[stringIndex], - sourceString, - stringLength); - } - - (*InsertionStringList)->NumberOfInsertionStrings = numberOfInsertionStrings; - -Exit: - - FuncExitNoReturn(DMF_TRACE); - return ntStatus; -} - -void -DMF_Utility_InsertionStringListDestroy( - _In_ DMF_INSERTION_STRING_LIST* InsertionStringList - ) -/*++ - -Routine Description: - - This routine destroys the insertion string list. - -Arguments: - - InsertionStringList - Pointer to a handle to DMF_INSERTION_STRING_LIST. - -Return Value: - - NTSTATUS - status of the Destroy operation. - ---*/ -{ - ULONG stringIndex; - ULONG numberOfInsertionStrings; - - DmfAssert(NULL != InsertionStringList); - DmfAssert(NULL != (InsertionStringList)->InsertionStrings); - - numberOfInsertionStrings = (InsertionStringList)->NumberOfInsertionStrings; - DmfAssert(numberOfInsertionStrings > 0); - - // Free memory associated with each string. - // - for (stringIndex = 0; stringIndex < numberOfInsertionStrings; stringIndex++) - { - free((InsertionStringList)->InsertionStrings[stringIndex]); - (InsertionStringList)->InsertionStrings[stringIndex] = NULL; - } - - // Free memory associated with the pointer to strings. - // - free((InsertionStringList)->InsertionStrings); - (InsertionStringList)->InsertionStrings = NULL; - (InsertionStringList)->NumberOfInsertionStrings = 0; - - // Free memory associated with the DMF_INSERTION_STRING_LIST structure. - // - free(InsertionStringList); - -} - -_IRQL_requires_max_(PASSIVE_LEVEL) -VOID -DMF_Utility_EventLogEntryWriteUserMode( - _In_ PWSTR Provider, - _In_ WORD EventType, - _In_ DWORD EventId, - _In_ INT NumberOfFormatStrings, - _In_opt_ PWCHAR* FormatStrings, - _In_ INT NumberOfInsertionStrings, - ... - ) -/*++ - -Routine Description: - - This routine writes an event from a User-mode driver to the system event log file. - -Arguments: - - Provider - Provider of the event. - EventType - Type of the event: EVENTLOG_SUCCESS/EVENTLOG_ERROR_TYPE/EVENTLOG_INFORMATION_TYPE/EVENTLOG_WARNING_TYPE - EventId - EventId from header generated by Message Compiler (MC.exe). - NumberOfFormatStrings - Number of format strings. - FormatStrings - An array of format specifiers for each argument passed below. - NumberOfInsertionStrings - Number of insertion strings. - ... - Variable list of insertion strings. - -Return Value: - - None. If there is an error, no error is logged. - ---*/ -{ - EVENTLOG_INSERTION_STRING_TABLE* eventLogStringTable; - DMF_INSERTION_STRING_LIST* insertionStringList; - va_list argumentList; - HANDLE eventSource; - WDFMEMORY eventLogStringTableMemory; - NTSTATUS ntStatus; - LPWSTR* insertionStrings; - - FuncEntry(DMF_TRACE); - - ntStatus = STATUS_SUCCESS; - eventSource = NULL; - eventLogStringTable = NULL; - eventLogStringTableMemory = NULL; - insertionStrings = NULL; - - DmfAssert(Provider != NULL); - DmfAssert(NumberOfInsertionStrings <= DMF_EVENTLOG_MAXIMUM_NUMBER_OF_INSERTION_STRINGS); - DmfAssert(NumberOfInsertionStrings == NumberOfFormatStrings); - - // Create the insertion string table. - // - va_start(argumentList, - NumberOfInsertionStrings); - - ntStatus = DMF_Utility_InsertionStringTableCreate(&eventLogStringTable, - &eventLogStringTableMemory, - NumberOfInsertionStrings, - argumentList, - NumberOfFormatStrings, - FormatStrings); - - va_end(argumentList); - - // Create the closely packed insertion string list. - // - ntStatus = DMF_Utility_InsertionStringListCreate(eventLogStringTable, - &insertionStringList); - if (! NT_SUCCESS(ntStatus)) - { - DmfAssert(NULL == insertionStringList); - NumberOfInsertionStrings = 0; - } - else if (NumberOfInsertionStrings > 0) - { - insertionStrings = insertionStringList->InsertionStrings; - } - - // 'Banned Crimson API Usage: RegisterEventSourceW is a Banned Crimson API'. - // - #pragma warning(suppress: 28735) - eventSource = RegisterEventSource(NULL, - Provider); - if (NULL == eventSource) - { - goto Exit; - } - - ReportEvent(eventSource, - EventType, - 0, - EventId, - NULL, - (WORD)NumberOfInsertionStrings, - 0, - (LPCWSTR*)insertionStrings, - NULL); - -Exit: - - if (eventSource) - { - DeregisterEventSource(eventSource); - } - - // Destroy the closely packed insertion string list. - // - if (insertionStringList) - { - DMF_Utility_InsertionStringListDestroy(insertionStringList); - insertionStringList = NULL; - } - - // Destroy the insertion string table. - // - if (eventLogStringTableMemory) - { - DMF_EventLogInsertionStringTableDeallocate(eventLogStringTableMemory); - eventLogStringTableMemory = NULL; - eventLogStringTable = NULL; - } - - FuncExitNoReturn(DMF_TRACE); -} -#endif // defined(DMF_KERNEL_MODE) - // eof: DmfUtility.c // diff --git a/Dmf/Framework/Modules.Core/Dmf_BufferPool.c b/Dmf/Framework/Modules.Core/Dmf_BufferPool.c index f1173890..8d394278 100644 --- a/Dmf/Framework/Modules.Core/Dmf_BufferPool.c +++ b/Dmf/Framework/Modules.Core/Dmf_BufferPool.c @@ -609,6 +609,7 @@ Routine Description: DMFMODULE dmfModule; DMF_CONTEXT_BufferPool* moduleContext; EVT_DMF_BufferPool_TimerCallback* timerExpirationCallback; + VOID* timerExpirationCallbackContext; LIST_ENTRY* listEntry; FuncEntry(DMF_TRACE); @@ -628,6 +629,7 @@ Routine Description: DMF_ModuleLock(dmfModule); timerExpirationCallback = NULL; + timerExpirationCallbackContext = NULL; // If timer callback executed, buffer associated with the timer should be present in the list. // But it might not be the first one. Search for it. // @@ -663,7 +665,11 @@ Routine Description: moduleContext, bufferPoolEntryTimer); + // These fields are both cleared in the next call. Save off so they can be passed to + // Client, otherwise they are NULL. + // timerExpirationCallback = bufferPoolEntryTimer->TimerExpirationCallback; + timerExpirationCallbackContext = bufferPoolEntryTimer->TimerExpirationCallbackContext; BufferPool_TimerFieldsClear(dmfModule, bufferPoolEntryTimer); @@ -688,7 +694,7 @@ Routine Description: timerExpirationCallback(dmfModule, bufferPoolEntryTimer->ClientBuffer, bufferPoolEntryTimer->ClientBufferContext, - bufferPoolEntryTimer->TimerExpirationCallbackContext); + timerExpirationCallbackContext); } else { diff --git a/Dmf/Modules.Library.Tests/Dmf_Tests_DeviceInterfaceMultipleTarget.c b/Dmf/Modules.Library.Tests/Dmf_Tests_DeviceInterfaceMultipleTarget.c index 41437d57..e6b28ef4 100644 --- a/Dmf/Modules.Library.Tests/Dmf_Tests_DeviceInterfaceMultipleTarget.c +++ b/Dmf/Modules.Library.Tests/Dmf_Tests_DeviceInterfaceMultipleTarget.c @@ -551,7 +551,7 @@ Return Value: ntStatus = DMF_BufferPool_Get(moduleContext->DmfModuleBufferPool, (VOID**)&sleepIoctlBuffer, NULL); - ASSERT(NT_SUCCESS(ntStatus)); + DmfAssert(NT_SUCCESS(ntStatus)); RtlZeroMemory(sleepIoctlBuffer, sizeof(Tests_IoctlHandler_Sleep)); @@ -806,7 +806,7 @@ Return Value: ntStatus = DMF_BufferPool_Get(moduleContext->DmfModuleBufferPool, (VOID**)&sleepIoctlBuffer, NULL); - ASSERT(NT_SUCCESS(ntStatus)); + DmfAssert(NT_SUCCESS(ntStatus)); timeToSleepMilliseconds = TestsUtility_GenerateRandomNumber(0, MAXIMUM_SLEEP_TIME_MS); @@ -856,7 +856,7 @@ Return Value: ntStatus = DMF_BufferPool_Get(moduleContext->DmfModuleBufferPool, (VOID**)&sleepIoctlBuffer, NULL); - ASSERT(NT_SUCCESS(ntStatus)); + DmfAssert(NT_SUCCESS(ntStatus)); ///////////////////////////////////////////////////////////////////////////////////// // Cancel the request after waiting the same time sent in timeout. @@ -866,7 +866,7 @@ Return Value: ntStatus = DMF_BufferPool_Get(moduleContext->DmfModuleBufferPool, (VOID**)&sleepIoctlBuffer, NULL); - ASSERT(NT_SUCCESS(ntStatus)); + DmfAssert(NT_SUCCESS(ntStatus)); timeToSleepMilliseconds = TestsUtility_GenerateRandomNumber(0, MAXIMUM_SLEEP_TIME_MS); @@ -914,7 +914,7 @@ Return Value: ntStatus = DMF_BufferPool_Get(moduleContext->DmfModuleBufferPool, (VOID**)&sleepIoctlBuffer, NULL); - ASSERT(NT_SUCCESS(ntStatus)); + DmfAssert(NT_SUCCESS(ntStatus)); ///////////////////////////////////////////////////////////////////////////////////// // Cancel the request immediately after sending it. It may or may not be canceled. @@ -923,7 +923,7 @@ Return Value: ntStatus = DMF_BufferPool_Get(moduleContext->DmfModuleBufferPool, (VOID**)&sleepIoctlBuffer, NULL); - ASSERT(NT_SUCCESS(ntStatus)); + DmfAssert(NT_SUCCESS(ntStatus)); timeToSleepMilliseconds = TestsUtility_GenerateRandomNumber(0, MAXIMUM_SLEEP_TIME_MS); @@ -962,7 +962,7 @@ Return Value: ntStatus = DMF_BufferPool_Get(moduleContext->DmfModuleBufferPool, (VOID**)&sleepIoctlBuffer, NULL); - ASSERT(NT_SUCCESS(ntStatus)); + DmfAssert(NT_SUCCESS(ntStatus)); timeToSleepMilliseconds = TestsUtility_GenerateRandomNumber(MINIMUM_SLEEP_TIME_MS, MAXIMUM_SLEEP_TIME_MS); @@ -1020,7 +1020,7 @@ Return Value: ntStatus = DMF_BufferPool_Get(moduleContext->DmfModuleBufferPool, (VOID**)&sleepIoctlBuffer, NULL); - ASSERT(NT_SUCCESS(ntStatus)); + DmfAssert(NT_SUCCESS(ntStatus)); timeToSleepMilliseconds = TestsUtility_GenerateRandomNumber(MINIMUM_SLEEP_TIME_MS, MAXIMUM_SLEEP_TIME_MS); @@ -1542,30 +1542,15 @@ Return Value: DMF_CONTEXT_Tests_DeviceInterfaceMultipleTarget* moduleContext; NTSTATUS ntStatus; LONG threadIndex; - WDF_OBJECT_ATTRIBUTES objectAttributes; TARGET_CONTEXT* targetContext; PAGED_CODE(); FuncEntry(DMF_TRACE); - moduleContext = DMF_CONTEXT_GET(DmfModule); - ntStatus = STATUS_SUCCESS; - - WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&objectAttributes, - TARGET_CONTEXT); - - ntStatus = WdfObjectAllocateContext(Target, - &objectAttributes, - (VOID**)&targetContext); - if (!NT_SUCCESS(ntStatus)) - { - TraceEvents(TRACE_LEVEL_ERROR, DMF_TRACE, "WdfObjectAllocateContext fails: ntStatus=%!STATUS!", ntStatus); - goto Exit; - } - - targetContext->Target = Target; + moduleContext = DMF_CONTEXT_GET(DmfModule); + targetContext = DeviceInterfaceMultipleTarget_TargetContextGet(Target); for (threadIndex = 0; threadIndex < THREAD_COUNT; threadIndex++) { diff --git a/Dmf/Modules.Library.Tests/Dmf_Tests_DeviceInterfaceTarget.c b/Dmf/Modules.Library.Tests/Dmf_Tests_DeviceInterfaceTarget.c index 6fe1bc5e..4a9f42b1 100644 --- a/Dmf/Modules.Library.Tests/Dmf_Tests_DeviceInterfaceTarget.c +++ b/Dmf/Modules.Library.Tests/Dmf_Tests_DeviceInterfaceTarget.c @@ -34,6 +34,11 @@ Module Name: #include +// Define TEST_CANCEL_SIMPLE to only execute simple tests that test cancel. +// +#define NO_TEST_CANCEL +#define NO_TEST_CANCEL_SIMPLE + // {5F4F3758-D11E-4684-B5AD-FE6D19D82A51} // DEFINE_GUID(GUID_NO_DEVICE, 0x5f4f3758, 0xd11e, 0x4684, 0xb5, 0xad, 0xfe, 0x6d, 0x19, 0xd8, 0x2a, 0x51); @@ -42,7 +47,12 @@ DEFINE_GUID(GUID_NO_DEVICE, 0x5f4f3758, 0xd11e, 0x4684, 0xb5, 0xad, 0xfe, 0x6d, #define MAXIMUM_SLEEP_TIME_MS (15000) // Keep synchronous maximum time short to make driver disable faster. // +#if !defined(TEST_CANCEL_SIMPLE) #define MAXIMUM_SLEEP_TIME_SYNCHRONOUS_MS (1000) +#else +#define MAXIMUM_SLEEP_TIME_SYNCHRONOUS_MS (30000) +#endif + // Asynchronous minimum sleep time to make sure request can be canceled. // #define MINIMUM_SLEEP_TIME_MS (4000) @@ -52,6 +62,8 @@ DEFINE_GUID(GUID_NO_DEVICE, 0x5f4f3758, 0xd11e, 0x4684, 0xb5, 0xad, 0xfe, 0x6d, #define TIMEOUT_FAST_MS 100 #define TIMEOUT_SLOW_MS 5000 #define TIMEOUT_TRAFFIC_DELAY_MS 250 +#define TIMEOUT_CANCEL_MS 15 +#define TIMEOUT_CANCEL_LONG_MS 250 #define NUMBER_OF_CONTINUOUS_REQUESTS 32 @@ -194,6 +206,7 @@ Tests_DeviceInterfaceTarget_ThreadAction_Synchronous( NTSTATUS ntStatus; Tests_IoctlHandler_Sleep sleepIoctlBuffer; size_t bytesWritten; + ULONG timeoutMs; UNREFERENCED_PARAMETER(DmfModuleAlertableSleep); @@ -204,8 +217,17 @@ Tests_DeviceInterfaceTarget_ThreadAction_Synchronous( RtlZeroMemory(&sleepIoctlBuffer, sizeof(sleepIoctlBuffer)); +#if defined(TEST_CANCEL) + // Test buffer never completes, always cancels. + // + sleepIoctlBuffer.TimeToSleepMilliseconds = TestsUtility_GenerateRandomNumber(MINIMUM_SLEEP_TIME_MS, + MAXIMUM_SLEEP_TIME_SYNCHRONOUS_MS); + timeoutMs = TIMEOUT_CANCEL_MS; +#else sleepIoctlBuffer.TimeToSleepMilliseconds = TestsUtility_GenerateRandomNumber(0, MAXIMUM_SLEEP_TIME_SYNCHRONOUS_MS); + timeoutMs = 0; +#endif bytesWritten = 0; ntStatus = DMF_DeviceInterfaceTarget_SendSynchronously(moduleContext->DmfModuleDeviceInterfaceTargetDispatchInput, &sleepIoctlBuffer, @@ -214,14 +236,72 @@ Tests_DeviceInterfaceTarget_ThreadAction_Synchronous( NULL, ContinuousRequestTarget_RequestType_Ioctl, IOCTL_Tests_IoctlHandler_SLEEP, - 0, + timeoutMs, + &bytesWritten); + DmfAssert(NT_SUCCESS(ntStatus) || (ntStatus == STATUS_CANCELLED) || (ntStatus == STATUS_INVALID_DEVICE_STATE)); + // TODO: Get time and compare with send time. + // + +#if defined(TEST_CANCEL) + // Test buffer always completes, no timeout. + // + sleepIoctlBuffer.TimeToSleepMilliseconds = TestsUtility_GenerateRandomNumber(0, + TIMEOUT_CANCEL_LONG_MS); + timeoutMs = MAXIMUM_SLEEP_TIME_SYNCHRONOUS_MS; +#else + sleepIoctlBuffer.TimeToSleepMilliseconds = TestsUtility_GenerateRandomNumber(0, + MAXIMUM_SLEEP_TIME_SYNCHRONOUS_MS); + timeoutMs = 0; +#endif + bytesWritten = 0; + ntStatus = DMF_DeviceInterfaceTarget_SendSynchronously(moduleContext->DmfModuleDeviceInterfaceTargetDispatchInput, + &sleepIoctlBuffer, + sizeof(Tests_IoctlHandler_Sleep), + NULL, + NULL, + ContinuousRequestTarget_RequestType_Ioctl, + IOCTL_Tests_IoctlHandler_SLEEP, + timeoutMs, + &bytesWritten); + DmfAssert(NT_SUCCESS(ntStatus) || (ntStatus == STATUS_CANCELLED) || (ntStatus == STATUS_INVALID_DEVICE_STATE)); + // TODO: Get time and compare with send time. + // + +#if defined(TEST_CANCEL) + // Test buffer never completes, always cancels. + // + sleepIoctlBuffer.TimeToSleepMilliseconds = TestsUtility_GenerateRandomNumber(MINIMUM_SLEEP_TIME_MS, + MAXIMUM_SLEEP_TIME_SYNCHRONOUS_MS); + timeoutMs = TIMEOUT_CANCEL_MS; +#else + sleepIoctlBuffer.TimeToSleepMilliseconds = TestsUtility_GenerateRandomNumber(0, + MAXIMUM_SLEEP_TIME_SYNCHRONOUS_MS); +#endif + + bytesWritten = 0; + ntStatus = DMF_DeviceInterfaceTarget_SendSynchronously(moduleContext->DmfModuleDeviceInterfaceTargetPassiveInput, + &sleepIoctlBuffer, + sizeof(Tests_IoctlHandler_Sleep), + NULL, + NULL, + ContinuousRequestTarget_RequestType_Ioctl, + IOCTL_Tests_IoctlHandler_SLEEP, + timeoutMs, &bytesWritten); DmfAssert(NT_SUCCESS(ntStatus) || (ntStatus == STATUS_CANCELLED) || (ntStatus == STATUS_INVALID_DEVICE_STATE)); // TODO: Get time and compare with send time. // +#if defined(TEST_CANCEL) + // Test buffer always completes, no timeout. + // + sleepIoctlBuffer.TimeToSleepMilliseconds = TestsUtility_GenerateRandomNumber(0, + TIMEOUT_CANCEL_LONG_MS); + timeoutMs = MAXIMUM_SLEEP_TIME_SYNCHRONOUS_MS; +#else sleepIoctlBuffer.TimeToSleepMilliseconds = TestsUtility_GenerateRandomNumber(0, MAXIMUM_SLEEP_TIME_SYNCHRONOUS_MS); +#endif bytesWritten = 0; ntStatus = DMF_DeviceInterfaceTarget_SendSynchronously(moduleContext->DmfModuleDeviceInterfaceTargetPassiveInput, &sleepIoctlBuffer, @@ -230,7 +310,7 @@ Tests_DeviceInterfaceTarget_ThreadAction_Synchronous( NULL, ContinuousRequestTarget_RequestType_Ioctl, IOCTL_Tests_IoctlHandler_SLEEP, - 0, + timeoutMs, &bytesWritten); DmfAssert(NT_SUCCESS(ntStatus) || (ntStatus == STATUS_CANCELLED) || (ntStatus == STATUS_INVALID_DEVICE_STATE)); // TODO: Get time and compare with send time. @@ -329,11 +409,12 @@ Tests_DeviceInterfaceTarget_ThreadAction_Asynchronous( ntStatus = DMF_BufferPool_Get(moduleContext->DmfModuleBufferPool, (VOID**)&sleepIoctlBuffer, NULL); - ASSERT(NT_SUCCESS(ntStatus)); + DmfAssert(NT_SUCCESS(ntStatus)); RtlZeroMemory(sleepIoctlBuffer, sizeof(Tests_IoctlHandler_Sleep)); +#if !defined(TEST_CANCEL) if (TestsUtility_GenerateRandomNumber(0, 1)) { @@ -344,6 +425,9 @@ Tests_DeviceInterfaceTarget_ThreadAction_Asynchronous( { timeoutMs = 0; } +#else + timeoutMs = TIMEOUT_CANCEL_MS; +#endif sleepIoctlBuffer->TimeToSleepMilliseconds = TestsUtility_GenerateRandomNumber(0, MAXIMUM_SLEEP_TIME_MS); @@ -363,7 +447,7 @@ Tests_DeviceInterfaceTarget_ThreadAction_Asynchronous( ntStatus = DMF_BufferPool_Get(moduleContext->DmfModuleBufferPool, (VOID**)&sleepIoctlBuffer, NULL); - ASSERT(NT_SUCCESS(ntStatus)); + DmfAssert(NT_SUCCESS(ntStatus)); RtlZeroMemory(sleepIoctlBuffer, sizeof(Tests_IoctlHandler_Sleep)); @@ -412,6 +496,7 @@ Tests_DeviceInterfaceTarget_ThreadAction_AsynchronousCancel( RequestTarget_DmfRequest DmfRequestId; BOOLEAN requestCanceled; LONG timeToSleepMilliseconds; + Tests_IoctlHandler_Sleep* sleepIoctlBuffer; PAGED_CODE(); @@ -423,11 +508,10 @@ Tests_DeviceInterfaceTarget_ThreadAction_AsynchronousCancel( // Cancel the request after it is normally completed. It should never cancel unless driver is shutting down. // - Tests_IoctlHandler_Sleep* sleepIoctlBuffer; ntStatus = DMF_BufferPool_Get(moduleContext->DmfModuleBufferPool, (VOID**)&sleepIoctlBuffer, NULL); - ASSERT(NT_SUCCESS(ntStatus)); + DmfAssert(NT_SUCCESS(ntStatus)); timeToSleepMilliseconds = TestsUtility_GenerateRandomNumber(MINIMUM_SLEEP_TIME_MS, MAXIMUM_SLEEP_TIME_MS); @@ -481,7 +565,7 @@ Tests_DeviceInterfaceTarget_ThreadAction_AsynchronousCancel( ntStatus = DMF_BufferPool_Get(moduleContext->DmfModuleBufferPool, (VOID**)&sleepIoctlBuffer, NULL); - ASSERT(NT_SUCCESS(ntStatus)); + DmfAssert(NT_SUCCESS(ntStatus)); sleepIoctlBuffer->TimeToSleepMilliseconds = timeToSleepMilliseconds; TraceEvents(TRACE_LEVEL_INFORMATION, DMF_TRACE, "SEND: sleepIoctlBuffer->TimeToSleepMilliseconds=%d sleepIoctlBuffer=0x%p", @@ -532,7 +616,7 @@ Tests_DeviceInterfaceTarget_ThreadAction_AsynchronousCancel( ntStatus = DMF_BufferPool_Get(moduleContext->DmfModuleBufferPool, (VOID**)&sleepIoctlBuffer, NULL); - ASSERT(NT_SUCCESS(ntStatus)); + DmfAssert(NT_SUCCESS(ntStatus)); timeToSleepMilliseconds = TestsUtility_GenerateRandomNumber(0, MAXIMUM_SLEEP_TIME_MS); @@ -580,7 +664,7 @@ Tests_DeviceInterfaceTarget_ThreadAction_AsynchronousCancel( ntStatus = DMF_BufferPool_Get(moduleContext->DmfModuleBufferPool, (VOID**)&sleepIoctlBuffer, NULL); - ASSERT(NT_SUCCESS(ntStatus)); + DmfAssert(NT_SUCCESS(ntStatus)); sleepIoctlBuffer->TimeToSleepMilliseconds = timeToSleepMilliseconds; bytesWritten = 0; @@ -620,7 +704,7 @@ Tests_DeviceInterfaceTarget_ThreadAction_AsynchronousCancel( ntStatus = DMF_BufferPool_Get(moduleContext->DmfModuleBufferPool, (VOID**)&sleepIoctlBuffer, NULL); - ASSERT(NT_SUCCESS(ntStatus)); + DmfAssert(NT_SUCCESS(ntStatus)); timeToSleepMilliseconds = TestsUtility_GenerateRandomNumber(0, MAXIMUM_SLEEP_TIME_MS); @@ -666,7 +750,7 @@ Tests_DeviceInterfaceTarget_ThreadAction_AsynchronousCancel( ntStatus = DMF_BufferPool_Get(moduleContext->DmfModuleBufferPool, (VOID**)&sleepIoctlBuffer, NULL); - ASSERT(NT_SUCCESS(ntStatus)); + DmfAssert(NT_SUCCESS(ntStatus)); sleepIoctlBuffer->TimeToSleepMilliseconds = timeToSleepMilliseconds; bytesWritten = 0; @@ -706,7 +790,7 @@ Tests_DeviceInterfaceTarget_ThreadAction_AsynchronousCancel( ntStatus = DMF_BufferPool_Get(moduleContext->DmfModuleBufferPool, (VOID**)&sleepIoctlBuffer, NULL); - ASSERT(NT_SUCCESS(ntStatus)); + DmfAssert(NT_SUCCESS(ntStatus)); sleepIoctlBuffer->TimeToSleepMilliseconds = timeToSleepMilliseconds; bytesWritten = 0; @@ -739,7 +823,7 @@ Tests_DeviceInterfaceTarget_ThreadAction_AsynchronousCancel( ntStatus = DMF_BufferPool_Get(moduleContext->DmfModuleBufferPool, (VOID**)&sleepIoctlBuffer, NULL); - ASSERT(NT_SUCCESS(ntStatus)); + DmfAssert(NT_SUCCESS(ntStatus)); sleepIoctlBuffer->TimeToSleepMilliseconds = timeToSleepMilliseconds; bytesWritten = 0; @@ -775,7 +859,7 @@ Tests_DeviceInterfaceTarget_ThreadAction_AsynchronousCancel( ntStatus = DMF_BufferPool_Get(moduleContext->DmfModuleBufferPool, (VOID**)&sleepIoctlBuffer, NULL); - ASSERT(NT_SUCCESS(ntStatus)); + DmfAssert(NT_SUCCESS(ntStatus)); sleepIoctlBuffer->TimeToSleepMilliseconds = timeToSleepMilliseconds; bytesWritten = 0; @@ -800,6 +884,7 @@ Tests_DeviceInterfaceTarget_ThreadAction_AsynchronousCancel( ntStatus = DMF_AlertableSleep_Sleep(DmfModuleAlertableSleep, 0, timeToSleepMilliseconds / 4); + // Cancel the request if possible. // It should always cancel since the time just waited is 1/4 the time that was sent above. // @@ -825,7 +910,7 @@ Tests_DeviceInterfaceTarget_ThreadAction_AsynchronousCancel( ntStatus = DMF_BufferPool_Get(moduleContext->DmfModuleBufferPool, (VOID**)&sleepIoctlBuffer, NULL); - ASSERT(NT_SUCCESS(ntStatus)); + DmfAssert(NT_SUCCESS(ntStatus)); sleepIoctlBuffer->TimeToSleepMilliseconds = timeToSleepMilliseconds; bytesWritten = 0; @@ -887,10 +972,14 @@ Tests_DeviceInterfaceTarget_WorkThread( threadIndex = WdfObjectGet_THREAD_INDEX_CONTEXT(DmfModuleThread); moduleContext = DMF_CONTEXT_GET(dmfModule); +#if !defined(TEST_CANCEL_SIMPLE) // Generate a random test action Id for a current iteration. // testAction = (TEST_ACTION)TestsUtility_GenerateRandomNumber(TEST_ACTION_MINIUM, TEST_ACTION_MAXIMUM); +#else + testAction = TEST_ACTION_SYNCHRONOUS; +#endif // Execute the test action. // @@ -1268,8 +1357,6 @@ Return Value: DMF_CONTEXT_Tests_DeviceInterfaceTarget* moduleContext; PAGED_CODE(); - TraceEvents(TRACE_LEVEL_INFORMATION, DMF_TRACE, "-->%!FUNC!"); - dmfModuleParent = DMF_ParentModuleGet(DmfModule); moduleContext = DMF_CONTEXT_GET(dmfModuleParent); @@ -1295,8 +1382,6 @@ Return Value: // ntStatus = Tests_DeviceInterfaceTarget_NonContinousStartAuto(dmfModuleParent); DmfAssert(NT_SUCCESS(ntStatus)); - - TraceEvents(TRACE_LEVEL_INFORMATION, DMF_TRACE, "<--%!FUNC!"); } #pragma code_seg() @@ -1328,15 +1413,11 @@ Return Value: PAGED_CODE(); - TraceEvents(TRACE_LEVEL_INFORMATION, DMF_TRACE, "-->%!FUNC!"); - dmfModuleParent = DMF_ParentModuleGet(DmfModule); // Stop the threads. Streaming is automatically stopped. // Tests_DeviceInterfaceTarget_NonContinousStopAuto(dmfModuleParent); - - TraceEvents(TRACE_LEVEL_INFORMATION, DMF_TRACE, "<--%!FUNC!"); } #pragma code_seg() @@ -1370,11 +1451,11 @@ Return Value: DMF_CONTEXT_Tests_DeviceInterfaceTarget* moduleContext; PAGED_CODE(); - TraceEvents(TRACE_LEVEL_INFORMATION, DMF_TRACE, "-->%!FUNC!"); - dmfModuleParent = DMF_ParentModuleGet(DmfModule); moduleContext = DMF_CONTEXT_GET(dmfModuleParent); +#if !defined(TEST_CANCEL_SIMPLE) + for (LONG threadIndex = 0; threadIndex < THREAD_COUNT; threadIndex++) { THREAD_INDEX_CONTEXT* threadIndexContext; @@ -1404,7 +1485,7 @@ Return Value: } DmfAssert(NT_SUCCESS(ntStatus)); - TraceEvents(TRACE_LEVEL_INFORMATION, DMF_TRACE, "<--%!FUNC!"); +#endif } #pragma code_seg() @@ -1438,8 +1519,6 @@ Return Value: DMF_CONTEXT_Tests_DeviceInterfaceTarget* moduleContext; PAGED_CODE(); - TraceEvents(TRACE_LEVEL_INFORMATION, DMF_TRACE, "-->%!FUNC!"); - dmfModuleParent = DMF_ParentModuleGet(DmfModule); moduleContext = DMF_CONTEXT_GET(dmfModuleParent); @@ -1471,8 +1550,6 @@ Return Value: Tests_DeviceInterfaceTarget_NonContinousStartManualOutput(dmfModuleParent); } DmfAssert(NT_SUCCESS(ntStatus)); - - TraceEvents(TRACE_LEVEL_INFORMATION, DMF_TRACE, "<--%!FUNC!"); } #pragma code_seg() @@ -1505,18 +1582,16 @@ Return Value: PAGED_CODE(); - TraceEvents(TRACE_LEVEL_INFORMATION, DMF_TRACE, "-->%!FUNC!"); - dmfModuleParent = DMF_ParentModuleGet(DmfModule); +#if !defined(TEST_CANCEL_SIMPLE) // Stop streaming. // DMF_DeviceInterfaceTarget_StreamStop(DmfModule); // Stop threads. // Tests_DeviceInterfaceTarget_NonContinousStopManualInput(dmfModuleParent); - - TraceEvents(TRACE_LEVEL_INFORMATION, DMF_TRACE, "<--%!FUNC!"); +#endif } #pragma code_seg() @@ -1549,8 +1624,6 @@ Return Value: PAGED_CODE(); - TraceEvents(TRACE_LEVEL_INFORMATION, DMF_TRACE, "-->%!FUNC!"); - dmfModuleParent = DMF_ParentModuleGet(DmfModule); // Stop streaming. @@ -1559,8 +1632,6 @@ Return Value: // Stop threads. // Tests_DeviceInterfaceTarget_NonContinousStopManualOutput(dmfModuleParent); - - TraceEvents(TRACE_LEVEL_INFORMATION, DMF_TRACE, "<--%!FUNC!"); } #pragma code_seg() @@ -1631,12 +1702,84 @@ Return Value: WDF_NO_OBJECT_ATTRIBUTES, &moduleContext->DmfModuleBufferPool); + // Thread + // ------ + // + for (LONG threadIndex = 0; threadIndex < THREAD_COUNT; threadIndex++) + { + DMF_CONFIG_Thread_AND_ATTRIBUTES_INIT(&moduleConfigThread, + &moduleAttributes); + moduleConfigThread.ThreadControlType = ThreadControlType_DmfControl; + moduleConfigThread.ThreadControl.DmfControl.EvtThreadWork = Tests_DeviceInterfaceTarget_WorkThread; + DMF_DmfModuleAdd(DmfModuleInit, + &moduleAttributes, + WDF_NO_OBJECT_ATTRIBUTES, + &moduleContext->DmfModuleThreadAuto[threadIndex]); + +#if !defined(TEST_CANCEL_SIMPLE) + DMF_CONFIG_Thread_AND_ATTRIBUTES_INIT(&moduleConfigThread, + &moduleAttributes); + moduleConfigThread.ThreadControlType = ThreadControlType_DmfControl; + moduleConfigThread.ThreadControl.DmfControl.EvtThreadWork = Tests_DeviceInterfaceTarget_WorkThread; + DMF_DmfModuleAdd(DmfModuleInit, + &moduleAttributes, + WDF_NO_OBJECT_ATTRIBUTES, + &moduleContext->DmfModuleThreadManualInput[threadIndex]); + + DMF_CONFIG_Thread_AND_ATTRIBUTES_INIT(&moduleConfigThread, + &moduleAttributes); + moduleConfigThread.ThreadControlType = ThreadControlType_DmfControl; + moduleConfigThread.ThreadControl.DmfControl.EvtThreadWork = Tests_DeviceInterfaceTarget_WorkThread; + DMF_DmfModuleAdd(DmfModuleInit, + &moduleAttributes, + WDF_NO_OBJECT_ATTRIBUTES, + &moduleContext->DmfModuleThreadManualOutput[threadIndex]); +#endif + + // AlertableSleep Auto + // ------------------- + // + DMF_CONFIG_AlertableSleep_AND_ATTRIBUTES_INIT(&moduleConfigAlertableSleep, + &moduleAttributes); + moduleConfigAlertableSleep.EventCount = 1; + moduleAttributes.ClientModuleInstanceName = "AlertableSleep.Auto"; + DMF_DmfModuleAdd(DmfModuleInit, + &moduleAttributes, + WDF_NO_OBJECT_ATTRIBUTES, + &moduleContext->DmfModuleAlertableSleepAuto[threadIndex]); + + // AlertableSleep Manual (Input) + // --------------------- + // + DMF_CONFIG_AlertableSleep_AND_ATTRIBUTES_INIT(&moduleConfigAlertableSleep, + &moduleAttributes); + moduleConfigAlertableSleep.EventCount = 1; + moduleAttributes.ClientModuleInstanceName = "AlertableSleep.ManualInput"; + DMF_DmfModuleAdd(DmfModuleInit, + &moduleAttributes, + WDF_NO_OBJECT_ATTRIBUTES, + &moduleContext->DmfModuleAlertableSleepManualInput[threadIndex]); + + // AlertableSleep Manual (Output) + // --------------------- + // + DMF_CONFIG_AlertableSleep_AND_ATTRIBUTES_INIT(&moduleConfigAlertableSleep, + &moduleAttributes); + moduleConfigAlertableSleep.EventCount = 1; + moduleAttributes.ClientModuleInstanceName = "AlertableSleep.ManualOutput"; + DMF_DmfModuleAdd(DmfModuleInit, + &moduleAttributes, + WDF_NO_OBJECT_ATTRIBUTES, + &moduleContext->DmfModuleAlertableSleepManualOutput[threadIndex]); + } + // DeviceInterfaceTarget (DISPATCH_LEVEL) // Processes Input Buffers. // DMF_CONFIG_DeviceInterfaceTarget_AND_ATTRIBUTES_INIT(&moduleConfigDeviceInterfaceTarget, &moduleAttributes); moduleConfigDeviceInterfaceTarget.DeviceInterfaceTargetGuid = GUID_DEVINTERFACE_Tests_IoctlHandler; +#if !defined(TEST_CANCEL_SIMPLE) moduleConfigDeviceInterfaceTarget.ContinuousRequestTargetModuleConfig.BufferCountInput = 1; moduleConfigDeviceInterfaceTarget.ContinuousRequestTargetModuleConfig.BufferInputSize = sizeof(Tests_IoctlHandler_Sleep); moduleConfigDeviceInterfaceTarget.ContinuousRequestTargetModuleConfig.ContinuousRequestCount = 1; @@ -1646,7 +1789,7 @@ Return Value: moduleConfigDeviceInterfaceTarget.ContinuousRequestTargetModuleConfig.EvtContinuousRequestTargetBufferInput = Tests_DeviceInterfaceTarget_BufferInput; moduleConfigDeviceInterfaceTarget.ContinuousRequestTargetModuleConfig.RequestType = ContinuousRequestTarget_RequestType_Ioctl; moduleConfigDeviceInterfaceTarget.ContinuousRequestTargetModuleConfig.ContinuousRequestTargetMode = ContinuousRequestTarget_Mode_Automatic; - +#endif moduleEventCallbacks.EvtModuleOnDeviceNotificationPostOpen = Tests_DeviceInterfaceTarget_OnDeviceArrivalNotification_AutoContinous; moduleEventCallbacks.EvtModuleOnDeviceNotificationPreClose = Tests_DeviceInterfaceTarget_OnDeviceRemovalNotification_AutoContinous; moduleAttributes.ClientCallbacks = &moduleEventCallbacks; @@ -1661,6 +1804,7 @@ Return Value: DMF_CONFIG_DeviceInterfaceTarget_AND_ATTRIBUTES_INIT(&moduleConfigDeviceInterfaceTarget, &moduleAttributes); moduleConfigDeviceInterfaceTarget.DeviceInterfaceTargetGuid = GUID_DEVINTERFACE_Tests_IoctlHandler; +#if !defined(TEST_CANCEL_SIMPLE) moduleConfigDeviceInterfaceTarget.ContinuousRequestTargetModuleConfig.BufferCountInput = 1; moduleConfigDeviceInterfaceTarget.ContinuousRequestTargetModuleConfig.BufferInputSize = sizeof(Tests_IoctlHandler_Sleep); moduleConfigDeviceInterfaceTarget.ContinuousRequestTargetModuleConfig.ContinuousRequestCount = 1; @@ -1670,16 +1814,18 @@ Return Value: moduleConfigDeviceInterfaceTarget.ContinuousRequestTargetModuleConfig.EvtContinuousRequestTargetBufferInput = Tests_DeviceInterfaceTarget_BufferInput; moduleConfigDeviceInterfaceTarget.ContinuousRequestTargetModuleConfig.RequestType = ContinuousRequestTarget_RequestType_Ioctl; moduleConfigDeviceInterfaceTarget.ContinuousRequestTargetModuleConfig.ContinuousRequestTargetMode = ContinuousRequestTarget_Mode_Manual; - - moduleAttributes.PassiveLevel = TRUE; +#endif moduleEventCallbacks.EvtModuleOnDeviceNotificationPostOpen = Tests_DeviceInterfaceTarget_OnDeviceArrivalNotification_ManualContinousInput; moduleEventCallbacks.EvtModuleOnDeviceNotificationPreClose = Tests_DeviceInterfaceTarget_OnDeviceRemovalNotification_ManualContinousInput; + moduleAttributes.PassiveLevel = TRUE; moduleAttributes.ClientCallbacks = &moduleEventCallbacks; DMF_DmfModuleAdd(DmfModuleInit, &moduleAttributes, WDF_NO_OBJECT_ATTRIBUTES, &moduleContext->DmfModuleDeviceInterfaceTargetPassiveInput); +#if !defined(TEST_CANCEL_SIMPLE) + // DeviceInterfaceTarget (PASSIVE_LEVEL) // Processes Output Buffers. // @@ -1705,75 +1851,6 @@ Return Value: WDF_NO_OBJECT_ATTRIBUTES, &moduleContext->DmfModuleDeviceInterfaceTargetPassiveOutput); - // Thread - // ------ - // - for (LONG threadIndex = 0; threadIndex < THREAD_COUNT; threadIndex++) - { - DMF_CONFIG_Thread_AND_ATTRIBUTES_INIT(&moduleConfigThread, - &moduleAttributes); - moduleConfigThread.ThreadControlType = ThreadControlType_DmfControl; - moduleConfigThread.ThreadControl.DmfControl.EvtThreadWork = Tests_DeviceInterfaceTarget_WorkThread; - DMF_DmfModuleAdd(DmfModuleInit, - &moduleAttributes, - WDF_NO_OBJECT_ATTRIBUTES, - &moduleContext->DmfModuleThreadAuto[threadIndex]); - - DMF_CONFIG_Thread_AND_ATTRIBUTES_INIT(&moduleConfigThread, - &moduleAttributes); - moduleConfigThread.ThreadControlType = ThreadControlType_DmfControl; - moduleConfigThread.ThreadControl.DmfControl.EvtThreadWork = Tests_DeviceInterfaceTarget_WorkThread; - DMF_DmfModuleAdd(DmfModuleInit, - &moduleAttributes, - WDF_NO_OBJECT_ATTRIBUTES, - &moduleContext->DmfModuleThreadManualInput[threadIndex]); - - DMF_CONFIG_Thread_AND_ATTRIBUTES_INIT(&moduleConfigThread, - &moduleAttributes); - moduleConfigThread.ThreadControlType = ThreadControlType_DmfControl; - moduleConfigThread.ThreadControl.DmfControl.EvtThreadWork = Tests_DeviceInterfaceTarget_WorkThread; - DMF_DmfModuleAdd(DmfModuleInit, - &moduleAttributes, - WDF_NO_OBJECT_ATTRIBUTES, - &moduleContext->DmfModuleThreadManualOutput[threadIndex]); - - // AlertableSleep Auto - // ------------------- - // - DMF_CONFIG_AlertableSleep_AND_ATTRIBUTES_INIT(&moduleConfigAlertableSleep, - &moduleAttributes); - moduleConfigAlertableSleep.EventCount = 1; - moduleAttributes.ClientModuleInstanceName = "AlertableSleep.Auto"; - DMF_DmfModuleAdd(DmfModuleInit, - &moduleAttributes, - WDF_NO_OBJECT_ATTRIBUTES, - &moduleContext->DmfModuleAlertableSleepAuto[threadIndex]); - - // AlertableSleep Manual (Input) - // --------------------- - // - DMF_CONFIG_AlertableSleep_AND_ATTRIBUTES_INIT(&moduleConfigAlertableSleep, - &moduleAttributes); - moduleConfigAlertableSleep.EventCount = 1; - moduleAttributes.ClientModuleInstanceName = "AlertableSleep.ManualInput"; - DMF_DmfModuleAdd(DmfModuleInit, - &moduleAttributes, - WDF_NO_OBJECT_ATTRIBUTES, - &moduleContext->DmfModuleAlertableSleepManualInput[threadIndex]); - - // AlertableSleep Manual (Output) - // --------------------- - // - DMF_CONFIG_AlertableSleep_AND_ATTRIBUTES_INIT(&moduleConfigAlertableSleep, - &moduleAttributes); - moduleConfigAlertableSleep.EventCount = 1; - moduleAttributes.ClientModuleInstanceName = "AlertableSleep.ManualOutput"; - DMF_DmfModuleAdd(DmfModuleInit, - &moduleAttributes, - WDF_NO_OBJECT_ATTRIBUTES, - &moduleContext->DmfModuleAlertableSleepManualOutput[threadIndex]); - } - // Test valid combinations of pool types. // @@ -1943,6 +2020,8 @@ Return Value: WDF_NO_OBJECT_ATTRIBUTES, NULL); +#endif + FuncExitVoid(DMF_TRACE); } #pragma code_seg() diff --git a/Dmf/Modules.Library.Tests/Dmf_Tests_SelfTarget.c b/Dmf/Modules.Library.Tests/Dmf_Tests_SelfTarget.c index dd73a4fd..42b89554 100644 --- a/Dmf/Modules.Library.Tests/Dmf_Tests_SelfTarget.c +++ b/Dmf/Modules.Library.Tests/Dmf_Tests_SelfTarget.c @@ -125,7 +125,7 @@ Tests_SelfTarget_ThreadAction_Synchronous( PAGED_CODE(); - TraceEvents(TRACE_LEVEL_INFORMATION, DMF_TRACE, "-->%!FUNC!"); + TraceEvents(TRACE_LEVEL_INFORMATION, DMF_TRACE, "Tests_SelfTarget_ThreadAction_Synchronous"); moduleContext = DMF_CONTEXT_GET(DmfModule); @@ -134,6 +134,7 @@ Tests_SelfTarget_ThreadAction_Synchronous( sleepIoctlBuffer.TimeToSleepMilliseconds = TestsUtility_GenerateRandomNumber(0, MAXIMUM_SLEEP_TIME_SYNCHRONOUS_MS); + bytesWritten = 0; ntStatus = DMF_SelfTarget_SendSynchronously(moduleContext->DmfModuleSelfTargetDispatch, &sleepIoctlBuffer, @@ -215,13 +216,15 @@ Tests_SelfTarget_ThreadAction_Asynchronous( PAGED_CODE(); + TraceEvents(TRACE_LEVEL_INFORMATION, DMF_TRACE, "Tests_SelfTarget_ThreadAction_Asynchronous"); + moduleContext = DMF_CONTEXT_GET(DmfModule); Tests_IoctlHandler_Sleep* sleepIoctlBuffer; ntStatus = DMF_BufferPool_Get(moduleContext->DmfModuleBufferPool, (VOID**)&sleepIoctlBuffer, NULL); - ASSERT(NT_SUCCESS(ntStatus)); + DmfAssert(NT_SUCCESS(ntStatus)); RtlZeroMemory(sleepIoctlBuffer, sizeof(Tests_IoctlHandler_Sleep)); @@ -255,7 +258,7 @@ Tests_SelfTarget_ThreadAction_Asynchronous( ntStatus = DMF_BufferPool_Get(moduleContext->DmfModuleBufferPool, (VOID**)&sleepIoctlBuffer, NULL); - ASSERT(NT_SUCCESS(ntStatus)); + DmfAssert(NT_SUCCESS(ntStatus)); RtlZeroMemory(sleepIoctlBuffer, sizeof(Tests_IoctlHandler_Sleep)); @@ -298,7 +301,7 @@ Tests_SelfTarget_ThreadAction_AsynchronousCancel( PAGED_CODE(); - TraceEvents(TRACE_LEVEL_INFORMATION, DMF_TRACE, "-->%!FUNC!"); + TraceEvents(TRACE_LEVEL_INFORMATION, DMF_TRACE, "Tests_SelfTarget_ThreadAction_AsynchronousCancel"); moduleContext = DMF_CONTEXT_GET(DmfModule); @@ -306,7 +309,7 @@ Tests_SelfTarget_ThreadAction_AsynchronousCancel( ntStatus = DMF_BufferPool_Get(moduleContext->DmfModuleBufferPool, (VOID**)&sleepIoctlBuffer, NULL); - ASSERT(NT_SUCCESS(ntStatus)); + DmfAssert(NT_SUCCESS(ntStatus)); RtlZeroMemory(sleepIoctlBuffer, sizeof(Tests_IoctlHandler_Sleep)); @@ -341,7 +344,7 @@ Tests_SelfTarget_ThreadAction_AsynchronousCancel( ntStatus = DMF_BufferPool_Get(moduleContext->DmfModuleBufferPool, (VOID**)&sleepIoctlBuffer, NULL); - ASSERT(NT_SUCCESS(ntStatus)); + DmfAssert(NT_SUCCESS(ntStatus)); RtlZeroMemory(sleepIoctlBuffer, sizeof(Tests_IoctlHandler_Sleep)); @@ -387,7 +390,7 @@ Tests_SelfTarget_WorkThread( PAGED_CODE(); - TraceEvents(TRACE_LEVEL_INFORMATION, DMF_TRACE, "-->%!FUNC!"); + TraceEvents(TRACE_LEVEL_INFORMATION, DMF_TRACE, "Tests_SelfTarget_WorkThread"); dmfModule = DMF_ParentModuleGet(DmfModuleThread); threadIndex = WdfObjectGet_THREAD_INDEX_CONTEXT(DmfModuleThread); @@ -595,6 +598,7 @@ Return Value: // SelfTarget (DISPATCH_LEVEL) // DMF_SelfTarget_ATTRIBUTES_INIT(&moduleAttributes); + moduleAttributes.ClientModuleInstanceName = "DmfModuleSelfTargetDispatch"; DMF_DmfModuleAdd(DmfModuleInit, &moduleAttributes, WDF_NO_OBJECT_ATTRIBUTES, @@ -604,6 +608,7 @@ Return Value: // DMF_SelfTarget_ATTRIBUTES_INIT(&moduleAttributes); moduleAttributes.PassiveLevel = TRUE; + moduleAttributes.ClientModuleInstanceName = "DmfModuleSelfTargetPassive"; DMF_DmfModuleAdd(DmfModuleInit, &moduleAttributes, WDF_NO_OBJECT_ATTRIBUTES, diff --git a/Dmf/Modules.Library/DmfModules.Library.h b/Dmf/Modules.Library/DmfModules.Library.h index 3fe3bea3..fa01a881 100644 --- a/Dmf/Modules.Library/DmfModules.Library.h +++ b/Dmf/Modules.Library/DmfModules.Library.h @@ -41,6 +41,7 @@ extern "C" // Interfaces in this Library. // #include "Dmf_Interface_ComponentFirmwareUpdate.h" +#include "Dmf_Interface_BusTarget.h" // All the Modules in this Library. // @@ -51,7 +52,6 @@ extern "C" #include "Dmf_QueuedWorkItem.h" #include "Dmf_InterruptResource.h" #include "Dmf_GpioTarget.h" -#include "Dmf_HidTarget.h" #include "Dmf_I2cTarget.h" #include "Dmf_AlertableSleep.h" #include "Dmf_NotifyUserWithEvent.h" @@ -63,25 +63,18 @@ extern "C" #include "Dmf_AcpiTarget.h" #include "Dmf_Pdo.h" #include "Dmf_Registry.h" -#include "Dmf_ResourceHub.h" #include "Dmf_SelfTarget.h" -#include "Dmf_SerialTarget.h" #include "Dmf_SmbiosWmi.h" #include "Dmf_SpiTarget.h" #include "Dmf_ThermalCoolingInterface.h" #include "Dmf_Thread.h" #include "Dmf_NotifyUserWithRequest.h" #include "Dmf_VirtualHidDeviceVhf.h" -#include "Dmf_VirtualHidMini.h" -#if defined(DMF_WDF_DRIVER) -#include "Dmf_Wmi.h" -#endif #include "Dmf_ThreadedBufferQueue.h" #include "Dmf_CmApi.h" #include "Dmf_SymbolicLinkTarget.h" #include "Dmf_DefaultTarget.h" #include "Dmf_VirtualHidKeyboard.h" -#include "Dmf_ComponentFirmwareUpdateHidTransport.h" #include "Dmf_ComponentFirmwareUpdate.h" #include "Dmf_SpbTarget.h" #include "Dmf_VirtualHidAmbientLightSensor.h" @@ -92,6 +85,18 @@ extern "C" #include "Dmf_HingeAngle.h" #include "Dmf_SimpleOrientation.h" +#if defined(DMF_WDF_DRIVER) +#include "Dmf_Wmi.h" +#endif + +#if defined(DMF_KERNEL_MODE) || defined(DMF_USER_MODE) +#include "Dmf_HidTarget.h" +#include "Dmf_ResourceHub.h" +#include "Dmf_SerialTarget.h" +#include "Dmf_VirtualHidMini.h" +#include "Dmf_ComponentFirmwareUpdateHidTransport.h" +#endif + #if defined(__cplusplus) } #endif // defined(__cplusplus) diff --git a/Dmf/Modules.Library/Dmf_HidTarget.c b/Dmf/Modules.Library/Dmf_HidTarget.c index 061df74d..c54c4801 100644 --- a/Dmf/Modules.Library/Dmf_HidTarget.c +++ b/Dmf/Modules.Library/Dmf_HidTarget.c @@ -2495,6 +2495,234 @@ Return Value: } #pragma code_seg() +_IRQL_requires_max_(PASSIVE_LEVEL) +_IRQL_requires_same_ +NTSTATUS +DMF_HidTarget_TransportAddressWrite( + _In_ DMFINTERFACE DmfInterface, + _In_ BusTransport_TransportPayload* Payload + ) +/*++ + +Routine Description: + + Does nothing + +Arguments: + + DmfInterface - Interface module handle. + Payload - Data to write. + +Return Value: + + STATUS_NOT_IMPLEMENTED for now. + +--*/ +{ + UNREFERENCED_PARAMETER(DmfInterface); + UNREFERENCED_PARAMETER(Payload); + + return STATUS_NOT_IMPLEMENTED; +} + +_IRQL_requires_max_(PASSIVE_LEVEL) +_IRQL_requires_same_ +NTSTATUS +DMF_HidTarget_TransportAddressRead( + _In_ DMFINTERFACE DmfInterface, + _In_ BusTransport_TransportPayload* Payload + ) +/*++ + +Routine Description: + + Does nothing + +Arguments: + + DmfInterface - Interface module handle. + Payload - Data to write. + +Return Value: + + STATUS_NOT_IMPLEMENTED for now. + +--*/ +{ + UNREFERENCED_PARAMETER(DmfInterface); + UNREFERENCED_PARAMETER(Payload); + + return STATUS_NOT_IMPLEMENTED; +} + +_IRQL_requires_max_(PASSIVE_LEVEL) +_IRQL_requires_same_ +NTSTATUS +DMF_HidTarget_TransportBufferWrite( + _In_ DMFINTERFACE DmfInterface, + _In_ BusTransport_TransportPayload* Payload + ) +/*++ + +Routine Description: + + Does nothing + +Arguments: + + DmfInterface - Interface module handle. + Payload - Data to write. + +Return Value: + + STATUS_NOT_IMPLEMENTED for now. + +--*/ +{ + UNREFERENCED_PARAMETER(DmfInterface); + UNREFERENCED_PARAMETER(Payload); + + return STATUS_NOT_IMPLEMENTED; +} + +_IRQL_requires_max_(PASSIVE_LEVEL) +_IRQL_requires_same_ +NTSTATUS +DMF_HidTarget_TransportBufferRead( + _In_ DMFINTERFACE DmfInterface, + _In_ BusTransport_TransportPayload* Payload + ) +/*++ + +Routine Description: + + Does nothing + +Arguments: + + DmfInterface - Interface module handle. + Payload - Data to write. + +Return Value: + + STATUS_NOT_IMPLEMENTED for now. + +--*/ +{ + UNREFERENCED_PARAMETER(DmfInterface); + UNREFERENCED_PARAMETER(Payload); + + return STATUS_NOT_IMPLEMENTED; +} + +_IRQL_requires_max_(PASSIVE_LEVEL) +_IRQL_requires_same_ +NTSTATUS +DMF_HidTarget_TransportBind( + _In_ DMFINTERFACE DmfInterface, + _In_ DMF_INTERFACE_PROTOCOL_BusTarget_BIND_DATA* ProtocolBindData, + _Out_ DMF_INTERFACE_TRANSPORT_BusTarget_BIND_DATA* TransportBindData + ) +/*++ + +Routine Description: + + Does nothing + +Arguments: + + DmfInterface - Interface module handle. + ProtocolBindData + TransportBindData + +Return Value: + + STATUS_SUCCESS + +--*/ +{ + UNREFERENCED_PARAMETER(DmfInterface); + UNREFERENCED_PARAMETER(ProtocolBindData); + UNREFERENCED_PARAMETER(TransportBindData); + + return STATUS_SUCCESS; +} + +_IRQL_requires_max_(PASSIVE_LEVEL) +_IRQL_requires_same_ +VOID +DMF_HidTarget_TransportUnbind( + _In_ DMFINTERFACE DmfInterface + ) +/*++ + +Routine Description: + + Does nothing + +Arguments: + + DmfInterface - Interface module handle. + +Return Value: + + None + +--*/ +{ + UNREFERENCED_PARAMETER(DmfInterface); +} + +_IRQL_requires_max_(PASSIVE_LEVEL) +_IRQL_requires_same_ +VOID +DMF_HidTarget_TransportPostBind( + _In_ DMFINTERFACE DmfInterface + ) +/*++ + +Routine Description: + + Does nothing + +Arguments: + + DmfInterface - Interface module handle. + +Return Value: + + None + +--*/ +{ + UNREFERENCED_PARAMETER(DmfInterface); +} + +_IRQL_requires_max_(PASSIVE_LEVEL) +_IRQL_requires_same_ +VOID +DMF_HidTarget_TransportPreUnbind( + _In_ DMFINTERFACE DmfInterface + ) +/*++ + +Routine Description: + + Does nothing + +Arguments: + + DmfInterface - Interface module handle. + +Return Value: + + None + +--*/ +{ + UNREFERENCED_PARAMETER(DmfInterface); +} + /////////////////////////////////////////////////////////////////////////////////////////////////////// // Public Calls by Client /////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -2532,6 +2760,7 @@ Return Value: NTSTATUS ntStatus; DMF_MODULE_DESCRIPTOR dmfModuleDescriptor_Hid; DMF_CALLBACKS_DMF dmfCallbacksDmf_HidTarget; + DMF_INTERFACE_TRANSPORT_BusTarget_DECLARATION_DATA BusTargetDeclarationData; PAGED_CODE(); @@ -2556,10 +2785,28 @@ Return Value: DmfModule); if (! NT_SUCCESS(ntStatus)) { - TraceEvents(TRACE_LEVEL_ERROR, - DMF_TRACE, - "DMF_ModuleCreate fails: ntStatus=%!STATUS!", - ntStatus); + TraceEvents(TRACE_LEVEL_ERROR, DMF_TRACE, "DMF_ModuleCreate fails: ntStatus=%!STATUS!", ntStatus); + goto Exit; + } + + DMF_INTERFACE_TRANSPORT_BusTarget_DESCRIPTOR_INIT(&BusTargetDeclarationData, + DMF_HidTarget_TransportPostBind, + DMF_HidTarget_TransportPreUnbind, + DMF_HidTarget_TransportBind, + DMF_HidTarget_TransportUnbind, + DMF_HidTarget_TransportAddressWrite, + DMF_HidTarget_TransportAddressRead, + DMF_HidTarget_TransportBufferWrite, + DMF_HidTarget_TransportBufferRead); + + // Add the interface to the Transport Module. + // + ntStatus = DMF_ModuleInterfaceDescriptorAdd(*DmfModule, + (DMF_INTERFACE_DESCRIPTOR*)&BusTargetDeclarationData); + + if (!NT_SUCCESS(ntStatus)) + { + TraceEvents(TRACE_LEVEL_ERROR, DMF_TRACE, "DMF_ModuleInterfaceDescriptorAdd fails: ntStatus=%!STATUS!", ntStatus); goto Exit; } @@ -3847,5 +4094,6 @@ Return Value: } #pragma code_seg() + // eof: Dmf_HidTarget.c // diff --git a/Dmf/Modules.Library/Dmf_Interface_BusTarget.c b/Dmf/Modules.Library/Dmf_Interface_BusTarget.c new file mode 100644 index 00000000..276dad0e --- /dev/null +++ b/Dmf/Modules.Library/Dmf_Interface_BusTarget.c @@ -0,0 +1,409 @@ +/*++ + + Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + Dmf_Interface_BusTarget.c + +Abstract: + + Implements an Interface Contract between a Protocol and BusTargets (Transport). + The protocol layer shouldnt not know the below transport layer that it is attached to. + All it has to do is call the interface functions which routes the calls to the + right Transport. + +Environment: + + Kernel-mode Driver Framework + User-mode Driver Framework + +--*/ + +// DMF and this Module's Library specific definitions. +// +#include "DmfModule.h" +#include "DmfModules.Library.h" +#include "DmfModules.Library.Trace.h" +#include "Dmf_Interface_BusTarget.tmh" + +/////////////////////////////////////////////////////////////////////////////////////////////////////// +// Interface Validation +/////////////////////////////////////////////////////////////////////////////////////////////////////// +// + +_IRQL_requires_max_(PASSIVE_LEVEL) +VOID +DMF_INTERFACE_PROTOCOL_BusTarget_DESCRIPTOR_INIT( + _Out_ DMF_INTERFACE_PROTOCOL_BusTarget_DECLARATION_DATA* ProtocolDeclarationData, + _In_ EVT_DMF_INTERFACE_ProtocolBind* EvtProtocolBind, + _In_ EVT_DMF_INTERFACE_ProtocolUnbind* EvtProtocolUnbind, + _In_opt_ EVT_DMF_INTERFACE_PostBind* EvtPostBind, + _In_opt_ EVT_DMF_INTERFACE_PreUnbind* EvtPreUnbind + ) +/*++ + +Routine Description: + + Ensures all required callbacks are provided by Protocol Module and populates the Declaration Data structure. + +Arguments: + + ProtocolDeclarationData - The Protocol's declaration data. + EvtProtocolBind - The Bind callback. Must be provided by all Protocol Modules. + EvtProtocolUnBind - The Unbind callback. Must be provided by all Protocol Modules. + EvtPostBind - Optional Post bind callback. + EvtPreUnbind - Optional Pre Unbind callback. + EvtBusTargetProtocolCallback1 - This callback is unique to the BusTarget and must be provided by any Protocol Module of this Interface. + +Returns: + + None. +--*/ +{ + DMF_INTERFACE_PROTOCOL_DESCRIPTOR_INIT(&(ProtocolDeclarationData->DmfProtocolDescriptor), + "BusTarget", + DMF_INTERFACE_PROTOCOL_BusTarget_DECLARATION_DATA, + EvtProtocolBind, + EvtProtocolUnbind, + EvtPostBind, + EvtPreUnbind); +} + +_IRQL_requires_max_(PASSIVE_LEVEL) +VOID +DMF_INTERFACE_TRANSPORT_BusTarget_DESCRIPTOR_INIT( + _Out_ DMF_INTERFACE_TRANSPORT_BusTarget_DECLARATION_DATA* TransportDeclarationData, + _In_opt_ EVT_DMF_INTERFACE_PostBind* EvtPostBind, + _In_opt_ EVT_DMF_INTERFACE_PreUnbind* EvtPreUnbind, + _In_ DMF_INTERFACE_BusTarget_TransportBind* BusTargetTransportBind, + _In_ DMF_INTERFACE_BusTarget_TransportUnbind* BusTargetTransportUnbind, + _In_ DMF_INTERFACE_BusTarget_AddressWrite* BusTarget_AddressWrite, + _In_ DMF_INTERFACE_BusTarget_AddressRead* BusTarget_AddressRead, + _In_ DMF_INTERFACE_BusTarget_BufferWrite* BusTarget_BufferWrite, + _In_ DMF_INTERFACE_BusTarget_BufferRead* BusTarget_BufferRead + ) +/*++ + +Routine Description: + + Ensures all required methods are provided by Transport Module and populates the Declaration Data structure. + +Arguments: + + TransportDeclarationData - The Transport's declaration data. + EvtPostBind - Optional Post bind callback. + EvtPreUnbind - Optional Pre Unbind callback. + BusTargetTransportBind - Transport's Bind method. + BusTargetTransportUnbind - Transport's Unbind method. + BusTargetTransportMethod - Transport's method. + +Return Value: + + None. +--*/ +{ + DMF_INTERFACE_TRANSPORT_DESCRIPTOR_INIT(&(TransportDeclarationData->DmfTransportDescriptor), + "BusTarget", + DMF_INTERFACE_TRANSPORT_BusTarget_DECLARATION_DATA, + EvtPostBind, + EvtPreUnbind); + + TransportDeclarationData->DMF_BusTarget_TransportBind = BusTargetTransportBind; + TransportDeclarationData->DMF_BusTarget_TransportUnbind = BusTargetTransportUnbind; + TransportDeclarationData->DMF_BusTarget_AddressWrite = BusTarget_AddressWrite; + TransportDeclarationData->DMF_BusTarget_AddressRead = BusTarget_AddressRead; + TransportDeclarationData->DMF_BusTarget_BufferWrite = BusTarget_BufferWrite; + TransportDeclarationData->DMF_BusTarget_BufferRead = BusTarget_BufferRead; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////// +// Interface Protocol Bind/Unbind +/////////////////////////////////////////////////////////////////////////////////////////////////////// +// + +NTSTATUS +DMF_BusTarget_TransportBind( + _In_ DMFINTERFACE DmfInterface, + _In_ DMF_INTERFACE_PROTOCOL_BusTarget_BIND_DATA* ProtocolBindData, + _Out_ DMF_INTERFACE_TRANSPORT_BusTarget_BIND_DATA* TransportBindData + ) +/*++ + +Routine Description: + + Registers Protocol Module with the Transport Module. This is called by Protocol Module. + +Arguments: + + DmfInterface - Interface handle. + ProtocolBindData - Bind time data provided by Protocol to the Transport. + TransportBindData - Bind time data provided by Transport to the Protocol. + +Return Value: + + NTSTATUS + +--*/ +{ + NTSTATUS ntStatus; + DMF_INTERFACE_TRANSPORT_BusTarget_DECLARATION_DATA* transportData; + + transportData = (DMF_INTERFACE_TRANSPORT_BusTarget_DECLARATION_DATA*)DMF_InterfaceTransportDeclarationDataGet(DmfInterface); + + DmfAssert(transportData != NULL); + + TraceEvents(TRACE_LEVEL_INFORMATION, DMF_TRACE, "DMF_BusTarget_TransportBind"); + + ntStatus = transportData->DMF_BusTarget_TransportBind(DmfInterface, + ProtocolBindData, + TransportBindData); + + if (!NT_SUCCESS(ntStatus)) + { + TraceEvents(TRACE_LEVEL_ERROR, DMF_TRACE, "DMF_BusTarget_TransportBind fails: ntStatus=%!STATUS!", ntStatus); + goto Exit; + } + +Exit: + + FuncExit(DMF_TRACE, "ntStatus=%!STATUS!", ntStatus); + + return ntStatus; +} + +VOID +DMF_BusTarget_TransportUnbind( + _In_ DMFINTERFACE DmfInterface + ) +/*++ + +Routine Description: + + Unregisters the given Protocol Module from the Transport Module. This is called by Protocol Module. + +Arguments: + + DmfInterfaceTransportModule - The given Transport Module. + DmfInterfaceProtocolModule - The given Protocol Module. + +Return Value: + + NTSTATUS + +--*/ +{ + DMF_INTERFACE_TRANSPORT_BusTarget_DECLARATION_DATA* transportData; + + transportData = (DMF_INTERFACE_TRANSPORT_BusTarget_DECLARATION_DATA*)DMF_InterfaceTransportDeclarationDataGet(DmfInterface); + + DmfAssert(transportData != NULL); + + TraceEvents(TRACE_LEVEL_INFORMATION, DMF_TRACE, "BusTarget_Unbind"); + + transportData->DMF_BusTarget_TransportUnbind(DmfInterface); + + return; +} + +_IRQL_requires_max_(PASSIVE_LEVEL) +_IRQL_requires_same_ +NTSTATUS +DMF_BusTarget_AddressWrite( + _In_ DMFINTERFACE DmfInterface, + _In_ BusTransport_TransportPayload* Payload + ) +/*++ + +Routine Description: + + Unregisters the given Protocol Module from the Transport Module. This is called by Protocol Module. + +Arguments: + + DmfInterfaceTransportModule - The given Transport Module. + DmfInterfaceProtocolModule - The given Protocol Module. + +Return Value: + + NTSTATUS + +--*/ +{ + NTSTATUS ntStatus; + DMF_INTERFACE_TRANSPORT_BusTarget_DECLARATION_DATA* transportData; + + transportData = (DMF_INTERFACE_TRANSPORT_BusTarget_DECLARATION_DATA*)DMF_InterfaceTransportDeclarationDataGet(DmfInterface); + + DmfAssert(transportData != NULL); + + ntStatus = transportData->DMF_BusTarget_AddressWrite(DmfInterface, + Payload); + + if (!NT_SUCCESS(ntStatus)) + { + TraceEvents(TRACE_LEVEL_ERROR, DMF_TRACE, "DMF_BusTarget_AddressWrite fails: ntStatus=%!STATUS!", ntStatus); + goto Exit; + } + +Exit: + + FuncExit(DMF_TRACE, "ntStatus=%!STATUS!", ntStatus); + + return ntStatus; +} + +_IRQL_requires_max_(PASSIVE_LEVEL) +_IRQL_requires_same_ +NTSTATUS +Dmf_BusTarget_AddressRead( + _In_ DMFINTERFACE DmfInterface, + _In_ BusTransport_TransportPayload* Payload + ) +/*++ + +Routine Description: + + Unregisters the given Protocol Module from the Transport Module. This is called by Protocol Module. + +Arguments: + + DmfInterfaceTransportModule - The given Transport Module. + DmfInterfaceProtocolModule - The given Protocol Module. + +Return Value: + + NTSTATUS + +--*/ +{ + NTSTATUS ntStatus; + DMF_INTERFACE_TRANSPORT_BusTarget_DECLARATION_DATA* transportData; + + transportData = (DMF_INTERFACE_TRANSPORT_BusTarget_DECLARATION_DATA*)DMF_InterfaceTransportDeclarationDataGet(DmfInterface); + + DmfAssert(transportData != NULL); + + ntStatus = transportData->DMF_BusTarget_AddressRead(DmfInterface, + Payload); + + if (!NT_SUCCESS(ntStatus)) + { + TraceEvents(TRACE_LEVEL_ERROR, DMF_TRACE, "DMF_BusTarget_AddressRead fails: ntStatus=%!STATUS!", ntStatus); + goto Exit; + } + +Exit: + + FuncExit(DMF_TRACE, "ntStatus=%!STATUS!", ntStatus); + + return ntStatus; +} + +_IRQL_requires_max_(PASSIVE_LEVEL) +_IRQL_requires_same_ +NTSTATUS +Dmf_BusTarget_BufferWrite( + _In_ DMFINTERFACE DmfInterface, + _In_ BusTransport_TransportPayload* Payload + ) +/*++ + +Routine Description: + + Unregisters the given Protocol Module from the Transport Module. This is called by Protocol Module. + +Arguments: + + DmfInterfaceTransportModule - The given Transport Module. + DmfInterfaceProtocolModule - The given Protocol Module. + +Return Value: + + NTSTATUS + +--*/ +{ + NTSTATUS ntStatus; + DMF_INTERFACE_TRANSPORT_BusTarget_DECLARATION_DATA* transportData; + + transportData = (DMF_INTERFACE_TRANSPORT_BusTarget_DECLARATION_DATA*)DMF_InterfaceTransportDeclarationDataGet(DmfInterface); + + DmfAssert(transportData != NULL); + + ntStatus = transportData->DMF_BusTarget_BufferWrite(DmfInterface, + Payload); + + if (!NT_SUCCESS(ntStatus)) + { + TraceEvents(TRACE_LEVEL_ERROR, DMF_TRACE, "DMF_BusTarget_BufferWrite fails: ntStatus=%!STATUS!", ntStatus); + goto Exit; + } + +Exit: + + FuncExit(DMF_TRACE, "ntStatus=%!STATUS!", ntStatus); + + return ntStatus; +} + +_IRQL_requires_max_(PASSIVE_LEVEL) +_IRQL_requires_same_ +NTSTATUS +Dmf_BusTarget_BufferRead( + _In_ DMFINTERFACE DmfInterface, + _In_ BusTransport_TransportPayload* Payload + ) +/*++ + +Routine Description: + + Unregisters the given Protocol Module from the Transport Module. This is called by Protocol Module. + +Arguments: + + DmfInterfaceTransportModule - The given Transport Module. + DmfInterfaceProtocolModule - The given Protocol Module. + +Return Value: + + NTSTATUS + +--*/ +{ + NTSTATUS ntStatus; + DMF_INTERFACE_TRANSPORT_BusTarget_DECLARATION_DATA* transportData; + + transportData = (DMF_INTERFACE_TRANSPORT_BusTarget_DECLARATION_DATA*)DMF_InterfaceTransportDeclarationDataGet(DmfInterface); + + DmfAssert(transportData != NULL); + + ntStatus = transportData->DMF_BusTarget_BufferRead(DmfInterface, + Payload); + + if (!NT_SUCCESS(ntStatus)) + { + TraceEvents(TRACE_LEVEL_ERROR, DMF_TRACE, "DMF_BusTarget_BufferRead fails: ntStatus=%!STATUS!", ntStatus); + goto Exit; + } + +Exit: + + FuncExit(DMF_TRACE, "ntStatus=%!STATUS!", ntStatus); + + return ntStatus; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////// +// Interface Methods +/////////////////////////////////////////////////////////////////////////////////////////////////////// +// + + +/////////////////////////////////////////////////////////////////////////////////////////////////////// +// Interface Callbacks +/////////////////////////////////////////////////////////////////////////////////////////////////////// +// + +// eof: Dmf_Interface_BusTarget.c +// diff --git a/Dmf/Modules.Library/Dmf_Interface_BusTarget.h b/Dmf/Modules.Library/Dmf_Interface_BusTarget.h new file mode 100644 index 00000000..e25bb77d --- /dev/null +++ b/Dmf/Modules.Library/Dmf_Interface_BusTarget.h @@ -0,0 +1,218 @@ +/*++ + + Copyright (c) Microsoft Corporation. All Rights Reserved. + Licensed under the MIT license. + +Module Name: + + Dmf_Interface_BusTarget.h + +Abstract: + + Implements an Interface Contract between a PowerMeterDevice (Protocol) and BusTargets + (Transport). The protocol layer shouldnt not know the below transport layer that it is + attached to. All it has to do is call the interface functions which routes the calls to the + right Transport based on INIT. + +Environment: + + Kernel-mode Driver Framework + User-mode Driver Framework + +--*/ + +#pragma once + +typedef struct +{ + ULONG Message; + union + { + struct + { + UCHAR* Address; + ULONG AddressLength; + UCHAR* Buffer; + ULONG BufferLength; + } AddressWrite; + + struct + { + UCHAR* Address; + ULONG AddressLength; + UCHAR* Buffer; + ULONG BufferLength; + } AddressRead; + + struct + { + UCHAR* Buffer; + ULONG BufferLength; + } BufferWrite; + + struct + { + UCHAR* Buffer; + ULONG BufferLength; + } BufferRead; + }; +} BusTransport_TransportPayload; + +// TransportCall Interface to Chip Module. +// + +// Bind Time Data. +// --------------- +// +// Data provided by the Protocol Module. +// +typedef struct _DMF_INTERFACE_PROTOCOL_BusTarget_BIND_DATA +{ + // Dummy for now + // + ULONG Dummy; +} DMF_INTERFACE_PROTOCOL_BusTarget_BIND_DATA; + +// Data provided by the Transport Module. +// +typedef struct _DMF_INTERFACE_TRANSPORT_BusTarget_BIND_DATA +{ + // Dummy for now + // + ULONG Dummy; +} DMF_INTERFACE_TRANSPORT_BusTarget_BIND_DATA; + +// Data that fully describes this BusTarget. +// +typedef struct _DMF_INTERFACE_PROTOCOL_BusTarget_DECLARATION_DATA +{ + // The Protocol Interface Descriptor. + // Every Interface must have this as the first member of its Protocol Declaration Data. + // + DMF_INTERFACE_PROTOCOL_DESCRIPTOR DmfProtocolDescriptor; + +} DMF_INTERFACE_PROTOCOL_BusTarget_DECLARATION_DATA; + +// Methods used to initialize Protocol's Declaration Data. +// +_IRQL_requires_max_(PASSIVE_LEVEL) +VOID +DMF_INTERFACE_PROTOCOL_BusTarget_DESCRIPTOR_INIT( + _Out_ DMF_INTERFACE_PROTOCOL_BusTarget_DECLARATION_DATA* ProtocolDeclarationData, + _In_ EVT_DMF_INTERFACE_ProtocolBind* EvtProtocolBind, + _In_ EVT_DMF_INTERFACE_ProtocolUnbind* EvtProtocolUnbind, + _In_opt_ EVT_DMF_INTERFACE_PostBind* EvtPostBind, + _In_opt_ EVT_DMF_INTERFACE_PreUnbind* EvtPreUnbind + ); + +// Methods provided by Transport Module. +// +typedef +_IRQL_requires_max_(PASSIVE_LEVEL) +_IRQL_requires_same_ +NTSTATUS +DMF_INTERFACE_BusTarget_TransportBind( + _In_ DMFINTERFACE DmfInterface, + _In_ DMF_INTERFACE_PROTOCOL_BusTarget_BIND_DATA* ProtocolBindData, + _Out_ DMF_INTERFACE_TRANSPORT_BusTarget_BIND_DATA* TransportBindData + ); + +typedef +_IRQL_requires_max_(PASSIVE_LEVEL) +_IRQL_requires_same_ +VOID +DMF_INTERFACE_BusTarget_TransportUnbind( + _In_ DMFINTERFACE DmfInterface + ); + +// Transport Method that is called from the client. +// +typedef +_IRQL_requires_max_(PASSIVE_LEVEL) +_IRQL_requires_same_ +NTSTATUS +DMF_INTERFACE_BusTarget_AddressWrite( + _In_ DMFINTERFACE DmfInterface, + _In_ BusTransport_TransportPayload* Payload + ); + +typedef +_IRQL_requires_max_(PASSIVE_LEVEL) +_IRQL_requires_same_ +NTSTATUS +DMF_INTERFACE_BusTarget_AddressRead( + _In_ DMFINTERFACE DmfInterface, + _In_ BusTransport_TransportPayload* Payload + ); + +typedef +_IRQL_requires_max_(PASSIVE_LEVEL) +_IRQL_requires_same_ +NTSTATUS +DMF_INTERFACE_BusTarget_BufferWrite( + _In_ DMFINTERFACE DmfInterface, + _In_ BusTransport_TransportPayload* Payload + ); + +typedef +_IRQL_requires_max_(PASSIVE_LEVEL) +_IRQL_requires_same_ +NTSTATUS +DMF_INTERFACE_BusTarget_BufferRead( + _In_ DMFINTERFACE DmfInterface, + _In_ BusTransport_TransportPayload* Payload + ); + +// Data that fully describes this Transport. +// + +typedef struct _DMF_INTERFACE_TRANSPORT_BusTarget_DECLARATION_DATA +{ + // The Transport Interface Descriptor. + // Every Interface must have this as the first member of its Transport Declaration Data. + // + DMF_INTERFACE_TRANSPORT_DESCRIPTOR DmfTransportDescriptor; + // Stores methods implemented by this Interface Transport. + // + DMF_INTERFACE_BusTarget_TransportBind* DMF_BusTarget_TransportBind; + DMF_INTERFACE_BusTarget_TransportUnbind* DMF_BusTarget_TransportUnbind; + DMF_INTERFACE_BusTarget_AddressWrite* DMF_BusTarget_AddressWrite; + DMF_INTERFACE_BusTarget_AddressRead* DMF_BusTarget_AddressRead; + DMF_INTERFACE_BusTarget_BufferWrite* DMF_BusTarget_BufferWrite; + DMF_INTERFACE_BusTarget_BufferRead* DMF_BusTarget_BufferRead; +} DMF_INTERFACE_TRANSPORT_BusTarget_DECLARATION_DATA; + +// Methods used to initialize Transport's Declaration Data. +// +_IRQL_requires_max_(PASSIVE_LEVEL) +VOID +DMF_INTERFACE_TRANSPORT_BusTarget_DESCRIPTOR_INIT( + _Out_ DMF_INTERFACE_TRANSPORT_BusTarget_DECLARATION_DATA* TransportDeclarationData, + _In_opt_ EVT_DMF_INTERFACE_PostBind* EvtPostBind, + _In_opt_ EVT_DMF_INTERFACE_PreUnbind* EvtPreUnbind, + _In_ DMF_INTERFACE_BusTarget_TransportBind* BusTargetTransportBind, + _In_ DMF_INTERFACE_BusTarget_TransportUnbind* BusTargetTransportUnbind, + _In_ DMF_INTERFACE_BusTarget_AddressWrite* BusTarget_AddressWrite, + _In_ DMF_INTERFACE_BusTarget_AddressRead* BusTarget_AddressRead, + _In_ DMF_INTERFACE_BusTarget_BufferWrite* BusTarget_BufferWrite, + _In_ DMF_INTERFACE_BusTarget_BufferRead* BusTarget_BufferRead + ); + +// Methods exposed to Protocol. +// ---------------------------- +// +DMF_INTERFACE_BusTarget_TransportBind DMF_BusTarget_TransportBind; +DMF_INTERFACE_BusTarget_TransportUnbind DMF_BusTarget_TransportUnbind; +DMF_INTERFACE_BusTarget_AddressWrite DMF_BusTarget_AddressWrite; +DMF_INTERFACE_BusTarget_AddressRead Dmf_BusTarget_AddressRead; +DMF_INTERFACE_BusTarget_BufferWrite Dmf_BusTarget_BufferWrite; +DMF_INTERFACE_BusTarget_BufferRead Dmf_BusTarget_BufferRead; + +// This macro defines the BusTargetProtocolDeclarationDataGet and BusTargetTransportDeclarationDataGet. +// Call this macro after the DMF_INTERFACE_PROTOCOL_BusTarget_DECLARATION_DATA and +// DMF_INTERFACE_TRANSPORT_BusTarget_DECLARATION_DATA are defined. +// +DECLARE_DMF_INTERFACE(BusTarget); + +// eof: Dmf_Interface_BusTarget.h +// \ No newline at end of file diff --git a/Dmf/Modules.Library/Dmf_MobileBroadband.cpp b/Dmf/Modules.Library/Dmf_MobileBroadband.cpp index a8ba4d90..7ff735ec 100644 --- a/Dmf/Modules.Library/Dmf_MobileBroadband.cpp +++ b/Dmf/Modules.Library/Dmf_MobileBroadband.cpp @@ -1014,7 +1014,7 @@ Return Value: --*/ { -NTSTATUS ntStatus; + NTSTATUS ntStatus; DMF_CONTEXT_MobileBroadband* moduleContext; PAGED_CODE(); @@ -1093,6 +1093,7 @@ NTSTATUS ntStatus; auto antenna = moduleContext->ModemDevice->sarManager.Antennas().GetAt(antennaIndex); antennas.push_back({antenna.AntennaIndex(), AntennaBackOffTableIndex[antennaIndex]}); + TraceEvents(TRACE_LEVEL_INFORMATION, DMF_TRACE, "antenna index from modem is %d", antenna.AntennaIndex()); } TraceEvents(TRACE_LEVEL_INFORMATION, DMF_TRACE, "Map Antenna No.%d back off index to %d success", diff --git a/Dmf/Modules.Library/Dmf_SpbTarget.c b/Dmf/Modules.Library/Dmf_SpbTarget.c index 71622825..34117638 100644 --- a/Dmf/Modules.Library/Dmf_SpbTarget.c +++ b/Dmf/Modules.Library/Dmf_SpbTarget.c @@ -717,6 +717,268 @@ Return Value: } #pragma code_seg() +_IRQL_requires_max_(PASSIVE_LEVEL) +_IRQL_requires_same_ +NTSTATUS +DMF_SpbTarget_TransportAddressWrite( + _In_ DMFINTERFACE DmfInterface, + _In_ BusTransport_TransportPayload* Payload + ) +/*++ + +Routine Description: + + Does nothing + +Arguments: + + DmfInterface - Interface module handle. + Payload - Data to write. + +Return Value: + + STATUS_NOT_IMPLEMENTED for now. + +--*/ +{ + UNREFERENCED_PARAMETER(DmfInterface); + UNREFERENCED_PARAMETER(Payload); + + return STATUS_NOT_IMPLEMENTED; +} + +_IRQL_requires_max_(PASSIVE_LEVEL) +_IRQL_requires_same_ +NTSTATUS +DMF_SpbTarget_TransportAddressRead( + _In_ DMFINTERFACE DmfInterface, + _In_ BusTransport_TransportPayload* Payload + ) +/*++ + +Routine Description: + + Write and read data from Spb. + +Arguments: + + DmfInterface - Interface module handle. + Payload - Data to write and read + +Return Value: + + ntStatus + +--*/ +{ + NTSTATUS ntStatus; + DMFMODULE BusTransportModule; + + BusTransportModule = DMF_InterfaceTransportModuleGet(DmfInterface); + + ntStatus = DMF_SpbTarget_BufferWriteRead(BusTransportModule, + Payload->AddressRead.Address, + Payload->AddressRead.AddressLength, + Payload->AddressRead.Buffer, + Payload->AddressRead.BufferLength); + + if (!NT_SUCCESS(ntStatus)) + { + TraceEvents(TRACE_LEVEL_ERROR, DMF_TRACE, "DMF_SpbTarget_BufferWriteRead fails: ntStatus=%!STATUS!", ntStatus); + goto Exit; + } + +Exit: + + FuncExit(DMF_TRACE, "ntStatus=%!STATUS!", ntStatus); + + return(ntStatus); +} + +_IRQL_requires_max_(PASSIVE_LEVEL) +_IRQL_requires_same_ +NTSTATUS +DMF_SpbTarget_TransportBufferWrite( + _In_ DMFINTERFACE DmfInterface, + _In_ BusTransport_TransportPayload* Payload + ) +/*++ + +Routine Description: + + Write and read data from Spb. + +Arguments: + + DmfInterface - Interface module handle. + Payload - Data to write. + +Return Value: + + ntStatus + +--*/ +{ + NTSTATUS ntStatus; + DMFMODULE BusTransportModule; + + BusTransportModule = DMF_InterfaceTransportModuleGet(DmfInterface); + + ntStatus = DMF_SpbTarget_BufferWrite(BusTransportModule, + Payload->BufferWrite.Buffer, + Payload->BufferWrite.BufferLength); + + if (!NT_SUCCESS(ntStatus)) + { + TraceEvents(TRACE_LEVEL_ERROR, DMF_TRACE, "DMF_SpbTarget_BufferWrite fails: ntStatus=%!STATUS!", ntStatus); + goto Exit; + } + +Exit: + + FuncExit(DMF_TRACE, "ntStatus=%!STATUS!", ntStatus); + + return(ntStatus); +} + +_IRQL_requires_max_(PASSIVE_LEVEL) +_IRQL_requires_same_ +NTSTATUS +DMF_SpbTarget_TransportBufferRead( + _In_ DMFINTERFACE DmfInterface, + _In_ BusTransport_TransportPayload* Payload + ) +/*++ + +Routine Description: + + Does nothing + +Arguments: + + DmfInterface - Interface module handle. + Payload - Data to write. + +Return Value: + + STATUS_NOT_IMPLEMENTED for now. + +--*/ +{ + UNREFERENCED_PARAMETER(DmfInterface); + UNREFERENCED_PARAMETER(Payload); + + return STATUS_NOT_IMPLEMENTED; +} + +_IRQL_requires_max_(PASSIVE_LEVEL) +_IRQL_requires_same_ +NTSTATUS +DMF_SpbBusTarget_TransportBind( + _In_ DMFINTERFACE DmfInterface, + _In_ DMF_INTERFACE_PROTOCOL_BusTarget_BIND_DATA* ProtocolBindData, + _Out_ DMF_INTERFACE_TRANSPORT_BusTarget_BIND_DATA* TransportBindData + ) +/*++ + +Routine Description: + + Does nothing + +Arguments: + + DmfInterface - Interface module handle. + ProtocolBindData + TransportBindData + +Return Value: + + STATUS_SUCCESS + +--*/ +{ + UNREFERENCED_PARAMETER(DmfInterface); + UNREFERENCED_PARAMETER(ProtocolBindData); + UNREFERENCED_PARAMETER(TransportBindData); + + return STATUS_SUCCESS; +} + +_IRQL_requires_max_(PASSIVE_LEVEL) +_IRQL_requires_same_ +VOID +DMF_SpbBusTarget_TransportUnbind( + _In_ DMFINTERFACE DmfInterface + ) +/*++ + +Routine Description: + + Does nothing + +Arguments: + + DmfInterface - Interface module handle. + +Return Value: + + None + +--*/ +{ + UNREFERENCED_PARAMETER(DmfInterface); +} + +_IRQL_requires_max_(PASSIVE_LEVEL) +_IRQL_requires_same_ +VOID +DMF_SpbTarget_TransportPostBind( + _In_ DMFINTERFACE DmfInterface + ) +/*++ + +Routine Description: + + Does nothing + +Arguments: + + DmfInterface - Interface module handle. + +Return Value: + + None + +--*/ +{ + UNREFERENCED_PARAMETER(DmfInterface); +} + +_IRQL_requires_max_(PASSIVE_LEVEL) +_IRQL_requires_same_ +VOID +DMF_SpbTarget_TransportPreUnbind( + _In_ DMFINTERFACE DmfInterface + ) +/*++ + +Routine Description: + + Does nothing + +Arguments: + + DmfInterface - Interface module handle. + +Return Value: + + None + +--*/ +{ + UNREFERENCED_PARAMETER(DmfInterface); +} + /////////////////////////////////////////////////////////////////////////////////////////////////////// // Public Calls by Client /////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -754,6 +1016,7 @@ Return Value: NTSTATUS ntStatus; DMF_MODULE_DESCRIPTOR dmfModuleDescriptor_SpbTarget; DMF_CALLBACKS_DMF dmfCallbacksDmf_SpbTarget; + DMF_INTERFACE_TRANSPORT_BusTarget_DECLARATION_DATA BusTargetDeclarationData; PAGED_CODE(); @@ -782,6 +1045,26 @@ Return Value: goto Exit; } + DMF_INTERFACE_TRANSPORT_BusTarget_DESCRIPTOR_INIT(&BusTargetDeclarationData, + DMF_SpbTarget_TransportPostBind, + DMF_SpbTarget_TransportPreUnbind, + DMF_SpbBusTarget_TransportBind, + DMF_SpbBusTarget_TransportUnbind, + DMF_SpbTarget_TransportAddressWrite, + DMF_SpbTarget_TransportAddressRead, + DMF_SpbTarget_TransportBufferWrite, + DMF_SpbTarget_TransportBufferRead); + + // Add the interface to the Transport Module. + // + ntStatus = DMF_ModuleInterfaceDescriptorAdd(*DmfModule, + (DMF_INTERFACE_DESCRIPTOR*)&BusTargetDeclarationData); + if (!NT_SUCCESS(ntStatus)) + { + TraceEvents(TRACE_LEVEL_ERROR, DMF_TRACE, "DMF_ModuleInterfaceDescriptorAdd fails: ntStatus=%!STATUS!", ntStatus); + goto Exit; + } + Exit: return(ntStatus); @@ -1221,7 +1504,6 @@ Return Value: FuncExitVoid(DMF_TRACE); } -#pragma code_seg() // eof: Dmf_SpbTarget.c //