Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

129 lines
3.2 KiB

/*
* GUIDHASH.C
*
* RSM Service : RSM Object Hash (by GUID)
*
* Author: ErvinP
*
* (c) 2001 Microsoft Corporation
*
*/
#include <windows.h>
#include <stdlib.h>
#include <wtypes.h>
#include <ntmsapi.h>
#include "internal.h"
#include "resource.h"
#include "debug.h"
/*
* Our HASH is indexed by a function on an object's GUID.
* There is a linked list at each hash table entry to resolve collisions.
*/
#define HASH_SIZE 256
#define HASH_FUNC(lpGuid) (UINT)(UCHAR)(*(PUCHAR)(lpGuid) + *((PUCHAR)(lpGuid)+sizeof(NTMS_GUID)-1))
LIST_ENTRY guidHashTable[HASH_SIZE];
VOID InitGuidHash()
{
int i;
for (i = 0; i < HASH_SIZE; i++){
InitializeListHead(&guidHashTable[i]);
}
}
VOID InsertObjectInGuidHash(OBJECT_HEADER *obj)
{
UINT index = HASH_FUNC(&obj->guid);
/*
* Unfortunately, have to use a global spinlock for the hash table.
*/
EnterCriticalSection(&g_globalServiceLock);
ASSERT(IsEmptyList(&obj->hashListEntry));
ASSERT(!obj->isDeleted);
InsertTailList(&guidHashTable[index], &obj->hashListEntry);
LeaveCriticalSection(&g_globalServiceLock);
}
VOID RemoveObjectFromGuidHash(OBJECT_HEADER *obj)
{
/*
* Unfortunately, have to use a global spinlock for the hash table.
*/
EnterCriticalSection(&g_globalServiceLock);
ASSERT(!IsEmptyList(&obj->hashListEntry));
ASSERT(!IsEmptyList(&guidHashTable[HASH_FUNC(obj->guid)]));
RemoveEntryList(&obj->hashListEntry);
InitializeListHead(&obj->hashListEntry);
LeaveCriticalSection(&g_globalServiceLock);
}
OBJECT_HEADER *FindObjectInGuidHash(NTMS_GUID *guid)
{
UINT index = HASH_FUNC(guid);
OBJECT_HEADER *foundObj = NULL;
LIST_ENTRY *listEntry;
/*
* Unfortunately, have to use a global spinlock for the hash table.
*/
EnterCriticalSection(&g_globalServiceLock);
listEntry = &guidHashTable[index];
while ((listEntry = listEntry->Flink) != &guidHashTable[index]){
OBJECT_HEADER *thisObj = CONTAINING_RECORD(listEntry, OBJECT_HEADER, hashListEntry);
if (RtlEqualMemory(&thisObj->guid, guid, sizeof(NTMS_GUID))){
if (!foundObj->isDeleted){
foundObj = thisObj;
RefObject(thisObj);
}
break;
}
}
LeaveCriticalSection(&g_globalServiceLock);
return foundObj;
}
/*
* RefObject
*
* Add a reference to the object.
* An object's refCount is incremented when:
* 1. a pointer to it is returned from a guid hash lookup
* or
* 2. its handle or GUID is returned to an RSM client app
*
*/
VOID RefObject(PVOID objectPtr)
{
OBJECT_HEADER *objHdr = (OBJECT_HEADER *)objectPtr;
InterlockedIncrement(&objHdr->refCount);
}
VOID DerefObject(PVOID objectPtr)
{
OBJECT_HEADER *objHdr = (OBJECT_HEADER *)objectPtr;
LONG newRefCount;
newRefCount = InterlockedDecrement(&objHdr->refCount);
ASSERT(newRefCount >= 0);
if (newRefCount == 0){
ASSERT(objHdr->isDeleted);
// BUGBUG FINISH
}
}