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.

387 lines
10 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1993.
  5. //
  6. // File: reserved.cxx
  7. //
  8. // Contents: Class that implements reserved memory for properties.
  9. // This implementation is in the form of two derivations
  10. // of the CReservedMemory class.
  11. //
  12. // Classes: CWin32ReservedMemory
  13. // CWin31ReservedMemory
  14. //
  15. // History: 1-Mar-95 BillMo Created.
  16. // 29-Aug-96 MikeHill Split CReservedMemory into CWin31 & CWin32
  17. //
  18. // Notes:
  19. //
  20. // Codework:
  21. //
  22. //--------------------------------------------------------------------------
  23. #include <pch.cxx>
  24. #include "reserved.hxx"
  25. #ifdef _MAC_NODOC
  26. ASSERTDATA // File-specific data for FnAssert
  27. #endif
  28. // Instantiate the appropriate object.
  29. #ifdef _MAC
  30. CWin31ReservedMemory g_ReservedMemory;
  31. #else
  32. CWin32ReservedMemory g_ReservedMemory;
  33. #endif
  34. //+----------------------------------------------------------------------------
  35. //
  36. // Method: CWin32ReservedMemory::_Init
  37. //
  38. // Synopsis: Prepare as much as possible during initialization, in order
  39. // to be able to provide memory in LockMemory.
  40. //
  41. // Inputs: None.
  42. //
  43. // Returns: None.
  44. //
  45. //+----------------------------------------------------------------------------
  46. #ifndef _MAC
  47. HRESULT
  48. CWin32ReservedMemory::_Init(VOID)
  49. {
  50. HRESULT hr = E_FAIL;
  51. SID_IDENTIFIER_AUTHORITY Sa = SECURITY_CREATOR_SID_AUTHORITY;
  52. ULONG cInits;
  53. // Ensure this method is called once and only once. This
  54. // is necessary since this class is implemented as a global
  55. // variable.
  56. cInits = InterlockedIncrement( &_cInits );
  57. if( 1 < cInits )
  58. {
  59. // We've already been initialized (probably simultaneously
  60. // in another thread). NOTE: This leaves one small race where
  61. // this thread really needs to use the reserved memory before
  62. // the other thread has finished initializing it. If that window
  63. // is hit, it won't cause a corruption, but will cause an out-of-mem
  64. // error to occur.
  65. InterlockedDecrement( &_cInits );
  66. hr = S_OK;
  67. goto Exit;
  68. }
  69. // Create a creator/owner SID. We'll give the creator/owner
  70. // full access to the temp file.
  71. if( !AllocateAndInitializeSid( &Sa, // Top-level authority
  72. 1,
  73. SECURITY_CREATOR_OWNER_RID,
  74. 0, 0, 0, 0, 0, 0, 0,
  75. &_pCreatorOwner ))
  76. {
  77. hr = HRESULT_FROM_WIN32( GetLastError() );
  78. _pCreatorOwner = NULL;
  79. goto Exit;
  80. }
  81. // Create a DACL that just gives the Creator/Owner full access.
  82. if (!InitializeAcl( &_DaclBuffer.acl, sizeof(_DaclBuffer), ACL_REVISION))
  83. {
  84. hr = HRESULT_FROM_WIN32( GetLastError() );
  85. goto Exit;
  86. }
  87. if (!AddAccessAllowedAce( &_DaclBuffer.acl,
  88. ACL_REVISION,
  89. STANDARD_RIGHTS_ALL | GENERIC_ALL,
  90. _pCreatorOwner
  91. ))
  92. {
  93. hr = HRESULT_FROM_WIN32( GetLastError() );
  94. goto Exit;
  95. }
  96. // Set up the security descriptor with that DACL in it.
  97. InitializeSecurityDescriptor( &_sd, SECURITY_DESCRIPTOR_REVISION );
  98. if( !SetSecurityDescriptorDacl( &_sd, TRUE, &_DaclBuffer.acl, FALSE ))
  99. {
  100. hr = HRESULT_FROM_WIN32( GetLastError() );
  101. goto Exit;
  102. }
  103. // Put the security descriptor into the security attributes.
  104. memset( &_secattr, 0, sizeof(_secattr) );
  105. _secattr.nLength = sizeof(SECURITY_ATTRIBUTES);
  106. _secattr.lpSecurityDescriptor = &_sd;
  107. _secattr.bInheritHandle = FALSE;
  108. // Initialize the critical section.
  109. __try
  110. {
  111. InitializeCriticalSection( &_critsec );
  112. _fInitialized = TRUE;
  113. }
  114. __except( EXCEPTION_EXECUTE_HANDLER )
  115. {
  116. hr = HRESULT_FROM_WIN32( GetExceptionCode() );
  117. goto Exit;
  118. }
  119. hr = S_OK;
  120. Exit:
  121. return hr;
  122. }
  123. #endif // #ifndef _MAC
  124. //+----------------------------------------------------------------------------
  125. //
  126. // Method: CWin32ReservedMemory::~CWin32ReservedMemory
  127. //
  128. // Inputs: N/A
  129. //
  130. // Returns: N/A
  131. //
  132. //+----------------------------------------------------------------------------
  133. #ifndef _MAC
  134. CWin32ReservedMemory::~CWin32ReservedMemory()
  135. {
  136. if( _fInitialized )
  137. DeleteCriticalSection( &_critsec );
  138. if( NULL != _pCreatorOwner )
  139. FreeSid( _pCreatorOwner );
  140. FreeResources();
  141. }
  142. //+----------------------------------------------------------------------------
  143. //
  144. // Method: CWin32ReservedMemory::FreeResources
  145. //
  146. // Inputs: N/A
  147. //
  148. // Returns: Void
  149. //
  150. // Synopsis: Free the view, the mapping, and the file.
  151. //
  152. //+----------------------------------------------------------------------------
  153. void
  154. CWin32ReservedMemory::FreeResources()
  155. {
  156. if( NULL != _pb )
  157. {
  158. UnmapViewOfFile( _pb );
  159. _pb = NULL;
  160. }
  161. if( NULL != _hMapping )
  162. {
  163. CloseHandle( _hMapping );
  164. _hMapping = NULL;
  165. }
  166. if( INVALID_HANDLE_VALUE != _hFile )
  167. {
  168. CloseHandle( _hFile );
  169. _hFile = INVALID_HANDLE_VALUE;
  170. }
  171. }
  172. #endif // #ifndef _MAC
  173. //+----------------------------------------------------------------------------
  174. //
  175. // Method: CWin32ReservedMemory::LockMemory
  176. //
  177. // Synopsis: Use a temporary file to get enough memory to hold the
  178. // largest possible property set and return a pointer to
  179. // that mapping.
  180. //
  181. // Inputs: None.
  182. //
  183. // Returns: Lock() returns a pointer to the locked memory.
  184. //
  185. //+----------------------------------------------------------------------------
  186. #ifndef _MAC
  187. BYTE * CWin32ReservedMemory::LockMemory(VOID)
  188. {
  189. WCHAR wszTempFileName[ MAX_PATH + 64 ];
  190. ULONG cchPath = 0;
  191. // If for some reason initialization failed, there's nothing we can do,
  192. // we'll return NULL.
  193. if( !_fInitialized )
  194. goto Exit;
  195. // Lock down this class until the caller has completed.
  196. // This isn't really necessary, since this class could be
  197. // a member variable instead of a global, but that is too
  198. // much of a change for NT5.
  199. EnterCriticalSection( &_critsec );
  200. // Get the temp directory.
  201. cchPath = GetTempPath( MAX_PATH + 1, wszTempFileName );
  202. if( 0 == cchPath || cchPath > MAX_PATH + 1 )
  203. goto Exit;
  204. // Create a temporary file. We can't use GetTempFileName, because it creates
  205. // the file, and consequently the DACL we pass in on CreateFile gets ignored.
  206. SYSTEMTIME st;
  207. FILETIME ft;
  208. GetSystemTime( &st );
  209. SystemTimeToFileTime( &st, &ft );
  210. StringCbPrintf( &wszTempFileName[cchPath],
  211. sizeof(wszTempFileName),
  212. L"OLEPROPSTG_%08x%08x.tmp",
  213. ft.dwHighDateTime,
  214. ft.dwLowDateTime );
  215. _hFile = CreateFile( wszTempFileName,
  216. GENERIC_WRITE|GENERIC_READ|DELETE,
  217. 0,
  218. &_secattr,
  219. CREATE_NEW,
  220. FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE,
  221. INVALID_HANDLE_VALUE );
  222. if( INVALID_HANDLE_VALUE == _hFile )
  223. goto Exit;
  224. // Map the temporary file.
  225. _hMapping = CreateFileMappingA(_hFile, // handle of file to map
  226. NULL, // optional security attributes
  227. PAGE_READWRITE, // protection for mapping object
  228. 0, // high-order 32 bits of object size
  229. CBMAXPROPSETSTREAM, // low-order 32 bits of object size
  230. NULL); // name of file-mapping object
  231. if( NULL == _hMapping )
  232. goto Exit;
  233. // Map a view.
  234. _pb = (BYTE*)MapViewOfFile(_hMapping, // file-mapping object to map into address space
  235. FILE_MAP_WRITE, // read/write access mode
  236. 0, // high-order 32 bits of file offset
  237. 0, // low-order 32 bits of file offset
  238. 0); // number of bytes to map
  239. if( NULL == _pb )
  240. goto Exit;
  241. Exit:
  242. // If there was an error, free everything.
  243. if( NULL == _pb && _fInitialized )
  244. {
  245. FreeResources();
  246. LeaveCriticalSection( &_critsec );
  247. }
  248. return _pb;
  249. }
  250. //+----------------------------------------------------------------------------
  251. //
  252. // Method: CWin32ReservedMemory
  253. //
  254. // Synopsis: Free the temp file and its mapping, and leave the critical
  255. // section.
  256. //
  257. //+----------------------------------------------------------------------------
  258. VOID CWin32ReservedMemory::UnlockMemory(VOID)
  259. {
  260. if( _fInitialized )
  261. {
  262. FreeResources();
  263. LeaveCriticalSection( &_critsec );
  264. }
  265. }
  266. #endif // #ifndef _MAC
  267. //+----------------------------------------------------------------------------
  268. //
  269. // Method: CWin31ReservedMemory::LockMemory/UnlockMemory
  270. //
  271. // Synopsis: This derivation of the CReservedMemory does not provide
  272. // a locking mechanism, so no locking is performed. The Lock
  273. // method simply returns the shared memory buffer.
  274. //
  275. // Inputs: None.
  276. //
  277. // Returns: Nothing
  278. //
  279. //+----------------------------------------------------------------------------
  280. #ifdef _MAC
  281. BYTE * CWin31ReservedMemory::LockMemory(VOID)
  282. {
  283. DfpAssert( !_fLocked );
  284. #if DBG==1
  285. _fLocked = TRUE;
  286. #endif
  287. return (BYTE*) g_pbPropSetReserved;
  288. }
  289. VOID CWin31ReservedMemory::UnlockMemory(VOID)
  290. {
  291. // No locking required on the Mac.
  292. DfpAssert( _fLocked );
  293. #if DBG==1
  294. _fLocked = FALSE;
  295. #endif
  296. }
  297. #endif // #ifdef _MAC