Recovery of release 990110 after disk crash.
[wine] / ole / ifs.c
1 /*
2  *      basic interfaces
3  *
4  *      Copyright 1997  Marcus Meissner
5  */
6
7 #include <ctype.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <assert.h>
11 #include "winerror.h"
12 #include "ldt.h"
13 #include "heap.h"
14 #include "wine/obj_base.h"
15 #include "objbase.h"
16 #include "local.h"
17 #include "module.h"
18 #include "debug.h"
19
20
21 /* --- IUnknown implementation */
22
23
24 /******************************************************************************
25  *              IUnknown_AddRef [VTABLE:IUNKNOWN.1]
26  */
27 static ULONG WINAPI IUnknown_fnAddRef(LPUNKNOWN iface) { 
28         ICOM_THIS(IUnknown,iface);
29         TRACE(relay,"(%p)->AddRef()\n",this);
30         return ++(this->ref);
31 }
32
33 /******************************************************************************
34  * IUnknown_Release [VTABLE:IUNKNOWN.2]
35  */
36 static ULONG WINAPI IUnknown_fnRelease(LPUNKNOWN iface) {
37         ICOM_THIS(IUnknown,iface);
38         TRACE(relay,"(%p)->Release()\n",this);
39         if (!--(this->ref)) {
40                 HeapFree(GetProcessHeap(),0,this);
41                 return 0;
42         }
43         return this->ref;
44 }
45
46 /******************************************************************************
47  * IUnknown_QueryInterface [VTABLE:IUNKNOWN.0]
48  */
49 static HRESULT WINAPI IUnknown_fnQueryInterface(LPUNKNOWN iface,REFIID refiid,LPVOID *obj) {
50         ICOM_THIS(IUnknown,iface);
51         char    xrefiid[50];
52
53         WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
54         TRACE(relay,"(%p)->QueryInterface(%s,%p)\n",this,xrefiid,obj);
55
56         if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
57                 *obj = this;
58                 return 0; 
59         }
60         return OLE_E_ENUM_NOMORE; 
61 }
62
63 static ICOM_VTABLE(IUnknown) uvt = {
64         IUnknown_fnQueryInterface,
65         IUnknown_fnAddRef,
66         IUnknown_fnRelease
67 };
68
69 /******************************************************************************
70  * IUnknown_Constructor [INTERNAL]
71  */
72 LPUNKNOWN
73 IUnknown_Constructor() {
74         _IUnknown*      unk;
75
76         unk = (_IUnknown*)HeapAlloc(GetProcessHeap(),0,sizeof(IUnknown));
77         unk->lpvtbl     = &uvt;
78         unk->ref        = 1;
79         return (LPUNKNOWN)unk;
80 }
81
82
83 /* --- IMalloc16 implementation */
84
85
86 typedef struct _IMalloc16 {
87         /* IUnknown fields */
88         ICOM_VTABLE(IMalloc16)* lpvtbl;
89         DWORD                   ref;
90         /* IMalloc16 fields */
91         /* Gmm, I think one is not enough, we should probably manage a list of
92          * heaps
93  */
94         HGLOBAL16 heap;
95 } _IMalloc16;
96
97 /******************************************************************************
98  *              IMalloc16_QueryInterface        [COMPOBJ.500]
99  */
100 HRESULT WINAPI IMalloc16_fnQueryInterface(LPUNKNOWN iface,REFIID refiid,LPVOID *obj) {
101         ICOM_THIS(IMalloc16,iface);
102         char    xrefiid[50];
103
104         WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
105         TRACE(relay,"(%p)->QueryInterface(%s,%p)\n",this,xrefiid,obj);
106         if (    !memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)) ||
107                 !memcmp(&IID_IMalloc,refiid,sizeof(IID_IMalloc))
108         ) {
109                 *obj = this;
110                 return 0;
111         }
112         return OLE_E_ENUM_NOMORE; 
113 }
114
115 /******************************************************************************
116  *              IMalloc16_AddRef        [COMPOBJ.501]
117  */
118 ULONG WINAPI IMalloc16_fnAddRef(LPUNKNOWN iface) {
119         ICOM_THIS(IMalloc16,iface);
120         TRACE(relay,"(%p)->AddRef()\n",this);
121         return 1; /* cannot be freed */
122 }
123
124 /******************************************************************************
125  *              IMalloc16_Release       [COMPOBJ.502]
126  */
127 ULONG WINAPI IMalloc16_fnRelease(LPUNKNOWN iface) {
128         ICOM_THIS(IMalloc16,iface);
129         TRACE(relay,"(%p)->Release()\n",this);
130         return 1; /* cannot be freed */
131 }
132
133 /******************************************************************************
134  * IMalloc16_Alloc [COMPOBJ.503]
135  */
136 LPVOID WINAPI IMalloc16_fnAlloc(IMalloc16* iface,DWORD cb) {
137         ICOM_THIS(IMalloc16,iface);
138         TRACE(relay,"(%p)->Alloc(%ld)\n",this,cb);
139         return (LPVOID)PTR_SEG_OFF_TO_SEGPTR(this->heap,LOCAL_Alloc(this->heap,0,cb));
140 }
141
142 /******************************************************************************
143  * IMalloc16_Realloc [COMPOBJ.504]
144  */
145 LPVOID WINAPI IMalloc16_fnRealloc(IMalloc16* iface,LPVOID pv,DWORD cb) {
146         ICOM_THIS(IMalloc16,iface);
147         TRACE(relay,"(%p)->Realloc(%p,%ld)\n",this,pv,cb);
148         return (LPVOID)PTR_SEG_OFF_TO_SEGPTR(this->heap,LOCAL_ReAlloc(this->heap,0,LOWORD(pv),cb));
149 }
150
151 /******************************************************************************
152  * IMalloc16_Free [COMPOBJ.505]
153  */
154 VOID WINAPI IMalloc16_fnFree(IMalloc16* iface,LPVOID pv) {
155         ICOM_THIS(IMalloc16,iface);
156         TRACE(relay,"(%p)->Free(%p)\n",this,pv);
157         LOCAL_Free(this->heap,LOWORD(pv));
158 }
159
160 /******************************************************************************
161  * IMalloc16_GetSize [COMPOBJ.506]
162  */
163 DWORD WINAPI IMalloc16_fnGetSize(const IMalloc16* iface,LPVOID pv) {
164         ICOM_CTHIS(IMalloc16,iface);
165         TRACE(relay,"(%p)->GetSize(%p)\n",this,pv);
166         return LOCAL_Size(this->heap,LOWORD(pv));
167 }
168
169 /******************************************************************************
170  * IMalloc16_DidAlloc [COMPOBJ.507]
171  */
172 INT16 WINAPI IMalloc16_fnDidAlloc(const IMalloc16* iface,LPVOID pv) {
173         ICOM_CTHIS(IMalloc16,iface);
174         TRACE(relay,"(%p)->DidAlloc(%p)\n",this,pv);
175         return (INT16)-1;
176 }
177
178 /******************************************************************************
179  * IMalloc16_HeapMinimize [COMPOBJ.508]
180  */
181 LPVOID WINAPI IMalloc16_fnHeapMinimize(IMalloc16* iface) {
182         ICOM_THIS(IMalloc16,iface);
183         TRACE(relay,"(%p)->HeapMinimize()\n",this);
184         return NULL;
185 }
186
187 static ICOM_VTABLE(IMalloc16)* msegvt16 = NULL;
188
189 /******************************************************************************
190  * IMalloc16_Constructor [VTABLE]
191  */
192 LPMALLOC16
193 IMalloc16_Constructor() {
194         _IMalloc16*     this;
195         HMODULE16       hcomp = GetModuleHandle16("COMPOBJ");
196
197         this = (_IMalloc16*)SEGPTR_NEW(_IMalloc16);
198         if (!msegvt16) {
199             this->lpvtbl = msegvt16 = SEGPTR_NEW(ICOM_VTABLE(IMalloc16));
200
201 #define VTENT(x) msegvt16->bvt.fn##x = (void*)WIN32_GetProcAddress16(hcomp,"IMalloc16_"#x);assert(msegvt16->bvt.fn##x)
202             VTENT(QueryInterface);
203             VTENT(AddRef);
204             VTENT(Release);
205 #undef VTENT
206 #define VTENT(x) msegvt16->fn##x = (void*)WIN32_GetProcAddress16(hcomp,"IMalloc16_"#x);assert(msegvt16->fn##x)
207             VTENT(Alloc);
208             VTENT(Realloc);
209             VTENT(Free);
210             VTENT(GetSize);
211             VTENT(DidAlloc);
212             VTENT(HeapMinimize);
213             msegvt16 = (ICOM_VTABLE(IMalloc16)*)SEGPTR_GET(msegvt16);
214 #undef VTENT
215         }
216         this->ref = 1;
217         /* FIXME: implement multiple heaps */
218         this->heap = GlobalAlloc16(GMEM_MOVEABLE,64000);
219         LocalInit(this->heap,0,64000);
220         return (LPMALLOC16)SEGPTR_GET(this);
221 }
222
223
224 /* --- IMalloc32 implementation */
225
226 typedef struct _IMalloc32 {
227         /* IUnknown fields */
228         ICOM_VTABLE(IMalloc32)* lpvtbl;
229         DWORD                   ref;
230 } _IMalloc32;
231
232 /******************************************************************************
233  *              IMalloc32_QueryInterface        [VTABLE]
234  */
235 static HRESULT WINAPI IMalloc32_fnQueryInterface(LPUNKNOWN iface,REFIID refiid,LPVOID *obj) {
236         ICOM_THIS(IMalloc32,iface);
237         char    xrefiid[50];
238
239         WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
240         TRACE(relay,"(%p)->QueryInterface(%s,%p)\n",this,xrefiid,obj);
241         if (    !memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)) ||
242                 !memcmp(&IID_IMalloc,refiid,sizeof(IID_IMalloc))
243         ) {
244                 *obj = this;
245                 return S_OK;
246         }
247         return OLE_E_ENUM_NOMORE; 
248 }
249
250 /******************************************************************************
251  *              IMalloc32_AddRef        [VTABLE]
252  */
253 static ULONG WINAPI IMalloc32_fnAddRef(LPUNKNOWN iface) {
254         ICOM_THIS(IMalloc32,iface);
255         TRACE(relay,"(%p)->AddRef()\n",this);
256         return 1; /* cannot be freed */
257 }
258
259 /******************************************************************************
260  *              IMalloc32_Release       [VTABLE]
261  */
262 static ULONG WINAPI IMalloc32_fnRelease(LPUNKNOWN iface) {
263         ICOM_THIS(IMalloc32,iface);
264         TRACE(relay,"(%p)->Release()\n",this);
265         return 1; /* cannot be freed */
266 }
267
268 /******************************************************************************
269  * IMalloc32_Alloc [VTABLE]
270  */
271 static LPVOID WINAPI IMalloc32_fnAlloc(LPMALLOC32 iface,DWORD cb) {
272         ICOM_THIS(IMalloc32,iface);
273         TRACE(relay,"(%p)->Alloc(%ld)\n",this,cb);
274         return HeapAlloc(GetProcessHeap(),0,cb);
275 }
276
277 /******************************************************************************
278  * IMalloc32_Realloc [VTABLE]
279  */
280 static LPVOID WINAPI IMalloc32_fnRealloc(LPMALLOC32 iface,LPVOID pv,DWORD cb) {
281         ICOM_THIS(IMalloc32,iface);
282         TRACE(relay,"(%p)->Realloc(%p,%ld)\n",this,pv,cb);
283         return HeapReAlloc(GetProcessHeap(),0,pv,cb);
284 }
285
286 /******************************************************************************
287  * IMalloc32_Free [VTABLE]
288  */
289 static VOID WINAPI IMalloc32_fnFree(LPMALLOC32 iface,LPVOID pv) {
290         ICOM_THIS(IMalloc32,iface);
291         TRACE(relay,"(%p)->Free(%p)\n",this,pv);
292         HeapFree(GetProcessHeap(),0,pv);
293 }
294
295 /******************************************************************************
296  * IMalloc32_GetSize [VTABLE]
297  */
298 static DWORD WINAPI IMalloc32_fnGetSize(const IMalloc32* iface,LPVOID pv) {
299         ICOM_CTHIS(IMalloc32,iface);
300         TRACE(relay,"(%p)->GetSize(%p)\n",this,pv);
301         return HeapSize(GetProcessHeap(),0,pv);
302 }
303
304 /******************************************************************************
305  * IMalloc32_DidAlloc [VTABLE]
306  */
307 static INT32 WINAPI IMalloc32_fnDidAlloc(const IMalloc32* iface,LPVOID pv) {
308         ICOM_CTHIS(IMalloc32,iface);
309         TRACE(relay,"(%p)->DidAlloc(%p)\n",this,pv);
310         return -1;
311 }
312
313 /******************************************************************************
314  * IMalloc32_HeapMinimize [VTABLE]
315  */
316 static LPVOID WINAPI IMalloc32_fnHeapMinimize(LPMALLOC32 iface) {
317         ICOM_THIS(IMalloc32,iface);
318         TRACE(relay,"(%p)->HeapMinimize()\n",this);
319         return NULL;
320 }
321
322 static ICOM_VTABLE(IMalloc32) VT_IMalloc32 = {
323   {
324     IMalloc32_fnQueryInterface,
325     IMalloc32_fnAddRef,
326     IMalloc32_fnRelease
327   },
328   IMalloc32_fnAlloc,
329   IMalloc32_fnRealloc,
330   IMalloc32_fnFree,
331   IMalloc32_fnGetSize,
332   IMalloc32_fnDidAlloc,
333   IMalloc32_fnHeapMinimize
334 };
335
336 /******************************************************************************
337  * IMalloc32_Constructor [VTABLE]
338  */
339 LPMALLOC32
340 IMalloc32_Constructor() {
341         _IMalloc32* this;
342
343         this = (_IMalloc32*)HeapAlloc(GetProcessHeap(),0,sizeof(_IMalloc32));
344         this->lpvtbl = &VT_IMalloc32;
345         this->ref = 1;
346         return (LPMALLOC32)this;
347 }
348
349 /****************************************************************************
350  * API Functions
351  */
352
353 /******************************************************************************
354  *              IsValidInterface32      [OLE32.78]
355  *
356  * RETURNS
357  *  True, if the passed pointer is a valid interface
358  */
359 BOOL32 WINAPI IsValidInterface32(
360         LPUNKNOWN punk  /* [in] interface to be tested */
361 ) {
362         return !(
363                 IsBadReadPtr32(punk,4)                                  ||
364                 IsBadReadPtr32(punk->lpvtbl,4)                          ||
365                 IsBadReadPtr32(punk->lpvtbl->fnQueryInterface,9)        ||
366                 IsBadCodePtr32(punk->lpvtbl->fnQueryInterface)
367         );
368 }