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.

207 lines
6.0 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Copyright (c) Microsoft Corporation 1991-1995
  4. //
  5. // File: shared.c
  6. //
  7. // History:
  8. // 06-07-95 BobDay Created.
  9. //
  10. // This file contains a set of routines for the management of shared memory.
  11. //
  12. //---------------------------------------------------------------------------
  13. #include "priv.h"
  14. #pragma hdrstop
  15. //---------------------------------------------------------------------------
  16. // SHAllocShared - Allocates a handle (in a given process) to a copy of a
  17. // memory block in this process.
  18. // SHFreeShared - Releases the handle (and the copy of the memory block)
  19. //
  20. // SHLockShared - Maps a handle (from a given process) into a memory block
  21. // in this process. Has the option of transfering the handle
  22. // to this process, thereby deleting it from the given process
  23. // SHUnlockShared - Opposite of SHLockShared, unmaps the memory block
  24. //---------------------------------------------------------------------------
  25. HANDLE SHMapHandle(HANDLE hData, DWORD dwSource, DWORD dwDest, DWORD dwDesiredAccess, DWORD dwFlags)
  26. {
  27. HANDLE hMap = NULL;
  28. HANDLE hSource;
  29. // Under certain (valid) circumstances it is possible for DDE to
  30. // use :0:pid as the shared memory handle, which we should ignore.
  31. if (hData != NULL)
  32. {
  33. if (dwSource == GetCurrentProcessId())
  34. hSource = GetCurrentProcess();
  35. else
  36. hSource = OpenProcess(PROCESS_DUP_HANDLE, FALSE, dwSource);
  37. if (hSource)
  38. {
  39. HANDLE hDest;
  40. if (dwDest == GetCurrentProcessId())
  41. hDest = GetCurrentProcess();
  42. else
  43. hDest = OpenProcess(PROCESS_DUP_HANDLE, FALSE, dwDest);
  44. if (hDest)
  45. {
  46. if (!DuplicateHandle(hSource, hData, hDest, &hMap,
  47. dwDesiredAccess, FALSE, dwFlags | DUPLICATE_SAME_ACCESS))
  48. {
  49. // may change the value...
  50. hMap = NULL;
  51. }
  52. CloseHandle(hDest);
  53. }
  54. CloseHandle(hSource);
  55. }
  56. }
  57. return hMap;
  58. }
  59. void _FillHeader(SHMAPHEADER *pmh, DWORD dwSize, DWORD dwSrcId, DWORD dwDstId, void *pvData)
  60. {
  61. pmh->dwSize = dwSize;
  62. pmh->dwSig = MAPHEAD_SIG;
  63. pmh->dwSrcId = dwSrcId;
  64. pmh->dwDstId = dwDstId;
  65. if (pvData)
  66. memcpy((pmh + 1), pvData, dwSize);
  67. }
  68. HANDLE _AllocShared(DWORD dwSize, DWORD dwSrcId, DWORD dwDstId, void *pvData, void **ppvLock)
  69. {
  70. HANDLE hShared = NULL;
  71. //
  72. // Make a filemapping handle with this data in it.
  73. //
  74. HANDLE hData = CreateFileMapping((HANDLE)-1, NULL, PAGE_READWRITE, 0,
  75. dwSize + sizeof(SHMAPHEADER),NULL);
  76. if (hData)
  77. {
  78. SHMAPHEADER *pmh = MapViewOfFile(hData, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
  79. if (pmh)
  80. {
  81. _FillHeader(pmh, dwSize, dwSrcId, dwDstId, pvData);
  82. hShared = SHMapHandle(hData, dwSrcId, dwDstId, FILE_MAP_ALL_ACCESS, DUPLICATE_SAME_ACCESS);
  83. if (hShared && ppvLock)
  84. *ppvLock = (pmh+1);
  85. else
  86. UnmapViewOfFile(pmh);
  87. }
  88. CloseHandle(hData);
  89. }
  90. return hShared;
  91. }
  92. #if SHAREDLOCAL
  93. HANDLE _AllocLocal(DWORD dwSize, DWORD dwSrcId, void *pvData, void **ppvLock)
  94. {
  95. SHMAPHEADER *pmh = LocalAlloc(LPTR, dwSize + sizeof(SHMAPHEADER));
  96. if (pmh)
  97. {
  98. _FillHeader(pmh, dwSize, dwSrcId, dwSrcId, pvData);
  99. if (ppvLock)
  100. *ppvLock = (pmh+1);
  101. }
  102. return pmh;
  103. }
  104. LWSTDAPI_(HANDLE) SHAllocSharedEx(DWORD dwSize, DWORD dwDstId, void *pvData, void **ppvLock)
  105. {
  106. DWORD dwSrcId = GetCurrentProcessId();
  107. if (fAllowLocal && dwDstId == dwSrcId)
  108. {
  109. return _AllocLocal(dwSize, dwSrcId, pvData, ppvLock);
  110. }
  111. else
  112. {
  113. return _AllocShared(dwSize, dwSrcId, dwDstId, pvData, ppvLock);
  114. }
  115. }
  116. #endif
  117. HANDLE SHAllocShared(void *pvData, DWORD dwSize, DWORD dwOtherProcId)
  118. {
  119. return _AllocShared(dwSize, GetCurrentProcessId(), dwOtherProcId, pvData, NULL);
  120. }
  121. LWSTDAPI_(void *) SHLockSharedEx(HANDLE hData, DWORD dwOtherProcId, BOOL fWrite)
  122. {
  123. HANDLE hMapped = SHMapHandle(hData, dwOtherProcId, GetCurrentProcessId(), FILE_MAP_ALL_ACCESS,0);
  124. if (hMapped)
  125. {
  126. //
  127. // Now map that new process specific handle and close it
  128. //
  129. DWORD dwAccess = fWrite ? FILE_MAP_WRITE | FILE_MAP_READ : FILE_MAP_READ;
  130. SHMAPHEADER *pmh = (SHMAPHEADER *) MapViewOfFile(hMapped, dwAccess, 0, 0, 0);
  131. CloseHandle(hMapped);
  132. if (pmh)
  133. {
  134. ASSERT(pmh->dwSig == MAPHEAD_SIG);
  135. return (void *)(pmh+1);
  136. }
  137. }
  138. return NULL;
  139. }
  140. LWSTDAPI_(void *) SHLockShared(HANDLE hData, DWORD dwOtherProcId)
  141. {
  142. return SHLockSharedEx(hData, dwOtherProcId, TRUE);
  143. }
  144. LWSTDAPI_(BOOL) SHUnlockShared(void *pvData)
  145. {
  146. SHMAPHEADER *pmh = ((SHMAPHEADER *)pvData) - 1;
  147. // Only assert on Whistler or higher, on downlevel machines SHUnlockShared would sometimes be called
  148. // without this header (the return value from SHAllocShared, for example) and we would fault.
  149. ASSERT(pmh->dwSig == MAPHEAD_SIG);
  150. //
  151. // Now just unmap the view of the file
  152. //
  153. return UnmapViewOfFile(pmh);
  154. }
  155. BOOL SHFreeShared(HANDLE hData, DWORD dwOtherProcId)
  156. {
  157. if (hData)
  158. {
  159. //
  160. // The below call closes the original handle in whatever process it
  161. // came from.
  162. //
  163. HANDLE hMapped = SHMapHandle(hData, dwOtherProcId, GetCurrentProcessId(),
  164. FILE_MAP_ALL_ACCESS, DUPLICATE_CLOSE_SOURCE);
  165. //
  166. // Now free up the local handle
  167. //
  168. return CloseHandle(hMapped);
  169. }
  170. else
  171. {
  172. return TRUE; // vacuous success, closing a NULL handle
  173. }
  174. }