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.

513 lines
15 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1999.
  5. //
  6. // File: namesem.hxx
  7. //
  8. // Contents: Classes to manage InterProcess Synchronization and shared
  9. // memory.
  10. //
  11. // Classes: CIPMutexSem, CSharedMemory, CIPLock
  12. //
  13. // History: 1-30-96 srikants Created
  14. //
  15. //----------------------------------------------------------------------------
  16. #pragma once
  17. //
  18. // No longer needed. Originally I thought it might be needed.
  19. //
  20. //+---------------------------------------------------------------------------
  21. //
  22. // Class: CNamedEventSem
  23. //
  24. // Purpose:
  25. //
  26. // History: 1-30-96 srikants Created
  27. //
  28. //----------------------------------------------------------------------------
  29. class CNamedEventSem
  30. {
  31. public:
  32. inline CNamedEventSem( DWORD dwMustBeZero, WCHAR const * pwszName,
  33. DWORD dwAccess = EVENT_ALL_ACCESS | EVENT_MODIFY_STATE | SYNCHRONIZE );
  34. inline CNamedEventSem( WCHAR const * pwszName,
  35. BOOL fInitState = FALSE,
  36. const LPSECURITY_ATTRIBUTES lpsa = NULL );
  37. enum eNameType { AppendPid };
  38. inline CNamedEventSem( WCHAR const * pwszName,
  39. eNameType eNT,
  40. BOOL fInitState = FALSE,
  41. const LPSECURITY_ATTRIBUTES lpsa = NULL );
  42. inline ~CNamedEventSem();
  43. HANDLE AcquireHandle()
  44. {
  45. HANDLE hVal = _hEvent;
  46. _hEvent = 0;
  47. return hVal;
  48. }
  49. HANDLE GetHandle() const { return _hEvent; }
  50. private:
  51. inline void Init( WCHAR const * pwszName, BOOL fInitState, const LPSECURITY_ATTRIBUTES lpsa );
  52. HANDLE _hEvent;
  53. };
  54. inline CNamedEventSem::CNamedEventSem( DWORD dwMustBeZero, WCHAR const * pwszName, DWORD dwAccess )
  55. {
  56. Win4Assert( 0 == dwMustBeZero && 0 != pwszName );
  57. //ciDebugOut(( DEB_ITRACE, "Opening a named event (%ws)\n", pwszName ));
  58. _hEvent = OpenEvent( dwAccess, TRUE, pwszName );
  59. if ( 0 == _hEvent )
  60. {
  61. //ciDebugOut(( DEB_ERROR, "Error while opening named event (%ws). Error - 0x%X\n",
  62. // pwszName, GetLastError() ));
  63. THROW( CException() );
  64. }
  65. }
  66. inline CNamedEventSem::CNamedEventSem( WCHAR const * pwszName,
  67. BOOL fInitState,
  68. const LPSECURITY_ATTRIBUTES lpsa )
  69. {
  70. Init( pwszName, fInitState, lpsa );
  71. }
  72. inline CNamedEventSem::CNamedEventSem( WCHAR const * pwszName,
  73. CNamedEventSem::eNameType eNT,
  74. BOOL fInitState,
  75. const LPSECURITY_ATTRIBUTES lpsa )
  76. {
  77. Win4Assert( eNT == CNamedEventSem::AppendPid );
  78. unsigned ccName = wcslen( pwszName );
  79. WCHAR wcsNewName[MAX_PATH];
  80. RtlCopyMemory( wcsNewName, pwszName, ccName * sizeof(WCHAR) );
  81. _itow( GetCurrentProcessId(), wcsNewName + ccName, 16 );
  82. Init( wcsNewName, fInitState, lpsa );
  83. }
  84. inline CNamedEventSem::~CNamedEventSem()
  85. {
  86. if ( 0 != _hEvent && !CloseHandle (_hEvent) )
  87. {
  88. THROW ( CException() );
  89. }
  90. }
  91. inline void CNamedEventSem::Init( WCHAR const * pwszName,
  92. BOOL fInitState,
  93. const LPSECURITY_ATTRIBUTES lpsa )
  94. {
  95. //ciDebugOut(( DEB_ITRACE, "Creating a named event (%ws)\n", pwszName ));
  96. _hEvent = CreateEvent ( lpsa, TRUE, fInitState, pwszName );
  97. if ( _hEvent == 0 )
  98. {
  99. //ciDebugOut(( DEB_ERROR, "Error while creating named event (%ws). Error - 0x%X\n",
  100. // pwszName, GetLastError() ));
  101. THROW ( CException() );
  102. }
  103. }
  104. //+---------------------------------------------------------------------------
  105. //
  106. // Class: CIPMutexSem
  107. //
  108. // Purpose: Mutex useful for inter-process synchronization. It can be
  109. // named or un-named.
  110. //
  111. // History: 1-30-96 srikants Created
  112. //
  113. //----------------------------------------------------------------------------
  114. class CIPMutexSem
  115. {
  116. public:
  117. inline CIPMutexSem( WCHAR const * pwszName,
  118. BOOL bInitialOwner = FALSE,
  119. const LPSECURITY_ATTRIBUTES lpsa=0 );
  120. inline CIPMutexSem( DWORD dwMustBeZero, WCHAR const * pwszName );
  121. inline CIPMutexSem( HANDLE hMutex ) : _hMutex(hMutex) {}
  122. enum eNameType { AppendPid };
  123. inline CIPMutexSem( WCHAR const * pwszName,
  124. eNameType eNT,
  125. BOOL bInitialOwner = FALSE,
  126. const LPSECURITY_ATTRIBUTES lpsa = 0 );
  127. inline ~CIPMutexSem();
  128. void Request( DWORD dwMilliSeconds = INFINITE );
  129. void Release();
  130. HANDLE GetHandle() const { return _hMutex; }
  131. private:
  132. inline void Init( WCHAR const * pwszName, BOOL bInitialOwner, const LPSECURITY_ATTRIBUTES lpsa );
  133. HANDLE _hMutex;
  134. };
  135. //+---------------------------------------------------------------------------
  136. //
  137. // Member: CIPMutexSem::CIPMutexSem
  138. //
  139. // Synopsis: Constructor for the "opening" of the mutex in a child process.
  140. // The mutex must already have been created by the parent
  141. // process.
  142. //
  143. // Arguments: [dwMustBeZero] - Just to distinguish two constructors.
  144. // [pwszName] - Name of the mutext. MUST NOT BE NULL.
  145. //
  146. // History: 2-02-96 srikants Created
  147. //
  148. //----------------------------------------------------------------------------
  149. inline CIPMutexSem::CIPMutexSem( DWORD dwMustBeZero, WCHAR const * pwszName )
  150. {
  151. Win4Assert( 0 != pwszName );
  152. //ciDebugOut(( DEB_ITRACE, "Opening a named (%ws) mutex \n", pwszName ));
  153. _hMutex = OpenMutex( MUTEX_ALL_ACCESS, TRUE, pwszName );
  154. if ( 0 == _hMutex )
  155. {
  156. //ciDebugOut(( DEB_ERROR,
  157. // "Failed to open named mutex (%ws). Error 0x%X\n",
  158. // pwszName, GetLastError() ));
  159. THROW( CException() );
  160. }
  161. }
  162. //+---------------------------------------------------------------------------
  163. //
  164. // Member: CIPMutexSem::CIPMutexSem
  165. //
  166. // Synopsis: Constructor to "create" a mutex object.
  167. //
  168. // Arguments: [pwszName] - Name of the mutex object. Can be NULL.
  169. // [bInitialOwner] - Set to TRUE if the mutex object is owned
  170. // by the creator immediately after creation.
  171. // [lpsa] - Pointer to the security object. It should
  172. // be a valid pointer to a SECURITY_ATTRIBUTES structure if the
  173. // the mutex handle must be inherited by a child process.
  174. //
  175. // History: 2-02-96 srikants Created
  176. //
  177. //----------------------------------------------------------------------------
  178. inline CIPMutexSem::CIPMutexSem( WCHAR const * pwszName,
  179. BOOL bInitialOwner,
  180. const LPSECURITY_ATTRIBUTES lpsa )
  181. {
  182. Init( pwszName, bInitialOwner, lpsa );
  183. }
  184. //+---------------------------------------------------------------------------
  185. //
  186. // Member: CIPMutexSem::CIPMutexSem
  187. //
  188. // Synopsis: Constructor to "create" a mutex object.
  189. //
  190. // Arguments: [eNt] - Distinguishes from other variants
  191. // [pwszName] - Name of the mutex object. Can be NULL.
  192. // [bInitialOwner] - Set to TRUE if the mutex object is owned
  193. // by the creator immediately after creation.
  194. // [lpsa] - Pointer to the security object. It should
  195. // be a valid pointer to a SECURITY_ATTRIBUTES structure if the
  196. // the mutex handle must be inherited by a child process.
  197. //
  198. // History: 2-02-96 srikants Created
  199. //
  200. //----------------------------------------------------------------------------
  201. inline CIPMutexSem::CIPMutexSem( WCHAR const * pwszName,
  202. CIPMutexSem::eNameType eNT,
  203. BOOL bInitialOwner,
  204. const LPSECURITY_ATTRIBUTES lpsa )
  205. {
  206. Win4Assert( eNT == CIPMutexSem::AppendPid );
  207. unsigned ccName = wcslen( pwszName );
  208. WCHAR wcsNewName[MAX_PATH];
  209. RtlCopyMemory( wcsNewName, pwszName, ccName * sizeof(WCHAR) );
  210. _itow( GetCurrentProcessId(), wcsNewName + ccName, 16 );
  211. Init( wcsNewName, bInitialOwner, lpsa );
  212. }
  213. //+---------------------------------------------------------------------------
  214. //
  215. // Member: CIPMutexSem::~CIPMutexSem
  216. //
  217. // Synopsis: Destructor of the CIPMutexSem object.
  218. //
  219. // History: 2-02-96 srikants Created
  220. //
  221. //----------------------------------------------------------------------------
  222. inline CIPMutexSem::~CIPMutexSem()
  223. {
  224. if ( !CloseHandle(_hMutex) )
  225. {
  226. THROW ( CException() );
  227. }
  228. }
  229. inline void CIPMutexSem::Request( DWORD dwMilliseconds)
  230. {
  231. WaitForSingleObject( _hMutex, dwMilliseconds );
  232. }
  233. inline void CIPMutexSem::Release()
  234. {
  235. if ( !ReleaseMutex( _hMutex ) )
  236. {
  237. THROW ( CException() );
  238. }
  239. }
  240. inline void CIPMutexSem::Init( WCHAR const * pwszName,
  241. BOOL bInitialOwner,
  242. const LPSECURITY_ATTRIBUTES lpsa )
  243. {
  244. #if CIDBG==1
  245. if ( 0 != pwszName )
  246. {
  247. //ciDebugOut(( DEB_ITRACE, "Creating a named (%ws) mutex \n", pwszName ));
  248. }
  249. #endif // CIDBG==1
  250. _hMutex = CreateMutex( lpsa, bInitialOwner, pwszName );
  251. if ( 0 == _hMutex )
  252. {
  253. //ciDebugOut(( DEB_ERROR,
  254. // "Failed to create a named mutex (%ws). Error 0x%X\n",
  255. // pwszName, GetLastError() ));
  256. THROW( CException() );
  257. }
  258. }
  259. //+---------------------------------------------------------------------------
  260. //
  261. // Class: CIPLock
  262. //
  263. // Purpose: An unwindable lock object for the CIPMutexSem object.
  264. //
  265. // History: 1-30-96 srikants Created
  266. //
  267. //----------------------------------------------------------------------------
  268. class CIPLock
  269. {
  270. public:
  271. CIPLock( CIPMutexSem & mxs ) : _mxs(mxs)
  272. {
  273. _mxs.Request();
  274. }
  275. ~CIPLock()
  276. {
  277. _mxs.Release();
  278. }
  279. private:
  280. CIPMutexSem & _mxs;
  281. };
  282. //+---------------------------------------------------------------------------
  283. //
  284. // Class: CLocalSystemSharedMemory
  285. //
  286. // Purpose: A class to contruct either a named or un-named shared memory
  287. // to a paging file.
  288. //
  289. // History: 1-30-96 srikants Created
  290. //
  291. // Notes: This class is hard-wide to allow only SYSTEM account access.
  292. //
  293. //----------------------------------------------------------------------------
  294. class CLocalSystemSharedMemory
  295. {
  296. public:
  297. CLocalSystemSharedMemory( WCHAR const * pwszName = 0,
  298. DWORD dwMaxSizeLow = 1024 );
  299. ~CLocalSystemSharedMemory()
  300. {
  301. if (_pBuf)
  302. {
  303. UnmapViewOfFile( _pBuf );
  304. _pBuf = 0;
  305. }
  306. CloseHandle( _hMap );
  307. }
  308. BYTE * Map()
  309. {
  310. _pBuf = (BYTE *) MapViewOfFile( _hMap, FILE_MAP_ALL_ACCESS,
  311. 0, 0, _dwMaxSizeLow );
  312. if ( 0 == _pBuf )
  313. {
  314. ciDebugOut(( DEB_ERROR, "Failed to map file. Error 0x%X\n",
  315. GetLastError() ));
  316. THROW( CException() );
  317. }
  318. return _pBuf;
  319. }
  320. BYTE * GetBuf()
  321. {
  322. return _pBuf;
  323. }
  324. DWORD SizeLow() const { return _dwMaxSizeLow; }
  325. HANDLE GetMapHandle() const { return _hMap; }
  326. private:
  327. HANDLE _hMap; // Handle of the shared memory map
  328. DWORD _dwMaxSizeLow; // Maximum size of the region
  329. BYTE * _pBuf; // Pointer to the mapped region
  330. };
  331. //+---------------------------------------------------------------------------
  332. //
  333. // Member: CLocalSystemSharedMemory::CLocalSystemSharedMemory
  334. //
  335. // Synopsis: Constructor for "creating" a shared memory.
  336. //
  337. // Arguments: [pwszName] - Name of the shared memory region. If NULL,
  338. // an unnamed shared memory region will be created.
  339. // [dwMaxSizeLow] - Maximum size of the shared memory region.
  340. //
  341. // History: 2-02-96 srikants Created
  342. // 07-Oct-1999 KyleP Wired to Local SYSTEM account
  343. //
  344. //----------------------------------------------------------------------------
  345. inline CLocalSystemSharedMemory::CLocalSystemSharedMemory( WCHAR const * pwszName,
  346. DWORD dwMaxSizeLow )
  347. {
  348. #if CIDBG==1
  349. if ( pwszName )
  350. {
  351. ciDebugOut(( DEB_ITRACE, "Creating named shared memory (%ws) \n", pwszName ));
  352. }
  353. #endif // CIDBG==1
  354. //
  355. // Build a security descriptor for the local system account
  356. //
  357. static SID sidLocalSystem = { SID_REVISION,
  358. 1,
  359. SECURITY_NT_AUTHORITY,
  360. SECURITY_LOCAL_SYSTEM_RID };
  361. int const cbSD = sizeof(SECURITY_DESCRIPTOR) +
  362. sizeof(ACL) +
  363. sizeof(ACCESS_ALLOWED_ACE) +
  364. sizeof(sidLocalSystem);
  365. BYTE abSD[cbSD];
  366. ACL * pAcl = (PACL)(((SECURITY_DESCRIPTOR *)&abSD[0]) + 1);
  367. SECURITY_DESCRIPTOR * psd = (SECURITY_DESCRIPTOR *)&abSD[0];
  368. BOOL bRetVal = InitializeAcl( pAcl, // Pointer to the ACL
  369. cbSD - sizeof(SECURITY_DESCRIPTOR), // Size of ACL
  370. ACL_REVISION ); // Revision level of ACL
  371. if (FALSE == bRetVal)
  372. {
  373. THROW( CException() );
  374. }
  375. bRetVal = AddAccessAllowedAce( pAcl, // Pointer to the ACL
  376. ACL_REVISION, // ACL revision level
  377. FILE_MAP_READ | FILE_MAP_WRITE | GENERIC_ALL | STANDARD_RIGHTS_ALL, // Access Mask
  378. &sidLocalSystem );
  379. if (FALSE == bRetVal)
  380. {
  381. THROW( CException() );
  382. }
  383. bRetVal = InitializeSecurityDescriptor( psd, // Pointer to SD
  384. SECURITY_DESCRIPTOR_REVISION ); // SD revision
  385. if (FALSE == bRetVal)
  386. {
  387. THROW( CException() )
  388. }
  389. bRetVal = SetSecurityDescriptorDacl( psd, // Security Descriptor
  390. TRUE, // Dacl present
  391. pAcl, // The Dacl
  392. FALSE ); // Not defaulted
  393. if (FALSE == bRetVal)
  394. {
  395. THROW( CException() );
  396. }
  397. SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES),
  398. psd,
  399. FALSE };
  400. //
  401. // Create file map
  402. //
  403. _hMap = CreateFileMapping( INVALID_HANDLE_VALUE, &sa, PAGE_READWRITE, 0, dwMaxSizeLow, pwszName );
  404. if ( 0 == _hMap )
  405. {
  406. ciDebugOut(( DEB_ERROR, "Failed to create a mapping. Error - 0x%X\n", GetLastError() ));
  407. THROW( CException() );
  408. }
  409. _dwMaxSizeLow = dwMaxSizeLow;
  410. _pBuf = 0;
  411. }