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

  1. /*
  2. * GUIDHASH.C
  3. *
  4. * RSM Service : RSM Object Hash (by GUID)
  5. *
  6. * Author: ErvinP
  7. *
  8. * (c) 2001 Microsoft Corporation
  9. *
  10. */
  11. #include <windows.h>
  12. #include <stdlib.h>
  13. #include <wtypes.h>
  14. #include <ntmsapi.h>
  15. #include "internal.h"
  16. #include "resource.h"
  17. #include "debug.h"
  18. /*
  19. * Our HASH is indexed by a function on an object's GUID.
  20. * There is a linked list at each hash table entry to resolve collisions.
  21. */
  22. #define HASH_SIZE 256
  23. #define HASH_FUNC(lpGuid) (UINT)(UCHAR)(*(PUCHAR)(lpGuid) + *((PUCHAR)(lpGuid)+sizeof(NTMS_GUID)-1))
  24. LIST_ENTRY guidHashTable[HASH_SIZE];
  25. VOID InitGuidHash()
  26. {
  27. int i;
  28. for (i = 0; i < HASH_SIZE; i++){
  29. InitializeListHead(&guidHashTable[i]);
  30. }
  31. }
  32. VOID InsertObjectInGuidHash(OBJECT_HEADER *obj)
  33. {
  34. UINT index = HASH_FUNC(&obj->guid);
  35. /*
  36. * Unfortunately, have to use a global spinlock for the hash table.
  37. */
  38. EnterCriticalSection(&g_globalServiceLock);
  39. ASSERT(IsEmptyList(&obj->hashListEntry));
  40. ASSERT(!obj->isDeleted);
  41. InsertTailList(&guidHashTable[index], &obj->hashListEntry);
  42. LeaveCriticalSection(&g_globalServiceLock);
  43. }
  44. VOID RemoveObjectFromGuidHash(OBJECT_HEADER *obj)
  45. {
  46. /*
  47. * Unfortunately, have to use a global spinlock for the hash table.
  48. */
  49. EnterCriticalSection(&g_globalServiceLock);
  50. ASSERT(!IsEmptyList(&obj->hashListEntry));
  51. ASSERT(!IsEmptyList(&guidHashTable[HASH_FUNC(obj->guid)]));
  52. RemoveEntryList(&obj->hashListEntry);
  53. InitializeListHead(&obj->hashListEntry);
  54. LeaveCriticalSection(&g_globalServiceLock);
  55. }
  56. OBJECT_HEADER *FindObjectInGuidHash(NTMS_GUID *guid)
  57. {
  58. UINT index = HASH_FUNC(guid);
  59. OBJECT_HEADER *foundObj = NULL;
  60. LIST_ENTRY *listEntry;
  61. /*
  62. * Unfortunately, have to use a global spinlock for the hash table.
  63. */
  64. EnterCriticalSection(&g_globalServiceLock);
  65. listEntry = &guidHashTable[index];
  66. while ((listEntry = listEntry->Flink) != &guidHashTable[index]){
  67. OBJECT_HEADER *thisObj = CONTAINING_RECORD(listEntry, OBJECT_HEADER, hashListEntry);
  68. if (RtlEqualMemory(&thisObj->guid, guid, sizeof(NTMS_GUID))){
  69. if (!foundObj->isDeleted){
  70. foundObj = thisObj;
  71. RefObject(thisObj);
  72. }
  73. break;
  74. }
  75. }
  76. LeaveCriticalSection(&g_globalServiceLock);
  77. return foundObj;
  78. }
  79. /*
  80. * RefObject
  81. *
  82. * Add a reference to the object.
  83. * An object's refCount is incremented when:
  84. * 1. a pointer to it is returned from a guid hash lookup
  85. * or
  86. * 2. its handle or GUID is returned to an RSM client app
  87. *
  88. */
  89. VOID RefObject(PVOID objectPtr)
  90. {
  91. OBJECT_HEADER *objHdr = (OBJECT_HEADER *)objectPtr;
  92. InterlockedIncrement(&objHdr->refCount);
  93. }
  94. VOID DerefObject(PVOID objectPtr)
  95. {
  96. OBJECT_HEADER *objHdr = (OBJECT_HEADER *)objectPtr;
  97. LONG newRefCount;
  98. newRefCount = InterlockedDecrement(&objHdr->refCount);
  99. ASSERT(newRefCount >= 0);
  100. if (newRefCount == 0){
  101. ASSERT(objHdr->isDeleted);
  102. // BUGBUG FINISH
  103. }
  104. }