|
|
/*++
Copyright (c) 1997-1999 Microsoft Corporation
Module Name:
main.c
Abstract: Implements WMI GUID handle management code
Author:
16-Jan-1997 AlanWar
Revision History:
--*/
#include "wmiump.h"
#include <rpc.h>
BOOLEAN WmipIsNumber( LPCWSTR String ) { while (*String != UNICODE_NULL) { if ((*String < L'0') || (*String++ > L'9')) { return(FALSE); } } return(TRUE); }
#define WmipWStringSizeInBytes(string) \
( ( (wcslen((string)) + 1) * sizeof(WCHAR) ) )
ULONG WmipBaseCookieIndex; LIST_ENTRY WmipCookieHead = {&WmipCookieHead, &WmipCookieHead};
PNOTIFYCOOKIE WmipFindCookieByGuid( LPGUID Guid, PNOTIFYCOOKIECHUNK *Chunk ) /*+++
Routine Description:
This routine assumes the PM critical section is held Arguments:
Return Value:
---*/ { PLIST_ENTRY CookieList; PNOTIFYCOOKIECHUNK CookieChunk; PNOTIFYCOOKIE Cookie; ULONG i; CookieList = WmipCookieHead.Flink; while (CookieList != &WmipCookieHead) { CookieChunk = CONTAINING_RECORD(CookieList, NOTIFYCOOKIECHUNK, Next);
for (i = 0; i < NOTIFYCOOKIESPERCHUNK; i++) { Cookie = &CookieChunk->Cookies[i]; if ((Cookie->InUse) && (IsEqualGUID(Guid, &Cookie->Guid))) { *Chunk = CookieChunk; return(Cookie); } } CookieList = CookieList->Flink; } return(NULL); }
ULONG WmipAllocateCookie( PVOID DeliveryInfo, PVOID DeliveryContext, LPGUID Guid ) { PLIST_ENTRY CookieList; PNOTIFYCOOKIECHUNK CookieChunk; PNOTIFYCOOKIE Cookie; ULONG i; ULONG CheckSlot, FreeSlot; WmipEnterPMCritSection();
while (1) { CookieList = WmipCookieHead.Flink; while (CookieList != &WmipCookieHead) { CookieChunk = CONTAINING_RECORD(CookieList, NOTIFYCOOKIECHUNK, Next); if (! CookieChunk->Full) { FreeSlot = CookieChunk->FreeSlot; for (i = 0; i < NOTIFYCOOKIESPERCHUNK; i++) { CheckSlot = (FreeSlot + i) % NOTIFYCOOKIESPERCHUNK; if (! CookieChunk->Cookies[CheckSlot].InUse) { //
// We found a free cookie slot
Cookie = &CookieChunk->Cookies[CheckSlot]; Cookie->InUse = TRUE; CookieChunk->FreeSlot = (USHORT)((CheckSlot + 1) % NOTIFYCOOKIESPERCHUNK); WmipLeavePMCritSection(); Cookie->DeliveryInfo = DeliveryInfo; Cookie->DeliveryContext = DeliveryContext; Cookie->Guid = *Guid; return(CookieChunk->BaseSlot + CheckSlot + 1); } } //
// All slots were full so mark as such
CookieChunk->Full = TRUE; } CookieList = CookieList->Flink; } //
// No free cookie slots, allocate a new chunk
CookieChunk = WmipAlloc(sizeof(NOTIFYCOOKIECHUNK)); if (CookieChunk == NULL) { WmipLeavePMCritSection(); return(0); } memset(CookieChunk, 0, sizeof(NOTIFYCOOKIECHUNK)); CookieChunk->BaseSlot = WmipBaseCookieIndex; WmipBaseCookieIndex += NOTIFYCOOKIESPERCHUNK; InsertHeadList(&WmipCookieHead, &CookieChunk->Next); } }
PNOTIFYCOOKIE WmipFindCookie( ULONG CookieSlot, LPGUID Guid, PNOTIFYCOOKIECHUNK *Chunk ) /*+++
Routine Description:
This routine assumes the PM critical section is held Arguments:
Return Value:
---*/ { PLIST_ENTRY CookieList; PNOTIFYCOOKIE Cookie; PNOTIFYCOOKIECHUNK CookieChunk; WmipAssert(CookieSlot != 0); CookieSlot--; CookieList = WmipCookieHead.Flink; while (CookieList != &WmipCookieHead) { CookieChunk = CONTAINING_RECORD(CookieList, NOTIFYCOOKIECHUNK, Next); if ((CookieSlot >= CookieChunk->BaseSlot) && (CookieSlot < (CookieChunk->BaseSlot + NOTIFYCOOKIESPERCHUNK))) { Cookie = &CookieChunk->Cookies[CookieSlot - CookieChunk->BaseSlot]; if (Guid != NULL) { if ((! Cookie->InUse) || (! IsEqualGUID(&Cookie->Guid, Guid))) { Cookie = WmipFindCookieByGuid(Guid, &CookieChunk); } } else { if (! (Cookie->InUse) ) return NULL; } *Chunk = CookieChunk; return(Cookie); } CookieList = CookieList->Flink; } if (Guid != NULL) { Cookie = WmipFindCookieByGuid(Guid, &CookieChunk); } else { Cookie = NULL; } return(Cookie); }
void WmipFreeCookie( ULONG CookieSlot ) { PNOTIFYCOOKIE Cookie; PNOTIFYCOOKIECHUNK CookieChunk; WmipEnterPMCritSection(); Cookie = WmipFindCookie(CookieSlot, NULL, &CookieChunk); if (Cookie != NULL) { Cookie->InUse = FALSE; CookieChunk->Full = FALSE; CookieChunk->FreeSlot = (USHORT)(CookieSlot - CookieChunk->BaseSlot - 1); } WmipLeavePMCritSection(); }
void WmipGetGuidInCookie( ULONG CookieSlot, LPGUID Guid ) { PNOTIFYCOOKIE Cookie; PNOTIFYCOOKIECHUNK CookieChunk;
WmipEnterPMCritSection(); Cookie = WmipFindCookie(CookieSlot, NULL, &CookieChunk); if (Cookie != NULL) { *Guid = Cookie->Guid; } WmipLeavePMCritSection();
return; }
BOOLEAN WmipLookupCookie( ULONG CookieSlot, LPGUID Guid, PVOID *DeliveryInfo, PVOID *DeliveryContext ) { PNOTIFYCOOKIE Cookie; PNOTIFYCOOKIECHUNK CookieChunk; WmipEnterPMCritSection(); Cookie = WmipFindCookie(CookieSlot, Guid, &CookieChunk); if (Cookie != NULL) { *DeliveryInfo = Cookie->DeliveryInfo; *DeliveryContext = Cookie->DeliveryContext; } WmipLeavePMCritSection(); return(Cookie != NULL); }
#if DBG
PCHAR GuidToStringA( PCHAR s, LPGUID piid ) { GUID XGuid = *piid; sprintf(s, "%x-%x-%x-%x%x%x%x%x%x%x%x", XGuid.Data1, XGuid.Data2, XGuid.Data3, XGuid.Data4[0], XGuid.Data4[1], XGuid.Data4[2], XGuid.Data4[3], XGuid.Data4[4], XGuid.Data4[5], XGuid.Data4[6], XGuid.Data4[7]);
return(s); } #endif
|