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
12 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1994.
  5. //
  6. // File: mapfile.hxx
  7. //
  8. // Contents: Mapped File class definition
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 12-Feb-96 PhilipLa Created
  15. //
  16. //----------------------------------------------------------------------------
  17. #ifndef __MAPFILE_HXX__
  18. #define __MAPFILE_HXX__
  19. #ifdef _MAC
  20. extern void swap(char *src, int nSize);
  21. #else
  22. #define swap(x, y)
  23. #endif // _MAC
  24. //+---------------------------------------------------------------------------
  25. //
  26. // Class: CMappedFile
  27. //
  28. // Purpose: Provides a wrapper over a file mapping
  29. //
  30. // Interface:
  31. //
  32. // History: 12-Feb-96 PhilipLa Created
  33. //
  34. // Notes:
  35. //
  36. //----------------------------------------------------------------------------
  37. class CMappedFile
  38. {
  39. public:
  40. inline CMappedFile();
  41. ~CMappedFile();
  42. SCODE Init(OLECHAR const *pwcsFileName,
  43. DWORD dwSize,
  44. DWORD dwAccess,
  45. DWORD dwCreationDisposition,
  46. void *pbDesiredBaseAddress);
  47. SCODE InitFromHandle(HANDLE h,
  48. BOOL fReadOnly,
  49. BOOL fDuplicate,
  50. void *pbDesiredBaseAddress);
  51. inline void * GetBaseAddress(void);
  52. inline ULONG GetSize(void);
  53. //Stuff for unmappable mode
  54. inline SECT operator[](ULONG uOffset);
  55. inline USHORT GetUSHORT(ULONG uOffset);
  56. inline ULONG GetULONG(ULONG uOffset);
  57. inline CMSFHeaderData * GetCMSFHeaderData(void);
  58. inline CFatSect * GetCFatSect (ULONG uOffset);
  59. inline CDirSect * GetCDirSect (ULONG uOffset);
  60. inline SCODE ReadFromFile( BYTE *pbBuffer,
  61. ULONG uOffset,
  62. ULONG uSize );
  63. inline SCODE WriteToFile( BYTE *pbBuffer,
  64. ULONG uOffset,
  65. ULONG uSize );
  66. inline SCODE WriteToFile (CMSFHeaderData *pheader);
  67. inline SCODE WriteToFile (CFatSect *pfs);
  68. inline SCODE WriteToFile (CDirSect *pds);
  69. inline void Remove (CMSFHeaderData *pheader);
  70. inline void Remove (CFatSect *pfs);
  71. inline void Remove (CDirSect *pds);
  72. inline void SetSectorSize(ULONG cbSectorSize);
  73. private:
  74. HANDLE _hFile;
  75. #ifdef SUPPORT_FILE_MAPPING
  76. HANDLE _hMapping;
  77. #endif
  78. void *_pbBase;
  79. DWORD _dwFatSectOffset;
  80. DWORD _dwDirSectOffset;
  81. DWORD _dwHeaderOffset;
  82. ULONG _uSectorSize;
  83. };
  84. inline SECT CMappedFile::operator[](ULONG uOffset)
  85. {
  86. SECT sect;
  87. DWORD dwBytesRead = 0;
  88. if (_pbBase == NULL)
  89. {
  90. Verify (-1 != SetFilePointer(_hFile,
  91. uOffset * sizeof(SECT),
  92. 0,
  93. FILE_BEGIN));
  94. Verify (ReadFile( _hFile, &sect, sizeof(SECT), &dwBytesRead, NULL));
  95. // we are writing the script as is
  96. // swap((char *) &sect, sizeof(ULONG));
  97. }
  98. else
  99. {
  100. sect = ((ULONG *)_pbBase)[uOffset];
  101. }
  102. return sect;
  103. }
  104. inline USHORT CMappedFile::GetUSHORT(ULONG uOffset)
  105. {
  106. USHORT ushort;
  107. DWORD dwBytesRead = 0;
  108. if (_pbBase == NULL)
  109. {
  110. Verify (-1 != SetFilePointer(_hFile, uOffset, 0, FILE_BEGIN));
  111. Verify (ReadFile( _hFile,
  112. &ushort,
  113. sizeof(USHORT),
  114. &dwBytesRead,
  115. NULL));
  116. }
  117. else
  118. {
  119. ushort = *(USHORT *)((BYTE *)_pbBase+ uOffset);
  120. }
  121. swap((char *) &ushort, sizeof(USHORT));
  122. return ushort;
  123. }
  124. inline ULONG CMappedFile::GetULONG(ULONG uOffset)
  125. {
  126. ULONG ulong;
  127. DWORD dwBytesRead = 0;
  128. if (_pbBase == NULL)
  129. {
  130. Verify (-1 != SetFilePointer(_hFile, uOffset, 0, FILE_BEGIN));
  131. Verify (ReadFile( _hFile, &ulong, sizeof(ULONG), &dwBytesRead, NULL));
  132. }
  133. else
  134. {
  135. ulong = *(ULONG *)((BYTE *)_pbBase+ uOffset);
  136. }
  137. swap((char *) &ulong, sizeof(ULONG));
  138. return ulong;
  139. }
  140. inline CMSFHeaderData * CMappedFile::GetCMSFHeaderData(void)
  141. {
  142. CMSFHeaderData *ph;
  143. if (_pbBase == NULL)
  144. {
  145. // We should never be working on more than one at a time
  146. Assert (_dwHeaderOffset == (DWORD) -1);
  147. DWORD dwBytesRead = 0;
  148. ph = (CMSFHeaderData *) CoTaskMemAlloc(sizeof(CMSFHeaderData));
  149. Assert (ph != NULL);
  150. _dwHeaderOffset = 0;
  151. Verify (-1 != SetFilePointer(_hFile, 0, 0, FILE_BEGIN));
  152. Verify (ReadFile( _hFile,
  153. ph,
  154. sizeof(CMSFHeaderData),
  155. &dwBytesRead,
  156. NULL));
  157. }
  158. else
  159. {
  160. ph = (CMSFHeaderData *)_pbBase;
  161. }
  162. swap((char *) &(ph->_uMinorVersion), sizeof(USHORT));
  163. swap((char *)&(ph->_uDllVersion), sizeof(USHORT));
  164. swap((char *)&(ph->_uByteOrder), sizeof(USHORT));
  165. swap((char *)&(ph->_uSectorShift), sizeof(USHORT));
  166. swap((char *)&(ph->_uMiniSectorShift), sizeof(USHORT));
  167. swap((char *)&(ph->_usReserved), sizeof(USHORT));
  168. swap((char *)&(ph->_ulReserved1), sizeof(ULONG));
  169. swap((char *)&(ph->_ulReserved2), sizeof(ULONG));
  170. swap((char *)&(ph->_csectFat), sizeof(FSINDEX));
  171. swap((char *)&(ph->_sectDirStart), sizeof(SECT));
  172. swap((char *)&(ph->_signature), sizeof(DFSIGNATURE));
  173. swap((char *)&(ph->_ulMiniSectorCutoff), sizeof(ULONG));
  174. swap((char *)&(ph->_sectMiniFatStart), sizeof(SECT));
  175. swap((char *)&(ph->_csectMiniFat), sizeof(FSINDEX));
  176. swap((char *)&(ph->_sectDifStart), sizeof(SECT));
  177. swap((char *)&(ph->_csectDif), sizeof(FSINDEX));
  178. for (ULONG i = 0; i < CSECTFAT; i++)
  179. {
  180. swap((char *)&(ph->_sectFat[i]), sizeof(SECT));
  181. }
  182. return ph;
  183. }
  184. inline CFatSect * CMappedFile::GetCFatSect (ULONG uOffset)
  185. {
  186. UINT i;
  187. CFatSect *pfs;
  188. if (_pbBase == NULL)
  189. {
  190. // We should never be working on more than one at a time
  191. Assert (_dwFatSectOffset == (DWORD) -1);
  192. DWORD dwBytesRead = 0;
  193. pfs = (CFatSect *) CoTaskMemAlloc (_uSectorSize );
  194. Assert (pfs != NULL);
  195. _dwFatSectOffset = uOffset;
  196. Verify(-1 != SetFilePointer(_hFile, uOffset, 0, FILE_BEGIN));
  197. Verify (ReadFile( _hFile, pfs, _uSectorSize, &dwBytesRead, NULL));
  198. }
  199. else
  200. {
  201. pfs = (CFatSect *)((BYTE *)_pbBase + uOffset);
  202. }
  203. for (i = 0; i < _uSectorSize; i += sizeof(SECT))
  204. {
  205. swap((char *) &(pfs[i]), sizeof(SECT) );
  206. }
  207. return pfs;
  208. }
  209. inline CDirSect * CMappedFile::GetCDirSect (ULONG uOffset)
  210. {
  211. CDirSect *pds;
  212. if (_pbBase == NULL)
  213. {
  214. // We should never be working on more than one at a time
  215. Assert (_dwDirSectOffset == (DWORD) -1);
  216. DWORD dwBytesRead = 0;
  217. pds = (CDirSect *) CoTaskMemAlloc (_uSectorSize);
  218. Assert (pds != NULL);
  219. _dwDirSectOffset = uOffset;
  220. Verify (-1 != SetFilePointer(_hFile, uOffset, 0, FILE_BEGIN));
  221. Verify (ReadFile( _hFile, pds, _uSectorSize, &dwBytesRead, NULL));
  222. }
  223. else
  224. {
  225. pds = (CDirSect *)((BYTE *)_pbBase + uOffset);
  226. }
  227. // don't swap this all here, because it is a byte array.
  228. // We will have to individual members separately
  229. return pds;
  230. }
  231. inline SCODE CMappedFile::ReadFromFile(BYTE *pbBuffer,
  232. ULONG uOffset,
  233. ULONG uSize)
  234. {
  235. DWORD dwBytesRead = 0;
  236. if (pbBuffer == NULL)
  237. {
  238. return STG_E_INVALIDPARAMETER;
  239. }
  240. if (-1 == SetFilePointer(_hFile, uOffset, 0, FILE_BEGIN))
  241. {
  242. return GetLastError();
  243. }
  244. if (!ReadFile( _hFile, pbBuffer, uSize, &dwBytesRead, NULL))
  245. {
  246. return GetLastError();
  247. }
  248. return S_OK;
  249. }
  250. inline SCODE CMappedFile::WriteToFile( BYTE *pbBuffer,
  251. ULONG uOffset,
  252. ULONG uSize )
  253. {
  254. DWORD dwBytesWritten = 0;
  255. if (pbBuffer == NULL)
  256. {
  257. return STG_E_INVALIDPARAMETER;
  258. }
  259. if (-1 == SetFilePointer(_hFile, uOffset, 0, FILE_BEGIN))
  260. {
  261. return GetLastError();
  262. }
  263. if (!WriteFile( _hFile, pbBuffer, uSize, &dwBytesWritten, NULL))
  264. {
  265. return GetLastError();
  266. }
  267. return S_OK;
  268. }
  269. inline SCODE CMappedFile::WriteToFile (CMSFHeaderData *pheader)
  270. {
  271. DWORD dwBytesWritten = 0;
  272. if (pheader == NULL)
  273. {
  274. return STG_E_INVALIDPARAMETER;
  275. }
  276. swap((char *) &(pheader->_uMinorVersion), sizeof(USHORT));
  277. swap((char *) &(pheader->_uDllVersion), sizeof(USHORT));
  278. swap((char *) &(pheader->_uByteOrder), sizeof(USHORT));
  279. swap((char *) &(pheader->_uSectorShift), sizeof(USHORT));
  280. swap((char *) &(pheader->_uMiniSectorShift), sizeof(USHORT));
  281. swap((char *)&(pheader->_usReserved), sizeof(USHORT));
  282. swap((char *)&(pheader->_ulReserved1), sizeof(ULONG));
  283. swap((char *)&(pheader->_ulReserved2), sizeof(ULONG));
  284. swap((char *)&(pheader->_csectFat), sizeof(FSINDEX));
  285. swap((char *)&(pheader->_sectDirStart), sizeof(SECT));
  286. swap((char *)&(pheader->_signature), sizeof(DFSIGNATURE));
  287. swap((char *)&(pheader->_ulMiniSectorCutoff), sizeof(ULONG));
  288. swap((char *)&(pheader->_sectMiniFatStart), sizeof(SECT));
  289. swap((char *)&(pheader->_csectMiniFat), sizeof(FSINDEX));
  290. swap((char *)&(pheader->_sectDifStart), sizeof(SECT));
  291. swap((char *)&(pheader->_csectDif), sizeof(FSINDEX));
  292. for (ULONG i = 0; i < CSECTFAT; i++)
  293. {
  294. swap((char *)&(pheader->_sectFat[i]), sizeof(SECT));
  295. }
  296. if (_pbBase == NULL)
  297. {
  298. if (-1 == SetFilePointer(_hFile, 0, 0, FILE_BEGIN))
  299. {
  300. return GetLastError();
  301. }
  302. if (!WriteFile(_hFile,
  303. pheader,
  304. sizeof (CMSFHeaderData),
  305. &dwBytesWritten,
  306. NULL))
  307. {
  308. return GetLastError();
  309. }
  310. }
  311. return S_OK;
  312. }
  313. inline SCODE CMappedFile::WriteToFile (CFatSect *pfs)
  314. {
  315. DWORD dwBytesWritten = 0;
  316. UINT i;
  317. if (pfs == NULL)
  318. {
  319. return STG_E_INVALIDPARAMETER;
  320. }
  321. for (i =0; i < _uSectorSize; i += sizeof(SECT))
  322. {
  323. swap((char *) &(pfs[i]), sizeof(SECT) );
  324. }
  325. if (_pbBase == NULL)
  326. {
  327. if (-1 == SetFilePointer(_hFile, _dwFatSectOffset, 0, FILE_BEGIN))
  328. {
  329. return GetLastError();
  330. }
  331. if (!WriteFile( _hFile, pfs, _uSectorSize, &dwBytesWritten, NULL))
  332. {
  333. return GetLastError();
  334. }
  335. }
  336. return S_OK;
  337. }
  338. inline SCODE CMappedFile::WriteToFile (CDirSect *pds)
  339. {
  340. DWORD dwBytesWritten = 0;
  341. if (pds == NULL)
  342. {
  343. return STG_E_INVALIDPARAMETER;
  344. }
  345. if (_pbBase == NULL)
  346. {
  347. if (-1 == SetFilePointer(_hFile, _dwDirSectOffset, 0, FILE_BEGIN))
  348. {
  349. return GetLastError();
  350. }
  351. // don't swap this all here, because it is a byte array.
  352. // We will have to individual members separately
  353. if (!WriteFile( _hFile, pds, _uSectorSize, &dwBytesWritten, NULL))
  354. {
  355. return GetLastError();
  356. }
  357. }
  358. return S_OK;
  359. }
  360. inline void CMappedFile::Remove (CMSFHeaderData *pheader)
  361. {
  362. if (_pbBase == NULL)
  363. {
  364. _dwHeaderOffset = (DWORD) -1;
  365. CoTaskMemFree(pheader);
  366. }
  367. }
  368. inline void CMappedFile::Remove (CFatSect *pfs)
  369. {
  370. if (_pbBase == NULL)
  371. {
  372. _dwFatSectOffset = (DWORD) -1;
  373. CoTaskMemFree (pfs);
  374. }
  375. }
  376. inline void CMappedFile::Remove (CDirSect *pds)
  377. {
  378. if (_pbBase == NULL)
  379. {
  380. _dwDirSectOffset = (DWORD) -1;
  381. CoTaskMemFree (pds);
  382. }
  383. }
  384. inline void CMappedFile::SetSectorSize(ULONG cbSectorSize)
  385. {
  386. _uSectorSize = cbSectorSize;
  387. }
  388. inline CMappedFile::CMappedFile(void)
  389. {
  390. _hFile = INVALID_HANDLE_VALUE;
  391. #ifdef SUPPORT_FILE_MAPPING
  392. _hMapping = INVALID_HANDLE_VALUE;
  393. #endif
  394. _pbBase = NULL;
  395. _dwFatSectOffset = (DWORD) -1;
  396. _dwDirSectOffset = (DWORD) -1;
  397. _dwHeaderOffset = (DWORD) -1;
  398. _uSectorSize = 512; //default sector size
  399. }
  400. inline void * CMappedFile::GetBaseAddress(void)
  401. {
  402. return _pbBase;
  403. }
  404. inline ULONG CMappedFile::GetSize(void)
  405. {
  406. layAssert(_hFile != INVALID_HANDLE_VALUE);
  407. return GetFileSize(_hFile, NULL);
  408. }
  409. #endif // #ifndef __MAPFILE_HXX__