ole2disp.dll16: Implement SafeArrayGet[UBound|LBound].
[wine.git] / dlls / ole2disp.dll16 / ole2disp.c
blob98aca3dbee7965055fb60b1b0bfa5a45ca235501
1 /*
2 * OLE2DISP library
4 * Copyright 1995 Martin von Loewis
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.
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.
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "config.h"
23 #include <stdarg.h>
24 #include <string.h>
26 #include "windef.h"
27 #include "winbase.h"
28 #include "wingdi.h"
29 #include "winuser.h"
30 #include "ole2.h"
31 #include "oleauto.h"
32 #include "winerror.h"
33 #include "wownt32.h"
34 #include "wine/windef16.h"
35 #include "wine/winbase16.h"
37 #include "ole2disp.h"
39 #include "wine/debug.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(ole);
43 #define E_OUTOFMEMORY16 MAKE_SCODE(SEVERITY_ERROR, FACILITY_NULL, 2)
44 #define E_INVALIDARG16 MAKE_SCODE(SEVERITY_ERROR, FACILITY_NULL, 3)
46 /* 16-bit SAFEARRAY implementation */
47 typedef struct tagSAFEARRAYBOUND16
49 ULONG cElements;
50 LONG lLbound;
51 } SAFEARRAYBOUND16;
53 typedef struct tagSAFEARRAY16
55 USHORT cDims;
56 USHORT fFeatures;
57 USHORT cbElements;
58 USHORT cLocks;
59 ULONG handle;
60 SEGPTR pvData;
61 SAFEARRAYBOUND16 rgsabound[1];
62 } SAFEARRAY16;
64 static SEGPTR safearray_alloc(ULONG size)
66 HANDLE16 h;
67 return WOWGlobalAllocLock16(GPTR, size, &h);
70 static void safearray_free(SEGPTR ptr)
72 WOWGlobalUnlockFree16(ptr);
75 static ULONG safearray_getcellcount(const SAFEARRAY16 *sa)
77 const SAFEARRAYBOUND16 *sab = sa->rgsabound;
78 USHORT count = sa->cDims;
79 ULONG cells = 1;
81 while (count--)
83 if (!sab->cElements)
84 return 0;
85 cells *= sab->cElements;
86 sab++;
89 return cells;
92 static HRESULT safearray_lock(SAFEARRAY16 *sa)
94 if (sa->cLocks == 0xffff)
95 return E_UNEXPECTED;
97 sa->cLocks++;
98 return S_OK;
101 /******************************************************************************
102 * SafeArrayGetDim [OLE2DISP.17]
104 USHORT WINAPI SafeArrayGetDim16(SAFEARRAY16 *sa)
106 TRACE("(%p)\n", sa);
107 return sa->cDims;
110 /******************************************************************************
111 * SafeArrayGetElemsize [OLE2DISP.18]
113 USHORT WINAPI SafeArrayGetElemsize16(SAFEARRAY16 *sa)
115 TRACE("(%p)\n", sa);
116 return sa->cbElements;
119 /******************************************************************************
120 * SafeArrayGetUBound [OLE2DISP.19]
122 HRESULT WINAPI SafeArrayGetUBound16(SAFEARRAY16 *sa, UINT16 dim, LONG *ubound)
124 TRACE("(%p, %u, %p)\n", sa, dim, ubound);
126 if (!sa)
127 return E_INVALIDARG16;
129 if (!dim || dim > sa->cDims)
130 return DISP_E_BADINDEX;
132 *ubound = sa->rgsabound[sa->cDims - dim].lLbound + sa->rgsabound[sa->cDims - dim].cElements - 1;
134 return S_OK;
137 /******************************************************************************
138 * SafeArrayGetLBound [OLE2DISP.20]
140 HRESULT WINAPI SafeArrayGetLBound16(SAFEARRAY16 *sa, UINT16 dim, LONG *lbound)
142 TRACE("(%p, %u, %p)\n", sa, dim, lbound);
144 if (!sa)
145 return E_INVALIDARG16;
147 if (!dim || dim > sa->cDims)
148 return DISP_E_BADINDEX;
150 *lbound = sa->rgsabound[sa->cDims - dim].lLbound;
152 return S_OK;
155 /******************************************************************************
156 * SafeArrayLock [OLE2DISP.21]
158 HRESULT WINAPI SafeArrayLock16(SAFEARRAY16 *sa)
160 TRACE("(%p)\n", sa);
162 if (!sa)
163 return E_INVALIDARG16;
165 return safearray_lock(sa);
168 /******************************************************************************
169 * SafeArrayUnlock [OLE2DISP.22]
171 HRESULT WINAPI SafeArrayUnlock16(SAFEARRAY16 *sa)
173 TRACE("(%p)\n", sa);
175 if (!sa)
176 return E_INVALIDARG16;
178 if (sa->cLocks == 0)
179 return E_UNEXPECTED;
181 sa->cLocks--;
182 return S_OK;
185 /******************************************************************************
186 * SafeArrayAccessData [OLE2DISP.23]
188 HRESULT WINAPI SafeArrayAccessData16(SAFEARRAY16 *sa, SEGPTR *data)
190 HRESULT hr;
192 TRACE("(%p, %p)\n", sa, data);
194 /* arguments are not tested, it crashes if any of them is NULL */
196 hr = safearray_lock(sa);
197 if (FAILED(hr))
198 return hr;
200 *data = sa->pvData;
201 return S_OK;
204 /******************************************************************************
205 * SafeArrayUnaccessData [OLE2DISP.24]
207 HRESULT WINAPI SafeArrayUnaccessData16(SAFEARRAY16 *sa)
209 TRACE("(%p)\n", sa);
210 return SafeArrayUnlock16(sa);
213 /******************************************************************************
214 * SafeArrayAllocDescriptor [OLE2DISP.38]
216 HRESULT WINAPI SafeArrayAllocDescriptor16(UINT16 dims, SEGPTR *ret)
218 SAFEARRAY16 *sa;
219 ULONG size;
221 TRACE("%u, %p\n", dims, ret);
223 if (!dims)
224 return E_INVALIDARG16;
226 size = sizeof(SAFEARRAY16) + sizeof(SAFEARRAYBOUND16) * (dims - 1);
227 *ret = safearray_alloc(size);
228 if (!*ret)
229 return E_OUTOFMEMORY16;
231 sa = MapSL(*ret);
232 sa->cDims = dims;
233 return S_OK;
236 /******************************************************************************
237 * SafeArrayAllocData [OLE2DISP.39]
239 HRESULT WINAPI SafeArrayAllocData16(SAFEARRAY16 *sa)
241 ULONG size;
243 TRACE("%p\n", sa);
245 if (!sa)
246 return E_INVALIDARG16;
248 size = safearray_getcellcount(sa);
249 sa->pvData = safearray_alloc(size * sa->cbElements);
250 return sa->pvData ? S_OK : E_OUTOFMEMORY16;
253 /******************************************************************************
254 * SafeArrayDestroyDescriptor [OLE2DISP.40]
256 HRESULT WINAPI SafeArrayDestroyDescriptor16(SEGPTR s)
258 TRACE("0x%08x\n", s);
260 if (s)
262 SAFEARRAY16 *sa = MapSL(s);
264 if (sa->cLocks)
265 return DISP_E_ARRAYISLOCKED;
267 safearray_free(s);
270 return S_OK;
273 /* This implementation of the BSTR API is 16-bit only. It
274 represents BSTR as a 16:16 far pointer, and the strings
275 as ISO-8859 */
277 /******************************************************************************
278 * BSTR_AllocBytes [Internal]
280 static BSTR16 BSTR_AllocBytes(int n)
282 void *ptr = HeapAlloc( GetProcessHeap(), 0, n );
283 return (BSTR16)MapLS(ptr);
286 /******************************************************************************
287 * BSTR_Free [INTERNAL]
289 static void BSTR_Free(BSTR16 in)
291 void *ptr = MapSL( (SEGPTR)in );
292 UnMapLS( (SEGPTR)in );
293 HeapFree( GetProcessHeap(), 0, ptr );
296 /******************************************************************************
297 * BSTR_GetAddr [INTERNAL]
299 static void* BSTR_GetAddr(BSTR16 in)
301 return in ? MapSL((SEGPTR)in) : 0;
304 /******************************************************************************
305 * SysAllocString [OLE2DISP.2]
307 * Create a BSTR16 from an OLESTR16 (16 Bit).
309 * PARAMS
310 * oleStr [I] Source to create BSTR16 from
312 * RETURNS
313 * Success: A BSTR16 allocated with SysAllocStringLen16().
314 * Failure: NULL, if oleStr is NULL.
316 BSTR16 WINAPI SysAllocString16(LPCOLESTR16 oleStr)
318 BSTR16 out;
320 if (!oleStr) return 0;
322 out = BSTR_AllocBytes(strlen(oleStr)+1);
323 if (!out) return 0;
324 strcpy(BSTR_GetAddr(out),oleStr);
325 return out;
328 /******************************************************************************
329 * SysReallocString [OLE2DISP.3]
331 * Change the length of a previously created BSTR16 (16 Bit).
333 * PARAMS
334 * pbstr [I] BSTR16 to change the length of
335 * oleStr [I] New source for pbstr
337 * RETURNS
338 * Success: 1
339 * Failure: 0.
341 * NOTES
342 * SysAllocStringStringLen16().
344 INT16 WINAPI SysReAllocString16(LPBSTR16 pbstr,LPCOLESTR16 oleStr)
346 BSTR16 new=SysAllocString16(oleStr);
347 BSTR_Free(*pbstr);
348 *pbstr=new;
349 return 1;
352 /******************************************************************************
353 * SysAllocStringLen [OLE2DISP.4]
355 * Create a BSTR16 from an OLESTR16 of a given character length (16 Bit).
357 * PARAMS
358 * oleStr [I] Source to create BSTR16 from
359 * len [I] Length of oleStr in wide characters
361 * RETURNS
362 * Success: A newly allocated BSTR16 from SysAllocStringByteLen16()
363 * Failure: NULL, if len is >= 0x80000000, or memory allocation fails.
365 * NOTES
366 * See SysAllocStringByteLen16().
368 BSTR16 WINAPI SysAllocStringLen16(const char *oleStr, int len)
370 BSTR16 out=BSTR_AllocBytes(len+1);
372 if (!out)
373 return 0;
376 * Copy the information in the buffer.
377 * Since it is valid to pass a NULL pointer here, we'll initialize the
378 * buffer to nul if it is the case.
380 if (oleStr != 0)
381 strcpy(BSTR_GetAddr(out),oleStr);
382 else
383 memset(BSTR_GetAddr(out), 0, len+1);
385 return out;
388 /******************************************************************************
389 * SysReAllocStringLen [OLE2DISP.5]
391 * Change the length of a previously created BSTR16 (16 Bit).
393 * PARAMS
394 * pbstr [I] BSTR16 to change the length of
395 * oleStr [I] New source for pbstr
396 * len [I] Length of oleStr in characters
398 * RETURNS
399 * Success: 1. The size of pbstr is updated.
400 * Failure: 0, if len >= 0x8000 or memory allocation fails.
402 * NOTES
403 * See SysAllocStringByteLen16().
404 * *pbstr may be changed by this function.
406 int WINAPI SysReAllocStringLen16(BSTR16 *old,const char *in,int len)
408 /* FIXME: Check input length */
409 BSTR16 new=SysAllocStringLen16(in,len);
410 BSTR_Free(*old);
411 *old=new;
412 return 1;
415 /******************************************************************************
416 * SysFreeString [OLE2DISP.6]
418 * Free a BSTR16 (16 Bit).
420 * PARAMS
421 * str [I] String to free.
423 * RETURNS
424 * Nothing.
426 void WINAPI SysFreeString16(BSTR16 str)
428 BSTR_Free(str);
431 /******************************************************************************
432 * SysStringLen [OLE2DISP.7]
434 * Get the allocated length of a BSTR16 in characters (16 Bit).
436 * PARAMS
437 * str [I] BSTR16 to find the length of
439 * RETURNS
440 * The allocated length of str, or 0 if str is NULL.
442 int WINAPI SysStringLen16(BSTR16 str)
444 return strlen(BSTR_GetAddr(str));
447 /******************************************************************************
448 * VariantChangeType [OLE2DISP.12]
450 HRESULT WINAPI VariantChangeType16(VARIANTARG *vargDest, VARIANTARG *varSrc, unsigned short flags, VARTYPE vt)
452 FIXME("stub: (%p, %p, %d, %d)\n", vargDest, varSrc, flags, vt);
453 return E_NOTIMPL;
457 /******************************************************************************
458 * CreateDispTypeInfo [OLE2DISP.31]
460 HRESULT WINAPI CreateDispTypeInfo16(
461 INTERFACEDATA *pidata,
462 LCID lcid,
463 ITypeInfo **pptinfo)
465 FIXME("(%p,%d,%p),stub\n",pidata,lcid,pptinfo);
466 return E_NOTIMPL;
469 /******************************************************************************
470 * CreateStdDispatch [OLE2DISP.32]
472 HRESULT WINAPI CreateStdDispatch16(
473 IUnknown* punkOuter,
474 void* pvThis,
475 ITypeInfo* ptinfo,
476 IUnknown** ppunkStdDisp)
478 FIXME("(%p,%p,%p,%p),stub\n",punkOuter, pvThis, ptinfo,
479 ppunkStdDisp);
480 return 0;
483 /******************************************************************************
484 * RegisterActiveObject [OLE2DISP.35]
486 HRESULT WINAPI RegisterActiveObject16(
487 IUnknown *punk, REFCLSID rclsid, DWORD dwFlags, unsigned long *pdwRegister
489 FIXME("(%p,%s,0x%08x,%p):stub\n",punk,debugstr_guid(rclsid),dwFlags,pdwRegister);
490 return E_NOTIMPL;
493 /******************************************************************************
494 * VariantChangeTypeEx [OLE2DISP.108]
496 HRESULT WINAPI VariantChangeTypeEx16(VARIANTARG *dest, const VARIANTARG *src, LCID lcid, USHORT flags, VARTYPE vt)
498 FIXME("stub: %p %p %d %d %d\n", dest, src, lcid, flags, vt);
499 return E_INVALIDARG;
502 /******************************************************************************
503 * SetErrorInfo [OLE2DISP.110]
505 HRESULT WINAPI SetErrorInfo16(ULONG dwReserved, IErrorInfo *perrinfo)
507 FIXME("stub: (%d, %p)\n", dwReserved, perrinfo);
508 return E_INVALIDARG;
511 /******************************************************************************
512 * VariantInit [OLE2DISP.8]
514 void WINAPI VariantInit16(VARIANTARG16 *v)
516 TRACE("(%p)\n", v);
517 v->vt = VT_EMPTY;