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.

284 lines
7.7 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1994.
  5. //
  6. // File: asyncapi.cxx
  7. //
  8. // Contents: APIs for async docfiles
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 19-Dec-95 PhilipLa Created
  15. //
  16. //----------------------------------------------------------------------------
  17. #include "astghead.cxx"
  18. #pragma hdrstop
  19. #include "filllkb.hxx"
  20. #ifdef ASYNC
  21. #include <expdf.hxx>
  22. #endif
  23. #if DBG == 1
  24. DECLARE_INFOLEVEL(astg);
  25. #endif
  26. #ifdef COORD
  27. SCODE DfFromLB(CPerContext *ppc,
  28. ILockBytes *plst,
  29. DFLAGS df,
  30. DWORD dwStartFlags,
  31. SNBW snbExclude,
  32. ITransaction *pTransaction,
  33. CExposedDocFile **ppdfExp,
  34. CLSID *pcid);
  35. #else
  36. SCODE DfFromLB(CPerContext *ppc,
  37. ILockBytes *plst,
  38. DFLAGS df,
  39. DWORD dwStartFlags,
  40. SNBW snbExclude,
  41. CExposedDocFile **ppdfExp,
  42. CLSID *pcid);
  43. #endif //COORD
  44. #ifndef KACF_OLE32ENABLEASYNCDOCFILE
  45. #define KACF_OLE32ENABLEASYNCDOCFILE 0x00000200
  46. #endif
  47. BOOL AllowAsyncDocfile()
  48. {
  49. // By default, StgOpenAsyncDocfileOnIFillLockBytes,
  50. // StgGetIFillLockBytesOnILockBytes,
  51. // StgGetIFillLockBytesOnFile are disabled
  52. return (BOOL)APPCOMPATFLAG(KACF_OLE32ENABLEASYNCDOCFILE);
  53. }
  54. STDAPI StgOpenAsyncDocfileOnIFillLockBytes(IFillLockBytes *pflb,
  55. DWORD grfMode,
  56. DWORD asyncFlags,
  57. IStorage **ppstgOpen)
  58. {
  59. if (!AllowAsyncDocfile())
  60. return STG_E_UNIMPLEMENTEDFUNCTION;
  61. SCODE sc;
  62. ILockBytes *pilb;
  63. IStorage *pstg;
  64. IFileLockBytes *pfl;
  65. sc = ValidateInterface(pflb, IID_IFillLockBytes);
  66. if (FAILED(sc))
  67. {
  68. return sc;
  69. }
  70. sc = ValidateOutPtrBuffer(ppstgOpen);
  71. if (FAILED(sc))
  72. {
  73. return sc;
  74. }
  75. *ppstgOpen = NULL;
  76. //We're going to do a song and dance here because the ILockBytes
  77. //implementation we return from StgGetIFillLockBytesOnFile won't
  78. //let you QI for ILockBytes (because those methods aren't thread safe,
  79. //among other things). Instead we QI for a private interface and do
  80. //a direct cast if that succeeds. Otherwise we're on someone else's
  81. //implementation so we just go right for ILockBytes.
  82. sc = pflb->QueryInterface(IID_IFileLockBytes, (void **)&pfl);
  83. if (FAILED(sc))
  84. {
  85. sc = pflb->QueryInterface(IID_ILockBytes, (void **)&pilb);
  86. if (FAILED(sc))
  87. {
  88. return sc;
  89. }
  90. }
  91. else
  92. {
  93. pilb = (ILockBytes *)((CFileStream *)pfl);
  94. }
  95. //If we're operating on the docfile owned ILockBytes, then we can
  96. // go directly to DfFromLB instead of using StgOpenStorageOnILockBytes
  97. // which will avoid creating another shared heap.
  98. if (pfl != NULL)
  99. {
  100. pfl->Release();
  101. pilb = NULL;
  102. CFileStream *pfst = (CFileStream *)pflb;
  103. CPerContext *ppc = pfst->GetContextPointer();
  104. #ifdef MULTIHEAP
  105. CSafeMultiHeap smh(ppc);
  106. #endif
  107. #ifdef COORD
  108. astgChk(DfFromLB(ppc,
  109. pfst,
  110. ModeToDFlags(grfMode),
  111. pfst->GetStartFlags(),
  112. NULL,
  113. NULL,
  114. (CExposedDocFile **)&pstg,
  115. NULL));
  116. #else
  117. astgChk(DfFromLB(ppc,
  118. pfst,
  119. ModeToDFlags(grfMode),
  120. pfst->GetStartFlags(),
  121. NULL,
  122. (CExposedDocFile **)&pstg,
  123. NULL));
  124. #endif
  125. //Note: Don't release the ILB reference we got from the QI
  126. // above, since DfFromLB recorded that pointer but didn't
  127. // AddRef it.
  128. pfst->AddRef(); // CExposedDocfile will release this reference
  129. }
  130. else
  131. {
  132. IFillLockBytes *pflb2;
  133. if (SUCCEEDED(pilb->QueryInterface(IID_IDefaultFillLockBytes,
  134. (void **)&pflb2)))
  135. {
  136. CFillLockBytes *pflbDefault = (CFillLockBytes *)pflb;
  137. CPerContext *ppc;
  138. pflb2->Release();
  139. astgChk(StgOpenStorageOnILockBytes(pilb,
  140. NULL,
  141. grfMode,
  142. NULL,
  143. 0,
  144. &pstg));
  145. //Get PerContext pointer from pstg
  146. ppc = ((CExposedDocFile *)pstg)->GetContext();
  147. pflbDefault->SetContext(ppc);
  148. }
  149. else
  150. {
  151. astgChk(StgOpenStorageOnILockBytes(pilb,
  152. NULL,
  153. grfMode,
  154. NULL,
  155. 0,
  156. &pstg));
  157. }
  158. pilb->Release();
  159. pilb = NULL;
  160. }
  161. astgChkTo(EH_stg, ((CExposedDocFile *)pstg)->InitConnection(NULL));
  162. ((CExposedDocFile *)pstg)->SetAsyncFlags(asyncFlags);
  163. *ppstgOpen = pstg;
  164. return NOERROR;
  165. EH_stg:
  166. pstg->Release();
  167. Err:
  168. if (pilb != NULL)
  169. pilb->Release();
  170. if (sc == STG_E_PENDINGCONTROL)
  171. {
  172. sc = E_PENDING;
  173. }
  174. return ResultFromScode(sc);
  175. }
  176. STDAPI StgGetIFillLockBytesOnILockBytes( ILockBytes *pilb,
  177. IFillLockBytes **ppflb)
  178. {
  179. if (!AllowAsyncDocfile())
  180. return STG_E_UNIMPLEMENTEDFUNCTION;
  181. SCODE sc = S_OK;
  182. CFillLockBytes *pflb = NULL;
  183. sc = ValidateOutPtrBuffer(ppflb);
  184. if (FAILED(sc))
  185. {
  186. return sc;
  187. }
  188. sc = ValidateInterface(pilb, IID_ILockBytes);
  189. if (FAILED(sc))
  190. {
  191. return sc;
  192. }
  193. pflb = new CFillLockBytes(pilb);
  194. if (pflb == NULL)
  195. {
  196. return STG_E_INSUFFICIENTMEMORY;
  197. }
  198. sc = pflb->Init();
  199. if (FAILED(sc))
  200. {
  201. pflb->Release();
  202. *ppflb = NULL;
  203. return sc;
  204. }
  205. *ppflb = pflb;
  206. return NOERROR;
  207. }
  208. STDAPI StgGetIFillLockBytesOnFile(OLECHAR const *pwcsName,
  209. IFillLockBytes **ppflb)
  210. {
  211. if (!AllowAsyncDocfile())
  212. return STG_E_UNIMPLEMENTEDFUNCTION;
  213. SCODE sc;
  214. IMalloc *pMalloc;
  215. CFileStream *plst;
  216. CFillLockBytes *pflb;
  217. CPerContext *ppc;
  218. astgChk(ValidateNameW(pwcsName, _MAX_PATH));
  219. astgChk(ValidateOutPtrBuffer(ppflb));
  220. DfInitSharedMemBase();
  221. astgHChk(DfCreateSharedAllocator(&pMalloc, FALSE));
  222. astgMemTo(EH_Malloc, plst = new (pMalloc) CFileStream(pMalloc));
  223. astgChkTo(EH_plst, plst->InitGlobal(RSF_CREATE,
  224. DF_DIRECT | DF_READ |
  225. DF_WRITE | DF_DENYALL));
  226. astgChkTo(EH_plst, plst->InitFile(pwcsName));
  227. astgMemTo(EH_plstInit, ppc = new (pMalloc) CPerContext(pMalloc));
  228. astgChkTo(EH_ppc, ppc->InitNewContext());
  229. //We want 0 normal references on the per context, and one reference
  230. // to the shared memory.
  231. ppc->DecRef();
  232. plst->SetContext(ppc);
  233. plst->StartAsyncMode();
  234. astgChkTo(EH_plstInit, ppc->InitNotificationEvent(plst));
  235. *ppflb = (IFillLockBytes *)plst;
  236. return S_OK;
  237. EH_ppc:
  238. delete ppc;
  239. EH_plstInit:
  240. plst->Delete();
  241. EH_plst:
  242. plst->Release();
  243. EH_Malloc:
  244. pMalloc->Release();
  245. Err:
  246. return sc;
  247. }