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.

397 lines
10 KiB

  1. /*---------------------------------------------------------------------------
  2. | PERS.C
  3. | This file has the IPersistStorage and IPersistfile interface implementation.
  4. |
  5. | Created By: Vij Rajarajan (VijR)
  6. +---------------------------------------------------------------------------*/
  7. #define SERVERONLY
  8. #include <Windows.h>
  9. #include "mpole.h"
  10. #include "mplayer.h"
  11. #define STRSAFE_NO_DEPRECATE
  12. #include <strsafe.h>
  13. #define STGM_SALL (STGM_READWRITE | STGM_SHARE_EXCLUSIVE)
  14. /**************************************************************************
  15. *************** IPersistStorage INTERFACE IMPLEMENTATION.
  16. **************************************************************************/
  17. //delegate to the common IUnknown implementation.
  18. STDMETHODIMP PSQueryInterface(
  19. LPPERSISTSTORAGE lpPersStg, // persist storage object ptr
  20. REFIID riidReq, // IID required
  21. LPVOID FAR * lplpUnk // pre for returning the interface
  22. )
  23. {
  24. return UnkQueryInterface((LPUNKNOWN)lpPersStg, riidReq, lplpUnk);
  25. }
  26. STDMETHODIMP_(ULONG) PSAddRef(
  27. LPPERSISTSTORAGE lpPersStg // persist storage object ptr
  28. )
  29. {
  30. return UnkAddRef((LPUNKNOWN) lpPersStg);
  31. }
  32. STDMETHODIMP_(ULONG) PSRelease (
  33. LPPERSISTSTORAGE lpPersStg // persist storage object ptr
  34. )
  35. {
  36. return UnkRelease((LPUNKNOWN) lpPersStg);
  37. }
  38. STDMETHODIMP PSGetClassID (
  39. LPPERSISTSTORAGE lpPersStg,
  40. CLSID FAR* pClsid
  41. )
  42. {
  43. DPF("PSGetClassID\n");
  44. /* Return the actual class ID that gets stored:
  45. */
  46. *pClsid = gClsIDOLE1Compat;
  47. return NOERROR;
  48. }
  49. STDMETHODIMP PSIsDirty (
  50. LPPERSISTSTORAGE lpPersStg
  51. )
  52. {DPF("PSIsDirty\n");
  53. RETURN_RESULT( (fDocChanged && !(gfPlayingInPlace || gfOle2IPPlaying))
  54. ? S_OK : S_FALSE);
  55. }
  56. STDMETHODIMP PSInitNew (
  57. LPPERSISTSTORAGE lpPersStg,
  58. LPSTORAGE lpStorage
  59. )
  60. {
  61. return NOERROR;
  62. }
  63. /**************************************************************************
  64. * PSLoad:
  65. * The Load method reads the embedded data from the "\1Ole10Native"
  66. * stream of the IStorage passed as an argument. This is because
  67. * we always pretend to be an OLE1 server when transferring data.
  68. * ItemSetData is called with this embedded data to to run the required
  69. * object.
  70. **************************************************************************/
  71. STDMETHODIMP PSLoad (
  72. LPPERSISTSTORAGE lpPersStg,
  73. LPSTORAGE lpStorage
  74. )
  75. {
  76. LPDOC lpdoc;
  77. SCODE error;
  78. LPSTREAM pstm;
  79. ULONG cbRead;
  80. DWORD size = 0;
  81. HGLOBAL hNative = NULL;
  82. LPTSTR lpnative = NULL;
  83. DPF("\nPSLoad is being called\n");
  84. lpdoc = ((struct CPersistStorageImpl FAR*)lpPersStg)->lpdoc;
  85. error = GetScode(IStorage_OpenStream(lpStorage, sz1Ole10Native,
  86. NULL, STGM_SALL, 0, &pstm));
  87. if (error == S_OK)
  88. {
  89. error = GetScode(IStream_Read(pstm, &size, 4, &cbRead));
  90. }
  91. if (error == S_OK)
  92. {
  93. hNative = GlobalAlloc(GMEM_DDESHARE |GMEM_ZEROINIT, (LONG)size);
  94. if (hNative)
  95. lpdoc->native = GLOBALLOCK(hNative);
  96. }
  97. if(lpdoc->native )
  98. {
  99. error = GetScode(IStream_Read(pstm, lpdoc->native, size, &cbRead));
  100. if (cbRead != size) error = E_FAIL; // REVIEW SCODE stream size error
  101. IStream_Release(pstm);
  102. }
  103. else error = E_OUTOFMEMORY;
  104. if (error == S_OK)
  105. {
  106. error = ItemSetData((LPBYTE)lpdoc->native);
  107. fDocChanged = FALSE;
  108. lpdoc->doctype = doctypeEmbedded;
  109. }
  110. if(hNative)
  111. {
  112. GLOBALUNLOCK(hNative);
  113. GLOBALFREE(hNative);
  114. }
  115. RETURN_RESULT( error);
  116. }
  117. /**************************************************************************
  118. * PSSave:
  119. * The Save method saves the native data in "\1Ole10Native" stream.
  120. * This is because we always pretend to be an OLE1 server when transferring
  121. * data. This ensures backward compatibility. GetLink is called to get
  122. * the embedding data.
  123. **************************************************************************/
  124. STDMETHODIMP PSSave (
  125. LPPERSISTSTORAGE lpPersStg,
  126. LPSTORAGE lpStorage,
  127. BOOL fSameAsLoad
  128. )
  129. {
  130. LPDOC lpdoc;
  131. SCODE error;
  132. LPSTREAM pstm = NULL;
  133. ULONG cbWritten;
  134. DWORD_PTR size;
  135. HGLOBAL hNative = NULL;
  136. LPTSTR lpnative = NULL;
  137. LPWSTR lpszUserType;
  138. DPF("* in pssave *");
  139. lpdoc = ((struct CPersistStorageImpl FAR*)lpPersStg)->lpdoc;
  140. #if 0
  141. // Allow saves if we're playing so that broken links can be fixed.
  142. if (fSameAsLoad && (gfOle2IPPlaying || gfPlayingInPlace))
  143. RETURN_RESULT(S_OK);
  144. #endif
  145. //Mark as OLE1 mplayer object.
  146. #ifndef UNICODE
  147. lpszUserType = AllocateUnicodeString(gachClassRoot);
  148. #else
  149. lpszUserType = gachClassRoot;
  150. #endif
  151. error = GetScode(WriteClassStg(lpStorage, &gClsIDOLE1Compat));
  152. error = GetScode(WriteFmtUserTypeStg(lpStorage, cfMPlayer, lpszUserType));
  153. #ifndef UNICODE
  154. FreeUnicodeString(lpszUserType);
  155. #endif
  156. if(error != S_OK)
  157. RETURN_RESULT(error);
  158. error = GetScode(IStorage_CreateStream(lpStorage, sz1Ole10Native,
  159. STGM_SALL | STGM_FAILIFTHERE, 0,0, &pstm));
  160. if (error == STG_E_FILEALREADYEXISTS)
  161. {
  162. error = GetScode(IStorage_OpenStream(lpStorage, sz1Ole10Native,
  163. NULL, STGM_SALL, 0,&pstm));
  164. DPF("*pssave--openstream*");
  165. }
  166. if(pstm && (error == S_OK))
  167. hNative = GetLink();
  168. if (hNative)
  169. {
  170. lpnative = GLOBALLOCK(hNative);
  171. size = GlobalSize(hNative);
  172. }
  173. else
  174. error = E_OUTOFMEMORY;
  175. if (lpnative && (size != 0L))
  176. {
  177. error = GetScode(IStream_Write(pstm, &size, 4, &cbWritten));
  178. error = GetScode(IStream_Write(pstm, lpnative, (ULONG)size, &cbWritten));
  179. DPF("\n*After pssave write");
  180. if (cbWritten != size) error = E_FAIL ; // REVIEW SCODE stream full error
  181. IStream_Release(pstm);
  182. }
  183. CleanObject();
  184. GLOBALUNLOCK(hNative);
  185. GLOBALFREE(hNative);
  186. RETURN_RESULT(error);
  187. }
  188. /* InPowerPointSlideView
  189. *
  190. * Check the class name of the container window to see if we're in PowerPoint.
  191. * This is to support the horrible hack to get around problem of PowerPoint
  192. * crashing if we delete an empty Media Clip.
  193. *
  194. */
  195. STATICFN BOOL InPowerPointSlideView()
  196. {
  197. TCHAR ClassName[256];
  198. if (GetClassName(ghwndCntr, ClassName, CHAR_COUNT(ClassName)) > 0)
  199. {
  200. if (lstrcmp(ClassName, TEXT("paneClassDC")) == 0)
  201. {
  202. return TRUE;
  203. }
  204. }
  205. return FALSE;
  206. }
  207. STDMETHODIMP PSSaveCompleted (
  208. LPPERSISTSTORAGE lpPersStg,
  209. LPSTORAGE lpStorage
  210. )
  211. {
  212. LPDOC lpdoc;
  213. DPF("\n**pssavecompleted**");
  214. lpdoc = ((struct CPersistStorageImpl FAR*)lpPersStg)->lpdoc;
  215. /* Win95 HOT bug #11142
  216. *
  217. * Stop PowerPoint crashing horribly:
  218. */
  219. if ((gwDeviceID == 0) && InPowerPointSlideView())
  220. SendDocMsg(lpdoc, OLE_CHANGED);
  221. // inform clients that the object has been saved
  222. return SendDocMsg (lpdoc, OLE_SAVED);
  223. }
  224. STDMETHODIMP PSHandsOffStorage (
  225. LPPERSISTSTORAGE lpPersStg
  226. )
  227. {
  228. return NOERROR;
  229. }
  230. /**************************************************************************
  231. ************ IPersistFile INTERFACE IMPLEMENTATION.
  232. **************************************************************************/
  233. //delegate to common IUnknown implementation.
  234. STDMETHODIMP PFQueryInterface(
  235. LPPERSISTFILE lpPersFile, // persist storage object ptr
  236. REFIID riidReq, // IID required
  237. LPVOID FAR * lplpUnk // pre for returning the interface
  238. )
  239. {
  240. return UnkQueryInterface((LPUNKNOWN)lpPersFile, riidReq, lplpUnk);
  241. }
  242. STDMETHODIMP_(ULONG) PFAddRef(
  243. LPPERSISTFILE lpPersFile // persist storage object ptr
  244. )
  245. {
  246. return UnkAddRef((LPUNKNOWN) lpPersFile);
  247. }
  248. STDMETHODIMP_(ULONG) PFRelease (
  249. LPPERSISTFILE lpPersFile // persist storage object ptr
  250. )
  251. {
  252. return UnkRelease((LPUNKNOWN) lpPersFile);
  253. }
  254. STDMETHODIMP PFGetClassID (
  255. LPPERSISTFILE lpPersFile,
  256. CLSID FAR* pCid
  257. )
  258. {
  259. DPF("\n* PFGetclassid");
  260. /* The docs are confusing here, but apparently IPersist interfaces
  261. * should return the old class ID:
  262. */
  263. *pCid = gClsIDOLE1Compat;
  264. return NOERROR;
  265. }
  266. STDMETHODIMP PFIsDirty (
  267. LPPERSISTFILE lpPersFile
  268. )
  269. {
  270. RETURN_RESULT( gfDirty ? S_OK : S_FALSE);
  271. }
  272. //This will be called when the user does a "Insert->Create from file".
  273. //Open the file with OpenMciDevice and we will be ready to transfer the
  274. //object.
  275. STDMETHODIMP PFLoad (
  276. LPPERSISTFILE lpPersFile,
  277. LPCWSTR lpszFileName,
  278. DWORD grfMode
  279. )
  280. {
  281. size_t nLen;
  282. LPDOC lpdoc;
  283. TCHAR szFileName[256];
  284. if(FAILED(StringCchLength(lpszFileName, 256, &nLen)))
  285. RETURN_RESULT(E_FAIL);
  286. //Don't even attempt to deal with file names greater then 256
  287. //Don't worry about nonUnincode so casting as LPTSTR
  288. if(nLen > 255)
  289. RETURN_RESULT(E_FAIL);
  290. lpdoc = ((struct CPersistStorageImpl FAR*)lpPersFile)->lpdoc;
  291. DPF("\n***IN PFLOAD: "DTS"\n", lpszFileName);
  292. #if UNICODE
  293. lstrcpy(szFileName, lpszFileName);
  294. #else
  295. UnicodeToAnsiString(lpszFileName, szFileName, UNKNOWN_LENGTH);
  296. #endif
  297. if(OpenMciDevice(szFileName, NULL))
  298. RETURN_RESULT(S_OK);
  299. else
  300. RETURN_RESULT(E_FAIL);
  301. }
  302. STDMETHODIMP PFSave (
  303. LPPERSISTFILE lpPersFile,
  304. LPCWSTR lpszFileName,
  305. BOOL fRemember
  306. )
  307. {
  308. return NOERROR;
  309. }
  310. STDMETHODIMP PFSaveCompleted (
  311. LPPERSISTFILE lpPersFile,
  312. LPCWSTR lpszFileName
  313. )
  314. {
  315. LPDOC lpdoc;
  316. lpdoc = ((struct CPersistStorageImpl FAR*)lpPersFile)->lpdoc;
  317. // inform clients that the object has been saved
  318. return SendDocMsg(lpdoc, OLE_SAVED);
  319. }
  320. STDMETHODIMP PFGetCurFile (
  321. LPPERSISTFILE lpPersFile,
  322. LPWSTR FAR* lplpszFileName
  323. )
  324. {
  325. RETURN_RESULT( E_NOTIMPL);
  326. }
  327.