Source code of Windows XP (NT5)
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.

306 lines
6.9 KiB

  1. /*++
  2. Copyright (c) 1997-1999 Microsoft Corporation
  3. Module Name:
  4. main.c
  5. Abstract:
  6. Implements WMI GUID handle management code
  7. Author:
  8. 16-Jan-1997 AlanWar
  9. Revision History:
  10. --*/
  11. #include "wmiump.h"
  12. #include <rpc.h>
  13. BOOLEAN WmipIsNumber(
  14. LPCWSTR String
  15. )
  16. {
  17. while (*String != UNICODE_NULL)
  18. {
  19. if ((*String < L'0') ||
  20. (*String++ > L'9'))
  21. {
  22. return(FALSE);
  23. }
  24. }
  25. return(TRUE);
  26. }
  27. #define WmipWStringSizeInBytes(string) \
  28. ( ( (wcslen((string)) + 1) * sizeof(WCHAR) ) )
  29. ULONG WmipBaseCookieIndex;
  30. LIST_ENTRY WmipCookieHead = {&WmipCookieHead, &WmipCookieHead};
  31. PNOTIFYCOOKIE WmipFindCookieByGuid(
  32. LPGUID Guid,
  33. PNOTIFYCOOKIECHUNK *Chunk
  34. )
  35. /*+++
  36. Routine Description:
  37. This routine assumes the PM critical section is held
  38. Arguments:
  39. Return Value:
  40. ---*/
  41. {
  42. PLIST_ENTRY CookieList;
  43. PNOTIFYCOOKIECHUNK CookieChunk;
  44. PNOTIFYCOOKIE Cookie;
  45. ULONG i;
  46. CookieList = WmipCookieHead.Flink;
  47. while (CookieList != &WmipCookieHead)
  48. {
  49. CookieChunk = CONTAINING_RECORD(CookieList,
  50. NOTIFYCOOKIECHUNK,
  51. Next);
  52. for (i = 0; i < NOTIFYCOOKIESPERCHUNK; i++)
  53. {
  54. Cookie = &CookieChunk->Cookies[i];
  55. if ((Cookie->InUse) &&
  56. (IsEqualGUID(Guid, &Cookie->Guid)))
  57. {
  58. *Chunk = CookieChunk;
  59. return(Cookie);
  60. }
  61. }
  62. CookieList = CookieList->Flink;
  63. }
  64. return(NULL);
  65. }
  66. ULONG WmipAllocateCookie(
  67. PVOID DeliveryInfo,
  68. PVOID DeliveryContext,
  69. LPGUID Guid
  70. )
  71. {
  72. PLIST_ENTRY CookieList;
  73. PNOTIFYCOOKIECHUNK CookieChunk;
  74. PNOTIFYCOOKIE Cookie;
  75. ULONG i;
  76. ULONG CheckSlot, FreeSlot;
  77. WmipEnterPMCritSection();
  78. while (1)
  79. {
  80. CookieList = WmipCookieHead.Flink;
  81. while (CookieList != &WmipCookieHead)
  82. {
  83. CookieChunk = CONTAINING_RECORD(CookieList,
  84. NOTIFYCOOKIECHUNK,
  85. Next);
  86. if (! CookieChunk->Full)
  87. {
  88. FreeSlot = CookieChunk->FreeSlot;
  89. for (i = 0; i < NOTIFYCOOKIESPERCHUNK; i++)
  90. {
  91. CheckSlot = (FreeSlot + i) % NOTIFYCOOKIESPERCHUNK;
  92. if (! CookieChunk->Cookies[CheckSlot].InUse)
  93. {
  94. //
  95. // We found a free cookie slot
  96. Cookie = &CookieChunk->Cookies[CheckSlot];
  97. Cookie->InUse = TRUE;
  98. CookieChunk->FreeSlot = (USHORT)((CheckSlot + 1) % NOTIFYCOOKIESPERCHUNK);
  99. WmipLeavePMCritSection();
  100. Cookie->DeliveryInfo = DeliveryInfo;
  101. Cookie->DeliveryContext = DeliveryContext;
  102. Cookie->Guid = *Guid;
  103. return(CookieChunk->BaseSlot + CheckSlot + 1);
  104. }
  105. }
  106. //
  107. // All slots were full so mark as such
  108. CookieChunk->Full = TRUE;
  109. }
  110. CookieList = CookieList->Flink;
  111. }
  112. //
  113. // No free cookie slots, allocate a new chunk
  114. CookieChunk = WmipAlloc(sizeof(NOTIFYCOOKIECHUNK));
  115. if (CookieChunk == NULL)
  116. {
  117. WmipLeavePMCritSection();
  118. return(0);
  119. }
  120. memset(CookieChunk, 0, sizeof(NOTIFYCOOKIECHUNK));
  121. CookieChunk->BaseSlot = WmipBaseCookieIndex;
  122. WmipBaseCookieIndex += NOTIFYCOOKIESPERCHUNK;
  123. InsertHeadList(&WmipCookieHead, &CookieChunk->Next);
  124. }
  125. }
  126. PNOTIFYCOOKIE WmipFindCookie(
  127. ULONG CookieSlot,
  128. LPGUID Guid,
  129. PNOTIFYCOOKIECHUNK *Chunk
  130. )
  131. /*+++
  132. Routine Description:
  133. This routine assumes the PM critical section is held
  134. Arguments:
  135. Return Value:
  136. ---*/
  137. {
  138. PLIST_ENTRY CookieList;
  139. PNOTIFYCOOKIE Cookie;
  140. PNOTIFYCOOKIECHUNK CookieChunk;
  141. WmipAssert(CookieSlot != 0);
  142. CookieSlot--;
  143. CookieList = WmipCookieHead.Flink;
  144. while (CookieList != &WmipCookieHead)
  145. {
  146. CookieChunk = CONTAINING_RECORD(CookieList,
  147. NOTIFYCOOKIECHUNK,
  148. Next);
  149. if ((CookieSlot >= CookieChunk->BaseSlot) &&
  150. (CookieSlot < (CookieChunk->BaseSlot + NOTIFYCOOKIESPERCHUNK)))
  151. {
  152. Cookie = &CookieChunk->Cookies[CookieSlot - CookieChunk->BaseSlot];
  153. if (Guid != NULL)
  154. {
  155. if ((! Cookie->InUse) ||
  156. (! IsEqualGUID(&Cookie->Guid, Guid)))
  157. {
  158. Cookie = WmipFindCookieByGuid(Guid, &CookieChunk);
  159. }
  160. } else {
  161. if (! (Cookie->InUse) )
  162. return NULL;
  163. }
  164. *Chunk = CookieChunk;
  165. return(Cookie);
  166. }
  167. CookieList = CookieList->Flink;
  168. }
  169. if (Guid != NULL)
  170. {
  171. Cookie = WmipFindCookieByGuid(Guid, &CookieChunk);
  172. } else {
  173. Cookie = NULL;
  174. }
  175. return(Cookie);
  176. }
  177. void WmipFreeCookie(
  178. ULONG CookieSlot
  179. )
  180. {
  181. PNOTIFYCOOKIE Cookie;
  182. PNOTIFYCOOKIECHUNK CookieChunk;
  183. WmipEnterPMCritSection();
  184. Cookie = WmipFindCookie(CookieSlot, NULL, &CookieChunk);
  185. if (Cookie != NULL)
  186. {
  187. Cookie->InUse = FALSE;
  188. CookieChunk->Full = FALSE;
  189. CookieChunk->FreeSlot = (USHORT)(CookieSlot - CookieChunk->BaseSlot - 1);
  190. }
  191. WmipLeavePMCritSection();
  192. }
  193. void
  194. WmipGetGuidInCookie(
  195. ULONG CookieSlot,
  196. LPGUID Guid
  197. )
  198. {
  199. PNOTIFYCOOKIE Cookie;
  200. PNOTIFYCOOKIECHUNK CookieChunk;
  201. WmipEnterPMCritSection();
  202. Cookie = WmipFindCookie(CookieSlot, NULL, &CookieChunk);
  203. if (Cookie != NULL)
  204. {
  205. *Guid = Cookie->Guid;
  206. }
  207. WmipLeavePMCritSection();
  208. return;
  209. }
  210. BOOLEAN WmipLookupCookie(
  211. ULONG CookieSlot,
  212. LPGUID Guid,
  213. PVOID *DeliveryInfo,
  214. PVOID *DeliveryContext
  215. )
  216. {
  217. PNOTIFYCOOKIE Cookie;
  218. PNOTIFYCOOKIECHUNK CookieChunk;
  219. WmipEnterPMCritSection();
  220. Cookie = WmipFindCookie(CookieSlot, Guid, &CookieChunk);
  221. if (Cookie != NULL)
  222. {
  223. *DeliveryInfo = Cookie->DeliveryInfo;
  224. *DeliveryContext = Cookie->DeliveryContext;
  225. }
  226. WmipLeavePMCritSection();
  227. return(Cookie != NULL);
  228. }
  229. #if DBG
  230. PCHAR GuidToStringA(
  231. PCHAR s,
  232. LPGUID piid
  233. )
  234. {
  235. GUID XGuid = *piid;
  236. sprintf(s, "%x-%x-%x-%x%x%x%x%x%x%x%x",
  237. XGuid.Data1, XGuid.Data2,
  238. XGuid.Data3,
  239. XGuid.Data4[0], XGuid.Data4[1],
  240. XGuid.Data4[2], XGuid.Data4[3],
  241. XGuid.Data4[4], XGuid.Data4[5],
  242. XGuid.Data4[6], XGuid.Data4[7]);
  243. return(s);
  244. }
  245. #endif