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.

228 lines
5.2 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. All rights reserved.
  4. Module Name:
  5. sharemem.cxx
  6. Abstract:
  7. Shared memory implementation.
  8. Author:
  9. Albert Ting (AlbertT) 17-Dec-1996
  10. Revision History:
  11. --*/
  12. #include "precomp.hxx"
  13. #pragma hdrstop
  14. #include "sharemem.hxx"
  15. #ifdef COUNTOF
  16. #undef COUNTOF
  17. #endif
  18. #define COUNTOF(x) (sizeof(x)/sizeof(*x))
  19. LPCTSTR szPrefixFile = TEXT( "_ShrMemF" );
  20. LPCTSTR szPrefixMutex = TEXT( "_ShrMemM" );
  21. TShareMem::
  22. TShareMem(
  23. IN UINT uSize,
  24. IN LPCTSTR pszName,
  25. IN UINT uFlags,
  26. IN PSECURITY_ATTRIBUTES psa, OPTIONAL
  27. OUT PUINT puSizeDisposition OPTIONAL
  28. ) : m_hFile( NULL ), m_hMutex( NULL ), m_pvBase( NULL ),
  29. m_pvUserData( NULL )
  30. /*++
  31. Routine Description:
  32. Create a shared memory access object.
  33. Arguments:
  34. uSize - Size of the buffer requested.
  35. pszName - Name of shared memory object.
  36. uFlags - Options
  37. kCreate - Create a new file mapping. If the mapping already
  38. exists, it will be used (see puSizeDisposition). If
  39. not specified, an existing one will be opened.
  40. kReadWrite - Open with ReadWrite access. If not specified,
  41. Read only access is used.
  42. psa - Pointer to security attributes. Used only if kCreate specified.
  43. puSizeDisposition - If the object already exists, returns its
  44. size. If the object did not exist, returns zero.
  45. Return Value:
  46. --*/
  47. {
  48. UINT cchName;
  49. //
  50. // Validate input and determine the size of the name.
  51. //
  52. if( !uSize || !pszName || !pszName[0] ||
  53. ( cchName = lstrlen( pszName )) >= MAX_PATH )
  54. {
  55. SetLastError( ERROR_INVALID_PARAMETER );
  56. return;
  57. }
  58. DWORD dwAccess = ( uFlags & kReadWrite ) ?
  59. FILE_MAP_READ | FILE_MAP_WRITE :
  60. FILE_MAP_READ;
  61. //
  62. // Pre-initialize output variables.
  63. //
  64. UINT uSizeDispositionDiscard;
  65. if( !puSizeDisposition )
  66. {
  67. puSizeDisposition = &uSizeDispositionDiscard;
  68. }
  69. *puSizeDisposition = 0;
  70. //
  71. // Create or shared mutex that will protect the data. Create
  72. // the new name. This needs to be created first to protect
  73. // against multiple people trying to create the file mapping
  74. // simultaneously.
  75. //
  76. TCHAR szFullName[MAX_PATH + max( COUNTOF( szPrefixFile ),
  77. COUNTOF( szPrefixMutex ))];
  78. lstrcpy( szFullName, pszName );
  79. lstrcpy( &szFullName[cchName], szPrefixMutex );
  80. m_hMutex = CreateMutex( psa,
  81. FALSE,
  82. szFullName );
  83. if( !m_hMutex )
  84. {
  85. return;
  86. }
  87. {
  88. //
  89. // Acquire the mutex for use while we're grabbing the resource.
  90. //
  91. WaitForSingleObject( m_hMutex, INFINITE );
  92. BOOL bFileExists = TRUE;
  93. //
  94. // Create the name of the mapped file.
  95. //
  96. lstrcpy( &szFullName[cchName], szPrefixFile );
  97. //
  98. // Either open or create the map file handle.
  99. //
  100. if( uFlags & kCreate )
  101. {
  102. //
  103. // Create a new map.
  104. //
  105. m_hFile = CreateFileMapping( INVALID_HANDLE_VALUE,
  106. psa,
  107. ( uFlags & kReadWrite ) ?
  108. PAGE_READWRITE :
  109. PAGE_READONLY,
  110. 0,
  111. uSize,
  112. szFullName );
  113. //
  114. // See if it already exists.
  115. //
  116. if( GetLastError() != ERROR_ALREADY_EXISTS )
  117. {
  118. bFileExists = FALSE;
  119. }
  120. }
  121. else
  122. {
  123. //
  124. // Open existing map.
  125. //
  126. m_hFile = OpenFileMapping( dwAccess,
  127. FALSE,
  128. szFullName );
  129. }
  130. if( m_hFile )
  131. {
  132. //
  133. // Map the file into our address space.
  134. //
  135. m_pvBase = MapViewOfFile( m_hFile,
  136. dwAccess,
  137. 0,
  138. 0,
  139. 0 );
  140. if( m_pvBase )
  141. {
  142. if( bFileExists )
  143. {
  144. *puSizeDisposition = GetHeader().uSize;
  145. }
  146. else
  147. {
  148. GetHeader().uHeaderSize = sizeof( HEADER );
  149. GetHeader().uSize = uSize;
  150. }
  151. m_pvUserData = reinterpret_cast<PBYTE>( m_pvBase ) +
  152. GetHeader().uHeaderSize;
  153. }
  154. }
  155. ReleaseMutex( m_hMutex );
  156. }
  157. //
  158. // m_pvUserData is our valid check. If this variable is NULL
  159. // then the object wasn't created correctly.
  160. //
  161. }
  162. TShareMem::
  163. ~TShareMem(
  164. VOID
  165. )
  166. {
  167. if( m_hMutex )
  168. {
  169. CloseHandle( m_hMutex );
  170. }
  171. if( m_pvBase )
  172. {
  173. UnmapViewOfFile( m_pvBase );
  174. }
  175. if( m_hFile )
  176. {
  177. CloseHandle( m_hFile );
  178. }
  179. }