| /* |
| * OLE2DISP library |
| * |
| * Copyright 1995 Martin von Loewis |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public |
| * License as published by the Free Software Foundation; either |
| * version 2.1 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with this library; if not, write to the Free Software |
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA |
| */ |
| |
| #include "config.h" |
| |
| #include <stdarg.h> |
| #include <string.h> |
| |
| #include "windef.h" |
| #include "winbase.h" |
| #include "wingdi.h" |
| #include "winuser.h" |
| #include "ole2.h" |
| #include "oleauto.h" |
| #include "winerror.h" |
| #include "wownt32.h" |
| #include "wine/windef16.h" |
| #include "wine/winbase16.h" |
| |
| #include "ole2disp.h" |
| |
| #include "wine/debug.h" |
| |
| WINE_DEFAULT_DEBUG_CHANNEL(ole); |
| |
| #define E_OUTOFMEMORY16 MAKE_SCODE(SEVERITY_ERROR, FACILITY_NULL, 2) |
| #define E_INVALIDARG16 MAKE_SCODE(SEVERITY_ERROR, FACILITY_NULL, 3) |
| |
| /* 16-bit SAFEARRAY implementation */ |
| typedef struct tagSAFEARRAYBOUND16 |
| { |
| ULONG cElements; |
| LONG lLbound; |
| } SAFEARRAYBOUND16; |
| |
| typedef struct tagSAFEARRAY16 |
| { |
| USHORT cDims; |
| USHORT fFeatures; |
| USHORT cbElements; |
| USHORT cLocks; |
| ULONG handle; |
| SEGPTR pvData; |
| SAFEARRAYBOUND16 rgsabound[1]; |
| } SAFEARRAY16; |
| |
| static SEGPTR safearray_alloc(ULONG size) |
| { |
| HANDLE16 h; |
| return WOWGlobalAllocLock16(GPTR, size, &h); |
| } |
| |
| static void safearray_free(SEGPTR ptr) |
| { |
| WOWGlobalUnlockFree16(ptr); |
| } |
| |
| static ULONG safearray_getcellcount(const SAFEARRAY16 *sa) |
| { |
| const SAFEARRAYBOUND16 *sab = sa->rgsabound; |
| USHORT count = sa->cDims; |
| ULONG cells = 1; |
| |
| while (count--) |
| { |
| if (!sab->cElements) |
| return 0; |
| cells *= sab->cElements; |
| sab++; |
| } |
| |
| return cells; |
| } |
| |
| static HRESULT safearray_lock(SAFEARRAY16 *sa) |
| { |
| if (sa->cLocks == 0xffff) |
| return E_UNEXPECTED; |
| |
| sa->cLocks++; |
| return S_OK; |
| } |
| |
| /****************************************************************************** |
| * SafeArrayGetDim [OLE2DISP.17] |
| */ |
| USHORT WINAPI SafeArrayGetDim16(SAFEARRAY16 *sa) |
| { |
| TRACE("(%p)\n", sa); |
| return sa->cDims; |
| } |
| |
| /****************************************************************************** |
| * SafeArrayGetElemsize [OLE2DISP.18] |
| */ |
| USHORT WINAPI SafeArrayGetElemsize16(SAFEARRAY16 *sa) |
| { |
| TRACE("(%p)\n", sa); |
| return sa->cbElements; |
| } |
| |
| /****************************************************************************** |
| * SafeArrayLock [OLE2DISP.21] |
| */ |
| HRESULT WINAPI SafeArrayLock16(SAFEARRAY16 *sa) |
| { |
| TRACE("(%p)\n", sa); |
| |
| if (!sa) |
| return E_INVALIDARG16; |
| |
| return safearray_lock(sa); |
| } |
| |
| /****************************************************************************** |
| * SafeArrayUnlock [OLE2DISP.22] |
| */ |
| HRESULT WINAPI SafeArrayUnlock16(SAFEARRAY16 *sa) |
| { |
| TRACE("(%p)\n", sa); |
| |
| if (!sa) |
| return E_INVALIDARG16; |
| |
| if (sa->cLocks == 0) |
| return E_UNEXPECTED; |
| |
| sa->cLocks--; |
| return S_OK; |
| } |
| |
| /****************************************************************************** |
| * SafeArrayAccessData [OLE2DISP.23] |
| */ |
| HRESULT WINAPI SafeArrayAccessData16(SAFEARRAY16 *sa, SEGPTR *data) |
| { |
| HRESULT hr; |
| |
| TRACE("(%p, %p)\n", sa, data); |
| |
| /* arguments are not tested, it crashes if any of them is NULL */ |
| |
| hr = safearray_lock(sa); |
| if (FAILED(hr)) |
| return hr; |
| |
| *data = sa->pvData; |
| return S_OK; |
| } |
| |
| /****************************************************************************** |
| * SafeArrayUnaccessData [OLE2DISP.24] |
| */ |
| HRESULT WINAPI SafeArrayUnaccessData16(SAFEARRAY16 *sa) |
| { |
| TRACE("(%p)\n", sa); |
| return SafeArrayUnlock16(sa); |
| } |
| |
| /****************************************************************************** |
| * SafeArrayAllocDescriptor [OLE2DISP.38] |
| */ |
| HRESULT WINAPI SafeArrayAllocDescriptor16(UINT16 dims, SEGPTR *ret) |
| { |
| SAFEARRAY16 *sa; |
| ULONG size; |
| |
| TRACE("%u, %p\n", dims, ret); |
| |
| if (!dims) |
| return E_INVALIDARG16; |
| |
| size = sizeof(SAFEARRAY16) + sizeof(SAFEARRAYBOUND16) * (dims - 1); |
| *ret = safearray_alloc(size); |
| if (!*ret) |
| return E_OUTOFMEMORY16; |
| |
| sa = MapSL(*ret); |
| sa->cDims = dims; |
| return S_OK; |
| } |
| |
| /****************************************************************************** |
| * SafeArrayAllocData [OLE2DISP.39] |
| */ |
| HRESULT WINAPI SafeArrayAllocData16(SAFEARRAY16 *sa) |
| { |
| ULONG size; |
| |
| TRACE("%p\n", sa); |
| |
| if (!sa) |
| return E_INVALIDARG16; |
| |
| size = safearray_getcellcount(sa); |
| sa->pvData = safearray_alloc(size * sa->cbElements); |
| return sa->pvData ? S_OK : E_OUTOFMEMORY16; |
| } |
| |
| /****************************************************************************** |
| * SafeArrayDestroyDescriptor [OLE2DISP.40] |
| */ |
| HRESULT WINAPI SafeArrayDestroyDescriptor16(SEGPTR s) |
| { |
| TRACE("0x%08x\n", s); |
| |
| if (s) |
| { |
| SAFEARRAY16 *sa = MapSL(s); |
| |
| if (sa->cLocks) |
| return DISP_E_ARRAYISLOCKED; |
| |
| safearray_free(s); |
| } |
| |
| return S_OK; |
| } |
| |
| /* This implementation of the BSTR API is 16-bit only. It |
| represents BSTR as a 16:16 far pointer, and the strings |
| as ISO-8859 */ |
| |
| /****************************************************************************** |
| * BSTR_AllocBytes [Internal] |
| */ |
| static BSTR16 BSTR_AllocBytes(int n) |
| { |
| void *ptr = HeapAlloc( GetProcessHeap(), 0, n ); |
| return (BSTR16)MapLS(ptr); |
| } |
| |
| /****************************************************************************** |
| * BSTR_Free [INTERNAL] |
| */ |
| static void BSTR_Free(BSTR16 in) |
| { |
| void *ptr = MapSL( (SEGPTR)in ); |
| UnMapLS( (SEGPTR)in ); |
| HeapFree( GetProcessHeap(), 0, ptr ); |
| } |
| |
| /****************************************************************************** |
| * BSTR_GetAddr [INTERNAL] |
| */ |
| static void* BSTR_GetAddr(BSTR16 in) |
| { |
| return in ? MapSL((SEGPTR)in) : 0; |
| } |
| |
| /****************************************************************************** |
| * SysAllocString [OLE2DISP.2] |
| * |
| * Create a BSTR16 from an OLESTR16 (16 Bit). |
| * |
| * PARAMS |
| * oleStr [I] Source to create BSTR16 from |
| * |
| * RETURNS |
| * Success: A BSTR16 allocated with SysAllocStringLen16(). |
| * Failure: NULL, if oleStr is NULL. |
| */ |
| BSTR16 WINAPI SysAllocString16(LPCOLESTR16 oleStr) |
| { |
| BSTR16 out; |
| |
| if (!oleStr) return 0; |
| |
| out = BSTR_AllocBytes(strlen(oleStr)+1); |
| if (!out) return 0; |
| strcpy(BSTR_GetAddr(out),oleStr); |
| return out; |
| } |
| |
| /****************************************************************************** |
| * SysReallocString [OLE2DISP.3] |
| * |
| * Change the length of a previously created BSTR16 (16 Bit). |
| * |
| * PARAMS |
| * pbstr [I] BSTR16 to change the length of |
| * oleStr [I] New source for pbstr |
| * |
| * RETURNS |
| * Success: 1 |
| * Failure: 0. |
| * |
| * NOTES |
| * SysAllocStringStringLen16(). |
| */ |
| INT16 WINAPI SysReAllocString16(LPBSTR16 pbstr,LPCOLESTR16 oleStr) |
| { |
| BSTR16 new=SysAllocString16(oleStr); |
| BSTR_Free(*pbstr); |
| *pbstr=new; |
| return 1; |
| } |
| |
| /****************************************************************************** |
| * SysAllocStringLen [OLE2DISP.4] |
| * |
| * Create a BSTR16 from an OLESTR16 of a given character length (16 Bit). |
| * |
| * PARAMS |
| * oleStr [I] Source to create BSTR16 from |
| * len [I] Length of oleStr in wide characters |
| * |
| * RETURNS |
| * Success: A newly allocated BSTR16 from SysAllocStringByteLen16() |
| * Failure: NULL, if len is >= 0x80000000, or memory allocation fails. |
| * |
| * NOTES |
| * See SysAllocStringByteLen16(). |
| */ |
| BSTR16 WINAPI SysAllocStringLen16(const char *oleStr, int len) |
| { |
| BSTR16 out=BSTR_AllocBytes(len+1); |
| |
| if (!out) |
| return 0; |
| |
| /* |
| * Copy the information in the buffer. |
| * Since it is valid to pass a NULL pointer here, we'll initialize the |
| * buffer to nul if it is the case. |
| */ |
| if (oleStr != 0) |
| strcpy(BSTR_GetAddr(out),oleStr); |
| else |
| memset(BSTR_GetAddr(out), 0, len+1); |
| |
| return out; |
| } |
| |
| /****************************************************************************** |
| * SysReAllocStringLen [OLE2DISP.5] |
| * |
| * Change the length of a previously created BSTR16 (16 Bit). |
| * |
| * PARAMS |
| * pbstr [I] BSTR16 to change the length of |
| * oleStr [I] New source for pbstr |
| * len [I] Length of oleStr in characters |
| * |
| * RETURNS |
| * Success: 1. The size of pbstr is updated. |
| * Failure: 0, if len >= 0x8000 or memory allocation fails. |
| * |
| * NOTES |
| * See SysAllocStringByteLen16(). |
| * *pbstr may be changed by this function. |
| */ |
| int WINAPI SysReAllocStringLen16(BSTR16 *old,const char *in,int len) |
| { |
| /* FIXME: Check input length */ |
| BSTR16 new=SysAllocStringLen16(in,len); |
| BSTR_Free(*old); |
| *old=new; |
| return 1; |
| } |
| |
| /****************************************************************************** |
| * SysFreeString [OLE2DISP.6] |
| * |
| * Free a BSTR16 (16 Bit). |
| * |
| * PARAMS |
| * str [I] String to free. |
| * |
| * RETURNS |
| * Nothing. |
| */ |
| void WINAPI SysFreeString16(BSTR16 str) |
| { |
| BSTR_Free(str); |
| } |
| |
| /****************************************************************************** |
| * SysStringLen [OLE2DISP.7] |
| * |
| * Get the allocated length of a BSTR16 in characters (16 Bit). |
| * |
| * PARAMS |
| * str [I] BSTR16 to find the length of |
| * |
| * RETURNS |
| * The allocated length of str, or 0 if str is NULL. |
| */ |
| int WINAPI SysStringLen16(BSTR16 str) |
| { |
| return strlen(BSTR_GetAddr(str)); |
| } |
| |
| /****************************************************************************** |
| * VariantChangeType [OLE2DISP.12] |
| */ |
| HRESULT WINAPI VariantChangeType16(VARIANTARG *vargDest, VARIANTARG *varSrc, unsigned short flags, VARTYPE vt) |
| { |
| FIXME("stub: (%p, %p, %d, %d)\n", vargDest, varSrc, flags, vt); |
| return E_NOTIMPL; |
| } |
| |
| |
| /****************************************************************************** |
| * CreateDispTypeInfo [OLE2DISP.31] |
| */ |
| HRESULT WINAPI CreateDispTypeInfo16( |
| INTERFACEDATA *pidata, |
| LCID lcid, |
| ITypeInfo **pptinfo) |
| { |
| FIXME("(%p,%d,%p),stub\n",pidata,lcid,pptinfo); |
| return E_NOTIMPL; |
| } |
| |
| /****************************************************************************** |
| * CreateStdDispatch [OLE2DISP.32] |
| */ |
| HRESULT WINAPI CreateStdDispatch16( |
| IUnknown* punkOuter, |
| void* pvThis, |
| ITypeInfo* ptinfo, |
| IUnknown** ppunkStdDisp) |
| { |
| FIXME("(%p,%p,%p,%p),stub\n",punkOuter, pvThis, ptinfo, |
| ppunkStdDisp); |
| return 0; |
| } |
| |
| /****************************************************************************** |
| * RegisterActiveObject [OLE2DISP.35] |
| */ |
| HRESULT WINAPI RegisterActiveObject16( |
| IUnknown *punk, REFCLSID rclsid, DWORD dwFlags, unsigned long *pdwRegister |
| ) { |
| FIXME("(%p,%s,0x%08x,%p):stub\n",punk,debugstr_guid(rclsid),dwFlags,pdwRegister); |
| return E_NOTIMPL; |
| } |
| |
| /****************************************************************************** |
| * VariantChangeTypeEx [OLE2DISP.108] |
| */ |
| HRESULT WINAPI VariantChangeTypeEx16(VARIANTARG *dest, const VARIANTARG *src, LCID lcid, USHORT flags, VARTYPE vt) |
| { |
| FIXME("stub: %p %p %d %d %d\n", dest, src, lcid, flags, vt); |
| return E_INVALIDARG; |
| } |
| |
| /****************************************************************************** |
| * SetErrorInfo [OLE2DISP.110] |
| */ |
| HRESULT WINAPI SetErrorInfo16(ULONG dwReserved, IErrorInfo *perrinfo) |
| { |
| FIXME("stub: (%d, %p)\n", dwReserved, perrinfo); |
| return E_INVALIDARG; |
| } |
| |
| /****************************************************************************** |
| * VariantInit [OLE2DISP.8] |
| */ |
| void WINAPI VariantInit16(VARIANTARG16 *v) |
| { |
| TRACE("(%p)\n", v); |
| v->vt = VT_EMPTY; |
| } |