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.

552 lines
14 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. if (-1 == SetFilePointer(_hFile,
  91. uOffset * sizeof(SECT),
  92. 0,
  93. FILE_BEGIN))
  94. return ENDOFCHAIN;
  95. if (FALSE == ReadFile( _hFile, &sect, sizeof(SECT), &dwBytesRead, NULL))
  96. return ENDOFCHAIN;
  97. // we are writing the script as is
  98. // swap((char *) &sect, sizeof(ULONG));
  99. }
  100. else
  101. {
  102. sect = ((ULONG *)_pbBase)[uOffset];
  103. }
  104. return sect;
  105. }
  106. inline USHORT CMappedFile::GetUSHORT(ULONG uOffset)
  107. {
  108. USHORT ushort;
  109. DWORD dwBytesRead = 0;
  110. if (_pbBase == NULL)
  111. {
  112. if (-1 == SetFilePointer(_hFile, uOffset, 0, FILE_BEGIN))
  113. return 0;
  114. if (FALSE == ReadFile( _hFile,
  115. &ushort,
  116. sizeof(USHORT),
  117. &dwBytesRead,
  118. NULL))
  119. return 0;
  120. }
  121. else
  122. {
  123. ushort = *(USHORT *)((BYTE *)_pbBase+ uOffset);
  124. }
  125. swap((char *) &ushort, sizeof(USHORT));
  126. return ushort;
  127. }
  128. inline ULONG CMappedFile::GetULONG(ULONG uOffset)
  129. {
  130. ULONG ulong;
  131. DWORD dwBytesRead = 0;
  132. if (_pbBase == NULL)
  133. {
  134. if (-1 == SetFilePointer(_hFile, uOffset, 0, FILE_BEGIN))
  135. return ENDOFCHAIN;
  136. if (FALSE == ReadFile( _hFile, &ulong, sizeof(ULONG), &dwBytesRead, NULL))
  137. return ENDOFCHAIN;
  138. }
  139. else
  140. {
  141. ulong = *(ULONG *)((BYTE *)_pbBase+ uOffset);
  142. }
  143. swap((char *) &ulong, sizeof(ULONG));
  144. return ulong;
  145. }
  146. inline CMSFHeaderData * CMappedFile::GetCMSFHeaderData(void)
  147. {
  148. CMSFHeaderData *ph;
  149. if (_pbBase == NULL)
  150. {
  151. // We should never be working on more than one at a time
  152. Assert (_dwHeaderOffset == (DWORD) -1);
  153. DWORD dwBytesRead = 0;
  154. ph = (CMSFHeaderData *) CoTaskMemAlloc(sizeof(CMSFHeaderData));
  155. if (ph == NULL)
  156. return NULL;
  157. _dwHeaderOffset = 0;
  158. if (-1 == SetFilePointer(_hFile, 0, 0, FILE_BEGIN))
  159. {
  160. CoTaskMemFree (ph);
  161. return NULL;
  162. }
  163. if (FALSE == ReadFile( _hFile,
  164. ph,
  165. sizeof(CMSFHeaderData),
  166. &dwBytesRead,
  167. NULL) || dwBytesRead != sizeof(CMSFHeaderData))
  168. {
  169. CoTaskMemFree (ph);
  170. return NULL;
  171. }
  172. }
  173. else
  174. {
  175. ph = (CMSFHeaderData *)_pbBase;
  176. }
  177. swap((char *) &(ph->_uMinorVersion), sizeof(USHORT));
  178. swap((char *)&(ph->_uDllVersion), sizeof(USHORT));
  179. swap((char *)&(ph->_uByteOrder), sizeof(USHORT));
  180. swap((char *)&(ph->_uSectorShift), sizeof(USHORT));
  181. swap((char *)&(ph->_uMiniSectorShift), sizeof(USHORT));
  182. swap((char *)&(ph->_usReserved), sizeof(USHORT));
  183. swap((char *)&(ph->_ulReserved1), sizeof(ULONG));
  184. swap((char *)&(ph->_ulReserved2), sizeof(ULONG));
  185. swap((char *)&(ph->_csectFat), sizeof(FSINDEX));
  186. swap((char *)&(ph->_sectDirStart), sizeof(SECT));
  187. swap((char *)&(ph->_signature), sizeof(DFSIGNATURE));
  188. swap((char *)&(ph->_ulMiniSectorCutoff), sizeof(ULONG));
  189. swap((char *)&(ph->_sectMiniFatStart), sizeof(SECT));
  190. swap((char *)&(ph->_csectMiniFat), sizeof(FSINDEX));
  191. swap((char *)&(ph->_sectDifStart), sizeof(SECT));
  192. swap((char *)&(ph->_csectDif), sizeof(FSINDEX));
  193. for (ULONG i = 0; i < CSECTFAT; i++)
  194. {
  195. swap((char *)&(ph->_sectFat[i]), sizeof(SECT));
  196. }
  197. return ph;
  198. }
  199. inline CFatSect * CMappedFile::GetCFatSect (ULONG uOffset)
  200. {
  201. UINT i;
  202. CFatSect *pfs;
  203. if (_pbBase == NULL)
  204. {
  205. // We should never be working on more than one at a time
  206. if (_dwFatSectOffset != (DWORD) -1)
  207. return NULL;
  208. DWORD dwBytesRead = 0;
  209. pfs = (CFatSect *) CoTaskMemAlloc (_uSectorSize );
  210. if (pfs == NULL)
  211. return NULL;
  212. _dwFatSectOffset = uOffset;
  213. if (-1 == SetFilePointer(_hFile, uOffset, 0, FILE_BEGIN))
  214. {
  215. CoTaskMemFree (pfs);
  216. return NULL;
  217. }
  218. if (FALSE ==ReadFile( _hFile, pfs, _uSectorSize, &dwBytesRead, NULL) ||
  219. dwBytesRead != _uSectorSize)
  220. {
  221. CoTaskMemFree (pfs);
  222. return NULL;
  223. }
  224. }
  225. else
  226. {
  227. pfs = (CFatSect *)((BYTE *)_pbBase + uOffset);
  228. }
  229. for (i = 0; i < _uSectorSize; i += sizeof(SECT))
  230. {
  231. swap((char *) &(pfs[i]), sizeof(SECT) );
  232. }
  233. return pfs;
  234. }
  235. inline CDirSect * CMappedFile::GetCDirSect (ULONG uOffset)
  236. {
  237. CDirSect *pds;
  238. if (_pbBase == NULL)
  239. {
  240. // We should never be working on more than one at a time
  241. Assert (_dwDirSectOffset == (DWORD) -1);
  242. DWORD dwBytesRead = 0;
  243. pds = (CDirSect *) CoTaskMemAlloc (_uSectorSize);
  244. if (pds == NULL)
  245. return NULL;
  246. _dwDirSectOffset = uOffset;
  247. if (-1 == SetFilePointer(_hFile, uOffset, 0, FILE_BEGIN))
  248. {
  249. CoTaskMemFree (pds);
  250. return NULL;
  251. }
  252. if (FALSE == ReadFile( _hFile, pds, _uSectorSize, &dwBytesRead, NULL) ||
  253. dwBytesRead != _uSectorSize)
  254. {
  255. CoTaskMemFree (pds);
  256. return NULL;
  257. }
  258. }
  259. else
  260. {
  261. pds = (CDirSect *)((BYTE *)_pbBase + uOffset);
  262. }
  263. // don't swap this all here, because it is a byte array.
  264. // We will have to individual members separately
  265. return pds;
  266. }
  267. inline SCODE CMappedFile::ReadFromFile(BYTE *pbBuffer,
  268. ULONG uOffset,
  269. ULONG uSize)
  270. {
  271. DWORD dwBytesRead = 0;
  272. if (pbBuffer == NULL)
  273. {
  274. return STG_E_INVALIDPARAMETER;
  275. }
  276. if (-1 == SetFilePointer(_hFile, uOffset, 0, FILE_BEGIN))
  277. {
  278. return GetLastError();
  279. }
  280. if (!ReadFile( _hFile, pbBuffer, uSize, &dwBytesRead, NULL))
  281. {
  282. return GetLastError();
  283. }
  284. return S_OK;
  285. }
  286. inline SCODE CMappedFile::WriteToFile( BYTE *pbBuffer,
  287. ULONG uOffset,
  288. ULONG uSize )
  289. {
  290. DWORD dwBytesWritten = 0;
  291. if (pbBuffer == NULL)
  292. {
  293. return STG_E_INVALIDPARAMETER;
  294. }
  295. if (-1 == SetFilePointer(_hFile, uOffset, 0, FILE_BEGIN))
  296. {
  297. return GetLastError();
  298. }
  299. if (!WriteFile( _hFile, pbBuffer, uSize, &dwBytesWritten, NULL))
  300. {
  301. return GetLastError();
  302. }
  303. return S_OK;
  304. }
  305. inline SCODE CMappedFile::WriteToFile (CMSFHeaderData *pheader)
  306. {
  307. DWORD dwBytesWritten = 0;
  308. if (pheader == NULL)
  309. {
  310. return STG_E_INVALIDPARAMETER;
  311. }
  312. swap((char *) &(pheader->_uMinorVersion), sizeof(USHORT));
  313. swap((char *) &(pheader->_uDllVersion), sizeof(USHORT));
  314. swap((char *) &(pheader->_uByteOrder), sizeof(USHORT));
  315. swap((char *) &(pheader->_uSectorShift), sizeof(USHORT));
  316. swap((char *) &(pheader->_uMiniSectorShift), sizeof(USHORT));
  317. swap((char *)&(pheader->_usReserved), sizeof(USHORT));
  318. swap((char *)&(pheader->_ulReserved1), sizeof(ULONG));
  319. swap((char *)&(pheader->_ulReserved2), sizeof(ULONG));
  320. swap((char *)&(pheader->_csectFat), sizeof(FSINDEX));
  321. swap((char *)&(pheader->_sectDirStart), sizeof(SECT));
  322. swap((char *)&(pheader->_signature), sizeof(DFSIGNATURE));
  323. swap((char *)&(pheader->_ulMiniSectorCutoff), sizeof(ULONG));
  324. swap((char *)&(pheader->_sectMiniFatStart), sizeof(SECT));
  325. swap((char *)&(pheader->_csectMiniFat), sizeof(FSINDEX));
  326. swap((char *)&(pheader->_sectDifStart), sizeof(SECT));
  327. swap((char *)&(pheader->_csectDif), sizeof(FSINDEX));
  328. for (ULONG i = 0; i < CSECTFAT; i++)
  329. {
  330. swap((char *)&(pheader->_sectFat[i]), sizeof(SECT));
  331. }
  332. if (_pbBase == NULL)
  333. {
  334. if (-1 == SetFilePointer(_hFile, 0, 0, FILE_BEGIN))
  335. {
  336. return GetLastError();
  337. }
  338. if (!WriteFile(_hFile,
  339. pheader,
  340. sizeof (CMSFHeaderData),
  341. &dwBytesWritten,
  342. NULL))
  343. {
  344. return GetLastError();
  345. }
  346. }
  347. return S_OK;
  348. }
  349. inline SCODE CMappedFile::WriteToFile (CFatSect *pfs)
  350. {
  351. DWORD dwBytesWritten = 0;
  352. UINT i;
  353. if (pfs == NULL)
  354. {
  355. return STG_E_INVALIDPARAMETER;
  356. }
  357. for (i =0; i < _uSectorSize; i += sizeof(SECT))
  358. {
  359. swap((char *) &(pfs[i]), sizeof(SECT) );
  360. }
  361. if (_pbBase == NULL)
  362. {
  363. if (-1 == SetFilePointer(_hFile, _dwFatSectOffset, 0, FILE_BEGIN))
  364. {
  365. return GetLastError();
  366. }
  367. if (!WriteFile( _hFile, pfs, _uSectorSize, &dwBytesWritten, NULL))
  368. {
  369. return GetLastError();
  370. }
  371. }
  372. return S_OK;
  373. }
  374. inline SCODE CMappedFile::WriteToFile (CDirSect *pds)
  375. {
  376. DWORD dwBytesWritten = 0;
  377. if (pds == NULL)
  378. {
  379. return STG_E_INVALIDPARAMETER;
  380. }
  381. if (_pbBase == NULL)
  382. {
  383. if (-1 == SetFilePointer(_hFile, _dwDirSectOffset, 0, FILE_BEGIN))
  384. {
  385. return GetLastError();
  386. }
  387. // don't swap this all here, because it is a byte array.
  388. // We will have to individual members separately
  389. if (!WriteFile( _hFile, pds, _uSectorSize, &dwBytesWritten, NULL))
  390. {
  391. return GetLastError();
  392. }
  393. }
  394. return S_OK;
  395. }
  396. inline void CMappedFile::Remove (CMSFHeaderData *pheader)
  397. {
  398. if (_pbBase == NULL)
  399. {
  400. _dwHeaderOffset = (DWORD) -1;
  401. CoTaskMemFree(pheader);
  402. }
  403. }
  404. inline void CMappedFile::Remove (CFatSect *pfs)
  405. {
  406. if (_pbBase == NULL)
  407. {
  408. _dwFatSectOffset = (DWORD) -1;
  409. CoTaskMemFree (pfs);
  410. }
  411. }
  412. inline void CMappedFile::Remove (CDirSect *pds)
  413. {
  414. if (_pbBase == NULL)
  415. {
  416. _dwDirSectOffset = (DWORD) -1;
  417. CoTaskMemFree (pds);
  418. }
  419. }
  420. inline void CMappedFile::SetSectorSize(ULONG cbSectorSize)
  421. {
  422. _uSectorSize = cbSectorSize;
  423. }
  424. inline CMappedFile::CMappedFile(void)
  425. {
  426. _hFile = INVALID_HANDLE_VALUE;
  427. #ifdef SUPPORT_FILE_MAPPING
  428. _hMapping = INVALID_HANDLE_VALUE;
  429. #endif
  430. _pbBase = NULL;
  431. _dwFatSectOffset = (DWORD) -1;
  432. _dwDirSectOffset = (DWORD) -1;
  433. _dwHeaderOffset = (DWORD) -1;
  434. _uSectorSize = 512; //default sector size
  435. }
  436. inline void * CMappedFile::GetBaseAddress(void)
  437. {
  438. return _pbBase;
  439. }
  440. inline ULONG CMappedFile::GetSize(void)
  441. {
  442. layAssert(_hFile != INVALID_HANDLE_VALUE);
  443. return GetFileSize(_hFile, NULL);
  444. }
  445. #endif // #ifndef __MAPFILE_HXX__