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.

1269 lines
36 KiB

  1. //+--------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1991 - 1992
  5. //
  6. // File: filest.hxx
  7. //
  8. // Contents: Windows FAT ILockBytes implementation
  9. //
  10. // History: 20-Nov-91 DrewB Created
  11. //
  12. //---------------------------------------------------------------
  13. #ifndef __FILEST_HXX__
  14. #define __FILEST_HXX__
  15. #include <dfmsp.hxx>
  16. #include <cntxlist.hxx>
  17. #include <filelkb.hxx>
  18. #if WIN32 >= 300
  19. #include <accstg.hxx>
  20. #endif
  21. #ifdef ASYNC
  22. #include <iconn.h>
  23. #endif
  24. #include <debnot.h>
  25. DECLARE_DEBUG(filest);
  26. #define DEB_INFO DEB_USER1 // General File Stream Information.
  27. #define DEB_SEEK DEB_USER2 // Report all Seeks.
  28. #define DEB_MAP DEB_USER3 // Information about the File Map.
  29. #define DEB_MAPIO DEB_USER4 // Report all I/O via the File Map.
  30. #define DEB_FILEIO DEB_USER5 // Report all I/O via ReadFile/WriteFile.
  31. #define DEB_LOCK DEB_USER6 // Report all file locking.
  32. #define fsErr(l, e) ErrJmp(filest, l, e, sc)
  33. #define fsChkTo(l, e) if (FAILED(sc = (e))) fsErr(l, sc) else 1
  34. #define fsHChkTo(l, e) if (FAILED(sc = DfGetScode(e))) fsErr(l, sc) else 1
  35. #define fsHChk(e) fsHChkTo(EH_Err, e)
  36. #define fsChk(e) fsChkTo(EH_Err, e)
  37. #define fsMemTo(l, e) \
  38. if ((e) == NULL) fsErr(l, STG_E_INSUFFICIENTMEMORY) else 1
  39. #define fsMem(e) fsMemTo(EH_Err, e)
  40. #if DBG == 1
  41. #define filestDebugOut(x) filestInlineDebugOut x
  42. #define filestDebug(x) filestDebugOut(x)
  43. #define fsAssert(e) Win4Assert(e)
  44. #define fsVerify(e) Win4Assert(e)
  45. #define fsHVerSucc(e) Win4Assert(SUCCEEDED(DfGetScode(e)))
  46. #else
  47. #define filestDebug(x)
  48. #define fsAssert(e)
  49. #define fsVerify(e) (e)
  50. #define fsHVerSucc(e)
  51. #endif
  52. #define boolChk(e) \
  53. if (!(e)) fsErr(EH_Err, LAST_STG_SCODE) else 1
  54. #define boolChkTo(l, e) \
  55. if (!(e)) fsErr(l, LAST_STG_SCODE) else 1
  56. #define negChk(e) \
  57. if ((e) == 0xffffffff) fsErr(EH_Err, LAST_STG_SCODE) else 1
  58. #define negChkTo(l, e) \
  59. if ((e) == 0xffffffff) fsErr(l, LAST_STG_SCODE) else 1
  60. // Local flags
  61. #define LFF_RESERVE_HANDLE 1
  62. // FILEH and INVALID_FH allow us to switch between file handle
  63. // types for Win16/32
  64. typedef HANDLE FILEH;
  65. #define INVALID_FH INVALID_HANDLE_VALUE
  66. #define CheckHandle() (_hFile == INVALID_FH ? STG_E_INVALIDHANDLE : S_OK)
  67. #if WIN32 == 100 || WIN32 > 200
  68. #define USE_FILEMAPPING
  69. #endif
  70. //
  71. // Flags for carring around state in InitWorker and friends.
  72. //
  73. #define FSINIT_NORMAL 0x0000
  74. #define FSINIT_UNMARSHAL 0x0001 // We are Unmarshaling
  75. #define FSINIT_MADEUPNAME 0x0002 // We made-up the file name.
  76. //+--------------------------------------------------------------
  77. //
  78. // Class: CFileStream (fst)
  79. //
  80. // Purpose: ILockBytes implementation for a file
  81. //
  82. // Interface: See below
  83. //
  84. // History: 24-Mar-92 DrewB Created
  85. // Nov-96 BChapman Mapped files implementation.
  86. //
  87. //---------------------------------------------------------------
  88. class CGlobalFileStream;
  89. class CPerContext;
  90. SAFE_DFBASED_PTR(CBasedGlobalFileStreamPtr, CGlobalFileStream);
  91. interface CFileStream : public ILockBytes,
  92. public IFileLockBytes,
  93. public IMarshal,
  94. #ifdef ASYNC
  95. public IFillLockBytes,
  96. public IFillInfo,
  97. #endif // ASYNC
  98. #if WIN32 >= 300
  99. public CAccessControl,
  100. #endif
  101. public CContext
  102. {
  103. public:
  104. CFileStream(IMalloc * const pMalloc);
  105. #if DBG == 1 && defined(MULTIHEAP)
  106. // This is only for global instances that do not use shared memory
  107. void RemoveFromGlobal () { _pgfst = NULL; _cReferences = 0; };
  108. #endif
  109. CGlobalFileStream * GetGlobal() { return _pgfst; };
  110. SCODE InitGlobal(DWORD dwStartFlags, DFLAGS df);
  111. void InitFromGlobal(CGlobalFileStream *pgfst);
  112. inline SCODE InitFile(WCHAR const *pwcsPath);
  113. inline SCODE InitUnmarshal(void);
  114. inline SCODE InitScratch(void);
  115. inline SCODE InitSnapShot(void);
  116. SCODE InitFromHandle(HANDLE h);
  117. void InitFromFileStream (CFileStream *pfst);
  118. ~CFileStream(void);
  119. ULONG vRelease(void);
  120. inline void vAddRef(void);
  121. // IUnknown
  122. STDMETHOD(QueryInterface)(REFIID iid, void **ppvObj);
  123. STDMETHOD_(ULONG, AddRef)(void);
  124. STDMETHOD_(ULONG, Release)(void);
  125. // IMarshal
  126. STDMETHOD(GetUnmarshalClass)(REFIID riid,
  127. LPVOID pv,
  128. DWORD dwDestContext,
  129. LPVOID pvDestContext,
  130. DWORD mshlflags,
  131. LPCLSID pCid);
  132. STDMETHOD(GetMarshalSizeMax)(REFIID riid,
  133. LPVOID pv,
  134. DWORD dwDestContext,
  135. LPVOID pvDestContext,
  136. DWORD mshlflags,
  137. LPDWORD pSize);
  138. STDMETHOD(MarshalInterface)(IStream *pStm,
  139. REFIID riid,
  140. LPVOID pv,
  141. DWORD dwDestContext,
  142. LPVOID pvDestContext,
  143. DWORD mshlflags);
  144. STDMETHOD(UnmarshalInterface)(IStream *pStm,
  145. REFIID riid,
  146. LPVOID *ppv);
  147. static SCODE StaticReleaseMarshalData(IStream *pstm,
  148. DWORD mshlflags);
  149. STDMETHOD(ReleaseMarshalData)(IStream *pStm);
  150. STDMETHOD(DisconnectObject)(DWORD dwReserved);
  151. // ILockBytes
  152. STDMETHOD(ReadAt)(ULARGE_INTEGER ulOffset,
  153. VOID HUGEP *pv,
  154. ULONG cb,
  155. ULONG *pcbRead);
  156. STDMETHOD(WriteAt)(ULARGE_INTEGER ulOffset,
  157. VOID const HUGEP *pv,
  158. ULONG cb,
  159. ULONG *pcbWritten);
  160. STDMETHOD(Flush)(void);
  161. STDMETHOD(SetSize)(ULARGE_INTEGER cb);
  162. STDMETHOD(LockRegion)(ULARGE_INTEGER libOffset,
  163. ULARGE_INTEGER cb,
  164. DWORD dwLockType);
  165. STDMETHOD(UnlockRegion)(ULARGE_INTEGER libOffset,
  166. ULARGE_INTEGER cb,
  167. DWORD dwLockType);
  168. STDMETHOD(Stat)(STATSTG *pstatstg, DWORD grfStatFlag);
  169. // IFileLockBytes
  170. STDMETHOD(SwitchToFile)(OLECHAR const *ptcsFile,
  171. #ifdef LARGE_DOCFILE
  172. ULONGLONG ulCommitSize,
  173. #else
  174. ULONG ulCommitSize,
  175. #endif
  176. ULONG cbBuffer,
  177. void *pvBuffer);
  178. STDMETHOD(FlushCache)(THIS);
  179. STDMETHOD(ReserveHandle)(void);
  180. STDMETHOD(GetLocksSupported)(THIS_ DWORD *pdwLockFlags);
  181. STDMETHOD(GetSize)(THIS_ ULARGE_INTEGER *puliSize);
  182. STDMETHOD_(ULONG, GetSectorSize) (THIS);
  183. STDMETHOD_(BOOL, IsEncryptedFile) (THIS);
  184. #ifdef ASYNC
  185. //IFillLockBytes
  186. STDMETHOD(FillAppend)(void const *pv,
  187. ULONG cb,
  188. ULONG *pcbWritten);
  189. STDMETHOD(FillAt)(ULARGE_INTEGER ulOffset,
  190. void const *pv,
  191. ULONG cb,
  192. ULONG *pcbWritten);
  193. STDMETHOD(SetFillSize)(ULARGE_INTEGER ulSize);
  194. STDMETHOD(Terminate)(BOOL bCanceled);
  195. //From IFillInfo
  196. STDMETHOD(GetFailureInfo)(ULONG *pulWaterMark,
  197. ULONG *pulFailurePoint);
  198. STDMETHOD(GetTerminationStatus)(DWORD *pdwFlags);
  199. void StartAsyncMode(void);
  200. inline void SetContext(CPerContext *ppc);
  201. inline CPerContext *GetContextPointer(void) const;
  202. #endif // ASYNC
  203. // New
  204. SCODE GetName(WCHAR **ppwcsName);
  205. inline ContextId GetContext(void) const;
  206. inline CFileStream *GetNext(void) const;
  207. inline SCODE Validate(void) const;
  208. inline void SetStartFlags(DWORD dwStartFlags);
  209. inline DWORD GetStartFlags(void) const;
  210. inline DFLAGS GetFlags(void) const;
  211. inline IMalloc *GetMalloc(void) const;
  212. void Delete(void);
  213. SCODE SetTime(WHICHTIME tt, TIME_T nt);
  214. SCODE SetAllTimes(TIME_T atm, TIME_T mtm, TIME_T ctm);
  215. static SCODE Unmarshal(IStream *pstm,
  216. void **ppv,
  217. DWORD mshlflags);
  218. inline void TurnOffAllMappings(void);
  219. inline BOOL IsHandleValid ();
  220. private:
  221. SCODE InitWorker(
  222. WCHAR const *pwcsPath,
  223. DWORD fCheck);
  224. SCODE Init_GetNtOpenFlags(
  225. LPDWORD pdwAccess,
  226. LPDWORD pdwShare,
  227. LPDWORD pdwCreation,
  228. LPDWORD pdwFlagAttr);
  229. SCODE Init_OpenOrCreate(
  230. WCHAR *pwcPath,
  231. TCHAR *ptcTmpPath,
  232. DWORD dwFSInit);
  233. SCODE Init_DupFileHandle(DWORD dwFSInit);
  234. SCODE DupFileHandleToOthers(void);
  235. #ifdef LARGE_DOCFILE
  236. SCODE SetSizeWorker(ULONGLONG ulSize);
  237. #else
  238. SCODE SetSizeWorker(ULONG ulLow);
  239. #endif
  240. SCODE WriteAtWorker(
  241. #ifdef LARGE_DOCFILE
  242. ULARGE_INTEGER ulPosition,
  243. #else
  244. ULONG ulLow,
  245. #endif
  246. VOID const *pb,
  247. ULONG cb,
  248. ULONG *pcbWritten);
  249. SCODE Init_GetTempName(
  250. TCHAR *ptcPath,
  251. TCHAR *ptcTmpPath);
  252. SCODE ReadAt_FromFile(
  253. #ifdef LARGE_DOCFILE
  254. ULONGLONG iPosition,
  255. #else
  256. ULONG iPosition,
  257. #endif
  258. VOID *pb,
  259. ULONG cb,
  260. ULONG *pcbRead);
  261. BOOL DeleteTheFile(const WCHAR *pwcName);
  262. #ifdef USE_FILEMAPPING
  263. SCODE Init_MemoryMap(DWORD dwFSinit);
  264. SCODE MapView(SIZE_T cbViewSize,
  265. DWORD dwPageFlags,
  266. DWORD dwFSInit);
  267. inline SCODE CheckMapView(ULONG cbRequested);
  268. SCODE ExtendMapView(ULONG cbRequest);
  269. inline SCODE MakeFileMapAddressValid(ULONG cbRequested);
  270. SCODE MakeFileMapAddressValidWorker( ULONG cbRequested,
  271. ULONG cbCommited);
  272. SCODE TurnOffMapping(BOOL fFlush);
  273. SCODE MakeFileStub(void);
  274. inline BOOL IsFileMapped(void);
  275. SCODE ReadAt_FromMap(
  276. ULONG iPosition,
  277. VOID *pb,
  278. ULONG cb,
  279. ULONG *pcbRead);
  280. #else
  281. inline SCODE Init_MemoryMap(DWORD) { return S_OK; };
  282. inline SCODE MapView(SIZE_T, DWORD, DWORD) { return S_OK; };
  283. inline SCODE CheckMapView(ULONG cbRequested) { return S_OK; };
  284. inline SCODE MakeFileMapAddressValid(ULONG) { return S_OK; };
  285. inline SCODE TurnOffMapping() { return S_OK; };
  286. inline void TurnOffAllMappings(void) {};
  287. inline BOOL IsFileMapped(void) { return FALSE; };
  288. inline SCODE ReadAt_FromMap(ULONG, VOID*, ULONG, ULONG*) { return E_FAIL; };
  289. #endif
  290. #ifdef LARGE_DOCFILE
  291. ULONGLONG SeekTo(ULONGLONG newPosition);
  292. ULONGLONG GetFilePointer();
  293. #if DBG == 1
  294. SCODE PossibleDiskFull(ULONGLONG);
  295. void CheckSeekPointer(void);
  296. #else
  297. inline SCODE PossibleDiskFull(ULONGLONG) { return S_OK; };
  298. inline void CheckSeekPointer(void) { };
  299. #endif
  300. inline void SetCachedFilePointer(ULONGLONG ulPos);
  301. inline BOOL FilePointerEqual(ULONGLONG ulPos);
  302. #else // !LARGE_DOCFILE
  303. DWORD SeekTo (ULONG newPosition);
  304. DWORD GetFilePointer();
  305. #if DBG == 1
  306. SCODE PossibleDiskFull(ULONG);
  307. void CheckSeekPointer(void);
  308. #else
  309. inline SCODE PossibleDiskFull(ULONG) { return S_OK; };
  310. inline void CheckSeekPointer(void) { };
  311. #endif
  312. inline void SetCachedFilePointer(ULONG ulLowPos);
  313. inline BOOL FilePointerEqual(ULONG ulLowPos);
  314. #endif // LARGE_DOCFILE
  315. CBasedGlobalFileStreamPtr _pgfst;
  316. #ifdef ASYNC
  317. CPerContext *_ppc;
  318. #endif
  319. FILEH _hFile;
  320. FILEH _hReserved;
  321. FILEH _hPreDuped; // other contexts can "push" dup'ed file handles here.
  322. ULONG _sig;
  323. LONG _cReferences;
  324. // Floppy support
  325. SCODE CheckIdentity(void);
  326. BYTE _fFixedDisk;
  327. DWORD _dwTicks;
  328. char _achVolume[11];
  329. DWORD _dwVolId;
  330. IMalloc * const _pMalloc;
  331. WORD _grfLocal;
  332. //
  333. // File Mapping state.
  334. //
  335. HANDLE _hMapObject;
  336. LPBYTE _pbBaseAddr;
  337. DWORD _cbViewSize;
  338. };
  339. #define COMMIT_BLOCK (16*1024)
  340. #define MAPNAME_MAXLEN 32
  341. #define MAPNAME_FORMAT L"DFMap%d-%d"
  342. #define TEMPFILE_PREFIX TSTR("~DF")
  343. //
  344. // Valid states for (Set/Reset/Test)State()
  345. //
  346. #ifdef USE_FILEMAPPING
  347. #define FSTSTATE_MAPPED 0x01 // Can (and is) using File Map.
  348. #define FSTSTATE_PAGEFILE 0x02 // Map is a map over the PageFile.
  349. #define FSTSTATE_SPILLED 0x04 // Was PAGEFILE but has been spilled.
  350. #define FSTSTATE_DIRTY 0x08 // Has fileMapping been written to.
  351. #endif // USE_FILEMAPPING
  352. //+---------------------------------------------------------------------------
  353. //
  354. // Class: CGlobalFileStream (gfst)
  355. //
  356. // Purpose: Maintains context-insensitive filestream information
  357. //
  358. // Interface: See below
  359. //
  360. // History: 26-Oct-92 DrewB Created
  361. //
  362. //----------------------------------------------------------------------------
  363. class CGlobalFileStream : public CContextList
  364. {
  365. public:
  366. inline CGlobalFileStream(IMalloc * const pMalloc,
  367. WCHAR const *pwcsPath,
  368. DFLAGS df,
  369. DWORD dwStartFlags);
  370. DECLARE_CONTEXT_LIST(CFileStream);
  371. void InitFromGlobalFileStream (CGlobalFileStream *pgfs);
  372. inline BOOL HasName(void) const;
  373. inline const WCHAR *GetName(void) const;
  374. inline void SetName(WCHAR const *pwcsPath);
  375. inline DFLAGS GetDFlags(void) const;
  376. inline DWORD GetStartFlags(void) const;
  377. inline void SetStartFlags(DWORD dwStartFlags);
  378. #ifdef USE_FILEMAPPING
  379. inline const WCHAR *GetMappingName(void) const;
  380. inline void SetMappingName(WCHAR const *pszmapName);
  381. inline ULONG GetMappedFileSize(void) const;
  382. inline void SetMappedFileSize(ULONG cbSize);
  383. inline ULONG GetMappedCommitSize(void) const;
  384. inline void SetMappedCommitSize(ULONG cbSize);
  385. inline void SetMapState(DWORD flag);
  386. inline void ResetMapState(DWORD flag);
  387. inline BOOL TestMapState(DWORD flag) const;
  388. #else
  389. // These stub out the File Mapping routines.
  390. //
  391. inline const WCHAR *GetMappingName(void) const { return NULL; };
  392. inline void SetMappingName(WCHAR const *pszmapName) { };
  393. inline ULONG GetMappedFileSize(void) const { return 0;} ;
  394. inline void SetMappedFileSize(ULONG cbSize) {};
  395. inline ULONG GetMappedCommitSize(void) const { return 0;} ;
  396. inline void SetMappedCommitSize(ULONG cbSize) {};
  397. inline void SetMapState(DWORD) {};
  398. inline void ResetMapState(DWORD) {};
  399. inline BOOL TestMapState(DWORD) const { return FALSE; };
  400. #endif
  401. inline IMalloc *GetMalloc(VOID) const;
  402. inline CFileStream *GetFirstContext() const;
  403. #ifdef LARGE_DOCFILE
  404. inline void SetCachedFilePointer(ULONGLONG llPos);
  405. inline BOOL FilePointerEqual(ULONGLONG llPos);
  406. #if DBG == 1
  407. void CheckSeekPointer(ULONGLONG ulChk);
  408. #endif
  409. #else
  410. inline void SetCachedFilePointer(ULONG ulLowPos);
  411. inline BOOL FilePointerEqual(ULONG ulLowPos);
  412. #if DBG == 1
  413. void CheckSeekPointer(DWORD ulLowChk);
  414. #endif
  415. #endif // LARGE_DOCFILE
  416. #ifdef ASYNC
  417. inline DWORD GetTerminationStatus(void) const;
  418. #ifdef LARGE_DOCFILE
  419. inline ULONGLONG GetHighWaterMark(void) const;
  420. inline ULONGLONG GetFailurePoint(void) const;
  421. #else
  422. inline ULONG GetHighWaterMark(void) const;
  423. inline ULONG GetFailurePoint(void) const;
  424. #endif
  425. inline void SetTerminationStatus(DWORD dwTerminate);
  426. #ifdef LARGE_DOCFILE
  427. inline void SetHighWaterMark(ULONGLONG ulHighWater);
  428. inline void SetFailurePoint(ULONGLONG ulFailure);
  429. #else
  430. inline void SetHighWaterMark(ULONG ulHighWater);
  431. inline void SetFailurePoint(ULONG ulFailure);
  432. #endif
  433. #endif
  434. inline ULONG GetSectorSize ();
  435. inline void SetSectorSize (ULONG cbSector);
  436. private:
  437. DFLAGS _df;
  438. DWORD _dwStartFlags;
  439. IMalloc * const _pMalloc;
  440. // Cache the current seek Position to save on calls to SetFilePointer
  441. // on Windows95. (We are using an "Overlapped" structure on NT).
  442. // We are duping the file handles on marshaling, so the current seek
  443. // position is shared.
  444. #ifdef LARGE_DOCFILE
  445. ULONGLONG _ulPos;
  446. #else
  447. // NOTE: We rely on the fact that we never pass in a high dword other
  448. // than zero. We only cache the low dword of the seek pointer.
  449. ULONG _ulLowPos;
  450. #endif
  451. ULONG _cbSector;
  452. #ifdef USE_FILEMAPPING
  453. DWORD _cbMappedFileSize;
  454. DWORD _cbMappedCommitSize;
  455. DWORD _dwMapFlags;
  456. WCHAR _awcMapName[MAPNAME_MAXLEN];
  457. #endif
  458. WCHAR _awcPath[_MAX_PATH+1];
  459. #ifdef ASYNC
  460. DWORD _dwTerminate;
  461. #ifdef LARGE_DOCFILE
  462. ULONGLONG _ulHighWater;
  463. ULONGLONG _ulFailurePoint;
  464. #else
  465. ULONG _ulHighWater;
  466. ULONG _ulFailurePoint;
  467. #endif // LARGE_DOCFILE
  468. #endif // ASYNC
  469. #if DBG == 1
  470. #ifdef LARGE_DOCFILE
  471. ULONGLONG _ulLastFilePos;
  472. #else
  473. ULONG _ulLastFilePos;
  474. #endif // LARGE_DOCFILE
  475. #endif
  476. };
  477. //+---------------------------------------------------------------------------
  478. //
  479. // Member: CGlobalFileStream::CGlobalFileStream, public
  480. //
  481. // Synopsis: Constructor
  482. //
  483. // Arguments: [pszPath] - Path
  484. // [df] - Permissions
  485. // [dwStartFlags] - Startup flags
  486. //
  487. // History: 27-Oct-92 DrewB Created
  488. // 18-May-93 AlexT Added pMalloc
  489. //
  490. //----------------------------------------------------------------------------
  491. inline CGlobalFileStream::CGlobalFileStream(IMalloc * const pMalloc,
  492. WCHAR const *pwcsPath,
  493. DFLAGS df,
  494. DWORD dwStartFlags)
  495. : _pMalloc(pMalloc)
  496. {
  497. SetName(pwcsPath);
  498. _df = df;
  499. _dwStartFlags = dwStartFlags;
  500. #ifdef USE_FILEMAPPING
  501. SetMappingName(NULL);
  502. _cbMappedFileSize = 0;
  503. _cbMappedCommitSize = 0;
  504. _dwMapFlags = 0;
  505. #endif
  506. #ifdef ASYNC
  507. _dwTerminate = TERMINATED_NORMAL;
  508. _ulHighWater = _ulFailurePoint = 0;
  509. #endif
  510. #ifdef LARGE_DOCFILE
  511. _ulPos = MAX_ULONGLONG; // 0xFFFFFFFFFFFFFFFF
  512. #if DBG == 1
  513. _ulLastFilePos = MAX_ULONGLONG; // 0xFFFFFFFFFFFFFFFF
  514. #endif
  515. #else
  516. _ulLowPos = 0xFFFFFFFF;
  517. #if DBG == 1
  518. _ulLastFilePos = 0xFFFFFFFF;
  519. #endif
  520. #endif
  521. _cbSector = HEADERSIZE;
  522. }
  523. //+---------------------------------------------------------------------------
  524. //
  525. // Member: CGlobalFileStream::HasName, public
  526. //
  527. // Synopsis: Checks for a name
  528. //
  529. // History: 13-Jan-93 DrewB Created
  530. //
  531. //----------------------------------------------------------------------------
  532. inline BOOL CGlobalFileStream::HasName(void) const
  533. {
  534. return (BOOL)_awcPath[0];
  535. }
  536. //+---------------------------------------------------------------------------
  537. //
  538. // Member: CGlobalFileStream::GetName, public
  539. //
  540. // Synopsis: Returns the name
  541. //
  542. // History: 13-Jan-93 DrewB Created
  543. //
  544. //----------------------------------------------------------------------------
  545. inline WCHAR const *CGlobalFileStream::GetName(void) const
  546. {
  547. return (WCHAR *) _awcPath;
  548. }
  549. //+---------------------------------------------------------------------------
  550. //
  551. // Member: CGlobalFileStream::GetDFlags, public
  552. //
  553. // Synopsis: Returns the flags
  554. //
  555. // History: 13-Jan-93 DrewB Created
  556. //
  557. //----------------------------------------------------------------------------
  558. inline DFLAGS CGlobalFileStream::GetDFlags(void) const
  559. {
  560. return _df;
  561. }
  562. //+---------------------------------------------------------------------------
  563. //
  564. // Member: CGlobalFileStream::GetStartFlags, public
  565. //
  566. // Synopsis: Returns the start flags
  567. //
  568. // History: 13-Jan-93 DrewB Created
  569. //
  570. //----------------------------------------------------------------------------
  571. inline DWORD CGlobalFileStream::GetStartFlags(void) const
  572. {
  573. return _dwStartFlags;
  574. }
  575. //+---------------------------------------------------------------------------
  576. //
  577. // Member: CGlobalFileStream::SetName, public
  578. //
  579. // Synopsis: Sets the name
  580. //
  581. // History: 13-Jan-93 DrewB Created
  582. //
  583. //----------------------------------------------------------------------------
  584. inline void CGlobalFileStream::SetName(WCHAR const *pwcsPath)
  585. {
  586. if (NULL != pwcsPath)
  587. StringCbCopy (_awcPath, sizeof(_awcPath), pwcsPath);
  588. else
  589. _awcPath[0] = 0;
  590. }
  591. //+---------------------------------------------------------------------------
  592. //
  593. // Member: CGlobalFileStream::SetStartFlags, public
  594. //
  595. // Synopsis: Sets the start flags
  596. //
  597. // History: 13-Jan-93 DrewB Created
  598. //
  599. //----------------------------------------------------------------------------
  600. inline void CGlobalFileStream::SetStartFlags(DWORD dwStartFlags)
  601. {
  602. _dwStartFlags = dwStartFlags;
  603. }
  604. #ifdef USE_FILEMAPPING
  605. //+---------------------------------------------------------------------------
  606. //
  607. // Member: CGlobalFileStream::GetMappingName, private
  608. // Member: CGlobalFileStream::SetMappingName, private
  609. //
  610. // Synopsis: Returns/Sets the name of the file mapping object.
  611. //
  612. // History: 13-Jan-1997 BChapman Created
  613. //
  614. //----------------------------------------------------------------------------
  615. inline const WCHAR *CGlobalFileStream::GetMappingName(void) const
  616. {
  617. if(0 != _awcMapName[0])
  618. return (WCHAR *) _awcMapName;
  619. else
  620. return NULL;
  621. }
  622. inline void CGlobalFileStream::SetMappingName(WCHAR const *pwcMapName)
  623. {
  624. if(NULL != pwcMapName)
  625. StringCbCopy (_awcMapName, sizeof(_awcMapName), pwcMapName);
  626. else
  627. _awcMapName[0] = 0;
  628. }
  629. //+---------------------------------------------------------------------------
  630. //
  631. // Member: CGlobalFileStream::GetMappedFileSize, private
  632. // CGlobalFileStream::SetMappedFileSize, private
  633. //
  634. // Synopsis: Returns/Sets the size of a file that is mapped. We need
  635. // this because SetEndOfFile cannot be called when a mapping
  636. // exists. We need to track the "logical" EOF and set it when
  637. // we flush and close the mapping.
  638. //
  639. // History: 01-Nov-96 BChapman Created
  640. //
  641. //----------------------------------------------------------------------------
  642. inline ULONG CGlobalFileStream::GetMappedFileSize(void) const
  643. {
  644. return _cbMappedFileSize;
  645. }
  646. inline void CGlobalFileStream::SetMappedFileSize(ULONG cbFileSize)
  647. {
  648. _cbMappedFileSize = cbFileSize;
  649. filestDebug((DEB_MAP,"GblFilest: StoreFileSize 0x%06x of '%ws'\n",
  650. cbFileSize, _awcPath));
  651. }
  652. //+---------------------------------------------------------------------------
  653. //
  654. // Member: CGlobalFileStream::GetMappedCommitSize, private
  655. // CGlobalFileStream::SetMappedCommitSize, private
  656. //
  657. // Synopsis: Returns/Sets the commed size of a file mapping. We use
  658. // this to decide if we should call VirtualAlloc().
  659. //
  660. // History: 01-Nov-96 BChapman Created
  661. //
  662. //----------------------------------------------------------------------------
  663. inline ULONG CGlobalFileStream::GetMappedCommitSize(void) const
  664. {
  665. return _cbMappedCommitSize;
  666. }
  667. inline void CGlobalFileStream::SetMappedCommitSize(ULONG cbCommitSize)
  668. {
  669. _cbMappedCommitSize = cbCommitSize;
  670. filestDebug((DEB_MAP,"GblFilest: StoreCommitSize 0x%06x of '%ws'\n",
  671. cbCommitSize, _awcPath));
  672. }
  673. //+---------------------------------------------------------------------------
  674. //
  675. // Member:
  676. // CGlobalFileStream::SetMapState, private
  677. // CGlobalFileStream::ResetMapState, private
  678. // CGlobalFileStream::TestMapState, private
  679. //
  680. // History: 01-Nov-96 BChapman Created
  681. //
  682. //----------------------------------------------------------------------------
  683. inline void CGlobalFileStream::SetMapState(DWORD flag)
  684. {
  685. _dwMapFlags |= flag;
  686. }
  687. inline void CGlobalFileStream::ResetMapState(DWORD flag)
  688. {
  689. _dwMapFlags &= ~flag;
  690. }
  691. inline BOOL CGlobalFileStream::TestMapState(DWORD flag) const
  692. {
  693. return(flag & _dwMapFlags);
  694. }
  695. #endif // USE_FILEMAPPING
  696. #ifdef ASYNC
  697. inline DWORD CGlobalFileStream::GetTerminationStatus(void) const
  698. {
  699. return _dwTerminate;
  700. }
  701. #ifdef LARGE_DOCFILE
  702. inline ULONGLONG CGlobalFileStream::GetHighWaterMark(void) const
  703. #else
  704. inline ULONG CGlobalFileStream::GetHighWaterMark(void) const
  705. #endif
  706. {
  707. return _ulHighWater;
  708. }
  709. #ifdef LARGE_DOCFILE
  710. inline ULONGLONG CGlobalFileStream::GetFailurePoint(void) const
  711. #else
  712. inline ULONG CGlobalFileStream::GetFailurePoint(void) const
  713. #endif
  714. {
  715. return _ulFailurePoint;
  716. }
  717. inline void CGlobalFileStream::SetTerminationStatus(DWORD dwTerminate)
  718. {
  719. fsAssert((dwTerminate == UNTERMINATED) ||
  720. (dwTerminate == TERMINATED_NORMAL) ||
  721. (dwTerminate == TERMINATED_ABNORMAL));
  722. _dwTerminate = dwTerminate;
  723. }
  724. #ifdef LARGE_DOCFILE
  725. inline void CGlobalFileStream::SetHighWaterMark(ULONGLONG ulHighWater)
  726. #else
  727. inline void CGlobalFileStream::SetHighWaterMark(ULONG ulHighWater)
  728. #endif
  729. {
  730. fsAssert(ulHighWater >= _ulHighWater);
  731. _ulHighWater = ulHighWater;
  732. }
  733. #ifdef LARGE_DOCFILE
  734. inline void CGlobalFileStream::SetFailurePoint(ULONGLONG ulFailure)
  735. #else
  736. inline void CGlobalFileStream::SetFailurePoint(ULONG ulFailure)
  737. #endif
  738. {
  739. _ulFailurePoint = ulFailure;
  740. }
  741. #endif //ASYNC
  742. //+--------------------------------------------------------------
  743. //
  744. // Member: CGlobalFileStream::GetMalloc, public
  745. //
  746. // Synopsis: Returns the allocator associated with this global file
  747. //
  748. // History: 05-May-93 AlexT Created
  749. //
  750. //---------------------------------------------------------------
  751. inline IMalloc *CGlobalFileStream::GetMalloc(VOID) const
  752. {
  753. return(_pMalloc);
  754. }
  755. #define CFILESTREAM_SIG LONGSIG('F', 'L', 'S', 'T')
  756. #define CFILESTREAM_SIGDEL LONGSIG('F', 'l', 'S', 't')
  757. //+--------------------------------------------------------------
  758. //
  759. // Member: CGlobalFileStream::GetFirstContext, public
  760. //
  761. // Synopsis: Returns the head of the context list
  762. //
  763. // History: 16-apr-97 BChapman created
  764. //
  765. //---------------------------------------------------------------
  766. inline CFileStream *CGlobalFileStream::GetFirstContext(VOID) const
  767. {
  768. return(GetHead());
  769. }
  770. //+--------------------------------------------------------------
  771. //
  772. // Member: CGlobalFileStream::SetCachedFilePointer, public
  773. // CGlobalFileStream::FilePointerEqual, public
  774. //
  775. // Synopsis: Maintain the cached file pointer. To Reduce the number
  776. // of calls to SetFilePointer.
  777. //
  778. // History: 16-apr-97 BChapman created
  779. //
  780. //---------------------------------------------------------------
  781. #ifdef LARGE_DOCFILE
  782. inline void CGlobalFileStream::SetCachedFilePointer(ULONGLONG ulPos)
  783. {
  784. _ulPos = ulPos;
  785. }
  786. inline BOOL CGlobalFileStream::FilePointerEqual(ULONGLONG ulPos)
  787. {
  788. return(ulPos == _ulPos);
  789. }
  790. #else
  791. inline void CGlobalFileStream::SetCachedFilePointer(DWORD ulLowPos)
  792. {
  793. _ulLowPos = ulLowPos;
  794. }
  795. inline BOOL CGlobalFileStream::FilePointerEqual(DWORD ulLow)
  796. {
  797. return(ulLow == _ulLowPos);
  798. }
  799. #endif
  800. //+--------------------------------------------------------------
  801. //
  802. // Member: CGlobalFileStream::SetSectorSize
  803. // CGlobalFileStream::GetSectorSize, public
  804. //
  805. // Synopsis: gets and sets the physical sector size for the file's volume
  806. //
  807. // History: 04-Dec-98 HenryLee created
  808. //
  809. //---------------------------------------------------------------
  810. ULONG CGlobalFileStream::GetSectorSize ()
  811. {
  812. return _cbSector;
  813. }
  814. void CGlobalFileStream::SetSectorSize (ULONG cbSector)
  815. {
  816. _cbSector = cbSector;
  817. }
  818. //+--------------------------------------------------------------
  819. //
  820. // Member: CFileStream::SetCachedFilePointer, public
  821. // CFileStream::FilePointerEqual, public
  822. //
  823. // Synopsis: Maintain the cached file pointer. To Reduce the number
  824. // of calls to SetFilePointer.
  825. //
  826. // History: 16-apr-97 BChapman created
  827. //
  828. //---------------------------------------------------------------
  829. #ifdef LARGE_DOCFILE
  830. inline void CFileStream::SetCachedFilePointer(ULONGLONG ulPos)
  831. #else
  832. inline void CFileStream::SetCachedFilePointer(DWORD ulLowPos)
  833. #endif
  834. {
  835. if(_pgfst == NULL)
  836. {
  837. filestDebug((DEB_SEEK, "File=%2x SetCachedFilePointer has no global "
  838. "file stream.", _hFile));
  839. return;
  840. }
  841. #ifdef LARGE_DOCFILE
  842. _pgfst->SetCachedFilePointer(ulPos);
  843. #else
  844. _pgfst->SetCachedFilePointer(ulLowPos);
  845. #endif
  846. CheckSeekPointer();
  847. }
  848. #ifdef LARGE_DOCFILE
  849. inline BOOL CFileStream::FilePointerEqual(ULONGLONG ulPos)
  850. #else
  851. inline BOOL CFileStream::FilePointerEqual(DWORD ulLow)
  852. #endif
  853. {
  854. if(_pgfst == NULL)
  855. {
  856. filestDebug((DEB_SEEK, "File=%2x FilePointerEqual has no global "
  857. "file stream.", _hFile));
  858. // Always Seek
  859. return FALSE;
  860. }
  861. CheckSeekPointer();
  862. #ifdef LARGE_DOCFILE
  863. return _pgfst->FilePointerEqual(ulPos);
  864. #else
  865. return _pgfst->FilePointerEqual(ulLow);
  866. #endif
  867. }
  868. //+--------------------------------------------------------------
  869. //
  870. // Member: CFileStream::Validate, public
  871. //
  872. // Synopsis: Validates the class signature
  873. //
  874. // Returns: Returns STG_E_INVALIDHANDLE for failure
  875. //
  876. // History: 20-Jan-92 DrewB Created
  877. //
  878. //---------------------------------------------------------------
  879. inline SCODE CFileStream::Validate(void) const
  880. {
  881. return (this == NULL || _sig != CFILESTREAM_SIG) ?
  882. STG_E_INVALIDHANDLE : S_OK;
  883. }
  884. //+--------------------------------------------------------------
  885. //
  886. // Member: CFileStream::AddRef, public
  887. //
  888. // Synopsis: Changes the ref count
  889. //
  890. // History: 26-Feb-92 DrewB Created
  891. //
  892. //---------------------------------------------------------------
  893. inline void CFileStream::vAddRef(void)
  894. {
  895. InterlockedIncrement(&_cReferences);
  896. }
  897. //+--------------------------------------------------------------
  898. //
  899. // Member: CFileStream::GetContext, public
  900. //
  901. // Synopsis: Returns the task ID.
  902. //
  903. // History: 24-Sep-92 PhilipLa Created
  904. //
  905. //---------------------------------------------------------------
  906. inline ContextId CFileStream::GetContext(void) const
  907. {
  908. return ctxid;
  909. }
  910. //+---------------------------------------------------------------------------
  911. //
  912. // Member: CFileStream::GetNext, public
  913. //
  914. // Synopsis: Returns the next filestream in the context list
  915. //
  916. // History: 27-Oct-92 DrewB Created
  917. //
  918. //----------------------------------------------------------------------------
  919. inline CFileStream *CFileStream::GetNext(void) const
  920. {
  921. return (CFileStream *) (CContext *) pctxNext;
  922. }
  923. //+--------------------------------------------------------------
  924. //
  925. // Member: CFileStream::SetStartFlags, public
  926. //
  927. // Synopsis: Sets the start flags
  928. //
  929. // History: 31-Aug-92 DrewB Created
  930. //
  931. //---------------------------------------------------------------
  932. inline void CFileStream::SetStartFlags(DWORD dwStartFlags)
  933. {
  934. _pgfst->SetStartFlags(dwStartFlags);
  935. }
  936. //+---------------------------------------------------------------------------
  937. //
  938. // Member: CFileStream::Init*, public
  939. //
  940. // Synopsis: Wrapper functions - call through to InitWorker
  941. //
  942. // History: 15-Jan-97 BChapman Created
  943. //
  944. //----------------------------------------------------------------------------
  945. inline SCODE CFileStream::InitFile(WCHAR const *pwcsPath)
  946. {
  947. fsAssert(!(GetStartFlags() & RSF_TEMPFILE));
  948. return InitWorker(pwcsPath, FSINIT_NORMAL);
  949. }
  950. inline SCODE CFileStream::InitScratch()
  951. {
  952. fsAssert(GetStartFlags() & RSF_SCRATCH);
  953. fsAssert(GetStartFlags() & RSF_DELETEONRELEASE);
  954. return InitWorker(NULL, FSINIT_NORMAL);
  955. }
  956. inline SCODE CFileStream::InitSnapShot()
  957. {
  958. fsAssert(GetStartFlags() & RSF_SNAPSHOT);
  959. fsAssert(GetStartFlags() & RSF_DELETEONRELEASE);
  960. return InitWorker(NULL, FSINIT_NORMAL);
  961. }
  962. inline SCODE CFileStream::InitUnmarshal()
  963. {
  964. return InitWorker(NULL, FSINIT_UNMARSHAL);
  965. }
  966. inline DWORD CFileStream::GetStartFlags(void) const
  967. {
  968. return _pgfst->GetStartFlags();
  969. }
  970. inline DFLAGS CFileStream::GetFlags(void) const
  971. {
  972. return _pgfst->GetDFlags();
  973. }
  974. inline IMalloc * CFileStream::GetMalloc(void) const
  975. {
  976. return _pgfst->GetMalloc();
  977. }
  978. #ifdef USE_FILEMAPPING
  979. //+---------------------------------------------------------------------------
  980. //
  981. // Member: CFileStream::IsFileMapped, private
  982. //
  983. // Synopsis: Check if the file memory mapped. This also shuts down an
  984. // an existing map if the global object tells it to.
  985. //
  986. // History: 01-Nov-96 BChapman Created
  987. //
  988. //----------------------------------------------------------------------------
  989. inline BOOL CFileStream::IsFileMapped()
  990. {
  991. //
  992. // If we don't have a map pointer then it is not mapped.
  993. //
  994. if (NULL == _pbBaseAddr)
  995. return FALSE;
  996. //
  997. // If we were mapped but the global state says STOP then someone
  998. // else has closed the file mapping and we should do the same.
  999. //
  1000. if( ! _pgfst->TestMapState(FSTSTATE_MAPPED))
  1001. {
  1002. TurnOffMapping(TRUE);
  1003. return FALSE;
  1004. }
  1005. return TRUE;
  1006. }
  1007. //+---------------------------------------------------------------------------
  1008. //
  1009. // Member: CFileStream::TurnOffAllMappings, private
  1010. //
  1011. // Synopsis: Turn off our file mapping. Then tell the global object that
  1012. // we want everyone else to give up their mappings. They will
  1013. // notice this in IsFileMapped and shut down then.
  1014. //
  1015. // History: 01-Nov-96 BChapman Created
  1016. //
  1017. //----------------------------------------------------------------------------
  1018. inline void CFileStream::TurnOffAllMappings()
  1019. {
  1020. TurnOffMapping(FALSE);
  1021. _pgfst->ResetMapState(FSTSTATE_MAPPED);
  1022. }
  1023. //+---------------------------------------------------------------------------
  1024. //
  1025. // Member: CFileStream::CheckMapView, private
  1026. //
  1027. // Synopsis: This inline routine prevents us from making a 'real'
  1028. // function call every time we might use the memory mapped
  1029. // file.
  1030. //
  1031. // History: 20-Feb-1997 BChapman Created
  1032. //
  1033. //----------------------------------------------------------------------------
  1034. inline SCODE CFileStream::CheckMapView(ULONG cbRequested)
  1035. {
  1036. if(cbRequested > _cbViewSize)
  1037. return ExtendMapView(cbRequested);
  1038. return S_OK;
  1039. }
  1040. //+---------------------------------------------------------------------------
  1041. //
  1042. // Member: CFileStream::MakeFileMapAddressValid, private
  1043. //
  1044. // Synopsis: This inline routine prevents us from making a 'real'
  1045. // function call every time we might use the memory mapped
  1046. // file.
  1047. //
  1048. // History: 01-Nov-96 BChapman Created
  1049. //
  1050. //----------------------------------------------------------------------------
  1051. inline SCODE CFileStream::MakeFileMapAddressValid(ULONG cbRequested)
  1052. {
  1053. if (IsFileMapped())
  1054. {
  1055. ULONG cbCommitSize = _pgfst->GetMappedCommitSize();
  1056. if(cbRequested > cbCommitSize)
  1057. return MakeFileMapAddressValidWorker(cbRequested, cbCommitSize);
  1058. else
  1059. return CheckMapView(cbRequested);
  1060. }
  1061. return STG_E_INVALIDHANDLE;
  1062. }
  1063. #endif // USE_FILEMAPPING
  1064. #ifdef ASYNC
  1065. inline CPerContext * CFileStream::GetContextPointer(void) const
  1066. {
  1067. return _ppc;
  1068. }
  1069. inline void CFileStream::SetContext(CPerContext *ppc)
  1070. {
  1071. _ppc = ppc;
  1072. }
  1073. #endif //ASYNC
  1074. inline ULONG CFileStream::GetSectorSize ()
  1075. {
  1076. return _pgfst->GetSectorSize();
  1077. }
  1078. inline BOOL CFileStream::IsHandleValid ()
  1079. {
  1080. BOOL fValid = TRUE;
  1081. if (_hFile != INVALID_FH &&
  1082. GetFileType(_hFile) != FILE_TYPE_DISK)
  1083. {
  1084. fValid = FALSE;
  1085. ctxid = 0; // don't let anyone find this context again
  1086. }
  1087. return fValid;
  1088. }
  1089. #endif