📄 spddkhlp.h
字号:
}
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 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -