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.

322 lines
9.7 KiB

  1. #include "privcpp.h"
  2. HRESULT CPackage::InitNew(IStorage *pstg)
  3. {
  4. HRESULT hr;
  5. LPSTREAM pstm;
  6. DebugMsg(DM_TRACE, "pack ps - InitNew() called.");
  7. if (_psState != PSSTATE_UNINIT)
  8. return E_UNEXPECTED;
  9. if (!pstg)
  10. return E_POINTER;
  11. // Create a stream to save the package and cache the pointer. By doing
  12. // this now we ensure being able to save in low memory conditions.
  13. //
  14. hr = pstg->CreateStream(SZCONTENTS,STGM_DIRECT | STGM_CREATE |
  15. STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0,
  16. &pstm);
  17. if (SUCCEEDED(hr))
  18. {
  19. hr = WriteFmtUserTypeStg(pstg, (CLIPFORMAT)_cf,SZUSERTYPE);
  20. if (SUCCEEDED(hr))
  21. {
  22. _fIsDirty = TRUE;
  23. _psState = PSSTATE_SCRIBBLE;
  24. DebugMsg(DM_TRACE, " leaving InitNew()");
  25. }
  26. pstm->Release();
  27. pstm = NULL;
  28. }
  29. return hr;
  30. }
  31. HRESULT CPackage::Load(IStorage *pstg)
  32. {
  33. HRESULT hr;
  34. LPSTREAM pstm = NULL; // package contents
  35. CLSID clsid;
  36. DebugMsg(DM_TRACE, "pack ps - Load() called.");
  37. if (_psState != PSSTATE_UNINIT)
  38. {
  39. DebugMsg(DM_TRACE," wrong state!!");
  40. return E_UNEXPECTED;
  41. }
  42. if (!pstg)
  43. {
  44. DebugMsg(DM_TRACE," bad pointer!!");
  45. return E_POINTER;
  46. }
  47. // check to make sure this is one of our storages
  48. hr = ReadClassStg(pstg, &clsid);
  49. if (SUCCEEDED(hr) &&
  50. (clsid != CLSID_CPackage && clsid != CLSID_OldPackage) || FAILED(hr))
  51. {
  52. DebugMsg(DM_TRACE," bad storage type!!");
  53. return E_UNEXPECTED;
  54. }
  55. hr = pstg->OpenStream(SZCONTENTS,0, STGM_DIRECT | STGM_READWRITE |
  56. STGM_SHARE_EXCLUSIVE, 0, &pstm);
  57. if (SUCCEEDED(hr))
  58. {
  59. hr = PackageReadFromStream(pstm);
  60. _psState = PSSTATE_SCRIBBLE;
  61. _fIsDirty = FALSE;
  62. _fLoaded = TRUE;
  63. pstm->Release();
  64. }
  65. else
  66. {
  67. DebugMsg(DM_TRACE," couldn't open contents stream!!");
  68. DebugMsg(DM_TRACE," hr==%Xh",hr);
  69. }
  70. return hr;
  71. }
  72. HRESULT CPackage::Save(IStorage *pstg, BOOL fSameAsLoad)
  73. {
  74. HRESULT hr;
  75. LPSTREAM pstm;
  76. DebugMsg(DM_TRACE, "pack ps - Save() called.");
  77. if(!_pEmbed || !(*_pEmbed->fd.cFileName))
  78. return S_OK;
  79. // must come here from scribble state
  80. if ((_psState != PSSTATE_SCRIBBLE) && fSameAsLoad)
  81. {
  82. DebugMsg(DM_TRACE," bad state!!");
  83. return E_UNEXPECTED;
  84. }
  85. // must have an IStorage if not SameAsLoad
  86. if (!pstg && !fSameAsLoad)
  87. {
  88. DebugMsg(DM_TRACE," bad pointer!!");
  89. return E_POINTER;
  90. }
  91. CreateTempFile(); // Make sure we have the temp file created
  92. // hopefully, the container calls WriteClassStg with our CLSID before
  93. // we get here, that way we can overwrite that and write out the old
  94. // packager's CLSID so that the old packager can read new packages.
  95. //
  96. if (FAILED(WriteClassStg(pstg, CLSID_OldPackage)))
  97. {
  98. DebugMsg(DM_TRACE,
  99. " couldn't write CLSID to storage!!");
  100. return E_FAIL;
  101. }
  102. //
  103. // ok, we have four possible ways we could be calling Save:
  104. // 1. we're creating a new package and saving to the same
  105. // storage we received in InitNew
  106. // 2. We're creating a new package and saving to a different
  107. // storage than we received in InitNew
  108. // 3. We were loaded by a container and we're saving to the
  109. // same stream we received in Load
  110. // 4. We were loaded by a container and we're saving to a
  111. // different stream than we received in Load
  112. //
  113. //////////////////////////////////////////////////////////////////
  114. //
  115. // Same Storage as Load
  116. //
  117. //////////////////////////////////////////////////////////////////
  118. if (fSameAsLoad)
  119. {
  120. DebugMsg(DM_TRACE," Same as load.");
  121. LARGE_INTEGER li = {0,0};
  122. // If we're not dirty, so there's nothing new to save.
  123. if (FALSE == _fIsDirty) {
  124. DebugMsg(DM_TRACE, " not saving cause we're not dirty!!");
  125. return S_OK;
  126. }
  127. hr = pstg->OpenStream(SZCONTENTS,0, STGM_DIRECT | STGM_READWRITE |
  128. STGM_SHARE_EXCLUSIVE, 0, &pstm);
  129. if (SUCCEEDED(hr))
  130. {
  131. // case 1: new package
  132. if (!_fLoaded)
  133. {
  134. switch(_panetype)
  135. {
  136. LPTSTR temp;
  137. case PEMBED:
  138. // if haven't created a temp file yet, then use the the
  139. // file to be packaged to get our file contents from,
  140. // otherwise we just use the temp file, because if we
  141. // have a temp file, it contains the most recent info.
  142. //
  143. temp = _pEmbed->pszTempName;
  144. if (!_pEmbed->pszTempName)
  145. {
  146. DebugMsg(DM_TRACE, " case 1a:not loaded, using initFile.");
  147. _pEmbed->pszTempName = _pEmbed->fd.cFileName;
  148. }
  149. else {
  150. DebugMsg(DM_TRACE, " case 1b:not loaded, using tempfile.");
  151. }
  152. hr = PackageWriteToStream(pstm);
  153. // reset our temp name back, since we might have changed it
  154. // basically, this just sets it to NULL if it was before
  155. _pEmbed->pszTempName = temp;
  156. break;
  157. case CMDLINK:
  158. // nothing screwy to do here...just write out the info
  159. // which we already have in memory.
  160. hr = PackageWriteToStream(pstm);
  161. break;
  162. }
  163. }
  164. // case 3: loaded package
  165. else {
  166. hr = PackageWriteToStream(pstm);
  167. }
  168. pstm->Release();
  169. if (FAILED(hr))
  170. return hr;
  171. }
  172. }
  173. //////////////////////////////////////////////////////////////////
  174. //
  175. // NEW Storage
  176. //
  177. //////////////////////////////////////////////////////////////////
  178. else
  179. {
  180. DebugMsg(DM_TRACE," NOT same as load.");
  181. hr = pstg->CreateStream(SZCONTENTS,STGM_DIRECT | STGM_CREATE |
  182. STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0,
  183. &pstm);
  184. if (FAILED(hr))
  185. {
  186. DebugMsg(DM_TRACE, " couldn't create contents stream!!");
  187. return hr;
  188. }
  189. WriteFmtUserTypeStg(pstg, (CLIPFORMAT)_cf,SZUSERTYPE);
  190. // case 2:
  191. if (!_fLoaded)
  192. {
  193. switch(_panetype)
  194. {
  195. LPTSTR temp;
  196. case PEMBED:
  197. temp = _pEmbed->pszTempName;
  198. if (!_pEmbed->pszTempName)
  199. {
  200. DebugMsg(DM_TRACE, " case 2a:not loaded, using initFile.");
  201. _pEmbed->pszTempName = _pEmbed->fd.cFileName;
  202. }
  203. else
  204. {
  205. DebugMsg(DM_TRACE, " case 2b:not loaded, using tempfile.");
  206. }
  207. hr = PackageWriteToStream(pstm);
  208. // reset our temp name back, since we might have changed it
  209. // basically, this just sets it to NULL if it was before
  210. _pEmbed->pszTempName = temp;
  211. break;
  212. case CMDLINK:
  213. // nothing interesting to do here, other than write out
  214. // the package.
  215. hr = PackageWriteToStream(pstm);
  216. break;
  217. }
  218. }
  219. // case 4:
  220. else
  221. {
  222. DebugMsg(DM_TRACE," case 4:loaded.");
  223. hr = PackageWriteToStream(pstm);
  224. }
  225. pstm->Release();
  226. }
  227. if (FAILED(hr))
  228. return hr;
  229. _psState = PSSTATE_ZOMBIE;
  230. DebugMsg(DM_TRACE, " leaving Save()");
  231. return S_OK;
  232. }
  233. HRESULT CPackage::SaveCompleted(IStorage *pstg)
  234. {
  235. DebugMsg(DM_TRACE, "pack ps - SaveCompleted() called.");
  236. // must be called from no-scribble or hands-off state
  237. if (!(_psState == PSSTATE_ZOMBIE || _psState == PSSTATE_HANDSOFF))
  238. return E_UNEXPECTED;
  239. // if we're hands-off, we'd better get a storage to re-init from
  240. if (!pstg && _psState == PSSTATE_HANDSOFF)
  241. return E_UNEXPECTED;
  242. _psState = PSSTATE_SCRIBBLE;
  243. _fIsDirty = FALSE;
  244. DebugMsg(DM_TRACE, " leaving SaveCompleted()");
  245. return S_OK;
  246. }
  247. HRESULT CPackage::HandsOffStorage(void)
  248. {
  249. DebugMsg(DM_TRACE, "pack ps - HandsOffStorage() called.");
  250. // must come from scribble or no-scribble. a repeated call to
  251. // HandsOffStorage is an unexpected error (bug in client).
  252. //
  253. if (_psState == PSSTATE_UNINIT || _psState == PSSTATE_HANDSOFF)
  254. return E_UNEXPECTED;
  255. _psState = PSSTATE_HANDSOFF;
  256. DebugMsg(DM_TRACE, " leaving HandsOffStorage()");
  257. return S_OK;
  258. }