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 //