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.

714 lines
21 KiB

  1. //+--------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1992.
  5. //
  6. // File: rpubdf.cxx
  7. //
  8. // Contents: CRootPubDocFile implementation
  9. //
  10. // History: 26-Aug-92 DrewB Created
  11. //
  12. //---------------------------------------------------------------
  13. #include <dfhead.cxx>
  14. #pragma hdrstop
  15. #include <header.hxx>
  16. #include <rpubdf.hxx>
  17. #include <lock.hxx>
  18. #include <filelkb.hxx>
  19. // Priority mode lock permissions
  20. #define PRIORITY_PERMS DF_READ
  21. //+--------------------------------------------------------------
  22. //
  23. // Member: CRootPubDocFile::CRootPubDocFile, public
  24. //
  25. // Synopsis: Ctor - Initializes empty object
  26. //
  27. // History: 30-Mar-92 DrewB Created
  28. // 05-Sep-5 MikeHill Init _timeModifyAtCommit.
  29. //
  30. //
  31. //---------------------------------------------------------------
  32. CRootPubDocFile::CRootPubDocFile(IMalloc * const pMalloc) :
  33. _pMalloc(pMalloc),
  34. CPubDocFile(NULL, NULL, 0, ROOT_LUID, NULL, NULL, 0, NULL)
  35. {
  36. olDebugOut((DEB_ITRACE, "In CRootPubDocFile::CRootPubDocFile()\n"));
  37. _ulPriLock = 0;
  38. // Default to an invalid value.
  39. _timeModifyAtCommit.dwLowDateTime = _timeModifyAtCommit.dwHighDateTime = (DWORD) -1L;
  40. _sig = CROOTPUBDOCFILE_SIG;
  41. olDebugOut((DEB_ITRACE, "Out CRootPubDocFile::CRootPubDocFile\n"));
  42. }
  43. //+--------------------------------------------------------------
  44. //
  45. // Member: CRootPubDocFile::InitInd, private
  46. //
  47. // Synopsis: Initializes independent root
  48. //
  49. // Arguments: [plstBase] - Base
  50. // [snbExclude] - Limited instantiation exclusions
  51. // [dwStartFlags] - Startup flags
  52. // [df] - Transactioning flags
  53. //
  54. // Returns: Appropriate status code
  55. //
  56. // History: 11-Jun-92 DrewB Created
  57. //
  58. //---------------------------------------------------------------
  59. SCODE CRootPubDocFile::InitInd(ILockBytes *plstBase,
  60. SNBW snbExclude,
  61. DWORD const dwStartFlags,
  62. DFLAGS const df)
  63. {
  64. CFileStream *pfstCopy;
  65. ILockBytes *plkbCopy;
  66. ULONG ulLock = 0;
  67. CDocFile *pdfFrom, *pdfTo;
  68. SCODE sc;
  69. CMStream *pms;
  70. olDebugOut((DEB_ITRACE, "In CRootPubDocFile::InitInd()\n"));
  71. if ((sc = DllGetCommitSig(plstBase, &_sigMSF)) == STG_E_INVALIDHEADER ||
  72. sc == STG_E_UNKNOWN)
  73. {
  74. _sigMSF = DF_INVALIDSIGNATURE;
  75. }
  76. else if (FAILED(sc))
  77. {
  78. olErr(EH_Err,sc);
  79. }
  80. olMem(pfstCopy = new (_pMalloc) CFileStream(_pMalloc));
  81. olChkTo(EH_pfstCopy, pfstCopy->InitGlobal(
  82. RSF_CREATE | RSF_DELETEONRELEASE | RSF_SNAPSHOT |
  83. (dwStartFlags & RSF_ENCRYPTED),
  84. DF_READWRITE));
  85. olChkTo(EH_pfstCopy, pfstCopy->InitSnapShot());
  86. if (!P_PRIORITY(df) && (_pdfb->GetOrigLockFlags() & LOCK_ONLYONCE))
  87. olChkTo(EH_pfstCopyInit, WaitForAccess(plstBase, DF_READ, &ulLock));
  88. if (snbExclude)
  89. {
  90. plkbCopy = pfstCopy;
  91. olChkTo(EH_GetAccess, DllMultiStreamFromStream(_pMalloc,
  92. &pms, &plstBase,
  93. dwStartFlags,
  94. df));
  95. olMemTo(EH_pmsFrom, pdfFrom = new (_pMalloc)
  96. CDocFile(pms, SIDROOT, ROOT_LUID, BP_TO_P(CDFBasis *, _pdfb)));
  97. pdfFrom->AddRef();
  98. olChkTo(EH_pdfFrom, DllMultiStreamFromStream(_pMalloc,
  99. &pms, &plkbCopy,
  100. RSF_CREATE,
  101. 0));
  102. olMemTo(EH_pmsTo, pdfTo = new (_pMalloc)
  103. CDocFile(pms, SIDROOT, ROOT_LUID, BP_TO_P(CDFBasis *, _pdfb)));
  104. pdfTo->AddRef();
  105. olChkTo(EH_pdfTo, pdfFrom->CopyTo(pdfTo, CDF_EXACT, snbExclude));
  106. olChkTo(EH_pdfTo, pms->Flush(0));
  107. pdfFrom->Release();
  108. pdfTo->Release();
  109. }
  110. else if ((dwStartFlags & RSF_TRUNCATE) == 0)
  111. {
  112. olChkTo(EH_GetAccess, CopyLStreamToLStream(plstBase, pfstCopy));
  113. }
  114. if (!P_PRIORITY(df) && ulLock != 0)
  115. ReleaseAccess(plstBase, DF_READ, ulLock);
  116. _pdfb->SetBase(pfstCopy);
  117. _pdfb->SetOriginal(plstBase);
  118. olDebugOut((DEB_ITRACE, "Out CRootPubDocFile::InitInd\n"));
  119. return S_OK;
  120. EH_pdfTo:
  121. pdfTo->Release();
  122. goto EH_pdfFrom;
  123. EH_pmsTo:
  124. DllReleaseMultiStream(pms);
  125. EH_pdfFrom:
  126. pdfFrom->Release();
  127. goto EH_GetAccess;
  128. EH_pmsFrom:
  129. DllReleaseMultiStream(pms);
  130. EH_GetAccess:
  131. if (!P_PRIORITY(df) && ulLock != 0)
  132. ReleaseAccess(plstBase, DF_READ, ulLock);
  133. EH_pfstCopyInit:
  134. EH_pfstCopy:
  135. olVerSucc(pfstCopy->Release());
  136. EH_Err:
  137. return sc;
  138. }
  139. //+--------------------------------------------------------------
  140. //
  141. // Member: CRootPubDocFile::InitNotInd, private
  142. //
  143. // Synopsis: Dependent root initialization
  144. //
  145. // Arguments: [plstBase] - Base
  146. // [snbExclude] - Limited instantiation exclusions
  147. // [dwStartFlags] - Startup flags
  148. //
  149. // Returns: Appropriate status code
  150. //
  151. // History: 11-Jun-92 DrewB Created
  152. //
  153. //---------------------------------------------------------------
  154. SCODE CRootPubDocFile::InitNotInd(ILockBytes *plstBase,
  155. SNBW snbExclude,
  156. DWORD const dwStartFlags,
  157. DFLAGS const df)
  158. {
  159. CDocFile *pdf;
  160. SCODE sc;
  161. CMStream *pms;
  162. olDebugOut((DEB_ITRACE, "In CRootPubDocFile::InitNotInd()\n"));
  163. if (snbExclude)
  164. {
  165. olChk(DllMultiStreamFromStream(_pMalloc,
  166. &pms, &plstBase, dwStartFlags,
  167. df));
  168. olMemTo(EH_pms, pdf = new(_pMalloc)
  169. CDocFile(pms, SIDROOT, ROOT_LUID, BP_TO_P(CDFBasis *, _pdfb)));
  170. pdf->AddRef();
  171. olChkTo(EH_pdf, PDocFile::ExcludeEntries(pdf, snbExclude));
  172. olChkTo(EH_pdf, pms->Flush(0));
  173. pdf->Release();
  174. }
  175. _pdfb->SetBase(plstBase);
  176. plstBase->AddRef();
  177. _pdfb->SetOriginal(plstBase);
  178. olDebugOut((DEB_ITRACE, "Out CRootPubDocFile::InitNotInd\n"));
  179. return S_OK;
  180. EH_pdf:
  181. //pdf->Release() will also release the multistream.
  182. pdf->Release();
  183. return sc;
  184. EH_pms:
  185. DllReleaseMultiStream(pms);
  186. EH_Err:
  187. return sc;
  188. }
  189. //+--------------------------------------------------------------
  190. //
  191. // Member: CRootPubDocFile::InitRoot, public
  192. //
  193. // Synopsis: Constructor
  194. //
  195. // Arguments: [plstBase] - Base LStream
  196. // [dwStartFlags] - How to start things
  197. // [df] - Transactioning flags
  198. // [snbExclude] - Parital instantiation list
  199. // [ppdfb] - Basis pointer return
  200. // [pulOpenLock] - Open lock index return
  201. //
  202. // Returns: Appropriate status code
  203. //
  204. // Modifies: [ppdfb]
  205. // [pulOpenLock]
  206. //
  207. // History: 09-Dec-91 DrewB Created
  208. // 09-Jun-92 PhilipLa Added conversion support
  209. // 05-Sep-95 MikeHill Initialize _timeModifyAtCommit.
  210. // Removed duplicate call to pdfWrapped->CopyTimesFrom
  211. //
  212. //---------------------------------------------------------------
  213. SCODE CRootPubDocFile::InitRoot(ILockBytes *plstBase,
  214. DWORD dwStartFlags,
  215. DFLAGS const df,
  216. SNBW snbExclude,
  217. CDFBasis **ppdfb,
  218. ULONG *pulOpenLock,
  219. CGlobalContext *pgc)
  220. {
  221. CWrappedDocFile *pdfWrapped;
  222. CDocFile *pdfBase;
  223. CFileStream *pfstScratch;
  224. CMStream *pmsScratch;
  225. SCODE sc, scConv = S_OK;
  226. STATSTG statstg;
  227. olDebugOut((DEB_ITRACE, "In CRootPubDocFile::InitRoot("
  228. "%p, %lX, %lX, %p, %p)\n",
  229. plstBase, dwStartFlags, df, snbExclude, ppdfb));
  230. // Exclusion only works with a plain open
  231. olAssert(snbExclude == NULL ||
  232. (dwStartFlags & (RSF_CREATEFLAGS | RSF_CONVERT)) == 0);
  233. // ILockBytes::Stat calls are very expensive; we avoid one here
  234. // if possible
  235. HRESULT hr;
  236. IFileLockBytes *pfl;
  237. if (SUCCEEDED(plstBase->QueryInterface(IID_IFileLockBytes,
  238. (void**) &pfl)))
  239. {
  240. // This is our private ILockBytes implementation.
  241. hr = pfl->GetLocksSupported(&statstg.grfLocksSupported);
  242. if (pfl->IsEncryptedFile())
  243. dwStartFlags |= RSF_ENCRYPTED;
  244. pfl->Release();
  245. }
  246. else
  247. hr = plstBase->Stat(&statstg, STATFLAG_NONAME);
  248. olHChk(hr);
  249. *pulOpenLock = 0;
  250. if (statstg.grfLocksSupported & LOCK_ONLYONCE)
  251. olChk(GetOpen(plstBase, df, TRUE, pulOpenLock));
  252. if (P_PRIORITY(df) && (statstg.grfLocksSupported & LOCK_ONLYONCE))
  253. olChkTo(EH_GetOpen, GetAccess(plstBase, PRIORITY_PERMS, &_ulPriLock));
  254. olMemTo(EH_GetPriority, *ppdfb = new (_pMalloc) CDFBasis(_pMalloc, df,
  255. statstg.grfLocksSupported, pgc));
  256. _pdfb = P_TO_BP(CBasedDFBasisPtr, *ppdfb);
  257. if (P_INDEPENDENT(df))
  258. olChkTo(EH_GetPriority, InitInd(plstBase, snbExclude, dwStartFlags,
  259. df));
  260. else
  261. olChkTo(EH_GetPriority,
  262. InitNotInd(plstBase, snbExclude, dwStartFlags, df));
  263. olMemTo(EH_SubInit, pfstScratch = new (_pMalloc) CFileStream(_pMalloc));
  264. olChkTo(EH_pfstScratchInit, pfstScratch->InitGlobal(
  265. RSF_CREATE | RSF_DELETEONRELEASE | RSF_SCRATCH |
  266. (dwStartFlags & RSF_ENCRYPTED),
  267. DF_READWRITE));
  268. _pdfb->SetDirty(pfstScratch);
  269. CMStream *pms;
  270. scConv = DllMultiStreamFromStream(_pMalloc,
  271. &pms, _pdfb->GetPBase(),
  272. dwStartFlags |
  273. ((!P_INDEPENDENT(df) &&
  274. P_TRANSACTED(df)) ? RSF_DELAY : 0),
  275. df);
  276. _pmsBase = P_TO_BP(CBasedMStreamPtr, pms);
  277. if (scConv == STG_E_INVALIDHEADER)
  278. scConv = STG_E_FILEALREADYEXISTS;
  279. olChkTo(EH_pfstScratchInit, scConv);
  280. if (P_NOSNAPSHOT(df))
  281. {
  282. if ((sc = DllGetCommitSig(plstBase, &_sigMSF)) == STG_E_INVALIDHEADER ||
  283. sc == STG_E_UNKNOWN)
  284. {
  285. _sigMSF = DF_INVALIDSIGNATURE;
  286. }
  287. else if (FAILED(sc))
  288. {
  289. olErr(EH_pmsBase,sc);
  290. }
  291. }
  292. olMemTo(EH_pmsBase, pdfBase = new (_pMalloc)
  293. CDocFile(pms, SIDROOT, ROOT_LUID, BP_TO_P(CDFBasis *, _pdfb)));
  294. pdfBase->AddRef();
  295. if (P_TRANSACTED(df))
  296. {
  297. _cTransactedDepth = 1;
  298. CDfName dfnNull; // auto-initialized to 0
  299. WCHAR wcZero = 0;
  300. dfnNull.Set(2, (BYTE*)&wcZero);
  301. // 3/11/93 - Demand scratch when opening/creating transacted
  302. olChkTo(EH_pdfBaseInit, _pdfb->GetDirty()->InitScratch());
  303. olMemTo(EH_pdfBaseInit, pdfWrapped = new(_pMalloc)
  304. CWrappedDocFile(&dfnNull, pdfBase->GetLuid(), df,
  305. BP_TO_P(CDFBasis *, _pdfb), this));
  306. olChkTo(EH_pdfWrapped,
  307. pdfWrapped->Init(pdfBase));
  308. AddXSMember(NULL, pdfWrapped, pdfWrapped->GetLuid());
  309. _pdf = P_TO_BP(CBasedDocFilePtr, (PDocFile *)pdfWrapped);
  310. }
  311. else
  312. _pdf = P_TO_BP(CBasedDocFilePtr, (PDocFile *)pdfBase);
  313. // For no-scratch transacted files, also save the Docfile's current modify
  314. // time. This will be used on the Release (in vdtor).
  315. if( P_NOSCRATCH( df ))
  316. {
  317. if( FAILED( _pmsBase->GetTime( SIDROOT, WT_MODIFICATION, &_timeModifyAtCommit )))
  318. {
  319. // Do not return an error, but record an error flag so that
  320. // vdtor will not try to use it.
  321. _timeModifyAtCommit.dwLowDateTime = _timeModifyAtCommit.dwHighDateTime = (DWORD) -1;
  322. }
  323. }
  324. olChkTo(EH_pfstScratchInit,
  325. DllGetScratchMultiStream(&pmsScratch,
  326. (df & DF_NOSCRATCH),
  327. (ILockBytes **)_pdfb->GetPDirty(),
  328. pms));
  329. _pdfb->SetScratch(pmsScratch);
  330. if (df & DF_NOSCRATCH)
  331. {
  332. _pdfb->SetBaseMultiStream(pms);
  333. olChkTo(EH_pfstScratchInit, pmsScratch->InitScratch(pms, TRUE));
  334. _pmsBase->SetScratchMS(pmsScratch);
  335. }
  336. else
  337. {
  338. _pdfb->SetBaseMultiStream(NULL);
  339. }
  340. _df = df;
  341. // _pdfb->mxs is constructed automatically
  342. olDebugOut((DEB_ITRACE, "Out CRootPubDocFile::InitRoot\n"));
  343. return scConv;
  344. EH_pdfWrapped:
  345. delete pdfWrapped;
  346. EH_pdfBaseInit:
  347. pdfBase->Release();
  348. goto EH_pfstScratchInit;
  349. EH_pmsBase:
  350. DllReleaseMultiStream(BP_TO_P(CMStream *, _pmsBase));
  351. EH_pfstScratchInit:
  352. olVerSucc(pfstScratch->Release());
  353. _pdfb->SetDirty(NULL);
  354. EH_SubInit:
  355. olVerSucc(_pdfb->GetBase()->Release());
  356. _pdfb->SetBase(NULL);
  357. EH_GetPriority:
  358. if (_ulPriLock > 0)
  359. {
  360. olAssert(P_PRIORITY(df) &&
  361. (statstg.grfLocksSupported & LOCK_ONLYONCE));
  362. ReleaseAccess(plstBase, PRIORITY_PERMS, _ulPriLock);
  363. _ulPriLock = 0;
  364. }
  365. EH_GetOpen:
  366. if (*pulOpenLock != 0)
  367. {
  368. olAssert(statstg.grfLocksSupported & LOCK_ONLYONCE);
  369. ReleaseOpen(plstBase, df, *pulOpenLock);
  370. *pulOpenLock = 0;
  371. }
  372. EH_Err:
  373. return sc;
  374. }
  375. //+--------------------------------------------------------------
  376. //
  377. // Member: CRootPubDocFile::~CRootPubDocFile, public
  378. //
  379. // Synopsis: dtor
  380. //
  381. // History: 09-Dec-91 DrewB Created
  382. // 05-Sep-95 MikeHill Revert time using _timeModifyAtCommit.
  383. //
  384. //---------------------------------------------------------------
  385. void CRootPubDocFile::vdtor(void)
  386. {
  387. olDebugOut((DEB_ITRACE, "In CRootPubDocFile::~CRootPubDocFile\n"));
  388. olAssert(_cReferences == 0);
  389. // If this is a no-scratch transacted file, revert the Modify timestamp
  390. // on the Docfile to that of the last commit.
  391. if( P_NOSCRATCH( _df )
  392. &&
  393. ( _timeModifyAtCommit.dwLowDateTime != -1L ) // Don't use an invalid timestamp.
  394. )
  395. {
  396. // We call SetFileLockBytesTime, rather than SetTime, so that
  397. // the underlying Docfile's timestamp is changed, but the Storage's
  398. // timestamp in the Directory is unchanged. If we changed the
  399. // Directory, we would have to flush the Multi-Stream.
  400. // An error here is ignored.
  401. _pmsBase->SetFileLockBytesTime( WT_MODIFICATION, _timeModifyAtCommit );
  402. }
  403. // We can't rely on CPubDocFile::~CPubDocFile to do this since
  404. // we're using a virtual destructor
  405. _sig = CROOTPUBDOCFILE_SIGDEL;
  406. if (SUCCEEDED(CheckReverted()))
  407. {
  408. ChangeXs(DF_NOLUID, XSO_RELEASE);
  409. _cilChildren.DeleteByName(NULL);
  410. if (_ulPriLock > 0)
  411. {
  412. // Priority instantiation can't be independent
  413. olAssert(!P_INDEPENDENT(_df));
  414. ReleaseAccess(_pdfb->GetBase(), PRIORITY_PERMS, _ulPriLock);
  415. }
  416. if (_pdf)
  417. _pdf->Release();
  418. if (_pdfb)
  419. _pdfb->vRelease();
  420. }
  421. olDebugOut((DEB_ITRACE, "Out CRootPubDocFile::~CRootPubDocFile\n"));
  422. delete this;
  423. }
  424. //+---------------------------------------------------------------------------
  425. //
  426. // Member: CRootPubDocFile::ReleaseLocks, public
  427. //
  428. // Synopsis: Release any locks using the given ILockBytes
  429. //
  430. // Arguments: [plkb] -- ILockBytes to use for release
  431. //
  432. // Returns: void
  433. //
  434. // History: 24-Jan-95 PhilipLa Created
  435. //
  436. // Notes: This is a cleanup function used to resolve the many
  437. // conflicts we get trying to release locks using an
  438. // ILockBytes in a basis that's already been released.
  439. //
  440. //----------------------------------------------------------------------------
  441. void CRootPubDocFile::ReleaseLocks(ILockBytes *plkb)
  442. {
  443. olDebugOut((DEB_ITRACE, "In CRootPubDocFile::ReleaseLocks:%p()\n", this));
  444. if (_ulPriLock > 0)
  445. {
  446. // Priority instantiation can't be independent
  447. olAssert(!P_INDEPENDENT(_df));
  448. ReleaseAccess(plkb, PRIORITY_PERMS, _ulPriLock);
  449. _ulPriLock = 0;
  450. }
  451. olDebugOut((DEB_ITRACE, "Out CRootPubDocFile::ReleaseLocks\n"));
  452. }
  453. //+--------------------------------------------------------------
  454. //
  455. // Member: CRootPubDocFile::Stat, public
  456. //
  457. // Synopsis: Fills in a stat buffer from the base LStream
  458. //
  459. // Arguments: [pstatstg] - Stat buffer
  460. // [grfStatFlag] - Stat flags
  461. //
  462. // Returns: Appropriate status code
  463. //
  464. // Modifies: [pstatstg]
  465. //
  466. // History: 25-Mar-92 DrewB Created
  467. //
  468. //---------------------------------------------------------------
  469. SCODE CRootPubDocFile::Stat(STATSTGW *pstatstg, DWORD grfStatFlag)
  470. {
  471. SCODE sc;
  472. olDebugOut((DEB_ITRACE, "In CRootPubDocFile::Stat(%p, %lu)\n",
  473. pstatstg, grfStatFlag));
  474. olChk(CheckReverted());
  475. olHChk(_pdfb->GetOriginal()->Stat((STATSTG *)pstatstg, grfStatFlag));
  476. pstatstg->grfMode = DFlagsToMode(_df);
  477. olChkTo(EH_pwcsName, _pdf->GetClass(&pstatstg->clsid));
  478. olChkTo(EH_pwcsName, _pdf->GetStateBits(&pstatstg->grfStateBits));
  479. olDebugOut((DEB_ITRACE, "Out CRootPubDocFile::Stat\n"));
  480. return S_OK;
  481. EH_pwcsName:
  482. if (pstatstg->pwcsName)
  483. TaskMemFree(pstatstg->pwcsName);
  484. EH_Err:
  485. return sc;
  486. }
  487. //+---------------------------------------------------------------------------
  488. //
  489. // Member: CRootPubDocFile::SwitchToFile, public
  490. //
  491. // Synopsis: Switches the underlying file in the base ILockBytes
  492. //
  493. // Arguments: [ptcsFile] - Filename
  494. // [plkb] - The ILockBytes to operate on
  495. // [pulOpenLock] - On entry, the current open lock
  496. // On exit, the new open lock
  497. //
  498. // Returns: Appropriate status code
  499. //
  500. // Modifies: [pulOpenLock]
  501. //
  502. // History: 08-Jan-93 DrewB Created
  503. //
  504. //----------------------------------------------------------------------------
  505. SCODE CRootPubDocFile::SwitchToFile(OLECHAR const *ptcsFile,
  506. ILockBytes *plkb,
  507. ULONG *pulOpenLock)
  508. {
  509. IFileLockBytes *pfl;
  510. SCODE sc;
  511. BYTE *pbBuffer;
  512. ULONG cbBuffer;
  513. olDebugOut((DEB_ITRACE, "In CRootPubDocFile::SwitchToFile:%p("
  514. "%s, %p, %p)\n", this, ptcsFile, plkb, pulOpenLock));
  515. // If you're transacted, nothing can be dirty in the base
  516. // If you're not dirty, there's no point in flushing
  517. // This is also necessary to allow SwitchToFile with a read-only source
  518. if (!P_TRANSACTED(_df) && IsDirty())
  519. {
  520. // Make sure pending changes are flushed
  521. olChk(_pmsBase->Flush(0));
  522. // Make sure ILockBytes contents are on disk
  523. olHChk(plkb->Flush());
  524. }
  525. #ifdef LARGE_DOCFILE
  526. ULONGLONG ulCommitSize;
  527. #else
  528. ULONG ulCommitSize;
  529. #endif
  530. olChk(GetCommitSize(&ulCommitSize));
  531. // Check for FileLockBytes
  532. olHChkTo(EH_NotFile, plkb->QueryInterface(IID_IFileLockBytes,
  533. (void **)&pfl));
  534. // Release old locks
  535. if (*pulOpenLock)
  536. ReleaseOpen(plkb, _df, *pulOpenLock);
  537. // Ask ILockBytes to switch
  538. GetSafeBuffer(CB_SMALLBUFFER, CB_LARGEBUFFER, &pbBuffer, &cbBuffer);
  539. olAssert(pbBuffer != NULL);
  540. sc = DfGetScode(pfl->SwitchToFile(
  541. ptcsFile,
  542. ulCommitSize,
  543. cbBuffer,
  544. pbBuffer));
  545. pfl->Release();
  546. FreeBuffer(pbBuffer);
  547. //Record the fact that we have enough space for overwrite commit.
  548. _wFlags = _wFlags | PF_PREPARED;
  549. // Attempt to get new locks
  550. // If SwitchToFile failed, the ILockBytes is the same so this will
  551. // restore our open locks released above
  552. // If SwitchToFile succeeded, the ILockBytes is working on the new file
  553. // so this will get locks for that
  554. if (*pulOpenLock)
  555. {
  556. ULONG ulLock;
  557. // Don't propagate failures here since there's nothing
  558. // that can be done
  559. if (SUCCEEDED(GetOpen(plkb, _df, FALSE, &ulLock)))
  560. *pulOpenLock = ulLock;
  561. }
  562. olDebugOut((DEB_ITRACE, "Out CRootPubDocFile::SwitchToFile\n"));
  563. EH_Err:
  564. return sc;
  565. EH_NotFile:
  566. return(STG_E_NOTFILEBASEDSTORAGE);
  567. }
  568. //+--------------------------------------------------------------
  569. //
  570. // Member: CRootPubDocFile::Commit, public
  571. //
  572. // Synopsis: Commits transacted changes
  573. //
  574. // Arguments: [dwFlags] - DFC_*
  575. //
  576. // Returns: Appropriate status code
  577. //
  578. // History: 29-Aug-95 MikeHill Created
  579. // 26-Apr-99 RogerCh Changed to use GetSystemTimeAsFileTime
  580. //
  581. //---------------------------------------------------------------
  582. void CRootPubDocFile::CommitTimestamps(DWORD const dwFlags)
  583. {
  584. // For no-scratch transacted files, also save the Docfile's modify
  585. // time. This will be used to restore the file's current time on a Release.
  586. if( P_NOSCRATCH( _df ) && P_TRANSACTED( _df ))
  587. {
  588. GetSystemTimeAsFileTime(&_timeModifyAtCommit);
  589. }
  590. }