summaryrefslogtreecommitdiff
path: root/nfp/net/driver/Queue.cpp
diff options
context:
space:
mode:
authorWei Mao <[email protected]>2023-03-07 17:49:46 -0800
committerGitHub <[email protected]>2023-03-07 17:49:46 -0800
commit670397ed629b8488beef603d5a6659f104e85e16 (patch)
treeab74701e6d1b7a78e1ca0b58c1573016384d0f28 /nfp/net/driver/Queue.cpp
parent91e07c437248cb21f5113a5f65780447abc40823 (diff)
Remove UMDF v1 samples - nfp (#912)
[UMDF v1] Remove nfp/net/driver/NetNfpProvider
Diffstat (limited to 'nfp/net/driver/Queue.cpp')
-rw-r--r--nfp/net/driver/Queue.cpp824
1 files changed, 0 insertions, 824 deletions
diff --git a/nfp/net/driver/Queue.cpp b/nfp/net/driver/Queue.cpp
deleted file mode 100644
index 129a5439..00000000
--- a/nfp/net/driver/Queue.cpp
+++ /dev/null
@@ -1,824 +0,0 @@
-/*++
-
-Copyright (c) Microsoft Corporation. All rights reserved.
-
-Module Name:
-
- queue.cpp
-
-Abstract:
-
- This file implements the I/O queue interface and performs
- the read/write/ioctl operations.
-
-Environment:
-
- user mode only
-
-Revision History:
-
---*/
-#include "internal.h"
-
-#include "queue.tmh"
-
-CMyQueue::CMyQueue(
- VOID
- )
-{
- InitializeListHead(&m_SubsHead);
- InitializeListHead(&m_ArrivalSubsHead);
- InitializeListHead(&m_DepartureSubsHead);
- InitializeListHead(&m_PubsHead);
- InitializeListHead(&m_ConnectionHead);
-
- InitializeCriticalSection(&m_SubsLock);
- InitializeCriticalSection(&m_PubsLock);
- InitializeCriticalSection(&m_ConnectionLock);
-}
-
-CMyQueue::~CMyQueue(
- VOID
- )
-{
- MethodEntry("void");
-
- m_SocketListener.StopAccepting();
-
- while (!IsListEmpty(&m_ConnectionHead))
- {
- delete CConnection::FromListEntry(RemoveHeadList(&m_ConnectionHead));
- }
-
- DeleteCriticalSection(&m_SubsLock);
- DeleteCriticalSection(&m_PubsLock);
- DeleteCriticalSection(&m_ConnectionLock);
-}
-
-//
-// Initialize
-//
-
-HRESULT
-CMyQueue::Initialize(
- _In_ CMyDevice * Device
- )
-/*++
-
-Routine Description:
-
- Queue Initialize helper routine.
- This routine will Create a default parallel queue associated with the Fx device object
- and pass the IUnknown for this queue
-
-Aruments:
- Device object pointer
-
-Return Value:
-
- S_OK if Initialize succeeds
-
---*/
-{
- MethodEntry("...");
-
- CComPtr<IWDFIoQueue> fxQueue;
-
- HRESULT hr;
-
- //
- // Create the I/O Queue object.
- //
- {
- CComPtr<IUnknown> pUnk;
-
- HRESULT hrQI = this->QueryInterface(__uuidof(IUnknown),(void**)&pUnk);
-
- WUDF_SAMPLE_DRIVER_ASSERT(SUCCEEDED(hrQI));
-
- hr = Device->GetFxDevice()->CreateIoQueue(
- pUnk,
- TRUE,
- WdfIoQueueDispatchParallel,
- TRUE,
- FALSE,
- &fxQueue
- );
- }
-
- if (FAILED(hr))
- {
- TraceErrorHR(hr, "Failed to initialize driver queue");
- }
-
- if (SUCCEEDED(hr))
- {
- hr = m_SocketListener.Bind();
- if (FAILED(hr))
- {
- TraceErrorHR(hr, "Failed to Bind");
- }
- }
-
- if (SUCCEEDED(hr))
- {
- hr = m_SocketListener.EnableAccepting(this);
- if (FAILED(hr))
- {
- TraceErrorHR(hr, "Failed to EnableAccepting");
- }
- }
-
- if (SUCCEEDED(hr))
- {
- m_FxQueue = fxQueue;
- }
-
- MethodReturnHR(hr);
-}
-
-HRESULT
-CMyQueue::Configure(
- VOID
- )
-/*++
-
-Routine Description:
-
- Queue configuration function .
- It is called after queue object has been succesfully initialized.
-
-Aruments:
-
- NONE
-
- Return Value:
-
- S_OK if succeeds.
-
---*/
-{
- MethodEntry("void");
-
- HRESULT hr = S_OK;
-
- MethodReturnHR(hr);
-}
-
-
-STDMETHODIMP_(void)
-CMyQueue::OnCreateFile(
- _In_ IWDFIoQueue* /*pWdfQueue*/,
- _In_ IWDFIoRequest* pWdfRequest,
- _In_ IWDFFile* pWdfFile
- )
-
-/*++
-
-Routine Description:
-
- Create callback from the framework for this default parallel queue
-
- The create request will create a socket connection , create a file i/o target associated
- with the socket handle for this connection and store in the file object context.
-
-Aruments:
-
- pWdfQueue - Framework Queue instance
- pWdfRequest - Framework Request instance
- pWdfFile - WDF file object for this create
-
- Return Value:
-
- VOID
-
---*/
-{
- MethodEntry("pWdfRequest = %p, pWdfFile = %p",
- pWdfRequest, pWdfFile);
-
- HRESULT hr = S_OK;
-
- //
- // Create file context for this file object
- //
-
- CFileContext *pContext = new CFileContext();
- if (NULL == pContext)
- {
- hr = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
- TraceErrorHR(hr, "Could not create file context");
- }
-
- if (SUCCEEDED(hr))
- {
- DWORD cchFileName = 0;
- hr = pWdfFile->RetrieveFileName(NULL, &cchFileName);
- if (SUCCEEDED(hr) && (cchFileName > 0) && (cchFileName <= MaxCchType))
- {
- // Allocate a buffer big enough for the filename plus some extra to prevent
- // overruns in the parsing below: The extra needs to be larger than the biggest
- // *_CHARS value. The value 20 is overly big, but allows room to grow without
- // hitting the OACR issue again. If the OACR issue is hit, just increase this
- // to be larger than the biggest *_CHARS value used below in parsing.
- DWORD cchFileNameBuffer = cchFileName + 20;
- PWSTR pszFileNameBuffer = new WCHAR[cchFileNameBuffer];
- hr = (pszFileNameBuffer != NULL) ? S_OK : E_OUTOFMEMORY;
- if (SUCCEEDED(hr))
- {
- ZeroMemory(pszFileNameBuffer, cchFileNameBuffer * sizeof(WCHAR));
-
- hr = pWdfFile->RetrieveFileName(pszFileNameBuffer, &cchFileName);
- }
-
- if (SUCCEEDED(hr))
- {
- PCWSTR pszFileName = pszFileNameBuffer;
- if (pszFileNameBuffer[0] == L'\\')
- {
- // If it exists, remove the inital slash
- pszFileName++;
- cchFileName--;
- }
-
- TraceInfo("cchFileName = %d, pszFileName = %S", cchFileName, pszFileName);
-
- PCWSTR pszProtocol = NULL;
- if (CompareStringOrdinal(pszFileName, PUBS_NAMESPACE_CHARS,
- PUBS_NAMESPACE, PUBS_NAMESPACE_CHARS,
- TRUE) == CSTR_EQUAL)
- {
- pContext->SetRolePublication();
- pszProtocol = pszFileName + PUBS_NAMESPACE_CHARS;
- }
- else if (CompareStringOrdinal(pszFileName, SUBS_NAMESPACE_CHARS,
- SUBS_NAMESPACE, SUBS_NAMESPACE_CHARS,
- TRUE) == CSTR_EQUAL)
- {
- pContext->SetRoleSubcription();
- pszProtocol = pszFileName + SUBS_NAMESPACE_CHARS;
- }
- else
- {
- hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
- }
-
- if (SUCCEEDED(hr))
- {
- if (CompareStringOrdinal(pszProtocol, WINDOWS_PROTOCOL_CHARS,
- WINDOWS_PROTOCOL, WINDOWS_PROTOCOL_CHARS,
- TRUE) == CSTR_EQUAL)
- {
- pContext->SetType(pszProtocol);
- }
- else if (CompareStringOrdinal(pszProtocol, -1,
- WINDOWSURI_PROTOCOL, -1,
- TRUE) == CSTR_EQUAL)
- {
- pContext->SetType(pszProtocol);
- }
- else if (CompareStringOrdinal(pszProtocol, WINDOWSMIME_PROTOCOL_CHARS,
- WINDOWSMIME_PROTOCOL, WINDOWSMIME_PROTOCOL_CHARS,
- TRUE) == CSTR_EQUAL)
- {
- pContext->SetType(pszProtocol);
- }
- else if (CompareStringOrdinal(pszProtocol, -1, DEVICE_ARRIVED, -1,
- TRUE) == CSTR_EQUAL)
- {
- if (!pContext->SetRoleArrivedSubcription())
- {
- hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
- }
- }
- else if (CompareStringOrdinal(pszProtocol, -1, DEVICE_DEPARTED, -1,
- TRUE) == CSTR_EQUAL)
- {
- if (!pContext->SetRoleDepartedSubcription())
- {
- hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
- }
- }
- else if (CompareStringOrdinal(pszProtocol, PAIRING_PROTOCOL_CHARS,
- PAIRING_PROTOCOL, PAIRING_PROTOCOL_CHARS,
- TRUE) == CSTR_EQUAL)
- {
- pContext->SetType(pszProtocol);
- }
- else if (CompareStringOrdinal(pszProtocol, NDEF_PROTOCOL_CHARS,
- NDEF_PROTOCOL, NDEF_PROTOCOL_CHARS,
- TRUE) == CSTR_EQUAL)
- {
- PCWSTR pszType = pszProtocol + NDEF_PROTOCOL_CHARS;
-
- if (CompareStringOrdinal(pszType, NDEF_EMPTY_TYPE_CHARS,
- NDEF_EMPTY_TYPE, NDEF_EMPTY_TYPE_CHARS,
- TRUE) != CSTR_EQUAL)
- {
- pContext->SetType(pszProtocol);
- }
- else
- {
- hr = HRESULT_FROM_NT(STATUS_INVALID_PARAMETER);
- }
- }
- else
- {
- hr = HRESULT_FROM_NT(STATUS_OBJECT_PATH_NOT_FOUND);
- }
- }
- }
-
- if (pszFileNameBuffer != NULL)
- {
- delete [] pszFileNameBuffer;
- }
- }
- }
-
- if (SUCCEEDED(hr))
- {
- hr = pWdfFile->AssignContext(NULL, (void*)pContext);
- if (FAILED(hr))
- {
- TraceErrorHR(hr, "Unable to Assign Context to this File Object");
- }
- }
-
- if (SUCCEEDED(hr))
- {
- EnterCriticalSection(&m_SubsLock);
-
- if (pContext->IsNormalSubscription())
- {
- // Place this CFileContext into a list of Subscriptions
- InsertHeadList(&m_SubsHead, pContext->GetListEntry());
- }
- else if (pContext->IsArrivedSubscription())
- {
- // Place this CFileContext into a list of arrival registrations
- InsertHeadList(&m_ArrivalSubsHead, pContext->GetListEntry());
- }
- else if (pContext->IsDepartedSubscription())
- {
- // Place this CFileContext into a list of removal registrations
- InsertHeadList(&m_DepartureSubsHead, pContext->GetListEntry());
- }
-
- LeaveCriticalSection(&m_SubsLock);
- }
-
- if (FAILED(hr))
- {
- if (pContext != NULL)
- {
- delete pContext;
- pContext = NULL;
- }
- }
-
- pWdfRequest->Complete(hr);
-
- MethodReturnVoid();
-}
-
-STDMETHODIMP_(void)
-CMyQueue::OnCloseFile(
- _In_ IWDFFile* pWdfFileObject
- )
-/*++
-
- Routine Description:
-
- This method is called when an app closes the file handle to this device.
- This will free the context memory associated with this file object, close
- the connection object associated with this file object and delete the file
- handle i/o target object associated with this file object.
-
- Arguments:
-
- pWdfFileObject - the framework file object for which close is handled.
-
- Return Value:
-
- None
-
---*/
-{
- MethodEntry("...");
-
- HRESULT hr = S_OK ;
- CFileContext* pContext = NULL;
- hr = pWdfFileObject->RetrieveContext((void**)&pContext);
- if (SUCCEEDED(hr) && (pContext != NULL))
- {
- CRITICAL_SECTION* pCritSec = NULL;
- LIST_ENTRY* pHead = NULL;
-
- if (pContext->IsNormalSubscription())
- {
- pCritSec = &m_SubsLock;
- pHead = &m_SubsHead;
- }
- else if (pContext->IsArrivedSubscription())
- {
- pCritSec = &m_SubsLock;
- pHead = &m_ArrivalSubsHead;
- }
- else if (pContext->IsDepartedSubscription())
- {
- pCritSec = &m_SubsLock;
- pHead = &m_DepartureSubsHead;
- }
- else if (pContext->IsPublication())
- {
- pCritSec = &m_PubsLock;
- pHead = &m_PubsHead;
- }
-
- if (pHead != NULL)
- {
- EnterCriticalSection(pCritSec);
-
- LIST_ENTRY* pFindEntry = pContext->GetListEntry();
- LIST_ENTRY* pEntry = pHead->Flink;
- while (pEntry != pHead)
- {
- if (pEntry == pFindEntry)
- {
- RemoveEntryList(pEntry);
- break;
- }
-
- pEntry = pEntry->Flink;
- }
-
- LeaveCriticalSection(pCritSec);
- }
-
- delete pContext;
- }
-
- MethodReturnVoid();
-}
-
-STDMETHODIMP_ (void)
-CMyQueue::OnCancel(
- _In_ IWDFIoRequest* pWdfRequest
- )
-{
- MethodEntry("pWdfRequest = %p",
- pWdfRequest);
-
- IWDFFile* pFxFile;
- pWdfRequest->GetFileObject(&pFxFile);
- if (pFxFile != NULL)
- {
- CFileContext* pFileContext;
- HRESULT hr = pFxFile->RetrieveContext((void**)&pFileContext);
- if (SUCCEEDED(hr))
- {
- pFileContext->OnCancel();
- }
- }
-
- MethodReturnVoid();
-}
-
-#define IOCTL_BEGIN_PROXIMITY CTL_CODE(FILE_DEVICE_UNKNOWN, 0x1000, METHOD_BUFFERED, FILE_ANY_ACCESS)
-
-STDMETHODIMP_ (void)
-CMyQueue::OnDeviceIoControl(
- _In_ IWDFIoQueue* /*pWdfQueue*/,
- _In_ IWDFIoRequest* pWdfRequest,
- _In_ ULONG ControlCode,
- _In_ SIZE_T /*InBufferSize*/,
- _In_ SIZE_T /*OutBufferSize*/
- )
-{
- MethodEntry("pWdfRequest = %p, ControlCode = %d",
- pWdfRequest, ControlCode);
-
- IWDFFile* pFxFile;
-
- pWdfRequest->GetFileObject(&pFxFile);
-
- bool fCompleteRequest = true;
-
- CFileContext *pFileContext;
- HRESULT hr = pFxFile->RetrieveContext((void**)&pFileContext);
- if (SUCCEEDED(hr))
- {
- switch (ControlCode)
- {
- case IOCTL_NFP_GET_MAX_MESSAGE_BYTES:
- {
- IWDFMemory* pWdfOutputMemory;
- pWdfRequest->GetOutputMemory(&pWdfOutputMemory);
- if (pWdfOutputMemory != NULL)
- {
- SIZE_T cbOutputBuffer = 0;
- // Set the first 4 bytes as the maximum message size of this device/driver
- DWORD dwMaxCbPayload = MaxCbPayload;
- hr = pWdfOutputMemory->CopyFromBuffer(0, &dwMaxCbPayload, 4);
- if (SUCCEEDED(hr))
- {
- cbOutputBuffer = 4;
- }
- pWdfOutputMemory->Release();
-
- pWdfRequest->CompleteWithInformation(hr, cbOutputBuffer);
- fCompleteRequest = false;
- }
- }
- break;
-
- case IOCTL_NFP_GET_KILO_BYTES_PER_SECOND:
- {
- IWDFMemory* pWdfOutputMemory;
- pWdfRequest->GetOutputMemory(&pWdfOutputMemory);
- if (pWdfOutputMemory != NULL)
- {
- SIZE_T cbOutputBuffer = 0;
- // Set the first 4 bytes as transfer speed of this device/driver
- DWORD dwKilobytesPerSecond = KilobytesPerSecond;
- hr = pWdfOutputMemory->CopyFromBuffer(0, &dwKilobytesPerSecond, 4);
- if (SUCCEEDED(hr))
- {
- cbOutputBuffer = 4;
- }
- pWdfOutputMemory->Release();
-
- pWdfRequest->CompleteWithInformation(hr, cbOutputBuffer);
- fCompleteRequest = false;
- }
- }
- break;
-
- case IOCTL_NFP_DISABLE:
- hr = pFileContext->Disable();
- break;
-
- case IOCTL_NFP_ENABLE:
- hr = pFileContext->Enable();
- break;
-
- case IOCTL_NFP_SET_PAYLOAD:
- hr = pFileContext->SetPayload(pWdfRequest);
- if (SUCCEEDED(hr))
- {
- MESSAGE* pMessage = new MESSAGE();
- hr = (pMessage != NULL) ? S_OK : E_OUTOFMEMORY;
- if (SUCCEEDED(hr))
- {
- pMessage->Initialize(pFileContext->GetType(), pFileContext->GetSize(), pFileContext->GetPayload());
-
- EnterCriticalSection(&m_ConnectionLock);
-
- for (LIST_ENTRY* pEntry = m_ConnectionHead.Flink;
- pEntry != &m_ConnectionHead;
- pEntry = pEntry->Flink)
- {
- CConnection* pConnection = CConnection::FromListEntry(pEntry);
- if (SUCCEEDED(pConnection->TransmitMessage(pMessage)))
- {
- pFileContext->HandleMessageTransmitted();
- }
- }
-
- LeaveCriticalSection(&m_ConnectionLock);
-
- // Place this CFileContext into a list of published messages
- EnterCriticalSection(&m_PubsLock);
- InsertHeadList(&m_PubsHead, pFileContext->GetListEntry());
- LeaveCriticalSection(&m_PubsLock);
-
- delete pMessage;
- }
- }
- break;
-
- case IOCTL_BEGIN_PROXIMITY:
- hr = pFileContext->BeginProximity(pWdfRequest, this);
- break;
-
- case IOCTL_NFP_GET_NEXT_SUBSCRIBED_MESSAGE:
- hr = pFileContext->GetNextSubscribedMessage(this, pWdfRequest);
- if (SUCCEEDED(hr))
- {
- fCompleteRequest = false;
- }
- break;
-
- case IOCTL_NFP_GET_NEXT_TRANSMITTED_MESSAGE:
- hr = pFileContext->GetNextTransmittedMessage(this, pWdfRequest);
- if (SUCCEEDED(hr))
- {
- fCompleteRequest = false;
- }
- break;
-
- default:
- hr = HRESULT_FROM_NT(STATUS_INVALID_DEVICE_STATE);
- break;
- }
- }
-
- if (fCompleteRequest)
- {
- TraceInfo("Completing Request: %!HRESULT!", hr);
- pWdfRequest->Complete(hr);
- }
-
- MethodReturnVoid();
-}
-
-void
-CMyQueue::ValidateAccept(_In_ SOCKET Socket, _In_ GUID* pMagicPacket)
-{
- MethodEntry("...");
-
- CConnection* pConnection;
- HRESULT hr = CConnection::Create(this, &pConnection);
- if (SUCCEEDED(hr))
- {
- // Mark it as an Inbound connection, so we know to delete it when
- // it's removed from the list
- pConnection->SetInboundConnection();
-
- pConnection->ValidateAccept(Socket, pMagicPacket);
- Socket = INVALID_SOCKET;
- }
-
- if (Socket != INVALID_SOCKET)
- {
- closesocket(Socket);
- }
-
- MethodReturnVoid();
-}
-
-void
-CMyQueue::HandleReceivedMessage(_In_ MESSAGE* pMessage)
-{
- MethodEntry("pMessage->m_szType = '%S'",
- pMessage->m_szType);
-
- if ((pMessage->m_cbPayload > 0) && (pMessage->m_cbPayload <= MaxCbPayload))
- {
- EnterCriticalSection(&m_SubsLock);
-
- LIST_ENTRY* pEntry = m_SubsHead.Flink;
- while (pEntry != &m_SubsHead)
- {
- CFileContext* pSub = CFileContext::FromListEntry(pEntry);
-
- pSub->HandleReceivedPublication(pMessage->m_szType,
- pMessage->m_cbPayload,
- pMessage->m_Payload);
-
- pEntry = pEntry->Flink;
- }
-
- LeaveCriticalSection(&m_SubsLock);
- }
-
- MethodReturnVoid();
-}
-
-void
-CMyQueue::ConnectionEstablished(_In_ CConnection* pConnection)
-{
- MethodEntry("...");
-
- EnterCriticalSection(&m_ConnectionLock);
- BOOL fFirstConnection = IsListEmpty(&m_ConnectionHead);
- InsertHeadList(&m_ConnectionHead, pConnection->GetListEntry());
- LeaveCriticalSection(&m_ConnectionLock);
-
- if (fFirstConnection)
- {
- AddArrivalEvent();
- }
-
- MESSAGE* pMessage = new MESSAGE();
- if (pMessage != NULL)
- {
- EnterCriticalSection(&m_PubsLock);
-
- LIST_ENTRY* pEntry = m_PubsHead.Flink;
- while (pEntry != &m_PubsHead)
- {
- CFileContext* pPub = CFileContext::FromListEntry(pEntry);
- if (pPub->IsEnabled())
- {
- pMessage->Initialize(pPub->GetType(), pPub->GetSize(), pPub->GetPayload());
- if (SUCCEEDED(pConnection->TransmitMessage(pMessage)))
- {
- pPub->HandleMessageTransmitted();
- }
- }
- pEntry = pEntry->Flink;
- }
-
- LeaveCriticalSection(&m_PubsLock);
- delete pMessage;
- }
-
- MethodReturnVoid();
-}
-
-BOOL
-CMyQueue::ConnectionTerminated(_In_ CConnection* pConnection)
-{
- MethodEntry("pConnection = 0x%p",
- pConnection);
-
- LIST_ENTRY* pRemoveListEntry = pConnection->GetListEntry();
-
- EnterCriticalSection(&m_ConnectionLock);
- LIST_ENTRY* pEntry = m_ConnectionHead.Flink;
- while (pEntry != &m_ConnectionHead)
- {
- if (pEntry == pRemoveListEntry)
- {
- RemoveEntryList(pEntry);
- break;
- }
- pEntry = pEntry->Flink;
- }
- BOOL fNoMoreConnections = IsListEmpty(&m_ConnectionHead);
-
- LeaveCriticalSection(&m_ConnectionLock);
-
- BOOL fConnectionDeleted = FALSE;
- if (pConnection->IsInboundConnection())
- {
- delete pConnection;
- fConnectionDeleted = TRUE;
- }
-
- if (fNoMoreConnections)
- {
- AddRemovalEvent();
- }
-
- MethodReturnBool(fConnectionDeleted);
-}
-
-void
-CMyQueue::AddArrivalEvent()
-{
- MethodEntry("void");
-
- EnterCriticalSection(&m_SubsLock);
-
- for (LIST_ENTRY* pEntry = m_ArrivalSubsHead.Flink;
- pEntry != &m_ArrivalSubsHead;
- pEntry = pEntry->Flink)
- {
- CFileContext::FromListEntry(pEntry)->HandleArrivalEvent();
- }
-
- LeaveCriticalSection(&m_SubsLock);
-
- MethodReturnVoid();
-}
-
-void
-CMyQueue::AddRemovalEvent()
-{
- MethodEntry("void");
-
- EnterCriticalSection(&m_SubsLock);
-
- for (LIST_ENTRY* pEntry = m_DepartureSubsHead.Flink;
- pEntry != &m_DepartureSubsHead;
- pEntry = pEntry->Flink)
- {
- CFileContext::FromListEntry(pEntry)->HandleRemovalEvent();
- }
-
- LeaveCriticalSection(&m_SubsLock);
-
- MethodReturnVoid();
-}
-
-STDMETHODIMP_(void)
-CMyQueue::OnCleanup(
- _In_ IWDFObject* /*pWdfObject*/
- )
-{
- MethodEntry("...");
-
- //
- // CMyQueue has a reference to framework device object via m_Queue.
- // Framework queue object has a reference to CMyQueue object via the callbacks.
- // This leads to circular reference and both the objects can't be destroyed until this circular reference is broken.
- // To break the circular reference we release the reference to the framework queue object here in OnCleanup.
- //
-
- m_FxQueue = NULL;
-
- MethodReturnVoid();
-}