- Implemented IMallocSpy hooks in IMalloc.
[wine] / dlls / ole32 / ole2impl.c
1 /*
2  * Ole 2 Create functions implementation
3  *
4  * Copyright (C) 1999-2000 Abey George
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include <string.h>
22 #include "winbase.h"
23 #include "wingdi.h"
24 #include "winuser.h"
25 #include "wine/debug.h"
26 #include "ole2.h"
27 #include "olestd.h"
28 #include "winreg.h"
29
30 WINE_DEFAULT_DEBUG_CHANNEL(ole);
31
32 #define MAX_CLIPFORMAT_NAME   80
33
34 /******************************************************************************
35  *              OleQueryCreateFromData [OLE32.117]
36  *
37  * Author   : Abey George
38  * Checks whether an object can become an embedded object.
39  * the clipboard or OLE drag and drop.
40  * Returns  : S_OK - Format that supports Embedded object creation are present.
41  *            OLE_E_STATIC - Format that supports static object creation are present.
42  *            S_FALSE - No acceptable format is available.
43  */
44
45 HRESULT WINAPI OleQueryCreateFromData(LPDATAOBJECT pSrcDataObject)
46 {
47   IEnumFORMATETC *pfmt;
48   FORMATETC fmt;
49   CHAR szFmtName[MAX_CLIPFORMAT_NAME];
50   BOOL bFoundStatic = FALSE;
51
52   HRESULT hr = IDataObject_EnumFormatEtc(pSrcDataObject, DATADIR_GET, &pfmt);
53
54   if (hr == S_OK)
55     hr = IEnumFORMATETC_Next(pfmt, 1, &fmt, NULL);
56
57   while (hr == S_OK)
58   {
59     GetClipboardFormatNameA(fmt.cfFormat, szFmtName, MAX_CLIPFORMAT_NAME-1);
60
61     /* first, Check for Embedded Object, Embed Source or Filename */
62
63     if (!strcmp(szFmtName, CF_EMBEDDEDOBJECT) || !strcmp(szFmtName, CF_EMBEDSOURCE) || !strcmp(szFmtName, CF_FILENAME))
64       return S_OK;
65
66     /* Check for Metafile, Bitmap or DIB */
67
68     if (fmt.cfFormat == CF_METAFILEPICT || fmt.cfFormat == CF_BITMAP || fmt.cfFormat == CF_DIB)
69       bFoundStatic = TRUE;
70
71     hr = IEnumFORMATETC_Next(pfmt, 1, &fmt, NULL);
72   }
73
74   /* Found a static format, but no embed format */
75
76   if (bFoundStatic)
77     return OLE_S_STATIC;
78
79   return S_FALSE;
80 }
81
82 /******************************************************************************
83  *              OleCreateFromData        [OLE32.92]
84  *
85  * Author   : Abey George
86  * Creates an embedded object from data transfer object retrieved from
87  * the clipboard or OLE drag and drop.
88  * Returns  : S_OK - Embedded object was created successfully.
89  *            OLE_E_STATIC - OLE can create only a static object
90  *            DV_E_FORMATETC - No acceptable format is available (only error return code)
91  * TODO : CF_FILENAME, CF_EMBEDEDOBJECT formats. Parameter renderopt is currently ignored.
92  */
93
94 HRESULT WINAPI OleCreateFromData(LPDATAOBJECT pSrcDataObject, REFIID riid,
95                 DWORD renderopt, LPFORMATETC pFormatEtc,
96                 LPOLECLIENTSITE pClientSite, LPSTORAGE pStg,
97                 LPVOID* ppvObj)
98 {
99   IEnumFORMATETC *pfmt;
100   FORMATETC fmt;
101   CHAR szFmtName[MAX_CLIPFORMAT_NAME];
102   STGMEDIUM std;
103   HRESULT hr;
104   HRESULT hr1;
105
106   hr = IDataObject_EnumFormatEtc(pSrcDataObject, DATADIR_GET, &pfmt);
107
108   if (hr == S_OK)
109   {
110     memset(&std, 0, sizeof(STGMEDIUM));
111
112     hr = IEnumFORMATETC_Next(pfmt, 1, &fmt, NULL);
113     while (hr == S_OK)
114     {
115       GetClipboardFormatNameA(fmt.cfFormat, szFmtName, MAX_CLIPFORMAT_NAME-1);
116
117       /* first, Check for Embedded Object, Embed Source or Filename */
118       /* TODO: Currently checks only for Embed Source. */
119
120       if (!strcmp(szFmtName, CF_EMBEDSOURCE))
121       {
122         std.tymed = TYMED_HGLOBAL;
123
124         if ((hr1 = IDataObject_GetData(pSrcDataObject, &fmt, &std)) == S_OK)
125         {
126           ILockBytes *ptrILockBytes = 0;
127           IStorage *pStorage = 0;
128           IOleObject *pOleObject = 0;
129           IPersistStorage *pPersistStorage = 0;
130           CLSID clsID;
131
132           /* Create ILock bytes */
133
134           hr1 = CreateILockBytesOnHGlobal(std.u.hGlobal, FALSE, &ptrILockBytes);
135
136           /* Open storage on the ILock bytes */
137
138           if (hr1 == S_OK)
139             hr1 = StgOpenStorageOnILockBytes(ptrILockBytes, NULL, STGM_SHARE_EXCLUSIVE, NULL, 0, &pStorage);
140
141           /* Get Class ID from the opened storage */
142
143           if (hr1 == S_OK)
144             hr1 = ReadClassStg(pStorage, &clsID);
145
146           /* Create default handler for Persist storage */
147
148           if (hr1 == S_OK)
149             hr1 = OleCreateDefaultHandler(&clsID, NULL, &IID_IPersistStorage, (LPVOID*)&pPersistStorage);
150
151           /* Load the storage to Persist storage */
152
153           if (hr1 == S_OK)
154             hr1 = IPersistStorage_Load(pPersistStorage, pStorage);
155
156           /* Query for IOleObject */
157
158           if (hr1 == S_OK)
159             hr1 = IPersistStorage_QueryInterface(pPersistStorage, &IID_IOleObject, (LPVOID*)&pOleObject);
160
161           /* Set client site with the IOleObject */
162
163           if (hr1 == S_OK)
164             hr1 = IOleObject_SetClientSite(pOleObject, pClientSite);
165
166           IPersistStorage_Release(pPersistStorage);
167           /* Query for the requested interface */
168
169           if (hr1 == S_OK)
170             hr1 = IPersistStorage_QueryInterface(pPersistStorage, riid, ppvObj);
171
172           IPersistStorage_Release(pPersistStorage);
173
174           IStorage_Release(pStorage);
175
176           if (hr1 == S_OK)
177             return S_OK;
178         }
179
180         /* Return error */
181
182         return DV_E_FORMATETC;
183       }
184
185       hr = IEnumFORMATETC_Next(pfmt, 1, &fmt, NULL);
186     }
187   }
188
189   return DV_E_FORMATETC;
190 }
191