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.

305 lines
5.5 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. All rights reserved.
  4. Module Name:
  5. sharedat.cxx
  6. Abstract:
  7. Shared data implementation.
  8. Author:
  9. Albert Ting (AlbertT) 5-Oct-1997
  10. Revision History:
  11. --*/
  12. #include "spllibp.hxx"
  13. #pragma hdrstop
  14. #include "sharedat.hxx"
  15. LPCTSTR szSuffixFile = SZ_SUFFIX_FILE;
  16. /********************************************************************
  17. TShareData::TBase
  18. Base functionality common to both TReadWrite and TRead.
  19. ********************************************************************/
  20. TShareData::
  21. TBase::
  22. TBase(
  23. VOID
  24. ) : m_hMap( NULL ), m_pData( NULL )
  25. {
  26. }
  27. VOID
  28. TShareData::
  29. TBase::
  30. vCleanup(
  31. VOID
  32. )
  33. {
  34. if( m_pData )
  35. {
  36. UnmapViewOfFile( m_pData );
  37. m_pData = NULL;
  38. }
  39. if( m_hMap )
  40. {
  41. CloseHandle( m_hMap );
  42. m_hMap = NULL;
  43. }
  44. }
  45. TShareData::
  46. TBase::
  47. ~TBase(
  48. VOID
  49. )
  50. {
  51. vCleanup();
  52. }
  53. BOOL
  54. TShareData::
  55. TBase::
  56. bGetFullName(
  57. LPCTSTR pszName,
  58. LPTSTR pszFullName
  59. )
  60. {
  61. UINT cchName;
  62. //
  63. // Validate input and determine the size of the name.
  64. //
  65. if( !pszName || !pszName[0] || ( cchName = lstrlen( pszName )) >= MAX_PATH )
  66. {
  67. SetLastError( ERROR_INVALID_NAME );
  68. return FALSE;
  69. }
  70. //
  71. // Create shared file object.
  72. //
  73. lstrcpy( pszFullName, pszName );
  74. lstrcpy( &pszFullName[cchName], szSuffixFile );
  75. return TRUE;
  76. }
  77. /********************************************************************
  78. TShareData::TReadWrite
  79. Class that allows user to read and write a shared data object.
  80. Since there is only one valid writer, the vWriteBegin and
  81. vWriteEnd functions are rolled up together here.
  82. ********************************************************************/
  83. TShareData::
  84. TReadWrite::
  85. TReadWrite(
  86. IN LPCTSTR pszName,
  87. IN DWORD cbSize,
  88. IN PSECURITY_ATTRIBUTES pSA
  89. ) : TBase()
  90. /*++
  91. Routine Description:
  92. Create a shared data access object.
  93. Arguments:
  94. pszName - Name of shared memory object.
  95. pSA - Security attributes.
  96. Return Value:
  97. --*/
  98. {
  99. TCHAR szFullName[kNameBufferMax];
  100. if( bGetFullName( pszName, szFullName ))
  101. {
  102. m_hMap = CreateFileMapping( INVALID_HANDLE_VALUE,
  103. pSA,
  104. PAGE_READWRITE,
  105. 0,
  106. sizeof( TData ) + cbSize,
  107. szFullName );
  108. if( m_hMap )
  109. {
  110. m_pData = (pTData)MapViewOfFile( m_hMap,
  111. FILE_MAP_WRITE,
  112. 0,
  113. 0,
  114. 0 );
  115. m_pData->cbSize = cbSize;
  116. //
  117. // Put ourselves in an inconsistent state so that clients won't
  118. // read bad data. The callee must call vWriteFirst() after
  119. // the first initialization.
  120. //
  121. m_pData->lCount2 = m_pData->lCount1 + 1;
  122. }
  123. }
  124. //
  125. // m_pData is our valid check. If this variable is NULL
  126. // then the object wasn't created correctly.
  127. //
  128. }
  129. VOID
  130. TShareData::
  131. TReadWrite::
  132. vWriteFirst(
  133. VOID
  134. )
  135. {
  136. m_pData->lCount1 = m_pData->lCount2 = 0;
  137. }
  138. VOID
  139. TShareData::
  140. TReadWrite::
  141. vWriteBegin(
  142. VOID
  143. )
  144. {
  145. InterlockedIncrement( &m_pData->lCount2 );
  146. }
  147. VOID
  148. TShareData::
  149. TReadWrite::
  150. vWriteEnd(
  151. VOID
  152. )
  153. {
  154. InterlockedIncrement( &m_pData->lCount1 );
  155. }
  156. /********************************************************************
  157. TShareData::TRead
  158. Read-only class. Since there can be multiple readers, the
  159. reader instance is separated out into a TReadSync class.
  160. ********************************************************************/
  161. TShareData::
  162. TRead::
  163. TRead(
  164. IN LPCTSTR pszName,
  165. IN DWORD cbSize
  166. ) : TBase()
  167. /*++
  168. Routine Description:
  169. Create a shared data access object.
  170. Arguments:
  171. pszName - Name of shared memory object.
  172. Return Value:
  173. --*/
  174. {
  175. TCHAR szFullName[kNameBufferMax];
  176. if( bGetFullName( pszName, szFullName ))
  177. {
  178. m_hMap = OpenFileMapping( FILE_MAP_READ,
  179. FALSE,
  180. szFullName );
  181. if( m_hMap )
  182. {
  183. m_pData = (pTData)MapViewOfFile( m_hMap,
  184. FILE_MAP_READ,
  185. 0,
  186. 0,
  187. 0 );
  188. if( m_pData )
  189. {
  190. if( m_pData->cbSize < cbSize )
  191. {
  192. vCleanup();
  193. SetLastError( ERROR_INVALID_PARAMETER );
  194. }
  195. }
  196. }
  197. }
  198. //
  199. // m_pData is our valid check. If this variable is NULL
  200. // then the object wasn't created correctly.
  201. //
  202. }
  203. /********************************************************************
  204. TShareData::TReadSync
  205. Synchronizes a read instance from a TShareData::Read object.
  206. There can be multiple TReadSyncs running concurrently for a
  207. given TShareData::Read object.
  208. ********************************************************************/
  209. TShareData::
  210. TReadSync::
  211. TReadSync(
  212. TRead& Read
  213. ) : m_Read( Read )
  214. {
  215. }
  216. VOID
  217. TShareData::
  218. TReadSync::
  219. vReadBegin(
  220. VOID
  221. )
  222. {
  223. m_lCount = m_Read.m_pData->lCount1;
  224. }
  225. BOOL
  226. TShareData::
  227. TReadSync::
  228. bReadEnd(
  229. VOID
  230. )
  231. {
  232. return m_Read.m_pData->lCount2 == m_lCount;
  233. }