Sample Code
windows driver samples/ Windows Filtering Platform Sample/ C++/ syslib/ HelperFunctions_WorkItems.cpp/
//////////////////////////////////////////////////////////////////////////////////////////////////// // // Copyright (c) 2012 Microsoft Corporation. All Rights Reserved. // // Module Name: // HelperFunctions_WorkItems.cpp // // Abstract: // This module contains kernel helper functions that assist with IO_WORKITEM routines. // // Naming Convention: // // <Module><Object><Action> // // i.e. // // KrnlHlprWorkItemQueue // // <Module> // KrnlHlpr - Function is located in syslib\ and applies to kernel mode. // <Object> // WorkItem - Function pertains to work item routines. // WorkItemData - Function pertains to WORKITEM_DATA objects. // <Action> // { // Create - Function allocates and fills memory. // Destroy - Function cleans up and frees memory. // Populate - Function fills memory with values // Purge - Function cleans up values // Queue - Function will take a reference on an object // Sleep - Function performs no operations for a set period. // } // // Private Functions: // // Public Functions: // KrnlHlprWorkItemDataCreate(), // KrnlHlprWorkItemDataDestroy(), // KrnlHlprWorkItemDataPopulate(), // KrnlHlprWorkItemDataPurge(), // KrnlHlprWorkItemQueue(), // KrnlHlprWorkItemSleep(), // // Author: // Dusty Harper (DHarper) // // Revision History: // // [ Month ][Day] [Year] - [Revision]-[ Comments ] // May 01, 2010 - 1.0 - Creation // //////////////////////////////////////////////////////////////////////////////////////////////////// #include "HelperFunctions_Include.h" /// . #include "HelperFunctions_WorkItems.tmh" /// $(OBJ_PATH)\$(O)\ /** @kernel_helper_function="KrnlHlprWorkItemDataPurge" Purpose: Cleanup a WORKITEM_DATA object. <br> <br> Notes: <br> <br> MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/FF549133.aspx <br> */ _IRQL_requires_min_(PASSIVE_LEVEL) _IRQL_requires_max_(DISPATCH_LEVEL) _IRQL_requires_same_ inline VOID KrnlHlprWorkItemDataPurge(_Inout_ WORKITEM_DATA* pWorkItemData) { #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " ---> KrnlHlprWorkItemDataPurge()\n"); #endif /// DBG NT_ASSERT(pWorkItemData); if(pWorkItemData->pIOWorkItem) IoFreeWorkItem(pWorkItemData->pIOWorkItem); RtlZeroMemory(pWorkItemData, sizeof(WORKITEM_DATA)); #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " <--- KrnlHlprWorkItemDataPurge()\n"); #endif /// DBG return; } /** @kernel_helper_function="KrnlHlprWorkItemDataDestroy" Purpose: Cleanup and free a WORKITEM_DATA object. <br> <br> Notes: <br> <br> MSDN_Ref: <br> */ _At_(*ppWorkItemData, _Pre_ _Notnull_) _At_(*ppWorkItemData, _Post_ _Null_ __drv_freesMem(Pool)) _IRQL_requires_min_(PASSIVE_LEVEL) _IRQL_requires_max_(DISPATCH_LEVEL) _IRQL_requires_same_ _Success_(*ppWorkItemData == 0) inline VOID KrnlHlprWorkItemDataDestroy(_Inout_ WORKITEM_DATA** ppWorkItemData) { #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " ---> KrnlHlprWorkItemDataDestroy()\n"); #endif /// DBG NT_ASSERT(ppWorkItemData); if(*ppWorkItemData) { KrnlHlprWorkItemDataPurge(*ppWorkItemData); HLPR_DELETE(*ppWorkItemData, WFPSAMPLER_SYSLIB_TAG); } #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " <--- KrnlHlprWorkItemDataDestroy()\n"); #endif /// DBG return; } /** @kernel_helper_function="KrnlHlprWorkItemDataPopulate" Purpose: Populates a WORKITEM_DATA object with the classifyData, injectionData, PIOWorkItem, and context supplied. <br> <br> Notes: <br> <br> MSDN_Ref: <br> */ _IRQL_requires_min_(PASSIVE_LEVEL) _IRQL_requires_max_(DISPATCH_LEVEL) _IRQL_requires_same_ inline VOID KrnlHlprWorkItemDataPopulate(_Inout_ WORKITEM_DATA* pWorkItemData, _In_ CLASSIFY_DATA* pClassifyData, _In_opt_ INJECTION_DATA* pInjectionData, /* 0 */ _In_opt_ PIO_WORKITEM pIOWorkItem, /* 0 */ _In_opt_ VOID* pContext) /* 0 */ { #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " ---> KrnlHlprWorkItemDataPopulate()\n"); #endif /// DBG NT_ASSERT(pWorkItemData); NT_ASSERT(pClassifyData); pWorkItemData->pIOWorkItem = pIOWorkItem; pWorkItemData->pClassifyData = pClassifyData; pWorkItemData->pInjectionData = pInjectionData; pWorkItemData->pContext = pContext; #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " <--- KrnlHlprWorkItemDataPopulate()\n"); #endif /// DBG return; } /** @kernel_helper_function="KrnlHlprWorkItemDataPopulate" Purpose: Populates a WORKITEM_DATA object with the classifyData, pendData, PIOWorkItem, and context supplied. <br> <br> Notes: <br> <br> MSDN_Ref: <br> */ _IRQL_requires_min_(PASSIVE_LEVEL) _IRQL_requires_max_(DISPATCH_LEVEL) _IRQL_requires_same_ inline VOID KrnlHlprWorkItemDataPopulate(_Inout_ WORKITEM_DATA* pWorkItemData, _In_ CLASSIFY_DATA* pClassifyData, _In_ PEND_DATA* pPendData, _In_opt_ PIO_WORKITEM pIOWorkItem, /* 0 */ _In_opt_ VOID* pContext) /* 0 */ { #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " ---> KrnlHlprWorkItemDataPopulate()\n"); #endif /// DBG NT_ASSERT(pWorkItemData); NT_ASSERT(pClassifyData); NT_ASSERT(pPendData); pWorkItemData->pIOWorkItem = pIOWorkItem; pWorkItemData->pClassifyData = pClassifyData; pWorkItemData->pPendData = pPendData; pWorkItemData->pContext = pContext; #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " <--- KrnlHlprWorkItemDataPopulate()\n"); #endif /// DBG return; } /** @kernel_helper_function="KrnlHlprWorkItemDataPopulate" Purpose: Populates a WORKITEM_DATA object with the classifyData, redirectData, PIOWorkItem, and context supplied. <br> <br> Notes: <br> <br> MSDN_Ref: <br> */ _IRQL_requires_min_(PASSIVE_LEVEL) _IRQL_requires_max_(DISPATCH_LEVEL) _IRQL_requires_same_ inline VOID KrnlHlprWorkItemDataPopulate(_Inout_ WORKITEM_DATA* pWorkItemData, _In_ CLASSIFY_DATA* pClassifyData, _In_ REDIRECT_DATA* pRedirectData, _In_opt_ PIO_WORKITEM pIOWorkItem, /* 0 */ _In_opt_ VOID* pContext) /* 0 */ { #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " ---> KrnlHlprWorkItemDataPopulate()\n"); #endif /// DBG NT_ASSERT(pWorkItemData); NT_ASSERT(pClassifyData); NT_ASSERT(pRedirectData); pWorkItemData->pIOWorkItem = pIOWorkItem; pWorkItemData->pClassifyData = pClassifyData; pWorkItemData->pRedirectData = pRedirectData; pWorkItemData->pContext = pContext; #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " <--- KrnlHlprWorkItemDataPopulate()\n"); #endif /// DBG return; } /** @kernel_helper_function="KrnlHlprWorkItemDataPopulate" Purpose: Populates a WORKITEM_DATA object with the notifyData, PIOWorkItem, and context supplied. <br> <br> Notes: <br> <br> MSDN_Ref: <br> */ _IRQL_requires_min_(PASSIVE_LEVEL) _IRQL_requires_max_(DISPATCH_LEVEL) _IRQL_requires_same_ inline VOID KrnlHlprWorkItemDataPopulate(_Inout_ WORKITEM_DATA* pWorkItemData, _In_ NOTIFY_DATA* pNotifyData, _In_opt_ PIO_WORKITEM pIOWorkItem, /* 0 */ _In_opt_ VOID* pContext) /* 0 */ { #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " ---> KrnlHlprWorkItemDataPopulate()\n"); #endif /// DBG NT_ASSERT(pWorkItemData); NT_ASSERT(pNotifyData); pWorkItemData->pIOWorkItem = pIOWorkItem; pWorkItemData->pNotifyData = pNotifyData; pWorkItemData->pContext = pContext; #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " <--- KrnlHlprWorkItemDataPopulate()\n"); #endif /// DBG return; } /** @kernel_helper_function="KrnlHlprWorkItemDataCreate" Purpose: Allocates and populates a WORKITEM_DATA object with the classifyData, injectionData, PIOWorkItem, and context supplied. <br> <br> Notes: <br> <br> MSDN_Ref: <br> */ _At_(*ppWorkItemData, _Pre_ _Null_) _When_(return != STATUS_SUCCESS, _At_(*ppWorkItemData, _Post_ _Null_)) _When_(return == STATUS_SUCCESS, _At_(*ppWorkItemData, _Post_ _Notnull_ __drv_allocatesMem(Pool))) _IRQL_requires_min_(PASSIVE_LEVEL) _IRQL_requires_max_(DISPATCH_LEVEL) _IRQL_requires_same_ _Check_return_ _Success_(return == STATUS_SUCCESS) NTSTATUS KrnlHlprWorkItemDataCreate(_Outptr_ WORKITEM_DATA** ppWorkItemData, _In_ CLASSIFY_DATA* pClassifyData, _In_opt_ INJECTION_DATA* pInjectionData, /* 0 */ _In_opt_ PIO_WORKITEM pIOWorkItem, /* 0 */ _In_opt_ VOID* pContext) /* 0 */ { #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " ---> KrnlHlprWorkItemDataCreate()\n"); #endif /// DBG NT_ASSERT(ppWorkItemData); NT_ASSERT(pClassifyData); NT_ASSERT(pInjectionData); NTSTATUS status = STATUS_SUCCESS; HLPR_NEW(*ppWorkItemData, WORKITEM_DATA, WFPSAMPLER_SYSLIB_TAG); HLPR_BAIL_ON_ALLOC_FAILURE(*ppWorkItemData, status); KrnlHlprWorkItemDataPopulate(*ppWorkItemData, pClassifyData, pInjectionData, pIOWorkItem, pContext); HLPR_BAIL_LABEL: if(status != STATUS_SUCCESS) KrnlHlprWorkItemDataDestroy(ppWorkItemData); #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " <--- KrnlHlprWorkItemDataCreate() [status: %#x]\n", status); #endif /// DBG return status; } /** @kernel_helper_function="KrnlHlprWorkItemDataCreate" Purpose: Allocates and populates a WORKITEM_DATA object with the classifyData, pendData, PIOWorkItem, and context supplied. <br> <br> Notes: <br> <br> MSDN_Ref: <br> */ _At_(*ppWorkItemData, _Pre_ _Null_) _When_(return != STATUS_SUCCESS, _At_(*ppWorkItemData, _Post_ _Null_)) _When_(return == STATUS_SUCCESS, _At_(*ppWorkItemData, _Post_ _Notnull_ __drv_allocatesMem(Pool))) _IRQL_requires_min_(PASSIVE_LEVEL) _IRQL_requires_max_(DISPATCH_LEVEL) _IRQL_requires_same_ _Check_return_ _Success_(return == STATUS_SUCCESS) NTSTATUS KrnlHlprWorkItemDataCreate(_Outptr_ WORKITEM_DATA** ppWorkItemData, _In_ CLASSIFY_DATA* pClassifyData, _In_ PEND_DATA* pPendData, _In_opt_ PIO_WORKITEM pIOWorkItem, /* 0 */ _In_opt_ VOID* pContext) /* 0 */ { #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " ---> KrnlHlprWorkItemDataCreate()\n"); #endif /// DBG NT_ASSERT(ppWorkItemData); NT_ASSERT(pClassifyData); NT_ASSERT(pPendData); NTSTATUS status = STATUS_SUCCESS; HLPR_NEW(*ppWorkItemData, WORKITEM_DATA, WFPSAMPLER_SYSLIB_TAG); HLPR_BAIL_ON_ALLOC_FAILURE(*ppWorkItemData, status); KrnlHlprWorkItemDataPopulate(*ppWorkItemData, pClassifyData, pPendData, pIOWorkItem, pContext); HLPR_BAIL_LABEL: if(status != STATUS_SUCCESS) KrnlHlprWorkItemDataDestroy(ppWorkItemData); #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " <--- KrnlHlprWorkItemDataCreate() [status: %#x]\n", status); #endif /// DBG return status; } /** @kernel_helper_function="KrnlHlprWorkItemDataCreate" Purpose: Allocates and populates a WORKITEM_DATA object with the classifyData, redirectData, PIOWorkItem, and context supplied. <br> <br> Notes: <br> <br> MSDN_Ref: <br> */ _At_(*ppWorkItemData, _Pre_ _Null_) _When_(return != STATUS_SUCCESS, _At_(*ppWorkItemData, _Post_ _Null_)) _When_(return == STATUS_SUCCESS, _At_(*ppWorkItemData, _Post_ _Notnull_ __drv_allocatesMem(Pool))) _IRQL_requires_min_(PASSIVE_LEVEL) _IRQL_requires_max_(DISPATCH_LEVEL) _IRQL_requires_same_ _Check_return_ _Success_(return == STATUS_SUCCESS) NTSTATUS KrnlHlprWorkItemDataCreate(_Outptr_ WORKITEM_DATA** ppWorkItemData, _In_ CLASSIFY_DATA* pClassifyData, _In_ REDIRECT_DATA* pRedirectData, _In_opt_ PIO_WORKITEM pIOWorkItem, /* 0 */ _In_opt_ VOID* pContext) /* 0 */ { #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " ---> KrnlHlprWorkItemDataCreate()\n"); #endif /// DBG NT_ASSERT(ppWorkItemData); NT_ASSERT(pClassifyData); NT_ASSERT(pRedirectData); NTSTATUS status = STATUS_SUCCESS; HLPR_NEW(*ppWorkItemData, WORKITEM_DATA, WFPSAMPLER_SYSLIB_TAG); HLPR_BAIL_ON_ALLOC_FAILURE(*ppWorkItemData, status); KrnlHlprWorkItemDataPopulate(*ppWorkItemData, pClassifyData, pRedirectData, pIOWorkItem, pContext); HLPR_BAIL_LABEL: if(status != STATUS_SUCCESS) KrnlHlprWorkItemDataDestroy(ppWorkItemData); #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " <--- KrnlHlprWorkItemDataCreate() [status: %#x]\n", status); #endif /// DBG return status; } /** @kernel_helper_function="KrnlHlprWorkItemDataCreate" Purpose: Allocates and populates a WORKITEM_DATA object with the notifyData, PIOWorkItem, and context supplied. <br> <br> Notes: <br> <br> MSDN_Ref: <br> */ _At_(*ppWorkItemData, _Pre_ _Null_) _When_(return != STATUS_SUCCESS, _At_(*ppWorkItemData, _Post_ _Null_)) _When_(return == STATUS_SUCCESS, _At_(*ppWorkItemData, _Post_ _Notnull_ __drv_allocatesMem(Pool))) _IRQL_requires_min_(PASSIVE_LEVEL) _IRQL_requires_max_(DISPATCH_LEVEL) _IRQL_requires_same_ _Check_return_ _Success_(return == STATUS_SUCCESS) NTSTATUS KrnlHlprWorkItemDataCreate(_Outptr_ WORKITEM_DATA** ppWorkItemData, _In_ NOTIFY_DATA* pNotifyData, _In_opt_ PIO_WORKITEM pIOWorkItem, /* 0 */ _In_opt_ VOID* pContext) /* 0 */ { #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " ---> KrnlHlprWorkItemDataCreate()\n"); #endif /// DBG NT_ASSERT(ppWorkItemData); NT_ASSERT(pNotifyData); NTSTATUS status = STATUS_SUCCESS; HLPR_NEW(*ppWorkItemData, WORKITEM_DATA, WFPSAMPLER_SYSLIB_TAG); HLPR_BAIL_ON_ALLOC_FAILURE(*ppWorkItemData, status); KrnlHlprWorkItemDataPopulate(*ppWorkItemData, pNotifyData, pIOWorkItem, pContext); HLPR_BAIL_LABEL: if(status != STATUS_SUCCESS) KrnlHlprWorkItemDataDestroy(ppWorkItemData); #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " <--- KrnlHlprWorkItemDataCreate() [status: %#x]\n", status); #endif /// DBG return status; } /** @kernel_helper_function="KrnlHlprWorkItemQueue" Purpose: Queue a workitem for later execution at PASSIVE_LEVEL. <br> <br> Notes: Data is expected to be obtained by other means (i.e. LIST_ENTRY) <br> <br> MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/FF548276.aspx <br> HTTP://MSDN.Microsoft.com/En-US/Library/FF549466.aspx <br> */ _IRQL_requires_min_(PASSIVE_LEVEL) _IRQL_requires_max_(DISPATCH_LEVEL) _IRQL_requires_same_ _Check_return_ _Success_(return == STATUS_SUCCESS) NTSTATUS KrnlHlprWorkItemQueue(_In_ PDEVICE_OBJECT pWDMDevice, _In_ IO_WORKITEM_ROUTINE* pWorkItemFn) { #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " ---> KrnlHlprWorkItemQueue()\n"); #endif /// DBG NT_ASSERT(pWDMDevice); NT_ASSERT(pWorkItemFn); NTSTATUS status = STATUS_SUCCESS; PIO_WORKITEM pIOWorkItem = 0; #pragma warning(push) #pragma warning(disable: 6014) /// pIOWorkItem is cleaned up in pWorkItemFn pIOWorkItem = IoAllocateWorkItem(pWDMDevice); if(pIOWorkItem == 0) { status = STATUS_UNSUCCESSFUL; DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, " !!!! KrnlHlprWorkItemQueue : IoAllocateWorkItem() [status: %#x]\n", status); HLPR_BAIL; } #pragma warning(pop) IoQueueWorkItem(pIOWorkItem, pWorkItemFn, DelayedWorkQueue, (PVOID)pIOWorkItem); HLPR_BAIL_LABEL: if(status != STATUS_SUCCESS && pIOWorkItem) IoFreeWorkItem(pIOWorkItem); #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " <--- KrnlHlprWorkItemQueue() [status: %#x]\n", status); #endif /// DBG return status; } /** @kernel_helper_function="KrnlHlprWorkItemQueue" Purpose: Queue a workitem for later execution at PASSIVE_LEVEL. <br> <br> Notes: INJECTION_DATA specific. <br> <br> MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/FF548276.aspx <br> HTTP://MSDN.Microsoft.com/En-US/Library/FF549466.aspx <br> */ _IRQL_requires_min_(PASSIVE_LEVEL) _IRQL_requires_max_(DISPATCH_LEVEL) _IRQL_requires_same_ _Check_return_ _Success_(return == STATUS_SUCCESS) NTSTATUS KrnlHlprWorkItemQueue(_In_ PDEVICE_OBJECT pWDMDevice, _In_ IO_WORKITEM_ROUTINE* pWorkItemFn, _In_ CLASSIFY_DATA* pClassifyData, _In_opt_ INJECTION_DATA* pInjectionData, /* 0 */ _In_opt_ VOID* pContext) /* 0 */ { #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " ---> KrnlHlprWorkItemQueue()\n"); #endif /// DBG NT_ASSERT(pWDMDevice); NT_ASSERT(pWorkItemFn); NT_ASSERT(pClassifyData); NTSTATUS status = STATUS_SUCCESS; PIO_WORKITEM pIOWorkItem = 0; WORKITEM_DATA* pWorkItemData = 0; #pragma warning(push) #pragma warning(disable: 6014) /// pIOWorkItem is cleaned up in KrnlHlprWorkItemDataDestroy pIOWorkItem = IoAllocateWorkItem(pWDMDevice); if(pIOWorkItem == 0) { status = STATUS_UNSUCCESSFUL; DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, " !!!! KrnlHlprWorkItemQueue : IoAllocateWorkItem() [status: %#x]\n", status); HLPR_BAIL; } #pragma warning(pop) status = KrnlHlprWorkItemDataCreate(&pWorkItemData, pClassifyData, pInjectionData, pIOWorkItem, pContext); HLPR_BAIL_ON_FAILURE(status); IoQueueWorkItem(pWorkItemData->pIOWorkItem, pWorkItemFn, DelayedWorkQueue, (PVOID)pWorkItemData); HLPR_BAIL_LABEL: if(status != STATUS_SUCCESS && pWorkItemData) KrnlHlprWorkItemDataDestroy(&pWorkItemData); #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " <--- KrnlHlprWorkItemQueue() [status: %#x]\n", status); #endif /// DBG return status; } /** @kernel_helper_function="KrnlHlprWorkItemQueue" Purpose: Queue a workitem for later execution at PASSIVE_LEVEL. <br> <br> Notes: PEND_DATA specific. <br> <br> MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/FF548276.aspx <br> HTTP://MSDN.Microsoft.com/En-US/Library/FF549466.aspx <br> */ _IRQL_requires_min_(PASSIVE_LEVEL) _IRQL_requires_max_(DISPATCH_LEVEL) _IRQL_requires_same_ _Check_return_ _Success_(return == STATUS_SUCCESS) NTSTATUS KrnlHlprWorkItemQueue(_In_ PDEVICE_OBJECT pWDMDevice, _In_ IO_WORKITEM_ROUTINE* pWorkItemFn, _In_ CLASSIFY_DATA* pClassifyData, _In_ PEND_DATA* pPendData, _In_opt_ VOID* pContext) /* 0 */ { #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " ---> KrnlHlprWorkItemQueue()\n"); #endif /// DBG NT_ASSERT(pWDMDevice); NT_ASSERT(pWorkItemFn); NT_ASSERT(pClassifyData); NT_ASSERT(pPendData); NTSTATUS status = STATUS_SUCCESS; PIO_WORKITEM pIOWorkItem = 0; WORKITEM_DATA* pWorkItemData = 0; #pragma warning(push) #pragma warning(disable: 6014) /// pIOWorkItem is cleaned up in KrnlHlprWorkItemDataDestroy pIOWorkItem = IoAllocateWorkItem(pWDMDevice); if(pIOWorkItem == 0) { status = STATUS_UNSUCCESSFUL; DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, " !!!! KrnlHlprWorkItemQueue : IoAllocateWorkItem() [status: %#x]\n", status); HLPR_BAIL; } #pragma warning(pop) status = KrnlHlprWorkItemDataCreate(&pWorkItemData, pClassifyData, pPendData, pIOWorkItem, pContext); HLPR_BAIL_ON_FAILURE(status); IoQueueWorkItem(pWorkItemData->pIOWorkItem, pWorkItemFn, DelayedWorkQueue, (PVOID)pWorkItemData); HLPR_BAIL_LABEL: if(status != STATUS_SUCCESS && pWorkItemData) KrnlHlprWorkItemDataDestroy(&pWorkItemData); #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " <--- KrnlHlprWorkItemQueue() [status: %#x]\n", status); #endif /// DBG return status; } /** @kernel_helper_function="KrnlHlprWorkItemQueue" Purpose: Queue a workitem for later execution at PASSIVE_LEVEL. <br> <br> Notes: REDIRECT_DATA specific. <br> <br> MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/FF548276.aspx <br> HTTP://MSDN.Microsoft.com/En-US/Library/FF549466.aspx <br> */ _IRQL_requires_min_(PASSIVE_LEVEL) _IRQL_requires_max_(DISPATCH_LEVEL) _IRQL_requires_same_ _Check_return_ _Success_(return == STATUS_SUCCESS) NTSTATUS KrnlHlprWorkItemQueue(_In_ PDEVICE_OBJECT pWDMDevice, _In_ IO_WORKITEM_ROUTINE* pWorkItemFn, _In_ CLASSIFY_DATA* pClassifyData, _In_ REDIRECT_DATA* pRedirectData, _In_opt_ VOID* pContext) /* 0 */ { #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " ---> KrnlHlprWorkItemQueue()\n"); #endif /// DBG NT_ASSERT(pWDMDevice); NT_ASSERT(pWorkItemFn); NT_ASSERT(pClassifyData); NT_ASSERT(pRedirectData); NTSTATUS status = STATUS_SUCCESS; PIO_WORKITEM pIOWorkItem = 0; WORKITEM_DATA* pWorkItemData = 0; #pragma warning(push) #pragma warning(disable: 6014) /// pIOWorkItem is cleaned up in KrnlHlprWorkItemDataDestroy pIOWorkItem = IoAllocateWorkItem(pWDMDevice); if(pIOWorkItem == 0) { status = STATUS_UNSUCCESSFUL; DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, " !!!! KrnlHlprWorkItemQueue : IoAllocateWorkItem() [status: %#x]\n", status); HLPR_BAIL; } #pragma warning(pop) status = KrnlHlprWorkItemDataCreate(&pWorkItemData, pClassifyData, pRedirectData, pIOWorkItem, pContext); HLPR_BAIL_ON_FAILURE(status); IoQueueWorkItem(pWorkItemData->pIOWorkItem, pWorkItemFn, DelayedWorkQueue, (PVOID)pWorkItemData); HLPR_BAIL_LABEL: if(status != STATUS_SUCCESS && pWorkItemData) KrnlHlprWorkItemDataDestroy(&pWorkItemData); #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " <--- KrnlHlprWorkItemQueue() [status: %#x]\n", status); #endif /// DBG return status; } /** @kernel_helper_function="KrnlHlprWorkItemQueue" Purpose: Queue a workitem for later execution at PASSIVE_LEVEL. <br> <br> Notes: NOTIFY_DATA specific. <br> <br> MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/FF548276.aspx <br> HTTP://MSDN.Microsoft.com/En-US/Library/FF549466.aspx <br> */ _IRQL_requires_min_(PASSIVE_LEVEL) _IRQL_requires_max_(DISPATCH_LEVEL) _IRQL_requires_same_ _Check_return_ _Success_(return == STATUS_SUCCESS) NTSTATUS KrnlHlprWorkItemQueue(_In_ PDEVICE_OBJECT pWDMDevice, _In_ IO_WORKITEM_ROUTINE* pWorkItemFn, _In_ NOTIFY_DATA* pNotifyData, _In_opt_ VOID* pContext) /* 0 */ { #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " ---> KrnlHlprWorkItemQueue()\n"); #endif /// DBG NT_ASSERT(pWDMDevice); NT_ASSERT(pWorkItemFn); NT_ASSERT(pNotifyData); NTSTATUS status = STATUS_SUCCESS; PIO_WORKITEM pIOWorkItem = 0; WORKITEM_DATA* pWorkItemData = 0; #pragma warning(push) #pragma warning(disable: 6014) /// pIOWorkItem is cleaned up in KrnlHlprWorkItemDataDestroy pIOWorkItem = IoAllocateWorkItem(pWDMDevice); if(pIOWorkItem == 0) { status = STATUS_UNSUCCESSFUL; DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, " !!!! KrnlHlprWorkItemQueue : IoAllocateWorkItem() [status: %#x]\n", status); HLPR_BAIL; } #pragma warning(pop) status = KrnlHlprWorkItemDataCreate(&pWorkItemData, pNotifyData, pIOWorkItem, pContext); HLPR_BAIL_ON_FAILURE(status); IoQueueWorkItem(pWorkItemData->pIOWorkItem, pWorkItemFn, DelayedWorkQueue, (PVOID)pWorkItemData); HLPR_BAIL_LABEL: if(status != STATUS_SUCCESS && pWorkItemData) KrnlHlprWorkItemDataDestroy(&pWorkItemData); #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " <--- KrnlHlprWorkItemQueue() [status: %#x]\n", status); #endif /// DBG return status; } /** @kernel_helper_function="KrnlHlprWorkItemSleep" Purpose: Delay the thread for the specified time. <br> <br> Notes: <br> <br> MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/FF551986.aspx <br> */ _IRQL_requires_min_(PASSIVE_LEVEL) _IRQL_requires_max_(APC_LEVEL) _IRQL_requires_same_ _Success_(return == STATUS_SUCCESS) NTSTATUS KrnlHlprWorkItemSleep(_In_ UINT32 numMS) { #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " ---> KrnlHlprWorkItemSleep()\n"); #endif /// DBG NT_ASSERT(numMS); NTSTATUS status = STATUS_SUCCESS; INT64 interval = numMS * -10000i64; /// (numMS[milli] * (-1[relative] * 1000[milli to micro] * 1000[micro to nano]) / 100[ns] status = KeDelayExecutionThread(KernelMode, FALSE, (PLARGE_INTEGER)&interval); #if DBG DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, " <--- KrnlHlprWorkItemSleep() [status: %#x]\n", status); #endif /// DBG return status; }
Our Services
-
What our customers say about us?
Read our customer testimonials to find out why our clients keep returning for their projects.
View Testimonials