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.

353 lines
12 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 2002.
  5. //
  6. // File : SMem.hxx
  7. //
  8. // Contents : Shared memory (named + file based)
  9. //
  10. // Classes : CNamedSharedMem
  11. //
  12. // History: 22-Mar-94 t-joshh Created
  13. //
  14. //----------------------------------------------------------------------------
  15. #pragma once
  16. #include <secutil.hxx>
  17. //+---------------------------------------------------------------------------
  18. //
  19. // Class: CNamedSharedMem
  20. //
  21. // Purpose: Named shared memory
  22. //
  23. // History: 22-Mar-94 t-joshh Created
  24. //
  25. //----------------------------------------------------------------------------
  26. class CNamedSharedMem
  27. {
  28. public:
  29. inline CNamedSharedMem( WCHAR const * pwszName, ULONG cb, SECURITY_DESCRIPTOR * psd = 0, BOOL fWrite = TRUE );
  30. CNamedSharedMem()
  31. : _hMap( 0 ),
  32. _pb( 0 )
  33. {
  34. }
  35. enum eNameType { AppendPid };
  36. CNamedSharedMem( WCHAR const * pwszName, eNameType eNT, ULONG cb )
  37. : _hMap( 0 ),
  38. _pb( 0 )
  39. {
  40. Win4Assert( eNT == CNamedSharedMem::AppendPid );
  41. unsigned ccName = wcslen( pwszName );
  42. WCHAR wcsNewName[MAX_PATH];
  43. RtlCopyMemory( wcsNewName, pwszName, ccName * sizeof(WCHAR) );
  44. _itow( GetCurrentProcessId(), wcsNewName + ccName, 16 );
  45. Init( wcsNewName, cb, 0 );
  46. }
  47. ~CNamedSharedMem()
  48. {
  49. if ( 0 != _pb )
  50. UnmapViewOfFile( _pb );
  51. if ( 0 != _hMap )
  52. CloseHandle( _hMap );
  53. }
  54. BYTE * GetPointer() { return _pb; }
  55. BYTE * Get() { return _pb; }
  56. BOOL Ok() { return ( 0 != _pb ); }
  57. inline void Init( WCHAR const * pwszName, ULONG cb, SECURITY_DESCRIPTOR * psd = 0, BOOL fWrite = TRUE );
  58. void CreateForWriteFromRegKey( WCHAR const * pwszName,
  59. ULONG cb,
  60. WCHAR const * pwcRegKey )
  61. {
  62. Win4Assert( 0 == _hMap );
  63. Win4Assert( 0 == _pb );
  64. Win4Assert( 0 != pwcRegKey );
  65. _hMap = CreateFileMapping( INVALID_HANDLE_VALUE, // Map to page file
  66. 0, // Security attributes
  67. PAGE_READWRITE, // Page-level protection
  68. 0, // Size high
  69. cb, // size low
  70. pwszName ); // Name
  71. if ( 0 == _hMap )
  72. THROW( CException() );
  73. DWORD dwErr = CopyNamedDacls( pwszName, pwcRegKey );
  74. if ( NO_ERROR != dwErr )
  75. THROW( CException( HRESULT_FROM_WIN32( dwErr ) ) );
  76. _pb = (BYTE *) MapViewOfFile( _hMap, // Handle to map
  77. FILE_MAP_WRITE, // Access
  78. 0, // Offset (high)
  79. 0, // Offset (low)
  80. 0 ); // Map all
  81. if ( 0 == _pb )
  82. {
  83. DWORD dwErr = GetLastError();
  84. CloseHandle( _hMap );
  85. _hMap = 0;
  86. THROW( CException( HRESULT_FROM_WIN32( dwErr ) ) );
  87. }
  88. }
  89. void CreateForWriteFromSA( WCHAR const * pwszName,
  90. ULONG cb,
  91. SECURITY_ATTRIBUTES & sa )
  92. {
  93. Win4Assert( 0 == _hMap );
  94. Win4Assert( 0 == _pb );
  95. _hMap = CreateFileMapping( INVALID_HANDLE_VALUE, // Map to page file
  96. &sa, // Security attributes
  97. PAGE_READWRITE, // Page-level protection
  98. 0, // Size high
  99. cb, // size low
  100. pwszName ); // Name
  101. if ( 0 == _hMap )
  102. THROW( CException() );
  103. _pb = (BYTE *) MapViewOfFile( _hMap, // Handle to map
  104. FILE_MAP_WRITE, // Access
  105. 0, // Offset (high)
  106. 0, // Offset (low)
  107. 0 ); // Map all
  108. if ( 0 == _pb )
  109. {
  110. DWORD dwErr = GetLastError();
  111. CloseHandle( _hMap );
  112. _hMap = 0;
  113. THROW( CException( HRESULT_FROM_WIN32( dwErr ) ) );
  114. }
  115. }
  116. BOOL OpenForRead( WCHAR const * pwszName )
  117. {
  118. Win4Assert( 0 == _hMap );
  119. Win4Assert( 0 == _pb );
  120. //
  121. // Note: you have to ask for PAGE_READWRITE even though we only want
  122. // PAGE_READ, otherwise you get ERROR_ACCESS_DENIED. I don't know
  123. // why, but since only a limited # of contexts have write access,
  124. // it should be OK.
  125. //
  126. _hMap = OpenFileMapping( PAGE_READWRITE, // Access
  127. FALSE, // Inherit
  128. pwszName ); // Name
  129. if ( 0 == _hMap )
  130. {
  131. if ( ERROR_FILE_NOT_FOUND == GetLastError() )
  132. return FALSE;
  133. THROW( CException() );
  134. }
  135. _pb = (BYTE *) MapViewOfFile( _hMap,
  136. FILE_MAP_READ, // Access
  137. 0, // Offset (high)
  138. 0, // Offset (low)
  139. 0 ); // Map all
  140. if ( 0 == _pb )
  141. {
  142. DWORD dwErr = GetLastError();
  143. CloseHandle( _hMap );
  144. _hMap = 0;
  145. THROW( CException( HRESULT_FROM_WIN32( dwErr ) ) );
  146. }
  147. return TRUE;
  148. }
  149. private:
  150. HANDLE _hMap;
  151. BYTE * _pb;
  152. };
  153. //+---------------------------------------------------------------------------
  154. //
  155. // Member: CNamedSharedMem::CNamedSharedMem, public
  156. //
  157. // Synopsis: Create/Open named shared memory
  158. //
  159. // Arguments: [pwszName] -- Name of shared memory region
  160. // [cb] -- Size of shared memory region
  161. // [psd] -- Security
  162. // [fWrite] -- TRUE if write-access is required
  163. //
  164. // History: 06-Oct-1999 KyleP Heavily modified
  165. //
  166. //----------------------------------------------------------------------------
  167. inline CNamedSharedMem::CNamedSharedMem( WCHAR const * pwszName,
  168. ULONG cb,
  169. SECURITY_DESCRIPTOR * psd,
  170. BOOL fWrite )
  171. : _hMap( 0 ),
  172. _pb( 0 )
  173. {
  174. //
  175. // Create null security descriptor, if needed
  176. //
  177. struct
  178. {
  179. SECURITY_DESCRIPTOR _sdMaxAccess;
  180. BYTE _sdExtra[SECURITY_DESCRIPTOR_MIN_LENGTH];
  181. } sd;
  182. if ( 0 == psd )
  183. {
  184. if ( !InitializeSecurityDescriptor( &sd, SECURITY_DESCRIPTOR_REVISION ) )
  185. {
  186. THROW( CException() );
  187. }
  188. if ( !SetSecurityDescriptorDacl( &sd._sdMaxAccess,// Security descriptor
  189. TRUE, // Discretionary ACL
  190. 0, // The null ACL (all access)
  191. FALSE ) ) // Not a default disc. ACL
  192. {
  193. THROW( CException() );
  194. }
  195. psd = &sd._sdMaxAccess;
  196. }
  197. Init( pwszName, cb, psd, fWrite );
  198. }
  199. //+---------------------------------------------------------------------------
  200. //
  201. // Member: CNamedSharedMem::Init, public
  202. //
  203. // Synopsis: Create/Open named shared memory
  204. //
  205. // Arguments: [pwszName] -- Name of shared memory region
  206. // [cb] -- Size of shared memory region
  207. // [psd] -- Security
  208. // [fWrite] -- TRUE if write-access is required
  209. //
  210. // History: 06-Oct-1999 KyleP Heavily modified
  211. //
  212. //----------------------------------------------------------------------------
  213. void CNamedSharedMem::Init( WCHAR const * pwszName,
  214. ULONG cb,
  215. SECURITY_DESCRIPTOR * psd,
  216. BOOL fWrite )
  217. {
  218. Win4Assert( 0 == _hMap );
  219. Win4Assert( 0 == _pb );
  220. //Win4Assert( 0 == psd ); // Handy assert to enable to analyze security problems.
  221. SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES),
  222. psd,
  223. FALSE };
  224. //
  225. // Set up flags
  226. //
  227. DWORD dwCFMMode;
  228. DWORD dwMVoFMode;
  229. if ( fWrite )
  230. {
  231. dwCFMMode = PAGE_READWRITE;
  232. dwMVoFMode = FILE_MAP_WRITE;
  233. }
  234. else
  235. {
  236. dwCFMMode = PAGE_READWRITE; // make it so that others can map for write
  237. dwMVoFMode = FILE_MAP_READ;
  238. }
  239. _hMap = CreateFileMapping( INVALID_HANDLE_VALUE, // Map to page file
  240. &sa, // Security attributes
  241. dwCFMMode, // Page-level protection
  242. 0, // Size high
  243. cb, // size low
  244. pwszName ); // Name
  245. #if 0
  246. if ( 0 != psd )
  247. {
  248. BYTE ab[1000];
  249. DWORD dwl;
  250. BOOL fOk = GetKernelObjectSecurity( _hMap, // handle to object
  251. FILE_MAP_WRITEDACL_SECURITY_INFORMATION, // request
  252. (SECURITY_DESCRIPTOR *)&ab[0], // SD
  253. sizeof(ab), // size of SD
  254. &dwl ); // required size of buffer
  255. Win4Assert( fOk );
  256. Win4Assert( !fOk );
  257. ciDebugOut(( DEB_ERROR, "pb = 0x%x\n", &ab[0] ));
  258. Win4Assert( !fOk );
  259. //HANDLE hTemp = OpenFileMapping( PAGE_READONLY, // Access
  260. // FALSE, // Inherit
  261. // pwszName ); // Name
  262. HANDLE hTemp = CreateFileMapping( INVALID_HANDLE_VALUE, // Map to page file
  263. &sa, // Security attributes
  264. PAGE_READONLY, // Page-level protection
  265. 0, // Size high
  266. cb, // size low
  267. pwszName ); // Name
  268. Win4Assert( 0 != hTemp );
  269. BYTE * pbTemp = (BYTE *) MapViewOfFile( hTemp, // Handle to map
  270. FILE_MAP_READ, // Access
  271. 0, // Offset (high)
  272. 0, // Offset (low)
  273. 0 ); // Map all
  274. Win4Assert( 0 != pbTemp );
  275. UnmapViewOfFile( pbTemp );
  276. CloseHandle( hTemp );
  277. }
  278. #endif
  279. if ( 0 != _hMap )
  280. _pb = (BYTE *) MapViewOfFile( _hMap, // Handle to map
  281. dwMVoFMode, // Access
  282. 0, // Offset (high)
  283. 0, // Offset (low)
  284. 0 ); // Map all
  285. }