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.

300 lines
6.3 KiB

  1. /*
  2. * LOALLOC.C
  3. *
  4. * Setup, cleanup, and MAPI memory allocation for the low-level
  5. * MAPI utility library.
  6. */
  7. #include "_apipch.h"
  8. #define LOALLOC_C
  9. #ifdef MAC
  10. #define PvGetInstanceGlobalsEx(_x) PvGetInstanceGlobalsMac(kInstMAPIU)
  11. #define ScSetInstanceGlobalsEx(_pinst, _x) ScSetInstanceGlobalsMac(_pinst, kInstMAPIU)
  12. //STDAPI HrCreateGuidNoNet(GUID FAR *pguid);
  13. #endif
  14. #ifndef STATIC
  15. #ifdef DEBUG
  16. #define STATIC
  17. #else
  18. #define STATIC static
  19. #endif
  20. #endif
  21. #ifdef OLD_STUFF
  22. #pragma SEGMENT(MAPI_Util)
  23. #endif // OLD_STUFF
  24. #if defined(WIN32) && !defined(MAC)
  25. const CHAR szMutexName[] = "MAPI_UIDGEN_MUTEX";
  26. //STDAPI HrCreateGuidNoNet(GUID FAR *pguid);
  27. #endif
  28. typedef SCODE (GENMUIDFN)(MAPIUID *lpMuid);
  29. #if defined (WIN32) && !defined (MAC)
  30. extern CRITICAL_SECTION csMapiInit;
  31. #endif
  32. #ifndef MAC
  33. DefineInstList(lpInstUtil);
  34. #endif
  35. STDAPI_(SCODE)
  36. ScInitMapiUtil(ULONG ulFlags)
  37. {
  38. LPINSTUTIL pinst;
  39. SCODE sc = S_OK;
  40. HLH hlh;
  41. #ifdef WIN16
  42. WORD wSS;
  43. HTASK hTask = GetCurrentTask();
  44. _asm mov wSS, ss
  45. #endif
  46. // Cheesy parameter validation
  47. AssertSz(ulFlags == 0L, TEXT("ScInitMapiUtil: reserved flags used"));
  48. pinst = (LPINSTUTIL) PvGetInstanceGlobalsEx(lpInstUtil);
  49. #ifdef WIN16
  50. {
  51. // Verify that the instance structure is valid because on Win16 the
  52. // stack segment could have been re-used by another task. When this
  53. // happens there is a good chance that PvGetInstanceGlobalsEx will
  54. // return a pinst belongs to the previous task. The memory for that
  55. // pinst may not be valid any more (because the system automatically
  56. // deallocates global memory when the task dies), or it may have been
  57. // allocated by some other task (in which case it is valid but isn't
  58. // a pinst anymore). Here we try our best to determine that the pinst
  59. // is indeed the one we were looking for.
  60. if ( pinst
  61. && ( IsBadWritePtr(pinst, sizeof(INSTUTIL))
  62. || pinst->dwBeg != INSTUTIL_SIG_BEG
  63. || pinst->wSS != wSS
  64. || pinst->hTask != hTask
  65. || pinst->pvBeg != pinst
  66. || pinst->dwEnd != INSTUTIL_SIG_END))
  67. {
  68. TraceSz("MAPI: ScInitMapiUtil: Rejecting orphaned instance globals");
  69. (void) ScSetInstanceGlobalsEx(0, lpInstUtil);
  70. pinst = 0;
  71. }
  72. }
  73. #endif
  74. if (pinst)
  75. {
  76. if (pinst->cRef == 0)
  77. {
  78. Assert(pinst->cRefIdle == 0);
  79. Assert(pinst->hlhClient);
  80. }
  81. ++(pinst->cRef);
  82. return S_OK;
  83. }
  84. #if defined (WIN32) && !defined (MAC)
  85. EnterCriticalSection(&csMapiInit);
  86. #endif
  87. // Create local heap for MAPIAllocateBuffer to play in
  88. hlh = LH_Open(0);
  89. if (hlh == 0)
  90. {
  91. sc = MAPI_E_NOT_ENOUGH_MEMORY;
  92. goto ret;
  93. }
  94. LH_SetHeapName(hlh, TEXT("Client MAPIAllocator"));
  95. pinst = (LPINSTUTIL) LH_Alloc(hlh, sizeof(INSTUTIL));
  96. if (!pinst)
  97. {
  98. LH_Close(hlh);
  99. sc = MAPI_E_NOT_ENOUGH_MEMORY;
  100. goto ret;
  101. }
  102. ZeroMemory((LPBYTE) pinst, sizeof(INSTUTIL));
  103. #ifdef WIN16
  104. pinst->dwBeg = INSTUTIL_SIG_BEG;
  105. pinst->wSS = wSS;
  106. pinst->hTask = hTask;
  107. pinst->pvBeg = pinst;
  108. pinst->dwEnd = INSTUTIL_SIG_END;
  109. #endif
  110. // Install the instance data
  111. sc = ScSetInstanceGlobalsEx(pinst, lpInstUtil);
  112. if (sc)
  113. {
  114. LH_Close(hlh);
  115. goto ret;
  116. }
  117. pinst->cRef = 1;
  118. pinst->hlhClient = hlh;
  119. ret:
  120. #if defined (WIN32) && !defined (MAC)
  121. LeaveCriticalSection(&csMapiInit);
  122. #endif
  123. DebugTraceSc(ScInitMapiUtil, sc);
  124. return sc;
  125. }
  126. STDAPI_(void)
  127. DeinitMapiUtil()
  128. {
  129. LPINSTUTIL pinst;
  130. pinst = (LPINSTUTIL) PvGetInstanceGlobalsEx(lpInstUtil);
  131. if (!pinst)
  132. return;
  133. Assert(pinst->cRef);
  134. if (--(pinst->cRef) == 0)
  135. {
  136. #if defined (WIN32) && !defined (MAC)
  137. EnterCriticalSection(&csMapiInit);
  138. #endif
  139. // Idle stuff must already have been cleaned up
  140. Assert(pinst->cRefIdle == 0);
  141. /*
  142. * !!! DO NOT CLOSE THE HEAP OR GET RID OF THE INST !!!
  143. *
  144. * Simple MAPI counts on being able to access and free buffers
  145. * right up until the DLL is unloaded from memory. Therefore we do
  146. * not explicitly close the heap; we count on the OS to make it
  147. * evaporate when the process exits.
  148. * Likewise, MAPIFreeBuffer needs the INSTUTIL to find the heap handle,
  149. * so we never deinstall the INSTUTIL.
  150. *
  151. * // Uninstall the globals.
  152. * (void) ScSetInstanceGlobalsEx(NULL, lpInstUtil);
  153. *
  154. * // Clean up the heap
  155. * hlh = pinst->hlhClient;
  156. * LH_Free(hlh, pinst);
  157. *
  158. * LH_Close(hlh);
  159. */
  160. #if defined (WIN32) && !defined (MAC)
  161. LeaveCriticalSection(&csMapiInit);
  162. #endif
  163. }
  164. }
  165. HLH
  166. HlhUtilities(VOID)
  167. {
  168. LPINSTUTIL pinst = (LPINSTUTIL) PvGetInstanceGlobalsEx(lpInstUtil);
  169. return pinst ? pinst->hlhClient : (HLH) 0;
  170. }
  171. #ifdef NOTIFICATIONS
  172. #ifdef TABLES
  173. #if defined(WIN16)
  174. STDAPI_(SCODE)
  175. ScGenerateMuid (LPMAPIUID lpMuid)
  176. {
  177. return GetScode(CoCreateGuid((LPGUID)lpMuid));
  178. }
  179. #endif // WIN16
  180. #if (defined(WIN32) && !defined(MAC))
  181. STDAPI_(SCODE)
  182. ScGenerateMuid (LPMAPIUID lpMuid)
  183. {
  184. HRESULT hr;
  185. // validate parameter
  186. AssertSz( !IsBadReadPtr( lpMuid, sizeof( MAPIUID ) ), "lpMuid fails address check" );
  187. #ifdef OLD_STUFF
  188. // WAB won't use this... why bother bringing in RPC when we are local anyway?
  189. if (hMuidMutex == NULL)
  190. {
  191. RPC_STATUS rpc_s;
  192. rpc_s = UuidCreate((UUID __RPC_FAR *) lpMuid);
  193. if (rpc_s == RPC_S_OK)
  194. {
  195. hr = hrSuccess;
  196. goto err;
  197. }
  198. else
  199. {
  200. hMuidMutex = CreateMutex(NULL, FALSE, szMutexName);
  201. if (hMuidMutex == NULL)
  202. {
  203. TraceSz1("MAPIU: ScGenerateMuid: call to CreateMutex failed"
  204. " - error %08lX\n", GetLastError());
  205. hr = ResultFromScode(MAPI_E_CALL_FAILED);
  206. goto err;
  207. }
  208. }
  209. }
  210. WaitForSingleObject(hMuidMutex, INFINITE);
  211. hr = HrCreateGuidNoNet((GUID FAR *) lpMuid);
  212. ReleaseMutex(hMuidMutex);
  213. #endif // OLD_STUFF
  214. //$ Note that we don't call CloseHandle on the mutex anywhere. If we're
  215. //$ really worried about this, we could call CloseHandle in the code that
  216. //$ WIN32 calls when the DLL is being unloaded.
  217. hr = CoCreateGuid((GUID *)lpMuid);
  218. err:
  219. DebugTraceResult(ScGenerateMuid, hr);
  220. return GetScode(hr);
  221. }
  222. #endif /* WIN32 - Mac*/
  223. #ifdef MAC
  224. STDAPI_(SCODE)
  225. ScGenerateMuid (LPMAPIUID lpMuid)
  226. {
  227. HRESULT hr;
  228. // hr = HrCreateGuidNoNet((GUID FAR *) lpMuid);
  229. DebugTraceResult(ScGenerateMuid, hr);
  230. return GetScode(hr);
  231. }
  232. #endif // MAC
  233. #endif //#ifdef TABLES
  234. #endif //#ifdef NOTIFICATIONS