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.

223 lines
9.2 KiB

  1. // ===========================================================================
  2. // File: M F C U I . C P P
  3. //
  4. // Copyright 1995 Microsoft Corporation. All Rights Reserved.
  5. // Microsoft Confidential
  6. // ===========================================================================
  7. #ifndef UNICODE
  8. // %%Includes: ---------------------------------------------------------------
  9. #include <windows.h>
  10. #include <ole2.h>
  11. #include <oledlg.h>
  12. // %%Prototypes: -------------------------------------------------------------
  13. STDAPI Ole2AnsiWFromA(REFIID riid, LPUNKNOWN punkWrappeeA, LPUNKNOWN *ppunkWrapperW);
  14. STDAPI Ole2AnsiAFromW(REFIID riid, LPUNKNOWN punkWrappeeW, LPUNKNOWN *ppunkWrapperA);
  15. // ---------------------------------------------------------------------------
  16. // %%Function: OleUIAddVerbMenu %%Reviewed: 00/00/95
  17. //
  18. // Description:
  19. // Wraps OleUIAddVerbMenu to OLEDLG.DLL for MFC clients, which expect to be
  20. // able to pass Ansi IOleObject's.
  21. // ---------------------------------------------------------------------------
  22. #undef OleUIAddVerbMenu // overrides the Ansi/Unicode macros in OLEDLG.H
  23. STDAPI_(BOOL)
  24. OleUIAddVerbMenu(LPOLEOBJECT lpOleObjA, LPCSTR lpszShortType,
  25. HMENU hMenu, UINT uPos, UINT uIDVerbMin, UINT uIDVerbMax,
  26. BOOL bAddConvert, UINT idConvert, HMENU FAR *lphMenu)
  27. {
  28. LPOLEOBJECT lpOleObjW = NULL;
  29. BOOL fResult = FALSE;
  30. // allow NULL IOleObject (OleUIAddVerbMenuA handles this by making an empty menu), but
  31. // otherwise wrap the Ansi IOleObject to Unicode.
  32. if (lpOleObjA == NULL ||
  33. SUCCEEDED(Ole2AnsiWFromA(IID_IOleObject, (LPUNKNOWN)lpOleObjA, (LPUNKNOWN *)&lpOleObjW)))
  34. {
  35. fResult = OleUIAddVerbMenuA(lpOleObjW, lpszShortType, hMenu, uPos, uIDVerbMin,
  36. uIDVerbMax, bAddConvert, idConvert, lphMenu);
  37. // release the Unicode IOleObject if it was created
  38. if (lpOleObjW != NULL)
  39. lpOleObjW->Release();
  40. }
  41. return fResult;
  42. } // OleUIAddVerbMenu
  43. // ---------------------------------------------------------------------------
  44. // %%Function: OleUIInsertObject %%Reviewed: 00/00/95
  45. //
  46. // Description:
  47. // Wraps OleUIInsertObject to OLEDLG.DLL for MFC clients, which expect to be
  48. // able to pass Ansi IOleClientSite and IStorage in and receive Ansi interfaces
  49. // out in ppvObj.
  50. // ---------------------------------------------------------------------------
  51. #undef OleUIInsertObject // overrides the Ansi/Unicode macros in OLEDLG.H
  52. STDAPI_(UINT)
  53. OleUIInsertObject(LPOLEUIINSERTOBJECTA lpio)
  54. {
  55. LPOLECLIENTSITE lpIOleClientSiteA = NULL;
  56. LPSTORAGE lpIStorageA = NULL;
  57. LPVOID FAR *ppvObjA;
  58. LPUNKNOWN punkObjW = NULL;
  59. BOOL fCreatingObject;
  60. UINT wResult;
  61. HRESULT hr = S_OK;
  62. // validate the structure superficially: let the actual function do most of the validation
  63. if (!lpio)
  64. return OLEUI_ERR_STRUCTURENULL;
  65. if (IsBadReadPtr(lpio, sizeof(LPOLEUIINSERTOBJECTA)) ||
  66. IsBadWritePtr(lpio, sizeof(LPOLEUIINSERTOBJECTA)))
  67. return OLEUI_ERR_STRUCTUREINVALID;
  68. if (lpio->cbStruct < sizeof(LPOLEUIINSERTOBJECTA))
  69. return OLEUI_ERR_CBSTRUCTINCORRECT;
  70. if (fCreatingObject = (lpio->dwFlags & (IOF_CREATENEWOBJECT | IOF_CREATEFILEOBJECT | IOF_CREATELINKOBJECT)))
  71. {
  72. // verify these parameters, otherwise cleanup becomes complicated
  73. if (IsBadWritePtr(lpio->ppvObj, sizeof(LPUNKNOWN)))
  74. return OLEUI_IOERR_PPVOBJINVALID;
  75. if (lpio->lpIOleClientSite != NULL && IsBadReadPtr(lpio->lpIOleClientSite, sizeof(IOleClientSite)))
  76. return OLEUI_IOERR_LPIOLECLIENTSITEINVALID;
  77. if (lpio->lpIStorage != NULL && IsBadReadPtr(lpio->lpIStorage, sizeof(IStorage)))
  78. return OLEUI_IOERR_LPISTORAGEINVALID;
  79. // save away the Ansi IOleClientSite, stuff in our Unicode one.
  80. // if it's NULL, OleUIInsertObjectA() will handle the error appropriately and we'll clean up correctly, below.
  81. if (lpIOleClientSiteA = lpio->lpIOleClientSite)
  82. {
  83. hr = Ole2AnsiWFromA(IID_IOleClientSite, (LPUNKNOWN)lpIOleClientSiteA, (LPUNKNOWN *)&lpio->lpIOleClientSite);
  84. if (FAILED(hr))
  85. {
  86. lpio->lpIOleClientSite = lpIOleClientSiteA;
  87. lpio->sc = hr;
  88. return OLEUI_IOERR_SCODEHASERROR;
  89. }
  90. }
  91. // save away the Ansi IStorage, stuff in our Unicode one.
  92. // if it's NULL, OleUIInsertObjectA() will handle the error appropriately and we'll clean up correctly, below.
  93. if (lpIStorageA = lpio->lpIStorage)
  94. {
  95. hr = Ole2AnsiWFromA(IID_IStorage, (LPUNKNOWN)lpIStorageA, (LPUNKNOWN *)&lpio->lpIStorage);
  96. if (FAILED(hr))
  97. {
  98. // make sure to free the Unicode IOleClientSite which we converted above.
  99. if (lpio->lpIOleClientSite)
  100. {
  101. lpio->lpIOleClientSite->Release();
  102. lpio->lpIOleClientSite = lpIOleClientSiteA;
  103. }
  104. lpio->lpIStorage = lpIStorageA;
  105. lpio->sc = hr;
  106. return OLEUI_IOERR_SCODEHASERROR;
  107. }
  108. }
  109. // save the current Ansi ppvObj, stuff in our Unicode one
  110. ppvObjA = lpio->ppvObj;
  111. lpio->ppvObj = (LPVOID FAR *)&punkObjW;
  112. }
  113. wResult = OleUIInsertObjectA(lpio);
  114. // regardless of success or failure of the above call, we have to clean up the wrapping we did
  115. if (fCreatingObject)
  116. {
  117. // return the Ansi versions of the IOleClientSite and IStorage to
  118. // the structure, and release the Unicode ones
  119. if (lpio->lpIOleClientSite)
  120. {
  121. lpio->lpIOleClientSite->Release();
  122. lpio->lpIOleClientSite = lpIOleClientSiteA;
  123. }
  124. if (lpio->lpIStorage)
  125. {
  126. lpio->lpIStorage->Release();
  127. lpio->lpIStorage = lpIStorageA;
  128. }
  129. // return the Ansi object pointer to the structure
  130. lpio->ppvObj = ppvObjA;
  131. // convert
  132. if (punkObjW != NULL)
  133. {
  134. HRESULT hr;
  135. // if we were creating an object and we succeeded, punkObjW must be valid and contain an interface
  136. // of type iid. if not, there is a problem in OleUIInsertObjectA(), not in this code. we could assert
  137. // here if this code wanted to, but wouldn't be able to properly circumvent the error anyway.
  138. if (FAILED(hr = Ole2AnsiAFromW(lpio->iid, (LPUNKNOWN)punkObjW, (LPUNKNOWN *)ppvObjA)))
  139. {
  140. lpio->sc = hr;
  141. }
  142. punkObjW->Release();
  143. if (lpio->sc != S_OK)
  144. return OLEUI_IOERR_SCODEHASERROR;
  145. }
  146. }
  147. return wResult;
  148. } // OleUIInsertObject
  149. // ---------------------------------------------------------------------------
  150. // %%Function: OleUIPasteSpecial %%Reviewed: 00/00/95
  151. //
  152. // Description:
  153. // Wraps OleUIPasteSpecial to OLEDLG.DLL for MFC clients, which expect to be
  154. // able to pass in and get back Ansi IDataObject's.
  155. // ---------------------------------------------------------------------------
  156. #undef OleUIPasteSpecial // overrides the Ansi/Unicode macros in OLEDLG.H
  157. STDAPI_(UINT)
  158. OleUIPasteSpecial(LPOLEUIPASTESPECIALA lpps)
  159. {
  160. LPDATAOBJECT lpSrcDataObjA;
  161. UINT wResult;
  162. // validate the structure superficially: let the actual function do most of the validation
  163. if (!lpps)
  164. return OLEUI_ERR_STRUCTURENULL;
  165. if (IsBadReadPtr(lpps, sizeof(LPOLEUIPASTESPECIALA)) ||
  166. IsBadWritePtr(lpps, sizeof(LPOLEUIPASTESPECIALA)))
  167. return OLEUI_ERR_STRUCTUREINVALID;
  168. if (lpps->cbStruct < sizeof(LPOLEUIPASTESPECIALA))
  169. return OLEUI_ERR_CBSTRUCTINCORRECT;
  170. if (NULL != lpps->lpSrcDataObj && IsBadReadPtr(lpps->lpSrcDataObj, sizeof(IDataObject)))
  171. return OLEUI_IOERR_SRCDATAOBJECTINVALID;
  172. if (!(lpSrcDataObjA = lpps->lpSrcDataObj) ||
  173. SUCCEEDED(Ole2AnsiWFromA(IID_IDataObject, (LPUNKNOWN)lpSrcDataObjA, (LPUNKNOWN *)&lpps->lpSrcDataObj)))
  174. {
  175. wResult = OleUIPasteSpecialA(lpps);
  176. // if we had an Ansi IDataObject on entry, put it back and release the Unicode wrapper.
  177. if (lpSrcDataObjA != NULL)
  178. {
  179. lpps->lpSrcDataObj->Release();
  180. lpps->lpSrcDataObj = lpSrcDataObjA;
  181. }
  182. // otherwise check to see if OleUIPasteSpecialA() placed a Unicode IDataObject into our structure.
  183. // if it did, wrap it to make sure an Ansi one gets sent back out.
  184. else if (lpps->lpSrcDataObj != NULL)
  185. {
  186. if (FAILED(Ole2AnsiAFromW(IID_IDataObject, (LPUNKNOWN)lpps->lpSrcDataObj, (LPUNKNOWN *)&lpSrcDataObjA)))
  187. {
  188. lpps->lpSrcDataObj->Release();
  189. lpps->lpSrcDataObj = NULL;
  190. return OLEUI_PSERR_GETCLIPBOARDFAILED; // well, that's pretty much what happened, after all
  191. }
  192. lpps->lpSrcDataObj->Release();
  193. lpps->lpSrcDataObj = lpSrcDataObjA;
  194. }
  195. }
  196. return wResult;
  197. } // OleUIPasteSpecial
  198. #endif // !UNICODE
  199. // EOF =======================================================================