spddkhlp.h
上传用户:dzyhzl
上传日期:2019-04-29
资源大小:56270k
文件大小:21k
- /*******************************************************************************
- * SPDDKHLP.h *
- *------------*
- * Description:
- * This is the header file for core helper functions implementation.
- *
- * Copyright (c) Microsoft Corporation. All rights reserved.
- *
- *******************************************************************************/
- #ifndef SPDDKHLP_h
- #define SPDDKHLP_h
- #ifndef SPHelper_h
- #include <sphelper.h>
- #endif
- #include <sapiddk.h>
- #ifndef SPError_h
- #include <SPError.h>
- #endif
- #ifndef SPDebug_h
- #include <SPDebug.h>
- #endif
- #ifndef _INC_LIMITS
- #include <limits.h>
- #endif
- #ifndef _INC_CRTDBG
- #include <crtdbg.h>
- #endif
- #ifndef _INC_MALLOC
- #include <malloc.h>
- #endif
- #ifndef _INC_MMSYSTEM
- #include <mmsystem.h>
- #endif
- #ifndef __comcat_h__
- #include <comcat.h>
- #endif
- //=== Constants ==============================================================
- #define sp_countof(x) ((sizeof(x) / sizeof(*(x))))
- #define SP_IS_BAD_WRITE_PTR(p) ( SPIsBadWritePtr( p, sizeof(*(p)) ))
- #define SP_IS_BAD_READ_PTR(p) ( SPIsBadReadPtr( p, sizeof(*(p)) ))
- #define SP_IS_BAD_CODE_PTR(p) ( ::IsBadCodePtr((FARPROC)(p) )
- #define SP_IS_BAD_INTERFACE_PTR(p) ( SPIsBadInterfacePtr( (p) ) )
- #define SP_IS_BAD_VARIANT_PTR(p) ( SPIsBadVARIANTPtr( (p) ) )
- #define SP_IS_BAD_STRING_PTR(p) ( SPIsBadStringPtr( (p) ) )
- #define SP_IS_BAD_OPTIONAL_WRITE_PTR(p) ((p) && SPIsBadWritePtr( p, sizeof(*(p)) ))
- #define SP_IS_BAD_OPTIONAL_READ_PTR(p) ((p) && SPIsBadReadPtr( p, sizeof(*(p)) ))
- #define SP_IS_BAD_OPTIONAL_INTERFACE_PTR(p) ((p) && SPIsBadInterfacePtr(p))
- #define SP_IS_BAD_OPTIONAL_STRING_PTR(p) ((p) && SPIsBadStringPtr(p))
- //=== Class, Enum, Struct, Template, and Union Declarations ==================
- //=== Inlines ================================================================
- /*** Pointer validation functions
- */
- // TODO: Add decent debug output for bad parameters
- inline BOOL SPIsBadStringPtr( const WCHAR * psz, ULONG cMaxChars = 0xFFFF )
- {
- BOOL IsBad = false;
- __try
- {
- do
- {
- if( *psz++ == 0 ) return IsBad;
- }
- while( --cMaxChars );
- }
- __except( GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION )
- {
- IsBad = true;
- }
- return IsBad;
- }
- inline BOOL SPIsBadReadPtr( const void* pMem, UINT Size )
- {
- #ifdef _DEBUG
- BOOL bIsBad = ::IsBadReadPtr( pMem, Size );
- SPDBG_ASSERT(!bIsBad);
- return bIsBad;
- #else
- return ::IsBadReadPtr( pMem, Size );
- #endif
- }
- inline BOOL SPIsBadWritePtr( void* pMem, UINT Size )
- {
- #ifdef _DEBUG
- BOOL bIsBad = ::IsBadWritePtr( pMem, Size );
- SPDBG_ASSERT(!bIsBad);
- return bIsBad;
- #else
- return ::IsBadWritePtr( pMem, Size );
- #endif
- }
- inline BOOL SPIsBadInterfacePtr( const IUnknown* pUnknown )
- {
- #ifdef _DEBUG
- BOOL bIsBad = ( ::IsBadReadPtr( pUnknown, sizeof( *pUnknown ) ) ||
- ::IsBadCodePtr( (FARPROC)((void**)pUnknown)[0] ))?
- (true):(false);
- SPDBG_ASSERT(!bIsBad);
- return bIsBad;
- #else
- return ( ::IsBadReadPtr( pUnknown, sizeof( *pUnknown ) ) ||
- ::IsBadCodePtr( (FARPROC)((void**)pUnknown)[0] ))?
- (true):(false);
- #endif
- }
- inline BOOL SPIsBadVARIANTPtr( const VARIANT* pVar )
- {
- #ifdef _DEBUG
- BOOL bIsBad = ::IsBadReadPtr( pVar, sizeof( *pVar ) );
- SPDBG_ASSERT(!bIsBad);
- return bIsBad;
- #else
- return ::IsBadReadPtr( pVar, sizeof( *pVar ) );
- #endif
- }
- #ifdef __ATLCOM_H__ //--- Only enable these if ATL is being used
- //
- // Helper functions can be used to implement GetObjectToken/SetObjectToken for objects that
- // support ISpObjectWithToken
- //
- inline HRESULT SpGenericSetObjectToken(ISpObjectToken * pCallersToken, CComPtr<ISpObjectToken> & cpObjToken)
- {
- HRESULT hr = S_OK;
- if (SP_IS_BAD_INTERFACE_PTR(pCallersToken))
- {
- hr = E_INVALIDARG;
- }
- else
- {
- if (cpObjToken)
- {
- hr = SPERR_ALREADY_INITIALIZED;
- }
- else
- {
- cpObjToken = pCallersToken;
- }
- }
- return hr;
- }
- inline HRESULT SpGenericGetObjectToken(ISpObjectToken ** ppCallersToken, CComPtr<ISpObjectToken> & cpObjToken)
- {
- HRESULT hr = S_OK;
- if (SP_IS_BAD_WRITE_PTR(ppCallersToken))
- {
- hr = E_POINTER;
- }
- else
- {
- *ppCallersToken = cpObjToken;
- if (*ppCallersToken)
- {
- (*ppCallersToken)->AddRef();
- }
- else
- {
- hr = S_FALSE;
- }
- }
- return hr;
- }
- #endif // __ATLCOM_H__
- //
- // Helper class for SPSTATEINFO sturcture automatically initializes and cleans up
- // the structure + provides a few helper functions.
- //
- class CSpStateInfo : public SPSTATEINFO
- {
- public:
- CSpStateInfo()
- {
- cAllocatedEntries = NULL;
- pTransitions = NULL;
- }
- ~CSpStateInfo()
- {
- ::CoTaskMemFree(pTransitions);
- }
- SPTRANSITIONENTRY * FirstEpsilon()
- {
- return pTransitions;
- }
- SPTRANSITIONENTRY * FirstRule()
- {
- return pTransitions + cEpsilons;
- }
- SPTRANSITIONENTRY * FirstWord()
- {
- return pTransitions + cEpsilons + cRules;
- }
- SPTRANSITIONENTRY * FirstSpecialTransition()
- {
- return pTransitions + cEpsilons + cRules + cWords;
- }
- };
- //
- // This basic queue implementation can be used to maintin linked lists of classes. The class T
- // must contain the member m_pNext which is used by this template to point to the next element.
- // If the bPurgeWhenDeleted is TRUE then all of the elements in the queue will be deleted
- // when the queue is deleted, otherwise they will not.
- // If bMaintainCount is TRUE then a running count will be maintained, and GetCount() will be
- // efficent. If it is FALSE then a running count will not be maintained, and GetCount() will
- // be an order N operation. If you do not require a count, then
- //
- template <class T, BOOL bPurgeWhenDeleted> class CSpBasicList;
- template <class T, BOOL bPurgeWhenDeleted = TRUE, BOOL bMaintainCount = FALSE>
- class CSpBasicQueue
- {
- public:
- T * m_pHead;
- T * m_pTail;
- ULONG m_cElements; // Warning! Use GetCount() -- Not maintained if bMaintainCount is FALSE.
- CSpBasicQueue()
- {
- m_pHead = NULL;
- if (bMaintainCount)
- {
- m_cElements = 0;
- }
- }
- ~CSpBasicQueue()
- {
- if (bPurgeWhenDeleted)
- {
- Purge();
- }
- }
- HRESULT CreateNode(T ** ppNode)
- {
- *ppNode = new T;
- if (*ppNode)
- {
- return S_OK;
- }
- else
- {
- return E_OUTOFMEMORY;
- }
- }
- T * GetNext(const T * pNode)
- {
- return pNode->m_pNext;
- }
- T * Item(ULONG i)
- {
- T * pNode = m_pHead;
- while (pNode && i)
- {
- i--;
- pNode = pNode->m_pNext;
- }
- return pNode;
- }
- void InsertAfter(T * pPrev, T * pNewNode)
- {
- if (pPrev)
- {
- pNewNode->m_pNext = pPrev->m_pNext;
- pPrev->m_pNext = pNewNode;
- if (pNewNode->m_pNext == NULL)
- {
- m_pTail = pNewNode;
- }
- if (bMaintainCount) ++m_cElements;
- }
- else
- {
- InsertHead(pNewNode);
- }
- }
- void InsertTail(T * pNode)
- {
- pNode->m_pNext = NULL;
- if (m_pHead)
- {
- m_pTail->m_pNext = pNode;
- }
- else
- {
- m_pHead = pNode;
- }
- m_pTail = pNode;
- if (bMaintainCount) ++m_cElements;
- }
- void InsertHead(T * pNode)
- {
- pNode->m_pNext = m_pHead;
- if (m_pHead == NULL)
- {
- m_pTail = pNode;
- }
- m_pHead = pNode;
- if (bMaintainCount) ++m_cElements;
- }
- T * RemoveHead()
- {
- T * pNode = m_pHead;
- if (pNode)
- {
- m_pHead = pNode->m_pNext;
- if (bMaintainCount) --m_cElements;
- }
- return pNode;
- }
- T * RemoveTail()
- {
- T * pNode = m_pHead;
- if (pNode)
- {
- if (pNode == m_pTail)
- {
- m_pHead = NULL;
- }
- else
- {
- T * pPrev;
- do
- {
- pPrev = pNode;
- pNode = pNode->m_pNext;
- } while ( pNode != m_pTail );
- pPrev->m_pNext = NULL;
- m_pTail = pPrev;
- }
- if (bMaintainCount) --m_cElements;
- }
- return pNode;
- }
- void Purge()
- {
- while (m_pHead)
- {
- T * pDie = m_pHead;
- m_pHead = pDie->m_pNext;
- delete pDie;
- }
- if (bMaintainCount) m_cElements = 0;
- }
- void ExplicitPurge()
- {
- T * pDie;
- BYTE * pb;
- while (m_pHead)
- {
- pDie = m_pHead;
- m_pHead = pDie->m_pNext;
- pDie->~T();
- pb = reinterpret_cast<BYTE *>(pDie);
- delete [] pb;
- }
- if (bMaintainCount) m_cElements = 0;
- }
- T * GetTail() const
- {
- if (m_pHead)
- {
- return m_pTail;
- }
- return NULL;
- }
- T * GetHead() const
- {
- return m_pHead;
- }
- BOOL IsEmpty() const
- {
- return m_pHead == NULL;
- }
- BOOL Remove(T * pNode)
- {
- if (m_pHead == pNode)
- {
- m_pHead = pNode->m_pNext;
- if (bMaintainCount) --m_cElements;
- return TRUE;
- }
- else
- {
- T * pCur = m_pHead;
- while (pCur)
- {
- T * pNext = pCur->m_pNext;
- if (pNext == pNode)
- {
- if ((pCur->m_pNext = pNode->m_pNext) == NULL)
- {
- m_pTail = pCur;
- }
- if (bMaintainCount) --m_cElements;
- return TRUE;
- }
- pCur = pNext;
- }
- }
- return FALSE;
- }
- void MoveAllToHeadOf(CSpBasicQueue & DestQueue)
- {
- if (m_pHead)
- {
- m_pTail->m_pNext = DestQueue.m_pHead;
- if (DestQueue.m_pHead == NULL)
- {
- DestQueue.m_pTail = m_pTail;
- }
- DestQueue.m_pHead = m_pHead;
- m_pHead = NULL;
- if (bMaintainCount)
- {
- DestQueue.m_cElements += m_cElements;
- m_cElements = 0;
- }
- }
- }
- void MoveAllToList(CSpBasicList<T, bPurgeWhenDeleted> & List)
- {
- if (m_pHead)
- {
- m_pTail->m_pNext = List.m_pFirst;
- List.m_pFirst = m_pHead;
- m_pHead = NULL;
- }
- if (bMaintainCount)
- {
- m_cElements = 0;
- }
- }
- BOOL MoveToList(T * pNode, CSpBasicList<T, bPurgeWhenDeleted> & List)
- {
- BOOL bFound = Remove(pNode);
- if (bFound)
- {
- List.AddNode(pNode);
- }
- return bFound;
- }
- ULONG GetCount() const
- {
- if (bMaintainCount)
- {
- return m_cElements;
- }
- else
- {
- ULONG c = 0;
- for (T * pNode = m_pHead;
- pNode;
- pNode = pNode->m_pNext, c++) {}
- return c;
- }
- }
- //
- // The following functions require the class T to implement a static function:
- //
- // LONG Compare(const T * pElem1, const T * pElem2)
- //
- // which returns < 0 if pElem1 is less than pElem2, 0 if they are equal, and > 0 if
- // pElem1 is greater than pElem2.
- //
- void InsertSorted(T * pNode)
- {
- if (m_pHead)
- {
- if (T::Compare(pNode, m_pTail) >= 0)
- {
- pNode->m_pNext = NULL;
- m_pTail->m_pNext = pNode;
- m_pTail = pNode;
- }
- else
- {
- //
- // We don't have to worry about walking off of the end of the list here since
- // we have already checked the tail.
- //
- T ** ppNext = &m_pHead;
- while (T::Compare(pNode, *ppNext) >= 0)
- {
- ppNext = &((*ppNext)->m_pNext);
- }
- pNode->m_pNext = *ppNext;
- *ppNext = pNode;
- }
- }
- else
- {
- pNode->m_pNext = NULL;
- m_pHead = m_pTail = pNode;
- }
- if (bMaintainCount) ++m_cElements;
- }
- HRESULT InsertSortedUnique(T * pNode)
- {
- HRESULT hr = S_OK;
- if (m_pHead)
- {
- if (T::Compare(pNode, m_pTail) > 0)
- {
- pNode->m_pNext = NULL;
- m_pTail->m_pNext = pNode;
- m_pTail = pNode;
- }
- else
- {
- //
- // We don't have to worry about walking off of the end of the list here since
- // we have already checked the tail.
- //
- T ** ppNext = &m_pHead;
- while (T::Compare(pNode, *ppNext) > 0)
- {
- ppNext = &((*ppNext)->m_pNext);
- }
- if (T::Compare(pNode, *ppNext) != 0)
- {
- pNode->m_pNext = *ppNext;
- *ppNext = pNode;
- }
- else
- {
- delete pNode;
- hr = S_FALSE;
- }
- }
- }
- else
- {
- pNode->m_pNext = NULL;
- m_pHead = m_pTail = pNode;
- }
- if (bMaintainCount) ++m_cElements;
- return hr;
- }
- //
- // These functions must support the "==" operator for the TFIND type.
- //
- template <class TFIND>
- T * Find(TFIND & FindVal) const
- {
- for (T * pNode = m_pHead; pNode && (!(*pNode == FindVal)); pNode = pNode->m_pNext)
- {}
- return pNode;
- }
- template <class TFIND>
- T * FindNext(const T * pCurNode, TFIND & FindVal) const
- {
- for (T * pNode = pCurNode->m_pNext; pNode && (!(*pNode == FindVal)); pNode = pNode->m_pNext)
- {}
- return pNode;
- }
- //
- // Searches for and removes a single list element
- //
- template <class TFIND>
- T * FindAndRemove(TFIND & FindVal)
- {
- T * pNode = m_pHead;
- if (pNode)
- {
- if (*pNode == FindVal)
- {
- m_pHead = pNode->m_pNext;
- if (bMaintainCount) --m_cElements;
- }
- else
- {
- T * pPrev = pNode;
- for (pNode = pNode->m_pNext;
- pNode;
- pPrev = pNode, pNode = pNode->m_pNext)
- {
- if (*pNode == FindVal)
- {
- pPrev->m_pNext = pNode->m_pNext;
- if (pNode->m_pNext == NULL)
- {
- m_pTail = pPrev;
- }
- if (bMaintainCount) --m_cElements;
- break;
- }
- }
- }
- }
- return pNode;
- }
- //
- // Searches for and deletes all list elements that match
- //
- template <class TFIND>
- void FindAndDeleteAll(TFIND & FindVal)
- {
- T * pNode = m_pHead;
- while (pNode && *pNode == FindVal)
- {
- m_pHead = pNode->m_pNext;
- delete pNode;
- if (bMaintainCount) --m_cElements;
- pNode = m_pHead;
- }
- T * pPrev = pNode;
- while (pNode)
- {
- T * pNext = pNode->m_pNext;
- if (*pNode == FindVal)
- {
- pPrev->m_pNext = pNext;
- delete pNode;
- if (bMaintainCount) --m_cElements;
- }
- else
- {
- pPrev = pNode;
- }
- pNode = pNext;
- }
- m_pTail = pPrev; // Just always set it in case we removed the tail.
- }
- };
- template <class T, BOOL bPurgeWhenDeleted = TRUE>
- class CSpBasicList
- {
- public:
- T * m_pFirst;
- CSpBasicList() : m_pFirst(NULL) {}
- ~CSpBasicList()
- {
- if (bPurgeWhenDeleted)
- {
- Purge();
- }
- }
- void Purge()
- {
- while (m_pFirst)
- {
- T * pNext = m_pFirst->m_pNext;
- delete m_pFirst;
- m_pFirst = pNext;
- }
- }
- void ExplicitPurge()
- {
- T * pDie;
- BYTE * pb;
- while (m_pFirst)
- {
- pDie = m_pFirst;
- m_pFirst = pDie->m_pNext;
- pDie->~T();
- pb = reinterpret_cast<BYTE *>(pDie);
- delete [] pb;
- }
- }
- HRESULT RemoveFirstOrAllocateNew(T ** ppNode)
- {
- if (m_pFirst)
- {
- *ppNode = m_pFirst;
- m_pFirst = m_pFirst->m_pNext;
- }
- else
- {
- *ppNode = new T;
- if (*ppNode == NULL)
- {
- return E_OUTOFMEMORY;
- }
- }
- return S_OK;
- }
- void AddNode(T * pNode)
- {
- pNode->m_pNext = m_pFirst;
- m_pFirst = pNode;
- }
- T * GetFirst()
- {
- return m_pFirst;
- }
- T * RemoveFirst()
- {
- T * pNode = m_pFirst;
- if (pNode)
- {
- m_pFirst = pNode->m_pNext;
- }
- return pNode;
- }
- };
- #define STACK_ALLOC(TYPE, COUNT) (TYPE *)_alloca(sizeof(TYPE) * (COUNT))
- #define STACK_ALLOC_AND_ZERO(TYPE, COUNT) (TYPE *)memset(_alloca(sizeof(TYPE) * (COUNT)), 0, (sizeof(TYPE) * (COUNT)))
- #define STACK_ALLOC_AND_COPY(TYPE, COUNT, SOURCE) (TYPE *)memcpy(_alloca(sizeof(TYPE) * (COUNT)), (SOURCE), (sizeof(TYPE) * (COUNT)))
- inline HRESULT SpGetSubTokenFromToken(
- ISpObjectToken * pToken,
- const WCHAR * pszSubKeyName,
- ISpObjectToken ** ppToken,
- BOOL fCreateIfNotExist = FALSE)
- {
- SPDBG_FUNC("SpGetTokenFromDataKey");
- HRESULT hr = S_OK;
- if (SP_IS_BAD_INTERFACE_PTR(pToken) ||
- SP_IS_BAD_STRING_PTR(pszSubKeyName) ||
- SP_IS_BAD_WRITE_PTR(ppToken))
- {
- hr = E_POINTER;
- }
- // First, either create or open the datakey for the new token
- CComPtr<ISpDataKey> cpDataKeyForNewToken;
- if (SUCCEEDED(hr))
- {
- if (fCreateIfNotExist)
- {
- hr = pToken->CreateKey(pszSubKeyName, &cpDataKeyForNewToken);
- }
- else
- {
- hr = pToken->OpenKey(pszSubKeyName, &cpDataKeyForNewToken);
- }
- }
- // The sub token's category will be the token id of it's parent token
- CSpDynamicString dstrCategoryId;
- if (SUCCEEDED(hr))
- {
- hr = pToken->GetId(&dstrCategoryId);
- }
- // The sub token's token id will be it's category id + "\" the key name
- CSpDynamicString dstrTokenId;
- if (SUCCEEDED(hr))
- {
- dstrTokenId = dstrCategoryId;
- dstrTokenId.Append2(L"\", pszSubKeyName);
- }
- // Now create the token and initalize it
- CComPtr<ISpObjectTokenInit> cpTokenInit;
- if (SUCCEEDED(hr))
- {
- hr = cpTokenInit.CoCreateInstance(CLSID_SpObjectToken);
- }
- if (SUCCEEDED(hr))
- {
- hr = cpTokenInit->InitFromDataKey(dstrCategoryId, dstrTokenId, cpDataKeyForNewToken);
- }
- if (SUCCEEDED(hr))
- {
- *ppToken = cpTokenInit.Detach();
- }
- SPDBG_REPORT_ON_FAIL(hr);
- return hr;
- }
- template<class T>
- HRESULT SpCreateObjectFromSubToken(ISpObjectToken * pToken, const WCHAR * pszSubKeyName, T ** ppObject,
- IUnknown * pUnkOuter = NULL, DWORD dwClsCtxt = CLSCTX_ALL)
- {
- SPDBG_FUNC("SpCreateObjectFromSubToken");
- HRESULT hr;
- CComPtr<ISpObjectToken> cpSubToken;
- hr = SpGetSubTokenFromToken(pToken, pszSubKeyName, &cpSubToken);
-
- if (SUCCEEDED(hr))
- {
- hr = SpCreateObjectFromToken(cpSubToken, ppObject, pUnkOuter, dwClsCtxt);
- }
- SPDBG_REPORT_ON_FAIL(hr);
- return hr;
- }
- #endif /* This must be the last line in the file */