From d8a1cb88e7515e4c4a5ecf29986f6fd6eaa5ec3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9=20van=20Geldorp?= Date: Fri, 31 Dec 2004 15:28:42 +0000 Subject: [PATCH] Import and merge Wine-20041201 svn path=/trunk/; revision=12579 --- reactos/lib/oleaut32/Makefile.in | 44 + reactos/lib/oleaut32/Makefile.ros-template | 21 + reactos/lib/oleaut32/connpt.c | 632 + reactos/lib/oleaut32/connpt.h | 24 + reactos/lib/oleaut32/cursoricon.h | 89 + reactos/lib/oleaut32/dispatch.c | 456 + reactos/lib/oleaut32/hash.c | 644 + reactos/lib/oleaut32/makefile | 9 + reactos/lib/oleaut32/oaidl_p.c | 13781 +++++++++++++++++++ reactos/lib/oleaut32/ole2disp.c | 250 + reactos/lib/oleaut32/ole2disp.h | 42 + reactos/lib/oleaut32/ole2disp.spec | 135 + reactos/lib/oleaut32/oleaut.c | 755 + reactos/lib/oleaut32/oleaut32.rc | 47 + reactos/lib/oleaut32/oleaut32.spec | 416 + reactos/lib/oleaut32/oleaut32_Cz.rc | 31 + reactos/lib/oleaut32/oleaut32_De.rc | 31 + reactos/lib/oleaut32/oleaut32_Dk.rc | 31 + reactos/lib/oleaut32/oleaut32_En.rc | 31 + reactos/lib/oleaut32/oleaut32_Es.rc | 31 + reactos/lib/oleaut32/oleaut32_Fr.rc | 31 + reactos/lib/oleaut32/oleaut32_Hu.rc | 31 + reactos/lib/oleaut32/oleaut32_It.rc | 31 + reactos/lib/oleaut32/oleaut32_Nl.rc | 31 + reactos/lib/oleaut32/oleaut32_No.rc | 31 + reactos/lib/oleaut32/oleaut32_Pl.rc | 32 + reactos/lib/oleaut32/oleaut32_Pt.rc | 31 + reactos/lib/oleaut32/oleaut32_Sv.rc | 31 + reactos/lib/oleaut32/oleaut32_Th.rc | 31 + reactos/lib/oleaut32/olefont.c | 2143 +++ reactos/lib/oleaut32/olepicture.c | 2046 +++ reactos/lib/oleaut32/regsvr.c | 580 + reactos/lib/oleaut32/resource.h | 46 + reactos/lib/oleaut32/safearray.c | 1734 +++ reactos/lib/oleaut32/stubs.c | 66 + reactos/lib/oleaut32/tmarshal.c | 1822 +++ reactos/lib/oleaut32/tmarshal.h | 24 + reactos/lib/oleaut32/typelib.c | 5923 ++++++++ reactos/lib/oleaut32/typelib.h | 600 + reactos/lib/oleaut32/typelib.spec | 12 + reactos/lib/oleaut32/typelib16.c | 180 + reactos/lib/oleaut32/typelib2.c | 3913 ++++++ reactos/lib/oleaut32/usrmarshal.c | 1181 ++ reactos/lib/oleaut32/varformat.c | 2412 ++++ reactos/lib/oleaut32/variant.c | 4401 ++++++ reactos/lib/oleaut32/variant.h | 435 + reactos/lib/oleaut32/vartype.c | 6556 +++++++++ reactos/lib/oleaut32/version.rc | 23 + 48 files changed, 51877 insertions(+) create mode 100644 reactos/lib/oleaut32/Makefile.in create mode 100644 reactos/lib/oleaut32/Makefile.ros-template create mode 100644 reactos/lib/oleaut32/connpt.c create mode 100644 reactos/lib/oleaut32/connpt.h create mode 100644 reactos/lib/oleaut32/cursoricon.h create mode 100644 reactos/lib/oleaut32/dispatch.c create mode 100644 reactos/lib/oleaut32/hash.c create mode 100644 reactos/lib/oleaut32/makefile create mode 100644 reactos/lib/oleaut32/oaidl_p.c create mode 100644 reactos/lib/oleaut32/ole2disp.c create mode 100644 reactos/lib/oleaut32/ole2disp.h create mode 100644 reactos/lib/oleaut32/ole2disp.spec create mode 100644 reactos/lib/oleaut32/oleaut.c create mode 100644 reactos/lib/oleaut32/oleaut32.rc create mode 100644 reactos/lib/oleaut32/oleaut32.spec create mode 100644 reactos/lib/oleaut32/oleaut32_Cz.rc create mode 100644 reactos/lib/oleaut32/oleaut32_De.rc create mode 100644 reactos/lib/oleaut32/oleaut32_Dk.rc create mode 100644 reactos/lib/oleaut32/oleaut32_En.rc create mode 100644 reactos/lib/oleaut32/oleaut32_Es.rc create mode 100644 reactos/lib/oleaut32/oleaut32_Fr.rc create mode 100644 reactos/lib/oleaut32/oleaut32_Hu.rc create mode 100644 reactos/lib/oleaut32/oleaut32_It.rc create mode 100644 reactos/lib/oleaut32/oleaut32_Nl.rc create mode 100644 reactos/lib/oleaut32/oleaut32_No.rc create mode 100644 reactos/lib/oleaut32/oleaut32_Pl.rc create mode 100644 reactos/lib/oleaut32/oleaut32_Pt.rc create mode 100644 reactos/lib/oleaut32/oleaut32_Sv.rc create mode 100644 reactos/lib/oleaut32/oleaut32_Th.rc create mode 100644 reactos/lib/oleaut32/olefont.c create mode 100644 reactos/lib/oleaut32/olepicture.c create mode 100644 reactos/lib/oleaut32/regsvr.c create mode 100644 reactos/lib/oleaut32/resource.h create mode 100644 reactos/lib/oleaut32/safearray.c create mode 100644 reactos/lib/oleaut32/stubs.c create mode 100644 reactos/lib/oleaut32/tmarshal.c create mode 100644 reactos/lib/oleaut32/tmarshal.h create mode 100644 reactos/lib/oleaut32/typelib.c create mode 100644 reactos/lib/oleaut32/typelib.h create mode 100644 reactos/lib/oleaut32/typelib.spec create mode 100644 reactos/lib/oleaut32/typelib16.c create mode 100644 reactos/lib/oleaut32/typelib2.c create mode 100644 reactos/lib/oleaut32/usrmarshal.c create mode 100644 reactos/lib/oleaut32/varformat.c create mode 100644 reactos/lib/oleaut32/variant.c create mode 100644 reactos/lib/oleaut32/variant.h create mode 100644 reactos/lib/oleaut32/vartype.c create mode 100644 reactos/lib/oleaut32/version.rc diff --git a/reactos/lib/oleaut32/Makefile.in b/reactos/lib/oleaut32/Makefile.in new file mode 100644 index 00000000000..b53541c530d --- /dev/null +++ b/reactos/lib/oleaut32/Makefile.in @@ -0,0 +1,44 @@ +EXTRADEFS = -D_OLEAUT32_ -DCOM_NO_WINDOWS_H +TOPSRCDIR = @top_srcdir@ +TOPOBJDIR = ../.. +SRCDIR = @srcdir@ +VPATH = @srcdir@ +MODULE = oleaut32.dll +IMPORTS = ole32 rpcrt4 user32 gdi32 advapi32 kernel32 ntdll +DELAYIMPORTS = comctl32 +EXTRALIBS = $(LIBUNICODE) -luuid + +C_SRCS = \ + connpt.c \ + dispatch.c \ + hash.c \ + oaidl_p.c \ + oleaut.c \ + olefont.c \ + olepicture.c \ + regsvr.c \ + safearray.c \ + stubs.c \ + tmarshal.c \ + typelib.c \ + typelib2.c \ + usrmarshal.c \ + varformat.c \ + variant.c \ + vartype.c + +C_SRCS16 = \ + ole2disp.c \ + typelib16.c + +SPEC_SRCS16 = \ + ole2disp.spec \ + typelib.spec + +RC_SRCS = oleaut32.rc + +SUBDIRS = tests + +@MAKE_DLL_RULES@ + +### Dependencies: diff --git a/reactos/lib/oleaut32/Makefile.ros-template b/reactos/lib/oleaut32/Makefile.ros-template new file mode 100644 index 00000000000..2e4659a9191 --- /dev/null +++ b/reactos/lib/oleaut32/Makefile.ros-template @@ -0,0 +1,21 @@ +# $Id: Makefile.ros-template 12052 2004-12-12 18:01:23Z navaraf $ + +TARGET_NAME = oleaut32 + +TARGET_OBJECTS = @C_SRCS@ + +TARGET_CFLAGS = @EXTRADEFS@ -D__REACTOS__ + +TARGET_SDKLIBS = @IMPORTS@ winmm.a wine.a wine_uuid.a wine_unicode.a ntdll.a + +TARGET_BASE = $(TARGET_BASE_LIB_OLEAUT32) + +TARGET_RC_SRCS = @RC_SRCS@ +TARGET_RC_BINSRC = @RC_BINSRC@ +TARGET_RC_BINARIES = @RC_BINARIES@ + +default: all + +DEP_OBJECTS = $(TARGET_OBJECTS) + +include $(TOOLS_PATH)/depend.mk diff --git a/reactos/lib/oleaut32/connpt.c b/reactos/lib/oleaut32/connpt.c new file mode 100644 index 00000000000..c820abf913c --- /dev/null +++ b/reactos/lib/oleaut32/connpt.c @@ -0,0 +1,632 @@ +/* + * Implementation of a generic ConnectionPoint object. + * + * Copyright 2000 Huw D M Davies for CodeWeavers + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * NOTES: + * See one exported function here is CreateConnectionPoint, see + * comments just above that function for information. + */ + +#include +#include +#include + +#define COBJMACROS + +#include "winerror.h" +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" +#include "ole2.h" +#include "olectl.h" +#include "connpt.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(ole); + +#define MAXSINKS 10 + +/************************************************************************ + * Implementation of IConnectionPoint + */ +typedef struct ConnectionPointImpl { + + IConnectionPointVtbl *lpvtbl; + + /* IUnknown of our main object*/ + IUnknown *Obj; + + /* Reference count */ + DWORD ref; + + /* IID of sink interface */ + IID iid; + + /* Array of sink IUnknowns */ + IUnknown **sinks; + DWORD maxSinks; + + DWORD nSinks; +} ConnectionPointImpl; + +static IConnectionPointVtbl ConnectionPointImpl_VTable; + + +/************************************************************************ + * Implementation of IEnumConnections + */ +typedef struct EnumConnectionsImpl { + + IEnumConnectionsVtbl *lpvtbl; + + DWORD ref; + + /* IUnknown of ConnectionPoint, used for ref counting */ + IUnknown *pUnk; + + /* Connection Data */ + CONNECTDATA *pCD; + DWORD nConns; + + /* Next connection to enumerate from */ + DWORD nCur; + +} EnumConnectionsImpl; + +static EnumConnectionsImpl *EnumConnectionsImpl_Construct(IUnknown *pUnk, + DWORD nSinks, + CONNECTDATA *pCD); + + +/************************************************************************ + * ConnectionPointImpl_Construct + */ +static ConnectionPointImpl *ConnectionPointImpl_Construct(IUnknown *pUnk, + REFIID riid) +{ + ConnectionPointImpl *Obj; + + Obj = HeapAlloc(GetProcessHeap(), 0, sizeof(*Obj)); + Obj->lpvtbl = &ConnectionPointImpl_VTable; + Obj->Obj = pUnk; + Obj->ref = 1; + Obj->iid = *riid; + Obj->maxSinks = MAXSINKS; + Obj->sinks = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + sizeof(IUnknown*) * MAXSINKS); + Obj->nSinks = 0; + return Obj; +} + +/************************************************************************ + * ConnectionPointImpl_Destroy + */ +static void ConnectionPointImpl_Destroy(ConnectionPointImpl *Obj) +{ + DWORD i; + for(i = 0; i < Obj->maxSinks; i++) { + if(Obj->sinks[i]) { + IUnknown_Release(Obj->sinks[i]); + Obj->sinks[i] = NULL; + } + } + HeapFree(GetProcessHeap(), 0, Obj->sinks); + HeapFree(GetProcessHeap(), 0, Obj); + return; +} + +static ULONG WINAPI ConnectionPointImpl_AddRef(IConnectionPoint* iface); +/************************************************************************ + * ConnectionPointImpl_QueryInterface (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static HRESULT WINAPI ConnectionPointImpl_QueryInterface( + IConnectionPoint* iface, + REFIID riid, + void** ppvObject) +{ + ConnectionPointImpl *This = (ConnectionPointImpl *)iface; + TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppvObject); + + /* + * Perform a sanity check on the parameters. + */ + if ( (This==0) || (ppvObject==0) ) + return E_INVALIDARG; + + /* + * Initialize the return parameter. + */ + *ppvObject = 0; + + /* + * Compare the riid with the interface IDs implemented by this object. + */ + if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0) + { + *ppvObject = (IConnectionPoint*)This; + } + else if (memcmp(&IID_IConnectionPoint, riid, sizeof(IID_IConnectionPoint)) == 0) + { + *ppvObject = (IConnectionPoint*)This; + } + + /* + * Check that we obtained an interface. + */ + if ((*ppvObject)==0) + { + FIXME("() : asking for un supported interface %s\n",debugstr_guid(riid)); + return E_NOINTERFACE; + } + + /* + * Query Interface always increases the reference count by one when it is + * successful + */ + ConnectionPointImpl_AddRef((IConnectionPoint*)This); + + return S_OK; +} + + +/************************************************************************ + * ConnectionPointImpl_AddRef (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static ULONG WINAPI ConnectionPointImpl_AddRef(IConnectionPoint* iface) +{ + ConnectionPointImpl *This = (ConnectionPointImpl *)iface; + TRACE("(%p)->(ref=%ld)\n", This, This->ref); + return InterlockedIncrement(&This->ref); +} + +/************************************************************************ + * ConnectionPointImpl_Release (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static ULONG WINAPI ConnectionPointImpl_Release( + IConnectionPoint* iface) +{ + ConnectionPointImpl *This = (ConnectionPointImpl *)iface; + ULONG ref; + TRACE("(%p)->(ref=%ld)\n", This, This->ref); + + /* + * Decrease the reference count on this object. + */ + ref = InterlockedDecrement(&This->ref); + + /* + * If the reference count goes down to 0, perform suicide. + */ + if (ref == 0) ConnectionPointImpl_Destroy(This); + + return ref; +} + +/************************************************************************ + * ConnectionPointImpl_GetConnectionInterface (IConnectionPoint) + * + */ +static HRESULT WINAPI ConnectionPointImpl_GetConnectionInterface( + IConnectionPoint *iface, + IID *piid) +{ + ConnectionPointImpl *This = (ConnectionPointImpl *)iface; + TRACE("(%p)->(%p) returning %s\n", This, piid, debugstr_guid(&(This->iid))); + *piid = This->iid; + return S_OK; +} + +/************************************************************************ + * ConnectionPointImpl_GetConnectionPointContainer (IConnectionPoint) + * + */ +static HRESULT WINAPI ConnectionPointImpl_GetConnectionPointContainer( + IConnectionPoint *iface, + IConnectionPointContainer **ppCPC) +{ + ConnectionPointImpl *This = (ConnectionPointImpl *)iface; + TRACE("(%p)->(%p)\n", This, ppCPC); + + return IUnknown_QueryInterface(This->Obj, + &IID_IConnectionPointContainer, + (LPVOID)ppCPC); +} + +/************************************************************************ + * ConnectionPointImpl_Advise (IConnectionPoint) + * + */ +static HRESULT WINAPI ConnectionPointImpl_Advise(IConnectionPoint *iface, + IUnknown *lpUnk, + DWORD *pdwCookie) +{ + DWORD i; + ConnectionPointImpl *This = (ConnectionPointImpl *)iface; + IUnknown *lpSink; + TRACE("(%p)->(%p, %p)\n", This, lpUnk, pdwCookie); + + *pdwCookie = 0; + if(FAILED(IUnknown_QueryInterface(lpUnk, &This->iid, (LPVOID)&lpSink))) + return CONNECT_E_CANNOTCONNECT; + + for(i = 0; i < This->maxSinks; i++) { + if(This->sinks[i] == NULL) + break; + } + if(i == This->maxSinks) { + This->maxSinks += MAXSINKS; + This->sinks = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->sinks, + This->maxSinks * sizeof(IUnknown *)); + } + This->sinks[i] = lpSink; + This->nSinks++; + *pdwCookie = i + 1; + return S_OK; +} + + +/************************************************************************ + * ConnectionPointImpl_Unadvise (IConnectionPoint) + * + */ +static HRESULT WINAPI ConnectionPointImpl_Unadvise(IConnectionPoint *iface, + DWORD dwCookie) +{ + ConnectionPointImpl *This = (ConnectionPointImpl *)iface; + TRACE("(%p)->(%ld)\n", This, dwCookie); + + if(dwCookie == 0 || dwCookie > This->maxSinks) return E_INVALIDARG; + + if(This->sinks[dwCookie-1] == NULL) return CONNECT_E_NOCONNECTION; + + IUnknown_Release(This->sinks[dwCookie-1]); + This->sinks[dwCookie-1] = NULL; + This->nSinks--; + return S_OK; +} + +/************************************************************************ + * ConnectionPointImpl_EnumConnections (IConnectionPoint) + * + */ +static HRESULT WINAPI ConnectionPointImpl_EnumConnections( + IConnectionPoint *iface, + LPENUMCONNECTIONS *ppEnum) +{ + ConnectionPointImpl *This = (ConnectionPointImpl *)iface; + CONNECTDATA *pCD; + DWORD i, nextslot; + EnumConnectionsImpl *EnumObj; + HRESULT hr; + + TRACE("(%p)->(%p)\n", This, ppEnum); + + *ppEnum = NULL; + + if(This->nSinks == 0) return OLE_E_NOCONNECTION; + + pCD = HeapAlloc(GetProcessHeap(), 0, sizeof(CONNECTDATA) * This->nSinks); + + for(i = 0, nextslot = 0; i < This->maxSinks; i++) { + if(This->sinks[i] != NULL) { + pCD[nextslot].pUnk = This->sinks[i]; + pCD[nextslot].dwCookie = i + 1; + nextslot++; + } + } + assert(nextslot == This->nSinks); + + /* Bump the ref count of this object up by one. It gets Released in + IEnumConnections_Release */ + IUnknown_AddRef((IUnknown*)This); + + EnumObj = EnumConnectionsImpl_Construct((IUnknown*)This, This->nSinks, pCD); + hr = IEnumConnections_QueryInterface((IEnumConnections*)EnumObj, + &IID_IEnumConnections, (LPVOID)ppEnum); + IEnumConnections_Release((IEnumConnections*)EnumObj); + + HeapFree(GetProcessHeap(), 0, pCD); + return hr; +} + +static IConnectionPointVtbl ConnectionPointImpl_VTable = +{ + ConnectionPointImpl_QueryInterface, + ConnectionPointImpl_AddRef, + ConnectionPointImpl_Release, + ConnectionPointImpl_GetConnectionInterface, + ConnectionPointImpl_GetConnectionPointContainer, + ConnectionPointImpl_Advise, + ConnectionPointImpl_Unadvise, + ConnectionPointImpl_EnumConnections +}; + + +static IEnumConnectionsVtbl EnumConnectionsImpl_VTable; +static ULONG WINAPI EnumConnectionsImpl_AddRef(IEnumConnections* iface); + +/************************************************************************ + * EnumConnectionsImpl_Construct + */ +static EnumConnectionsImpl *EnumConnectionsImpl_Construct(IUnknown *pUnk, + DWORD nSinks, + CONNECTDATA *pCD) +{ + EnumConnectionsImpl *Obj = HeapAlloc(GetProcessHeap(), 0, sizeof(*Obj)); + DWORD i; + + Obj->lpvtbl = &EnumConnectionsImpl_VTable; + Obj->ref = 1; + Obj->pUnk = pUnk; + Obj->pCD = HeapAlloc(GetProcessHeap(), 0, nSinks * sizeof(CONNECTDATA)); + Obj->nConns = nSinks; + Obj->nCur = 0; + + for(i = 0; i < nSinks; i++) { + Obj->pCD[i] = pCD[i]; + IUnknown_AddRef(Obj->pCD[i].pUnk); + } + return Obj; +} + +/************************************************************************ + * EnumConnectionsImpl_Destroy + */ +static void EnumConnectionsImpl_Destroy(EnumConnectionsImpl *Obj) +{ + DWORD i; + + for(i = 0; i < Obj->nConns; i++) + IUnknown_Release(Obj->pCD[i].pUnk); + + HeapFree(GetProcessHeap(), 0, Obj->pCD); + HeapFree(GetProcessHeap(), 0, Obj); + return; +} + +/************************************************************************ + * EnumConnectionsImpl_QueryInterface (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static HRESULT WINAPI EnumConnectionsImpl_QueryInterface( + IEnumConnections* iface, + REFIID riid, + void** ppvObject) +{ + ConnectionPointImpl *This = (ConnectionPointImpl *)iface; + TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppvObject); + + /* + * Perform a sanity check on the parameters. + */ + if ( (This==0) || (ppvObject==0) ) + return E_INVALIDARG; + + /* + * Initialize the return parameter. + */ + *ppvObject = 0; + + /* + * Compare the riid with the interface IDs implemented by this object. + */ + if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0) + { + *ppvObject = (IEnumConnections*)This; + } + else if (memcmp(&IID_IEnumConnections, riid, sizeof(IID_IEnumConnections)) == 0) + { + *ppvObject = (IEnumConnections*)This; + } + + /* + * Check that we obtained an interface. + */ + if ((*ppvObject)==0) + { + FIXME("() : asking for un supported interface %s\n",debugstr_guid(riid)); + return E_NOINTERFACE; + } + + /* + * Query Interface always increases the reference count by one when it is + * successful + */ + EnumConnectionsImpl_AddRef((IEnumConnections*)This); + + return S_OK; +} + + +/************************************************************************ + * EnumConnectionsImpl_AddRef (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static ULONG WINAPI EnumConnectionsImpl_AddRef(IEnumConnections* iface) +{ + EnumConnectionsImpl *This = (EnumConnectionsImpl *)iface; + ULONG ref; + TRACE("(%p)->(ref=%ld)\n", This, This->ref); + ref = InterlockedIncrement(&This->ref); + IUnknown_AddRef(This->pUnk); + return ref; +} + +/************************************************************************ + * EnumConnectionsImpl_Release (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static ULONG WINAPI EnumConnectionsImpl_Release(IEnumConnections* iface) +{ + EnumConnectionsImpl *This = (EnumConnectionsImpl *)iface; + ULONG ref; + TRACE("(%p)->(ref=%ld)\n", This, This->ref); + + IUnknown_Release(This->pUnk); + + /* + * Decrease the reference count on this object. + */ + ref = InterlockedDecrement(&This->ref); + + /* + * If the reference count goes down to 0, perform suicide. + */ + if (ref == 0) EnumConnectionsImpl_Destroy(This); + + return ref; +} + +/************************************************************************ + * EnumConnectionsImpl_Next (IEnumConnections) + * + */ +static HRESULT WINAPI EnumConnectionsImpl_Next(IEnumConnections* iface, + ULONG cConn, LPCONNECTDATA pCD, + ULONG *pEnum) +{ + EnumConnectionsImpl *This = (EnumConnectionsImpl *)iface; + DWORD nRet = 0; + TRACE("(%p)->(%ld, %p, %p)\n", This, cConn, pCD, pEnum); + + if(pEnum == NULL) { + if(cConn != 1) + return E_POINTER; + } else + *pEnum = 0; + + if(This->nCur >= This->nConns) + return S_FALSE; + + while(This->nCur < This->nConns && cConn) { + *pCD++ = This->pCD[This->nCur]; + IUnknown_AddRef(This->pCD[This->nCur].pUnk); + This->nCur++; + cConn--; + nRet++; + } + + if(pEnum) + *pEnum = nRet; + + return S_OK; +} + + +/************************************************************************ + * EnumConnectionsImpl_Skip (IEnumConnections) + * + */ +static HRESULT WINAPI EnumConnectionsImpl_Skip(IEnumConnections* iface, + ULONG cSkip) +{ + EnumConnectionsImpl *This = (EnumConnectionsImpl *)iface; + TRACE("(%p)->(%ld)\n", This, cSkip); + + if(This->nCur + cSkip >= This->nConns) + return S_FALSE; + + This->nCur += cSkip; + + return S_OK; +} + + +/************************************************************************ + * EnumConnectionsImpl_Reset (IEnumConnections) + * + */ +static HRESULT WINAPI EnumConnectionsImpl_Reset(IEnumConnections* iface) +{ + EnumConnectionsImpl *This = (EnumConnectionsImpl *)iface; + TRACE("(%p)\n", This); + + This->nCur = 0; + + return S_OK; +} + + +/************************************************************************ + * EnumConnectionsImpl_Clone (IEnumConnections) + * + */ +static HRESULT WINAPI EnumConnectionsImpl_Clone(IEnumConnections* iface, + LPENUMCONNECTIONS *ppEnum) +{ + EnumConnectionsImpl *This = (EnumConnectionsImpl *)iface; + EnumConnectionsImpl *newObj; + TRACE("(%p)->(%p)\n", This, ppEnum); + + newObj = EnumConnectionsImpl_Construct(This->pUnk, This->nConns, This->pCD); + newObj->nCur = This->nCur; + *ppEnum = (LPENUMCONNECTIONS)newObj; + IUnknown_AddRef(This->pUnk); + return S_OK; +} + +static IEnumConnectionsVtbl EnumConnectionsImpl_VTable = +{ + EnumConnectionsImpl_QueryInterface, + EnumConnectionsImpl_AddRef, + EnumConnectionsImpl_Release, + EnumConnectionsImpl_Next, + EnumConnectionsImpl_Skip, + EnumConnectionsImpl_Reset, + EnumConnectionsImpl_Clone +}; + +/************************************************************************ + * + * The exported function to create the connection point. + * NB not a windows API + * + * PARAMS + * pUnk [in] IUnknown of object to which the ConnectionPoint is associated. + * Needed to access IConnectionPointContainer. + * + * riid [in] IID of sink interface that this ConnectionPoint manages + * + * pCP [out] returns IConnectionPoint + * + */ +HRESULT CreateConnectionPoint(IUnknown *pUnk, REFIID riid, + IConnectionPoint **pCP) +{ + ConnectionPointImpl *Obj; + HRESULT hr; + + Obj = ConnectionPointImpl_Construct(pUnk, riid); + if(!Obj) return E_OUTOFMEMORY; + + hr = IConnectionPoint_QueryInterface((IConnectionPoint *)Obj, + &IID_IConnectionPoint, (LPVOID)pCP); + IConnectionPoint_Release((IConnectionPoint *)Obj); + return hr; +} diff --git a/reactos/lib/oleaut32/connpt.h b/reactos/lib/oleaut32/connpt.h new file mode 100644 index 00000000000..307e17d6ea3 --- /dev/null +++ b/reactos/lib/oleaut32/connpt.h @@ -0,0 +1,24 @@ +/* + * Copyright 2000 Huw D M Davies for CodeWeavers + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _CONNPT_H +#define _CONNPT_H + +HRESULT CreateConnectionPoint(IUnknown *pUnk, REFIID riid, IConnectionPoint **pCP); + +#endif /* _CONNPT_H */ diff --git a/reactos/lib/oleaut32/cursoricon.h b/reactos/lib/oleaut32/cursoricon.h new file mode 100644 index 00000000000..62f053cd997 --- /dev/null +++ b/reactos/lib/oleaut32/cursoricon.h @@ -0,0 +1,89 @@ +/* + * Cursor and icon definitions + * + * Copyright 1995 Alexandre Julliard + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __WINE_CURSORICON_H +#define __WINE_CURSORICON_H + +#include + +#include + +typedef struct +{ + BYTE bWidth; + BYTE bHeight; + BYTE bColorCount; + BYTE bReserved; +} ICONRESDIR; + +typedef struct +{ + WORD wWidth; + WORD wHeight; +} CURSORDIR; + +typedef struct +{ union + { ICONRESDIR icon; + CURSORDIR cursor; + } ResInfo; + WORD wPlanes; + WORD wBitCount; + DWORD dwBytesInRes; + WORD wResId; +} CURSORICONDIRENTRY; + +typedef struct +{ + WORD idReserved; + WORD idType; + WORD idCount; + CURSORICONDIRENTRY idEntries[1]; +} CURSORICONDIR; + +typedef struct { + BYTE bWidth; + BYTE bHeight; + BYTE bColorCount; + BYTE bReserved; + WORD xHotspot; + WORD yHotspot; + DWORD dwDIBSize; + DWORD dwDIBOffset; +} CURSORICONFILEDIRENTRY; + +typedef struct +{ + WORD idReserved; + WORD idType; + WORD idCount; + CURSORICONFILEDIRENTRY idEntries[1]; +} CURSORICONFILEDIR; + + +#include + +#define CID_RESOURCE 0x0001 +#define CID_WIN32 0x0004 +#define CID_NONSHARED 0x0008 + +extern void CURSORICON_FreeModuleIcons( HMODULE16 hModule ); + +#endif /* __WINE_CURSORICON_H */ diff --git a/reactos/lib/oleaut32/dispatch.c b/reactos/lib/oleaut32/dispatch.c new file mode 100644 index 00000000000..b3bc302c5df --- /dev/null +++ b/reactos/lib/oleaut32/dispatch.c @@ -0,0 +1,456 @@ +/** + * Dispatch API functions + * + * Copyright 2000 Francois Jacques, Macadamian Technologies Inc. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * TODO: Type coercion is implemented in variant.c but not called yet. + */ + +#include "config.h" + +#include +#include +#include +#include +#include + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "objbase.h" +#include "oleauto.h" +#include "winerror.h" +#include "winreg.h" +#include "winnls.h" /* for PRIMARYLANGID */ + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(ole); +WINE_DECLARE_DEBUG_CHANNEL(typelib); + +static IDispatch * WINAPI StdDispatch_Construct(IUnknown * punkOuter, void * pvThis, ITypeInfo * pTypeInfo); + +/****************************************************************************** + * DispInvoke (OLEAUT32.30) + * + * Call an object method using the information from its type library. + * + * RETURNS + * Success: S_OK. + * Failure: Returns DISP_E_EXCEPTION and updates pexcepinfo if an exception occurs. + * DISP_E_BADPARAMCOUNT if the number of parameters is incorrect. + * DISP_E_MEMBERNOTFOUND if the method does not exist. + * puArgErr is updated if a parameter error (see notes) occurs. + * Otherwise, returns the result of calling ITypeInfo_Invoke(). + * + * NOTES + * Parameter errors include the following: + *| DISP_E_BADVARTYPE + *| E_INVALIDARG An argument was invalid + *| DISP_E_TYPEMISMATCH, + *| DISP_E_OVERFLOW An argument was valid but could not be coerced + *| DISP_E_PARAMNOTOPTIONAL A non optional parameter was not passed + *| DISP_E_PARAMNOTFOUND A parameter was passed that was not expected by the method + * This call defers to ITypeInfo_Invoke(). + */ +HRESULT WINAPI DispInvoke( + VOID *_this, /* [in] Object to call method on */ + ITypeInfo *ptinfo, /* [in] Object type info */ + DISPID dispidMember, /* [in] DISPID of the member (e.g. from GetIDsOfNames()) */ + USHORT wFlags, /* [in] Kind of method call (DISPATCH_ flags from "oaidl.h") */ + DISPPARAMS *pparams, /* [in] Array of method arguments */ + VARIANT *pvarResult, /* [out] Destination for the result of the call */ + EXCEPINFO *pexcepinfo, /* [out] Destination for exception information */ + UINT *puArgErr) /* [out] Destination for bad argument */ +{ + /** + * TODO: + * For each param, call DispGetParam to perform type coercion + */ + FIXME("Coercion of arguments not implemented\n"); + + return ITypeInfo_Invoke(ptinfo, _this, dispidMember, wFlags, + pparams, pvarResult, pexcepinfo, puArgErr); +} + +/****************************************************************************** + * DispGetIDsOfNames (OLEAUT32.29) + * + * Convert a set of parameter names to DISPID's for DispInvoke(). + * + * RETURNS + * Success: S_OK. + * Failure: An HRESULT error code. + * + * NOTES + * This call defers to ITypeInfo_GetIDsOfNames(). The ITypeInfo interface passed + * as ptinfo contains the information to map names to DISPID's. + */ +HRESULT WINAPI DispGetIDsOfNames( + ITypeInfo *ptinfo, /* [in] Object's type info */ + OLECHAR **rgszNames, /* [in] Array of names to get DISPID's for */ + UINT cNames, /* [in] Number of names in rgszNames */ + DISPID *rgdispid) /* [out] Destination for converted DISPID's */ +{ + return ITypeInfo_GetIDsOfNames(ptinfo, rgszNames, cNames, rgdispid); +} + +/****************************************************************************** + * DispGetParam (OLEAUT32.28) + * + * Retrive a parameter from a DISPPARAMS structure and coerce it to the + * specified variant type. + * + * NOTES + * Coercion is done using system (0) locale. + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_PARAMNOTFOUND, if position is invalid. or + * DISP_E_TYPEMISMATCH, if the coercion failed. puArgErr is + * set to the index of the argument in pdispparams. + */ +HRESULT WINAPI DispGetParam( + DISPPARAMS *pdispparams, /* [in] Parameter list */ + UINT position, /* [in] Position of parameter to coerce in pdispparams */ + VARTYPE vtTarg, /* [in] Type of value to coerce to */ + VARIANT *pvarResult, /* [out] Destination for resulting variant */ + UINT *puArgErr) /* [out] Destination for error code */ +{ + /* position is counted backwards */ + UINT pos; + HRESULT hr; + + TRACE("position=%d, cArgs=%d, cNamedArgs=%d\n", + position, pdispparams->cArgs, pdispparams->cNamedArgs); + if (position < pdispparams->cArgs) { + /* positional arg? */ + pos = pdispparams->cArgs - position - 1; + } else { + /* FIXME: is this how to handle named args? */ + for (pos=0; poscNamedArgs; pos++) + if (pdispparams->rgdispidNamedArgs[pos] == position) break; + + if (pos==pdispparams->cNamedArgs) + return DISP_E_PARAMNOTFOUND; + } + hr = VariantChangeType(pvarResult, + &pdispparams->rgvarg[pos], + 0, vtTarg); + if (hr == DISP_E_TYPEMISMATCH) *puArgErr = pos; + return hr; +} + +/****************************************************************************** + * CreateStdDispatch [OLEAUT32.32] + * + * Create and return a standard IDispatch object. + * + * RETURNS + * Success: S_OK. ppunkStdDisp contains the new object. + * Failure: An HRESULT error code. + * + * NOTES + * Outer unknown appears to be completely ignored. + */ +HRESULT WINAPI CreateStdDispatch( + IUnknown* punkOuter, + void* pvThis, + ITypeInfo* ptinfo, + IUnknown** ppunkStdDisp) +{ + TRACE("(%p, %p, %p, %p)\n", punkOuter, pvThis, ptinfo, ppunkStdDisp); + + *ppunkStdDisp = (LPUNKNOWN)StdDispatch_Construct(punkOuter, pvThis, ptinfo); + if (!*ppunkStdDisp) + return E_OUTOFMEMORY; + return S_OK; +} + + +/****************************************************************************** + * IDispatch {OLEAUT32} + * + * NOTES + * The IDispatch interface provides a single interface to dispatch method calls, + * regardless of whether the object to be called is in or out of process, + * local or remote (e.g. being called over a network). This interface is late-bound + * (linked at run-time), as opposed to early-bound (linked at compile time). + * + * The interface is used by objects that wish to called by scripting + * languages such as VBA, in order to minimise the amount of COM and C/C++ + * knowledge required, or by objects that wish to live out of process from code + * that will call their methods. + * + * Method, property and parameter names can be localised. The details required to + * map names to methods and parameters are collected in a type library, usually + * output by an IDL compiler using the objects IDL description. This information is + * accessible programatically through the ITypeLib interface (for a type library), + * and the ITypeInfo interface (for an object within the type library). Type information + * can also be created at run-time using CreateDispTypeInfo(). + * + * WRAPPERS + * Instead of using IDispatch directly, there are several wrapper functions available + * to simplify the process of calling an objects methods through IDispatch. + * + * A standard implementation of an IDispatch object is created by calling + * CreateStdDispatch(). Numeric Id values for the parameters and methods (DISPID's) + * of an object of interest are retrieved by calling DispGetIDsOfNames(). DispGetParam() + * retrieves information about a particular parameter. Finally the DispInvoke() + * function is responsable for actually calling methods on an object. + * + * METHODS + */ + +typedef struct +{ + IDispatchVtbl *lpVtbl; + void * pvThis; + ITypeInfo * pTypeInfo; + ULONG ref; +} StdDispatch; + +/****************************************************************************** + * IDispatch_QueryInterface {OLEAUT32} + * + * See IUnknown_QueryInterface. + */ +static HRESULT WINAPI StdDispatch_QueryInterface( + LPDISPATCH iface, + REFIID riid, + void** ppvObject) +{ + StdDispatch *This = (StdDispatch *)iface; + TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppvObject); + + if (IsEqualIID(riid, &IID_IDispatch) || + IsEqualIID(riid, &IID_IUnknown)) + { + *ppvObject = (LPVOID)This; + IUnknown_AddRef((LPUNKNOWN)*ppvObject); + return S_OK; + } + return E_NOINTERFACE; +} + +/****************************************************************************** + * IDispatch_AddRef {OLEAUT32} + * + * See IUnknown_AddRef. + */ +static ULONG WINAPI StdDispatch_AddRef(LPDISPATCH iface) +{ + StdDispatch *This = (StdDispatch *)iface; + TRACE("()\n"); + + return InterlockedIncrement(&This->ref); +} + +/****************************************************************************** + * IDispatch_Release {OLEAUT32} + * + * See IUnknown_Release. + */ +static ULONG WINAPI StdDispatch_Release(LPDISPATCH iface) +{ + StdDispatch *This = (StdDispatch *)iface; + ULONG ref; + TRACE("(%p)->()\n", This); + + ref = InterlockedDecrement(&This->ref); + + if (ref == 0) + { + ITypeInfo_Release(This->pTypeInfo); + CoTaskMemFree(This); + } + + return ref; +} + +/****************************************************************************** + * IDispatch_GetTypeInfoCount {OLEAUT32} + * + * Get the count of type information in an IDispatch interface. + * + * PARAMS + * iface [I] IDispatch interface + * pctinfo [O] Destination for the count + * + * RETURNS + * Success: S_OK. pctinfo is updated with the count. This is always 1 if + * the object provides type information, and 0 if it does not. + * Failure: E_NOTIMPL. The object does not provide type information. + * + * NOTES + * See IDispatch() and IDispatch_GetTypeInfo(). + */ +static HRESULT WINAPI StdDispatch_GetTypeInfoCount(LPDISPATCH iface, UINT * pctinfo) +{ + StdDispatch *This = (StdDispatch *)iface; + TRACE("(%p)\n", pctinfo); + + *pctinfo = This->pTypeInfo ? 1 : 0; + return S_OK; +} + +/****************************************************************************** + * IDispatch_GetTypeInfo {OLEAUT32} + * + * Get type information from an IDispatch interface. + * + * PARAMS + * iface [I] IDispatch interface + * iTInfo [I] Index of type information. + * lcid [I] Locale of the type information to get + * ppTInfo [O] Destination for the ITypeInfo object + * + * RETURNS + * Success: S_OK. ppTInfo is updated with the objects type information + * Failure: DISP_E_BADINDEX, if iTInfo is any value other than 0. + * + * NOTES + * See IDispatch. + */ +static HRESULT WINAPI StdDispatch_GetTypeInfo(LPDISPATCH iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo) +{ + StdDispatch *This = (StdDispatch *)iface; + TRACE("(%d, %lx, %p)\n", iTInfo, lcid, ppTInfo); + + *ppTInfo = NULL; + if (iTInfo != 0) + return DISP_E_BADINDEX; + + if (This->pTypeInfo) + { + *ppTInfo = This->pTypeInfo; + ITypeInfo_AddRef(*ppTInfo); + } + return S_OK; +} + +/****************************************************************************** + * IDispatch_GetIDsOfNames {OLEAUT32} + * + * Convert a methods name and an optional set of parameter names into DISPID's + * for passing to IDispatch_Invoke(). + * + * PARAMS + * iface [I] IDispatch interface + * riid [I] Reserved, set to IID_NULL + * rgszNames [I] Name to convert + * cNames [I] Number of names in rgszNames + * lcid [I] Locale of the type information to convert from + * rgDispId [O] Destination for converted DISPID's. + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_UNKNOWNNAME, if any of the names is invalid. + * DISP_E_UNKNOWNLCID if lcid is invalid. + * Otherwise, an An HRESULT error code. + * + * NOTES + * This call defers to ITypeInfo_GetIDsOfNames(), using the ITypeInfo object + * contained within the IDispatch object. + * The first member of the names list must be a method name. The names following + * the method name are the parameters for that method. + */ +static HRESULT WINAPI StdDispatch_GetIDsOfNames(LPDISPATCH iface, REFIID riid, LPOLESTR * rgszNames, UINT cNames, LCID lcid, DISPID * rgDispId) +{ + StdDispatch *This = (StdDispatch *)iface; + TRACE("(%s, %p, %d, 0x%lx, %p)\n", debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId); + + if (!IsEqualGUID(riid, &IID_NULL)) + { + FIXME(" expected riid == IID_NULL\n"); + return E_INVALIDARG; + } + return DispGetIDsOfNames(This->pTypeInfo, rgszNames, cNames, rgDispId); +} + +/****************************************************************************** + * IDispatch_Invoke {OLEAUT32} + * + * Call an object method. + * + * PARAMS + * iface [I] IDispatch interface + * dispIdMember [I] DISPID of the method (from GetIDsOfNames()) + * riid [I] Reserved, set to IID_NULL + * lcid [I] Locale of the type information to convert parameters with + * wFlags, [I] Kind of method call (DISPATCH_ flags from "oaidl.h") + * pDispParams [I] Array of method arguments + * pVarResult [O] Destination for the result of the call + * pExcepInfo [O] Destination for exception information + * puArgErr [O] Destination for bad argument + * + * RETURNS + * Success: S_OK. + * Failure: See DispInvoke() for failure cases. + * + * NOTES + * See DispInvoke() and IDispatch(). + */ +static HRESULT WINAPI StdDispatch_Invoke(LPDISPATCH iface, DISPID dispIdMember, REFIID riid, LCID lcid, + WORD wFlags, DISPPARAMS * pDispParams, VARIANT * pVarResult, + EXCEPINFO * pExcepInfo, UINT * puArgErr) +{ + StdDispatch *This = (StdDispatch *)iface; + TRACE("(%ld, %s, 0x%lx, 0x%x, %p, %p, %p, %p)\n", dispIdMember, debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + + if (!IsEqualGUID(riid, &IID_NULL)) + { + FIXME(" expected riid == IID_NULL\n"); + return E_INVALIDARG; + } + return DispInvoke(This->pvThis, This->pTypeInfo, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); +} + +static IDispatchVtbl StdDispatch_VTable = +{ + StdDispatch_QueryInterface, + StdDispatch_AddRef, + StdDispatch_Release, + StdDispatch_GetTypeInfoCount, + StdDispatch_GetTypeInfo, + StdDispatch_GetIDsOfNames, + StdDispatch_Invoke +}; + +static IDispatch * WINAPI StdDispatch_Construct( + IUnknown * punkOuter, + void * pvThis, + ITypeInfo * pTypeInfo) +{ + StdDispatch * pStdDispatch; + + pStdDispatch = CoTaskMemAlloc(sizeof(StdDispatch)); + if (!pStdDispatch) + return (IDispatch *)pStdDispatch; + + pStdDispatch->lpVtbl = &StdDispatch_VTable; + pStdDispatch->pvThis = pvThis; + pStdDispatch->pTypeInfo = pTypeInfo; + pStdDispatch->ref = 1; + + /* we keep a reference to the type info so prevent it from + * being destroyed until we are done with it */ + ITypeInfo_AddRef(pTypeInfo); + + return (IDispatch *)pStdDispatch; +} diff --git a/reactos/lib/oleaut32/hash.c b/reactos/lib/oleaut32/hash.c new file mode 100644 index 00000000000..fa6fb544b22 --- /dev/null +++ b/reactos/lib/oleaut32/hash.c @@ -0,0 +1,644 @@ +/* + * Oleaut32 hash functions + * + * Copyright 1999 Corel Corporation + * Copyright 2001-2003 Jon Griffiths + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include + +#include "windef.h" +#include "winbase.h" +#include "winnls.h" +#include "objbase.h" +#include "oaidl.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(ole); + +static const unsigned char Lookup_16[128 * 3] = { + /* Common */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, + 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x00, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, + 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x56, 0x58, 0x55, 0x5A, + 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x56, 0x58, 0x55, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, + + /* Windows */ + 0x7F, 0x7F, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x7F, 0x89, 0x53, 0x8B, 0x8C, + 0x7F, 0x7F, 0x7F, 0x7F, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x96, 0x98, 0x99, + 0x53, 0x9B, 0x8C, 0x7F, 0x7F, 0x55, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x96, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, + 0x49, 0x49, 0x44, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0xD7, 0x4F, 0x55, 0x55, + 0x55, 0x55, 0x55, 0xDE, 0xDF, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x43, + 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0x44, 0x4E, 0x4F, 0x4F, 0x4F, + 0x4F, 0x4F, 0xF7, 0x4F, 0x55, 0x55, 0x55, 0x55, 0x55, 0xDE, 0x55, + + /* Mac */ + 0x41, 0x41, 0x43, 0x45, 0x4E, 0x4F, 0x55, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0x4E, 0x4F, 0x4F, 0x4F, + 0x4F, 0x4F, 0x55, 0x55, 0x55, 0x55, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0x41, 0x4F, 0xB0, 0xB1, 0xB2, 0xB3, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0x41, 0x4F, 0xBD, 0x41, 0x4F, 0xC0, + 0xC1, 0xC2, 0xC3, 0x46, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0x41, 0x41, 0x4F, + 0xCE, 0xCE, 0xD0, 0xD0, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0x55, 0x55, 0xDA, + 0xDB, 0xDC, 0xDD, 0x3F, 0x3F, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0x41, 0x45, 0x41, + 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0x4F, 0x4F, 0x3F, 0x4F, 0x55, 0x55, 0x55, + 0x49, 0x7F, 0xF7, 0x7F, 0xF9, 0xFA, 0xFB, 0x3F, 0xFD, 0xFE, 0x7F +}; + +static const unsigned char Lookup_32[128 * 3] = { + /* Common */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, + 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x00, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, + 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, + 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, + + /* Windows */ + 0x7F, 0x7F, 0x82, 0x7F, 0x84, 0x85, 0x86, 0x87, 0x7F, 0x89, 0x53, 0x8B, 0x53, + 0x54, 0x5A, 0x5A, 0x7F, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x96, 0x7F, 0x99, + 0x53, 0x9B, 0x53, 0x54, 0x5A, 0x5A, 0xA0, 0x7F, 0xA2, 0x4C, 0xA4, 0x41, 0xA6, + 0xA7, 0xA8, 0xA9, 0x53, 0xAB, 0xAC, 0x96, 0xAE, 0x5A, 0xB0, 0xB1, 0xB2, 0x4C, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x41, 0x53, 0xBB, 0x4C, 0xBD, 0x4C, 0x5A, 0x52, + 0x41, 0x41, 0x41, 0x41, 0x4C, 0x43, 0x43, 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, + 0x49, 0x44, 0xD0, 0x4E, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0xD7, 0x52, 0x55, 0x55, + 0x55, 0x55, 0x59, 0x54, 0xDF, 0x52, 0x41, 0x41, 0x41, 0x41, 0x4C, 0x43, 0x43, + 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x44, 0xD0, 0x4E, 0x4E, 0x4F, 0x4F, + 0x4F, 0x4F, 0xF7, 0x52, 0x55, 0x55, 0x55, 0x55, 0x59, 0x54, 0xFF, + + /* Mac */ + 0x41, 0x41, 0x41, 0x45, 0x41, 0x4F, 0x55, 0x41, 0x41, 0x43, 0x41, 0x43, 0x43, + 0x43, 0x45, 0x5A, 0x5A, 0x44, 0x49, 0x44, 0x45, 0x45, 0x45, 0x4F, 0x45, 0x4F, + 0x4F, 0x4F, 0x55, 0x45, 0x45, 0x55, 0xA0, 0xA1, 0x45, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0xAA, 0x45, 0xAC, 0xAD, 0x47, 0x49, 0x49, 0x49, 0xB2, 0xB3, + 0x49, 0x4B, 0xB6, 0xB7, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4E, 0x4E, + 0x4E, 0xC2, 0xC3, 0x4E, 0x4E, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0x4E, 0x4F, 0x4F, + 0x4F, 0x4F, 0xD0, 0xD0, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0x4F, 0x52, 0x52, + 0x52, 0xDC, 0xDD, 0x52, 0x52, 0x52, 0x53, 0xE2, 0xE3, 0x53, 0x53, 0x53, 0x41, + 0x54, 0x54, 0x49, 0x5A, 0x5A, 0x55, 0x4F, 0x4F, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x59, 0x59, 0x4B, 0x5A, 0x4C, 0x4C, 0x47, 0xFF +}; + +static const unsigned char Lookup_48[128 * 3] = { + /* Common */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, + 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x00, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, + 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, + 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, + + /* Windows */ + 0x7F, 0x7F, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x7F, 0x89, 0x53, 0x8B, 0x8C, + 0x7F, 0x7F, 0x7F, 0x7F, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x96, 0x98, 0x99, + 0x53, 0x9B, 0x8C, 0x7F, 0x7F, 0x59, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x96, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0xC6, 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, + 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0xD7, 0x4F, 0x55, 0x55, + 0x55, 0x55, 0x59, 0xDE, 0xDF, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0xC6, 0x43, + 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0x4F, 0x4F, + 0x4F, 0x4F, 0xF7, 0x4F, 0x55, 0x55, 0x55, 0x55, 0x59, 0xDE, 0x59, + + /* Mac */ + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, + 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, + 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAB, 0xAD, 0xAE, 0xAE, 0xB0, 0xB1, 0xB2, 0xB3, + 0xA7, 0xB5, 0xB6, 0xB7, 0xB8, 0xB8, 0xBA, 0xBA, 0xBC, 0xBC, 0xBE, 0xBE, 0xB7, + 0xC1, 0xC2, 0xC3, 0x46, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCB, 0xCD, + 0xCD, 0xC1, 0xD0, 0xD0, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD8, 0xDA, + 0xDA, 0xDC, 0xDD, 0xDD, 0x9F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, + 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F +}; + +static const unsigned char Lookup_64[128 * 3] = { + /* Common */ + 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x00, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, + 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x56, 0x58, 0x55, 0x5A, + 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x56, 0x58, 0x55, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, + +/* Windows */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x96, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, + 0x49, 0x49, 0x44, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0xD7, 0x4F, 0x55, 0x55, + 0x55, 0x55, 0x55, 0xDE, 0xDF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* Mac */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x96, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, + 0x49, 0x49, 0x44, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0xD7, 0x4F, 0x55, 0x55, + 0x55, 0x55, 0x55, 0xDE, 0xDF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +static const unsigned char Lookup_80[128 * 3] = { + /* Common */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, + 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x00, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, + 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x56, 0x58, 0x55, 0x5A, + 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x56, 0x58, 0x55, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, + +/* Windows */ + 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, + + /* Mac */ + 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, +}; + +static const unsigned char Lookup_112[128 * 3] = { + /* Common */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, + 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x00, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, + 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x56, 0x58, 0x55, 0x5A, + 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x56, 0x58, 0x55, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, + +/* Windows */ + 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, + + /* Mac */ + 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, +}; + +static const unsigned char Lookup_128[128 * 3] = { + /* Common */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, + 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, + 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, + 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x00, + +/* Windows */ + 0x00, 0x00, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x00, 0x89, 0x00, 0x8B, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x91, 0x92, 0x93, 0x94, 0x95, 0x2D, 0x2D, 0x00, 0x99, + 0x00, 0x9B, 0x00, 0x00, 0x00, 0x00, 0x09, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0x00, 0xAB, 0xAC, 0x2D, 0xAE, 0x2D, 0xB0, 0xB1, 0x32, 0x33, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xBA, + 0xA2, 0xC2, 0xC3, 0xC4, 0xB8, 0xC6, 0xB9, 0xC8, 0xBA, 0xCA, 0xCB, 0xCC, 0xCD, + 0xCE, 0xBC, 0xD0, 0xD1, 0x00, 0xD3, 0xD4, 0xBE, 0xD6, 0xD7, 0xD8, 0xBF, 0xBA, + 0xBE, 0xA2, 0xB8, 0xB9, 0xBA, 0xBE, 0xA2, 0xC2, 0xC3, 0xC4, 0xB8, 0xC6, 0xB9, + 0xC8, 0xBA, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xBC, 0xD0, 0xD1, 0xD3, 0xD3, 0xD4, + 0xBE, 0xD6, 0xD7, 0xD8, 0xBF, 0xBA, 0xBE, 0xBC, 0xBE, 0xBF, 0x00, + + /* Mac */ + 0x41, 0x31, 0x32, 0x45, 0x33, 0x4F, 0x55, 0x87, 0x41, 0x41, 0x41, 0x00, 0x8C, + 0x43, 0x45, 0x45, 0x45, 0x45, 0x92, 0x93, 0x49, 0x49, 0x96, 0x97, 0x98, 0x4F, + 0x4F, 0x9B, 0x3F, 0x55, 0x55, 0x55, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xAB, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xB0, + 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0x09, 0xBD, 0xCC, 0xB0, + 0xB6, 0xCF, 0x2D, 0x2D, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xB8, 0xAB, 0xC3, 0xBD, + 0xB6, 0xB8, 0xAB, 0xC3, 0xBF, 0xBD, 0xB0, 0xB5, 0xBE, 0xA2, 0xB6, 0xBC, 0xA1, + 0xB8, 0xAB, 0xA5, 0xBA, 0xA4, 0xBB, 0xC1, 0xC3, 0xA6, 0xBF, 0xC4, 0xAA, 0xC6, + 0xA3, 0xBF, 0xAA, 0xCC, 0xBD, 0xB7, 0xAB, 0xBD, 0xAB, 0xBD, 0x3F, +}; + +static const unsigned char Lookup_144[128 * 3] = { + /* Common */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, + 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, + 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, + 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x00, + +/* Windows */ + 0x00, 0x00, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x00, 0x89, 0x53, 0x8B, 0x8C, + 0x00, 0x00, 0x00, 0x00, 0x91, 0x92, 0x93, 0x94, 0x95, 0x2D, 0x2D, 0x98, 0x99, + 0x53, 0x9B, 0x8C, 0x00, 0x00, 0x59, 0x09, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x2D, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, + 0xC1, 0x41, 0x41, 0x41, 0x41, 0xC6, 0x43, 0x45, 0xC9, 0x45, 0x45, 0x49, 0xCD, + 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0xD3, 0x4F, 0x4F, 0xD6, 0xD7, 0xD6, 0x55, 0xDA, + 0x55, 0x55, 0xDD, 0xDE, 0xDF, 0x41, 0xC1, 0x41, 0x41, 0x41, 0x41, 0xC6, 0x43, + 0x45, 0xC9, 0x45, 0x45, 0x49, 0xCD, 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0xD3, 0x4F, + 0x4F, 0xD6, 0xF7, 0xD6, 0x55, 0xDA, 0x55, 0x55, 0xDD, 0xDE, 0x59, + + /* Mac */ + 0x00, 0x00, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x00, 0x89, 0x53, 0x8B, 0x8C, + 0x00, 0x00, 0x00, 0x00, 0x91, 0x92, 0x93, 0x94, 0x95, 0x2D, 0x2D, 0x98, 0x99, + 0x53, 0x9B, 0x8C, 0x00, 0x00, 0x59, 0x09, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x2D, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, + 0xC1, 0x41, 0x41, 0x41, 0x41, 0xC6, 0x43, 0x45, 0xC9, 0x45, 0x45, 0x49, 0xCD, + 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0xD3, 0x4F, 0x4F, 0xD6, 0xD7, 0xD6, 0x55, 0xDA, + 0x55, 0x55, 0xDD, 0xDE, 0xDF, 0x41, 0xC1, 0x41, 0x41, 0x41, 0x41, 0xC6, 0x43, + 0x45, 0xC9, 0x45, 0x45, 0x49, 0xCD, 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0xD3, 0x4F, + 0x4F, 0xD6, 0xF7, 0xD6, 0x55, 0xDA, 0x55, 0x55, 0xDD, 0xDE, 0x59, +}; + +static const unsigned char Lookup_160[128 * 3] = { + /* Common */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, + 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, + 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, + 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x00, + +/* Windows */ + 0x00, 0x00, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x00, 0x89, 0x53, 0x8B, 0x8C, + 0x00, 0x00, 0x00, 0x00, 0x91, 0x92, 0x93, 0x94, 0x95, 0x2D, 0x2D, 0x98, 0x99, + 0x53, 0x9B, 0x8C, 0x00, 0x00, 0x59, 0x09, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x2D, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0xC6, 0xC7, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, + 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0xD6, 0xD7, 0x4F, 0x55, 0x55, + 0x55, 0xDC, 0xDD, 0xDE, 0xDF, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0xC6, 0xC7, + 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0x4F, 0x4F, + 0x4F, 0xD6, 0xF7, 0x4F, 0x55, 0x55, 0x55, 0xDC, 0xDD, 0xDE, 0x59, + + /* Mac */ + 0x00, 0x00, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x00, 0x89, 0x53, 0x8B, 0x8C, + 0x00, 0x00, 0x00, 0x00, 0x91, 0x92, 0x93, 0x94, 0x95, 0x2D, 0x2D, 0x98, 0x99, + 0x53, 0x9B, 0x8C, 0x00, 0x00, 0x59, 0x09, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x2D, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0xC6, 0xC7, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, + 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0xD6, 0xD7, 0x4F, 0x55, 0x55, + 0x55, 0xDC, 0xDD, 0xDE, 0xDF, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0xC6, 0xC7, + 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0x4F, 0x4F, + 0x4F, 0xD6, 0xF7, 0x4F, 0x55, 0x55, 0x55, 0xDC, 0xDD, 0xDE, 0x59, +}; + +static const unsigned char Lookup_176[128 * 3] = { + /* Common */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, + 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, + 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, + 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x00, + + /* Windows */ + 0x00, 0x00, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x00, 0x89, 0x53, 0x8B, 0x8C, + 0x00, 0x00, 0x00, 0x00, 0x91, 0x92, 0x93, 0x94, 0x95, 0x2D, 0x2D, 0x98, 0x99, + 0x53, 0x9B, 0x8C, 0x00, 0x00, 0x59, 0x09, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x2D, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, + 0x41, 0x41, 0x41, 0xC4, 0xC5, 0xC4, 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, + 0x49, 0x49, 0x44, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0xD6, 0xD7, 0xD6, 0x55, 0x55, + 0x55, 0x59, 0x59, 0xDE, 0xDF, 0x41, 0x41, 0x41, 0x41, 0xC4, 0xC5, 0xC4, 0x43, + 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0x44, 0x4E, 0x4F, 0x4F, 0x4F, + 0x4F, 0xD6, 0xF7, 0xD6, 0x55, 0x55, 0x55, 0x59, 0x59, 0xDE, 0x59, + + /* Mac */ + 0x80, 0x81, 0x43, 0x45, 0x4E, 0x85, 0x59, 0x41, 0x41, 0x41, 0x80, 0x41, 0x81, + 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0x4E, 0x4F, 0x4F, 0x4F, + 0x85, 0x4F, 0x55, 0x55, 0x55, 0x59, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0x80, 0x85, 0xB0, 0xB1, 0xB2, 0xB3, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0x41, 0x4F, 0xBD, 0x80, 0x85, 0xC0, + 0xC1, 0xC2, 0xC3, 0x46, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0x09, 0x41, 0x41, 0x4F, + 0xCE, 0xCE, 0x2D, 0x2D, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0x59, 0x59, 0xDA, + 0xDB, 0xDC, 0xDD, 0x3F, 0x3F, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0x41, 0x45, 0x41, + 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0x4F, 0x4F, 0x3F, 0x4F, 0x55, 0x55, 0x55, + 0x49, 0x00, 0xF7, 0x00, 0xF9, 0xFA, 0xFB, 0x3F, 0xFD, 0xFE, 0x00 +}; + +static const unsigned char Lookup_208[128 * 3] = { + /* Common */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, + 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, + 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, + 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, + +/* Windows */ + 0x80, 0x81, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x5E, 0x89, 0x8A, 0x8B, 0x8C, + 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, + 0x9A, 0x9B, 0x8C, 0x9D, 0x00, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, + 0xC1, 0xC2, 0xC1, 0xC1, 0xC1, 0xC1, 0xC7, 0xC8, 0xC9, 0xC9, 0xCB, 0xCC, 0xCD, + 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, + 0xDB, 0x00, 0xDD, 0xDE, 0xDF, 0x41, 0xE1, 0x41, 0xE3, 0xE4, 0xE5, 0xE6, 0x43, + 0x45, 0x45, 0x45, 0x45, 0xEC, 0xEC, 0x49, 0x49, 0xF0, 0xF1, 0xF2, 0xF3, 0x4F, + 0xF5, 0xF6, 0xF7, 0xF8, 0x55, 0xFA, 0x55, 0x55, 0x00, 0x00, 0xFF, + + /* Mac */ + 0x41, 0x81, 0x43, 0x45, 0x4E, 0x4F, 0x55, 0x41, 0x41, 0x41, 0x41, 0x8B, 0x8C, + 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x93, 0x49, 0x49, 0x4E, 0x4F, 0x98, 0x4F, + 0x4F, 0x9B, 0x55, 0x55, 0x55, 0x55, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, + 0xC1, 0xC2, 0xC1, 0xC1, 0xC1, 0xC1, 0xC7, 0xC8, 0xC9, 0xC9, 0xCB, 0xCC, 0xCD, + 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, + 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0x00, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, + 0xE8, 0xE9, 0xE9, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, + 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, +}; + +static const unsigned char Lookup_224[128 * 3] = { + /* Common */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, + 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, + 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, + 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, + +/* Windows */ + 0x80, 0x81, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x5E, 0x89, 0x8A, 0x8B, 0x8C, + 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, + 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, + 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, + 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, + 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, + 0xE8, 0xE9, 0xEA, 0xEA, 0xEC, 0xED, 0xED, 0xEF, 0xEF, 0xF1, 0xF2, 0xF3, 0xF3, + 0xF5, 0xF5, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0x00, 0x00, 0xFF, + + /* Mac */ + 0x41, 0x41, 0x43, 0x45, 0x4E, 0x4F, 0x55, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0x4E, 0x4F, 0x4F, 0x4F, + 0x4F, 0x4F, 0x55, 0x55, 0x55, 0x55, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, + 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, + 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, + 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, + 0xE8, 0xE9, 0xEA, 0xEA, 0xEC, 0xED, 0xED, 0xEF, 0xEF, 0xF1, 0xF2, 0xF3, 0xF3, + 0xF5, 0xF5, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, +}; + +/*********************************************************************** + * LHashValOfNameSysA (OLEAUT32.166) + * + * Produce a string hash value. + * + * PARAMS + * skind [I] Type of the system. + * lcid [I] Locale id for the hash. + * lpStr [I] String to hash. + * + * RETURNS + * Success: The hash value of the string. + * Failure: 0, if lpStr is NULL. + * + * NOTES + * This function produces a two part hash: The high word is based on + * skind and lcid, while the low word is based on a repeated string + * hash of skind/str. + */ +ULONG WINAPI LHashValOfNameSysA( SYSKIND skind, LCID lcid, LPCSTR lpStr) +{ + ULONG nOffset, nMask = skind == SYS_MAC ? 1 : 0; + ULONG nHiWord, nLoWord = 0x0deadbee; + const unsigned char *str = (const unsigned char *)lpStr, *pnLookup = NULL; + + if (!str) + return 0; + + lcid = ConvertDefaultLocale(lcid); + + switch (PRIMARYLANGID(LANGIDFROMLCID(lcid))) + { + default: + ERR("Unknown lcid %lx, treating as latin-based, please report\n", lcid); + /* .. Fall Through .. */ + case LANG_AFRIKAANS: case LANG_ALBANIAN: case LANG_ARMENIAN: + case LANG_ASSAMESE: case LANG_AZERI: case LANG_BASQUE: + case LANG_BELARUSIAN: case LANG_BENGALI: case LANG_BULGARIAN: + case LANG_CATALAN: case LANG_DANISH: case LANG_DIVEHI: + case LANG_DUTCH: case LANG_ENGLISH: case LANG_ESTONIAN: + case LANG_FAEROESE: case LANG_FINNISH: case LANG_FRENCH: + case LANG_GALICIAN: case LANG_GEORGIAN: case LANG_GERMAN: + case LANG_GUJARATI: case LANG_HINDI: case LANG_INDONESIAN: + case LANG_ITALIAN: case LANG_KANNADA: case LANG_KASHMIRI: + case LANG_KAZAK: case LANG_KONKANI: case LANG_KYRGYZ: + case LANG_LATVIAN: case LANG_LITHUANIAN: case LANG_MACEDONIAN: + case LANG_MALAY: case LANG_MALAYALAM: case LANG_MANIPURI: + case LANG_MARATHI: case LANG_MONGOLIAN: case LANG_NEPALI: + case LANG_ORIYA: case LANG_PORTUGUESE: case LANG_PUNJABI: + case LANG_ROMANIAN: case LANG_SANSKRIT: case LANG_SERBIAN: + case LANG_SINDHI: case LANG_SLOVENIAN: case LANG_SWAHILI: + case LANG_SWEDISH: case LANG_SYRIAC: case LANG_TAMIL: + case LANG_TATAR: case LANG_TELUGU: case LANG_THAI: + case LANG_UKRAINIAN: case LANG_URDU: case LANG_UZBEK: + case LANG_VIETNAMESE: case LANG_GAELIC: case LANG_MALTESE: + case LANG_MAORI: case LANG_RHAETO_ROMANCE: + case LANG_SAAMI: case LANG_SORBIAN: case LANG_SUTU: + case LANG_TSONGA: case LANG_TSWANA: case LANG_VENDA: + case LANG_XHOSA: case LANG_ZULU: case LANG_ESPERANTO: + case LANG_WALON: case LANG_CORNISH: case LANG_WELSH: + case LANG_BRETON: + nOffset = 16; + pnLookup = Lookup_16; + break; + case LANG_CZECH: case LANG_HUNGARIAN: case LANG_POLISH: + case LANG_SLOVAK: case LANG_SPANISH: + nOffset = 32; + pnLookup = Lookup_32; + break; + case LANG_HEBREW: + nOffset = 48; + pnLookup = Lookup_48; + break; + case LANG_JAPANESE: + nOffset = 64; + pnLookup = Lookup_64; + break; + case LANG_KOREAN: + nOffset = 80; + pnLookup = Lookup_80; + break; + case LANG_CHINESE: + nOffset = 112; + pnLookup = Lookup_112; + break; + case LANG_GREEK: + nOffset = 128; + pnLookup = Lookup_128; + break; + case LANG_ICELANDIC: + nOffset = 144; + pnLookup = Lookup_144; + break; + case LANG_TURKISH: + nOffset = 160; + pnLookup = Lookup_160; + break; + case LANG_NORWEGIAN: + if (SUBLANGID(LANGIDFROMLCID(lcid)) == SUBLANG_NORWEGIAN_NYNORSK) + { + nOffset = 176; + pnLookup = Lookup_176; + } + else + { + nOffset = 16; + pnLookup = Lookup_16; + } + break; + case LANG_ARABIC: + case LANG_FARSI: + nOffset = 208; + pnLookup = Lookup_208; + break; + case LANG_RUSSIAN: + nOffset = 224; + pnLookup = Lookup_224; + break; + } + + nHiWord = (nOffset | nMask) << 16; + + while (*str) + { + ULONG newLoWord = 0, i; + + /* Cumulative prime multiplication (*37) with modulo 2^32 wrap-around */ + for (i = 0; i < 37; i++) + newLoWord += nLoWord; + + nLoWord = newLoWord + pnLookup[*str > 0x7f && nMask ? *str + 0x80 : *str]; + str++; + } + /* Constrain to a prime modulo and sizeof(WORD) */ + nLoWord = (nLoWord % 65599) & 0xffff; + + return nHiWord | nLoWord; +} + +/*********************************************************************** + * LHashValOfNameSys (OLEAUT32.165) + * + * See LHashValOfNameSysA. + */ +ULONG WINAPI LHashValOfNameSys(SYSKIND skind, LCID lcid, LPCOLESTR str) +{ + LPSTR strA; + ULONG res; + INT len; + + if (!str) return 0; + len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL ); + strA = HeapAlloc( GetProcessHeap(), 0, len ); + WideCharToMultiByte( CP_ACP, 0, str, -1, strA, len, NULL, NULL ); + res = LHashValOfNameSysA(skind, lcid, strA); + HeapFree(GetProcessHeap(), 0, strA); + return res; +} diff --git a/reactos/lib/oleaut32/makefile b/reactos/lib/oleaut32/makefile new file mode 100644 index 00000000000..72b90c6321f --- /dev/null +++ b/reactos/lib/oleaut32/makefile @@ -0,0 +1,9 @@ +# $Id: makefile 8082 2004-02-07 18:53:59Z mf $ + +PATH_TO_TOP = ../.. + +TARGET_TYPE = winedll + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk diff --git a/reactos/lib/oleaut32/oaidl_p.c b/reactos/lib/oleaut32/oaidl_p.c new file mode 100644 index 00000000000..0d7f8545bce --- /dev/null +++ b/reactos/lib/oleaut32/oaidl_p.c @@ -0,0 +1,13781 @@ +/* This file contains the proxy/stub code for core COM interfaces. + + It is usually generated directly by MIDL, however this file has + been tweaked since then to account for slight differences in the way + gcc and MSVC++ compile it. In particular, in some functions REFIIDs + declared on the stack have been converted to plain IID* in order to eliminate + the constness of the REFIID type, ensuring that the zero initializer is not + discarded. + + Therefore, please do not regenerate this file. +*/ + +/* File created by MIDL compiler version 5.01.0164 */ +/* at Tue Jan 07 22:24:52 2003 + */ +/* Compiler settings for oaidl.idl: + Os (OptLev=s), W1, Zp8, env=Win32, ms_ext, c_ext + error checks: allocation ref bounds_check enum stub_data +*/ +/*@@MIDL_FILE_HEADING( ) */ + + +/* verify that the version is high enough to compile this file*/ +#ifndef __REDQ_RPCPROXY_H_VERSION__ +#define __REQUIRED_RPCPROXY_H_VERSION__ 440 +#endif + + +#include + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "objbase.h" +#include "rpcproxy.h" +#ifndef __RPCPROXY_H_VERSION__ +#error this stub requires an updated version of +#endif /* __RPCPROXY_H_VERSION__ */ + + +#include "oaidl.h" + +#define TYPE_FORMAT_STRING_SIZE 1907 +#define PROC_FORMAT_STRING_SIZE 495 + +typedef struct _MIDL_TYPE_FORMAT_STRING + { + short Pad; + unsigned char Format[ TYPE_FORMAT_STRING_SIZE ]; + } MIDL_TYPE_FORMAT_STRING; + +typedef struct _MIDL_PROC_FORMAT_STRING + { + short Pad; + unsigned char Format[ PROC_FORMAT_STRING_SIZE ]; + } MIDL_PROC_FORMAT_STRING; + + +static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString; +static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString; + + +/* Standard interface: __MIDL_itf_oaidl_0000, ver. 0.0, + GUID={0x00000000,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}} */ + + +/* Standard interface: IOleAutomationTypes, ver. 1.0, + GUID={0x00000000,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}} */ + + +/* Object interface: IUnknown, ver. 0.0, + GUID={0x00000000,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}} */ + + +/* Object interface: IDispatch, ver. 0.0, + GUID={0x00020400,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}} */ + + +static const MIDL_STUB_DESC Object_StubDesc; + + +HRESULT STDMETHODCALLTYPE IDispatch_GetTypeInfoCount_Proxy( + IDispatch __RPC_FAR * This, + /* [out] */ UINT __RPC_FAR *pctinfo) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 3); + + + + if(!pctinfo) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 0U; + NdrProxyGetBuffer(This, &_StubMsg); + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[0] ); + + *pctinfo = *( UINT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(UINT); + + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[2], + ( void __RPC_FAR * )pctinfo); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB IDispatch_GetTypeInfoCount_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + UINT _M0; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + UINT __RPC_FAR *pctinfo; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + pctinfo = 0; + RpcTryFinally + { + pctinfo = &_M0; + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((IDispatch*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> GetTypeInfoCount((IDispatch *) ((CStdStubBuffer *)This)->pvServerObject,pctinfo); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 4U + 4U; + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + *( UINT __RPC_FAR * )_StubMsg.Buffer = *pctinfo; + _StubMsg.Buffer += sizeof(UINT); + + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +HRESULT STDMETHODCALLTYPE IDispatch_GetTypeInfo_Proxy( + IDispatch __RPC_FAR * This, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(ppTInfo) + { + MIDL_memset( + ppTInfo, + 0, + sizeof( ITypeInfo __RPC_FAR *__RPC_FAR * )); + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 4); + + + + if(!ppTInfo) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 4U + 4U; + NdrProxyGetBuffer(This, &_StubMsg); + *( UINT __RPC_FAR * )_StubMsg.Buffer = iTInfo; + _StubMsg.Buffer += sizeof(UINT); + + *( LCID __RPC_FAR * )_StubMsg.Buffer = lcid; + _StubMsg.Buffer += sizeof(LCID); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[6] ); + + NdrPointerUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&ppTInfo, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[6], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[6], + ( void __RPC_FAR * )ppTInfo); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB IDispatch_GetTypeInfo_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + ITypeInfo __RPC_FAR *_M1; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + UINT iTInfo; + LCID lcid; + ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + ppTInfo = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[6] ); + + iTInfo = *( UINT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(UINT); + + lcid = *( LCID __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(LCID); + + ppTInfo = &_M1; + _M1 = 0; + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((IDispatch*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> GetTypeInfo( + (IDispatch *) ((CStdStubBuffer *)This)->pvServerObject, + iTInfo, + lcid, + ppTInfo); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 0U + 4U; + NdrPointerBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)ppTInfo, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[6] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + NdrPointerMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)ppTInfo, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[6] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)ppTInfo, + &__MIDL_TypeFormatString.Format[6] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +HRESULT STDMETHODCALLTYPE IDispatch_GetIDsOfNames_Proxy( + IDispatch __RPC_FAR * This, + /* [in] */ REFIID riid, + /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames, + /* [in] */ UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ DISPID __RPC_FAR *rgDispId) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 5); + + + + if(!riid) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!rgszNames) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!rgDispId) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 0U + 7U + 7U + 7U; + NdrSimpleStructBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)riid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[38] ); + + _StubMsg.MaxCount = cNames; + + NdrConformantArrayBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)rgszNames, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[54] ); + + NdrProxyGetBuffer(This, &_StubMsg); + NdrSimpleStructMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)riid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[38] ); + + _StubMsg.MaxCount = cNames; + + NdrConformantArrayMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)rgszNames, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[54] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( UINT __RPC_FAR * )_StubMsg.Buffer = cNames; + _StubMsg.Buffer += sizeof(UINT); + + *( LCID __RPC_FAR * )_StubMsg.Buffer = lcid; + _StubMsg.Buffer += sizeof(LCID); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[16] ); + + NdrConformantArrayUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&rgDispId, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[88], + (unsigned char)0 ); + + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + _StubMsg.MaxCount = cNames; + + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[84], + ( void __RPC_FAR * )rgDispId); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB IDispatch_GetIDsOfNames_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + UINT cNames; + LCID lcid; + DISPID __RPC_FAR *rgDispId; + LPOLESTR __RPC_FAR *rgszNames; + IID* riid = 0; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + rgszNames = 0; + rgDispId = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[16] ); + + NdrSimpleStructUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&riid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[38], + (unsigned char)0 ); + + NdrConformantArrayUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&rgszNames, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[54], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + cNames = *( UINT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(UINT); + + + lcid = *( LCID __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(LCID); + + rgDispId = NdrAllocate(&_StubMsg,cNames * 4); + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((IDispatch*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> GetIDsOfNames( + (IDispatch *) ((CStdStubBuffer *)This)->pvServerObject, + riid, + rgszNames, + cNames, + lcid, + rgDispId); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 4U + 7U; + _StubMsg.MaxCount = cNames; + + NdrConformantArrayBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)rgDispId, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[88] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + _StubMsg.MaxCount = cNames; + + NdrConformantArrayMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)rgDispId, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[88] ); + + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + _StubMsg.MaxCount = cNames; + + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)rgszNames, + &__MIDL_TypeFormatString.Format[50] ); + + if ( rgDispId ) + _StubMsg.pfnFree( rgDispId ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +/* [call_as] */ HRESULT STDMETHODCALLTYPE IDispatch_RemoteInvoke_Proxy( + IDispatch __RPC_FAR * This, + /* [in] */ DISPID dispIdMember, + /* [in] */ REFIID riid, + /* [in] */ LCID lcid, + /* [in] */ DWORD dwFlags, + /* [in] */ DISPPARAMS __RPC_FAR *pDispParams, + /* [out] */ VARIANT __RPC_FAR *pVarResult, + /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo, + /* [out] */ UINT __RPC_FAR *pArgErr, + /* [in] */ UINT cVarRef, + /* [size_is][in] */ UINT __RPC_FAR *rgVarRefIdx, + /* [size_is][out][in] */ VARIANTARG __RPC_FAR *rgVarRef) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(pVarResult) + { + MIDL_memset( + pVarResult, + 0, + sizeof( VARIANT )); + } + if(pExcepInfo) + { + MIDL_memset( + pExcepInfo, + 0, + sizeof( EXCEPINFO )); + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 6); + + + + if(!riid) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!pDispParams) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!pVarResult) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!pExcepInfo) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!pArgErr) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!rgVarRefIdx) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!rgVarRef) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 4U + 4U + 11U + 7U + 4U + 11U + 7U + 7U; + NdrSimpleStructBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)riid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[38] ); + + NdrComplexStructBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)pDispParams, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1080] ); + + _StubMsg.MaxCount = cVarRef; + + NdrConformantArrayBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)rgVarRefIdx, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1170] ); + + _StubMsg.MaxCount = cVarRef; + + NdrComplexArrayBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)rgVarRef, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1184] ); + + NdrProxyGetBuffer(This, &_StubMsg); + *( DISPID __RPC_FAR * )_StubMsg.Buffer = dispIdMember; + _StubMsg.Buffer += sizeof(DISPID); + + NdrSimpleStructMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)riid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[38] ); + + *( LCID __RPC_FAR * )_StubMsg.Buffer = lcid; + _StubMsg.Buffer += sizeof(LCID); + + *( DWORD __RPC_FAR * )_StubMsg.Buffer = dwFlags; + _StubMsg.Buffer += sizeof(DWORD); + + NdrComplexStructMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)pDispParams, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1080] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( UINT __RPC_FAR * )_StubMsg.Buffer = cVarRef; + _StubMsg.Buffer += sizeof(UINT); + + _StubMsg.MaxCount = cVarRef; + + NdrConformantArrayMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)rgVarRefIdx, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1170] ); + + _StubMsg.MaxCount = cVarRef; + + NdrComplexArrayMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)rgVarRef, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1184] ); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[34] ); + + NdrUserMarshalUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&pVarResult, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1110], + (unsigned char)0 ); + + NdrComplexStructUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&pExcepInfo, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1138], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *pArgErr = *( UINT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(UINT); + + NdrComplexArrayUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&rgVarRef, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1184], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1102], + ( void __RPC_FAR * )pVarResult); + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1120], + ( void __RPC_FAR * )pExcepInfo); + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[2], + ( void __RPC_FAR * )pArgErr); + _StubMsg.MaxCount = cVarRef; + + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1180], + ( void __RPC_FAR * )rgVarRef); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB IDispatch_RemoteInvoke_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + VARIANT _M6; + UINT _M7; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + EXCEPINFO _pExcepInfoM; + UINT cVarRef; + DISPID dispIdMember; + DWORD dwFlags; + LCID lcid; + UINT __RPC_FAR *pArgErr; + DISPPARAMS __RPC_FAR *pDispParams; + EXCEPINFO __RPC_FAR *pExcepInfo; + VARIANT __RPC_FAR *pVarResult; + VARIANTARG __RPC_FAR *rgVarRef; + UINT __RPC_FAR *rgVarRefIdx; + IID* riid = 0; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + pDispParams = 0; + pVarResult = 0; + pExcepInfo = 0; + pArgErr = 0; + rgVarRefIdx = 0; + rgVarRef = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[34] ); + + dispIdMember = *( DISPID __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(DISPID); + + NdrSimpleStructUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&riid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[38], + (unsigned char)0 ); + + lcid = *( LCID __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(LCID); + + dwFlags = *( DWORD __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(DWORD); + + NdrComplexStructUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&pDispParams, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1080], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + cVarRef = *( UINT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(UINT); + + NdrConformantArrayUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&rgVarRefIdx, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1170], + (unsigned char)0 ); + + NdrComplexArrayUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&rgVarRef, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1184], + (unsigned char)0 ); + + pVarResult = &_M6; + MIDL_memset( + pVarResult, + 0, + sizeof( VARIANT )); + pExcepInfo = &_pExcepInfoM; + pArgErr = &_M7; + + *_pdwStubPhase = STUB_CALL_SERVER; + + + _RetVal = IDispatch_Invoke_Stub( + (IDispatch *) ((CStdStubBuffer *)This)->pvServerObject, + dispIdMember, + riid, + lcid, + dwFlags, + pDispParams, + pVarResult, + pExcepInfo, + pArgErr, + cVarRef, + rgVarRefIdx, + rgVarRef); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 8U + 7U + 11U + 7U + 7U; + NdrUserMarshalBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)pVarResult, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1110] ); + + NdrComplexStructBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)pExcepInfo, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1138] ); + + _StubMsg.MaxCount = cVarRef; + + NdrComplexArrayBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)rgVarRef, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1184] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + NdrUserMarshalMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)pVarResult, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1110] ); + + NdrComplexStructMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)pExcepInfo, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1138] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( UINT __RPC_FAR * )_StubMsg.Buffer = *pArgErr; + _StubMsg.Buffer += sizeof(UINT); + + _StubMsg.MaxCount = cVarRef; + + NdrComplexArrayMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)rgVarRef, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1184] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)pDispParams, + &__MIDL_TypeFormatString.Format[98] ); + + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)pVarResult, + &__MIDL_TypeFormatString.Format[1102] ); + + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)pExcepInfo, + &__MIDL_TypeFormatString.Format[1120] ); + + _StubMsg.MaxCount = cVarRef; + + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)rgVarRef, + &__MIDL_TypeFormatString.Format[1180] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + +const CINTERFACE_PROXY_VTABLE(7) _IDispatchProxyVtbl = +{ + { &IID_IDispatch }, + { + IUnknown_QueryInterface_Proxy, + IUnknown_AddRef_Proxy, + IUnknown_Release_Proxy , + IDispatch_GetTypeInfoCount_Proxy , + IDispatch_GetTypeInfo_Proxy , + IDispatch_GetIDsOfNames_Proxy , + IDispatch_Invoke_Proxy + } +}; + + +static const PRPC_STUB_FUNCTION IDispatch_table[] = +{ + IDispatch_GetTypeInfoCount_Stub, + IDispatch_GetTypeInfo_Stub, + IDispatch_GetIDsOfNames_Stub, + IDispatch_RemoteInvoke_Stub +}; + +const CInterfaceStubVtbl _IDispatchStubVtbl = +{ + { + &IID_IDispatch, + 0, + 7, + &IDispatch_table[-3] + }, + { CStdStubBuffer_METHODS } +}; + + +/* Object interface: IEnumVARIANT, ver. 0.0, + GUID={0x00020404,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}} */ + + +extern const MIDL_STUB_DESC Object_StubDesc; + + +/* [call_as] */ HRESULT STDMETHODCALLTYPE IEnumVARIANT_RemoteNext_Proxy( + IEnumVARIANT __RPC_FAR * This, + /* [in] */ ULONG celt, + /* [length_is][size_is][out] */ VARIANT __RPC_FAR *rgVar, + /* [out] */ ULONG __RPC_FAR *pCeltFetched) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(rgVar) + { + MIDL_memset( + rgVar, + 0, + celt * sizeof( VARIANT )); + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 3); + + + + if(!rgVar) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!pCeltFetched) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 4U; + NdrProxyGetBuffer(This, &_StubMsg); + *( ULONG __RPC_FAR * )_StubMsg.Buffer = celt; + _StubMsg.Buffer += sizeof(ULONG); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[72] ); + + NdrComplexArrayUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&rgVar, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1206], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *pCeltFetched = *( ULONG __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(ULONG); + + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + _StubMsg.MaxCount = celt; + _StubMsg.Offset = 0; + _StubMsg.ActualCount = _StubMsg.MaxCount; + + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1202], + ( void __RPC_FAR * )rgVar); + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[2], + ( void __RPC_FAR * )pCeltFetched); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB IEnumVARIANT_RemoteNext_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + ULONG _M11; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + ULONG celt; + ULONG __RPC_FAR *pCeltFetched; + VARIANT __RPC_FAR *rgVar; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + rgVar = 0; + pCeltFetched = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[72] ); + + celt = *( ULONG __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(ULONG); + + rgVar = NdrAllocate(&_StubMsg,celt * 16); + pCeltFetched = &_M11; + + *_pdwStubPhase = STUB_CALL_SERVER; + + + _RetVal = IEnumVARIANT_Next_Stub( + (IEnumVARIANT *) ((CStdStubBuffer *)This)->pvServerObject, + celt, + rgVar, + pCeltFetched); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 12U + 7U + 7U; + _StubMsg.MaxCount = celt; + _StubMsg.Offset = 0; + _StubMsg.ActualCount = pCeltFetched ? *pCeltFetched : 0; + + NdrComplexArrayBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)rgVar, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1206] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + _StubMsg.MaxCount = celt; + _StubMsg.Offset = 0; + _StubMsg.ActualCount = pCeltFetched ? *pCeltFetched : 0; + + NdrComplexArrayMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)rgVar, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1206] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( ULONG __RPC_FAR * )_StubMsg.Buffer = *pCeltFetched; + _StubMsg.Buffer += sizeof(ULONG); + + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + _StubMsg.MaxCount = celt; + _StubMsg.Offset = 0; + _StubMsg.ActualCount = pCeltFetched ? *pCeltFetched : 0; + + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)rgVar, + &__MIDL_TypeFormatString.Format[1202] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +HRESULT STDMETHODCALLTYPE IEnumVARIANT_Skip_Proxy( + IEnumVARIANT __RPC_FAR * This, + /* [in] */ ULONG celt) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 4); + + + + RpcTryFinally + { + + _StubMsg.BufferLength = 4U; + NdrProxyGetBuffer(This, &_StubMsg); + *( ULONG __RPC_FAR * )_StubMsg.Buffer = celt; + _StubMsg.Buffer += sizeof(ULONG); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[84] ); + + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB IEnumVARIANT_Skip_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + ULONG celt; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[84] ); + + celt = *( ULONG __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(ULONG); + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((IEnumVARIANT*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> Skip((IEnumVARIANT *) ((CStdStubBuffer *)This)->pvServerObject,celt); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 4U; + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +HRESULT STDMETHODCALLTYPE IEnumVARIANT_Reset_Proxy( + IEnumVARIANT __RPC_FAR * This) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 5); + + + + RpcTryFinally + { + + _StubMsg.BufferLength = 0U; + NdrProxyGetBuffer(This, &_StubMsg); + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[88] ); + + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB IEnumVARIANT_Reset_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + RpcTryFinally + { + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((IEnumVARIANT*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> Reset((IEnumVARIANT *) ((CStdStubBuffer *)This)->pvServerObject); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 4U; + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +HRESULT STDMETHODCALLTYPE IEnumVARIANT_Clone_Proxy( + IEnumVARIANT __RPC_FAR * This, + /* [out] */ IEnumVARIANT __RPC_FAR *__RPC_FAR *ppEnum) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(ppEnum) + { + MIDL_memset( + ppEnum, + 0, + sizeof( IEnumVARIANT __RPC_FAR *__RPC_FAR * )); + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 6); + + + + if(!ppEnum) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 0U; + NdrProxyGetBuffer(This, &_StubMsg); + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[90] ); + + NdrPointerUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&ppEnum, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1224], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1224], + ( void __RPC_FAR * )ppEnum); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB IEnumVARIANT_Clone_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + IEnumVARIANT __RPC_FAR *_M12; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + IEnumVARIANT __RPC_FAR *__RPC_FAR *ppEnum; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + ppEnum = 0; + RpcTryFinally + { + ppEnum = &_M12; + _M12 = 0; + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((IEnumVARIANT*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> Clone((IEnumVARIANT *) ((CStdStubBuffer *)This)->pvServerObject,ppEnum); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 0U + 4U; + NdrPointerBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)ppEnum, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1224] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + NdrPointerMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)ppEnum, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1224] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)ppEnum, + &__MIDL_TypeFormatString.Format[1224] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + +const CINTERFACE_PROXY_VTABLE(7) _IEnumVARIANTProxyVtbl = +{ + { &IID_IEnumVARIANT }, + { + IUnknown_QueryInterface_Proxy, + IUnknown_AddRef_Proxy, + IUnknown_Release_Proxy , + IEnumVARIANT_Next_Proxy , + IEnumVARIANT_Skip_Proxy , + IEnumVARIANT_Reset_Proxy , + IEnumVARIANT_Clone_Proxy + } +}; + + +static const PRPC_STUB_FUNCTION IEnumVARIANT_table[] = +{ + IEnumVARIANT_RemoteNext_Stub, + IEnumVARIANT_Skip_Stub, + IEnumVARIANT_Reset_Stub, + IEnumVARIANT_Clone_Stub +}; + +const CInterfaceStubVtbl _IEnumVARIANTStubVtbl = +{ + { + &IID_IEnumVARIANT, + 0, + 7, + &IEnumVARIANT_table[-3] + }, + { CStdStubBuffer_METHODS } +}; + + +/* Object interface: ITypeComp, ver. 0.0, + GUID={0x00020403,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}} */ + + +extern const MIDL_STUB_DESC Object_StubDesc; + + +/* [call_as] */ HRESULT STDMETHODCALLTYPE ITypeComp_RemoteBind_Proxy( + ITypeComp __RPC_FAR * This, + /* [in] */ LPOLESTR szName, + /* [in] */ ULONG lHashVal, + /* [in] */ WORD wFlags, + /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo, + /* [out] */ DESCKIND __RPC_FAR *pDescKind, + /* [out] */ LPFUNCDESC __RPC_FAR *ppFuncDesc, + /* [out] */ LPVARDESC __RPC_FAR *ppVarDesc, + /* [out] */ ITypeComp __RPC_FAR *__RPC_FAR *ppTypeComp, + /* [out] */ CLEANLOCALSTORAGE __RPC_FAR *pDummy) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(ppTInfo) + { + MIDL_memset( + ppTInfo, + 0, + sizeof( ITypeInfo __RPC_FAR *__RPC_FAR * )); + } + if(ppFuncDesc) + { + *ppFuncDesc = 0; + } + if(ppVarDesc) + { + *ppVarDesc = 0; + } + if(ppTypeComp) + { + MIDL_memset( + ppTypeComp, + 0, + sizeof( ITypeComp __RPC_FAR *__RPC_FAR * )); + } + if(pDummy) + { + MIDL_memset( + pDummy, + 0, + sizeof( CLEANLOCALSTORAGE )); + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 3); + + + + if(!szName) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!ppTInfo) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!pDescKind) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!ppFuncDesc) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!ppVarDesc) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!ppTypeComp) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!pDummy) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 12U + 10U + 4U; + NdrConformantStringBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)szName, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1248] ); + + NdrProxyGetBuffer(This, &_StubMsg); + NdrConformantStringMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)szName, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1248] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( ULONG __RPC_FAR * )_StubMsg.Buffer = lHashVal; + _StubMsg.Buffer += sizeof(ULONG); + + *( WORD __RPC_FAR * )_StubMsg.Buffer = wFlags; + _StubMsg.Buffer += sizeof(WORD); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[96] ); + + NdrPointerUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&ppTInfo, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[6], + (unsigned char)0 ); + + NdrPointerUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&pDescKind, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1250], + (unsigned char)0 ); + + NdrPointerUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&ppFuncDesc, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1254], + (unsigned char)0 ); + + NdrPointerUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&ppVarDesc, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1464], + (unsigned char)0 ); + + NdrPointerUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&ppTypeComp, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1540], + (unsigned char)0 ); + + NdrUserMarshalUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&pDummy, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1568], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[6], + ( void __RPC_FAR * )ppTInfo); + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1250], + ( void __RPC_FAR * )pDescKind); + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1254], + ( void __RPC_FAR * )ppFuncDesc); + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1464], + ( void __RPC_FAR * )ppVarDesc); + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1540], + ( void __RPC_FAR * )ppTypeComp); + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1562], + ( void __RPC_FAR * )pDummy); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeComp_RemoteBind_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + ITypeInfo __RPC_FAR *_M15; + DESCKIND _M16; + LPFUNCDESC _M17; + LPVARDESC _M18; + ITypeComp __RPC_FAR *_M19; + CLEANLOCALSTORAGE _M20; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + ULONG lHashVal; + DESCKIND __RPC_FAR *pDescKind; + CLEANLOCALSTORAGE __RPC_FAR *pDummy; + LPFUNCDESC __RPC_FAR *ppFuncDesc; + ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo; + ITypeComp __RPC_FAR *__RPC_FAR *ppTypeComp; + LPVARDESC __RPC_FAR *ppVarDesc; + LPOLESTR szName; + WORD wFlags; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + szName = 0; + ppTInfo = 0; + pDescKind = 0; + ppFuncDesc = 0; + ppVarDesc = 0; + ppTypeComp = 0; + pDummy = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[96] ); + + NdrConformantStringUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&szName, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1248], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + lHashVal = *( ULONG __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(ULONG); + + wFlags = *( WORD __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(WORD); + + ppTInfo = &_M15; + _M15 = 0; + pDescKind = &_M16; + ppFuncDesc = &_M17; + _M17 = 0; + ppVarDesc = &_M18; + _M18 = 0; + ppTypeComp = &_M19; + _M19 = 0; + pDummy = &_M20; + MIDL_memset( + pDummy, + 0, + sizeof( CLEANLOCALSTORAGE )); + + *_pdwStubPhase = STUB_CALL_SERVER; + + + _RetVal = ITypeComp_Bind_Stub( + (ITypeComp *) ((CStdStubBuffer *)This)->pvServerObject, + szName, + lHashVal, + wFlags, + ppTInfo, + pDescKind, + ppFuncDesc, + ppVarDesc, + ppTypeComp, + pDummy); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 0U + 4U + 4U + 15U + 0U + 11U + 7U; + NdrPointerBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)ppTInfo, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[6] ); + + NdrPointerBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)ppFuncDesc, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1254] ); + + NdrPointerBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)ppVarDesc, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1464] ); + + NdrPointerBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)ppTypeComp, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1540] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + NdrPointerMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)ppTInfo, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[6] ); + + NdrPointerMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)pDescKind, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1250] ); + + NdrPointerMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)ppFuncDesc, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1254] ); + + NdrPointerMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)ppVarDesc, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1464] ); + + NdrPointerMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)ppTypeComp, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1540] ); + + NdrUserMarshalMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)pDummy, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1568] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)ppTInfo, + &__MIDL_TypeFormatString.Format[6] ); + + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)ppFuncDesc, + &__MIDL_TypeFormatString.Format[1254] ); + + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)ppVarDesc, + &__MIDL_TypeFormatString.Format[1464] ); + + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)ppTypeComp, + &__MIDL_TypeFormatString.Format[1540] ); + + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)pDummy, + &__MIDL_TypeFormatString.Format[1562] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +/* [call_as] */ HRESULT STDMETHODCALLTYPE ITypeComp_RemoteBindType_Proxy( + ITypeComp __RPC_FAR * This, + /* [in] */ LPOLESTR szName, + /* [in] */ ULONG lHashVal, + /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(ppTInfo) + { + MIDL_memset( + ppTInfo, + 0, + sizeof( ITypeInfo __RPC_FAR *__RPC_FAR * )); + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 4); + + + + if(!szName) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!ppTInfo) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 12U + 10U; + NdrConformantStringBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)szName, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1248] ); + + NdrProxyGetBuffer(This, &_StubMsg); + NdrConformantStringMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)szName, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1248] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( ULONG __RPC_FAR * )_StubMsg.Buffer = lHashVal; + _StubMsg.Buffer += sizeof(ULONG); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[130] ); + + NdrPointerUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&ppTInfo, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[6], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[6], + ( void __RPC_FAR * )ppTInfo); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeComp_RemoteBindType_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + ITypeInfo __RPC_FAR *_M23; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + ULONG lHashVal; + ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo; + LPOLESTR szName; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + szName = 0; + ppTInfo = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[130] ); + + NdrConformantStringUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&szName, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1248], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + lHashVal = *( ULONG __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(ULONG); + + ppTInfo = &_M23; + _M23 = 0; + + *_pdwStubPhase = STUB_CALL_SERVER; + + + _RetVal = ITypeComp_BindType_Stub( + (ITypeComp *) ((CStdStubBuffer *)This)->pvServerObject, + szName, + lHashVal, + ppTInfo); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 0U + 4U; + NdrPointerBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)ppTInfo, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[6] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + NdrPointerMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)ppTInfo, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[6] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)ppTInfo, + &__MIDL_TypeFormatString.Format[6] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + +const CINTERFACE_PROXY_VTABLE(5) _ITypeCompProxyVtbl = +{ + { &IID_ITypeComp }, + { + IUnknown_QueryInterface_Proxy, + IUnknown_AddRef_Proxy, + IUnknown_Release_Proxy , + ITypeComp_Bind_Proxy , + ITypeComp_BindType_Proxy + } +}; + + +static const PRPC_STUB_FUNCTION ITypeComp_table[] = +{ + ITypeComp_RemoteBind_Stub, + ITypeComp_RemoteBindType_Stub +}; + +const CInterfaceStubVtbl _ITypeCompStubVtbl = +{ + { + &IID_ITypeComp, + 0, + 5, + &ITypeComp_table[-3] + }, + { CStdStubBuffer_METHODS } +}; + + +/* Object interface: ITypeInfo, ver. 0.0, + GUID={0x00020401,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}} */ + + +extern const MIDL_STUB_DESC Object_StubDesc; + + +/* [call_as] */ HRESULT STDMETHODCALLTYPE ITypeInfo_RemoteGetTypeAttr_Proxy( + ITypeInfo __RPC_FAR * This, + /* [out] */ LPTYPEATTR __RPC_FAR *ppTypeAttr, + /* [out] */ CLEANLOCALSTORAGE __RPC_FAR *pDummy) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(ppTypeAttr) + { + *ppTypeAttr = 0; + } + if(pDummy) + { + MIDL_memset( + pDummy, + 0, + sizeof( CLEANLOCALSTORAGE )); + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 3); + + + + if(!ppTypeAttr) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!pDummy) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 0U; + NdrProxyGetBuffer(This, &_StubMsg); + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[142] ); + + NdrPointerUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&ppTypeAttr, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1578], + (unsigned char)0 ); + + NdrUserMarshalUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&pDummy, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1644], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1578], + ( void __RPC_FAR * )ppTypeAttr); + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1638], + ( void __RPC_FAR * )pDummy); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeInfo_RemoteGetTypeAttr_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + LPTYPEATTR _M24; + CLEANLOCALSTORAGE _M25; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + CLEANLOCALSTORAGE __RPC_FAR *pDummy; + LPTYPEATTR __RPC_FAR *ppTypeAttr; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + ppTypeAttr = 0; + pDummy = 0; + RpcTryFinally + { + ppTypeAttr = &_M24; + _M24 = 0; + pDummy = &_M25; + MIDL_memset( + pDummy, + 0, + sizeof( CLEANLOCALSTORAGE )); + + *_pdwStubPhase = STUB_CALL_SERVER; + + + _RetVal = ITypeInfo_GetTypeAttr_Stub( + (ITypeInfo *) ((CStdStubBuffer *)This)->pvServerObject, + ppTypeAttr, + pDummy); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 8U + 11U + 7U; + NdrPointerBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)ppTypeAttr, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1578] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + NdrPointerMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)ppTypeAttr, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1578] ); + + NdrUserMarshalMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)pDummy, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1644] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)ppTypeAttr, + &__MIDL_TypeFormatString.Format[1578] ); + + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)pDummy, + &__MIDL_TypeFormatString.Format[1638] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +HRESULT STDMETHODCALLTYPE ITypeInfo_GetTypeComp_Proxy( + ITypeInfo __RPC_FAR * This, + /* [out] */ ITypeComp __RPC_FAR *__RPC_FAR *ppTComp) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(ppTComp) + { + MIDL_memset( + ppTComp, + 0, + sizeof( ITypeComp __RPC_FAR *__RPC_FAR * )); + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 4); + + + + if(!ppTComp) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 0U; + NdrProxyGetBuffer(This, &_StubMsg); + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[152] ); + + NdrPointerUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&ppTComp, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1540], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1540], + ( void __RPC_FAR * )ppTComp); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeInfo_GetTypeComp_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + ITypeComp __RPC_FAR *_M26; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + ITypeComp __RPC_FAR *__RPC_FAR *ppTComp; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + ppTComp = 0; + RpcTryFinally + { + ppTComp = &_M26; + _M26 = 0; + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((ITypeInfo*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> GetTypeComp((ITypeInfo *) ((CStdStubBuffer *)This)->pvServerObject,ppTComp); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 0U + 4U; + NdrPointerBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)ppTComp, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1540] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + NdrPointerMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)ppTComp, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1540] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)ppTComp, + &__MIDL_TypeFormatString.Format[1540] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +/* [call_as] */ HRESULT STDMETHODCALLTYPE ITypeInfo_RemoteGetFuncDesc_Proxy( + ITypeInfo __RPC_FAR * This, + /* [in] */ UINT index, + /* [out] */ LPFUNCDESC __RPC_FAR *ppFuncDesc, + /* [out] */ CLEANLOCALSTORAGE __RPC_FAR *pDummy) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(ppFuncDesc) + { + *ppFuncDesc = 0; + } + if(pDummy) + { + MIDL_memset( + pDummy, + 0, + sizeof( CLEANLOCALSTORAGE )); + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 5); + + + + if(!ppFuncDesc) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!pDummy) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 4U; + NdrProxyGetBuffer(This, &_StubMsg); + *( UINT __RPC_FAR * )_StubMsg.Buffer = index; + _StubMsg.Buffer += sizeof(UINT); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[158] ); + + NdrPointerUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&ppFuncDesc, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1254], + (unsigned char)0 ); + + NdrUserMarshalUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&pDummy, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1660], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1254], + ( void __RPC_FAR * )ppFuncDesc); + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1654], + ( void __RPC_FAR * )pDummy); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeInfo_RemoteGetFuncDesc_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + LPFUNCDESC _M27; + CLEANLOCALSTORAGE _M28; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + UINT index; + CLEANLOCALSTORAGE __RPC_FAR *pDummy; + LPFUNCDESC __RPC_FAR *ppFuncDesc; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + ppFuncDesc = 0; + pDummy = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[158] ); + + index = *( UINT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(UINT); + + ppFuncDesc = &_M27; + _M27 = 0; + pDummy = &_M28; + MIDL_memset( + pDummy, + 0, + sizeof( CLEANLOCALSTORAGE )); + + *_pdwStubPhase = STUB_CALL_SERVER; + + + _RetVal = ITypeInfo_GetFuncDesc_Stub( + (ITypeInfo *) ((CStdStubBuffer *)This)->pvServerObject, + index, + ppFuncDesc, + pDummy); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 8U + 11U + 7U; + NdrPointerBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)ppFuncDesc, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1254] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + NdrPointerMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)ppFuncDesc, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1254] ); + + NdrUserMarshalMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)pDummy, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1660] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)ppFuncDesc, + &__MIDL_TypeFormatString.Format[1254] ); + + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)pDummy, + &__MIDL_TypeFormatString.Format[1654] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +/* [call_as] */ HRESULT STDMETHODCALLTYPE ITypeInfo_RemoteGetVarDesc_Proxy( + ITypeInfo __RPC_FAR * This, + /* [in] */ UINT index, + /* [out] */ LPVARDESC __RPC_FAR *ppVarDesc, + /* [out] */ CLEANLOCALSTORAGE __RPC_FAR *pDummy) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(ppVarDesc) + { + *ppVarDesc = 0; + } + if(pDummy) + { + MIDL_memset( + pDummy, + 0, + sizeof( CLEANLOCALSTORAGE )); + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 6); + + + + if(!ppVarDesc) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!pDummy) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 4U; + NdrProxyGetBuffer(This, &_StubMsg); + *( UINT __RPC_FAR * )_StubMsg.Buffer = index; + _StubMsg.Buffer += sizeof(UINT); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[170] ); + + NdrPointerUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&ppVarDesc, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1464], + (unsigned char)0 ); + + NdrUserMarshalUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&pDummy, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1676], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1464], + ( void __RPC_FAR * )ppVarDesc); + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1670], + ( void __RPC_FAR * )pDummy); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeInfo_RemoteGetVarDesc_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + LPVARDESC _M29; + CLEANLOCALSTORAGE _M30; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + UINT index; + CLEANLOCALSTORAGE __RPC_FAR *pDummy; + LPVARDESC __RPC_FAR *ppVarDesc; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + ppVarDesc = 0; + pDummy = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[170] ); + + index = *( UINT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(UINT); + + ppVarDesc = &_M29; + _M29 = 0; + pDummy = &_M30; + MIDL_memset( + pDummy, + 0, + sizeof( CLEANLOCALSTORAGE )); + + *_pdwStubPhase = STUB_CALL_SERVER; + + + _RetVal = ITypeInfo_GetVarDesc_Stub( + (ITypeInfo *) ((CStdStubBuffer *)This)->pvServerObject, + index, + ppVarDesc, + pDummy); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 8U + 11U + 7U; + NdrPointerBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)ppVarDesc, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1464] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + NdrPointerMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)ppVarDesc, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1464] ); + + NdrUserMarshalMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)pDummy, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1676] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)ppVarDesc, + &__MIDL_TypeFormatString.Format[1464] ); + + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)pDummy, + &__MIDL_TypeFormatString.Format[1670] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +/* [call_as] */ HRESULT STDMETHODCALLTYPE ITypeInfo_RemoteGetNames_Proxy( + ITypeInfo __RPC_FAR * This, + /* [in] */ MEMBERID memid, + /* [length_is][size_is][out] */ BSTR __RPC_FAR *rgBstrNames, + /* [in] */ UINT cMaxNames, + /* [out] */ UINT __RPC_FAR *pcNames) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(rgBstrNames) + { + MIDL_memset( + rgBstrNames, + 0, + cMaxNames * sizeof( BSTR )); + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 7); + + + + if(!rgBstrNames) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!pcNames) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 4U + 4U; + NdrProxyGetBuffer(This, &_StubMsg); + *( MEMBERID __RPC_FAR * )_StubMsg.Buffer = memid; + _StubMsg.Buffer += sizeof(MEMBERID); + + *( UINT __RPC_FAR * )_StubMsg.Buffer = cMaxNames; + _StubMsg.Buffer += sizeof(UINT); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[182] ); + + NdrComplexArrayUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&rgBstrNames, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1690], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *pcNames = *( UINT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(UINT); + + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + _StubMsg.MaxCount = cMaxNames; + _StubMsg.Offset = 0; + _StubMsg.ActualCount = _StubMsg.MaxCount; + + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1686], + ( void __RPC_FAR * )rgBstrNames); + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[2], + ( void __RPC_FAR * )pcNames); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeInfo_RemoteGetNames_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + UINT _M34; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + UINT cMaxNames; + MEMBERID memid; + UINT __RPC_FAR *pcNames; + BSTR __RPC_FAR *rgBstrNames; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + rgBstrNames = 0; + pcNames = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[182] ); + + memid = *( MEMBERID __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(MEMBERID); + + cMaxNames = *( UINT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(UINT); + + rgBstrNames = NdrAllocate(&_StubMsg,cMaxNames * 4); + pcNames = &_M34; + + *_pdwStubPhase = STUB_CALL_SERVER; + + + _RetVal = ITypeInfo_GetNames_Stub( + (ITypeInfo *) ((CStdStubBuffer *)This)->pvServerObject, + memid, + rgBstrNames, + cMaxNames, + pcNames); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 12U + 7U + 7U; + _StubMsg.MaxCount = cMaxNames; + _StubMsg.Offset = 0; + _StubMsg.ActualCount = pcNames ? *pcNames : 0; + + NdrComplexArrayBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)rgBstrNames, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1690] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + _StubMsg.MaxCount = cMaxNames; + _StubMsg.Offset = 0; + _StubMsg.ActualCount = pcNames ? *pcNames : 0; + + NdrComplexArrayMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)rgBstrNames, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1690] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( UINT __RPC_FAR * )_StubMsg.Buffer = *pcNames; + _StubMsg.Buffer += sizeof(UINT); + + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + _StubMsg.MaxCount = cMaxNames; + _StubMsg.Offset = 0; + _StubMsg.ActualCount = pcNames ? *pcNames : 0; + + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)rgBstrNames, + &__MIDL_TypeFormatString.Format[1686] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +HRESULT STDMETHODCALLTYPE ITypeInfo_GetRefTypeOfImplType_Proxy( + ITypeInfo __RPC_FAR * This, + /* [in] */ UINT index, + /* [out] */ HREFTYPE __RPC_FAR *pRefType) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 8); + + + + if(!pRefType) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 4U; + NdrProxyGetBuffer(This, &_StubMsg); + *( UINT __RPC_FAR * )_StubMsg.Buffer = index; + _StubMsg.Buffer += sizeof(UINT); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[196] ); + + *pRefType = *( HREFTYPE __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HREFTYPE); + + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[2], + ( void __RPC_FAR * )pRefType); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeInfo_GetRefTypeOfImplType_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + HREFTYPE _M35; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + UINT index; + HREFTYPE __RPC_FAR *pRefType; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + pRefType = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[196] ); + + index = *( UINT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(UINT); + + pRefType = &_M35; + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((ITypeInfo*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> GetRefTypeOfImplType( + (ITypeInfo *) ((CStdStubBuffer *)This)->pvServerObject, + index, + pRefType); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 4U + 4U; + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + *( HREFTYPE __RPC_FAR * )_StubMsg.Buffer = *pRefType; + _StubMsg.Buffer += sizeof(HREFTYPE); + + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +HRESULT STDMETHODCALLTYPE ITypeInfo_GetImplTypeFlags_Proxy( + ITypeInfo __RPC_FAR * This, + /* [in] */ UINT index, + /* [out] */ INT __RPC_FAR *pImplTypeFlags) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 9); + + + + if(!pImplTypeFlags) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 4U; + NdrProxyGetBuffer(This, &_StubMsg); + *( UINT __RPC_FAR * )_StubMsg.Buffer = index; + _StubMsg.Buffer += sizeof(UINT); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[196] ); + + *pImplTypeFlags = *( INT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(INT); + + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[2], + ( void __RPC_FAR * )pImplTypeFlags); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeInfo_GetImplTypeFlags_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + INT _M36; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + UINT index; + INT __RPC_FAR *pImplTypeFlags; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + pImplTypeFlags = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[196] ); + + index = *( UINT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(UINT); + + pImplTypeFlags = &_M36; + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((ITypeInfo*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> GetImplTypeFlags( + (ITypeInfo *) ((CStdStubBuffer *)This)->pvServerObject, + index, + pImplTypeFlags); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 4U + 4U; + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + *( INT __RPC_FAR * )_StubMsg.Buffer = *pImplTypeFlags; + _StubMsg.Buffer += sizeof(INT); + + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +/* [call_as] */ HRESULT STDMETHODCALLTYPE ITypeInfo_LocalGetIDsOfNames_Proxy( + ITypeInfo __RPC_FAR * This) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 10); + + + + RpcTryFinally + { + + _StubMsg.BufferLength = 0U; + NdrProxyGetBuffer(This, &_StubMsg); + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[88] ); + + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeInfo_LocalGetIDsOfNames_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + RpcTryFinally + { + + *_pdwStubPhase = STUB_CALL_SERVER; + + + _RetVal = ITypeInfo_GetIDsOfNames_Stub((ITypeInfo *) ((CStdStubBuffer *)This)->pvServerObject); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 4U; + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +/* [call_as] */ HRESULT STDMETHODCALLTYPE ITypeInfo_LocalInvoke_Proxy( + ITypeInfo __RPC_FAR * This) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 11); + + + + RpcTryFinally + { + + _StubMsg.BufferLength = 0U; + NdrProxyGetBuffer(This, &_StubMsg); + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[88] ); + + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeInfo_LocalInvoke_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + RpcTryFinally + { + + *_pdwStubPhase = STUB_CALL_SERVER; + + + _RetVal = ITypeInfo_Invoke_Stub((ITypeInfo *) ((CStdStubBuffer *)This)->pvServerObject); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 4U; + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +/* [call_as] */ HRESULT STDMETHODCALLTYPE ITypeInfo_RemoteGetDocumentation_Proxy( + ITypeInfo __RPC_FAR * This, + /* [in] */ MEMBERID memid, + /* [in] */ DWORD refPtrFlags, + /* [out] */ BSTR __RPC_FAR *pBstrName, + /* [out] */ BSTR __RPC_FAR *pBstrDocString, + /* [out] */ DWORD __RPC_FAR *pdwHelpContext, + /* [out] */ BSTR __RPC_FAR *pBstrHelpFile) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(pBstrName) + { + MIDL_memset( + pBstrName, + 0, + sizeof( BSTR )); + } + if(pBstrDocString) + { + MIDL_memset( + pBstrDocString, + 0, + sizeof( BSTR )); + } + if(pBstrHelpFile) + { + MIDL_memset( + pBstrHelpFile, + 0, + sizeof( BSTR )); + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 12); + + + + if(!pBstrName) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!pBstrDocString) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!pdwHelpContext) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!pBstrHelpFile) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 4U + 4U; + NdrProxyGetBuffer(This, &_StubMsg); + *( MEMBERID __RPC_FAR * )_StubMsg.Buffer = memid; + _StubMsg.Buffer += sizeof(MEMBERID); + + *( DWORD __RPC_FAR * )_StubMsg.Buffer = refPtrFlags; + _StubMsg.Buffer += sizeof(DWORD); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[204] ); + + NdrUserMarshalUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&pBstrName, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128], + (unsigned char)0 ); + + NdrUserMarshalUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&pBstrDocString, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *pdwHelpContext = *( DWORD __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(DWORD); + + NdrUserMarshalUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&pBstrHelpFile, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1708], + ( void __RPC_FAR * )pBstrName); + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1708], + ( void __RPC_FAR * )pBstrDocString); + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[2], + ( void __RPC_FAR * )pdwHelpContext); + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1708], + ( void __RPC_FAR * )pBstrHelpFile); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeInfo_RemoteGetDocumentation_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + BSTR _M37; + BSTR _M38; + DWORD _M39; + BSTR _M40; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + MEMBERID memid; + BSTR __RPC_FAR *pBstrDocString; + BSTR __RPC_FAR *pBstrHelpFile; + BSTR __RPC_FAR *pBstrName; + DWORD __RPC_FAR *pdwHelpContext; + DWORD refPtrFlags; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + pBstrName = 0; + pBstrDocString = 0; + pdwHelpContext = 0; + pBstrHelpFile = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[204] ); + + memid = *( MEMBERID __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(MEMBERID); + + refPtrFlags = *( DWORD __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(DWORD); + + pBstrName = &_M37; + MIDL_memset( + pBstrName, + 0, + sizeof( BSTR )); + pBstrDocString = &_M38; + MIDL_memset( + pBstrDocString, + 0, + sizeof( BSTR )); + pdwHelpContext = &_M39; + pBstrHelpFile = &_M40; + MIDL_memset( + pBstrHelpFile, + 0, + sizeof( BSTR )); + + *_pdwStubPhase = STUB_CALL_SERVER; + + + _RetVal = ITypeInfo_GetDocumentation_Stub( + (ITypeInfo *) ((CStdStubBuffer *)This)->pvServerObject, + memid, + refPtrFlags, + pBstrName, + pBstrDocString, + pdwHelpContext, + pBstrHelpFile); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 8U + 15U + 11U + 11U + 11U; + NdrUserMarshalBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)pBstrName, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128] ); + + NdrUserMarshalBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)pBstrDocString, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128] ); + + NdrUserMarshalBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)pBstrHelpFile, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + NdrUserMarshalMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)pBstrName, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128] ); + + NdrUserMarshalMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)pBstrDocString, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( DWORD __RPC_FAR * )_StubMsg.Buffer = *pdwHelpContext; + _StubMsg.Buffer += sizeof(DWORD); + + NdrUserMarshalMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)pBstrHelpFile, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)pBstrName, + &__MIDL_TypeFormatString.Format[1708] ); + + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)pBstrDocString, + &__MIDL_TypeFormatString.Format[1708] ); + + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)pBstrHelpFile, + &__MIDL_TypeFormatString.Format[1708] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +/* [call_as] */ HRESULT STDMETHODCALLTYPE ITypeInfo_RemoteGetDllEntry_Proxy( + ITypeInfo __RPC_FAR * This, + /* [in] */ MEMBERID memid, + /* [in] */ INVOKEKIND invKind, + /* [in] */ DWORD refPtrFlags, + /* [out] */ BSTR __RPC_FAR *pBstrDllName, + /* [out] */ BSTR __RPC_FAR *pBstrName, + /* [out] */ WORD __RPC_FAR *pwOrdinal) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(pBstrDllName) + { + MIDL_memset( + pBstrDllName, + 0, + sizeof( BSTR )); + } + if(pBstrName) + { + MIDL_memset( + pBstrName, + 0, + sizeof( BSTR )); + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 13); + + + + if(!pBstrDllName) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!pBstrName) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!pwOrdinal) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 4U + 4U + 4U; + NdrProxyGetBuffer(This, &_StubMsg); + *( MEMBERID __RPC_FAR * )_StubMsg.Buffer = memid; + _StubMsg.Buffer += sizeof(MEMBERID); + + NdrSimpleTypeMarshall( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( unsigned char __RPC_FAR * )&invKind, + 14); + *( DWORD __RPC_FAR * )_StubMsg.Buffer = refPtrFlags; + _StubMsg.Buffer += sizeof(DWORD); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[226] ); + + NdrUserMarshalUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&pBstrDllName, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128], + (unsigned char)0 ); + + NdrUserMarshalUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&pBstrName, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 1) & ~ 0x1); + *pwOrdinal = *( WORD __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(WORD); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1708], + ( void __RPC_FAR * )pBstrDllName); + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1708], + ( void __RPC_FAR * )pBstrName); + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1712], + ( void __RPC_FAR * )pwOrdinal); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeInfo_RemoteGetDllEntry_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + BSTR _M41; + BSTR _M42; + WORD _M43; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + INVOKEKIND invKind; + MEMBERID memid; + BSTR __RPC_FAR *pBstrDllName; + BSTR __RPC_FAR *pBstrName; + WORD __RPC_FAR *pwOrdinal; + DWORD refPtrFlags; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + pBstrDllName = 0; + pBstrName = 0; + pwOrdinal = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[226] ); + + memid = *( MEMBERID __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(MEMBERID); + + NdrSimpleTypeUnmarshall( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( unsigned char __RPC_FAR * )&invKind, + 14); + refPtrFlags = *( DWORD __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(DWORD); + + pBstrDllName = &_M41; + MIDL_memset( + pBstrDllName, + 0, + sizeof( BSTR )); + pBstrName = &_M42; + MIDL_memset( + pBstrName, + 0, + sizeof( BSTR )); + pwOrdinal = &_M43; + + *_pdwStubPhase = STUB_CALL_SERVER; + + + _RetVal = ITypeInfo_GetDllEntry_Stub( + (ITypeInfo *) ((CStdStubBuffer *)This)->pvServerObject, + memid, + invKind, + refPtrFlags, + pBstrDllName, + pBstrName, + pwOrdinal); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 8U + 15U + 5U + 10U; + NdrUserMarshalBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)pBstrDllName, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128] ); + + NdrUserMarshalBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)pBstrName, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + NdrUserMarshalMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)pBstrDllName, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128] ); + + NdrUserMarshalMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)pBstrName, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 1) & ~ 0x1); + *( WORD __RPC_FAR * )_StubMsg.Buffer = *pwOrdinal; + _StubMsg.Buffer += sizeof(WORD); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)pBstrDllName, + &__MIDL_TypeFormatString.Format[1708] ); + + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)pBstrName, + &__MIDL_TypeFormatString.Format[1708] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +HRESULT STDMETHODCALLTYPE ITypeInfo_GetRefTypeInfo_Proxy( + ITypeInfo __RPC_FAR * This, + /* [in] */ HREFTYPE hRefType, + /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(ppTInfo) + { + MIDL_memset( + ppTInfo, + 0, + sizeof( ITypeInfo __RPC_FAR *__RPC_FAR * )); + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 14); + + + + if(!ppTInfo) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 4U; + NdrProxyGetBuffer(This, &_StubMsg); + *( HREFTYPE __RPC_FAR * )_StubMsg.Buffer = hRefType; + _StubMsg.Buffer += sizeof(HREFTYPE); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[246] ); + + NdrPointerUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&ppTInfo, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[6], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[6], + ( void __RPC_FAR * )ppTInfo); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeInfo_GetRefTypeInfo_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + ITypeInfo __RPC_FAR *_M44; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + HREFTYPE hRefType; + ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + ppTInfo = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[246] ); + + hRefType = *( HREFTYPE __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HREFTYPE); + + ppTInfo = &_M44; + _M44 = 0; + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((ITypeInfo*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> GetRefTypeInfo( + (ITypeInfo *) ((CStdStubBuffer *)This)->pvServerObject, + hRefType, + ppTInfo); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 0U + 4U; + NdrPointerBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)ppTInfo, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[6] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + NdrPointerMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)ppTInfo, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[6] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)ppTInfo, + &__MIDL_TypeFormatString.Format[6] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +/* [call_as] */ HRESULT STDMETHODCALLTYPE ITypeInfo_LocalAddressOfMember_Proxy( + ITypeInfo __RPC_FAR * This) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 15); + + + + RpcTryFinally + { + + _StubMsg.BufferLength = 0U; + NdrProxyGetBuffer(This, &_StubMsg); + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[88] ); + + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeInfo_LocalAddressOfMember_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + RpcTryFinally + { + + *_pdwStubPhase = STUB_CALL_SERVER; + + + _RetVal = ITypeInfo_AddressOfMember_Stub((ITypeInfo *) ((CStdStubBuffer *)This)->pvServerObject); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 4U; + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +/* [call_as] */ HRESULT STDMETHODCALLTYPE ITypeInfo_RemoteCreateInstance_Proxy( + ITypeInfo __RPC_FAR * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ IUnknown __RPC_FAR *__RPC_FAR *ppvObj) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(ppvObj) + { + MIDL_memset( + ppvObj, + 0, + sizeof( IUnknown __RPC_FAR *__RPC_FAR * )); + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 16); + + + + if(!riid) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!ppvObj) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 0U; + NdrSimpleStructBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)riid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[38] ); + + NdrProxyGetBuffer(This, &_StubMsg); + NdrSimpleStructMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)riid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[38] ); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[254] ); + + NdrPointerUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&ppvObj, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1716], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + _StubMsg.MaxCount = (unsigned long) ( riid ); + + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1716], + ( void __RPC_FAR * )ppvObj); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeInfo_RemoteCreateInstance_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + IUnknown __RPC_FAR *__RPC_FAR *_M45; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + IUnknown __RPC_FAR *__RPC_FAR *ppvObj; + IID* riid = 0; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + ppvObj = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[254] ); + + NdrSimpleStructUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&riid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[38], + (unsigned char)0 ); + + ppvObj = (void *)&_M45; + _M45 = 0; + + *_pdwStubPhase = STUB_CALL_SERVER; + + + _RetVal = ITypeInfo_CreateInstance_Stub( + (ITypeInfo *) ((CStdStubBuffer *)This)->pvServerObject, + riid, + ppvObj); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 0U + 4U; + _StubMsg.MaxCount = (unsigned long) ( riid ); + + NdrPointerBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)ppvObj, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1716] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + _StubMsg.MaxCount = (unsigned long) ( riid ); + + NdrPointerMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)ppvObj, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1716] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + _StubMsg.MaxCount = (unsigned long) ( riid ); + + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)ppvObj, + &__MIDL_TypeFormatString.Format[1716] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +HRESULT STDMETHODCALLTYPE ITypeInfo_GetMops_Proxy( + ITypeInfo __RPC_FAR * This, + /* [in] */ MEMBERID memid, + /* [out] */ BSTR __RPC_FAR *pBstrMops) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(pBstrMops) + { + MIDL_memset( + pBstrMops, + 0, + sizeof( BSTR )); + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 17); + + + + if(!pBstrMops) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 4U; + NdrProxyGetBuffer(This, &_StubMsg); + *( MEMBERID __RPC_FAR * )_StubMsg.Buffer = memid; + _StubMsg.Buffer += sizeof(MEMBERID); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[264] ); + + NdrUserMarshalUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&pBstrMops, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1708], + ( void __RPC_FAR * )pBstrMops); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeInfo_GetMops_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + BSTR _M46; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + MEMBERID memid; + BSTR __RPC_FAR *pBstrMops; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + pBstrMops = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[264] ); + + memid = *( MEMBERID __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(MEMBERID); + + pBstrMops = &_M46; + MIDL_memset( + pBstrMops, + 0, + sizeof( BSTR )); + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((ITypeInfo*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> GetMops( + (ITypeInfo *) ((CStdStubBuffer *)This)->pvServerObject, + memid, + pBstrMops); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 8U + 11U; + NdrUserMarshalBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)pBstrMops, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + NdrUserMarshalMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)pBstrMops, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)pBstrMops, + &__MIDL_TypeFormatString.Format[1708] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +/* [call_as] */ HRESULT STDMETHODCALLTYPE ITypeInfo_RemoteGetContainingTypeLib_Proxy( + ITypeInfo __RPC_FAR * This, + /* [out] */ ITypeLib __RPC_FAR *__RPC_FAR *ppTLib, + /* [out] */ UINT __RPC_FAR *pIndex) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(ppTLib) + { + MIDL_memset( + ppTLib, + 0, + sizeof( ITypeLib __RPC_FAR *__RPC_FAR * )); + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 18); + + + + if(!ppTLib) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!pIndex) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 0U; + NdrProxyGetBuffer(This, &_StubMsg); + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[272] ); + + NdrPointerUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&ppTLib, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1726], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *pIndex = *( UINT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(UINT); + + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1726], + ( void __RPC_FAR * )ppTLib); + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[2], + ( void __RPC_FAR * )pIndex); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeInfo_RemoteGetContainingTypeLib_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + ITypeLib __RPC_FAR *_M47; + UINT _M48; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + UINT __RPC_FAR *pIndex; + ITypeLib __RPC_FAR *__RPC_FAR *ppTLib; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + ppTLib = 0; + pIndex = 0; + RpcTryFinally + { + ppTLib = &_M47; + _M47 = 0; + pIndex = &_M48; + + *_pdwStubPhase = STUB_CALL_SERVER; + + + _RetVal = ITypeInfo_GetContainingTypeLib_Stub( + (ITypeInfo *) ((CStdStubBuffer *)This)->pvServerObject, + ppTLib, + pIndex); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 0U + 4U + 4U; + NdrPointerBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)ppTLib, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1726] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + NdrPointerMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)ppTLib, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1726] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( UINT __RPC_FAR * )_StubMsg.Buffer = *pIndex; + _StubMsg.Buffer += sizeof(UINT); + + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)ppTLib, + &__MIDL_TypeFormatString.Format[1726] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +/* [call_as] */ HRESULT STDMETHODCALLTYPE ITypeInfo_LocalReleaseTypeAttr_Proxy( + ITypeInfo __RPC_FAR * This) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 19); + + + + RpcTryFinally + { + + _StubMsg.BufferLength = 0U; + NdrProxyGetBuffer(This, &_StubMsg); + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[88] ); + + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeInfo_LocalReleaseTypeAttr_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + RpcTryFinally + { + + *_pdwStubPhase = STUB_CALL_SERVER; + + + _RetVal = ITypeInfo_ReleaseTypeAttr_Stub((ITypeInfo *) ((CStdStubBuffer *)This)->pvServerObject); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 4U; + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +/* [call_as] */ HRESULT STDMETHODCALLTYPE ITypeInfo_LocalReleaseFuncDesc_Proxy( + ITypeInfo __RPC_FAR * This) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 20); + + + + RpcTryFinally + { + + _StubMsg.BufferLength = 0U; + NdrProxyGetBuffer(This, &_StubMsg); + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[88] ); + + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeInfo_LocalReleaseFuncDesc_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + RpcTryFinally + { + + *_pdwStubPhase = STUB_CALL_SERVER; + + + _RetVal = ITypeInfo_ReleaseFuncDesc_Stub((ITypeInfo *) ((CStdStubBuffer *)This)->pvServerObject); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 4U; + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +/* [call_as] */ HRESULT STDMETHODCALLTYPE ITypeInfo_LocalReleaseVarDesc_Proxy( + ITypeInfo __RPC_FAR * This) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 21); + + + + RpcTryFinally + { + + _StubMsg.BufferLength = 0U; + NdrProxyGetBuffer(This, &_StubMsg); + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[88] ); + + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeInfo_LocalReleaseVarDesc_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + RpcTryFinally + { + + *_pdwStubPhase = STUB_CALL_SERVER; + + + _RetVal = ITypeInfo_ReleaseVarDesc_Stub((ITypeInfo *) ((CStdStubBuffer *)This)->pvServerObject); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 4U; + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + +const CINTERFACE_PROXY_VTABLE(22) _ITypeInfoProxyVtbl = +{ + { &IID_ITypeInfo }, + { + IUnknown_QueryInterface_Proxy, + IUnknown_AddRef_Proxy, + IUnknown_Release_Proxy , + ITypeInfo_GetTypeAttr_Proxy , + ITypeInfo_GetTypeComp_Proxy , + ITypeInfo_GetFuncDesc_Proxy , + ITypeInfo_GetVarDesc_Proxy , + ITypeInfo_GetNames_Proxy , + ITypeInfo_GetRefTypeOfImplType_Proxy , + ITypeInfo_GetImplTypeFlags_Proxy , + ITypeInfo_GetIDsOfNames_Proxy , + ITypeInfo_Invoke_Proxy , + ITypeInfo_GetDocumentation_Proxy , + ITypeInfo_GetDllEntry_Proxy , + ITypeInfo_GetRefTypeInfo_Proxy , + ITypeInfo_AddressOfMember_Proxy , + ITypeInfo_CreateInstance_Proxy , + ITypeInfo_GetMops_Proxy , + ITypeInfo_GetContainingTypeLib_Proxy , + ITypeInfo_ReleaseTypeAttr_Proxy , + ITypeInfo_ReleaseFuncDesc_Proxy , + ITypeInfo_ReleaseVarDesc_Proxy + } +}; + + +static const PRPC_STUB_FUNCTION ITypeInfo_table[] = +{ + ITypeInfo_RemoteGetTypeAttr_Stub, + ITypeInfo_GetTypeComp_Stub, + ITypeInfo_RemoteGetFuncDesc_Stub, + ITypeInfo_RemoteGetVarDesc_Stub, + ITypeInfo_RemoteGetNames_Stub, + ITypeInfo_GetRefTypeOfImplType_Stub, + ITypeInfo_GetImplTypeFlags_Stub, + ITypeInfo_LocalGetIDsOfNames_Stub, + ITypeInfo_LocalInvoke_Stub, + ITypeInfo_RemoteGetDocumentation_Stub, + ITypeInfo_RemoteGetDllEntry_Stub, + ITypeInfo_GetRefTypeInfo_Stub, + ITypeInfo_LocalAddressOfMember_Stub, + ITypeInfo_RemoteCreateInstance_Stub, + ITypeInfo_GetMops_Stub, + ITypeInfo_RemoteGetContainingTypeLib_Stub, + ITypeInfo_LocalReleaseTypeAttr_Stub, + ITypeInfo_LocalReleaseFuncDesc_Stub, + ITypeInfo_LocalReleaseVarDesc_Stub +}; + +const CInterfaceStubVtbl _ITypeInfoStubVtbl = +{ + { + &IID_ITypeInfo, + 0, + 22, + &ITypeInfo_table[-3] + }, + { CStdStubBuffer_METHODS } +}; + + +/* Object interface: ITypeInfo2, ver. 0.0, + GUID={0x00020412,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}} */ + + +extern const MIDL_STUB_DESC Object_StubDesc; + + +HRESULT STDMETHODCALLTYPE ITypeInfo2_GetTypeKind_Proxy( + ITypeInfo2 __RPC_FAR * This, + /* [out] */ TYPEKIND __RPC_FAR *pTypeKind) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 22); + + + + if(!pTypeKind) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 0U; + NdrProxyGetBuffer(This, &_StubMsg); + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[282] ); + + NdrPointerUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&pTypeKind, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1250], + (unsigned char)0 ); + + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1250], + ( void __RPC_FAR * )pTypeKind); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeInfo2_GetTypeKind_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + TYPEKIND _M49; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + TYPEKIND __RPC_FAR *pTypeKind; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + pTypeKind = 0; + RpcTryFinally + { + pTypeKind = &_M49; + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((ITypeInfo2*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> GetTypeKind((ITypeInfo2 *) ((CStdStubBuffer *)This)->pvServerObject,pTypeKind); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 4U + 4U; + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + NdrPointerMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)pTypeKind, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1250] ); + + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +HRESULT STDMETHODCALLTYPE ITypeInfo2_GetTypeFlags_Proxy( + ITypeInfo2 __RPC_FAR * This, + /* [out] */ ULONG __RPC_FAR *pTypeFlags) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 23); + + + + if(!pTypeFlags) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 0U; + NdrProxyGetBuffer(This, &_StubMsg); + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[0] ); + + *pTypeFlags = *( ULONG __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(ULONG); + + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[2], + ( void __RPC_FAR * )pTypeFlags); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeInfo2_GetTypeFlags_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + ULONG _M50; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + ULONG __RPC_FAR *pTypeFlags; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + pTypeFlags = 0; + RpcTryFinally + { + pTypeFlags = &_M50; + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((ITypeInfo2*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> GetTypeFlags((ITypeInfo2 *) ((CStdStubBuffer *)This)->pvServerObject,pTypeFlags); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 4U + 4U; + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + *( ULONG __RPC_FAR * )_StubMsg.Buffer = *pTypeFlags; + _StubMsg.Buffer += sizeof(ULONG); + + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +HRESULT STDMETHODCALLTYPE ITypeInfo2_GetFuncIndexOfMemId_Proxy( + ITypeInfo2 __RPC_FAR * This, + /* [in] */ MEMBERID memid, + /* [in] */ INVOKEKIND invKind, + /* [out] */ UINT __RPC_FAR *pFuncIndex) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 24); + + + + if(!pFuncIndex) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 4U + 4U; + NdrProxyGetBuffer(This, &_StubMsg); + *( MEMBERID __RPC_FAR * )_StubMsg.Buffer = memid; + _StubMsg.Buffer += sizeof(MEMBERID); + + NdrSimpleTypeMarshall( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( unsigned char __RPC_FAR * )&invKind, + 14); + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[288] ); + + *pFuncIndex = *( UINT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(UINT); + + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[2], + ( void __RPC_FAR * )pFuncIndex); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeInfo2_GetFuncIndexOfMemId_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + UINT _M51; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + INVOKEKIND invKind; + MEMBERID memid; + UINT __RPC_FAR *pFuncIndex; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + pFuncIndex = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[288] ); + + memid = *( MEMBERID __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(MEMBERID); + + NdrSimpleTypeUnmarshall( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( unsigned char __RPC_FAR * )&invKind, + 14); + pFuncIndex = &_M51; + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((ITypeInfo2*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> GetFuncIndexOfMemId( + (ITypeInfo2 *) ((CStdStubBuffer *)This)->pvServerObject, + memid, + invKind, + pFuncIndex); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 4U + 4U; + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + *( UINT __RPC_FAR * )_StubMsg.Buffer = *pFuncIndex; + _StubMsg.Buffer += sizeof(UINT); + + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +HRESULT STDMETHODCALLTYPE ITypeInfo2_GetVarIndexOfMemId_Proxy( + ITypeInfo2 __RPC_FAR * This, + /* [in] */ MEMBERID memid, + /* [out] */ UINT __RPC_FAR *pVarIndex) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 25); + + + + if(!pVarIndex) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 4U; + NdrProxyGetBuffer(This, &_StubMsg); + *( MEMBERID __RPC_FAR * )_StubMsg.Buffer = memid; + _StubMsg.Buffer += sizeof(MEMBERID); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[196] ); + + *pVarIndex = *( UINT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(UINT); + + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[2], + ( void __RPC_FAR * )pVarIndex); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeInfo2_GetVarIndexOfMemId_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + UINT _M52; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + MEMBERID memid; + UINT __RPC_FAR *pVarIndex; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + pVarIndex = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[196] ); + + memid = *( MEMBERID __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(MEMBERID); + + pVarIndex = &_M52; + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((ITypeInfo2*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> GetVarIndexOfMemId( + (ITypeInfo2 *) ((CStdStubBuffer *)This)->pvServerObject, + memid, + pVarIndex); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 4U + 4U; + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + *( UINT __RPC_FAR * )_StubMsg.Buffer = *pVarIndex; + _StubMsg.Buffer += sizeof(UINT); + + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +HRESULT STDMETHODCALLTYPE ITypeInfo2_GetCustData_Proxy( + ITypeInfo2 __RPC_FAR * This, + /* [in] */ REFGUID guid, + /* [out] */ VARIANT __RPC_FAR *pVarVal) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(pVarVal) + { + MIDL_memset( + pVarVal, + 0, + sizeof( VARIANT )); + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 26); + + + + if(!guid) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!pVarVal) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 0U; + NdrSimpleStructBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)guid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[38] ); + + NdrProxyGetBuffer(This, &_StubMsg); + NdrSimpleStructMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)guid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[38] ); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[298] ); + + NdrUserMarshalUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&pVarVal, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1110], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1102], + ( void __RPC_FAR * )pVarVal); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeInfo2_GetCustData_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + VARIANT _M53; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + REFGUID guid = 0; + VARIANT __RPC_FAR *pVarVal; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + pVarVal = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[298] ); + + NdrSimpleStructUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&guid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[38], + (unsigned char)0 ); + + pVarVal = &_M53; + MIDL_memset( + pVarVal, + 0, + sizeof( VARIANT )); + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((ITypeInfo2*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> GetCustData( + (ITypeInfo2 *) ((CStdStubBuffer *)This)->pvServerObject, + guid, + pVarVal); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 8U + 11U; + NdrUserMarshalBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)pVarVal, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1110] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + NdrUserMarshalMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)pVarVal, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1110] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)pVarVal, + &__MIDL_TypeFormatString.Format[1102] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +HRESULT STDMETHODCALLTYPE ITypeInfo2_GetFuncCustData_Proxy( + ITypeInfo2 __RPC_FAR * This, + /* [in] */ UINT index, + /* [in] */ REFGUID guid, + /* [out] */ VARIANT __RPC_FAR *pVarVal) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(pVarVal) + { + MIDL_memset( + pVarVal, + 0, + sizeof( VARIANT )); + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 27); + + + + if(!guid) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!pVarVal) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 4U + 4U; + NdrSimpleStructBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)guid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[38] ); + + NdrProxyGetBuffer(This, &_StubMsg); + *( UINT __RPC_FAR * )_StubMsg.Buffer = index; + _StubMsg.Buffer += sizeof(UINT); + + NdrSimpleStructMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)guid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[38] ); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[308] ); + + NdrUserMarshalUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&pVarVal, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1110], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1102], + ( void __RPC_FAR * )pVarVal); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeInfo2_GetFuncCustData_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + VARIANT _M54; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + REFGUID guid = 0; + UINT index; + VARIANT __RPC_FAR *pVarVal; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + pVarVal = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[308] ); + + index = *( UINT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(UINT); + + NdrSimpleStructUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&guid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[38], + (unsigned char)0 ); + + pVarVal = &_M54; + MIDL_memset( + pVarVal, + 0, + sizeof( VARIANT )); + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((ITypeInfo2*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> GetFuncCustData( + (ITypeInfo2 *) ((CStdStubBuffer *)This)->pvServerObject, + index, + guid, + pVarVal); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 8U + 11U; + NdrUserMarshalBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)pVarVal, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1110] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + NdrUserMarshalMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)pVarVal, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1110] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)pVarVal, + &__MIDL_TypeFormatString.Format[1102] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +HRESULT STDMETHODCALLTYPE ITypeInfo2_GetParamCustData_Proxy( + ITypeInfo2 __RPC_FAR * This, + /* [in] */ UINT indexFunc, + /* [in] */ UINT indexParam, + /* [in] */ REFGUID guid, + /* [out] */ VARIANT __RPC_FAR *pVarVal) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(pVarVal) + { + MIDL_memset( + pVarVal, + 0, + sizeof( VARIANT )); + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 28); + + + + if(!guid) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!pVarVal) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 4U + 4U + 0U; + NdrSimpleStructBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)guid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[38] ); + + NdrProxyGetBuffer(This, &_StubMsg); + *( UINT __RPC_FAR * )_StubMsg.Buffer = indexFunc; + _StubMsg.Buffer += sizeof(UINT); + + *( UINT __RPC_FAR * )_StubMsg.Buffer = indexParam; + _StubMsg.Buffer += sizeof(UINT); + + NdrSimpleStructMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)guid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[38] ); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[320] ); + + NdrUserMarshalUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&pVarVal, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1110], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1102], + ( void __RPC_FAR * )pVarVal); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeInfo2_GetParamCustData_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + VARIANT _M55; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + REFGUID guid = 0; + UINT indexFunc; + UINT indexParam; + VARIANT __RPC_FAR *pVarVal; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + pVarVal = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[320] ); + + indexFunc = *( UINT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(UINT); + + indexParam = *( UINT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(UINT); + + NdrSimpleStructUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&guid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[38], + (unsigned char)0 ); + + pVarVal = &_M55; + MIDL_memset( + pVarVal, + 0, + sizeof( VARIANT )); + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((ITypeInfo2*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> GetParamCustData( + (ITypeInfo2 *) ((CStdStubBuffer *)This)->pvServerObject, + indexFunc, + indexParam, + guid, + pVarVal); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 8U + 11U; + NdrUserMarshalBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)pVarVal, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1110] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + NdrUserMarshalMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)pVarVal, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1110] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)pVarVal, + &__MIDL_TypeFormatString.Format[1102] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +HRESULT STDMETHODCALLTYPE ITypeInfo2_GetVarCustData_Proxy( + ITypeInfo2 __RPC_FAR * This, + /* [in] */ UINT index, + /* [in] */ REFGUID guid, + /* [out] */ VARIANT __RPC_FAR *pVarVal) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(pVarVal) + { + MIDL_memset( + pVarVal, + 0, + sizeof( VARIANT )); + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 29); + + + + if(!guid) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!pVarVal) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 4U + 4U; + NdrSimpleStructBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)guid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[38] ); + + NdrProxyGetBuffer(This, &_StubMsg); + *( UINT __RPC_FAR * )_StubMsg.Buffer = index; + _StubMsg.Buffer += sizeof(UINT); + + NdrSimpleStructMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)guid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[38] ); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[308] ); + + NdrUserMarshalUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&pVarVal, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1110], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1102], + ( void __RPC_FAR * )pVarVal); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeInfo2_GetVarCustData_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + VARIANT _M56; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + REFGUID guid = 0; + UINT index; + VARIANT __RPC_FAR *pVarVal; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + pVarVal = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[308] ); + + index = *( UINT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(UINT); + + NdrSimpleStructUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&guid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[38], + (unsigned char)0 ); + + pVarVal = &_M56; + MIDL_memset( + pVarVal, + 0, + sizeof( VARIANT )); + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((ITypeInfo2*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> GetVarCustData( + (ITypeInfo2 *) ((CStdStubBuffer *)This)->pvServerObject, + index, + guid, + pVarVal); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 8U + 11U; + NdrUserMarshalBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)pVarVal, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1110] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + NdrUserMarshalMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)pVarVal, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1110] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)pVarVal, + &__MIDL_TypeFormatString.Format[1102] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +HRESULT STDMETHODCALLTYPE ITypeInfo2_GetImplTypeCustData_Proxy( + ITypeInfo2 __RPC_FAR * This, + /* [in] */ UINT index, + /* [in] */ REFGUID guid, + /* [out] */ VARIANT __RPC_FAR *pVarVal) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(pVarVal) + { + MIDL_memset( + pVarVal, + 0, + sizeof( VARIANT )); + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 30); + + + + if(!guid) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!pVarVal) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 4U + 4U; + NdrSimpleStructBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)guid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[38] ); + + NdrProxyGetBuffer(This, &_StubMsg); + *( UINT __RPC_FAR * )_StubMsg.Buffer = index; + _StubMsg.Buffer += sizeof(UINT); + + NdrSimpleStructMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)guid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[38] ); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[308] ); + + NdrUserMarshalUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&pVarVal, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1110], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1102], + ( void __RPC_FAR * )pVarVal); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeInfo2_GetImplTypeCustData_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + VARIANT _M57; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + REFGUID guid = 0; + UINT index; + VARIANT __RPC_FAR *pVarVal; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + pVarVal = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[308] ); + + index = *( UINT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(UINT); + + NdrSimpleStructUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&guid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[38], + (unsigned char)0 ); + + pVarVal = &_M57; + MIDL_memset( + pVarVal, + 0, + sizeof( VARIANT )); + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((ITypeInfo2*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> GetImplTypeCustData( + (ITypeInfo2 *) ((CStdStubBuffer *)This)->pvServerObject, + index, + guid, + pVarVal); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 8U + 11U; + NdrUserMarshalBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)pVarVal, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1110] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + NdrUserMarshalMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)pVarVal, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1110] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)pVarVal, + &__MIDL_TypeFormatString.Format[1102] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +/* [call_as] */ HRESULT STDMETHODCALLTYPE ITypeInfo2_RemoteGetDocumentation2_Proxy( + ITypeInfo2 __RPC_FAR * This, + /* [in] */ MEMBERID memid, + /* [in] */ LCID lcid, + /* [in] */ DWORD refPtrFlags, + /* [out] */ BSTR __RPC_FAR *pbstrHelpString, + /* [out] */ DWORD __RPC_FAR *pdwHelpStringContext, + /* [out] */ BSTR __RPC_FAR *pbstrHelpStringDll) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(pbstrHelpString) + { + MIDL_memset( + pbstrHelpString, + 0, + sizeof( BSTR )); + } + if(pbstrHelpStringDll) + { + MIDL_memset( + pbstrHelpStringDll, + 0, + sizeof( BSTR )); + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 31); + + + + if(!pbstrHelpString) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!pdwHelpStringContext) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!pbstrHelpStringDll) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 4U + 4U + 4U; + NdrProxyGetBuffer(This, &_StubMsg); + *( MEMBERID __RPC_FAR * )_StubMsg.Buffer = memid; + _StubMsg.Buffer += sizeof(MEMBERID); + + *( LCID __RPC_FAR * )_StubMsg.Buffer = lcid; + _StubMsg.Buffer += sizeof(LCID); + + *( DWORD __RPC_FAR * )_StubMsg.Buffer = refPtrFlags; + _StubMsg.Buffer += sizeof(DWORD); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[334] ); + + NdrUserMarshalUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&pbstrHelpString, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *pdwHelpStringContext = *( DWORD __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(DWORD); + + NdrUserMarshalUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&pbstrHelpStringDll, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1708], + ( void __RPC_FAR * )pbstrHelpString); + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[2], + ( void __RPC_FAR * )pdwHelpStringContext); + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1708], + ( void __RPC_FAR * )pbstrHelpStringDll); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeInfo2_RemoteGetDocumentation2_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + BSTR _M58; + DWORD _M59; + BSTR _M60; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + LCID lcid; + MEMBERID memid; + BSTR __RPC_FAR *pbstrHelpString; + BSTR __RPC_FAR *pbstrHelpStringDll; + DWORD __RPC_FAR *pdwHelpStringContext; + DWORD refPtrFlags; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + pbstrHelpString = 0; + pdwHelpStringContext = 0; + pbstrHelpStringDll = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[334] ); + + memid = *( MEMBERID __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(MEMBERID); + + lcid = *( LCID __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(LCID); + + refPtrFlags = *( DWORD __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(DWORD); + + pbstrHelpString = &_M58; + MIDL_memset( + pbstrHelpString, + 0, + sizeof( BSTR )); + pdwHelpStringContext = &_M59; + pbstrHelpStringDll = &_M60; + MIDL_memset( + pbstrHelpStringDll, + 0, + sizeof( BSTR )); + + *_pdwStubPhase = STUB_CALL_SERVER; + + + _RetVal = ITypeInfo2_GetDocumentation2_Stub( + (ITypeInfo2 *) ((CStdStubBuffer *)This)->pvServerObject, + memid, + lcid, + refPtrFlags, + pbstrHelpString, + pdwHelpStringContext, + pbstrHelpStringDll); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 8U + 11U + 11U + 11U; + NdrUserMarshalBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)pbstrHelpString, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128] ); + + NdrUserMarshalBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)pbstrHelpStringDll, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + NdrUserMarshalMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)pbstrHelpString, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( DWORD __RPC_FAR * )_StubMsg.Buffer = *pdwHelpStringContext; + _StubMsg.Buffer += sizeof(DWORD); + + NdrUserMarshalMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)pbstrHelpStringDll, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)pbstrHelpString, + &__MIDL_TypeFormatString.Format[1708] ); + + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)pbstrHelpStringDll, + &__MIDL_TypeFormatString.Format[1708] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +HRESULT STDMETHODCALLTYPE ITypeInfo2_GetAllCustData_Proxy( + ITypeInfo2 __RPC_FAR * This, + /* [out] */ CUSTDATA __RPC_FAR *pCustData) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(pCustData) + { + MIDL_memset( + pCustData, + 0, + sizeof( CUSTDATA )); + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 32); + + + + if(!pCustData) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 0U; + NdrProxyGetBuffer(This, &_StubMsg); + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[354] ); + + NdrComplexStructUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&pCustData, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1788], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1748], + ( void __RPC_FAR * )pCustData); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeInfo2_GetAllCustData_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + CUSTDATA _pCustDataM; + CUSTDATA __RPC_FAR *pCustData; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + pCustData = 0; + RpcTryFinally + { + pCustData = &_pCustDataM; + pCustData -> prgCustData = 0; + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((ITypeInfo2*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> GetAllCustData((ITypeInfo2 *) ((CStdStubBuffer *)This)->pvServerObject,pCustData); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 0U + 11U; + NdrComplexStructBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)pCustData, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1788] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + NdrComplexStructMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)pCustData, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1788] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)pCustData, + &__MIDL_TypeFormatString.Format[1748] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +HRESULT STDMETHODCALLTYPE ITypeInfo2_GetAllFuncCustData_Proxy( + ITypeInfo2 __RPC_FAR * This, + /* [in] */ UINT index, + /* [out] */ CUSTDATA __RPC_FAR *pCustData) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(pCustData) + { + MIDL_memset( + pCustData, + 0, + sizeof( CUSTDATA )); + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 33); + + + + if(!pCustData) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 4U; + NdrProxyGetBuffer(This, &_StubMsg); + *( UINT __RPC_FAR * )_StubMsg.Buffer = index; + _StubMsg.Buffer += sizeof(UINT); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[360] ); + + NdrComplexStructUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&pCustData, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1788], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1748], + ( void __RPC_FAR * )pCustData); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeInfo2_GetAllFuncCustData_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + CUSTDATA _pCustDataM; + UINT index; + CUSTDATA __RPC_FAR *pCustData; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + pCustData = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[360] ); + + index = *( UINT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(UINT); + + pCustData = &_pCustDataM; + pCustData -> prgCustData = 0; + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((ITypeInfo2*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> GetAllFuncCustData( + (ITypeInfo2 *) ((CStdStubBuffer *)This)->pvServerObject, + index, + pCustData); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 0U + 11U; + NdrComplexStructBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)pCustData, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1788] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + NdrComplexStructMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)pCustData, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1788] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)pCustData, + &__MIDL_TypeFormatString.Format[1748] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +HRESULT STDMETHODCALLTYPE ITypeInfo2_GetAllParamCustData_Proxy( + ITypeInfo2 __RPC_FAR * This, + /* [in] */ UINT indexFunc, + /* [in] */ UINT indexParam, + /* [out] */ CUSTDATA __RPC_FAR *pCustData) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(pCustData) + { + MIDL_memset( + pCustData, + 0, + sizeof( CUSTDATA )); + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 34); + + + + if(!pCustData) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 4U + 4U; + NdrProxyGetBuffer(This, &_StubMsg); + *( UINT __RPC_FAR * )_StubMsg.Buffer = indexFunc; + _StubMsg.Buffer += sizeof(UINT); + + *( UINT __RPC_FAR * )_StubMsg.Buffer = indexParam; + _StubMsg.Buffer += sizeof(UINT); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[368] ); + + NdrComplexStructUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&pCustData, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1788], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1748], + ( void __RPC_FAR * )pCustData); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeInfo2_GetAllParamCustData_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + CUSTDATA _pCustDataM; + UINT indexFunc; + UINT indexParam; + CUSTDATA __RPC_FAR *pCustData; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + pCustData = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[368] ); + + indexFunc = *( UINT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(UINT); + + indexParam = *( UINT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(UINT); + + pCustData = &_pCustDataM; + pCustData -> prgCustData = 0; + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((ITypeInfo2*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> GetAllParamCustData( + (ITypeInfo2 *) ((CStdStubBuffer *)This)->pvServerObject, + indexFunc, + indexParam, + pCustData); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 0U + 11U; + NdrComplexStructBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)pCustData, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1788] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + NdrComplexStructMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)pCustData, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1788] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)pCustData, + &__MIDL_TypeFormatString.Format[1748] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +HRESULT STDMETHODCALLTYPE ITypeInfo2_GetAllVarCustData_Proxy( + ITypeInfo2 __RPC_FAR * This, + /* [in] */ UINT index, + /* [out] */ CUSTDATA __RPC_FAR *pCustData) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(pCustData) + { + MIDL_memset( + pCustData, + 0, + sizeof( CUSTDATA )); + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 35); + + + + if(!pCustData) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 4U; + NdrProxyGetBuffer(This, &_StubMsg); + *( UINT __RPC_FAR * )_StubMsg.Buffer = index; + _StubMsg.Buffer += sizeof(UINT); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[360] ); + + NdrComplexStructUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&pCustData, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1788], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1748], + ( void __RPC_FAR * )pCustData); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeInfo2_GetAllVarCustData_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + CUSTDATA _pCustDataM; + UINT index; + CUSTDATA __RPC_FAR *pCustData; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + pCustData = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[360] ); + + index = *( UINT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(UINT); + + pCustData = &_pCustDataM; + pCustData -> prgCustData = 0; + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((ITypeInfo2*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> GetAllVarCustData( + (ITypeInfo2 *) ((CStdStubBuffer *)This)->pvServerObject, + index, + pCustData); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 0U + 11U; + NdrComplexStructBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)pCustData, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1788] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + NdrComplexStructMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)pCustData, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1788] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)pCustData, + &__MIDL_TypeFormatString.Format[1748] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +HRESULT STDMETHODCALLTYPE ITypeInfo2_GetAllImplTypeCustData_Proxy( + ITypeInfo2 __RPC_FAR * This, + /* [in] */ UINT index, + /* [out] */ CUSTDATA __RPC_FAR *pCustData) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(pCustData) + { + MIDL_memset( + pCustData, + 0, + sizeof( CUSTDATA )); + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 36); + + + + if(!pCustData) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 4U; + NdrProxyGetBuffer(This, &_StubMsg); + *( UINT __RPC_FAR * )_StubMsg.Buffer = index; + _StubMsg.Buffer += sizeof(UINT); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[360] ); + + NdrComplexStructUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&pCustData, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1788], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1748], + ( void __RPC_FAR * )pCustData); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeInfo2_GetAllImplTypeCustData_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + CUSTDATA _pCustDataM; + UINT index; + CUSTDATA __RPC_FAR *pCustData; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + pCustData = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[360] ); + + index = *( UINT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(UINT); + + pCustData = &_pCustDataM; + pCustData -> prgCustData = 0; + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((ITypeInfo2*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> GetAllImplTypeCustData( + (ITypeInfo2 *) ((CStdStubBuffer *)This)->pvServerObject, + index, + pCustData); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 0U + 11U; + NdrComplexStructBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)pCustData, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1788] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + NdrComplexStructMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)pCustData, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1788] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)pCustData, + &__MIDL_TypeFormatString.Format[1748] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + +const CINTERFACE_PROXY_VTABLE(37) _ITypeInfo2ProxyVtbl = +{ + { &IID_ITypeInfo2 }, + { + IUnknown_QueryInterface_Proxy, + IUnknown_AddRef_Proxy, + IUnknown_Release_Proxy , + ITypeInfo_GetTypeAttr_Proxy , + ITypeInfo_GetTypeComp_Proxy , + ITypeInfo_GetFuncDesc_Proxy , + ITypeInfo_GetVarDesc_Proxy , + ITypeInfo_GetNames_Proxy , + ITypeInfo_GetRefTypeOfImplType_Proxy , + ITypeInfo_GetImplTypeFlags_Proxy , + ITypeInfo_GetIDsOfNames_Proxy , + ITypeInfo_Invoke_Proxy , + ITypeInfo_GetDocumentation_Proxy , + ITypeInfo_GetDllEntry_Proxy , + ITypeInfo_GetRefTypeInfo_Proxy , + ITypeInfo_AddressOfMember_Proxy , + ITypeInfo_CreateInstance_Proxy , + ITypeInfo_GetMops_Proxy , + ITypeInfo_GetContainingTypeLib_Proxy , + ITypeInfo_ReleaseTypeAttr_Proxy , + ITypeInfo_ReleaseFuncDesc_Proxy , + ITypeInfo_ReleaseVarDesc_Proxy , + ITypeInfo2_GetTypeKind_Proxy , + ITypeInfo2_GetTypeFlags_Proxy , + ITypeInfo2_GetFuncIndexOfMemId_Proxy , + ITypeInfo2_GetVarIndexOfMemId_Proxy , + ITypeInfo2_GetCustData_Proxy , + ITypeInfo2_GetFuncCustData_Proxy , + ITypeInfo2_GetParamCustData_Proxy , + ITypeInfo2_GetVarCustData_Proxy , + ITypeInfo2_GetImplTypeCustData_Proxy , + ITypeInfo2_GetDocumentation2_Proxy , + ITypeInfo2_GetAllCustData_Proxy , + ITypeInfo2_GetAllFuncCustData_Proxy , + ITypeInfo2_GetAllParamCustData_Proxy , + ITypeInfo2_GetAllVarCustData_Proxy , + ITypeInfo2_GetAllImplTypeCustData_Proxy + } +}; + + +static const PRPC_STUB_FUNCTION ITypeInfo2_table[] = +{ + ITypeInfo_RemoteGetTypeAttr_Stub, + ITypeInfo_GetTypeComp_Stub, + ITypeInfo_RemoteGetFuncDesc_Stub, + ITypeInfo_RemoteGetVarDesc_Stub, + ITypeInfo_RemoteGetNames_Stub, + ITypeInfo_GetRefTypeOfImplType_Stub, + ITypeInfo_GetImplTypeFlags_Stub, + ITypeInfo_LocalGetIDsOfNames_Stub, + ITypeInfo_LocalInvoke_Stub, + ITypeInfo_RemoteGetDocumentation_Stub, + ITypeInfo_RemoteGetDllEntry_Stub, + ITypeInfo_GetRefTypeInfo_Stub, + ITypeInfo_LocalAddressOfMember_Stub, + ITypeInfo_RemoteCreateInstance_Stub, + ITypeInfo_GetMops_Stub, + ITypeInfo_RemoteGetContainingTypeLib_Stub, + ITypeInfo_LocalReleaseTypeAttr_Stub, + ITypeInfo_LocalReleaseFuncDesc_Stub, + ITypeInfo_LocalReleaseVarDesc_Stub, + ITypeInfo2_GetTypeKind_Stub, + ITypeInfo2_GetTypeFlags_Stub, + ITypeInfo2_GetFuncIndexOfMemId_Stub, + ITypeInfo2_GetVarIndexOfMemId_Stub, + ITypeInfo2_GetCustData_Stub, + ITypeInfo2_GetFuncCustData_Stub, + ITypeInfo2_GetParamCustData_Stub, + ITypeInfo2_GetVarCustData_Stub, + ITypeInfo2_GetImplTypeCustData_Stub, + ITypeInfo2_RemoteGetDocumentation2_Stub, + ITypeInfo2_GetAllCustData_Stub, + ITypeInfo2_GetAllFuncCustData_Stub, + ITypeInfo2_GetAllParamCustData_Stub, + ITypeInfo2_GetAllVarCustData_Stub, + ITypeInfo2_GetAllImplTypeCustData_Stub +}; + +const CInterfaceStubVtbl _ITypeInfo2StubVtbl = +{ + { + &IID_ITypeInfo2, + 0, + 37, + &ITypeInfo2_table[-3] + }, + { CStdStubBuffer_METHODS } +}; + + +/* Object interface: ITypeLib, ver. 0.0, + GUID={0x00020402,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}} */ + + +extern const MIDL_STUB_DESC Object_StubDesc; + + +/* [call_as] */ HRESULT STDMETHODCALLTYPE ITypeLib_RemoteGetTypeInfoCount_Proxy( + ITypeLib __RPC_FAR * This, + /* [out] */ UINT __RPC_FAR *pcTInfo) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 3); + + + + if(!pcTInfo) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 0U; + NdrProxyGetBuffer(This, &_StubMsg); + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[0] ); + + *pcTInfo = *( UINT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(UINT); + + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[2], + ( void __RPC_FAR * )pcTInfo); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeLib_RemoteGetTypeInfoCount_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + UINT _M61; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + UINT __RPC_FAR *pcTInfo; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + pcTInfo = 0; + RpcTryFinally + { + pcTInfo = &_M61; + + *_pdwStubPhase = STUB_CALL_SERVER; + + + _RetVal = ITypeLib_GetTypeInfoCount_Stub((ITypeLib *) ((CStdStubBuffer *)This)->pvServerObject,pcTInfo); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 4U + 4U; + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + *( UINT __RPC_FAR * )_StubMsg.Buffer = *pcTInfo; + _StubMsg.Buffer += sizeof(UINT); + + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +HRESULT STDMETHODCALLTYPE ITypeLib_GetTypeInfo_Proxy( + ITypeLib __RPC_FAR * This, + /* [in] */ UINT index, + /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(ppTInfo) + { + MIDL_memset( + ppTInfo, + 0, + sizeof( ITypeInfo __RPC_FAR *__RPC_FAR * )); + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 4); + + + + if(!ppTInfo) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 4U; + NdrProxyGetBuffer(This, &_StubMsg); + *( UINT __RPC_FAR * )_StubMsg.Buffer = index; + _StubMsg.Buffer += sizeof(UINT); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[246] ); + + NdrPointerUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&ppTInfo, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[6], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[6], + ( void __RPC_FAR * )ppTInfo); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeLib_GetTypeInfo_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + ITypeInfo __RPC_FAR *_M62; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + UINT index; + ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + ppTInfo = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[246] ); + + index = *( UINT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(UINT); + + ppTInfo = &_M62; + _M62 = 0; + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((ITypeLib*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> GetTypeInfo( + (ITypeLib *) ((CStdStubBuffer *)This)->pvServerObject, + index, + ppTInfo); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 0U + 4U; + NdrPointerBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)ppTInfo, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[6] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + NdrPointerMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)ppTInfo, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[6] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)ppTInfo, + &__MIDL_TypeFormatString.Format[6] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +HRESULT STDMETHODCALLTYPE ITypeLib_GetTypeInfoType_Proxy( + ITypeLib __RPC_FAR * This, + /* [in] */ UINT index, + /* [out] */ TYPEKIND __RPC_FAR *pTKind) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 5); + + + + if(!pTKind) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 4U; + NdrProxyGetBuffer(This, &_StubMsg); + *( UINT __RPC_FAR * )_StubMsg.Buffer = index; + _StubMsg.Buffer += sizeof(UINT); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[378] ); + + NdrPointerUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&pTKind, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1250], + (unsigned char)0 ); + + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1250], + ( void __RPC_FAR * )pTKind); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeLib_GetTypeInfoType_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + TYPEKIND _M63; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + UINT index; + TYPEKIND __RPC_FAR *pTKind; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + pTKind = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[378] ); + + index = *( UINT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(UINT); + + pTKind = &_M63; + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((ITypeLib*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> GetTypeInfoType( + (ITypeLib *) ((CStdStubBuffer *)This)->pvServerObject, + index, + pTKind); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 4U + 4U; + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + NdrPointerMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)pTKind, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1250] ); + + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +HRESULT STDMETHODCALLTYPE ITypeLib_GetTypeInfoOfGuid_Proxy( + ITypeLib __RPC_FAR * This, + /* [in] */ REFGUID guid, + /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTinfo) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(ppTinfo) + { + MIDL_memset( + ppTinfo, + 0, + sizeof( ITypeInfo __RPC_FAR *__RPC_FAR * )); + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 6); + + + + if(!guid) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!ppTinfo) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 0U; + NdrSimpleStructBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)guid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[38] ); + + NdrProxyGetBuffer(This, &_StubMsg); + NdrSimpleStructMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)guid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[38] ); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[386] ); + + NdrPointerUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&ppTinfo, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[6], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[6], + ( void __RPC_FAR * )ppTinfo); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeLib_GetTypeInfoOfGuid_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + ITypeInfo __RPC_FAR *_M64; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + REFGUID guid = 0; + ITypeInfo __RPC_FAR *__RPC_FAR *ppTinfo; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + ppTinfo = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[386] ); + + NdrSimpleStructUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&guid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[38], + (unsigned char)0 ); + + ppTinfo = &_M64; + _M64 = 0; + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((ITypeLib*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> GetTypeInfoOfGuid( + (ITypeLib *) ((CStdStubBuffer *)This)->pvServerObject, + guid, + ppTinfo); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 0U + 4U; + NdrPointerBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)ppTinfo, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[6] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + NdrPointerMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)ppTinfo, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[6] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)ppTinfo, + &__MIDL_TypeFormatString.Format[6] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +/* [call_as] */ HRESULT STDMETHODCALLTYPE ITypeLib_RemoteGetLibAttr_Proxy( + ITypeLib __RPC_FAR * This, + /* [out] */ LPTLIBATTR __RPC_FAR *ppTLibAttr, + /* [out] */ CLEANLOCALSTORAGE __RPC_FAR *pDummy) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(ppTLibAttr) + { + *ppTLibAttr = 0; + } + if(pDummy) + { + MIDL_memset( + pDummy, + 0, + sizeof( CLEANLOCALSTORAGE )); + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 7); + + + + if(!ppTLibAttr) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!pDummy) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 0U; + NdrProxyGetBuffer(This, &_StubMsg); + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[396] ); + + NdrPointerUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&ppTLibAttr, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1804], + (unsigned char)0 ); + + NdrUserMarshalUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&pDummy, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1838], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1804], + ( void __RPC_FAR * )ppTLibAttr); + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1832], + ( void __RPC_FAR * )pDummy); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeLib_RemoteGetLibAttr_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + LPTLIBATTR _M65; + CLEANLOCALSTORAGE _M66; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + CLEANLOCALSTORAGE __RPC_FAR *pDummy; + LPTLIBATTR __RPC_FAR *ppTLibAttr; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + ppTLibAttr = 0; + pDummy = 0; + RpcTryFinally + { + ppTLibAttr = &_M65; + _M65 = 0; + pDummy = &_M66; + MIDL_memset( + pDummy, + 0, + sizeof( CLEANLOCALSTORAGE )); + + *_pdwStubPhase = STUB_CALL_SERVER; + + + _RetVal = ITypeLib_GetLibAttr_Stub( + (ITypeLib *) ((CStdStubBuffer *)This)->pvServerObject, + ppTLibAttr, + pDummy); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 8U + 11U + 7U; + NdrPointerBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)ppTLibAttr, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1804] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + NdrPointerMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)ppTLibAttr, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1804] ); + + NdrUserMarshalMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)pDummy, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1838] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)ppTLibAttr, + &__MIDL_TypeFormatString.Format[1804] ); + + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)pDummy, + &__MIDL_TypeFormatString.Format[1832] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +HRESULT STDMETHODCALLTYPE ITypeLib_GetTypeComp_Proxy( + ITypeLib __RPC_FAR * This, + /* [out] */ ITypeComp __RPC_FAR *__RPC_FAR *ppTComp) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(ppTComp) + { + MIDL_memset( + ppTComp, + 0, + sizeof( ITypeComp __RPC_FAR *__RPC_FAR * )); + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 8); + + + + if(!ppTComp) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 0U; + NdrProxyGetBuffer(This, &_StubMsg); + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[152] ); + + NdrPointerUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&ppTComp, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1540], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1540], + ( void __RPC_FAR * )ppTComp); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeLib_GetTypeComp_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + ITypeComp __RPC_FAR *_M67; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + ITypeComp __RPC_FAR *__RPC_FAR *ppTComp; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + ppTComp = 0; + RpcTryFinally + { + ppTComp = &_M67; + _M67 = 0; + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((ITypeLib*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> GetTypeComp((ITypeLib *) ((CStdStubBuffer *)This)->pvServerObject,ppTComp); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 0U + 4U; + NdrPointerBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)ppTComp, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1540] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + NdrPointerMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)ppTComp, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1540] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)ppTComp, + &__MIDL_TypeFormatString.Format[1540] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +/* [call_as] */ HRESULT STDMETHODCALLTYPE ITypeLib_RemoteGetDocumentation_Proxy( + ITypeLib __RPC_FAR * This, + /* [in] */ INT index, + /* [in] */ DWORD refPtrFlags, + /* [out] */ BSTR __RPC_FAR *pBstrName, + /* [out] */ BSTR __RPC_FAR *pBstrDocString, + /* [out] */ DWORD __RPC_FAR *pdwHelpContext, + /* [out] */ BSTR __RPC_FAR *pBstrHelpFile) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(pBstrName) + { + MIDL_memset( + pBstrName, + 0, + sizeof( BSTR )); + } + if(pBstrDocString) + { + MIDL_memset( + pBstrDocString, + 0, + sizeof( BSTR )); + } + if(pBstrHelpFile) + { + MIDL_memset( + pBstrHelpFile, + 0, + sizeof( BSTR )); + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 9); + + + + if(!pBstrName) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!pBstrDocString) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!pdwHelpContext) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!pBstrHelpFile) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 4U + 4U; + NdrProxyGetBuffer(This, &_StubMsg); + *( INT __RPC_FAR * )_StubMsg.Buffer = index; + _StubMsg.Buffer += sizeof(INT); + + *( DWORD __RPC_FAR * )_StubMsg.Buffer = refPtrFlags; + _StubMsg.Buffer += sizeof(DWORD); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[204] ); + + NdrUserMarshalUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&pBstrName, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128], + (unsigned char)0 ); + + NdrUserMarshalUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&pBstrDocString, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *pdwHelpContext = *( DWORD __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(DWORD); + + NdrUserMarshalUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&pBstrHelpFile, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1708], + ( void __RPC_FAR * )pBstrName); + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1708], + ( void __RPC_FAR * )pBstrDocString); + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[2], + ( void __RPC_FAR * )pdwHelpContext); + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1708], + ( void __RPC_FAR * )pBstrHelpFile); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeLib_RemoteGetDocumentation_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + BSTR _M68; + BSTR _M69; + DWORD _M70; + BSTR _M71; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + INT index; + BSTR __RPC_FAR *pBstrDocString; + BSTR __RPC_FAR *pBstrHelpFile; + BSTR __RPC_FAR *pBstrName; + DWORD __RPC_FAR *pdwHelpContext; + DWORD refPtrFlags; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + pBstrName = 0; + pBstrDocString = 0; + pdwHelpContext = 0; + pBstrHelpFile = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[204] ); + + index = *( INT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(INT); + + refPtrFlags = *( DWORD __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(DWORD); + + pBstrName = &_M68; + MIDL_memset( + pBstrName, + 0, + sizeof( BSTR )); + pBstrDocString = &_M69; + MIDL_memset( + pBstrDocString, + 0, + sizeof( BSTR )); + pdwHelpContext = &_M70; + pBstrHelpFile = &_M71; + MIDL_memset( + pBstrHelpFile, + 0, + sizeof( BSTR )); + + *_pdwStubPhase = STUB_CALL_SERVER; + + + _RetVal = ITypeLib_GetDocumentation_Stub( + (ITypeLib *) ((CStdStubBuffer *)This)->pvServerObject, + index, + refPtrFlags, + pBstrName, + pBstrDocString, + pdwHelpContext, + pBstrHelpFile); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 8U + 15U + 11U + 11U + 11U; + NdrUserMarshalBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)pBstrName, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128] ); + + NdrUserMarshalBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)pBstrDocString, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128] ); + + NdrUserMarshalBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)pBstrHelpFile, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + NdrUserMarshalMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)pBstrName, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128] ); + + NdrUserMarshalMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)pBstrDocString, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( DWORD __RPC_FAR * )_StubMsg.Buffer = *pdwHelpContext; + _StubMsg.Buffer += sizeof(DWORD); + + NdrUserMarshalMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)pBstrHelpFile, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)pBstrName, + &__MIDL_TypeFormatString.Format[1708] ); + + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)pBstrDocString, + &__MIDL_TypeFormatString.Format[1708] ); + + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)pBstrHelpFile, + &__MIDL_TypeFormatString.Format[1708] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +/* [call_as] */ HRESULT STDMETHODCALLTYPE ITypeLib_RemoteIsName_Proxy( + ITypeLib __RPC_FAR * This, + /* [in] */ LPOLESTR szNameBuf, + /* [in] */ ULONG lHashVal, + /* [out] */ BOOL __RPC_FAR *pfName, + /* [out] */ BSTR __RPC_FAR *pBstrLibName) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(pBstrLibName) + { + MIDL_memset( + pBstrLibName, + 0, + sizeof( BSTR )); + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 10); + + + + if(!szNameBuf) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!pfName) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!pBstrLibName) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 12U + 10U; + NdrConformantStringBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)szNameBuf, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1248] ); + + NdrProxyGetBuffer(This, &_StubMsg); + NdrConformantStringMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)szNameBuf, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1248] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( ULONG __RPC_FAR * )_StubMsg.Buffer = lHashVal; + _StubMsg.Buffer += sizeof(ULONG); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[406] ); + + *pfName = *( BOOL __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(BOOL); + + NdrUserMarshalUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&pBstrLibName, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[2], + ( void __RPC_FAR * )pfName); + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1708], + ( void __RPC_FAR * )pBstrLibName); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeLib_RemoteIsName_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + BOOL _M74; + BSTR _M75; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + ULONG lHashVal; + BSTR __RPC_FAR *pBstrLibName; + BOOL __RPC_FAR *pfName; + LPOLESTR szNameBuf; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + szNameBuf = 0; + pfName = 0; + pBstrLibName = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[406] ); + + NdrConformantStringUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&szNameBuf, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1248], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + lHashVal = *( ULONG __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(ULONG); + + pfName = &_M74; + pBstrLibName = &_M75; + MIDL_memset( + pBstrLibName, + 0, + sizeof( BSTR )); + + *_pdwStubPhase = STUB_CALL_SERVER; + + + _RetVal = ITypeLib_IsName_Stub( + (ITypeLib *) ((CStdStubBuffer *)This)->pvServerObject, + szNameBuf, + lHashVal, + pfName, + pBstrLibName); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 4U + 4U + 11U; + NdrUserMarshalBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)pBstrLibName, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + *( BOOL __RPC_FAR * )_StubMsg.Buffer = *pfName; + _StubMsg.Buffer += sizeof(BOOL); + + NdrUserMarshalMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)pBstrLibName, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)pBstrLibName, + &__MIDL_TypeFormatString.Format[1708] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +/* [call_as] */ HRESULT STDMETHODCALLTYPE ITypeLib_RemoteFindName_Proxy( + ITypeLib __RPC_FAR * This, + /* [in] */ LPOLESTR szNameBuf, + /* [in] */ ULONG lHashVal, + /* [length_is][size_is][out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo, + /* [length_is][size_is][out] */ MEMBERID __RPC_FAR *rgMemId, + /* [out][in] */ USHORT __RPC_FAR *pcFound, + /* [out] */ BSTR __RPC_FAR *pBstrLibName) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(ppTInfo) + { + MIDL_memset( + ppTInfo, + 0, + *pcFound * sizeof( ITypeInfo __RPC_FAR *__RPC_FAR * )); + } + if(pBstrLibName) + { + MIDL_memset( + pBstrLibName, + 0, + sizeof( BSTR )); + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 11); + + + + if(!szNameBuf) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!ppTInfo) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!rgMemId) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!pcFound) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!pBstrLibName) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 12U + 10U + 4U; + NdrConformantStringBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)szNameBuf, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1248] ); + + NdrProxyGetBuffer(This, &_StubMsg); + NdrConformantStringMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)szNameBuf, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1248] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( ULONG __RPC_FAR * )_StubMsg.Buffer = lHashVal; + _StubMsg.Buffer += sizeof(ULONG); + + *( USHORT __RPC_FAR * )_StubMsg.Buffer = *pcFound; + _StubMsg.Buffer += sizeof(USHORT); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[422] ); + + NdrComplexArrayUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&ppTInfo, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1852], + (unsigned char)0 ); + + NdrConformantVaryingArrayUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&rgMemId, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1874], + (unsigned char)0 ); + + *pcFound = *( USHORT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(USHORT); + + NdrUserMarshalUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&pBstrLibName, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + _StubMsg.MaxCount = pcFound ? *pcFound : 0; + _StubMsg.Offset = 0; + _StubMsg.ActualCount = _StubMsg.MaxCount; + + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1848], + ( void __RPC_FAR * )ppTInfo); + _StubMsg.MaxCount = pcFound ? *pcFound : 0; + _StubMsg.Offset = 0; + _StubMsg.ActualCount = _StubMsg.MaxCount; + + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1870], + ( void __RPC_FAR * )rgMemId); + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1888], + ( void __RPC_FAR * )pcFound); + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1708], + ( void __RPC_FAR * )pBstrLibName); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeLib_RemoteFindName_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + BSTR _M84; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + ULONG lHashVal; + BSTR __RPC_FAR *pBstrLibName; + USHORT __RPC_FAR *pcFound; + ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo; + MEMBERID __RPC_FAR *rgMemId; + LPOLESTR szNameBuf; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + szNameBuf = 0; + ppTInfo = 0; + rgMemId = 0; + pcFound = 0; + pBstrLibName = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[422] ); + + NdrConformantStringUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&szNameBuf, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1248], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + lHashVal = *( ULONG __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(ULONG); + + pcFound = ( USHORT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof( USHORT ); + + ppTInfo = NdrAllocate(&_StubMsg,*pcFound * 4); + rgMemId = NdrAllocate(&_StubMsg,*pcFound * 4); + pBstrLibName = &_M84; + MIDL_memset( + pBstrLibName, + 0, + sizeof( BSTR )); + + *_pdwStubPhase = STUB_CALL_SERVER; + + + _RetVal = ITypeLib_FindName_Stub( + (ITypeLib *) ((CStdStubBuffer *)This)->pvServerObject, + szNameBuf, + lHashVal, + ppTInfo, + rgMemId, + pcFound, + pBstrLibName); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 12U + 15U + 4U + 14U + 11U; + _StubMsg.MaxCount = pcFound ? *pcFound : 0; + _StubMsg.Offset = 0; + _StubMsg.ActualCount = pcFound ? *pcFound : 0; + + NdrComplexArrayBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)ppTInfo, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1852] ); + + _StubMsg.MaxCount = pcFound ? *pcFound : 0; + _StubMsg.Offset = 0; + _StubMsg.ActualCount = pcFound ? *pcFound : 0; + + NdrConformantVaryingArrayBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)rgMemId, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1874] ); + + NdrUserMarshalBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)pBstrLibName, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + _StubMsg.MaxCount = pcFound ? *pcFound : 0; + _StubMsg.Offset = 0; + _StubMsg.ActualCount = pcFound ? *pcFound : 0; + + NdrComplexArrayMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)ppTInfo, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1852] ); + + _StubMsg.MaxCount = pcFound ? *pcFound : 0; + _StubMsg.Offset = 0; + _StubMsg.ActualCount = pcFound ? *pcFound : 0; + + NdrConformantVaryingArrayMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)rgMemId, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1874] ); + + *( USHORT __RPC_FAR * )_StubMsg.Buffer = *pcFound; + _StubMsg.Buffer += sizeof(USHORT); + + NdrUserMarshalMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)pBstrLibName, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + _StubMsg.MaxCount = pcFound ? *pcFound : 0; + _StubMsg.Offset = 0; + _StubMsg.ActualCount = pcFound ? *pcFound : 0; + + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)ppTInfo, + &__MIDL_TypeFormatString.Format[1848] ); + + _StubMsg.MaxCount = pcFound ? *pcFound : 0; + _StubMsg.Offset = 0; + _StubMsg.ActualCount = pcFound ? *pcFound : 0; + + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)rgMemId, + &__MIDL_TypeFormatString.Format[1870] ); + + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)pBstrLibName, + &__MIDL_TypeFormatString.Format[1708] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +/* [call_as] */ HRESULT STDMETHODCALLTYPE ITypeLib_LocalReleaseTLibAttr_Proxy( + ITypeLib __RPC_FAR * This) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 12); + + + + RpcTryFinally + { + + _StubMsg.BufferLength = 0U; + NdrProxyGetBuffer(This, &_StubMsg); + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[88] ); + + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeLib_LocalReleaseTLibAttr_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + RpcTryFinally + { + + *_pdwStubPhase = STUB_CALL_SERVER; + + + _RetVal = ITypeLib_ReleaseTLibAttr_Stub((ITypeLib *) ((CStdStubBuffer *)This)->pvServerObject); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 4U; + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + +const CINTERFACE_PROXY_VTABLE(13) _ITypeLibProxyVtbl = +{ + { &IID_ITypeLib }, + { + IUnknown_QueryInterface_Proxy, + IUnknown_AddRef_Proxy, + IUnknown_Release_Proxy , + ITypeLib_GetTypeInfoCount_Proxy , + ITypeLib_GetTypeInfo_Proxy , + ITypeLib_GetTypeInfoType_Proxy , + ITypeLib_GetTypeInfoOfGuid_Proxy , + ITypeLib_GetLibAttr_Proxy , + ITypeLib_GetTypeComp_Proxy , + ITypeLib_GetDocumentation_Proxy , + ITypeLib_IsName_Proxy , + ITypeLib_FindName_Proxy , + ITypeLib_ReleaseTLibAttr_Proxy + } +}; + + +static const PRPC_STUB_FUNCTION ITypeLib_table[] = +{ + ITypeLib_RemoteGetTypeInfoCount_Stub, + ITypeLib_GetTypeInfo_Stub, + ITypeLib_GetTypeInfoType_Stub, + ITypeLib_GetTypeInfoOfGuid_Stub, + ITypeLib_RemoteGetLibAttr_Stub, + ITypeLib_GetTypeComp_Stub, + ITypeLib_RemoteGetDocumentation_Stub, + ITypeLib_RemoteIsName_Stub, + ITypeLib_RemoteFindName_Stub, + ITypeLib_LocalReleaseTLibAttr_Stub +}; + +const CInterfaceStubVtbl _ITypeLibStubVtbl = +{ + { + &IID_ITypeLib, + 0, + 13, + &ITypeLib_table[-3] + }, + { CStdStubBuffer_METHODS } +}; + + +/* Object interface: ITypeLib2, ver. 0.0, + GUID={0x00020411,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}} */ + + +extern const MIDL_STUB_DESC Object_StubDesc; + + +HRESULT STDMETHODCALLTYPE ITypeLib2_GetCustData_Proxy( + ITypeLib2 __RPC_FAR * This, + /* [in] */ REFGUID guid, + /* [out] */ VARIANT __RPC_FAR *pVarVal) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(pVarVal) + { + MIDL_memset( + pVarVal, + 0, + sizeof( VARIANT )); + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 13); + + + + if(!guid) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!pVarVal) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 0U; + NdrSimpleStructBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)guid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[38] ); + + NdrProxyGetBuffer(This, &_StubMsg); + NdrSimpleStructMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)guid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[38] ); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[298] ); + + NdrUserMarshalUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&pVarVal, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1110], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1102], + ( void __RPC_FAR * )pVarVal); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeLib2_GetCustData_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + VARIANT _M85; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + REFGUID guid = 0; + VARIANT __RPC_FAR *pVarVal; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + pVarVal = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[298] ); + + NdrSimpleStructUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&guid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[38], + (unsigned char)0 ); + + pVarVal = &_M85; + MIDL_memset( + pVarVal, + 0, + sizeof( VARIANT )); + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((ITypeLib2*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> GetCustData( + (ITypeLib2 *) ((CStdStubBuffer *)This)->pvServerObject, + guid, + pVarVal); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 8U + 11U; + NdrUserMarshalBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)pVarVal, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1110] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + NdrUserMarshalMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)pVarVal, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1110] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)pVarVal, + &__MIDL_TypeFormatString.Format[1102] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +/* [call_as] */ HRESULT STDMETHODCALLTYPE ITypeLib2_RemoteGetLibStatistics_Proxy( + ITypeLib2 __RPC_FAR * This, + /* [out] */ ULONG __RPC_FAR *pcUniqueNames, + /* [out] */ ULONG __RPC_FAR *pcchUniqueNames) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 14); + + + + if(!pcUniqueNames) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!pcchUniqueNames) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 0U; + NdrProxyGetBuffer(This, &_StubMsg); + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[446] ); + + *pcUniqueNames = *( ULONG __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(ULONG); + + *pcchUniqueNames = *( ULONG __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(ULONG); + + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[2], + ( void __RPC_FAR * )pcUniqueNames); + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[2], + ( void __RPC_FAR * )pcchUniqueNames); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeLib2_RemoteGetLibStatistics_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + ULONG _M86; + ULONG _M87; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + ULONG __RPC_FAR *pcUniqueNames; + ULONG __RPC_FAR *pcchUniqueNames; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + pcUniqueNames = 0; + pcchUniqueNames = 0; + RpcTryFinally + { + pcUniqueNames = &_M86; + pcchUniqueNames = &_M87; + + *_pdwStubPhase = STUB_CALL_SERVER; + + + _RetVal = ITypeLib2_GetLibStatistics_Stub( + (ITypeLib2 *) ((CStdStubBuffer *)This)->pvServerObject, + pcUniqueNames, + pcchUniqueNames); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 4U + 4U + 4U; + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + *( ULONG __RPC_FAR * )_StubMsg.Buffer = *pcUniqueNames; + _StubMsg.Buffer += sizeof(ULONG); + + *( ULONG __RPC_FAR * )_StubMsg.Buffer = *pcchUniqueNames; + _StubMsg.Buffer += sizeof(ULONG); + + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +/* [call_as] */ HRESULT STDMETHODCALLTYPE ITypeLib2_RemoteGetDocumentation2_Proxy( + ITypeLib2 __RPC_FAR * This, + /* [in] */ INT index, + /* [in] */ LCID lcid, + /* [in] */ DWORD refPtrFlags, + /* [out] */ BSTR __RPC_FAR *pbstrHelpString, + /* [out] */ DWORD __RPC_FAR *pdwHelpStringContext, + /* [out] */ BSTR __RPC_FAR *pbstrHelpStringDll) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(pbstrHelpString) + { + MIDL_memset( + pbstrHelpString, + 0, + sizeof( BSTR )); + } + if(pbstrHelpStringDll) + { + MIDL_memset( + pbstrHelpStringDll, + 0, + sizeof( BSTR )); + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 15); + + + + if(!pbstrHelpString) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!pdwHelpStringContext) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!pbstrHelpStringDll) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 4U + 4U + 4U; + NdrProxyGetBuffer(This, &_StubMsg); + *( INT __RPC_FAR * )_StubMsg.Buffer = index; + _StubMsg.Buffer += sizeof(INT); + + *( LCID __RPC_FAR * )_StubMsg.Buffer = lcid; + _StubMsg.Buffer += sizeof(LCID); + + *( DWORD __RPC_FAR * )_StubMsg.Buffer = refPtrFlags; + _StubMsg.Buffer += sizeof(DWORD); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[334] ); + + NdrUserMarshalUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&pbstrHelpString, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *pdwHelpStringContext = *( DWORD __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(DWORD); + + NdrUserMarshalUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&pbstrHelpStringDll, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1708], + ( void __RPC_FAR * )pbstrHelpString); + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[2], + ( void __RPC_FAR * )pdwHelpStringContext); + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1708], + ( void __RPC_FAR * )pbstrHelpStringDll); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeLib2_RemoteGetDocumentation2_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + BSTR _M88; + DWORD _M89; + BSTR _M90; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + INT index; + LCID lcid; + BSTR __RPC_FAR *pbstrHelpString; + BSTR __RPC_FAR *pbstrHelpStringDll; + DWORD __RPC_FAR *pdwHelpStringContext; + DWORD refPtrFlags; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + pbstrHelpString = 0; + pdwHelpStringContext = 0; + pbstrHelpStringDll = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[334] ); + + index = *( INT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(INT); + + lcid = *( LCID __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(LCID); + + refPtrFlags = *( DWORD __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(DWORD); + + pbstrHelpString = &_M88; + MIDL_memset( + pbstrHelpString, + 0, + sizeof( BSTR )); + pdwHelpStringContext = &_M89; + pbstrHelpStringDll = &_M90; + MIDL_memset( + pbstrHelpStringDll, + 0, + sizeof( BSTR )); + + *_pdwStubPhase = STUB_CALL_SERVER; + + + _RetVal = ITypeLib2_GetDocumentation2_Stub( + (ITypeLib2 *) ((CStdStubBuffer *)This)->pvServerObject, + index, + lcid, + refPtrFlags, + pbstrHelpString, + pdwHelpStringContext, + pbstrHelpStringDll); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 8U + 11U + 11U + 11U; + NdrUserMarshalBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)pbstrHelpString, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128] ); + + NdrUserMarshalBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)pbstrHelpStringDll, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + NdrUserMarshalMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)pbstrHelpString, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( DWORD __RPC_FAR * )_StubMsg.Buffer = *pdwHelpStringContext; + _StubMsg.Buffer += sizeof(DWORD); + + NdrUserMarshalMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)pbstrHelpStringDll, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)pbstrHelpString, + &__MIDL_TypeFormatString.Format[1708] ); + + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)pbstrHelpStringDll, + &__MIDL_TypeFormatString.Format[1708] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +HRESULT STDMETHODCALLTYPE ITypeLib2_GetAllCustData_Proxy( + ITypeLib2 __RPC_FAR * This, + /* [out] */ CUSTDATA __RPC_FAR *pCustData) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(pCustData) + { + MIDL_memset( + pCustData, + 0, + sizeof( CUSTDATA )); + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 16); + + + + if(!pCustData) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 0U; + NdrProxyGetBuffer(This, &_StubMsg); + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[354] ); + + NdrComplexStructUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&pCustData, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1788], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1748], + ( void __RPC_FAR * )pCustData); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeLib2_GetAllCustData_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + CUSTDATA _pCustDataM; + CUSTDATA __RPC_FAR *pCustData; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + pCustData = 0; + RpcTryFinally + { + pCustData = &_pCustDataM; + pCustData -> prgCustData = 0; + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((ITypeLib2*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> GetAllCustData((ITypeLib2 *) ((CStdStubBuffer *)This)->pvServerObject,pCustData); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 0U + 11U; + NdrComplexStructBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)pCustData, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1788] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + NdrComplexStructMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)pCustData, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1788] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)pCustData, + &__MIDL_TypeFormatString.Format[1748] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + +const CINTERFACE_PROXY_VTABLE(17) _ITypeLib2ProxyVtbl = +{ + { &IID_ITypeLib2 }, + { + IUnknown_QueryInterface_Proxy, + IUnknown_AddRef_Proxy, + IUnknown_Release_Proxy , + ITypeLib_GetTypeInfoCount_Proxy , + ITypeLib_GetTypeInfo_Proxy , + ITypeLib_GetTypeInfoType_Proxy , + ITypeLib_GetTypeInfoOfGuid_Proxy , + ITypeLib_GetLibAttr_Proxy , + ITypeLib_GetTypeComp_Proxy , + ITypeLib_GetDocumentation_Proxy , + ITypeLib_IsName_Proxy , + ITypeLib_FindName_Proxy , + ITypeLib_ReleaseTLibAttr_Proxy , + ITypeLib2_GetCustData_Proxy , + ITypeLib2_GetLibStatistics_Proxy , + ITypeLib2_GetDocumentation2_Proxy , + ITypeLib2_GetAllCustData_Proxy + } +}; + + +static const PRPC_STUB_FUNCTION ITypeLib2_table[] = +{ + ITypeLib_RemoteGetTypeInfoCount_Stub, + ITypeLib_GetTypeInfo_Stub, + ITypeLib_GetTypeInfoType_Stub, + ITypeLib_GetTypeInfoOfGuid_Stub, + ITypeLib_RemoteGetLibAttr_Stub, + ITypeLib_GetTypeComp_Stub, + ITypeLib_RemoteGetDocumentation_Stub, + ITypeLib_RemoteIsName_Stub, + ITypeLib_RemoteFindName_Stub, + ITypeLib_LocalReleaseTLibAttr_Stub, + ITypeLib2_GetCustData_Stub, + ITypeLib2_RemoteGetLibStatistics_Stub, + ITypeLib2_RemoteGetDocumentation2_Stub, + ITypeLib2_GetAllCustData_Stub +}; + +const CInterfaceStubVtbl _ITypeLib2StubVtbl = +{ + { + &IID_ITypeLib2, + 0, + 17, + &ITypeLib2_table[-3] + }, + { CStdStubBuffer_METHODS } +}; + + +/* Object interface: ITypeChangeEvents, ver. 0.0, + GUID={0x00020410,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}} */ + + +/* Object interface: IErrorInfo, ver. 0.0, + GUID={0x1CF2B120,0x547D,0x101B,{0x8E,0x65,0x08,0x00,0x2B,0x2B,0xD1,0x19}} */ + + +extern const MIDL_STUB_DESC Object_StubDesc; + + +HRESULT STDMETHODCALLTYPE IErrorInfo_GetGUID_Proxy( + IErrorInfo __RPC_FAR * This, + /* [out] */ GUID __RPC_FAR *pGUID) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(pGUID) + { + MIDL_memset( + pGUID, + 0, + sizeof( IID )); + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 3); + + + + if(!pGUID) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 0U; + NdrProxyGetBuffer(This, &_StubMsg); + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[456] ); + + NdrSimpleStructUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&pGUID, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[38], + (unsigned char)0 ); + + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1892], + ( void __RPC_FAR * )pGUID); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB IErrorInfo_GetGUID_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + IID _pGUIDM; + GUID __RPC_FAR *pGUID; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + pGUID = 0; + RpcTryFinally + { + pGUID = &_pGUIDM; + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((IErrorInfo*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> GetGUID((IErrorInfo *) ((CStdStubBuffer *)This)->pvServerObject,pGUID); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 0U + 11U; + NdrSimpleStructBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)pGUID, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[38] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + NdrSimpleStructMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)pGUID, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[38] ); + + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +HRESULT STDMETHODCALLTYPE IErrorInfo_GetSource_Proxy( + IErrorInfo __RPC_FAR * This, + /* [out] */ BSTR __RPC_FAR *pBstrSource) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(pBstrSource) + { + MIDL_memset( + pBstrSource, + 0, + sizeof( BSTR )); + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 4); + + + + if(!pBstrSource) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 0U; + NdrProxyGetBuffer(This, &_StubMsg); + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[462] ); + + NdrUserMarshalUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&pBstrSource, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1708], + ( void __RPC_FAR * )pBstrSource); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB IErrorInfo_GetSource_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + BSTR _M91; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + BSTR __RPC_FAR *pBstrSource; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + pBstrSource = 0; + RpcTryFinally + { + pBstrSource = &_M91; + MIDL_memset( + pBstrSource, + 0, + sizeof( BSTR )); + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((IErrorInfo*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> GetSource((IErrorInfo *) ((CStdStubBuffer *)This)->pvServerObject,pBstrSource); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 8U + 11U; + NdrUserMarshalBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)pBstrSource, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + NdrUserMarshalMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)pBstrSource, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)pBstrSource, + &__MIDL_TypeFormatString.Format[1708] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +HRESULT STDMETHODCALLTYPE IErrorInfo_GetDescription_Proxy( + IErrorInfo __RPC_FAR * This, + /* [out] */ BSTR __RPC_FAR *pBstrDescription) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(pBstrDescription) + { + MIDL_memset( + pBstrDescription, + 0, + sizeof( BSTR )); + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 5); + + + + if(!pBstrDescription) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 0U; + NdrProxyGetBuffer(This, &_StubMsg); + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[462] ); + + NdrUserMarshalUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&pBstrDescription, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1708], + ( void __RPC_FAR * )pBstrDescription); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB IErrorInfo_GetDescription_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + BSTR _M92; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + BSTR __RPC_FAR *pBstrDescription; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + pBstrDescription = 0; + RpcTryFinally + { + pBstrDescription = &_M92; + MIDL_memset( + pBstrDescription, + 0, + sizeof( BSTR )); + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((IErrorInfo*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> GetDescription((IErrorInfo *) ((CStdStubBuffer *)This)->pvServerObject,pBstrDescription); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 8U + 11U; + NdrUserMarshalBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)pBstrDescription, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + NdrUserMarshalMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)pBstrDescription, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)pBstrDescription, + &__MIDL_TypeFormatString.Format[1708] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +HRESULT STDMETHODCALLTYPE IErrorInfo_GetHelpFile_Proxy( + IErrorInfo __RPC_FAR * This, + /* [out] */ BSTR __RPC_FAR *pBstrHelpFile) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(pBstrHelpFile) + { + MIDL_memset( + pBstrHelpFile, + 0, + sizeof( BSTR )); + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 6); + + + + if(!pBstrHelpFile) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 0U; + NdrProxyGetBuffer(This, &_StubMsg); + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[462] ); + + NdrUserMarshalUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&pBstrHelpFile, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1708], + ( void __RPC_FAR * )pBstrHelpFile); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB IErrorInfo_GetHelpFile_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + BSTR _M93; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + BSTR __RPC_FAR *pBstrHelpFile; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + pBstrHelpFile = 0; + RpcTryFinally + { + pBstrHelpFile = &_M93; + MIDL_memset( + pBstrHelpFile, + 0, + sizeof( BSTR )); + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((IErrorInfo*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> GetHelpFile((IErrorInfo *) ((CStdStubBuffer *)This)->pvServerObject,pBstrHelpFile); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 8U + 11U; + NdrUserMarshalBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)pBstrHelpFile, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + NdrUserMarshalMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)pBstrHelpFile, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1128] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)pBstrHelpFile, + &__MIDL_TypeFormatString.Format[1708] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +HRESULT STDMETHODCALLTYPE IErrorInfo_GetHelpContext_Proxy( + IErrorInfo __RPC_FAR * This, + /* [out] */ DWORD __RPC_FAR *pdwHelpContext) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 7); + + + + if(!pdwHelpContext) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 0U; + NdrProxyGetBuffer(This, &_StubMsg); + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[0] ); + + *pdwHelpContext = *( DWORD __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(DWORD); + + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[2], + ( void __RPC_FAR * )pdwHelpContext); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB IErrorInfo_GetHelpContext_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + DWORD _M94; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + DWORD __RPC_FAR *pdwHelpContext; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + pdwHelpContext = 0; + RpcTryFinally + { + pdwHelpContext = &_M94; + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((IErrorInfo*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> GetHelpContext((IErrorInfo *) ((CStdStubBuffer *)This)->pvServerObject,pdwHelpContext); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 4U + 4U; + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + *( DWORD __RPC_FAR * )_StubMsg.Buffer = *pdwHelpContext; + _StubMsg.Buffer += sizeof(DWORD); + + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + +const CINTERFACE_PROXY_VTABLE(8) _IErrorInfoProxyVtbl = +{ + { &IID_IErrorInfo }, + { + IUnknown_QueryInterface_Proxy, + IUnknown_AddRef_Proxy, + IUnknown_Release_Proxy , + IErrorInfo_GetGUID_Proxy , + IErrorInfo_GetSource_Proxy , + IErrorInfo_GetDescription_Proxy , + IErrorInfo_GetHelpFile_Proxy , + IErrorInfo_GetHelpContext_Proxy + } +}; + + +static const PRPC_STUB_FUNCTION IErrorInfo_table[] = +{ + IErrorInfo_GetGUID_Stub, + IErrorInfo_GetSource_Stub, + IErrorInfo_GetDescription_Stub, + IErrorInfo_GetHelpFile_Stub, + IErrorInfo_GetHelpContext_Stub +}; + +const CInterfaceStubVtbl _IErrorInfoStubVtbl = +{ + { + &IID_IErrorInfo, + 0, + 8, + &IErrorInfo_table[-3] + }, + { CStdStubBuffer_METHODS } +}; + + +/* Object interface: ICreateErrorInfo, ver. 0.0, + GUID={0x22F03340,0x547D,0x101B,{0x8E,0x65,0x08,0x00,0x2B,0x2B,0xD1,0x19}} */ + + +extern const MIDL_STUB_DESC Object_StubDesc; + + +HRESULT STDMETHODCALLTYPE ICreateErrorInfo_SetGUID_Proxy( + ICreateErrorInfo __RPC_FAR * This, + /* [in] */ REFGUID rguid) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 3); + + + + if(!rguid) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 0U; + NdrSimpleStructBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)rguid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[38] ); + + NdrProxyGetBuffer(This, &_StubMsg); + NdrSimpleStructMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)rguid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[38] ); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[468] ); + + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ICreateErrorInfo_SetGUID_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + REFGUID rguid = 0; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[468] ); + + NdrSimpleStructUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&rguid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[38], + (unsigned char)0 ); + + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((ICreateErrorInfo*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> SetGUID((ICreateErrorInfo *) ((CStdStubBuffer *)This)->pvServerObject,rguid); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 4U; + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +HRESULT STDMETHODCALLTYPE ICreateErrorInfo_SetSource_Proxy( + ICreateErrorInfo __RPC_FAR * This, + /* [in] */ LPOLESTR szSource) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 4); + + + + if(!szSource) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 12U; + NdrConformantStringBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)szSource, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1248] ); + + NdrProxyGetBuffer(This, &_StubMsg); + NdrConformantStringMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)szSource, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1248] ); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[474] ); + + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ICreateErrorInfo_SetSource_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + LPOLESTR szSource; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + szSource = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[474] ); + + NdrConformantStringUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&szSource, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1248], + (unsigned char)0 ); + + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((ICreateErrorInfo*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> SetSource((ICreateErrorInfo *) ((CStdStubBuffer *)This)->pvServerObject,szSource); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 4U; + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +HRESULT STDMETHODCALLTYPE ICreateErrorInfo_SetDescription_Proxy( + ICreateErrorInfo __RPC_FAR * This, + /* [in] */ LPOLESTR szDescription) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 5); + + + + if(!szDescription) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 12U; + NdrConformantStringBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)szDescription, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1248] ); + + NdrProxyGetBuffer(This, &_StubMsg); + NdrConformantStringMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)szDescription, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1248] ); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[474] ); + + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ICreateErrorInfo_SetDescription_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + LPOLESTR szDescription; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + szDescription = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[474] ); + + NdrConformantStringUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&szDescription, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1248], + (unsigned char)0 ); + + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((ICreateErrorInfo*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> SetDescription((ICreateErrorInfo *) ((CStdStubBuffer *)This)->pvServerObject,szDescription); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 4U; + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +HRESULT STDMETHODCALLTYPE ICreateErrorInfo_SetHelpFile_Proxy( + ICreateErrorInfo __RPC_FAR * This, + /* [in] */ LPOLESTR szHelpFile) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 6); + + + + if(!szHelpFile) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 12U; + NdrConformantStringBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)szHelpFile, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1248] ); + + NdrProxyGetBuffer(This, &_StubMsg); + NdrConformantStringMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)szHelpFile, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1248] ); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[474] ); + + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ICreateErrorInfo_SetHelpFile_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + LPOLESTR szHelpFile; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + szHelpFile = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[474] ); + + NdrConformantStringUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&szHelpFile, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1248], + (unsigned char)0 ); + + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((ICreateErrorInfo*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> SetHelpFile((ICreateErrorInfo *) ((CStdStubBuffer *)This)->pvServerObject,szHelpFile); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 4U; + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + + +HRESULT STDMETHODCALLTYPE ICreateErrorInfo_SetHelpContext_Proxy( + ICreateErrorInfo __RPC_FAR * This, + /* [in] */ DWORD dwHelpContext) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 7); + + + + RpcTryFinally + { + + _StubMsg.BufferLength = 4U; + NdrProxyGetBuffer(This, &_StubMsg); + *( DWORD __RPC_FAR * )_StubMsg.Buffer = dwHelpContext; + _StubMsg.Buffer += sizeof(DWORD); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[84] ); + + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ICreateErrorInfo_SetHelpContext_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + DWORD dwHelpContext; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[84] ); + + dwHelpContext = *( DWORD __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(DWORD); + + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((ICreateErrorInfo*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> SetHelpContext((ICreateErrorInfo *) ((CStdStubBuffer *)This)->pvServerObject,dwHelpContext); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 4U; + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + +const CINTERFACE_PROXY_VTABLE(8) _ICreateErrorInfoProxyVtbl = +{ + { &IID_ICreateErrorInfo }, + { + IUnknown_QueryInterface_Proxy, + IUnknown_AddRef_Proxy, + IUnknown_Release_Proxy , + ICreateErrorInfo_SetGUID_Proxy , + ICreateErrorInfo_SetSource_Proxy , + ICreateErrorInfo_SetDescription_Proxy , + ICreateErrorInfo_SetHelpFile_Proxy , + ICreateErrorInfo_SetHelpContext_Proxy + } +}; + + +static const PRPC_STUB_FUNCTION ICreateErrorInfo_table[] = +{ + ICreateErrorInfo_SetGUID_Stub, + ICreateErrorInfo_SetSource_Stub, + ICreateErrorInfo_SetDescription_Stub, + ICreateErrorInfo_SetHelpFile_Stub, + ICreateErrorInfo_SetHelpContext_Stub +}; + +const CInterfaceStubVtbl _ICreateErrorInfoStubVtbl = +{ + { + &IID_ICreateErrorInfo, + 0, + 8, + &ICreateErrorInfo_table[-3] + }, + { CStdStubBuffer_METHODS } +}; + + +/* Object interface: ISupportErrorInfo, ver. 0.0, + GUID={0xDF0B3D60,0x548F,0x101B,{0x8E,0x65,0x08,0x00,0x2B,0x2B,0xD1,0x19}} */ + + +extern const MIDL_STUB_DESC Object_StubDesc; + + +HRESULT STDMETHODCALLTYPE ISupportErrorInfo_InterfaceSupportsErrorInfo_Proxy( + ISupportErrorInfo __RPC_FAR * This, + /* [in] */ REFIID riid) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 3); + + + + if(!riid) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 0U; + NdrSimpleStructBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)riid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[38] ); + + NdrProxyGetBuffer(This, &_StubMsg); + NdrSimpleStructMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)riid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[38] ); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[468] ); + + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ISupportErrorInfo_InterfaceSupportsErrorInfo_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + IID* riid = 0; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[468] ); + + NdrSimpleStructUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&riid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[38], + (unsigned char)0 ); + + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((ISupportErrorInfo*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> InterfaceSupportsErrorInfo((ISupportErrorInfo *) ((CStdStubBuffer *)This)->pvServerObject,riid); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 4U; + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + +const CINTERFACE_PROXY_VTABLE(4) _ISupportErrorInfoProxyVtbl = +{ + { &IID_ISupportErrorInfo }, + { + IUnknown_QueryInterface_Proxy, + IUnknown_AddRef_Proxy, + IUnknown_Release_Proxy , + ISupportErrorInfo_InterfaceSupportsErrorInfo_Proxy + } +}; + + +static const PRPC_STUB_FUNCTION ISupportErrorInfo_table[] = +{ + ISupportErrorInfo_InterfaceSupportsErrorInfo_Stub +}; + +const CInterfaceStubVtbl _ISupportErrorInfoStubVtbl = +{ + { + &IID_ISupportErrorInfo, + 0, + 4, + &ISupportErrorInfo_table[-3] + }, + { CStdStubBuffer_METHODS } +}; + + +/* Object interface: ITypeFactory, ver. 0.0, + GUID={0x0000002E,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}} */ + + +extern const MIDL_STUB_DESC Object_StubDesc; + + +HRESULT STDMETHODCALLTYPE ITypeFactory_CreateFromTypeInfo_Proxy( + ITypeFactory __RPC_FAR * This, + /* [in] */ ITypeInfo __RPC_FAR *pTypeInfo, + /* [in] */ REFIID riid, + /* [iid_is][out] */ IUnknown __RPC_FAR *__RPC_FAR *ppv) +{ + + HRESULT _RetVal; + + RPC_MESSAGE _RpcMessage; + + MIDL_STUB_MESSAGE _StubMsg; + + if(ppv) + { + MIDL_memset( + ppv, + 0, + sizeof( IUnknown __RPC_FAR *__RPC_FAR * )); + } + RpcTryExcept + { + NdrProxyInitialize( + ( void __RPC_FAR * )This, + ( PRPC_MESSAGE )&_RpcMessage, + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PMIDL_STUB_DESC )&Object_StubDesc, + 3); + + + + if(!riid) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + if(!ppv) + { + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + RpcTryFinally + { + + _StubMsg.BufferLength = 0U + 0U; + NdrInterfacePointerBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)pTypeInfo, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[10] ); + + NdrSimpleStructBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)riid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[38] ); + + NdrProxyGetBuffer(This, &_StubMsg); + NdrInterfacePointerMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)pTypeInfo, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[10] ); + + NdrSimpleStructMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)riid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[38] ); + + NdrProxySendReceive(This, &_StubMsg); + + if ( (_RpcMessage.DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[480] ); + + NdrPointerUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&ppv, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1896], + (unsigned char)0 ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + _RetVal = *( HRESULT __RPC_FAR * )_StubMsg.Buffer; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrProxyFreeBuffer(This, &_StubMsg); + + } + RpcEndFinally + + } + RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE) + { + _StubMsg.MaxCount = (unsigned long) ( riid ); + + NdrClearOutParameters( + ( PMIDL_STUB_MESSAGE )&_StubMsg, + ( PFORMAT_STRING )&__MIDL_TypeFormatString.Format[1896], + ( void __RPC_FAR * )ppv); + _RetVal = NdrProxyErrorHandler(RpcExceptionCode()); + } + RpcEndExcept + return _RetVal; +} + +void __RPC_STUB ITypeFactory_CreateFromTypeInfo_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase) +{ + IUnknown __RPC_FAR *__RPC_FAR *_M101; + HRESULT _RetVal; + MIDL_STUB_MESSAGE _StubMsg; + ITypeInfo __RPC_FAR *pTypeInfo; + IUnknown __RPC_FAR *__RPC_FAR *ppv; + IID* riid = 0; + +NdrStubInitialize( + _pRpcMessage, + &_StubMsg, + &Object_StubDesc, + _pRpcChannelBuffer); + pTypeInfo = 0; + ppv = 0; + RpcTryFinally + { + if ( (_pRpcMessage->DataRepresentation & 0X0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION ) + NdrConvert( (PMIDL_STUB_MESSAGE) &_StubMsg, (PFORMAT_STRING) &__MIDL_ProcFormatString.Format[480] ); + + NdrInterfacePointerUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&pTypeInfo, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[10], + (unsigned char)0 ); + + NdrSimpleStructUnmarshall( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR * __RPC_FAR *)&riid, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[38], + (unsigned char)0 ); + + ppv = (void *)&_M101; + _M101 = 0; + + *_pdwStubPhase = STUB_CALL_SERVER; + _RetVal = (((ITypeFactory*) ((CStdStubBuffer *)This)->pvServerObject)->lpVtbl) -> CreateFromTypeInfo( + (ITypeFactory *) ((CStdStubBuffer *)This)->pvServerObject, + pTypeInfo, + riid, + ppv); + + *_pdwStubPhase = STUB_MARSHAL; + + _StubMsg.BufferLength = 0U + 4U; + _StubMsg.MaxCount = (unsigned long) ( riid ); + + NdrPointerBufferSize( (PMIDL_STUB_MESSAGE) &_StubMsg, + (unsigned char __RPC_FAR *)ppv, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1896] ); + + _StubMsg.BufferLength += 16; + + NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg); + _StubMsg.MaxCount = (unsigned long) ( riid ); + + NdrPointerMarshall( (PMIDL_STUB_MESSAGE)& _StubMsg, + (unsigned char __RPC_FAR *)ppv, + (PFORMAT_STRING) &__MIDL_TypeFormatString.Format[1896] ); + + _StubMsg.Buffer = (unsigned char __RPC_FAR *)(((long)_StubMsg.Buffer + 3) & ~ 0x3); + *( HRESULT __RPC_FAR * )_StubMsg.Buffer = _RetVal; + _StubMsg.Buffer += sizeof(HRESULT); + + } + RpcFinally + { + NdrInterfacePointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)pTypeInfo, + &__MIDL_TypeFormatString.Format[10] ); + + _StubMsg.MaxCount = (unsigned long) ( riid ); + + NdrPointerFree( &_StubMsg, + (unsigned char __RPC_FAR *)ppv, + &__MIDL_TypeFormatString.Format[1896] ); + + } + RpcEndFinally + _pRpcMessage->BufferLength = + (unsigned int)((long)_StubMsg.Buffer - (long)_pRpcMessage->Buffer); + +} + +static const USER_MARSHAL_ROUTINE_QUADRUPLE UserMarshalRoutines[3] = + { + { + (USER_MARSHAL_SIZING_ROUTINE)VARIANT_UserSize, + (USER_MARSHAL_MARSHALLING_ROUTINE)VARIANT_UserMarshal, + (USER_MARSHAL_UNMARSHALLING_ROUTINE)VARIANT_UserUnmarshal, + (USER_MARSHAL_FREEING_ROUTINE)VARIANT_UserFree + }, + { + (USER_MARSHAL_SIZING_ROUTINE)BSTR_UserSize, + (USER_MARSHAL_MARSHALLING_ROUTINE)BSTR_UserMarshal, + (USER_MARSHAL_UNMARSHALLING_ROUTINE)BSTR_UserUnmarshal, + (USER_MARSHAL_FREEING_ROUTINE)BSTR_UserFree + }, + { + (USER_MARSHAL_SIZING_ROUTINE)CLEANLOCALSTORAGE_UserSize, + (USER_MARSHAL_MARSHALLING_ROUTINE)CLEANLOCALSTORAGE_UserMarshal, + (USER_MARSHAL_UNMARSHALLING_ROUTINE)CLEANLOCALSTORAGE_UserUnmarshal, + (USER_MARSHAL_FREEING_ROUTINE)CLEANLOCALSTORAGE_UserFree + } + + }; + +static const MIDL_STUB_DESC Object_StubDesc = + { + 0, + NdrOleAllocate, + NdrOleFree, + { 0 }, + 0, + 0, + 0, + 0, + __MIDL_TypeFormatString.Format, + 1, /* -error bounds_check flag */ + 0x20000, /* Ndr library version */ + 0, + 0x50100a4, /* MIDL Version 5.1.164 */ + 0, + UserMarshalRoutines, + 0, /* notify & notify_flag routine table */ + 1, /* Flags */ + 0, /* Reserved3 */ + 0, /* Reserved4 */ + 0 /* Reserved5 */ + }; + +const CINTERFACE_PROXY_VTABLE(4) _ITypeFactoryProxyVtbl = +{ + { &IID_ITypeFactory }, + { + IUnknown_QueryInterface_Proxy, + IUnknown_AddRef_Proxy, + IUnknown_Release_Proxy , + ITypeFactory_CreateFromTypeInfo_Proxy + } +}; + + +static const PRPC_STUB_FUNCTION ITypeFactory_table[] = +{ + ITypeFactory_CreateFromTypeInfo_Stub +}; + +const CInterfaceStubVtbl _ITypeFactoryStubVtbl = +{ + { + &IID_ITypeFactory, + 0, + 4, + &ITypeFactory_table[-3] + }, + { CStdStubBuffer_METHODS } +}; + + +/* Object interface: ITypeMarshal, ver. 0.0, + GUID={0x0000002D,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}} */ + + +/* Object interface: IRecordInfo, ver. 0.0, + GUID={0x0000002F,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}} */ + + +/* Object interface: ICreateTypeInfo, ver. 0.0, + GUID={0x00020405,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}} */ + + +/* Object interface: ICreateTypeInfo2, ver. 0.0, + GUID={0x0002040E,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}} */ + + +/* Object interface: ICreateTypeLib, ver. 0.0, + GUID={0x00020406,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}} */ + + +/* Object interface: ICreateTypeLib2, ver. 0.0, + GUID={0x0002040F,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}} */ + +#if !defined(__RPC_WIN32__) +#error Invalid build platform for this stub. +#endif + +#if !(TARGET_IS_NT40_OR_LATER) +#error You need a Windows NT 4.0 or later to run this stub because it uses these features: +#error [wire_marshal] or [user_marshal] attribute. +#error However, your C/C++ compilation flags indicate you intend to run this app on earlier systems. +#error This app will die there with the RPC_X_WRONG_STUB_VERSION error. +#endif + + +static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString = + { + 0, + { + + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 2 */ NdrFcShort( 0x2 ), /* Type Offset=2 */ +/* 4 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 6 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 8 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 10 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 12 */ NdrFcShort( 0x6 ), /* Type Offset=6 */ +/* 14 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 16 */ + 0x4d, /* FC_IN_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 18 */ NdrFcShort( 0x1c ), /* Type Offset=28 */ +/* 20 */ + 0x4d, /* FC_IN_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 22 */ NdrFcShort( 0x32 ), /* Type Offset=50 */ +/* 24 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 26 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 28 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 30 */ NdrFcShort( 0x54 ), /* Type Offset=84 */ +/* 32 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 34 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 36 */ + 0x4d, /* FC_IN_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 38 */ NdrFcShort( 0x1c ), /* Type Offset=28 */ +/* 40 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 42 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 44 */ + 0x4d, /* FC_IN_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 46 */ NdrFcShort( 0x62 ), /* Type Offset=98 */ +/* 48 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 50 */ NdrFcShort( 0x44e ), /* Type Offset=1102 */ +/* 52 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 54 */ NdrFcShort( 0x460 ), /* Type Offset=1120 */ +/* 56 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 58 */ NdrFcShort( 0x2 ), /* Type Offset=2 */ +/* 60 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 62 */ + 0x4d, /* FC_IN_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 64 */ NdrFcShort( 0x48e ), /* Type Offset=1166 */ +/* 66 */ + 0x50, /* FC_IN_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 68 */ NdrFcShort( 0x49c ), /* Type Offset=1180 */ +/* 70 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 72 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 74 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 76 */ NdrFcShort( 0x4b2 ), /* Type Offset=1202 */ +/* 78 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 80 */ NdrFcShort( 0x2 ), /* Type Offset=2 */ +/* 82 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 84 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 86 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 88 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 90 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 92 */ NdrFcShort( 0x4c8 ), /* Type Offset=1224 */ +/* 94 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 96 */ + 0x4d, /* FC_IN_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 98 */ NdrFcShort( 0x4de ), /* Type Offset=1246 */ +/* 100 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 102 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x6, /* FC_SHORT */ +/* 104 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 106 */ NdrFcShort( 0x6 ), /* Type Offset=6 */ +/* 108 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 110 */ NdrFcShort( 0x4e2 ), /* Type Offset=1250 */ +/* 112 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 114 */ NdrFcShort( 0x4e6 ), /* Type Offset=1254 */ +/* 116 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 118 */ NdrFcShort( 0x5b8 ), /* Type Offset=1464 */ +/* 120 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 122 */ NdrFcShort( 0x604 ), /* Type Offset=1540 */ +/* 124 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 126 */ NdrFcShort( 0x61a ), /* Type Offset=1562 */ +/* 128 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 130 */ + 0x4d, /* FC_IN_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 132 */ NdrFcShort( 0x4de ), /* Type Offset=1246 */ +/* 134 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 136 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 138 */ NdrFcShort( 0x6 ), /* Type Offset=6 */ +/* 140 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 142 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 144 */ NdrFcShort( 0x62a ), /* Type Offset=1578 */ +/* 146 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 148 */ NdrFcShort( 0x666 ), /* Type Offset=1638 */ +/* 150 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 152 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 154 */ NdrFcShort( 0x604 ), /* Type Offset=1540 */ +/* 156 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 158 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 160 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 162 */ NdrFcShort( 0x4e6 ), /* Type Offset=1254 */ +/* 164 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 166 */ NdrFcShort( 0x676 ), /* Type Offset=1654 */ +/* 168 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 170 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 172 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 174 */ NdrFcShort( 0x5b8 ), /* Type Offset=1464 */ +/* 176 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 178 */ NdrFcShort( 0x686 ), /* Type Offset=1670 */ +/* 180 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 182 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 184 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 186 */ NdrFcShort( 0x696 ), /* Type Offset=1686 */ +/* 188 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 190 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 192 */ NdrFcShort( 0x2 ), /* Type Offset=2 */ +/* 194 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 196 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 198 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 200 */ NdrFcShort( 0x2 ), /* Type Offset=2 */ +/* 202 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 204 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 206 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 208 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 210 */ NdrFcShort( 0x6ac ), /* Type Offset=1708 */ +/* 212 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 214 */ NdrFcShort( 0x6ac ), /* Type Offset=1708 */ +/* 216 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 218 */ NdrFcShort( 0x2 ), /* Type Offset=2 */ +/* 220 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 222 */ NdrFcShort( 0x6ac ), /* Type Offset=1708 */ +/* 224 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 226 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 228 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0xe, /* FC_ENUM32 */ +/* 230 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 232 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 234 */ NdrFcShort( 0x6ac ), /* Type Offset=1708 */ +/* 236 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 238 */ NdrFcShort( 0x6ac ), /* Type Offset=1708 */ +/* 240 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 242 */ NdrFcShort( 0x6b0 ), /* Type Offset=1712 */ +/* 244 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 246 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 248 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 250 */ NdrFcShort( 0x6 ), /* Type Offset=6 */ +/* 252 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 254 */ + 0x4d, /* FC_IN_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 256 */ NdrFcShort( 0x1c ), /* Type Offset=28 */ +/* 258 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 260 */ NdrFcShort( 0x6b4 ), /* Type Offset=1716 */ +/* 262 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 264 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 266 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 268 */ NdrFcShort( 0x6ac ), /* Type Offset=1708 */ +/* 270 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 272 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 274 */ NdrFcShort( 0x6be ), /* Type Offset=1726 */ +/* 276 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 278 */ NdrFcShort( 0x2 ), /* Type Offset=2 */ +/* 280 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 282 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 284 */ NdrFcShort( 0x4e2 ), /* Type Offset=1250 */ +/* 286 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 288 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 290 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0xe, /* FC_ENUM32 */ +/* 292 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 294 */ NdrFcShort( 0x2 ), /* Type Offset=2 */ +/* 296 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 298 */ + 0x4d, /* FC_IN_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 300 */ NdrFcShort( 0x1c ), /* Type Offset=28 */ +/* 302 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 304 */ NdrFcShort( 0x44e ), /* Type Offset=1102 */ +/* 306 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 308 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 310 */ + 0x4d, /* FC_IN_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 312 */ NdrFcShort( 0x1c ), /* Type Offset=28 */ +/* 314 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 316 */ NdrFcShort( 0x44e ), /* Type Offset=1102 */ +/* 318 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 320 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 322 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 324 */ + 0x4d, /* FC_IN_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 326 */ NdrFcShort( 0x1c ), /* Type Offset=28 */ +/* 328 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 330 */ NdrFcShort( 0x44e ), /* Type Offset=1102 */ +/* 332 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 334 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 336 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 338 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 340 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 342 */ NdrFcShort( 0x6ac ), /* Type Offset=1708 */ +/* 344 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 346 */ NdrFcShort( 0x2 ), /* Type Offset=2 */ +/* 348 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 350 */ NdrFcShort( 0x6ac ), /* Type Offset=1708 */ +/* 352 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 354 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 356 */ NdrFcShort( 0x6d4 ), /* Type Offset=1748 */ +/* 358 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 360 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 362 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 364 */ NdrFcShort( 0x6d4 ), /* Type Offset=1748 */ +/* 366 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 368 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 370 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 372 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 374 */ NdrFcShort( 0x6d4 ), /* Type Offset=1748 */ +/* 376 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 378 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 380 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 382 */ NdrFcShort( 0x4e2 ), /* Type Offset=1250 */ +/* 384 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 386 */ + 0x4d, /* FC_IN_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 388 */ NdrFcShort( 0x1c ), /* Type Offset=28 */ +/* 390 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 392 */ NdrFcShort( 0x6 ), /* Type Offset=6 */ +/* 394 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 396 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 398 */ NdrFcShort( 0x70c ), /* Type Offset=1804 */ +/* 400 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 402 */ NdrFcShort( 0x728 ), /* Type Offset=1832 */ +/* 404 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 406 */ + 0x4d, /* FC_IN_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 408 */ NdrFcShort( 0x4de ), /* Type Offset=1246 */ +/* 410 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 412 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 414 */ NdrFcShort( 0x2 ), /* Type Offset=2 */ +/* 416 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 418 */ NdrFcShort( 0x6ac ), /* Type Offset=1708 */ +/* 420 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 422 */ + 0x4d, /* FC_IN_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 424 */ NdrFcShort( 0x4de ), /* Type Offset=1246 */ +/* 426 */ 0x4e, /* FC_IN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 428 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 430 */ NdrFcShort( 0x738 ), /* Type Offset=1848 */ +/* 432 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 434 */ NdrFcShort( 0x74e ), /* Type Offset=1870 */ +/* 436 */ + 0x50, /* FC_IN_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 438 */ NdrFcShort( 0x760 ), /* Type Offset=1888 */ +/* 440 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 442 */ NdrFcShort( 0x6ac ), /* Type Offset=1708 */ +/* 444 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 446 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 448 */ NdrFcShort( 0x2 ), /* Type Offset=2 */ +/* 450 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 452 */ NdrFcShort( 0x2 ), /* Type Offset=2 */ +/* 454 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 456 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 458 */ NdrFcShort( 0x764 ), /* Type Offset=1892 */ +/* 460 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 462 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 464 */ NdrFcShort( 0x6ac ), /* Type Offset=1708 */ +/* 466 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 468 */ + 0x4d, /* FC_IN_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 470 */ NdrFcShort( 0x1c ), /* Type Offset=28 */ +/* 472 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 474 */ + 0x4d, /* FC_IN_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 476 */ NdrFcShort( 0x4de ), /* Type Offset=1246 */ +/* 478 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ +/* 480 */ + 0x4d, /* FC_IN_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 482 */ NdrFcShort( 0xa ), /* Type Offset=10 */ +/* 484 */ + 0x4d, /* FC_IN_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 486 */ NdrFcShort( 0x1c ), /* Type Offset=28 */ +/* 488 */ + 0x51, /* FC_OUT_PARAM */ +#ifndef _ALPHA_ + 0x1, /* x86, MIPS & PPC Stack size = 1 */ +#else + 0x2, /* Alpha Stack size = 2 */ +#endif +/* 490 */ NdrFcShort( 0x768 ), /* Type Offset=1896 */ +/* 492 */ 0x53, /* FC_RETURN_PARAM_BASETYPE */ + 0x8, /* FC_LONG */ + + 0x0 + } + }; + +static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString = + { + 0, + { + NdrFcShort( 0x0 ), /* 0 */ +/* 2 */ + 0x11, 0xc, /* FC_RP [alloced_on_stack] [simple_pointer] */ +/* 4 */ 0x8, /* FC_LONG */ + 0x5c, /* FC_PAD */ +/* 6 */ + 0x11, 0x14, /* FC_RP [alloced_on_stack] */ +/* 8 */ NdrFcShort( 0x2 ), /* Offset= 2 (10) */ +/* 10 */ + 0x2f, /* FC_IP */ + 0x5a, /* FC_CONSTANT_IID */ +/* 12 */ NdrFcLong( 0x20401 ), /* 132097 */ +/* 16 */ NdrFcShort( 0x0 ), /* 0 */ +/* 18 */ NdrFcShort( 0x0 ), /* 0 */ +/* 20 */ 0xc0, /* 192 */ + 0x0, /* 0 */ +/* 22 */ 0x0, /* 0 */ + 0x0, /* 0 */ +/* 24 */ 0x0, /* 0 */ + 0x0, /* 0 */ +/* 26 */ 0x0, /* 0 */ + 0x46, /* 70 */ +/* 28 */ + 0x11, 0x0, /* FC_RP */ +/* 30 */ NdrFcShort( 0x8 ), /* Offset= 8 (38) */ +/* 32 */ + 0x1d, /* FC_SMFARRAY */ + 0x0, /* 0 */ +/* 34 */ NdrFcShort( 0x8 ), /* 8 */ +/* 36 */ 0x2, /* FC_CHAR */ + 0x5b, /* FC_END */ +/* 38 */ + 0x15, /* FC_STRUCT */ + 0x3, /* 3 */ +/* 40 */ NdrFcShort( 0x10 ), /* 16 */ +/* 42 */ 0x8, /* FC_LONG */ + 0x6, /* FC_SHORT */ +/* 44 */ 0x6, /* FC_SHORT */ + 0x4c, /* FC_EMBEDDED_COMPLEX */ +/* 46 */ 0x0, /* 0 */ + NdrFcShort( 0xfffffff1 ), /* Offset= -15 (32) */ + 0x5b, /* FC_END */ +/* 50 */ + 0x11, 0x0, /* FC_RP */ +/* 52 */ NdrFcShort( 0x2 ), /* Offset= 2 (54) */ +/* 54 */ + 0x1b, /* FC_CARRAY */ + 0x3, /* 3 */ +/* 56 */ NdrFcShort( 0x4 ), /* 4 */ +/* 58 */ 0x29, /* Corr desc: parameter, FC_ULONG */ + 0x0, /* */ +#ifndef _ALPHA_ +/* 60 */ NdrFcShort( 0xc ), /* x86, MIPS, PPC Stack size/offset = 12 */ +#else + NdrFcShort( 0x18 ), /* Alpha Stack size/offset = 24 */ +#endif +/* 62 */ + 0x4b, /* FC_PP */ + 0x5c, /* FC_PAD */ +/* 64 */ + 0x48, /* FC_VARIABLE_REPEAT */ + 0x49, /* FC_FIXED_OFFSET */ +/* 66 */ NdrFcShort( 0x4 ), /* 4 */ +/* 68 */ NdrFcShort( 0x0 ), /* 0 */ +/* 70 */ NdrFcShort( 0x1 ), /* 1 */ +/* 72 */ NdrFcShort( 0x0 ), /* 0 */ +/* 74 */ NdrFcShort( 0x0 ), /* 0 */ +/* 76 */ 0x12, 0x8, /* FC_UP [simple_pointer] */ +/* 78 */ + 0x25, /* FC_C_WSTRING */ + 0x5c, /* FC_PAD */ +/* 80 */ + 0x5b, /* FC_END */ + + 0x8, /* FC_LONG */ +/* 82 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 84 */ + 0x11, 0x0, /* FC_RP */ +/* 86 */ NdrFcShort( 0x2 ), /* Offset= 2 (88) */ +/* 88 */ + 0x1b, /* FC_CARRAY */ + 0x3, /* 3 */ +/* 90 */ NdrFcShort( 0x4 ), /* 4 */ +/* 92 */ 0x29, /* Corr desc: parameter, FC_ULONG */ + 0x0, /* */ +#ifndef _ALPHA_ +/* 94 */ NdrFcShort( 0xc ), /* x86, MIPS, PPC Stack size/offset = 12 */ +#else + NdrFcShort( 0x18 ), /* Alpha Stack size/offset = 24 */ +#endif +/* 96 */ 0x8, /* FC_LONG */ + 0x5b, /* FC_END */ +/* 98 */ + 0x11, 0x0, /* FC_RP */ +/* 100 */ NdrFcShort( 0x3d4 ), /* Offset= 980 (1080) */ +/* 102 */ + 0x12, 0x0, /* FC_UP */ +/* 104 */ NdrFcShort( 0x396 ), /* Offset= 918 (1022) */ +/* 106 */ + 0x2b, /* FC_NON_ENCAPSULATED_UNION */ + 0x7, /* FC_USHORT */ +/* 108 */ 0x7, /* Corr desc: FC_USHORT */ + 0x0, /* */ +/* 110 */ NdrFcShort( 0xfff8 ), /* -8 */ +/* 112 */ NdrFcShort( 0x2 ), /* Offset= 2 (114) */ +/* 114 */ NdrFcShort( 0x10 ), /* 16 */ +/* 116 */ NdrFcShort( 0x2b ), /* 43 */ +/* 118 */ NdrFcLong( 0x0 ), /* 0 */ +/* 122 */ NdrFcShort( 0x0 ), /* Offset= 0 (122) */ +/* 124 */ NdrFcLong( 0x1 ), /* 1 */ +/* 128 */ NdrFcShort( 0x0 ), /* Offset= 0 (128) */ +/* 130 */ NdrFcLong( 0x10 ), /* 16 */ +/* 134 */ NdrFcShort( 0x8002 ), /* Simple arm type: FC_CHAR */ +/* 136 */ NdrFcLong( 0x12 ), /* 18 */ +/* 140 */ NdrFcShort( 0x8006 ), /* Simple arm type: FC_SHORT */ +/* 142 */ NdrFcLong( 0x13 ), /* 19 */ +/* 146 */ NdrFcShort( 0x8008 ), /* Simple arm type: FC_LONG */ +/* 148 */ NdrFcLong( 0x16 ), /* 22 */ +/* 152 */ NdrFcShort( 0x8008 ), /* Simple arm type: FC_LONG */ +/* 154 */ NdrFcLong( 0x17 ), /* 23 */ +/* 158 */ NdrFcShort( 0x8008 ), /* Simple arm type: FC_LONG */ +/* 160 */ NdrFcLong( 0x11 ), /* 17 */ +/* 164 */ NdrFcShort( 0x8002 ), /* Simple arm type: FC_CHAR */ +/* 166 */ NdrFcLong( 0x2 ), /* 2 */ +/* 170 */ NdrFcShort( 0x8006 ), /* Simple arm type: FC_SHORT */ +/* 172 */ NdrFcLong( 0x3 ), /* 3 */ +/* 176 */ NdrFcShort( 0x8008 ), /* Simple arm type: FC_LONG */ +/* 178 */ NdrFcLong( 0x4 ), /* 4 */ +/* 182 */ NdrFcShort( 0x800a ), /* Simple arm type: FC_FLOAT */ +/* 184 */ NdrFcLong( 0x5 ), /* 5 */ +/* 188 */ NdrFcShort( 0x800c ), /* Simple arm type: FC_DOUBLE */ +/* 190 */ NdrFcLong( 0xb ), /* 11 */ +/* 194 */ NdrFcShort( 0x8006 ), /* Simple arm type: FC_SHORT */ +/* 196 */ NdrFcLong( 0xa ), /* 10 */ +/* 200 */ NdrFcShort( 0x8008 ), /* Simple arm type: FC_LONG */ +/* 202 */ NdrFcLong( 0x7 ), /* 7 */ +/* 206 */ NdrFcShort( 0x800c ), /* Simple arm type: FC_DOUBLE */ +/* 208 */ NdrFcLong( 0x8 ), /* 8 */ +/* 212 */ NdrFcShort( 0xa6 ), /* Offset= 166 (378) */ +/* 214 */ NdrFcLong( 0x6 ), /* 6 */ +/* 218 */ NdrFcShort( 0xb8 ), /* Offset= 184 (402) */ +/* 220 */ NdrFcLong( 0xe ), /* 14 */ +/* 224 */ NdrFcShort( 0xb8 ), /* Offset= 184 (408) */ +/* 226 */ NdrFcLong( 0xd ), /* 13 */ +/* 230 */ NdrFcShort( 0xbe ), /* Offset= 190 (420) */ +/* 232 */ NdrFcLong( 0x9 ), /* 9 */ +/* 236 */ NdrFcShort( 0xca ), /* Offset= 202 (438) */ +/* 238 */ NdrFcLong( 0x2000 ), /* 8192 */ +/* 242 */ NdrFcShort( 0xd6 ), /* Offset= 214 (456) */ +/* 244 */ NdrFcLong( 0x4010 ), /* 16400 */ +/* 248 */ NdrFcShort( 0x2ce ), /* Offset= 718 (966) */ +/* 250 */ NdrFcLong( 0x4012 ), /* 16402 */ +/* 254 */ NdrFcShort( 0x2cc ), /* Offset= 716 (970) */ +/* 256 */ NdrFcLong( 0x4013 ), /* 16403 */ +/* 260 */ NdrFcShort( 0x2ca ), /* Offset= 714 (974) */ +/* 262 */ NdrFcLong( 0x4016 ), /* 16406 */ +/* 266 */ NdrFcShort( 0x2c4 ), /* Offset= 708 (974) */ +/* 268 */ NdrFcLong( 0x4017 ), /* 16407 */ +/* 272 */ NdrFcShort( 0x2be ), /* Offset= 702 (974) */ +/* 274 */ NdrFcLong( 0x4011 ), /* 16401 */ +/* 278 */ NdrFcShort( 0x2b0 ), /* Offset= 688 (966) */ +/* 280 */ NdrFcLong( 0x4002 ), /* 16386 */ +/* 284 */ NdrFcShort( 0x2ae ), /* Offset= 686 (970) */ +/* 286 */ NdrFcLong( 0x4003 ), /* 16387 */ +/* 290 */ NdrFcShort( 0x2ac ), /* Offset= 684 (974) */ +/* 292 */ NdrFcLong( 0x4004 ), /* 16388 */ +/* 296 */ NdrFcShort( 0x2aa ), /* Offset= 682 (978) */ +/* 298 */ NdrFcLong( 0x4005 ), /* 16389 */ +/* 302 */ NdrFcShort( 0x2a8 ), /* Offset= 680 (982) */ +/* 304 */ NdrFcLong( 0x400b ), /* 16395 */ +/* 308 */ NdrFcShort( 0x296 ), /* Offset= 662 (970) */ +/* 310 */ NdrFcLong( 0x400a ), /* 16394 */ +/* 314 */ NdrFcShort( 0x294 ), /* Offset= 660 (974) */ +/* 316 */ NdrFcLong( 0x4007 ), /* 16391 */ +/* 320 */ NdrFcShort( 0x296 ), /* Offset= 662 (982) */ +/* 322 */ NdrFcLong( 0x4008 ), /* 16392 */ +/* 326 */ NdrFcShort( 0x294 ), /* Offset= 660 (986) */ +/* 328 */ NdrFcLong( 0x400c ), /* 16396 */ +/* 332 */ NdrFcShort( 0x292 ), /* Offset= 658 (990) */ +/* 334 */ NdrFcLong( 0x4006 ), /* 16390 */ +/* 338 */ NdrFcShort( 0x294 ), /* Offset= 660 (998) */ +/* 340 */ NdrFcLong( 0x400e ), /* 16398 */ +/* 344 */ NdrFcShort( 0x292 ), /* Offset= 658 (1002) */ +/* 346 */ NdrFcLong( 0x400d ), /* 16397 */ +/* 350 */ NdrFcShort( 0x290 ), /* Offset= 656 (1006) */ +/* 352 */ NdrFcLong( 0x4009 ), /* 16393 */ +/* 356 */ NdrFcShort( 0x28e ), /* Offset= 654 (1010) */ +/* 358 */ NdrFcLong( 0x6000 ), /* 24576 */ +/* 362 */ NdrFcShort( 0x28c ), /* Offset= 652 (1014) */ +/* 364 */ NdrFcLong( 0x24 ), /* 36 */ +/* 368 */ NdrFcShort( 0x28a ), /* Offset= 650 (1018) */ +/* 370 */ NdrFcLong( 0x4024 ), /* 16420 */ +/* 374 */ NdrFcShort( 0x284 ), /* Offset= 644 (1018) */ +/* 376 */ NdrFcShort( 0xffffffff ), /* Offset= -1 (375) */ +/* 378 */ + 0x12, 0x0, /* FC_UP */ +/* 380 */ NdrFcShort( 0xc ), /* Offset= 12 (392) */ +/* 382 */ + 0x1b, /* FC_CARRAY */ + 0x1, /* 1 */ +/* 384 */ NdrFcShort( 0x2 ), /* 2 */ +/* 386 */ 0x9, /* Corr desc: FC_ULONG */ + 0x0, /* */ +/* 388 */ NdrFcShort( 0xfffc ), /* -4 */ +/* 390 */ 0x6, /* FC_SHORT */ + 0x5b, /* FC_END */ +/* 392 */ + 0x17, /* FC_CSTRUCT */ + 0x3, /* 3 */ +/* 394 */ NdrFcShort( 0x8 ), /* 8 */ +/* 396 */ NdrFcShort( 0xfffffff2 ), /* Offset= -14 (382) */ +/* 398 */ 0x8, /* FC_LONG */ + 0x8, /* FC_LONG */ +/* 400 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 402 */ + 0x15, /* FC_STRUCT */ + 0x7, /* 7 */ +/* 404 */ NdrFcShort( 0x8 ), /* 8 */ +/* 406 */ 0xb, /* FC_HYPER */ + 0x5b, /* FC_END */ +/* 408 */ + 0x15, /* FC_STRUCT */ + 0x7, /* 7 */ +/* 410 */ NdrFcShort( 0x10 ), /* 16 */ +/* 412 */ 0x6, /* FC_SHORT */ + 0x2, /* FC_CHAR */ +/* 414 */ 0x2, /* FC_CHAR */ + 0x38, /* FC_ALIGNM4 */ +/* 416 */ 0x8, /* FC_LONG */ + 0x39, /* FC_ALIGNM8 */ +/* 418 */ 0xb, /* FC_HYPER */ + 0x5b, /* FC_END */ +/* 420 */ + 0x2f, /* FC_IP */ + 0x5a, /* FC_CONSTANT_IID */ +/* 422 */ NdrFcLong( 0x0 ), /* 0 */ +/* 426 */ NdrFcShort( 0x0 ), /* 0 */ +/* 428 */ NdrFcShort( 0x0 ), /* 0 */ +/* 430 */ 0xc0, /* 192 */ + 0x0, /* 0 */ +/* 432 */ 0x0, /* 0 */ + 0x0, /* 0 */ +/* 434 */ 0x0, /* 0 */ + 0x0, /* 0 */ +/* 436 */ 0x0, /* 0 */ + 0x46, /* 70 */ +/* 438 */ + 0x2f, /* FC_IP */ + 0x5a, /* FC_CONSTANT_IID */ +/* 440 */ NdrFcLong( 0x20400 ), /* 132096 */ +/* 444 */ NdrFcShort( 0x0 ), /* 0 */ +/* 446 */ NdrFcShort( 0x0 ), /* 0 */ +/* 448 */ 0xc0, /* 192 */ + 0x0, /* 0 */ +/* 450 */ 0x0, /* 0 */ + 0x0, /* 0 */ +/* 452 */ 0x0, /* 0 */ + 0x0, /* 0 */ +/* 454 */ 0x0, /* 0 */ + 0x46, /* 70 */ +/* 456 */ + 0x12, 0x0, /* FC_UP */ +/* 458 */ NdrFcShort( 0x1ea ), /* Offset= 490 (948) */ +/* 460 */ + 0x2a, /* FC_ENCAPSULATED_UNION */ + 0x49, /* 73 */ +/* 462 */ NdrFcShort( 0x18 ), /* 24 */ +/* 464 */ NdrFcShort( 0xa ), /* 10 */ +/* 466 */ NdrFcLong( 0x8 ), /* 8 */ +/* 470 */ NdrFcShort( 0x58 ), /* Offset= 88 (558) */ +/* 472 */ NdrFcLong( 0xd ), /* 13 */ +/* 476 */ NdrFcShort( 0x78 ), /* Offset= 120 (596) */ +/* 478 */ NdrFcLong( 0x9 ), /* 9 */ +/* 482 */ NdrFcShort( 0x94 ), /* Offset= 148 (630) */ +/* 484 */ NdrFcLong( 0xc ), /* 12 */ +/* 488 */ NdrFcShort( 0xbc ), /* Offset= 188 (676) */ +/* 490 */ NdrFcLong( 0x24 ), /* 36 */ +/* 494 */ NdrFcShort( 0x114 ), /* Offset= 276 (770) */ +/* 496 */ NdrFcLong( 0x800d ), /* 32781 */ +/* 500 */ NdrFcShort( 0x11e ), /* Offset= 286 (786) */ +/* 502 */ NdrFcLong( 0x10 ), /* 16 */ +/* 506 */ NdrFcShort( 0x136 ), /* Offset= 310 (816) */ +/* 508 */ NdrFcLong( 0x2 ), /* 2 */ +/* 512 */ NdrFcShort( 0x14e ), /* Offset= 334 (846) */ +/* 514 */ NdrFcLong( 0x3 ), /* 3 */ +/* 518 */ NdrFcShort( 0x166 ), /* Offset= 358 (876) */ +/* 520 */ NdrFcLong( 0x14 ), /* 20 */ +/* 524 */ NdrFcShort( 0x17e ), /* Offset= 382 (906) */ +/* 526 */ NdrFcShort( 0xffffffff ), /* Offset= -1 (525) */ +/* 528 */ + 0x1b, /* FC_CARRAY */ + 0x3, /* 3 */ +/* 530 */ NdrFcShort( 0x4 ), /* 4 */ +/* 532 */ 0x19, /* Corr desc: field pointer, FC_ULONG */ + 0x0, /* */ +/* 534 */ NdrFcShort( 0x0 ), /* 0 */ +/* 536 */ + 0x4b, /* FC_PP */ + 0x5c, /* FC_PAD */ +/* 538 */ + 0x48, /* FC_VARIABLE_REPEAT */ + 0x49, /* FC_FIXED_OFFSET */ +/* 540 */ NdrFcShort( 0x4 ), /* 4 */ +/* 542 */ NdrFcShort( 0x0 ), /* 0 */ +/* 544 */ NdrFcShort( 0x1 ), /* 1 */ +/* 546 */ NdrFcShort( 0x0 ), /* 0 */ +/* 548 */ NdrFcShort( 0x0 ), /* 0 */ +/* 550 */ 0x12, 0x0, /* FC_UP */ +/* 552 */ NdrFcShort( 0xffffff60 ), /* Offset= -160 (392) */ +/* 554 */ + 0x5b, /* FC_END */ + + 0x8, /* FC_LONG */ +/* 556 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 558 */ + 0x16, /* FC_PSTRUCT */ + 0x3, /* 3 */ +/* 560 */ NdrFcShort( 0x8 ), /* 8 */ +/* 562 */ + 0x4b, /* FC_PP */ + 0x5c, /* FC_PAD */ +/* 564 */ + 0x46, /* FC_NO_REPEAT */ + 0x5c, /* FC_PAD */ +/* 566 */ NdrFcShort( 0x4 ), /* 4 */ +/* 568 */ NdrFcShort( 0x4 ), /* 4 */ +/* 570 */ 0x11, 0x0, /* FC_RP */ +/* 572 */ NdrFcShort( 0xffffffd4 ), /* Offset= -44 (528) */ +/* 574 */ + 0x5b, /* FC_END */ + + 0x8, /* FC_LONG */ +/* 576 */ 0x8, /* FC_LONG */ + 0x5b, /* FC_END */ +/* 578 */ + 0x21, /* FC_BOGUS_ARRAY */ + 0x3, /* 3 */ +/* 580 */ NdrFcShort( 0x0 ), /* 0 */ +/* 582 */ 0x19, /* Corr desc: field pointer, FC_ULONG */ + 0x0, /* */ +/* 584 */ NdrFcShort( 0x0 ), /* 0 */ +/* 586 */ NdrFcLong( 0xffffffff ), /* -1 */ +/* 590 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 592 */ NdrFcShort( 0xffffff54 ), /* Offset= -172 (420) */ +/* 594 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 596 */ + 0x1a, /* FC_BOGUS_STRUCT */ + 0x3, /* 3 */ +/* 598 */ NdrFcShort( 0x8 ), /* 8 */ +/* 600 */ NdrFcShort( 0x0 ), /* 0 */ +/* 602 */ NdrFcShort( 0x6 ), /* Offset= 6 (608) */ +/* 604 */ 0x8, /* FC_LONG */ + 0x36, /* FC_POINTER */ +/* 606 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 608 */ + 0x11, 0x0, /* FC_RP */ +/* 610 */ NdrFcShort( 0xffffffe0 ), /* Offset= -32 (578) */ +/* 612 */ + 0x21, /* FC_BOGUS_ARRAY */ + 0x3, /* 3 */ +/* 614 */ NdrFcShort( 0x0 ), /* 0 */ +/* 616 */ 0x19, /* Corr desc: field pointer, FC_ULONG */ + 0x0, /* */ +/* 618 */ NdrFcShort( 0x0 ), /* 0 */ +/* 620 */ NdrFcLong( 0xffffffff ), /* -1 */ +/* 624 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 626 */ NdrFcShort( 0xffffff44 ), /* Offset= -188 (438) */ +/* 628 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 630 */ + 0x1a, /* FC_BOGUS_STRUCT */ + 0x3, /* 3 */ +/* 632 */ NdrFcShort( 0x8 ), /* 8 */ +/* 634 */ NdrFcShort( 0x0 ), /* 0 */ +/* 636 */ NdrFcShort( 0x6 ), /* Offset= 6 (642) */ +/* 638 */ 0x8, /* FC_LONG */ + 0x36, /* FC_POINTER */ +/* 640 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 642 */ + 0x11, 0x0, /* FC_RP */ +/* 644 */ NdrFcShort( 0xffffffe0 ), /* Offset= -32 (612) */ +/* 646 */ + 0x1b, /* FC_CARRAY */ + 0x3, /* 3 */ +/* 648 */ NdrFcShort( 0x4 ), /* 4 */ +/* 650 */ 0x19, /* Corr desc: field pointer, FC_ULONG */ + 0x0, /* */ +/* 652 */ NdrFcShort( 0x0 ), /* 0 */ +/* 654 */ + 0x4b, /* FC_PP */ + 0x5c, /* FC_PAD */ +/* 656 */ + 0x48, /* FC_VARIABLE_REPEAT */ + 0x49, /* FC_FIXED_OFFSET */ +/* 658 */ NdrFcShort( 0x4 ), /* 4 */ +/* 660 */ NdrFcShort( 0x0 ), /* 0 */ +/* 662 */ NdrFcShort( 0x1 ), /* 1 */ +/* 664 */ NdrFcShort( 0x0 ), /* 0 */ +/* 666 */ NdrFcShort( 0x0 ), /* 0 */ +/* 668 */ 0x12, 0x0, /* FC_UP */ +/* 670 */ NdrFcShort( 0x160 ), /* Offset= 352 (1022) */ +/* 672 */ + 0x5b, /* FC_END */ + + 0x8, /* FC_LONG */ +/* 674 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 676 */ + 0x1a, /* FC_BOGUS_STRUCT */ + 0x3, /* 3 */ +/* 678 */ NdrFcShort( 0x8 ), /* 8 */ +/* 680 */ NdrFcShort( 0x0 ), /* 0 */ +/* 682 */ NdrFcShort( 0x6 ), /* Offset= 6 (688) */ +/* 684 */ 0x8, /* FC_LONG */ + 0x36, /* FC_POINTER */ +/* 686 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 688 */ + 0x11, 0x0, /* FC_RP */ +/* 690 */ NdrFcShort( 0xffffffd4 ), /* Offset= -44 (646) */ +/* 692 */ + 0x2f, /* FC_IP */ + 0x5a, /* FC_CONSTANT_IID */ +/* 694 */ NdrFcLong( 0x2f ), /* 47 */ +/* 698 */ NdrFcShort( 0x0 ), /* 0 */ +/* 700 */ NdrFcShort( 0x0 ), /* 0 */ +/* 702 */ 0xc0, /* 192 */ + 0x0, /* 0 */ +/* 704 */ 0x0, /* 0 */ + 0x0, /* 0 */ +/* 706 */ 0x0, /* 0 */ + 0x0, /* 0 */ +/* 708 */ 0x0, /* 0 */ + 0x46, /* 70 */ +/* 710 */ + 0x1b, /* FC_CARRAY */ + 0x0, /* 0 */ +/* 712 */ NdrFcShort( 0x1 ), /* 1 */ +/* 714 */ 0x19, /* Corr desc: field pointer, FC_ULONG */ + 0x0, /* */ +/* 716 */ NdrFcShort( 0x4 ), /* 4 */ +/* 718 */ 0x1, /* FC_BYTE */ + 0x5b, /* FC_END */ +/* 720 */ + 0x1a, /* FC_BOGUS_STRUCT */ + 0x3, /* 3 */ +/* 722 */ NdrFcShort( 0x10 ), /* 16 */ +/* 724 */ NdrFcShort( 0x0 ), /* 0 */ +/* 726 */ NdrFcShort( 0xa ), /* Offset= 10 (736) */ +/* 728 */ 0x8, /* FC_LONG */ + 0x8, /* FC_LONG */ +/* 730 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 732 */ NdrFcShort( 0xffffffd8 ), /* Offset= -40 (692) */ +/* 734 */ 0x36, /* FC_POINTER */ + 0x5b, /* FC_END */ +/* 736 */ + 0x12, 0x0, /* FC_UP */ +/* 738 */ NdrFcShort( 0xffffffe4 ), /* Offset= -28 (710) */ +/* 740 */ + 0x1b, /* FC_CARRAY */ + 0x3, /* 3 */ +/* 742 */ NdrFcShort( 0x4 ), /* 4 */ +/* 744 */ 0x19, /* Corr desc: field pointer, FC_ULONG */ + 0x0, /* */ +/* 746 */ NdrFcShort( 0x0 ), /* 0 */ +/* 748 */ + 0x4b, /* FC_PP */ + 0x5c, /* FC_PAD */ +/* 750 */ + 0x48, /* FC_VARIABLE_REPEAT */ + 0x49, /* FC_FIXED_OFFSET */ +/* 752 */ NdrFcShort( 0x4 ), /* 4 */ +/* 754 */ NdrFcShort( 0x0 ), /* 0 */ +/* 756 */ NdrFcShort( 0x1 ), /* 1 */ +/* 758 */ NdrFcShort( 0x0 ), /* 0 */ +/* 760 */ NdrFcShort( 0x0 ), /* 0 */ +/* 762 */ 0x12, 0x0, /* FC_UP */ +/* 764 */ NdrFcShort( 0xffffffd4 ), /* Offset= -44 (720) */ +/* 766 */ + 0x5b, /* FC_END */ + + 0x8, /* FC_LONG */ +/* 768 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 770 */ + 0x1a, /* FC_BOGUS_STRUCT */ + 0x3, /* 3 */ +/* 772 */ NdrFcShort( 0x8 ), /* 8 */ +/* 774 */ NdrFcShort( 0x0 ), /* 0 */ +/* 776 */ NdrFcShort( 0x6 ), /* Offset= 6 (782) */ +/* 778 */ 0x8, /* FC_LONG */ + 0x36, /* FC_POINTER */ +/* 780 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 782 */ + 0x11, 0x0, /* FC_RP */ +/* 784 */ NdrFcShort( 0xffffffd4 ), /* Offset= -44 (740) */ +/* 786 */ + 0x1a, /* FC_BOGUS_STRUCT */ + 0x3, /* 3 */ +/* 788 */ NdrFcShort( 0x18 ), /* 24 */ +/* 790 */ NdrFcShort( 0x0 ), /* 0 */ +/* 792 */ NdrFcShort( 0xa ), /* Offset= 10 (802) */ +/* 794 */ 0x8, /* FC_LONG */ + 0x36, /* FC_POINTER */ +/* 796 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 798 */ NdrFcShort( 0xfffffd08 ), /* Offset= -760 (38) */ +/* 800 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 802 */ + 0x11, 0x0, /* FC_RP */ +/* 804 */ NdrFcShort( 0xffffff1e ), /* Offset= -226 (578) */ +/* 806 */ + 0x1b, /* FC_CARRAY */ + 0x0, /* 0 */ +/* 808 */ NdrFcShort( 0x1 ), /* 1 */ +/* 810 */ 0x19, /* Corr desc: field pointer, FC_ULONG */ + 0x0, /* */ +/* 812 */ NdrFcShort( 0x0 ), /* 0 */ +/* 814 */ 0x1, /* FC_BYTE */ + 0x5b, /* FC_END */ +/* 816 */ + 0x16, /* FC_PSTRUCT */ + 0x3, /* 3 */ +/* 818 */ NdrFcShort( 0x8 ), /* 8 */ +/* 820 */ + 0x4b, /* FC_PP */ + 0x5c, /* FC_PAD */ +/* 822 */ + 0x46, /* FC_NO_REPEAT */ + 0x5c, /* FC_PAD */ +/* 824 */ NdrFcShort( 0x4 ), /* 4 */ +/* 826 */ NdrFcShort( 0x4 ), /* 4 */ +/* 828 */ 0x12, 0x0, /* FC_UP */ +/* 830 */ NdrFcShort( 0xffffffe8 ), /* Offset= -24 (806) */ +/* 832 */ + 0x5b, /* FC_END */ + + 0x8, /* FC_LONG */ +/* 834 */ 0x8, /* FC_LONG */ + 0x5b, /* FC_END */ +/* 836 */ + 0x1b, /* FC_CARRAY */ + 0x1, /* 1 */ +/* 838 */ NdrFcShort( 0x2 ), /* 2 */ +/* 840 */ 0x19, /* Corr desc: field pointer, FC_ULONG */ + 0x0, /* */ +/* 842 */ NdrFcShort( 0x0 ), /* 0 */ +/* 844 */ 0x6, /* FC_SHORT */ + 0x5b, /* FC_END */ +/* 846 */ + 0x16, /* FC_PSTRUCT */ + 0x3, /* 3 */ +/* 848 */ NdrFcShort( 0x8 ), /* 8 */ +/* 850 */ + 0x4b, /* FC_PP */ + 0x5c, /* FC_PAD */ +/* 852 */ + 0x46, /* FC_NO_REPEAT */ + 0x5c, /* FC_PAD */ +/* 854 */ NdrFcShort( 0x4 ), /* 4 */ +/* 856 */ NdrFcShort( 0x4 ), /* 4 */ +/* 858 */ 0x12, 0x0, /* FC_UP */ +/* 860 */ NdrFcShort( 0xffffffe8 ), /* Offset= -24 (836) */ +/* 862 */ + 0x5b, /* FC_END */ + + 0x8, /* FC_LONG */ +/* 864 */ 0x8, /* FC_LONG */ + 0x5b, /* FC_END */ +/* 866 */ + 0x1b, /* FC_CARRAY */ + 0x3, /* 3 */ +/* 868 */ NdrFcShort( 0x4 ), /* 4 */ +/* 870 */ 0x19, /* Corr desc: field pointer, FC_ULONG */ + 0x0, /* */ +/* 872 */ NdrFcShort( 0x0 ), /* 0 */ +/* 874 */ 0x8, /* FC_LONG */ + 0x5b, /* FC_END */ +/* 876 */ + 0x16, /* FC_PSTRUCT */ + 0x3, /* 3 */ +/* 878 */ NdrFcShort( 0x8 ), /* 8 */ +/* 880 */ + 0x4b, /* FC_PP */ + 0x5c, /* FC_PAD */ +/* 882 */ + 0x46, /* FC_NO_REPEAT */ + 0x5c, /* FC_PAD */ +/* 884 */ NdrFcShort( 0x4 ), /* 4 */ +/* 886 */ NdrFcShort( 0x4 ), /* 4 */ +/* 888 */ 0x12, 0x0, /* FC_UP */ +/* 890 */ NdrFcShort( 0xffffffe8 ), /* Offset= -24 (866) */ +/* 892 */ + 0x5b, /* FC_END */ + + 0x8, /* FC_LONG */ +/* 894 */ 0x8, /* FC_LONG */ + 0x5b, /* FC_END */ +/* 896 */ + 0x1b, /* FC_CARRAY */ + 0x7, /* 7 */ +/* 898 */ NdrFcShort( 0x8 ), /* 8 */ +/* 900 */ 0x19, /* Corr desc: field pointer, FC_ULONG */ + 0x0, /* */ +/* 902 */ NdrFcShort( 0x0 ), /* 0 */ +/* 904 */ 0xb, /* FC_HYPER */ + 0x5b, /* FC_END */ +/* 906 */ + 0x16, /* FC_PSTRUCT */ + 0x3, /* 3 */ +/* 908 */ NdrFcShort( 0x8 ), /* 8 */ +/* 910 */ + 0x4b, /* FC_PP */ + 0x5c, /* FC_PAD */ +/* 912 */ + 0x46, /* FC_NO_REPEAT */ + 0x5c, /* FC_PAD */ +/* 914 */ NdrFcShort( 0x4 ), /* 4 */ +/* 916 */ NdrFcShort( 0x4 ), /* 4 */ +/* 918 */ 0x12, 0x0, /* FC_UP */ +/* 920 */ NdrFcShort( 0xffffffe8 ), /* Offset= -24 (896) */ +/* 922 */ + 0x5b, /* FC_END */ + + 0x8, /* FC_LONG */ +/* 924 */ 0x8, /* FC_LONG */ + 0x5b, /* FC_END */ +/* 926 */ + 0x15, /* FC_STRUCT */ + 0x3, /* 3 */ +/* 928 */ NdrFcShort( 0x8 ), /* 8 */ +/* 930 */ 0x8, /* FC_LONG */ + 0x8, /* FC_LONG */ +/* 932 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 934 */ + 0x1b, /* FC_CARRAY */ + 0x3, /* 3 */ +/* 936 */ NdrFcShort( 0x8 ), /* 8 */ +/* 938 */ 0x7, /* Corr desc: FC_USHORT */ + 0x0, /* */ +/* 940 */ NdrFcShort( 0xffd8 ), /* -40 */ +/* 942 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 944 */ NdrFcShort( 0xffffffee ), /* Offset= -18 (926) */ +/* 946 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 948 */ + 0x1a, /* FC_BOGUS_STRUCT */ + 0x3, /* 3 */ +/* 950 */ NdrFcShort( 0x28 ), /* 40 */ +/* 952 */ NdrFcShort( 0xffffffee ), /* Offset= -18 (934) */ +/* 954 */ NdrFcShort( 0x0 ), /* Offset= 0 (954) */ +/* 956 */ 0x6, /* FC_SHORT */ + 0x6, /* FC_SHORT */ +/* 958 */ 0x38, /* FC_ALIGNM4 */ + 0x8, /* FC_LONG */ +/* 960 */ 0x8, /* FC_LONG */ + 0x4c, /* FC_EMBEDDED_COMPLEX */ +/* 962 */ 0x0, /* 0 */ + NdrFcShort( 0xfffffe09 ), /* Offset= -503 (460) */ + 0x5b, /* FC_END */ +/* 966 */ + 0x12, 0x8, /* FC_UP [simple_pointer] */ +/* 968 */ 0x2, /* FC_CHAR */ + 0x5c, /* FC_PAD */ +/* 970 */ + 0x12, 0x8, /* FC_UP [simple_pointer] */ +/* 972 */ 0x6, /* FC_SHORT */ + 0x5c, /* FC_PAD */ +/* 974 */ + 0x12, 0x8, /* FC_UP [simple_pointer] */ +/* 976 */ 0x8, /* FC_LONG */ + 0x5c, /* FC_PAD */ +/* 978 */ + 0x12, 0x8, /* FC_UP [simple_pointer] */ +/* 980 */ 0xa, /* FC_FLOAT */ + 0x5c, /* FC_PAD */ +/* 982 */ + 0x12, 0x8, /* FC_UP [simple_pointer] */ +/* 984 */ 0xc, /* FC_DOUBLE */ + 0x5c, /* FC_PAD */ +/* 986 */ + 0x12, 0x10, /* FC_UP */ +/* 988 */ NdrFcShort( 0xfffffd9e ), /* Offset= -610 (378) */ +/* 990 */ + 0x12, 0x10, /* FC_UP */ +/* 992 */ NdrFcShort( 0x2 ), /* Offset= 2 (994) */ +/* 994 */ + 0x12, 0x0, /* FC_UP */ +/* 996 */ NdrFcShort( 0xfffffc1c ), /* Offset= -996 (0) */ +/* 998 */ + 0x12, 0x0, /* FC_UP */ +/* 1000 */ NdrFcShort( 0xfffffdaa ), /* Offset= -598 (402) */ +/* 1002 */ + 0x12, 0x0, /* FC_UP */ +/* 1004 */ NdrFcShort( 0xfffffdac ), /* Offset= -596 (408) */ +/* 1006 */ + 0x12, 0x10, /* FC_UP */ +/* 1008 */ NdrFcShort( 0xfffffdb4 ), /* Offset= -588 (420) */ +/* 1010 */ + 0x12, 0x10, /* FC_UP */ +/* 1012 */ NdrFcShort( 0xfffffdc2 ), /* Offset= -574 (438) */ +/* 1014 */ + 0x12, 0x10, /* FC_UP */ +/* 1016 */ NdrFcShort( 0xfffffdd0 ), /* Offset= -560 (456) */ +/* 1018 */ + 0x12, 0x0, /* FC_UP */ +/* 1020 */ NdrFcShort( 0xfffffed4 ), /* Offset= -300 (720) */ +/* 1022 */ + 0x1a, /* FC_BOGUS_STRUCT */ + 0x7, /* 7 */ +/* 1024 */ NdrFcShort( 0x20 ), /* 32 */ +/* 1026 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1028 */ NdrFcShort( 0x0 ), /* Offset= 0 (1028) */ +/* 1030 */ 0x8, /* FC_LONG */ + 0x8, /* FC_LONG */ +/* 1032 */ 0x6, /* FC_SHORT */ + 0x6, /* FC_SHORT */ +/* 1034 */ 0x6, /* FC_SHORT */ + 0x6, /* FC_SHORT */ +/* 1036 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 1038 */ NdrFcShort( 0xfffffc5c ), /* Offset= -932 (106) */ +/* 1040 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 1042 */ 0xb4, /* FC_USER_MARSHAL */ + 0x83, /* 131 */ +/* 1044 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1046 */ NdrFcShort( 0x10 ), /* 16 */ +/* 1048 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1050 */ NdrFcShort( 0xfffffc4c ), /* Offset= -948 (102) */ +/* 1052 */ + 0x21, /* FC_BOGUS_ARRAY */ + 0x3, /* 3 */ +/* 1054 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1056 */ 0x19, /* Corr desc: field pointer, FC_ULONG */ + 0x0, /* */ +/* 1058 */ NdrFcShort( 0x8 ), /* 8 */ +/* 1060 */ NdrFcLong( 0xffffffff ), /* -1 */ +/* 1064 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 1066 */ NdrFcShort( 0xffffffe8 ), /* Offset= -24 (1042) */ +/* 1068 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 1070 */ + 0x1b, /* FC_CARRAY */ + 0x3, /* 3 */ +/* 1072 */ NdrFcShort( 0x4 ), /* 4 */ +/* 1074 */ 0x19, /* Corr desc: field pointer, FC_ULONG */ + 0x0, /* */ +/* 1076 */ NdrFcShort( 0xc ), /* 12 */ +/* 1078 */ 0x8, /* FC_LONG */ + 0x5b, /* FC_END */ +/* 1080 */ + 0x1a, /* FC_BOGUS_STRUCT */ + 0x3, /* 3 */ +/* 1082 */ NdrFcShort( 0x10 ), /* 16 */ +/* 1084 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1086 */ NdrFcShort( 0x8 ), /* Offset= 8 (1094) */ +/* 1088 */ 0x36, /* FC_POINTER */ + 0x36, /* FC_POINTER */ +/* 1090 */ 0x8, /* FC_LONG */ + 0x8, /* FC_LONG */ +/* 1092 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 1094 */ + 0x12, 0x0, /* FC_UP */ +/* 1096 */ NdrFcShort( 0xffffffd4 ), /* Offset= -44 (1052) */ +/* 1098 */ + 0x12, 0x0, /* FC_UP */ +/* 1100 */ NdrFcShort( 0xffffffe2 ), /* Offset= -30 (1070) */ +/* 1102 */ + 0x11, 0x4, /* FC_RP [alloced_on_stack] */ +/* 1104 */ NdrFcShort( 0x6 ), /* Offset= 6 (1110) */ +/* 1106 */ + 0x13, 0x0, /* FC_OP */ +/* 1108 */ NdrFcShort( 0xffffffaa ), /* Offset= -86 (1022) */ +/* 1110 */ 0xb4, /* FC_USER_MARSHAL */ + 0x83, /* 131 */ +/* 1112 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1114 */ NdrFcShort( 0x10 ), /* 16 */ +/* 1116 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1118 */ NdrFcShort( 0xfffffff4 ), /* Offset= -12 (1106) */ +/* 1120 */ + 0x11, 0x4, /* FC_RP [alloced_on_stack] */ +/* 1122 */ NdrFcShort( 0x10 ), /* Offset= 16 (1138) */ +/* 1124 */ + 0x13, 0x0, /* FC_OP */ +/* 1126 */ NdrFcShort( 0xfffffd22 ), /* Offset= -734 (392) */ +/* 1128 */ 0xb4, /* FC_USER_MARSHAL */ + 0x83, /* 131 */ +/* 1130 */ NdrFcShort( 0x1 ), /* 1 */ +/* 1132 */ NdrFcShort( 0x4 ), /* 4 */ +/* 1134 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1136 */ NdrFcShort( 0xfffffff4 ), /* Offset= -12 (1124) */ +/* 1138 */ + 0x1a, /* FC_BOGUS_STRUCT */ + 0x3, /* 3 */ +/* 1140 */ NdrFcShort( 0x20 ), /* 32 */ +/* 1142 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1144 */ NdrFcShort( 0x0 ), /* Offset= 0 (1144) */ +/* 1146 */ 0x6, /* FC_SHORT */ + 0x6, /* FC_SHORT */ +/* 1148 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 1150 */ NdrFcShort( 0xffffffea ), /* Offset= -22 (1128) */ +/* 1152 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 1154 */ NdrFcShort( 0xffffffe6 ), /* Offset= -26 (1128) */ +/* 1156 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 1158 */ NdrFcShort( 0xffffffe2 ), /* Offset= -30 (1128) */ +/* 1160 */ 0x38, /* FC_ALIGNM4 */ + 0x8, /* FC_LONG */ +/* 1162 */ 0x8, /* FC_LONG */ + 0x8, /* FC_LONG */ +/* 1164 */ 0x8, /* FC_LONG */ + 0x5b, /* FC_END */ +/* 1166 */ + 0x11, 0x0, /* FC_RP */ +/* 1168 */ NdrFcShort( 0x2 ), /* Offset= 2 (1170) */ +/* 1170 */ + 0x1b, /* FC_CARRAY */ + 0x3, /* 3 */ +/* 1172 */ NdrFcShort( 0x4 ), /* 4 */ +/* 1174 */ 0x29, /* Corr desc: parameter, FC_ULONG */ + 0x0, /* */ +#ifndef _ALPHA_ +/* 1176 */ NdrFcShort( 0x24 ), /* x86, MIPS, PPC Stack size/offset = 36 */ +#else + NdrFcShort( 0x48 ), /* Alpha Stack size/offset = 72 */ +#endif +/* 1178 */ 0x8, /* FC_LONG */ + 0x5b, /* FC_END */ +/* 1180 */ + 0x11, 0x0, /* FC_RP */ +/* 1182 */ NdrFcShort( 0x2 ), /* Offset= 2 (1184) */ +/* 1184 */ + 0x21, /* FC_BOGUS_ARRAY */ + 0x3, /* 3 */ +/* 1186 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1188 */ 0x29, /* Corr desc: parameter, FC_ULONG */ + 0x0, /* */ +#ifndef _ALPHA_ +/* 1190 */ NdrFcShort( 0x24 ), /* x86, MIPS, PPC Stack size/offset = 36 */ +#else + NdrFcShort( 0x48 ), /* Alpha Stack size/offset = 72 */ +#endif +/* 1192 */ NdrFcLong( 0xffffffff ), /* -1 */ +/* 1196 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 1198 */ NdrFcShort( 0xffffffa8 ), /* Offset= -88 (1110) */ +/* 1200 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 1202 */ + 0x11, 0x0, /* FC_RP */ +/* 1204 */ NdrFcShort( 0x2 ), /* Offset= 2 (1206) */ +/* 1206 */ + 0x21, /* FC_BOGUS_ARRAY */ + 0x3, /* 3 */ +/* 1208 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1210 */ 0x29, /* Corr desc: parameter, FC_ULONG */ + 0x0, /* */ +#ifndef _ALPHA_ +/* 1212 */ NdrFcShort( 0x4 ), /* x86, MIPS, PPC Stack size/offset = 4 */ +#else + NdrFcShort( 0x8 ), /* Alpha Stack size/offset = 8 */ +#endif +/* 1214 */ 0x29, /* Corr desc: parameter, FC_ULONG */ + 0x54, /* FC_DEREFERENCE */ +#ifndef _ALPHA_ +/* 1216 */ NdrFcShort( 0xc ), /* x86, MIPS, PPC Stack size/offset = 12 */ +#else + NdrFcShort( 0x18 ), /* Alpha Stack size/offset = 24 */ +#endif +/* 1218 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 1220 */ NdrFcShort( 0xffffff92 ), /* Offset= -110 (1110) */ +/* 1222 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 1224 */ + 0x11, 0x14, /* FC_RP [alloced_on_stack] */ +/* 1226 */ NdrFcShort( 0x2 ), /* Offset= 2 (1228) */ +/* 1228 */ + 0x2f, /* FC_IP */ + 0x5a, /* FC_CONSTANT_IID */ +/* 1230 */ NdrFcLong( 0x20404 ), /* 132100 */ +/* 1234 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1236 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1238 */ 0xc0, /* 192 */ + 0x0, /* 0 */ +/* 1240 */ 0x0, /* 0 */ + 0x0, /* 0 */ +/* 1242 */ 0x0, /* 0 */ + 0x0, /* 0 */ +/* 1244 */ 0x0, /* 0 */ + 0x46, /* 70 */ +/* 1246 */ + 0x11, 0x8, /* FC_RP [simple_pointer] */ +/* 1248 */ + 0x25, /* FC_C_WSTRING */ + 0x5c, /* FC_PAD */ +/* 1250 */ + 0x11, 0xc, /* FC_RP [alloced_on_stack] [simple_pointer] */ +/* 1252 */ 0xe, /* FC_ENUM32 */ + 0x5c, /* FC_PAD */ +/* 1254 */ + 0x11, 0x14, /* FC_RP [alloced_on_stack] */ +/* 1256 */ NdrFcShort( 0x2 ), /* Offset= 2 (1258) */ +/* 1258 */ + 0x13, 0x0, /* FC_OP */ +/* 1260 */ NdrFcShort( 0xaa ), /* Offset= 170 (1430) */ +/* 1262 */ + 0x2b, /* FC_NON_ENCAPSULATED_UNION */ + 0x7, /* FC_USHORT */ +/* 1264 */ 0x7, /* Corr desc: FC_USHORT */ + 0x0, /* */ +/* 1266 */ NdrFcShort( 0x4 ), /* 4 */ +/* 1268 */ NdrFcShort( 0x2 ), /* Offset= 2 (1270) */ +/* 1270 */ NdrFcShort( 0x4 ), /* 4 */ +/* 1272 */ NdrFcShort( 0x4 ), /* 4 */ +/* 1274 */ NdrFcLong( 0x1a ), /* 26 */ +/* 1278 */ NdrFcShort( 0x16 ), /* Offset= 22 (1300) */ +/* 1280 */ NdrFcLong( 0x1b ), /* 27 */ +/* 1284 */ NdrFcShort( 0x10 ), /* Offset= 16 (1300) */ +/* 1286 */ NdrFcLong( 0x1c ), /* 28 */ +/* 1290 */ NdrFcShort( 0xe ), /* Offset= 14 (1304) */ +/* 1292 */ NdrFcLong( 0x1d ), /* 29 */ +/* 1296 */ NdrFcShort( 0x8008 ), /* Simple arm type: FC_LONG */ +/* 1298 */ NdrFcShort( 0x0 ), /* Offset= 0 (1298) */ +/* 1300 */ + 0x13, 0x0, /* FC_OP */ +/* 1302 */ NdrFcShort( 0x24 ), /* Offset= 36 (1338) */ +/* 1304 */ + 0x13, 0x0, /* FC_OP */ +/* 1306 */ NdrFcShort( 0x10 ), /* Offset= 16 (1322) */ +/* 1308 */ + 0x1b, /* FC_CARRAY */ + 0x3, /* 3 */ +/* 1310 */ NdrFcShort( 0x8 ), /* 8 */ +/* 1312 */ 0x7, /* Corr desc: FC_USHORT */ + 0x0, /* */ +/* 1314 */ NdrFcShort( 0xfffc ), /* -4 */ +/* 1316 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 1318 */ NdrFcShort( 0xfffffe78 ), /* Offset= -392 (926) */ +/* 1320 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 1322 */ + 0x1a, /* FC_BOGUS_STRUCT */ + 0x3, /* 3 */ +/* 1324 */ NdrFcShort( 0x4 ), /* 4 */ +/* 1326 */ NdrFcShort( 0xffffffee ), /* Offset= -18 (1308) */ +/* 1328 */ NdrFcShort( 0x0 ), /* Offset= 0 (1328) */ +/* 1330 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 1332 */ NdrFcShort( 0x6 ), /* Offset= 6 (1338) */ +/* 1334 */ 0x6, /* FC_SHORT */ + 0x3e, /* FC_STRUCTPAD2 */ +/* 1336 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 1338 */ + 0x1a, /* FC_BOGUS_STRUCT */ + 0x3, /* 3 */ +/* 1340 */ NdrFcShort( 0x8 ), /* 8 */ +/* 1342 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1344 */ NdrFcShort( 0x0 ), /* Offset= 0 (1344) */ +/* 1346 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 1348 */ NdrFcShort( 0xffffffaa ), /* Offset= -86 (1262) */ +/* 1350 */ 0x6, /* FC_SHORT */ + 0x3e, /* FC_STRUCTPAD2 */ +/* 1352 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 1354 */ + 0x1a, /* FC_BOGUS_STRUCT */ + 0x3, /* 3 */ +/* 1356 */ NdrFcShort( 0x18 ), /* 24 */ +/* 1358 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1360 */ NdrFcShort( 0x0 ), /* Offset= 0 (1360) */ +/* 1362 */ 0x8, /* FC_LONG */ + 0x4c, /* FC_EMBEDDED_COMPLEX */ +/* 1364 */ 0x4, /* 4 */ + NdrFcShort( 0xffffff01 ), /* Offset= -255 (1110) */ + 0x5b, /* FC_END */ +/* 1368 */ + 0x1a, /* FC_BOGUS_STRUCT */ + 0x3, /* 3 */ +/* 1370 */ NdrFcShort( 0x8 ), /* 8 */ +/* 1372 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1374 */ NdrFcShort( 0x6 ), /* Offset= 6 (1380) */ +/* 1376 */ 0x36, /* FC_POINTER */ + 0x6, /* FC_SHORT */ +/* 1378 */ 0x3e, /* FC_STRUCTPAD2 */ + 0x5b, /* FC_END */ +/* 1380 */ + 0x13, 0x0, /* FC_OP */ +/* 1382 */ NdrFcShort( 0xffffffe4 ), /* Offset= -28 (1354) */ +/* 1384 */ + 0x1a, /* FC_BOGUS_STRUCT */ + 0x3, /* 3 */ +/* 1386 */ NdrFcShort( 0x10 ), /* 16 */ +/* 1388 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1390 */ NdrFcShort( 0x0 ), /* Offset= 0 (1390) */ +/* 1392 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 1394 */ NdrFcShort( 0xffffffc8 ), /* Offset= -56 (1338) */ +/* 1396 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 1398 */ NdrFcShort( 0xffffffe2 ), /* Offset= -30 (1368) */ +/* 1400 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 1402 */ + 0x1b, /* FC_CARRAY */ + 0x3, /* 3 */ +/* 1404 */ NdrFcShort( 0x4 ), /* 4 */ +/* 1406 */ 0x16, /* Corr desc: field pointer, FC_SHORT */ + 0x0, /* */ +/* 1408 */ NdrFcShort( 0x1e ), /* 30 */ +/* 1410 */ 0x8, /* FC_LONG */ + 0x5b, /* FC_END */ +/* 1412 */ + 0x21, /* FC_BOGUS_ARRAY */ + 0x3, /* 3 */ +/* 1414 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1416 */ 0x16, /* Corr desc: field pointer, FC_SHORT */ + 0x0, /* */ +/* 1418 */ NdrFcShort( 0x18 ), /* 24 */ +/* 1420 */ NdrFcLong( 0xffffffff ), /* -1 */ +/* 1424 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 1426 */ NdrFcShort( 0xffffffd6 ), /* Offset= -42 (1384) */ +/* 1428 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 1430 */ + 0x1a, /* FC_BOGUS_STRUCT */ + 0x3, /* 3 */ +/* 1432 */ NdrFcShort( 0x34 ), /* 52 */ +/* 1434 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1436 */ NdrFcShort( 0x14 ), /* Offset= 20 (1456) */ +/* 1438 */ 0x8, /* FC_LONG */ + 0x36, /* FC_POINTER */ +/* 1440 */ 0x36, /* FC_POINTER */ + 0xe, /* FC_ENUM32 */ +/* 1442 */ 0xe, /* FC_ENUM32 */ + 0xe, /* FC_ENUM32 */ +/* 1444 */ 0x6, /* FC_SHORT */ + 0x6, /* FC_SHORT */ +/* 1446 */ 0x6, /* FC_SHORT */ + 0x6, /* FC_SHORT */ +/* 1448 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 1450 */ NdrFcShort( 0xffffffbe ), /* Offset= -66 (1384) */ +/* 1452 */ 0x6, /* FC_SHORT */ + 0x3e, /* FC_STRUCTPAD2 */ +/* 1454 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 1456 */ + 0x13, 0x0, /* FC_OP */ +/* 1458 */ NdrFcShort( 0xffffffc8 ), /* Offset= -56 (1402) */ +/* 1460 */ + 0x13, 0x0, /* FC_OP */ +/* 1462 */ NdrFcShort( 0xffffffce ), /* Offset= -50 (1412) */ +/* 1464 */ + 0x11, 0x14, /* FC_RP [alloced_on_stack] */ +/* 1466 */ NdrFcShort( 0x2 ), /* Offset= 2 (1468) */ +/* 1468 */ + 0x13, 0x0, /* FC_OP */ +/* 1470 */ NdrFcShort( 0x2c ), /* Offset= 44 (1514) */ +/* 1472 */ + 0x2b, /* FC_NON_ENCAPSULATED_UNION */ + 0x8, /* FC_LONG */ +/* 1474 */ 0x8, /* Corr desc: FC_LONG */ + 0x0, /* */ +/* 1476 */ NdrFcShort( 0x18 ), /* 24 */ +/* 1478 */ NdrFcShort( 0x2 ), /* Offset= 2 (1480) */ +/* 1480 */ NdrFcShort( 0x4 ), /* 4 */ +/* 1482 */ NdrFcShort( 0x4 ), /* 4 */ +/* 1484 */ NdrFcLong( 0x0 ), /* 0 */ +/* 1488 */ NdrFcShort( 0x8008 ), /* Simple arm type: FC_LONG */ +/* 1490 */ NdrFcLong( 0x3 ), /* 3 */ +/* 1494 */ NdrFcShort( 0x8008 ), /* Simple arm type: FC_LONG */ +/* 1496 */ NdrFcLong( 0x1 ), /* 1 */ +/* 1500 */ NdrFcShort( 0x8008 ), /* Simple arm type: FC_LONG */ +/* 1502 */ NdrFcLong( 0x2 ), /* 2 */ +/* 1506 */ NdrFcShort( 0x4 ), /* Offset= 4 (1510) */ +/* 1508 */ NdrFcShort( 0xffffffff ), /* Offset= -1 (1507) */ +/* 1510 */ + 0x13, 0x0, /* FC_OP */ +/* 1512 */ NdrFcShort( 0xfffffe6e ), /* Offset= -402 (1110) */ +/* 1514 */ + 0x1a, /* FC_BOGUS_STRUCT */ + 0x3, /* 3 */ +/* 1516 */ NdrFcShort( 0x24 ), /* 36 */ +/* 1518 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1520 */ NdrFcShort( 0x10 ), /* Offset= 16 (1536) */ +/* 1522 */ 0x8, /* FC_LONG */ + 0x36, /* FC_POINTER */ +/* 1524 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 1526 */ NdrFcShort( 0xffffffca ), /* Offset= -54 (1472) */ +/* 1528 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 1530 */ NdrFcShort( 0xffffff6e ), /* Offset= -146 (1384) */ +/* 1532 */ 0x6, /* FC_SHORT */ + 0x38, /* FC_ALIGNM4 */ +/* 1534 */ 0xe, /* FC_ENUM32 */ + 0x5b, /* FC_END */ +/* 1536 */ + 0x13, 0x8, /* FC_OP [simple_pointer] */ +/* 1538 */ + 0x25, /* FC_C_WSTRING */ + 0x5c, /* FC_PAD */ +/* 1540 */ + 0x11, 0x14, /* FC_RP [alloced_on_stack] */ +/* 1542 */ NdrFcShort( 0x2 ), /* Offset= 2 (1544) */ +/* 1544 */ + 0x2f, /* FC_IP */ + 0x5a, /* FC_CONSTANT_IID */ +/* 1546 */ NdrFcLong( 0x20403 ), /* 132099 */ +/* 1550 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1552 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1554 */ 0xc0, /* 192 */ + 0x0, /* 0 */ +/* 1556 */ 0x0, /* 0 */ + 0x0, /* 0 */ +/* 1558 */ 0x0, /* 0 */ + 0x0, /* 0 */ +/* 1560 */ 0x0, /* 0 */ + 0x46, /* 70 */ +/* 1562 */ + 0x11, 0x4, /* FC_RP [alloced_on_stack] */ +/* 1564 */ NdrFcShort( 0x4 ), /* Offset= 4 (1568) */ +/* 1566 */ 0x8, /* FC_LONG */ + 0x5c, /* FC_PAD */ +/* 1568 */ 0xb4, /* FC_USER_MARSHAL */ + 0x3, /* 3 */ +/* 1570 */ NdrFcShort( 0x2 ), /* 2 */ +/* 1572 */ NdrFcShort( 0xc ), /* 12 */ +/* 1574 */ NdrFcShort( 0x4 ), /* 4 */ +/* 1576 */ NdrFcShort( 0xfffffff6 ), /* Offset= -10 (1566) */ +/* 1578 */ + 0x11, 0x14, /* FC_RP [alloced_on_stack] */ +/* 1580 */ NdrFcShort( 0x2 ), /* Offset= 2 (1582) */ +/* 1582 */ + 0x13, 0x0, /* FC_OP */ +/* 1584 */ NdrFcShort( 0xe ), /* Offset= 14 (1598) */ +/* 1586 */ + 0x1a, /* FC_BOGUS_STRUCT */ + 0x3, /* 3 */ +/* 1588 */ NdrFcShort( 0x8 ), /* 8 */ +/* 1590 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1592 */ NdrFcShort( 0x0 ), /* Offset= 0 (1592) */ +/* 1594 */ 0x8, /* FC_LONG */ + 0x6, /* FC_SHORT */ +/* 1596 */ 0x3e, /* FC_STRUCTPAD2 */ + 0x5b, /* FC_END */ +/* 1598 */ + 0x1a, /* FC_BOGUS_STRUCT */ + 0x3, /* 3 */ +/* 1600 */ NdrFcShort( 0x4c ), /* 76 */ +/* 1602 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1604 */ NdrFcShort( 0x1e ), /* Offset= 30 (1634) */ +/* 1606 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 1608 */ NdrFcShort( 0xfffff9de ), /* Offset= -1570 (38) */ +/* 1610 */ 0x8, /* FC_LONG */ + 0x8, /* FC_LONG */ +/* 1612 */ 0x8, /* FC_LONG */ + 0x8, /* FC_LONG */ +/* 1614 */ 0x36, /* FC_POINTER */ + 0x8, /* FC_LONG */ +/* 1616 */ 0xe, /* FC_ENUM32 */ + 0x6, /* FC_SHORT */ +/* 1618 */ 0x6, /* FC_SHORT */ + 0x6, /* FC_SHORT */ +/* 1620 */ 0x6, /* FC_SHORT */ + 0x6, /* FC_SHORT */ +/* 1622 */ 0x6, /* FC_SHORT */ + 0x6, /* FC_SHORT */ +/* 1624 */ 0x6, /* FC_SHORT */ + 0x4c, /* FC_EMBEDDED_COMPLEX */ +/* 1626 */ 0x0, /* 0 */ + NdrFcShort( 0xfffffedf ), /* Offset= -289 (1338) */ + 0x4c, /* FC_EMBEDDED_COMPLEX */ +/* 1630 */ 0x0, /* 0 */ + NdrFcShort( 0xffffffd3 ), /* Offset= -45 (1586) */ + 0x5b, /* FC_END */ +/* 1634 */ + 0x13, 0x8, /* FC_OP [simple_pointer] */ +/* 1636 */ + 0x25, /* FC_C_WSTRING */ + 0x5c, /* FC_PAD */ +/* 1638 */ + 0x11, 0x4, /* FC_RP [alloced_on_stack] */ +/* 1640 */ NdrFcShort( 0x4 ), /* Offset= 4 (1644) */ +/* 1642 */ 0x8, /* FC_LONG */ + 0x5c, /* FC_PAD */ +/* 1644 */ 0xb4, /* FC_USER_MARSHAL */ + 0x3, /* 3 */ +/* 1646 */ NdrFcShort( 0x2 ), /* 2 */ +/* 1648 */ NdrFcShort( 0xc ), /* 12 */ +/* 1650 */ NdrFcShort( 0x4 ), /* 4 */ +/* 1652 */ NdrFcShort( 0xfffffff6 ), /* Offset= -10 (1642) */ +/* 1654 */ + 0x11, 0x4, /* FC_RP [alloced_on_stack] */ +/* 1656 */ NdrFcShort( 0x4 ), /* Offset= 4 (1660) */ +/* 1658 */ 0x8, /* FC_LONG */ + 0x5c, /* FC_PAD */ +/* 1660 */ 0xb4, /* FC_USER_MARSHAL */ + 0x3, /* 3 */ +/* 1662 */ NdrFcShort( 0x2 ), /* 2 */ +/* 1664 */ NdrFcShort( 0xc ), /* 12 */ +/* 1666 */ NdrFcShort( 0x4 ), /* 4 */ +/* 1668 */ NdrFcShort( 0xfffffff6 ), /* Offset= -10 (1658) */ +/* 1670 */ + 0x11, 0x4, /* FC_RP [alloced_on_stack] */ +/* 1672 */ NdrFcShort( 0x4 ), /* Offset= 4 (1676) */ +/* 1674 */ 0x8, /* FC_LONG */ + 0x5c, /* FC_PAD */ +/* 1676 */ 0xb4, /* FC_USER_MARSHAL */ + 0x3, /* 3 */ +/* 1678 */ NdrFcShort( 0x2 ), /* 2 */ +/* 1680 */ NdrFcShort( 0xc ), /* 12 */ +/* 1682 */ NdrFcShort( 0x4 ), /* 4 */ +/* 1684 */ NdrFcShort( 0xfffffff6 ), /* Offset= -10 (1674) */ +/* 1686 */ + 0x11, 0x0, /* FC_RP */ +/* 1688 */ NdrFcShort( 0x2 ), /* Offset= 2 (1690) */ +/* 1690 */ + 0x21, /* FC_BOGUS_ARRAY */ + 0x3, /* 3 */ +/* 1692 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1694 */ 0x29, /* Corr desc: parameter, FC_ULONG */ + 0x0, /* */ +#ifndef _ALPHA_ +/* 1696 */ NdrFcShort( 0xc ), /* x86, MIPS, PPC Stack size/offset = 12 */ +#else + NdrFcShort( 0x18 ), /* Alpha Stack size/offset = 24 */ +#endif +/* 1698 */ 0x29, /* Corr desc: parameter, FC_ULONG */ + 0x54, /* FC_DEREFERENCE */ +#ifndef _ALPHA_ +/* 1700 */ NdrFcShort( 0x10 ), /* x86, MIPS, PPC Stack size/offset = 16 */ +#else + NdrFcShort( 0x20 ), /* Alpha Stack size/offset = 32 */ +#endif +/* 1702 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 1704 */ NdrFcShort( 0xfffffdc0 ), /* Offset= -576 (1128) */ +/* 1706 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 1708 */ + 0x11, 0x4, /* FC_RP [alloced_on_stack] */ +/* 1710 */ NdrFcShort( 0xfffffdba ), /* Offset= -582 (1128) */ +/* 1712 */ + 0x11, 0xc, /* FC_RP [alloced_on_stack] [simple_pointer] */ +/* 1714 */ 0x6, /* FC_SHORT */ + 0x5c, /* FC_PAD */ +/* 1716 */ + 0x11, 0x14, /* FC_RP [alloced_on_stack] */ +/* 1718 */ NdrFcShort( 0x2 ), /* Offset= 2 (1720) */ +/* 1720 */ + 0x2f, /* FC_IP */ + 0x5c, /* FC_PAD */ +/* 1722 */ 0x28, /* Corr desc: parameter, FC_LONG */ + 0x0, /* */ +#ifndef _ALPHA_ +/* 1724 */ NdrFcShort( 0x4 ), /* x86, MIPS, PPC Stack size/offset = 4 */ +#else + NdrFcShort( 0x8 ), /* Alpha Stack size/offset = 8 */ +#endif +/* 1726 */ + 0x11, 0x14, /* FC_RP [alloced_on_stack] */ +/* 1728 */ NdrFcShort( 0x2 ), /* Offset= 2 (1730) */ +/* 1730 */ + 0x2f, /* FC_IP */ + 0x5a, /* FC_CONSTANT_IID */ +/* 1732 */ NdrFcLong( 0x20402 ), /* 132098 */ +/* 1736 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1738 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1740 */ 0xc0, /* 192 */ + 0x0, /* 0 */ +/* 1742 */ 0x0, /* 0 */ + 0x0, /* 0 */ +/* 1744 */ 0x0, /* 0 */ + 0x0, /* 0 */ +/* 1746 */ 0x0, /* 0 */ + 0x46, /* 70 */ +/* 1748 */ + 0x11, 0x4, /* FC_RP [alloced_on_stack] */ +/* 1750 */ NdrFcShort( 0x26 ), /* Offset= 38 (1788) */ +/* 1752 */ + 0x1a, /* FC_BOGUS_STRUCT */ + 0x3, /* 3 */ +/* 1754 */ NdrFcShort( 0x20 ), /* 32 */ +/* 1756 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1758 */ NdrFcShort( 0x0 ), /* Offset= 0 (1758) */ +/* 1760 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 1762 */ NdrFcShort( 0xfffff944 ), /* Offset= -1724 (38) */ +/* 1764 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 1766 */ NdrFcShort( 0xfffffd70 ), /* Offset= -656 (1110) */ +/* 1768 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 1770 */ + 0x21, /* FC_BOGUS_ARRAY */ + 0x3, /* 3 */ +/* 1772 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1774 */ 0x19, /* Corr desc: field pointer, FC_ULONG */ + 0x0, /* */ +/* 1776 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1778 */ NdrFcLong( 0xffffffff ), /* -1 */ +/* 1782 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 1784 */ NdrFcShort( 0xffffffe0 ), /* Offset= -32 (1752) */ +/* 1786 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 1788 */ + 0x1a, /* FC_BOGUS_STRUCT */ + 0x3, /* 3 */ +/* 1790 */ NdrFcShort( 0x8 ), /* 8 */ +/* 1792 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1794 */ NdrFcShort( 0x6 ), /* Offset= 6 (1800) */ +/* 1796 */ 0x8, /* FC_LONG */ + 0x36, /* FC_POINTER */ +/* 1798 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 1800 */ + 0x13, 0x0, /* FC_OP */ +/* 1802 */ NdrFcShort( 0xffffffe0 ), /* Offset= -32 (1770) */ +/* 1804 */ + 0x11, 0x14, /* FC_RP [alloced_on_stack] */ +/* 1806 */ NdrFcShort( 0x2 ), /* Offset= 2 (1808) */ +/* 1808 */ + 0x13, 0x0, /* FC_OP */ +/* 1810 */ NdrFcShort( 0x2 ), /* Offset= 2 (1812) */ +/* 1812 */ + 0x1a, /* FC_BOGUS_STRUCT */ + 0x3, /* 3 */ +/* 1814 */ NdrFcShort( 0x20 ), /* 32 */ +/* 1816 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1818 */ NdrFcShort( 0x0 ), /* Offset= 0 (1818) */ +/* 1820 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 1822 */ NdrFcShort( 0xfffff908 ), /* Offset= -1784 (38) */ +/* 1824 */ 0x8, /* FC_LONG */ + 0xe, /* FC_ENUM32 */ +/* 1826 */ 0x6, /* FC_SHORT */ + 0x6, /* FC_SHORT */ +/* 1828 */ 0x6, /* FC_SHORT */ + 0x3e, /* FC_STRUCTPAD2 */ +/* 1830 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 1832 */ + 0x11, 0x4, /* FC_RP [alloced_on_stack] */ +/* 1834 */ NdrFcShort( 0x4 ), /* Offset= 4 (1838) */ +/* 1836 */ 0x8, /* FC_LONG */ + 0x5c, /* FC_PAD */ +/* 1838 */ 0xb4, /* FC_USER_MARSHAL */ + 0x3, /* 3 */ +/* 1840 */ NdrFcShort( 0x2 ), /* 2 */ +/* 1842 */ NdrFcShort( 0xc ), /* 12 */ +/* 1844 */ NdrFcShort( 0x4 ), /* 4 */ +/* 1846 */ NdrFcShort( 0xfffffff6 ), /* Offset= -10 (1836) */ +/* 1848 */ + 0x11, 0x0, /* FC_RP */ +/* 1850 */ NdrFcShort( 0x2 ), /* Offset= 2 (1852) */ +/* 1852 */ + 0x21, /* FC_BOGUS_ARRAY */ + 0x3, /* 3 */ +/* 1854 */ NdrFcShort( 0x0 ), /* 0 */ +/* 1856 */ 0x27, /* Corr desc: parameter, FC_USHORT */ + 0x54, /* FC_DEREFERENCE */ +#ifndef _ALPHA_ +/* 1858 */ NdrFcShort( 0x14 ), /* x86, MIPS, PPC Stack size/offset = 20 */ +#else + NdrFcShort( 0x28 ), /* Alpha Stack size/offset = 40 */ +#endif +/* 1860 */ 0x27, /* Corr desc: parameter, FC_USHORT */ + 0x54, /* FC_DEREFERENCE */ +#ifndef _ALPHA_ +/* 1862 */ NdrFcShort( 0x14 ), /* x86, MIPS, PPC Stack size/offset = 20 */ +#else + NdrFcShort( 0x28 ), /* Alpha Stack size/offset = 40 */ +#endif +/* 1864 */ 0x4c, /* FC_EMBEDDED_COMPLEX */ + 0x0, /* 0 */ +/* 1866 */ NdrFcShort( 0xfffff8c0 ), /* Offset= -1856 (10) */ +/* 1868 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ +/* 1870 */ + 0x11, 0x0, /* FC_RP */ +/* 1872 */ NdrFcShort( 0x2 ), /* Offset= 2 (1874) */ +/* 1874 */ + 0x1c, /* FC_CVARRAY */ + 0x3, /* 3 */ +/* 1876 */ NdrFcShort( 0x4 ), /* 4 */ +/* 1878 */ 0x27, /* Corr desc: parameter, FC_USHORT */ + 0x54, /* FC_DEREFERENCE */ +#ifndef _ALPHA_ +/* 1880 */ NdrFcShort( 0x14 ), /* x86, MIPS, PPC Stack size/offset = 20 */ +#else + NdrFcShort( 0x28 ), /* Alpha Stack size/offset = 40 */ +#endif +/* 1882 */ 0x27, /* Corr desc: parameter, FC_USHORT */ + 0x54, /* FC_DEREFERENCE */ +#ifndef _ALPHA_ +/* 1884 */ NdrFcShort( 0x14 ), /* x86, MIPS, PPC Stack size/offset = 20 */ +#else + NdrFcShort( 0x28 ), /* Alpha Stack size/offset = 40 */ +#endif +/* 1886 */ 0x8, /* FC_LONG */ + 0x5b, /* FC_END */ +/* 1888 */ + 0x11, 0x8, /* FC_RP [simple_pointer] */ +/* 1890 */ 0x6, /* FC_SHORT */ + 0x5c, /* FC_PAD */ +/* 1892 */ + 0x11, 0x4, /* FC_RP [alloced_on_stack] */ +/* 1894 */ NdrFcShort( 0xfffff8c0 ), /* Offset= -1856 (38) */ +/* 1896 */ + 0x11, 0x14, /* FC_RP [alloced_on_stack] */ +/* 1898 */ NdrFcShort( 0x2 ), /* Offset= 2 (1900) */ +/* 1900 */ + 0x2f, /* FC_IP */ + 0x5c, /* FC_PAD */ +/* 1902 */ 0x28, /* Corr desc: parameter, FC_LONG */ + 0x0, /* */ +#ifndef _ALPHA_ +/* 1904 */ NdrFcShort( 0x8 ), /* x86, MIPS, PPC Stack size/offset = 8 */ +#else + NdrFcShort( 0x10 ), /* Alpha Stack size/offset = 16 */ +#endif + + 0x0 + } + }; + +const CInterfaceProxyVtbl * _oaidl_ProxyVtblList[] = +{ + ( CInterfaceProxyVtbl *) &_IDispatchProxyVtbl, + ( CInterfaceProxyVtbl *) &_ITypeInfoProxyVtbl, + ( CInterfaceProxyVtbl *) &_ITypeLibProxyVtbl, + ( CInterfaceProxyVtbl *) &_ITypeCompProxyVtbl, + ( CInterfaceProxyVtbl *) &_IEnumVARIANTProxyVtbl, + ( CInterfaceProxyVtbl *) &_ITypeLib2ProxyVtbl, + ( CInterfaceProxyVtbl *) &_ITypeInfo2ProxyVtbl, + ( CInterfaceProxyVtbl *) &_IErrorInfoProxyVtbl, + ( CInterfaceProxyVtbl *) &_ITypeFactoryProxyVtbl, + ( CInterfaceProxyVtbl *) &_ICreateErrorInfoProxyVtbl, + ( CInterfaceProxyVtbl *) &_ISupportErrorInfoProxyVtbl, + 0 +}; + +const CInterfaceStubVtbl * _oaidl_StubVtblList[] = +{ + ( CInterfaceStubVtbl *) &_IDispatchStubVtbl, + ( CInterfaceStubVtbl *) &_ITypeInfoStubVtbl, + ( CInterfaceStubVtbl *) &_ITypeLibStubVtbl, + ( CInterfaceStubVtbl *) &_ITypeCompStubVtbl, + ( CInterfaceStubVtbl *) &_IEnumVARIANTStubVtbl, + ( CInterfaceStubVtbl *) &_ITypeLib2StubVtbl, + ( CInterfaceStubVtbl *) &_ITypeInfo2StubVtbl, + ( CInterfaceStubVtbl *) &_IErrorInfoStubVtbl, + ( CInterfaceStubVtbl *) &_ITypeFactoryStubVtbl, + ( CInterfaceStubVtbl *) &_ICreateErrorInfoStubVtbl, + ( CInterfaceStubVtbl *) &_ISupportErrorInfoStubVtbl, + 0 +}; + +PCInterfaceName const _oaidl_InterfaceNamesList[] = +{ + "IDispatch", + "ITypeInfo", + "ITypeLib", + "ITypeComp", + "IEnumVARIANT", + "ITypeLib2", + "ITypeInfo2", + "IErrorInfo", + "ITypeFactory", + "ICreateErrorInfo", + "ISupportErrorInfo", + 0 +}; + + +#define _oaidl_CHECK_IID(n) IID_GENERIC_CHECK_IID( _oaidl, pIID, n) + +int __stdcall _oaidl_IID_Lookup( const IID * pIID, int * pIndex ) +{ + IID_BS_LOOKUP_SETUP + + IID_BS_LOOKUP_INITIAL_TEST( _oaidl, 11, 8 ) + IID_BS_LOOKUP_NEXT_TEST( _oaidl, 4 ) + IID_BS_LOOKUP_NEXT_TEST( _oaidl, 2 ) + IID_BS_LOOKUP_NEXT_TEST( _oaidl, 1 ) + IID_BS_LOOKUP_RETURN_RESULT( _oaidl, 11, *pIndex ) + +} + +const ExtendedProxyFileInfo oaidl_ProxyFileInfo = +{ + (PCInterfaceProxyVtblList *) & _oaidl_ProxyVtblList, + (PCInterfaceStubVtblList *) & _oaidl_StubVtblList, + (const PCInterfaceName * ) & _oaidl_InterfaceNamesList, + 0, /* no delegation */ + & _oaidl_IID_Lookup, + 11, + 1, + 0, /* table of [async_uuid] interfaces */ + 0, /* Filler1 */ + 0, /* Filler2 */ + 0 /* Filler3 */ +}; diff --git a/reactos/lib/oleaut32/ole2disp.c b/reactos/lib/oleaut32/ole2disp.c new file mode 100644 index 00000000000..37cbef0d7fd --- /dev/null +++ b/reactos/lib/oleaut32/ole2disp.c @@ -0,0 +1,250 @@ +/* + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "config.h" + +#include +#include + +#include "wine/windef16.h" +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" +#include "ole2.h" +#include "oleauto.h" +#include "winerror.h" + +#include "ole2disp.h" +#include "olectl.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(ole); + +/* 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)); +} + +/****************************************************************************** + * CreateDispTypeInfo [OLE2DISP.31] + */ +HRESULT WINAPI CreateDispTypeInfo16( + INTERFACEDATA *pidata, + LCID lcid, + ITypeInfo **pptinfo) +{ + FIXME("(%p,%ld,%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%08lx,%p):stub\n",punk,debugstr_guid(rclsid),dwFlags,pdwRegister); + return E_NOTIMPL; +} diff --git a/reactos/lib/oleaut32/ole2disp.h b/reactos/lib/oleaut32/ole2disp.h new file mode 100644 index 00000000000..2ca2d09d34d --- /dev/null +++ b/reactos/lib/oleaut32/ole2disp.h @@ -0,0 +1,42 @@ +/* + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __WINE_OLEAUT32_OLE2DISP_H +#define __WINE_OLEAUT32_OLE2DISP_H + +#include + +#include "windef.h" +#include "winbase.h" +#include "wtypes.h" +#include "wine/windef16.h" + +typedef CHAR OLECHAR16; +typedef LPSTR LPOLESTR16; +typedef LPCSTR LPCOLESTR16; +typedef OLECHAR16 *BSTR16; +typedef BSTR16 *LPBSTR16; + +BSTR16 WINAPI SysAllocString16(LPCOLESTR16); +BSTR16 WINAPI SysAllocStringLen16(const char*, int); +VOID WINAPI SysFreeString16(BSTR16); +INT16 WINAPI SysReAllocString16(LPBSTR16,LPCOLESTR16); +int WINAPI SysReAllocStringLen16(BSTR16*, const char*, int); +int WINAPI SysStringLen16(BSTR16); + +#endif /* !defined(__WINE_OLEAUT32_OLE2DISP_H) */ diff --git a/reactos/lib/oleaut32/ole2disp.spec b/reactos/lib/oleaut32/ole2disp.spec new file mode 100644 index 00000000000..74558802b09 --- /dev/null +++ b/reactos/lib/oleaut32/ole2disp.spec @@ -0,0 +1,135 @@ +1 stub DLLGETCLASSOBJECT +2 pascal SysAllocString(str) SysAllocString16 +3 pascal SysReallocString(ptr str) SysReAllocString16 +4 pascal SysAllocStringLen(str word) SysAllocStringLen16 +5 pascal SysReAllocStringLen(ptr str word) SysReAllocStringLen16 +6 pascal SysFreeString(segstr) SysFreeString16 +7 pascal SysStringLen(segstr) SysStringLen16 +8 stub VARIANTINIT +9 stub VARIANTCLEAR +10 stub VARIANTCOPY +11 stub VARIANTCOPYIND +12 stub VARIANTCHANGETYPE +13 stub VARIANTTIMETODOSDATETIME +14 stub DOSDATETIMETOVARIANTTIME +15 stub SAFEARRAYCREATE +16 stub SAFEARRAYDESTROY +17 stub SAFEARRAYGETDIM +18 stub SAFEARRAYGETELEMSIZE +19 stub SAFEARRAYGETUBOUND +20 stub SAFEARRAYGETLBOUND +21 stub SAFEARRAYLOCK +22 stub SAFEARRAYUNLOCK +23 stub SAFEARRAYACCESSDATA +24 stub SAFEARRAYUNACCESSDATA +25 stub SAFEARRAYGETELEMENT +26 stub SAFEARRAYPUTELEMENT +27 stub SAFEARRAYCOPY +28 stub DISPGETPARAM +29 stub DISPGETIDSOFNAMES +30 stub DISPINVOKE +31 pascal CreateDispTypeInfo(ptr long ptr) CreateDispTypeInfo16 +32 pascal CreateStdDispatch(ptr ptr ptr ptr) CreateStdDispatch16 +33 stub _IID_IDISPATCH +34 stub _IID_IENUMVARIANT +35 pascal RegisterActiveObject(ptr ptr long ptr) RegisterActiveObject16 +36 stub REVOKEACTIVEOBJECT +37 stub GETACTIVEOBJECT +38 stub SAFEARRAYALLOCDESCRIPTOR +39 stub SAFEARRAYALLOCDATA +40 stub SAFEARRAYDESTROYDESCRIPTOR +41 stub SAFEARRAYDESTROYDATA +42 stub SAFEARRAYREDIM +43 stub VARI2FROMI4 +44 stub VARI2FROMR4 +45 stub VARI2FROMR8 +46 stub VARI2FROMCY +47 stub VARI2FROMDATE +48 stub VARI2FROMSTR +49 stub VARI2FROMDISP +50 stub VARI2FROMBOOL +51 stub VARI4FROMI2 +52 stub VARI4FROMR4 +53 stub VARI4FROMR8 +54 stub VARI4FROMCY +55 stub VARI4FROMDATE +56 stub VARI4FROMSTR +57 stub VARI4FROMDISP +58 stub VARI4FROMBOOL +59 stub VARR4FROMI2 +60 stub VARR4FROMI4 +61 stub VARR4FROMR8 +62 stub VARR4FROMCY +63 stub VARR4FROMDATE +64 stub VARR4FROMSTR +65 stub VARR4FROMDISP +66 stub VARR4FROMBOOL +67 stub VARR8FROMI2 +68 stub VARR8FROMI4 +69 stub VARR8FROMR4 +70 stub VARR8FROMCY +71 stub VARR8FROMDATE +72 stub VARR8FROMSTR +73 stub VARR8FROMDISP +74 stub VARR8FROMBOOL +75 stub VARDATEFROMI2 +76 stub VARDATEFROMI4 +77 stub VARDATEFROMR4 +78 stub VARDATEFROMR8 +79 stub VARDATEFROMCY +80 stub VARDATEFROMSTR +81 stub VARDATEFROMDISP +82 stub VARDATEFROMBOOL +83 stub VARCYFROMI2 +84 stub VARCYFROMI4 +85 stub VARCYFROMR4 +86 stub VARCYFROMR8 +87 stub VARCYFROMDATE +88 stub VARCYFROMSTR +89 stub VARCYFROMDISP +90 stub VARCYFROMBOOL +91 stub VARBSTRFROMI2 +92 stub VARBSTRFROMI4 +93 stub VARBSTRFROMR4 +94 stub VARBSTRFROMR8 +95 stub VARBSTRFROMCY +96 stub VARBSTRFROMDATE +97 stub VARBSTRFROMDISP +98 stub VARBSTRFROMBOOL +99 stub VARBOOLFROMI2 +100 stub VARBOOLFROMI4 +101 stub VARBOOLFROMR4 +102 stub VARBOOLFROMR8 +103 stub VARBOOLFROMDATE +104 stub VARBOOLFROMCY +105 stub VARBOOLFROMSTR +106 stub VARBOOLFROMDISP +107 stub DOINVOKEMETHOD +108 stub VARIANTCHANGETYPEEX +109 stub SAFEARRAYPTROFINDEX +110 stub SETERRORINFO +111 stub GETERRORINFO +112 stub CREATEERRORINFO +113 stub _IID_IERRORINFO +114 stub _IID_ICREATEERRORINFO +115 stub _IID_ISUPPORTERRORINFO +116 stub VARUI1FROMI2 +117 stub VARUI1FROMI4 +118 stub VARUI1FROMR4 +119 stub VARUI1FROMR8 +120 stub VARUI1FROMCY +121 stub VARUI1FROMDATE +122 stub VARUI1FROMSTR +123 stub VARUI1FROMDISP +124 stub VARUI1FROMBOOL +125 stub VARI2FROMUI1 +126 stub VARI4FROMUI1 +127 stub VARR4FROMUI1 +128 stub VARR8FROMUI1 +129 stub VARDATEFROMUI1 +130 stub VARCYFROMUI1 +131 stub VARBSTRFROMUI1 +132 stub VARBOOLFROMUI1 +133 stub DLLCANUNLOADNOW +#134 stub WEP +#135 stub ___EXPORTEDSTUB diff --git a/reactos/lib/oleaut32/oleaut.c b/reactos/lib/oleaut32/oleaut.c new file mode 100644 index 00000000000..374eddf35e5 --- /dev/null +++ b/reactos/lib/oleaut32/oleaut.c @@ -0,0 +1,755 @@ +/* + * OLEAUT32 + * + * Copyright 1999, 2000 Marcus Meissner + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" +#include "winerror.h" + +#include "ole2.h" +#include "olectl.h" +#include "oleauto.h" + +#include "tmarshal.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(ole); + +/* The OLE Automation ProxyStub Interface Class (aka Typelib Marshaler) */ +extern const GUID CLSID_PSOAInterface; + +/* IDispatch marshaler */ +extern const GUID CLSID_PSDispatch; + +static BOOL BSTR_bCache = TRUE; /* Cache allocations to minimise alloc calls? */ + +HMODULE OLEAUT32_hModule = NULL; + +/****************************************************************************** + * BSTR {OLEAUT32} + * + * NOTES + * BSTR is a simple typedef for a wide-character string used as the principle + * string type in ole automation. When encapsulated in a Variant type they are + * automatically copied and destroyed as the variant is processed. + * + * The low level BSTR Api allows manipulation of these strings and is used by + * higher level Api calls to manage the strings transparently to the caller. + * + * Internally the BSTR type is allocated with space for a DWORD byte count before + * the string data begins. This is undocumented and non-system code should not + * access the count directly. Use SysStringLen() or SysStringByteLen() + * instead. Note that the byte count does not include the terminating NUL. + * + * To create a new BSTR, use SysAllocString(), SysAllocStringLen() or + * SysAllocStringByteLen(). To change the size of an existing BSTR, use SysReAllocString() + * or SysReAllocStringLen(). Finally to destroy a string use SysFreeString(). + * + * BSTR's are cached by Ole Automation by default. To override this behaviour + * either set the environment variable 'OANOCACHE', or call SetOaNoCache(). + * + * SEE ALSO + * 'Inside OLE, second edition' by Kraig Brockshmidt. + */ + +/****************************************************************************** + * SysStringLen [OLEAUT32.7] + * + * Get the allocated length of a BSTR in wide characters. + * + * PARAMS + * str [I] BSTR to find the length of + * + * RETURNS + * The allocated length of str, or 0 if str is NULL. + * + * NOTES + * See BSTR. + * The returned length may be different from the length of the string as + * calculated by lstrlenW(), since it returns the length that was used to + * allocate the string by SysAllocStringLen(). + */ +UINT WINAPI SysStringLen(BSTR str) +{ + DWORD* bufferPointer; + + if (!str) return 0; + /* + * The length of the string (in bytes) is contained in a DWORD placed + * just before the BSTR pointer + */ + bufferPointer = (DWORD*)str; + + bufferPointer--; + + return (int)(*bufferPointer/sizeof(WCHAR)); +} + +/****************************************************************************** + * SysStringByteLen [OLEAUT32.149] + * + * Get the allocated length of a BSTR in bytes. + * + * PARAMS + * str [I] BSTR to find the length of + * + * RETURNS + * The allocated length of str, or 0 if str is NULL. + * + * NOTES + * See SysStringLen(), BSTR(). + */ +UINT WINAPI SysStringByteLen(BSTR str) +{ + DWORD* bufferPointer; + + if (!str) return 0; + /* + * The length of the string (in bytes) is contained in a DWORD placed + * just before the BSTR pointer + */ + bufferPointer = (DWORD*)str; + + bufferPointer--; + + return (int)(*bufferPointer); +} + +/****************************************************************************** + * SysAllocString [OLEAUT32.2] + * + * Create a BSTR from an OLESTR. + * + * PARAMS + * str [I] Source to create BSTR from + * + * RETURNS + * Success: A BSTR allocated with SysAllocStringLen(). + * Failure: NULL, if oleStr is NULL. + * + * NOTES + * See BSTR. + * MSDN (October 2001) incorrectly states that NULL is returned if oleStr has + * a length of 0. Native Win32 and this implementation both return a valid + * empty BSTR in this case. + */ +BSTR WINAPI SysAllocString(LPCOLESTR str) +{ + if (!str) return 0; + + /* Delegate this to the SysAllocStringLen32 method. */ + return SysAllocStringLen(str, lstrlenW(str)); +} + +/****************************************************************************** + * SysFreeString [OLEAUT32.6] + * + * Free a BSTR. + * + * PARAMS + * str [I] BSTR to free. + * + * RETURNS + * Nothing. + * + * NOTES + * See BSTR. + * str may be NULL, in which case this function does nothing. + */ +void WINAPI SysFreeString(BSTR str) +{ + DWORD* bufferPointer; + + /* NULL is a valid parameter */ + if(!str) return; + + /* + * We have to be careful when we free a BSTR pointer, it points to + * the beginning of the string but it skips the byte count contained + * before the string. + */ + bufferPointer = (DWORD*)str; + + bufferPointer--; + + /* + * Free the memory from its "real" origin. + */ + HeapFree(GetProcessHeap(), 0, bufferPointer); +} + +/****************************************************************************** + * SysAllocStringLen [OLEAUT32.4] + * + * Create a BSTR from an OLESTR of a given wide character length. + * + * PARAMS + * str [I] Source to create BSTR from + * len [I] Length of oleStr in wide characters + * + * RETURNS + * Success: A newly allocated BSTR from SysAllocStringByteLen() + * Failure: NULL, if len is >= 0x80000000, or memory allocation fails. + * + * NOTES + * See BSTR(), SysAllocStringByteLen(). + */ +BSTR WINAPI SysAllocStringLen(const OLECHAR *str, unsigned int len) +{ + DWORD bufferSize; + DWORD* newBuffer; + WCHAR* stringBuffer; + + /* + * Find the length of the buffer passed-in in bytes. + */ + bufferSize = len * sizeof (WCHAR); + + /* + * Allocate a new buffer to hold the string. + * don't forget to keep an empty spot at the beginning of the + * buffer for the character count and an extra character at the + * end for the NULL. + */ + newBuffer = (DWORD*)HeapAlloc(GetProcessHeap(), + 0, + bufferSize + sizeof(WCHAR) + sizeof(DWORD)); + + /* + * If the memory allocation failed, return a null pointer. + */ + if (newBuffer==0) + return 0; + + /* + * Copy the length of the string in the placeholder. + */ + *newBuffer = bufferSize; + + /* + * Skip the byte count. + */ + newBuffer++; + + /* + * 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 (str != 0) + memcpy(newBuffer, str, bufferSize); + else + memset(newBuffer, 0, bufferSize); + + /* + * Make sure that there is a nul character at the end of the + * string. + */ + stringBuffer = (WCHAR*)newBuffer; + stringBuffer[len] = L'\0'; + + return (LPWSTR)stringBuffer; +} + +/****************************************************************************** + * SysReAllocStringLen [OLEAUT32.5] + * + * Change the length of a previously created BSTR. + * + * PARAMS + * old [O] BSTR to change the length of + * str [I] New source for pbstr + * len [I] Length of oleStr in wide characters + * + * RETURNS + * Success: 1. The size of pbstr is updated. + * Failure: 0, if len >= 0x80000000 or memory allocation fails. + * + * NOTES + * See BSTR(), SysAllocStringByteLen(). + * *pbstr may be changed by this function. + */ +int WINAPI SysReAllocStringLen(BSTR* old, const OLECHAR* str, unsigned int len) +{ + if (*old!=NULL) { + DWORD newbytelen = len*sizeof(WCHAR); + DWORD *ptr = HeapReAlloc(GetProcessHeap(),0,((DWORD*)*old)-1,newbytelen+sizeof(WCHAR)+sizeof(DWORD)); + *old = (BSTR)(ptr+1); + *ptr = newbytelen; + if (str) { + memcpy(*old, str, newbytelen); + (*old)[len] = 0; + } else { + /* Subtle hidden feature: The old string data is still there + * when 'in' is NULL! + * Some Microsoft program needs it. + */ + } + } else { + /* + * Allocate the new string + */ + *old = SysAllocStringLen(str, len); + } + + return 1; +} + +/****************************************************************************** + * SysAllocStringByteLen [OLEAUT32.150] + * + * Create a BSTR from an OLESTR of a given byte length. + * + * PARAMS + * str [I] Source to create BSTR from + * len [I] Length of oleStr in bytes + * + * RETURNS + * Success: A newly allocated BSTR + * Failure: NULL, if len is >= 0x80000000, or memory allocation fails. + * + * NOTES + * -If len is 0 or oleStr is NULL the resulting string is empty (""). + * -This function always NUL terminates the resulting BSTR. + * -oleStr may be either an LPCSTR or LPCOLESTR, since it is copied + * without checking for a terminating NUL. + * See BSTR. + */ +BSTR WINAPI SysAllocStringByteLen(LPCSTR str, UINT len) +{ + DWORD* newBuffer; + char* stringBuffer; + + /* + * Allocate a new buffer to hold the string. + * don't forget to keep an empty spot at the beginning of the + * buffer for the character count and an extra character at the + * end for the NULL. + */ + newBuffer = (DWORD*)HeapAlloc(GetProcessHeap(), + 0, + len + sizeof(WCHAR) + sizeof(DWORD)); + + /* + * If the memory allocation failed, return a null pointer. + */ + if (newBuffer==0) + return 0; + + /* + * Copy the length of the string in the placeholder. + */ + *newBuffer = len; + + /* + * Skip the byte count. + */ + newBuffer++; + + /* + * 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 (str != 0) + memcpy(newBuffer, str, len); + + /* + * Make sure that there is a nul character at the end of the + * string. + */ + stringBuffer = (char *)newBuffer; + stringBuffer[len] = 0; + stringBuffer[len+1] = 0; + + return (LPWSTR)stringBuffer; +} + +/****************************************************************************** + * SysReAllocString [OLEAUT32.3] + * + * Change the length of a previously created BSTR. + * + * PARAMS + * old [I/O] BSTR to change the length of + * str [I] New source for pbstr + * + * RETURNS + * Success: 1 + * Failure: 0. + * + * NOTES + * See BSTR(), SysAllocStringStringLen(). + */ +INT WINAPI SysReAllocString(LPBSTR old,LPCOLESTR str) +{ + /* + * Sanity check + */ + if (old==NULL) + return 0; + + /* + * Make sure we free the old string. + */ + if (*old!=NULL) + SysFreeString(*old); + + /* + * Allocate the new string + */ + *old = SysAllocString(str); + + return 1; +} + +/****************************************************************************** + * SetOaNoCache (OLEAUT32.327) + * + * Instruct Ole Automation not to cache BSTR allocations. + * + * PARAMS + * None. + * + * RETURNS + * Nothing. + * + * NOTES + * See BSTR. + */ +void WINAPI SetOaNoCache(void) +{ + BSTR_bCache = FALSE; +} + +static WCHAR _delimiter[2] = {'!',0}; /* default delimiter apparently */ +static WCHAR *pdelimiter = &_delimiter[0]; + +/*********************************************************************** + * RegisterActiveObject (OLEAUT32.33) + */ +HRESULT WINAPI RegisterActiveObject( + LPUNKNOWN punk,REFCLSID rcid,DWORD dwFlags,LPDWORD pdwRegister +) { + WCHAR guidbuf[80]; + HRESULT ret; + LPRUNNINGOBJECTTABLE runobtable; + LPMONIKER moniker; + + StringFromGUID2(rcid,guidbuf,39); + ret = CreateItemMoniker(pdelimiter,guidbuf,&moniker); + if (FAILED(ret)) + return ret; + ret = GetRunningObjectTable(0,&runobtable); + if (FAILED(ret)) { + IMoniker_Release(moniker); + return ret; + } + ret = IRunningObjectTable_Register(runobtable,dwFlags,punk,moniker,pdwRegister); + IRunningObjectTable_Release(runobtable); + IMoniker_Release(moniker); + return ret; +} + +/*********************************************************************** + * RevokeActiveObject (OLEAUT32.34) + */ +HRESULT WINAPI RevokeActiveObject(DWORD xregister,LPVOID reserved) +{ + LPRUNNINGOBJECTTABLE runobtable; + HRESULT ret; + + ret = GetRunningObjectTable(0,&runobtable); + if (FAILED(ret)) return ret; + ret = IRunningObjectTable_Revoke(runobtable,xregister); + if (SUCCEEDED(ret)) ret = S_OK; + IRunningObjectTable_Release(runobtable); + return ret; +} + +/*********************************************************************** + * GetActiveObject (OLEAUT32.35) + */ +HRESULT WINAPI GetActiveObject(REFCLSID rcid,LPVOID preserved,LPUNKNOWN *ppunk) +{ + WCHAR guidbuf[80]; + HRESULT ret; + LPRUNNINGOBJECTTABLE runobtable; + LPMONIKER moniker; + + StringFromGUID2(rcid,guidbuf,39); + ret = CreateItemMoniker(pdelimiter,guidbuf,&moniker); + if (FAILED(ret)) + return ret; + ret = GetRunningObjectTable(0,&runobtable); + if (FAILED(ret)) { + IMoniker_Release(moniker); + return ret; + } + ret = IRunningObjectTable_GetObject(runobtable,moniker,ppunk); + IRunningObjectTable_Release(runobtable); + IMoniker_Release(moniker); + return ret; +} + + +/*********************************************************************** + * OaBuildVersion [OLEAUT32.170] + * + * Get the Ole Automation build version. + * + * PARAMS + * None + * + * RETURNS + * The build version. + * + * NOTES + * Known oleaut32.dll versions: + *| OLE Ver. Comments Date Build Ver. + *| -------- ------------------------- ---- --------- + *| OLE 2.1 NT 1993-95 10 3023 + *| OLE 2.1 10 3027 + *| Win32s Ver 1.1e 20 4049 + *| OLE 2.20 W95/NT 1993-96 20 4112 + *| OLE 2.20 W95/NT 1993-96 20 4118 + *| OLE 2.20 W95/NT 1993-96 20 4122 + *| OLE 2.30 W95/NT 1993-98 30 4265 + *| OLE 2.40 NT?? 1993-98 40 4267 + *| OLE 2.40 W98 SE orig. file 1993-98 40 4275 + *| OLE 2.40 W2K orig. file 1993-XX 40 4514 + * + * Currently the versions returned are 2.20 for Win3.1, 2.30 for Win95 & NT 3.51, + * and 2.40 for all later versions. The build number is maximum, i.e. 0xffff. + */ +ULONG WINAPI OaBuildVersion() +{ + switch(GetVersion() & 0x8000ffff) /* mask off build number */ + { + case 0x80000a03: /* WIN31 */ + return MAKELONG(0xffff, 20); + case 0x00003303: /* NT351 */ + return MAKELONG(0xffff, 30); + case 0x80000004: /* WIN95; I'd like to use the "standard" w95 minor + version here (30), but as we still use w95 + as default winver (which is good IMHO), I better + play safe and use the latest value for w95 for now. + Change this as soon as default winver gets changed + to something more recent */ + case 0x80000a04: /* WIN98 */ + case 0x00000004: /* NT40 */ + case 0x00000005: /* W2K */ + return MAKELONG(0xffff, 40); + default: + ERR("Version value not known yet. Please investigate it !\n"); + return 0x0; + } +} + +/****************************************************************************** + * GetRecordInfoFromGuids [OLEAUT32.322] + * + * RETURNS + * Success: S_OK + * Failure: E_INVALIDARG, if any argument is invalid. + * + * BUGS + * Unimplemented + */ +HRESULT WINAPI GetRecordInfoFromGuids( + REFGUID rGuidTypeLib, + ULONG uVerMajor, + ULONG uVerMinor, + LCID lcid, + REFGUID rGuidTypeInfo, + IRecordInfo** ppRecInfo) +{ + FIXME("(%p,%ld,%ld,%ld,%p,%p),stub!\n",rGuidTypeLib, uVerMajor, uVerMinor, lcid, rGuidTypeInfo, ppRecInfo); + return E_NOTIMPL; +} + +/****************************************************************************** + * OleTranslateColor [OLEAUT32.421] + * + * Convert an OLE_COLOR to a COLORREF. + * + * PARAMS + * clr [I] Color to convert + * hpal [I] Handle to a palette for the conversion + * pColorRef [O] Destination for converted color, or NULL to test if the conversion is ok + * + * RETURNS + * Success: S_OK. The conversion is ok, and pColorRef contains the converted color if non-NULL. + * Failure: E_INVALIDARG, if any argument is invalid. + * + * FIXME + * Document the conversion rules. + */ +HRESULT WINAPI OleTranslateColor( + OLE_COLOR clr, + HPALETTE hpal, + COLORREF* pColorRef) +{ + COLORREF colorref; + BYTE b = HIBYTE(HIWORD(clr)); + + TRACE("(%08lx, %p, %p):stub\n", clr, hpal, pColorRef); + + /* + * In case pColorRef is NULL, provide our own to simplify the code. + */ + if (pColorRef == NULL) + pColorRef = &colorref; + + switch (b) + { + case 0x00: + { + if (hpal != 0) + *pColorRef = PALETTERGB(GetRValue(clr), + GetGValue(clr), + GetBValue(clr)); + else + *pColorRef = clr; + + break; + } + + case 0x01: + { + if (hpal != 0) + { + PALETTEENTRY pe; + /* + * Validate the palette index. + */ + if (GetPaletteEntries(hpal, LOWORD(clr), 1, &pe) == 0) + return E_INVALIDARG; + } + + *pColorRef = clr; + + break; + } + + case 0x02: + *pColorRef = clr; + break; + + case 0x80: + { + int index = LOBYTE(LOWORD(clr)); + + /* + * Validate GetSysColor index. + */ + if ((index < COLOR_SCROLLBAR) || (index > COLOR_MENUBAR)) + return E_INVALIDARG; + + *pColorRef = GetSysColor(index); + + break; + } + + default: + return E_INVALIDARG; + } + + return S_OK; +} + +extern HRESULT OLEAUTPS_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv); + +extern void _get_STDFONT_CF(LPVOID); +extern void _get_STDPIC_CF(LPVOID); + +/*********************************************************************** + * DllGetClassObject (OLEAUT32.1) + */ +HRESULT WINAPI OLEAUT32_DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv) +{ + *ppv = NULL; + if (IsEqualGUID(rclsid,&CLSID_StdFont)) { + if (IsEqualGUID(iid,&IID_IClassFactory)) { + _get_STDFONT_CF(ppv); + IClassFactory_AddRef((IClassFactory*)*ppv); + return S_OK; + } + } + if (IsEqualGUID(rclsid,&CLSID_StdPicture)) { + if (IsEqualGUID(iid,&IID_IClassFactory)) { + _get_STDPIC_CF(ppv); + IClassFactory_AddRef((IClassFactory*)*ppv); + return S_OK; + } + } + if (IsEqualGUID(rclsid,&CLSID_PSDispatch)) { + return OLEAUTPS_DllGetClassObject(rclsid,iid,ppv); + } + if (IsEqualGUID(rclsid,&CLSID_PSOAInterface)) { + if (S_OK==TypeLibFac_DllGetClassObject(rclsid,iid,ppv)) + return S_OK; + /*FALLTHROUGH*/ + } + FIXME("\n\tCLSID:\t%s,\n\tIID:\t%s\n",debugstr_guid(rclsid),debugstr_guid(iid)); + return CLASS_E_CLASSNOTAVAILABLE; +} + +/*********************************************************************** + * DllCanUnloadNow (OLEAUT32.410) + * + * Determine if this dll can be unloaded from the callers address space. + * + * PARAMS + * None. + * + * RETURNS + * Always returns S_FALSE. This dll cannot be unloaded. + */ +HRESULT WINAPI OLEAUT32_DllCanUnloadNow(void) +{ + return S_FALSE; +} + +/***************************************************************************** + * DllMain [OLEAUT32.@] + */ +BOOL WINAPI DllMain(HINSTANCE hInstDll, DWORD fdwReason, LPVOID lpvReserved) +{ + TRACE("(%p,%lu,%p)\n", hInstDll, fdwReason, lpvReserved); + + switch (fdwReason) { + case DLL_PROCESS_ATTACH: + DisableThreadLibraryCalls(hInstDll); + OLEAUT32_hModule = (HMODULE)hInstDll; + break; + case DLL_PROCESS_DETACH: + break; + }; + + return TRUE; +} diff --git a/reactos/lib/oleaut32/oleaut32.rc b/reactos/lib/oleaut32/oleaut32.rc new file mode 100644 index 00000000000..2825a4885d1 --- /dev/null +++ b/reactos/lib/oleaut32/oleaut32.rc @@ -0,0 +1,47 @@ +/* + * Top level resource file for oleaut32 + * + * Copyright 2003 Jon Griffiths + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "windef.h" +#include "winbase.h" +#include "resource.h" + +#include "version.rc" + +#include "oleaut32_De.rc" +#include "oleaut32_Dk.rc" +#include "oleaut32_En.rc" +#include "oleaut32_Es.rc" +#include "oleaut32_Cz.rc" +#include "oleaut32_Fr.rc" +#include "oleaut32_Hu.rc" +#include "oleaut32_It.rc" +#include "oleaut32_Nl.rc" +#include "oleaut32_No.rc" +#include "oleaut32_Pl.rc" +#include "oleaut32_Pt.rc" +#include "oleaut32_Sv.rc" +#include "oleaut32_Th.rc" + +/* + * FIXME: + * Finnish, Greek, Hebrew, Japanese, Korean, Portuguese, + * Russian, Turkish, Slovenian (at least) are localised in XP Home. + * I expect Chinese etc are localised in Asian Editions also. + */ diff --git a/reactos/lib/oleaut32/oleaut32.spec b/reactos/lib/oleaut32/oleaut32.spec new file mode 100644 index 00000000000..ab04bf25f88 --- /dev/null +++ b/reactos/lib/oleaut32/oleaut32.spec @@ -0,0 +1,416 @@ +1 stdcall -private DllGetClassObject(ptr ptr ptr) OLEAUT32_DllGetClassObject +2 stdcall SysAllocString(wstr) +3 stdcall SysReAllocString(ptr wstr) +4 stdcall SysAllocStringLen(wstr long) +5 stdcall SysReAllocStringLen(ptr ptr long) +6 stdcall SysFreeString(wstr) +7 stdcall SysStringLen(wstr) +8 stdcall VariantInit(ptr) +9 stdcall VariantClear(ptr) +10 stdcall VariantCopy(ptr ptr) +11 stdcall VariantCopyInd(ptr ptr) +12 stdcall VariantChangeType(ptr ptr long long) +13 stdcall VariantTimeToDosDateTime(double ptr ptr) +14 stdcall DosDateTimeToVariantTime(long long ptr) +15 stdcall SafeArrayCreate(long long ptr) +16 stdcall SafeArrayDestroy(ptr) +17 stdcall SafeArrayGetDim(ptr) +18 stdcall SafeArrayGetElemsize(ptr) +19 stdcall SafeArrayGetUBound(ptr long long) +20 stdcall SafeArrayGetLBound(ptr long long) +21 stdcall SafeArrayLock(ptr) +22 stdcall SafeArrayUnlock(ptr) +23 stdcall SafeArrayAccessData(ptr ptr) +24 stdcall SafeArrayUnaccessData(ptr) +25 stdcall SafeArrayGetElement(ptr ptr ptr) +26 stdcall SafeArrayPutElement(ptr ptr ptr) +27 stdcall SafeArrayCopy(ptr ptr) +28 stdcall DispGetParam(ptr long long ptr ptr) +29 stdcall DispGetIDsOfNames(ptr ptr long ptr) +30 stdcall DispInvoke(ptr ptr long long ptr ptr ptr ptr) +31 stdcall CreateDispTypeInfo(ptr long ptr) +32 stdcall CreateStdDispatch(ptr ptr ptr ptr) +33 stdcall RegisterActiveObject(ptr ptr long ptr) +34 stdcall RevokeActiveObject(long ptr) +35 stdcall GetActiveObject(ptr ptr ptr) +36 stdcall SafeArrayAllocDescriptor(long ptr) +37 stdcall SafeArrayAllocData(ptr) +38 stdcall SafeArrayDestroyDescriptor(ptr) +39 stdcall SafeArrayDestroyData(ptr) +40 stdcall SafeArrayRedim(ptr ptr) +41 stdcall SafeArrayAllocDescriptorEx(long long ptr) +42 stdcall SafeArrayCreateEx(long long ptr ptr) +43 stdcall SafeArrayCreateVectorEx(long long long ptr) +44 stdcall SafeArraySetRecordInfo(ptr ptr) +45 stdcall SafeArrayGetRecordInfo(ptr ptr) +46 stdcall VarParseNumFromStr(wstr long long ptr ptr) +47 stdcall VarNumFromParseNum(ptr ptr long ptr) +48 stdcall VarI2FromUI1(long ptr) +49 stdcall VarI2FromI4(long ptr) +50 stdcall VarI2FromR4(long ptr) +51 stdcall VarI2FromR8(double ptr) +52 stdcall VarI2FromCy(long long ptr) +53 stdcall VarI2FromDate(double ptr) +54 stdcall VarI2FromStr(wstr long long ptr) +55 stdcall VarI2FromDisp(ptr long ptr) +56 stdcall VarI2FromBool(long ptr) +57 stdcall SafeArraySetIID(ptr ptr) +58 stdcall VarI4FromUI1(long ptr) +59 stdcall VarI4FromI2(long ptr) +60 stdcall VarI4FromR4(long ptr) +61 stdcall VarI4FromR8(double ptr) +62 stdcall VarI4FromCy(long long ptr) +63 stdcall VarI4FromDate(double ptr) +64 stdcall VarI4FromStr(wstr long long ptr) +65 stdcall VarI4FromDisp(ptr long ptr) +66 stdcall VarI4FromBool(long ptr) +67 stdcall SafeArrayGetIID(ptr ptr) +68 stdcall VarR4FromUI1(long ptr) +69 stdcall VarR4FromI2(long ptr) +70 stdcall VarR4FromI4(long ptr) +71 stdcall VarR4FromR8(double ptr) +72 stdcall VarR4FromCy(long long ptr) +73 stdcall VarR4FromDate(double ptr) +74 stdcall VarR4FromStr(wstr long long ptr) +75 stdcall VarR4FromDisp(ptr long ptr) +76 stdcall VarR4FromBool(long ptr) +77 stdcall SafeArrayGetVartype(ptr ptr) +78 stdcall VarR8FromUI1(long ptr) +79 stdcall VarR8FromI2(long ptr) +80 stdcall VarR8FromI4(long ptr) +81 stdcall VarR8FromR4(long ptr) +82 stdcall VarR8FromCy(long long ptr) +83 stdcall VarR8FromDate(double ptr) +84 stdcall VarR8FromStr(wstr long long ptr) +85 stdcall VarR8FromDisp(ptr long ptr) +86 stdcall VarR8FromBool(long ptr) +87 stdcall VarFormat(ptr ptr long long long ptr) +88 stdcall VarDateFromUI1(long ptr) +89 stdcall VarDateFromI2(long ptr) +90 stdcall VarDateFromI4(long ptr) +91 stdcall VarDateFromR4(long ptr) +92 stdcall VarDateFromR8(double ptr) +93 stdcall VarDateFromCy(long long ptr) +94 stdcall VarDateFromStr(wstr long long ptr) +95 stdcall VarDateFromDisp(ptr long ptr) +96 stdcall VarDateFromBool(long ptr) +97 stdcall VarFormatDateTime(ptr long long ptr) +98 stdcall VarCyFromUI1(long ptr) +99 stdcall VarCyFromI2(long ptr) +100 stdcall VarCyFromI4(long ptr) +101 stdcall VarCyFromR4(long ptr) +102 stdcall VarCyFromR8(double ptr) +103 stdcall VarCyFromDate(double ptr) +104 stdcall VarCyFromStr(wstr long long ptr) +105 stdcall VarCyFromDisp(ptr long ptr) +106 stdcall VarCyFromBool(long ptr) +107 stdcall VarFormatNumber(ptr long long long long long ptr) +108 stdcall VarBstrFromUI1(long long long ptr) +109 stdcall VarBstrFromI2(long long long ptr) +110 stdcall VarBstrFromI4(long long long ptr) +111 stdcall VarBstrFromR4(long long long ptr) +112 stdcall VarBstrFromR8(double long long ptr) +113 stdcall VarBstrFromCy(long long long long ptr) +114 stdcall VarBstrFromDate(double long long ptr) +115 stub VarBstrFromDisp +116 stdcall VarBstrFromBool(long long long ptr) +117 stdcall VarFormatPercent(ptr long long long long long ptr) +118 stdcall VarBoolFromUI1(long ptr) +119 stdcall VarBoolFromI2(long ptr) +120 stdcall VarBoolFromI4(long ptr) +121 stdcall VarBoolFromR4(long ptr) +122 stdcall VarBoolFromR8(double ptr) +123 stdcall VarBoolFromDate(double ptr) +124 stdcall VarBoolFromCy(long long ptr) +125 stdcall VarBoolFromStr(wstr long long ptr) +126 stdcall VarBoolFromDisp(ptr long ptr) +127 stdcall VarFormatCurrency(ptr long long long long long ptr) +128 stub VarWeekdayName # stdcall (long long long long ptr) +129 stub VarMonthName # stdcall (long long long ptr) +130 stdcall VarUI1FromI2(long ptr) +131 stdcall VarUI1FromI4(long ptr) +132 stdcall VarUI1FromR4(long ptr) +133 stdcall VarUI1FromR8(double ptr) +134 stdcall VarUI1FromCy(long long ptr) +135 stdcall VarUI1FromDate(double ptr) +136 stdcall VarUI1FromStr(wstr long long ptr) +137 stdcall VarUI1FromDisp(ptr long ptr) +138 stdcall VarUI1FromBool(long ptr) +139 stdcall VarFormatFromTokens (ptr ptr ptr long ptr long) +140 stdcall VarTokenizeFormatString (ptr ptr long long long long ptr) +141 stdcall VarAdd(ptr ptr ptr) +142 stdcall VarAnd(ptr ptr ptr) +143 stdcall VarDiv(ptr ptr ptr) +144 stub OACreateTypeLib2 +146 stdcall DispCallFunc(ptr long long long long ptr ptr ptr) +147 stdcall VariantChangeTypeEx(ptr ptr long long long) +148 stdcall SafeArrayPtrOfIndex(ptr ptr ptr) +149 stdcall SysStringByteLen(ptr) +150 stdcall SysAllocStringByteLen(ptr long) +152 stdcall VarEqv(ptr ptr ptr) +153 stub VarIdiv # stdcall (ptr ptr ptr) +154 stub VarImp # stdcall (ptr ptr ptr) +155 stdcall VarMod(ptr ptr ptr) +156 stdcall VarMul(ptr ptr ptr) +157 stdcall VarOr(ptr ptr ptr) +158 stdcall VarPow(ptr ptr ptr) +159 stdcall VarSub(ptr ptr ptr) +160 stdcall CreateTypeLib(long wstr ptr) +161 stdcall LoadTypeLib (wstr ptr) +162 stdcall LoadRegTypeLib (ptr long long long ptr) +163 stdcall RegisterTypeLib(ptr wstr wstr) +164 stdcall QueryPathOfRegTypeLib(ptr long long long ptr) +165 stdcall LHashValOfNameSys(long long wstr) +166 stdcall LHashValOfNameSysA(long long str) +167 stdcall VarXor(ptr ptr ptr) +168 stdcall VarAbs(ptr ptr) +169 stdcall VarFix(ptr ptr) +170 stdcall OaBuildVersion() +171 stdcall ClearCustData(ptr) +172 stdcall VarInt(ptr ptr) +173 stdcall VarNeg(ptr ptr) +174 stdcall VarNot(ptr ptr) +175 stdcall VarRound(ptr long ptr) +176 stdcall VarCmp(ptr ptr long long) +177 stdcall VarDecAdd(ptr ptr ptr) +178 stdcall VarDecDiv(ptr ptr ptr) +179 stdcall VarDecMul(ptr ptr ptr) +180 stdcall CreateTypeLib2(long wstr ptr) +181 stdcall VarDecSub(ptr ptr ptr) +182 stdcall VarDecAbs(ptr ptr) +183 stdcall LoadTypeLibEx (wstr long ptr) +184 stdcall SystemTimeToVariantTime(ptr ptr) +185 stdcall VariantTimeToSystemTime(double ptr) +186 stdcall UnRegisterTypeLib (ptr long long long long) +187 stdcall VarDecFix(ptr ptr) +188 stdcall VarDecInt(ptr ptr) +189 stdcall VarDecNeg(ptr ptr) +190 stdcall VarDecFromUI1(long ptr) +191 stdcall VarDecFromI2(long ptr) +192 stdcall VarDecFromI4(long ptr) +193 stdcall VarDecFromR4(long ptr) +194 stdcall VarDecFromR8(double ptr) +195 stdcall VarDecFromDate(double ptr) +196 stdcall VarDecFromCy(long long ptr) +197 stdcall VarDecFromStr(wstr long long ptr) +198 stdcall VarDecFromDisp(ptr long ptr) +199 stdcall VarDecFromBool(long ptr) +200 stdcall GetErrorInfo(long ptr) ole32.GetErrorInfo +201 stdcall SetErrorInfo(long ptr) ole32.SetErrorInfo +202 stdcall CreateErrorInfo(ptr) ole32.CreateErrorInfo +203 stdcall VarDecRound(ptr long ptr) +204 stdcall VarDecCmp(ptr ptr) +205 stdcall VarI2FromI1(long ptr) +206 stdcall VarI2FromUI2(long ptr) +207 stdcall VarI2FromUI4(long ptr) +208 stdcall VarI2FromDec(ptr ptr) +209 stdcall VarI4FromI1(long ptr) +210 stdcall VarI4FromUI2(long ptr) +211 stdcall VarI4FromUI4(long ptr) +212 stdcall VarI4FromDec(ptr ptr) +213 stdcall VarR4FromI1(long ptr) +214 stdcall VarR4FromUI2(long ptr) +215 stdcall VarR4FromUI4(long ptr) +216 stdcall VarR4FromDec(ptr ptr) +217 stdcall VarR8FromI1(long ptr) +218 stdcall VarR8FromUI2(long ptr) +219 stdcall VarR8FromUI4(long ptr) +220 stdcall VarR8FromDec(ptr ptr) +221 stdcall VarDateFromI1(long ptr) +222 stdcall VarDateFromUI2(long ptr) +223 stdcall VarDateFromUI4(long ptr) +224 stdcall VarDateFromDec(ptr ptr) +225 stdcall VarCyFromI1(long ptr) +226 stdcall VarCyFromUI2(long ptr) +227 stdcall VarCyFromUI4(long ptr) +228 stdcall VarCyFromDec(ptr ptr) +229 stdcall VarBstrFromI1(long long long ptr) +230 stdcall VarBstrFromUI2(long long long ptr) +231 stdcall VarBstrFromUI4(long long long ptr) +232 stdcall VarBstrFromDec(ptr long long ptr) +233 stdcall VarBoolFromI1(long ptr) +234 stdcall VarBoolFromUI2(long ptr) +235 stdcall VarBoolFromUI4(long ptr) +236 stdcall VarBoolFromDec(ptr ptr) +237 stdcall VarUI1FromI1(long ptr) +238 stdcall VarUI1FromUI2(long ptr) +239 stdcall VarUI1FromUI4(long ptr) +240 stdcall VarUI1FromDec(ptr ptr) +241 stdcall VarDecFromI1(long ptr) +242 stdcall VarDecFromUI2(long ptr) +243 stdcall VarDecFromUI4(long ptr) +244 stdcall VarI1FromUI1(long ptr) +245 stdcall VarI1FromI2(long ptr) +246 stdcall VarI1FromI4(long ptr) +247 stdcall VarI1FromR4(long ptr) +248 stdcall VarI1FromR8(double ptr) +249 stdcall VarI1FromDate(double ptr) +250 stdcall VarI1FromCy(long long ptr) +251 stdcall VarI1FromStr(wstr long long ptr) +252 stdcall VarI1FromDisp(ptr long ptr) +253 stdcall VarI1FromBool(long ptr) +254 stdcall VarI1FromUI2(long ptr) +255 stdcall VarI1FromUI4(long ptr) +256 stdcall VarI1FromDec(ptr ptr) +257 stdcall VarUI2FromUI1(long ptr) +258 stdcall VarUI2FromI2(long ptr) +259 stdcall VarUI2FromI4(long ptr) +260 stdcall VarUI2FromR4(long ptr) +261 stdcall VarUI2FromR8(double ptr) +262 stdcall VarUI2FromDate(double ptr) +263 stdcall VarUI2FromCy(long long ptr) +264 stdcall VarUI2FromStr(wstr long long ptr) +265 stdcall VarUI2FromDisp(ptr long ptr) +266 stdcall VarUI2FromBool(long ptr) +267 stdcall VarUI2FromI1(long ptr) +268 stdcall VarUI2FromUI4(long ptr) +269 stdcall VarUI2FromDec(ptr ptr) +270 stdcall VarUI4FromUI1(long ptr) +271 stdcall VarUI4FromI2(long ptr) +272 stdcall VarUI4FromI4(long ptr) +273 stdcall VarUI4FromR4(long ptr) +274 stdcall VarUI4FromR8(double ptr) +275 stdcall VarUI4FromDate(double ptr) +276 stdcall VarUI4FromCy(long long ptr) +277 stdcall VarUI4FromStr(wstr long long ptr) +278 stdcall VarUI4FromDisp(ptr long ptr) +279 stdcall VarUI4FromBool(long ptr) +280 stdcall VarUI4FromI1(long ptr) +281 stdcall VarUI4FromUI2(long ptr) +282 stdcall VarUI4FromDec(ptr ptr) +283 stdcall BSTR_UserSize(ptr long ptr) +284 stdcall BSTR_UserMarshal(ptr ptr ptr) +285 stdcall BSTR_UserUnmarshal(ptr ptr ptr) +286 stdcall BSTR_UserFree(ptr ptr) +287 stdcall VARIANT_UserSize(ptr long ptr) +288 stdcall VARIANT_UserMarshal(ptr ptr ptr) +289 stdcall VARIANT_UserUnmarshal(ptr ptr ptr) +290 stdcall VARIANT_UserFree(ptr ptr) +291 stub LPSAFEARRAY_UserSize +292 stub LPSAFEARRAY_UserMarshal +293 stub LPSAFEARRAY_UserUnmarshal +294 stub LPSAFEARRAY_UserFree +295 stub LPSAFEARRAY_Size +296 stub LPSAFEARRAY_Marshal +297 stub LPSAFEARRAY_Unmarshal +298 stdcall VarDecCmpR8(ptr double) +299 stdcall VarCyAdd(long long long long ptr) +303 stdcall VarCyMul(long long long long ptr) +304 stdcall VarCyMulI4(long long long ptr) +305 stdcall VarCySub(long long long long ptr) +306 stdcall VarCyAbs(long long ptr) +307 stdcall VarCyFix(long long ptr) +308 stdcall VarCyInt(long long ptr) +309 stdcall VarCyNeg(long long ptr) +310 stdcall VarCyRound(long long long ptr) +311 stdcall VarCyCmp(long long long long) +312 stdcall VarCyCmpR8(long long double) +313 stdcall VarBstrCat(wstr wstr ptr) +314 stdcall VarBstrCmp(wstr wstr long long) +315 stdcall VarR8Pow(double double ptr) +316 stdcall VarR4CmpR8(long double) +317 stdcall VarR8Round(double long ptr) +318 stdcall VarCat(ptr ptr ptr) +319 stdcall VarDateFromUdateEx(ptr long long ptr) +320 stdcall -private DllRegisterServer() OLEAUT32_DllRegisterServer +321 stdcall -private DllUnregisterServer() OLEAUT32_DllUnregisterServer +322 stdcall GetRecordInfoFromGuids(ptr long long long ptr ptr) +323 stub GetRecordInfoFromTypeInfo # stdcall (ptr ptr) +325 stub SetVarConversionLocaleSetting +326 stub GetVarConversionLocaleSetting +327 stdcall SetOaNoCache() +329 stdcall VarCyMulI8(long long long long ptr) +330 stdcall VarDateFromUdate(ptr long ptr) +331 stdcall VarUdateFromDate(double long ptr) +332 stub GetAltMonthNames +333 stdcall VarI8FromUI1(long long) +334 stdcall VarI8FromI2(long long) +335 stdcall VarI8FromR4(long long) +336 stdcall VarI8FromR8(double long) +337 stdcall VarI8FromCy(long long ptr) +338 stdcall VarI8FromDate(double long) +339 stdcall VarI8FromStr(wstr long long ptr) +340 stdcall VarI8FromDisp(ptr long ptr) +341 stdcall VarI8FromBool(long long) +342 stdcall VarI8FromI1(long long) +343 stdcall VarI8FromUI2(long long) +344 stdcall VarI8FromUI4(long long) +345 stdcall VarI8FromDec(ptr ptr) +346 stdcall VarI2FromI8(long long ptr) +347 stdcall VarI2FromUI8(long long ptr) +348 stdcall VarI4FromI8(long long ptr) +349 stdcall VarI4FromUI8(long long ptr) +360 stdcall VarR4FromI8(long long ptr) +361 stdcall VarR4FromUI8(long long ptr) +362 stdcall VarR8FromI8(long long ptr) +363 stdcall VarR8FromUI8(long long ptr) +364 stdcall VarDateFromI8(long long ptr) +365 stdcall VarDateFromUI8(long long ptr) +366 stdcall VarCyFromI8(long long ptr) +367 stdcall VarCyFromUI8(long long ptr) +368 stdcall VarBstrFromI8(long long long long ptr) +369 stdcall VarBstrFromUI8(long long long long ptr) +370 stdcall VarBoolFromI8(long long ptr) +371 stdcall VarBoolFromUI8(long long ptr) +372 stdcall VarUI1FromI8(long long ptr) +373 stdcall VarUI1FromUI8(long long ptr) +374 stdcall VarDecFromI8(long long ptr) +375 stdcall VarDecFromUI8(long long ptr) +376 stdcall VarI1FromI8(long long ptr) +377 stdcall VarI1FromUI8(long long ptr) +378 stdcall VarUI2FromI8(long long ptr) +379 stdcall VarUI2FromUI8(long long ptr) +380 stub UserHWND_from_local +381 stub UserHWND_to_local +382 stub UserHWND_free_inst +383 stub UserHWND_free_local +384 stub UserBSTR_from_local +385 stub UserBSTR_to_local +386 stub UserBSTR_free_inst +387 stub UserBSTR_free_local +388 stub UserVARIANT_from_local +389 stub UserVARIANT_to_local +390 stub UserVARIANT_free_inst +391 stub UserVARIANT_free_local +392 stub UserEXCEPINFO_from_local +393 stub UserEXCEPINFO_to_local +394 stub UserEXCEPINFO_free_inst +395 stub UserEXCEPINFO_free_local +396 stub UserMSG_from_local +397 stub UserMSG_to_local +398 stub UserMSG_free_inst +399 stub UserMSG_free_local +401 stdcall OleLoadPictureEx(ptr long long long long long long ptr) +402 stub OleLoadPictureFileEx +410 stdcall -private DllCanUnloadNow() OLEAUT32_DllCanUnloadNow +411 stdcall SafeArrayCreateVector(long long long) +412 stdcall SafeArrayCopyData(ptr ptr) +413 stdcall VectorFromBstr(ptr ptr) +414 stdcall BstrFromVector(ptr ptr) +415 stdcall OleIconToCursor(long long) +416 stdcall OleCreatePropertyFrameIndirect(ptr) +417 stdcall OleCreatePropertyFrame(ptr long long ptr long ptr long ptr ptr long ptr) +418 stdcall OleLoadPicture(ptr long long ptr ptr) +419 stdcall OleCreatePictureIndirect(ptr ptr long ptr) +420 stdcall OleCreateFontIndirect(ptr ptr ptr) +421 stdcall OleTranslateColor(long long long) +422 stub OleLoadPictureFile +423 stub OleSavePictureFile +424 stub OleLoadPicturePath +425 stdcall VarUI4FromI8(long long ptr) +426 stdcall VarUI4FromUI8(long long ptr) +427 stdcall VarI8FromUI8(long long ptr) +428 stdcall VarUI8FromI8(long long ptr) +429 stdcall VarUI8FromUI1(long ptr) +430 stdcall VarUI8FromI2(long ptr) +431 stdcall VarUI8FromR4(long ptr) +432 stdcall VarUI8FromR8(double ptr) +433 stdcall VarUI8FromCy(long long ptr) +434 stdcall VarUI8FromDate(double ptr) +435 stdcall VarUI8FromStr(wstr long long ptr) +436 stdcall VarUI8FromDisp(ptr long ptr) +437 stdcall VarUI8FromBool(long ptr) +438 stdcall VarUI8FromI1(long ptr) +439 stdcall VarUI8FromUI2(long ptr) +440 stdcall VarUI8FromUI4(long ptr) +441 stdcall VarUI8FromDec(long ptr) diff --git a/reactos/lib/oleaut32/oleaut32_Cz.rc b/reactos/lib/oleaut32/oleaut32_Cz.rc new file mode 100644 index 00000000000..ec871271469 --- /dev/null +++ b/reactos/lib/oleaut32/oleaut32_Cz.rc @@ -0,0 +1,31 @@ +/* + * Czech resources for oleaut32 + * + * Copyright 2003 Jon Griffiths + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_CZECH, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +{ + IDS_TRUE "Pravda" + IDS_FALSE "Nepravda" + IDS_YES "Ano" + IDS_NO "Ne" + IDS_ON "Zapnuto" + IDS_OFF "Vypnuto" +} diff --git a/reactos/lib/oleaut32/oleaut32_De.rc b/reactos/lib/oleaut32/oleaut32_De.rc new file mode 100644 index 00000000000..06cd7008da6 --- /dev/null +++ b/reactos/lib/oleaut32/oleaut32_De.rc @@ -0,0 +1,31 @@ +/* + * German resources for oleaut32 + * + * Copyright 2003 Jon Griffiths + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_GERMAN, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +{ + IDS_TRUE "Wahr" + IDS_FALSE "Falsch" + IDS_YES "Ja" + IDS_NO "Nein" + IDS_ON "Ein" + IDS_OFF "Aus" +} diff --git a/reactos/lib/oleaut32/oleaut32_Dk.rc b/reactos/lib/oleaut32/oleaut32_Dk.rc new file mode 100644 index 00000000000..84666797ba4 --- /dev/null +++ b/reactos/lib/oleaut32/oleaut32_Dk.rc @@ -0,0 +1,31 @@ +/* + * Danish resources for oleaut32 + * + * Copyright 2003 Jon Griffiths + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_DANISH, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +{ + IDS_TRUE "Sand" + IDS_FALSE "Falsk" + IDS_YES "Ja" + IDS_NO "Nej" + IDS_ON "Til" + IDS_OFF "Fra" +} diff --git a/reactos/lib/oleaut32/oleaut32_En.rc b/reactos/lib/oleaut32/oleaut32_En.rc new file mode 100644 index 00000000000..ccd00867e50 --- /dev/null +++ b/reactos/lib/oleaut32/oleaut32_En.rc @@ -0,0 +1,31 @@ +/* + * English resources for oleaut32 + * + * Copyright 2003 Jon Griffiths + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +{ + IDS_TRUE "True" + IDS_FALSE "False" + IDS_YES "Yes" + IDS_NO "No" + IDS_ON "On" + IDS_OFF "Off" +} diff --git a/reactos/lib/oleaut32/oleaut32_Es.rc b/reactos/lib/oleaut32/oleaut32_Es.rc new file mode 100644 index 00000000000..a11ce142e9e --- /dev/null +++ b/reactos/lib/oleaut32/oleaut32_Es.rc @@ -0,0 +1,31 @@ +/* + * Spanish resources for oleaut32 + * + * Copyright 2003 Jon Griffiths + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_SPANISH, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +{ + IDS_TRUE "Verdadero" + IDS_FALSE "Falso" + IDS_YES "Sí" + IDS_NO "No" + IDS_ON "Activado" + IDS_OFF "Desactivado" +} diff --git a/reactos/lib/oleaut32/oleaut32_Fr.rc b/reactos/lib/oleaut32/oleaut32_Fr.rc new file mode 100644 index 00000000000..43e7546d013 --- /dev/null +++ b/reactos/lib/oleaut32/oleaut32_Fr.rc @@ -0,0 +1,31 @@ +/* + * French resources for oleaut32 + * + * Copyright 2003 Jon Griffiths + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +{ + IDS_TRUE "Vrai" + IDS_FALSE "Faux" + IDS_YES "Oui" + IDS_NO "Non" + IDS_ON "Actif" + IDS_OFF "Inactif" +} diff --git a/reactos/lib/oleaut32/oleaut32_Hu.rc b/reactos/lib/oleaut32/oleaut32_Hu.rc new file mode 100644 index 00000000000..bfdf7e4e34c --- /dev/null +++ b/reactos/lib/oleaut32/oleaut32_Hu.rc @@ -0,0 +1,31 @@ +/* + * Hungarian resources for oleaut32 + * + * Copyright 2003 Jon Griffiths + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +{ + IDS_TRUE "Igaz" + IDS_FALSE "Hamis" + IDS_YES "Igen" + IDS_NO "Nem" + IDS_ON "Be" + IDS_OFF "Ki" +} diff --git a/reactos/lib/oleaut32/oleaut32_It.rc b/reactos/lib/oleaut32/oleaut32_It.rc new file mode 100644 index 00000000000..c482c86bc99 --- /dev/null +++ b/reactos/lib/oleaut32/oleaut32_It.rc @@ -0,0 +1,31 @@ +/* + * Italian resources for oleaut32 + * + * Copyright 2003 Jon Griffiths + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_ITALIAN, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +{ + IDS_TRUE "Vero" + IDS_FALSE "Falso" + IDS_YES "Si" + IDS_NO "No" + IDS_ON "On" + IDS_OFF "Off" +} diff --git a/reactos/lib/oleaut32/oleaut32_Nl.rc b/reactos/lib/oleaut32/oleaut32_Nl.rc new file mode 100644 index 00000000000..21b84fd39e1 --- /dev/null +++ b/reactos/lib/oleaut32/oleaut32_Nl.rc @@ -0,0 +1,31 @@ +/* + * Dutch resources for oleaut32 + * + * Copyright 2003 Jon Griffiths + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_DUTCH, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +{ + IDS_TRUE "Waar" + IDS_FALSE "Onwaar" + IDS_YES "Ja" + IDS_NO "Nee" + IDS_ON "Aan" + IDS_OFF "Uit" +} diff --git a/reactos/lib/oleaut32/oleaut32_No.rc b/reactos/lib/oleaut32/oleaut32_No.rc new file mode 100644 index 00000000000..b07dbcd368a --- /dev/null +++ b/reactos/lib/oleaut32/oleaut32_No.rc @@ -0,0 +1,31 @@ +/* + * Norwegian resources for oleaut32 + * + * Copyright 2003 Jon Griffiths + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_NORWEGIAN, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +{ + IDS_TRUE "Sann" + IDS_FALSE "Usann" + IDS_YES "Ja" + IDS_NO "Nei" + IDS_ON "PÕ" + IDS_OFF "Av" +} diff --git a/reactos/lib/oleaut32/oleaut32_Pl.rc b/reactos/lib/oleaut32/oleaut32_Pl.rc new file mode 100644 index 00000000000..7f9421901b9 --- /dev/null +++ b/reactos/lib/oleaut32/oleaut32_Pl.rc @@ -0,0 +1,32 @@ +/* + * Polish resources for oleaut32 + * + * Copyright 2003 Jon Griffiths + * Copyright 2004 Jacek Caban + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_POLISH, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +{ + IDS_TRUE "Prawda" + IDS_FALSE "Fa³sz" + IDS_YES "Tak" + IDS_NO "Nie" + IDS_ON "W³¹czone" + IDS_OFF "Wy³¹czone" +} diff --git a/reactos/lib/oleaut32/oleaut32_Pt.rc b/reactos/lib/oleaut32/oleaut32_Pt.rc new file mode 100644 index 00000000000..d4ce6030d95 --- /dev/null +++ b/reactos/lib/oleaut32/oleaut32_Pt.rc @@ -0,0 +1,31 @@ +/* + * Portuguese resources for oleaut32 + * + * Copyright 2003 Marcelo Duarte + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_PORTUGUESE, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +{ + IDS_TRUE "Verdadeiro" + IDS_FALSE "Falso" + IDS_YES "Sim" + IDS_NO "Não" + IDS_ON "Ligado" + IDS_OFF "Desligado" +} diff --git a/reactos/lib/oleaut32/oleaut32_Sv.rc b/reactos/lib/oleaut32/oleaut32_Sv.rc new file mode 100644 index 00000000000..24415e9bceb --- /dev/null +++ b/reactos/lib/oleaut32/oleaut32_Sv.rc @@ -0,0 +1,31 @@ +/* + * Swedish resources for oleaut32 + * + * Copyright 2003 Jon Griffiths + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_SWEDISH, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +{ + IDS_TRUE "Sant" + IDS_FALSE "Falskt" + IDS_YES "Ja" + IDS_NO "Nej" + IDS_ON "PÕ" + IDS_OFF "Av" +} diff --git a/reactos/lib/oleaut32/oleaut32_Th.rc b/reactos/lib/oleaut32/oleaut32_Th.rc new file mode 100644 index 00000000000..1160a764712 --- /dev/null +++ b/reactos/lib/oleaut32/oleaut32_Th.rc @@ -0,0 +1,31 @@ +/* + * Thai resources for oleaut32 + * + * Copyright 2003 Jon Griffiths + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_THAI, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +{ + IDS_TRUE "¨ÃÔ§" + IDS_FALSE "äÁè¨ÃÔ§" + IDS_YES "ãªè" + IDS_NO "äÁèãªè" + IDS_ON "à»Ô´" + IDS_OFF "»Ô´" +} diff --git a/reactos/lib/oleaut32/olefont.c b/reactos/lib/oleaut32/olefont.c new file mode 100644 index 00000000000..2a6ad27a095 --- /dev/null +++ b/reactos/lib/oleaut32/olefont.c @@ -0,0 +1,2143 @@ +/* + * OLE Font encapsulation implementation + * + * This file contains an implementation of the IFont + * interface and the OleCreateFontIndirect API call. + * + * Copyright 1999 Francis Beaudet + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include + +#define COBJMACROS +#define NONAMELESSUNION +#define NONAMELESSSTRUCT + +#include "winerror.h" +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" +#include "wine/unicode.h" +#include "objbase.h" +#include "oleauto.h" /* for SysAllocString(....) */ +#include "ole2.h" +#include "olectl.h" +#include "wine/debug.h" +#include "connpt.h" /* for CreateConnectionPoint */ + +WINE_DEFAULT_DEBUG_CHANNEL(ole); + +/*********************************************************************** + * Declaration of constants used when serializing the font object. + */ +#define FONTPERSIST_ITALIC 0x02 +#define FONTPERSIST_UNDERLINE 0x04 +#define FONTPERSIST_STRIKETHROUGH 0x08 + +/*********************************************************************** + * Declaration of the implementation class for the IFont interface + */ +typedef struct OLEFontImpl OLEFontImpl; + +struct OLEFontImpl +{ + /* + * This class supports many interfaces. IUnknown, IFont, + * IDispatch, IDispFont IPersistStream and IConnectionPointContainer. + * The first two are supported by the first vtable, the next two are + * supported by the second table and the last two have their own. + */ + IFontVtbl* lpvtbl1; + IDispatchVtbl* lpvtbl2; + IPersistStreamVtbl* lpvtbl3; + IConnectionPointContainerVtbl* lpvtbl4; + IPersistPropertyBagVtbl* lpvtbl5; + IPersistStreamInitVtbl* lpvtbl6; + /* + * Reference count for that instance of the class. + */ + ULONG ref; + + /* + * This structure contains the description of the class. + */ + FONTDESC description; + + /* + * Contain the font associated with this object. + */ + HFONT gdiFont; + + /* + * Font lock count. + */ + DWORD fontLock; + + /* + * Size ratio + */ + long cyLogical; + long cyHimetric; + + IConnectionPoint *pCP; +}; + +/* + * Here, I define utility macros to help with the casting of the + * "this" parameter. + * There is a version to accommodate all of the VTables implemented + * by this object. + */ +#define _ICOM_THIS_From_IDispatch(class, name) class* this = (class*)(((char*)name)-sizeof(void*)) +#define _ICOM_THIS_From_IPersistStream(class, name) class* this = (class*)(((char*)name)-2*sizeof(void*)) +#define _ICOM_THIS_From_IConnectionPointContainer(class, name) class* this = (class*)(((char*)name)-3*sizeof(void*)) +#define _ICOM_THIS_From_IPersistPropertyBag(class, name) class* this = (class*)(((char*)name)-4*sizeof(void*)) +#define _ICOM_THIS_From_IPersistStreamInit(class, name) class* this = (class*)(((char*)name)-5*sizeof(void*)) + + +/*********************************************************************** + * Prototypes for the implementation functions for the IFont + * interface + */ +static OLEFontImpl* OLEFontImpl_Construct(LPFONTDESC fontDesc); +static void OLEFontImpl_Destroy(OLEFontImpl* fontDesc); +static HRESULT WINAPI OLEFontImpl_QueryInterface(IFont* iface, REFIID riid, VOID** ppvoid); +static ULONG WINAPI OLEFontImpl_AddRef(IFont* iface); +static ULONG WINAPI OLEFontImpl_Release(IFont* iface); +static HRESULT WINAPI OLEFontImpl_get_Name(IFont* iface, BSTR* pname); +static HRESULT WINAPI OLEFontImpl_put_Name(IFont* iface, BSTR name); +static HRESULT WINAPI OLEFontImpl_get_Size(IFont* iface, CY* psize); +static HRESULT WINAPI OLEFontImpl_put_Size(IFont* iface, CY size); +static HRESULT WINAPI OLEFontImpl_get_Bold(IFont* iface, BOOL* pbold); +static HRESULT WINAPI OLEFontImpl_put_Bold(IFont* iface, BOOL bold); +static HRESULT WINAPI OLEFontImpl_get_Italic(IFont* iface, BOOL* pitalic); +static HRESULT WINAPI OLEFontImpl_put_Italic(IFont* iface, BOOL italic); +static HRESULT WINAPI OLEFontImpl_get_Underline(IFont* iface, BOOL* punderline); +static HRESULT WINAPI OLEFontImpl_put_Underline(IFont* iface, BOOL underline); +static HRESULT WINAPI OLEFontImpl_get_Strikethrough(IFont* iface, BOOL* pstrikethrough); +static HRESULT WINAPI OLEFontImpl_put_Strikethrough(IFont* iface, BOOL strikethrough); +static HRESULT WINAPI OLEFontImpl_get_Weight(IFont* iface, short* pweight); +static HRESULT WINAPI OLEFontImpl_put_Weight(IFont* iface, short weight); +static HRESULT WINAPI OLEFontImpl_get_Charset(IFont* iface, short* pcharset); +static HRESULT WINAPI OLEFontImpl_put_Charset(IFont* iface, short charset); +static HRESULT WINAPI OLEFontImpl_get_hFont(IFont* iface, HFONT* phfont); +static HRESULT WINAPI OLEFontImpl_Clone(IFont* iface, IFont** ppfont); +static HRESULT WINAPI OLEFontImpl_IsEqual(IFont* iface, IFont* pFontOther); +static HRESULT WINAPI OLEFontImpl_SetRatio(IFont* iface, LONG cyLogical, LONG cyHimetric); +static HRESULT WINAPI OLEFontImpl_QueryTextMetrics(IFont* iface, TEXTMETRICOLE* ptm); +static HRESULT WINAPI OLEFontImpl_AddRefHfont(IFont* iface, HFONT hfont); +static HRESULT WINAPI OLEFontImpl_ReleaseHfont(IFont* iface, HFONT hfont); +static HRESULT WINAPI OLEFontImpl_SetHdc(IFont* iface, HDC hdc); + +/*********************************************************************** + * Prototypes for the implementation functions for the IDispatch + * interface + */ +static HRESULT WINAPI OLEFontImpl_IDispatch_QueryInterface(IDispatch* iface, + REFIID riid, + VOID** ppvoid); +static ULONG WINAPI OLEFontImpl_IDispatch_AddRef(IDispatch* iface); +static ULONG WINAPI OLEFontImpl_IDispatch_Release(IDispatch* iface); +static HRESULT WINAPI OLEFontImpl_GetTypeInfoCount(IDispatch* iface, + unsigned int* pctinfo); +static HRESULT WINAPI OLEFontImpl_GetTypeInfo(IDispatch* iface, + UINT iTInfo, + LCID lcid, + ITypeInfo** ppTInfo); +static HRESULT WINAPI OLEFontImpl_GetIDsOfNames(IDispatch* iface, + REFIID riid, + LPOLESTR* rgszNames, + UINT cNames, + LCID lcid, + DISPID* rgDispId); +static HRESULT WINAPI OLEFontImpl_Invoke(IDispatch* iface, + DISPID dispIdMember, + REFIID riid, + LCID lcid, + WORD wFlags, + DISPPARAMS* pDispParams, + VARIANT* pVarResult, + EXCEPINFO* pExepInfo, + UINT* puArgErr); + +/*********************************************************************** + * Prototypes for the implementation functions for the IPersistStream + * interface + */ +static HRESULT WINAPI OLEFontImpl_IPersistStream_QueryInterface(IPersistStream* iface, + REFIID riid, + VOID** ppvoid); +static ULONG WINAPI OLEFontImpl_IPersistStream_AddRef(IPersistStream* iface); +static ULONG WINAPI OLEFontImpl_IPersistStream_Release(IPersistStream* iface); +static HRESULT WINAPI OLEFontImpl_GetClassID(IPersistStream* iface, + CLSID* pClassID); +static HRESULT WINAPI OLEFontImpl_IsDirty(IPersistStream* iface); +static HRESULT WINAPI OLEFontImpl_Load(IPersistStream* iface, + IStream* pLoadStream); +static HRESULT WINAPI OLEFontImpl_Save(IPersistStream* iface, + IStream* pOutStream, + BOOL fClearDirty); +static HRESULT WINAPI OLEFontImpl_GetSizeMax(IPersistStream* iface, + ULARGE_INTEGER* pcbSize); + +/*********************************************************************** + * Prototypes for the implementation functions for the + * IConnectionPointContainer interface + */ +static HRESULT WINAPI OLEFontImpl_IConnectionPointContainer_QueryInterface( + IConnectionPointContainer* iface, + REFIID riid, + VOID** ppvoid); +static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_AddRef( + IConnectionPointContainer* iface); +static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_Release( + IConnectionPointContainer* iface); +static HRESULT WINAPI OLEFontImpl_EnumConnectionPoints( + IConnectionPointContainer* iface, + IEnumConnectionPoints **ppEnum); +static HRESULT WINAPI OLEFontImpl_FindConnectionPoint( + IConnectionPointContainer* iface, + REFIID riid, + IConnectionPoint **ppCp); + +/* + * Virtual function tables for the OLEFontImpl class. + */ +static IFontVtbl OLEFontImpl_VTable = +{ + OLEFontImpl_QueryInterface, + OLEFontImpl_AddRef, + OLEFontImpl_Release, + OLEFontImpl_get_Name, + OLEFontImpl_put_Name, + OLEFontImpl_get_Size, + OLEFontImpl_put_Size, + OLEFontImpl_get_Bold, + OLEFontImpl_put_Bold, + OLEFontImpl_get_Italic, + OLEFontImpl_put_Italic, + OLEFontImpl_get_Underline, + OLEFontImpl_put_Underline, + OLEFontImpl_get_Strikethrough, + OLEFontImpl_put_Strikethrough, + OLEFontImpl_get_Weight, + OLEFontImpl_put_Weight, + OLEFontImpl_get_Charset, + OLEFontImpl_put_Charset, + OLEFontImpl_get_hFont, + OLEFontImpl_Clone, + OLEFontImpl_IsEqual, + OLEFontImpl_SetRatio, + OLEFontImpl_QueryTextMetrics, + OLEFontImpl_AddRefHfont, + OLEFontImpl_ReleaseHfont, + OLEFontImpl_SetHdc +}; + +static IDispatchVtbl OLEFontImpl_IDispatch_VTable = +{ + OLEFontImpl_IDispatch_QueryInterface, + OLEFontImpl_IDispatch_AddRef, + OLEFontImpl_IDispatch_Release, + OLEFontImpl_GetTypeInfoCount, + OLEFontImpl_GetTypeInfo, + OLEFontImpl_GetIDsOfNames, + OLEFontImpl_Invoke +}; + +static IPersistStreamVtbl OLEFontImpl_IPersistStream_VTable = +{ + OLEFontImpl_IPersistStream_QueryInterface, + OLEFontImpl_IPersistStream_AddRef, + OLEFontImpl_IPersistStream_Release, + OLEFontImpl_GetClassID, + OLEFontImpl_IsDirty, + OLEFontImpl_Load, + OLEFontImpl_Save, + OLEFontImpl_GetSizeMax +}; + +static IConnectionPointContainerVtbl + OLEFontImpl_IConnectionPointContainer_VTable = +{ + OLEFontImpl_IConnectionPointContainer_QueryInterface, + OLEFontImpl_IConnectionPointContainer_AddRef, + OLEFontImpl_IConnectionPointContainer_Release, + OLEFontImpl_EnumConnectionPoints, + OLEFontImpl_FindConnectionPoint +}; + +static IPersistPropertyBagVtbl OLEFontImpl_IPersistPropertyBag_VTable; +static IPersistStreamInitVtbl OLEFontImpl_IPersistStreamInit_VTable; +/****************************************************************************** + * OleCreateFontIndirect [OLEAUT32.420] + */ +HRESULT WINAPI OleCreateFontIndirect( + LPFONTDESC lpFontDesc, + REFIID riid, + LPVOID* ppvObj) +{ + OLEFontImpl* newFont = 0; + HRESULT hr = S_OK; + + TRACE("(%p, %s, %p)\n", lpFontDesc, debugstr_guid(riid), ppvObj); + /* + * Sanity check + */ + if (ppvObj==0) + return E_POINTER; + + *ppvObj = 0; + + if (!lpFontDesc) { + FONTDESC fd; + + static const WCHAR fname[] = { 'S','y','s','t','e','m',0 }; + + fd.cbSizeofstruct = sizeof(fd); + fd.lpstrName = (WCHAR*)fname; + fd.cySize.s.Lo = 80000; + fd.cySize.s.Hi = 0; + fd.sWeight = 0; + fd.sCharset = 0; + fd.fItalic = 0; + fd.fUnderline = 0; + fd.fStrikethrough = 0; + lpFontDesc = &fd; + } + + /* + * Try to construct a new instance of the class. + */ + newFont = OLEFontImpl_Construct(lpFontDesc); + + if (newFont == 0) + return E_OUTOFMEMORY; + + /* + * Make sure it supports the interface required by the caller. + */ + hr = IFont_QueryInterface((IFont*)newFont, riid, ppvObj); + + /* + * Release the reference obtained in the constructor. If + * the QueryInterface was unsuccessful, it will free the class. + */ + IFont_Release((IFont*)newFont); + + return hr; +} + + +/*********************************************************************** + * Implementation of the OLEFontImpl class. + */ + +/*********************************************************************** + * OLEFont_SendNotify (internal) + * + * Sends notification messages of changed properties to any interested + * connections. + */ +static void OLEFont_SendNotify(OLEFontImpl* this, DISPID dispID) +{ + IEnumConnections *pEnum; + CONNECTDATA CD; + HRESULT hres; + + hres = IConnectionPoint_EnumConnections(this->pCP, &pEnum); + if (FAILED(hres)) /* When we have 0 connections. */ + return; + + while(IEnumConnections_Next(pEnum, 1, &CD, NULL) == S_OK) { + IPropertyNotifySink *sink; + + IUnknown_QueryInterface(CD.pUnk, &IID_IPropertyNotifySink, (LPVOID)&sink); + IPropertyNotifySink_OnChanged(sink, dispID); + IPropertyNotifySink_Release(sink); + IUnknown_Release(CD.pUnk); + } + IEnumConnections_Release(pEnum); + return; +} + +/************************************************************************ + * OLEFontImpl_Construct + * + * This method will construct a new instance of the OLEFontImpl + * class. + * + * The caller of this method must release the object when it's + * done with it. + */ +static OLEFontImpl* OLEFontImpl_Construct(LPFONTDESC fontDesc) +{ + OLEFontImpl* newObject = 0; + + /* + * Allocate space for the object. + */ + newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl)); + + if (newObject==0) + return newObject; + + /* + * Initialize the virtual function table. + */ + newObject->lpvtbl1 = &OLEFontImpl_VTable; + newObject->lpvtbl2 = &OLEFontImpl_IDispatch_VTable; + newObject->lpvtbl3 = &OLEFontImpl_IPersistStream_VTable; + newObject->lpvtbl4 = &OLEFontImpl_IConnectionPointContainer_VTable; + newObject->lpvtbl5 = &OLEFontImpl_IPersistPropertyBag_VTable; + newObject->lpvtbl6 = &OLEFontImpl_IPersistStreamInit_VTable; + + /* + * Start with one reference count. The caller of this function + * must release the interface pointer when it is done. + */ + newObject->ref = 1; + + /* + * Copy the description of the font in the object. + */ + assert(fontDesc->cbSizeofstruct >= sizeof(FONTDESC)); + + newObject->description.cbSizeofstruct = sizeof(FONTDESC); + newObject->description.lpstrName = HeapAlloc(GetProcessHeap(), + 0, + (lstrlenW(fontDesc->lpstrName)+1) * sizeof(WCHAR)); + strcpyW(newObject->description.lpstrName, fontDesc->lpstrName); + newObject->description.cySize = fontDesc->cySize; + newObject->description.sWeight = fontDesc->sWeight; + newObject->description.sCharset = fontDesc->sCharset; + newObject->description.fItalic = fontDesc->fItalic; + newObject->description.fUnderline = fontDesc->fUnderline; + newObject->description.fStrikethrough = fontDesc->fStrikethrough; + + /* + * Initializing all the other members. + */ + newObject->gdiFont = 0; + newObject->fontLock = 0; + newObject->cyLogical = 72L; + newObject->cyHimetric = 2540L; + CreateConnectionPoint((IUnknown*)newObject, &IID_IPropertyNotifySink, &newObject->pCP); + TRACE("returning %p\n", newObject); + return newObject; +} + +/************************************************************************ + * OLEFontImpl_Destroy + * + * This method is called by the Release method when the reference + * count goes down to 0. It will free all resources used by + * this object. + */ +static void OLEFontImpl_Destroy(OLEFontImpl* fontDesc) +{ + TRACE("(%p)\n", fontDesc); + + if (fontDesc->description.lpstrName!=0) + HeapFree(GetProcessHeap(), 0, fontDesc->description.lpstrName); + + if (fontDesc->gdiFont!=0) + DeleteObject(fontDesc->gdiFont); + + HeapFree(GetProcessHeap(), 0, fontDesc); +} + +/************************************************************************ + * OLEFontImpl_QueryInterface (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +HRESULT WINAPI OLEFontImpl_QueryInterface( + IFont* iface, + REFIID riid, + void** ppvObject) +{ + OLEFontImpl *this = (OLEFontImpl *)iface; + TRACE("(%p)->(%s, %p)\n", this, debugstr_guid(riid), ppvObject); + + /* + * Perform a sanity check on the parameters. + */ + if ( (this==0) || (ppvObject==0) ) + return E_INVALIDARG; + + /* + * Initialize the return parameter. + */ + *ppvObject = 0; + + /* + * Compare the riid with the interface IDs implemented by this object. + */ + if (IsEqualGUID(&IID_IUnknown, riid)) + *ppvObject = (IFont*)this; + if (IsEqualGUID(&IID_IFont, riid)) + *ppvObject = (IFont*)this; + if (IsEqualGUID(&IID_IDispatch, riid)) + *ppvObject = (IDispatch*)&(this->lpvtbl2); + if (IsEqualGUID(&IID_IFontDisp, riid)) + *ppvObject = (IDispatch*)&(this->lpvtbl2); + if (IsEqualGUID(&IID_IPersistStream, riid)) + *ppvObject = (IPersistStream*)&(this->lpvtbl3); + if (IsEqualGUID(&IID_IConnectionPointContainer, riid)) + *ppvObject = (IConnectionPointContainer*)&(this->lpvtbl4); + if (IsEqualGUID(&IID_IPersistPropertyBag, riid)) + *ppvObject = (IPersistPropertyBag*)&(this->lpvtbl5); + if (IsEqualGUID(&IID_IPersistStreamInit, riid)) + *ppvObject = (IPersistStreamInit*)&(this->lpvtbl6); + + /* + * Check that we obtained an interface. + */ + if ((*ppvObject)==0) + { + FIXME("() : asking for unsupported interface %s\n",debugstr_guid(riid)); + return E_NOINTERFACE; + } + OLEFontImpl_AddRef((IFont*)this); + return S_OK; +} + +/************************************************************************ + * OLEFontImpl_AddRef (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +ULONG WINAPI OLEFontImpl_AddRef( + IFont* iface) +{ + OLEFontImpl *this = (OLEFontImpl *)iface; + TRACE("(%p)->(ref=%ld)\n", this, this->ref); + return InterlockedIncrement(&this->ref); +} + +/************************************************************************ + * OLEFontImpl_Release (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +ULONG WINAPI OLEFontImpl_Release( + IFont* iface) +{ + OLEFontImpl *this = (OLEFontImpl *)iface; + ULONG ret; + TRACE("(%p)->(ref=%ld)\n", this, this->ref); + + /* + * Decrease the reference count on this object. + */ + ret = InterlockedDecrement(&this->ref); + + /* + * If the reference count goes down to 0, perform suicide. + */ + if (ret==0) OLEFontImpl_Destroy(this); + + return ret; +} + +/************************************************************************ + * OLEFontImpl_get_Name (IFont) + * + * See Windows documentation for more details on IFont methods. + */ +static HRESULT WINAPI OLEFontImpl_get_Name( + IFont* iface, + BSTR* pname) +{ + OLEFontImpl *this = (OLEFontImpl *)iface; + TRACE("(%p)->(%p)\n", this, pname); + /* + * Sanity check. + */ + if (pname==0) + return E_POINTER; + + if (this->description.lpstrName!=0) + *pname = SysAllocString(this->description.lpstrName); + else + *pname = 0; + + return S_OK; +} + +/************************************************************************ + * OLEFontImpl_put_Name (IFont) + * + * See Windows documentation for more details on IFont methods. + */ +static HRESULT WINAPI OLEFontImpl_put_Name( + IFont* iface, + BSTR name) +{ + OLEFontImpl *this = (OLEFontImpl *)iface; + TRACE("(%p)->(%p)\n", this, name); + + if (this->description.lpstrName==0) + { + this->description.lpstrName = HeapAlloc(GetProcessHeap(), + 0, + (lstrlenW(name)+1) * sizeof(WCHAR)); + } + else + { + this->description.lpstrName = HeapReAlloc(GetProcessHeap(), + 0, + this->description.lpstrName, + (lstrlenW(name)+1) * sizeof(WCHAR)); + } + + if (this->description.lpstrName==0) + return E_OUTOFMEMORY; + + strcpyW(this->description.lpstrName, name); + TRACE("new name %s\n", debugstr_w(this->description.lpstrName)); + OLEFont_SendNotify(this, DISPID_FONT_NAME); + return S_OK; +} + +/************************************************************************ + * OLEFontImpl_get_Size (IFont) + * + * See Windows documentation for more details on IFont methods. + */ +static HRESULT WINAPI OLEFontImpl_get_Size( + IFont* iface, + CY* psize) +{ + OLEFontImpl *this = (OLEFontImpl *)iface; + TRACE("(%p)->(%p)\n", this, psize); + + /* + * Sanity check + */ + if (psize==0) + return E_POINTER; + + psize->s.Hi = 0; + psize->s.Lo = this->description.cySize.s.Lo; + + return S_OK; +} + +/************************************************************************ + * OLEFontImpl_put_Size (IFont) + * + * See Windows documentation for more details on IFont methods. + */ +static HRESULT WINAPI OLEFontImpl_put_Size( + IFont* iface, + CY size) +{ + OLEFontImpl *this = (OLEFontImpl *)iface; + TRACE("(%p)->(%ld)\n", this, size.s.Lo); + this->description.cySize.s.Hi = 0; + this->description.cySize.s.Lo = size.s.Lo; + OLEFont_SendNotify(this, DISPID_FONT_SIZE); + + return S_OK; +} + +/************************************************************************ + * OLEFontImpl_get_Bold (IFont) + * + * See Windows documentation for more details on IFont methods. + */ +static HRESULT WINAPI OLEFontImpl_get_Bold( + IFont* iface, + BOOL* pbold) +{ + OLEFontImpl *this = (OLEFontImpl *)iface; + TRACE("(%p)->(%p)\n", this, pbold); + /* + * Sanity check + */ + if (pbold==0) + return E_POINTER; + + *pbold = this->description.sWeight > 550; + + return S_OK; +} + +/************************************************************************ + * OLEFontImpl_put_Bold (IFont) + * + * See Windows documentation for more details on IFont methods. + */ +static HRESULT WINAPI OLEFontImpl_put_Bold( + IFont* iface, + BOOL bold) +{ + OLEFontImpl *this = (OLEFontImpl *)iface; + TRACE("(%p)->(%d)\n", this, bold); + this->description.sWeight = bold ? FW_BOLD : FW_NORMAL; + OLEFont_SendNotify(this, DISPID_FONT_BOLD); + + return S_OK; +} + +/************************************************************************ + * OLEFontImpl_get_Italic (IFont) + * + * See Windows documentation for more details on IFont methods. + */ +static HRESULT WINAPI OLEFontImpl_get_Italic( + IFont* iface, + BOOL* pitalic) +{ + OLEFontImpl *this = (OLEFontImpl *)iface; + TRACE("(%p)->(%p)\n", this, pitalic); + /* + * Sanity check + */ + if (pitalic==0) + return E_POINTER; + + *pitalic = this->description.fItalic; + + return S_OK; +} + +/************************************************************************ + * OLEFontImpl_put_Italic (IFont) + * + * See Windows documentation for more details on IFont methods. + */ +static HRESULT WINAPI OLEFontImpl_put_Italic( + IFont* iface, + BOOL italic) +{ + OLEFontImpl *this = (OLEFontImpl *)iface; + TRACE("(%p)->(%d)\n", this, italic); + + this->description.fItalic = italic; + + OLEFont_SendNotify(this, DISPID_FONT_ITALIC); + return S_OK; +} + +/************************************************************************ + * OLEFontImpl_get_Underline (IFont) + * + * See Windows documentation for more details on IFont methods. + */ +static HRESULT WINAPI OLEFontImpl_get_Underline( + IFont* iface, + BOOL* punderline) +{ + OLEFontImpl *this = (OLEFontImpl *)iface; + TRACE("(%p)->(%p)\n", this, punderline); + + /* + * Sanity check + */ + if (punderline==0) + return E_POINTER; + + *punderline = this->description.fUnderline; + + return S_OK; +} + +/************************************************************************ + * OLEFontImpl_put_Underline (IFont) + * + * See Windows documentation for more details on IFont methods. + */ +static HRESULT WINAPI OLEFontImpl_put_Underline( + IFont* iface, + BOOL underline) +{ + OLEFontImpl *this = (OLEFontImpl *)iface; + TRACE("(%p)->(%d)\n", this, underline); + + this->description.fUnderline = underline; + + OLEFont_SendNotify(this, DISPID_FONT_UNDER); + return S_OK; +} + +/************************************************************************ + * OLEFontImpl_get_Strikethrough (IFont) + * + * See Windows documentation for more details on IFont methods. + */ +static HRESULT WINAPI OLEFontImpl_get_Strikethrough( + IFont* iface, + BOOL* pstrikethrough) +{ + OLEFontImpl *this = (OLEFontImpl *)iface; + TRACE("(%p)->(%p)\n", this, pstrikethrough); + + /* + * Sanity check + */ + if (pstrikethrough==0) + return E_POINTER; + + *pstrikethrough = this->description.fStrikethrough; + + return S_OK; +} + +/************************************************************************ + * OLEFontImpl_put_Strikethrough (IFont) + * + * See Windows documentation for more details on IFont methods. + */ +static HRESULT WINAPI OLEFontImpl_put_Strikethrough( + IFont* iface, + BOOL strikethrough) +{ + OLEFontImpl *this = (OLEFontImpl *)iface; + TRACE("(%p)->(%d)\n", this, strikethrough); + + this->description.fStrikethrough = strikethrough; + OLEFont_SendNotify(this, DISPID_FONT_STRIKE); + + return S_OK; +} + +/************************************************************************ + * OLEFontImpl_get_Weight (IFont) + * + * See Windows documentation for more details on IFont methods. + */ +static HRESULT WINAPI OLEFontImpl_get_Weight( + IFont* iface, + short* pweight) +{ + OLEFontImpl *this = (OLEFontImpl *)iface; + TRACE("(%p)->(%p)\n", this, pweight); + + /* + * Sanity check + */ + if (pweight==0) + return E_POINTER; + + *pweight = this->description.sWeight; + + return S_OK; +} + +/************************************************************************ + * OLEFontImpl_put_Weight (IFont) + * + * See Windows documentation for more details on IFont methods. + */ +static HRESULT WINAPI OLEFontImpl_put_Weight( + IFont* iface, + short weight) +{ + OLEFontImpl *this = (OLEFontImpl *)iface; + TRACE("(%p)->(%d)\n", this, weight); + + this->description.sWeight = weight; + + OLEFont_SendNotify(this, DISPID_FONT_WEIGHT); + return S_OK; +} + +/************************************************************************ + * OLEFontImpl_get_Charset (IFont) + * + * See Windows documentation for more details on IFont methods. + */ +static HRESULT WINAPI OLEFontImpl_get_Charset( + IFont* iface, + short* pcharset) +{ + OLEFontImpl *this = (OLEFontImpl *)iface; + TRACE("(%p)->(%p)\n", this, pcharset); + + /* + * Sanity check + */ + if (pcharset==0) + return E_POINTER; + + *pcharset = this->description.sCharset; + + return S_OK; +} + +/************************************************************************ + * OLEFontImpl_put_Charset (IFont) + * + * See Windows documentation for more details on IFont methods. + */ +static HRESULT WINAPI OLEFontImpl_put_Charset( + IFont* iface, + short charset) +{ + OLEFontImpl *this = (OLEFontImpl *)iface; + TRACE("(%p)->(%d)\n", this, charset); + + this->description.sCharset = charset; + OLEFont_SendNotify(this, DISPID_FONT_CHARSET); + + return S_OK; +} + +/************************************************************************ + * OLEFontImpl_get_hFont (IFont) + * + * See Windows documentation for more details on IFont methods. + */ +static HRESULT WINAPI OLEFontImpl_get_hFont( + IFont* iface, + HFONT* phfont) +{ + OLEFontImpl *this = (OLEFontImpl *)iface; + TRACE("(%p)->(%p)\n", this, phfont); + if (phfont==NULL) + return E_POINTER; + + /* + * Realize the font if necessary + */ + if (this->gdiFont==0) +{ + LOGFONTW logFont; + INT fontHeight; + CY cySize; + + /* + * The height of the font returned by the get_Size property is the + * height of the font in points multiplied by 10000... Using some + * simple conversions and the ratio given by the application, it can + * be converted to a height in pixels. + */ + IFont_get_Size(iface, &cySize); + + fontHeight = MulDiv( cySize.s.Lo, this->cyLogical, this->cyHimetric ); + + memset(&logFont, 0, sizeof(LOGFONTW)); + + logFont.lfHeight = ((fontHeight%10000L)>5000L) ? (-fontHeight/10000L)-1 : + (-fontHeight/10000L); + logFont.lfItalic = this->description.fItalic; + logFont.lfUnderline = this->description.fUnderline; + logFont.lfStrikeOut = this->description.fStrikethrough; + logFont.lfWeight = this->description.sWeight; + logFont.lfCharSet = this->description.sCharset; + logFont.lfOutPrecision = OUT_CHARACTER_PRECIS; + logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS; + logFont.lfQuality = DEFAULT_QUALITY; + logFont.lfPitchAndFamily = DEFAULT_PITCH; + strcpyW(logFont.lfFaceName,this->description.lpstrName); + + this->gdiFont = CreateFontIndirectW(&logFont); + } + + *phfont = this->gdiFont; + TRACE("Returning %p\n", *phfont); + return S_OK; +} + +/************************************************************************ + * OLEFontImpl_Clone (IFont) + * + * See Windows documentation for more details on IFont methods. + */ +static HRESULT WINAPI OLEFontImpl_Clone( + IFont* iface, + IFont** ppfont) +{ + OLEFontImpl* newObject = 0; + LOGFONTW logFont; + INT fontHeight; + CY cySize; + OLEFontImpl *this = (OLEFontImpl *)iface; + TRACE("(%p)->(%p)\n", this, ppfont); + + if (ppfont == NULL) + return E_POINTER; + + *ppfont = NULL; + + /* + * Allocate space for the object. + */ + newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl)); + + if (newObject==NULL) + return E_OUTOFMEMORY; + + *newObject = *this; + + /* We need to alloc new memory for the string, otherwise + * we free memory twice. + */ + newObject->description.lpstrName = HeapAlloc( + GetProcessHeap(),0, + (1+strlenW(this->description.lpstrName))*2 + ); + strcpyW(newObject->description.lpstrName, this->description.lpstrName); + /* We need to clone the HFONT too. This is just cut & paste from above */ + IFont_get_Size(iface, &cySize); + + fontHeight = MulDiv(cySize.s.Lo, this->cyLogical,this->cyHimetric); + + memset(&logFont, 0, sizeof(LOGFONTW)); + + logFont.lfHeight = ((fontHeight%10000L)>5000L) ? (-fontHeight/10000L)-1 : + (-fontHeight/10000L); + logFont.lfItalic = this->description.fItalic; + logFont.lfUnderline = this->description.fUnderline; + logFont.lfStrikeOut = this->description.fStrikethrough; + logFont.lfWeight = this->description.sWeight; + logFont.lfCharSet = this->description.sCharset; + logFont.lfOutPrecision = OUT_CHARACTER_PRECIS; + logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS; + logFont.lfQuality = DEFAULT_QUALITY; + logFont.lfPitchAndFamily = DEFAULT_PITCH; + strcpyW(logFont.lfFaceName,this->description.lpstrName); + + newObject->gdiFont = CreateFontIndirectW(&logFont); + + + /* The cloned object starts with a reference count of 1 */ + newObject->ref = 1; + + *ppfont = (IFont*)newObject; + + return S_OK; +} + +/************************************************************************ + * OLEFontImpl_IsEqual (IFont) + * + * See Windows documentation for more details on IFont methods. + */ +static HRESULT WINAPI OLEFontImpl_IsEqual( + IFont* iface, + IFont* pFontOther) +{ + FIXME("(%p, %p), stub!\n",iface,pFontOther); + return E_NOTIMPL; +} + +/************************************************************************ + * OLEFontImpl_SetRatio (IFont) + * + * See Windows documentation for more details on IFont methods. + */ +static HRESULT WINAPI OLEFontImpl_SetRatio( + IFont* iface, + LONG cyLogical, + LONG cyHimetric) +{ + OLEFontImpl *this = (OLEFontImpl *)iface; + TRACE("(%p)->(%ld, %ld)\n", this, cyLogical, cyHimetric); + + this->cyLogical = cyLogical; + this->cyHimetric = cyHimetric; + + return S_OK; +} + +/************************************************************************ + * OLEFontImpl_QueryTextMetrics (IFont) + * + * See Windows documentation for more details on IFont methods. + */ +static HRESULT WINAPI OLEFontImpl_QueryTextMetrics( + IFont* iface, + TEXTMETRICOLE* ptm) +{ + FIXME("(%p, %p), stub!\n",iface,ptm); + return E_NOTIMPL; +} + +/************************************************************************ + * OLEFontImpl_AddRefHfont (IFont) + * + * See Windows documentation for more details on IFont methods. + */ +static HRESULT WINAPI OLEFontImpl_AddRefHfont( + IFont* iface, + HFONT hfont) +{ + OLEFontImpl *this = (OLEFontImpl *)iface; + TRACE("(%p)->(%p) (lock=%ld)\n", this, hfont, this->fontLock); + + if ( (hfont == 0) || + (hfont != this->gdiFont) ) + return E_INVALIDARG; + + this->fontLock++; + + return S_OK; +} + +/************************************************************************ + * OLEFontImpl_ReleaseHfont (IFont) + * + * See Windows documentation for more details on IFont methods. + */ +static HRESULT WINAPI OLEFontImpl_ReleaseHfont( + IFont* iface, + HFONT hfont) +{ + OLEFontImpl *this = (OLEFontImpl *)iface; + TRACE("(%p)->(%p) (lock=%ld)\n", this, hfont, this->fontLock); + + if ( (hfont == 0) || + (hfont != this->gdiFont) ) + return E_INVALIDARG; + + this->fontLock--; + + /* + * If we just released our last font reference, destroy it. + */ + if (this->fontLock==0) + { + DeleteObject(this->gdiFont); + this->gdiFont = 0; + } + + return S_OK; +} + +/************************************************************************ + * OLEFontImpl_SetHdc (IFont) + * + * See Windows documentation for more details on IFont methods. + */ +static HRESULT WINAPI OLEFontImpl_SetHdc( + IFont* iface, + HDC hdc) +{ + OLEFontImpl *this = (OLEFontImpl *)iface; + FIXME("(%p)->(%p): Stub\n", this, hdc); + return E_NOTIMPL; +} + +/************************************************************************ + * OLEFontImpl_IDispatch_QueryInterface (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static HRESULT WINAPI OLEFontImpl_IDispatch_QueryInterface( + IDispatch* iface, + REFIID riid, + VOID** ppvoid) +{ + _ICOM_THIS_From_IDispatch(IFont, iface); + + return IFont_QueryInterface(this, riid, ppvoid); +} + +/************************************************************************ + * OLEFontImpl_IDispatch_Release (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static ULONG WINAPI OLEFontImpl_IDispatch_Release( + IDispatch* iface) +{ + _ICOM_THIS_From_IDispatch(IFont, iface); + + return IFont_Release(this); +} + +/************************************************************************ + * OLEFontImpl_IDispatch_AddRef (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static ULONG WINAPI OLEFontImpl_IDispatch_AddRef( + IDispatch* iface) +{ + _ICOM_THIS_From_IDispatch(IFont, iface); + + return IFont_AddRef(this); +} + +/************************************************************************ + * OLEFontImpl_GetTypeInfoCount (IDispatch) + * + * See Windows documentation for more details on IDispatch methods. + */ +static HRESULT WINAPI OLEFontImpl_GetTypeInfoCount( + IDispatch* iface, + unsigned int* pctinfo) +{ + _ICOM_THIS_From_IDispatch(IFont, iface); + FIXME("(%p)->(%p): Stub\n", this, pctinfo); + + return E_NOTIMPL; +} + +/************************************************************************ + * OLEFontImpl_GetTypeInfo (IDispatch) + * + * See Windows documentation for more details on IDispatch methods. + */ +static HRESULT WINAPI OLEFontImpl_GetTypeInfo( + IDispatch* iface, + UINT iTInfo, + LCID lcid, + ITypeInfo** ppTInfo) +{ + static const WCHAR stdole32tlb[] = {'s','t','d','o','l','e','3','2','.','t','l','b',0}; + ITypeLib *tl; + HRESULT hres; + + _ICOM_THIS_From_IDispatch(OLEFontImpl, iface); + TRACE("(%p, iTInfo=%d, lcid=%04x, %p)\n", this, iTInfo, (int)lcid, ppTInfo); + if (iTInfo != 0) + return E_FAIL; + hres = LoadTypeLib(stdole32tlb, &tl); + if (FAILED(hres)) { + FIXME("Could not load the stdole32.tlb?\n"); + return hres; + } + hres = ITypeLib_GetTypeInfoOfGuid(tl, &IID_IDispatch, ppTInfo); + if (FAILED(hres)) { + FIXME("Did not IDispatch typeinfo from typelib, hres %lx\n",hres); + } + return hres; +} + +/************************************************************************ + * OLEFontImpl_GetIDsOfNames (IDispatch) + * + * See Windows documentation for more details on IDispatch methods. + */ +static HRESULT WINAPI OLEFontImpl_GetIDsOfNames( + IDispatch* iface, + REFIID riid, + LPOLESTR* rgszNames, + UINT cNames, + LCID lcid, + DISPID* rgDispId) +{ + _ICOM_THIS_From_IDispatch(IFont, iface); + FIXME("(%p,%s,%p,%d,%04x,%p), stub!\n", this, debugstr_guid(riid), rgszNames, + cNames, (int)lcid, rgDispId + ); + return E_NOTIMPL; +} + +/************************************************************************ + * OLEFontImpl_Invoke (IDispatch) + * + * See Windows documentation for more details on IDispatch methods. + * + * Note: Do not call _put_Xxx methods, since setting things here + * should not call notify functions as I found out debugging the generic + * MS VB5 installer. + */ +static HRESULT WINAPI OLEFontImpl_Invoke( + IDispatch* iface, + DISPID dispIdMember, + REFIID riid, + LCID lcid, + WORD wFlags, + DISPPARAMS* pDispParams, + VARIANT* pVarResult, + EXCEPINFO* pExepInfo, + UINT* puArgErr) +{ + _ICOM_THIS_From_IDispatch(IFont, iface); + OLEFontImpl *xthis = (OLEFontImpl*)this; + + switch (dispIdMember) { + case DISPID_FONT_NAME: + switch (wFlags) { + case DISPATCH_PROPERTYGET: + case DISPATCH_PROPERTYGET|DISPATCH_METHOD: + V_VT(pVarResult) = VT_BSTR; + return OLEFontImpl_get_Name(this, &V_BSTR(pVarResult)); + case DISPATCH_PROPERTYPUT: { + BSTR name; + BOOL freename; + + if (V_VT(&pDispParams->rgvarg[0]) == VT_DISPATCH) { + IFont *font; + HRESULT hr = S_OK; + + hr = IUnknown_QueryInterface(V_DISPATCH(&pDispParams->rgvarg[0]), &IID_IFont, (void **) &font); + if (FAILED(hr)) + { + FIXME("dispatch value for name property is not an OleFont, returning hr=0x%lx\n", hr); + return hr; + } + + hr = IFont_get_Name(font, &name); /* this allocates a new BSTR so free it later */ + if (FAILED(hr)) return hr; + + IUnknown_Release(font); + + freename = TRUE; + } else if (V_VT(&pDispParams->rgvarg[0]) == VT_BSTR) { + name = V_BSTR(&pDispParams->rgvarg[0]); + freename = FALSE; + } else { + FIXME("app is trying to set name property with a non BSTR, non dispatch value. returning E_FAIL\n"); + return E_FAIL; + } + + TRACE("name is %s\n", debugstr_w(name)); + + if (!xthis->description.lpstrName) + xthis->description.lpstrName = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(name)+1) * sizeof(WCHAR)); + else + xthis->description.lpstrName = HeapReAlloc(GetProcessHeap(), 0, xthis->description.lpstrName, (lstrlenW(name)+1) * sizeof(WCHAR)); + + if (xthis->description.lpstrName==0) + return E_OUTOFMEMORY; + strcpyW(xthis->description.lpstrName, name); + + if (freename) SysFreeString(name); + + return S_OK; + } + } + break; + case DISPID_FONT_BOLD: + switch (wFlags) { + case DISPATCH_PROPERTYGET: + case DISPATCH_PROPERTYGET|DISPATCH_METHOD: + V_VT(pVarResult) = VT_BOOL; + return OLEFontImpl_get_Bold(this, (BOOL*)&V_BOOL(pVarResult)); + case DISPATCH_PROPERTYPUT: + if (V_VT(&pDispParams->rgvarg[0]) != VT_BOOL) { + FIXME("DISPID_FONT_BOLD/put, vt is %d, not VT_BOOL.\n",V_VT(&pDispParams->rgvarg[0])); + return E_FAIL; + } else { + xthis->description.sWeight = V_BOOL(&pDispParams->rgvarg[0]) ? FW_BOLD : FW_NORMAL; + return S_OK; + } + } + break; + case DISPID_FONT_ITALIC: + switch (wFlags) { + case DISPATCH_PROPERTYGET: + case DISPATCH_PROPERTYGET|DISPATCH_METHOD: + V_VT(pVarResult) = VT_BOOL; + return OLEFontImpl_get_Italic(this, (BOOL*)&V_BOOL(pVarResult)); + case DISPATCH_PROPERTYPUT: + if (V_VT(&pDispParams->rgvarg[0]) != VT_BOOL) { + FIXME("DISPID_FONT_ITALIC/put, vt is %d, not VT_BOOL.\n",V_VT(&pDispParams->rgvarg[0])); + return E_FAIL; + } else { + xthis->description.fItalic = V_BOOL(&pDispParams->rgvarg[0]); + return S_OK; + } + } + break; + case DISPID_FONT_UNDER: + switch (wFlags) { + case DISPATCH_PROPERTYGET: + case DISPATCH_PROPERTYGET|DISPATCH_METHOD: + V_VT(pVarResult) = VT_BOOL; + return OLEFontImpl_get_Underline(this, (BOOL*)&V_BOOL(pVarResult)); + case DISPATCH_PROPERTYPUT: + if (V_VT(&pDispParams->rgvarg[0]) != VT_BOOL) { + FIXME("DISPID_FONT_UNDER/put, vt is %d, not VT_BOOL.\n",V_VT(&pDispParams->rgvarg[0])); + return E_FAIL; + } else { + xthis->description.fUnderline = V_BOOL(&pDispParams->rgvarg[0]); + return S_OK; + } + } + break; + case DISPID_FONT_STRIKE: + switch (wFlags) { + case DISPATCH_PROPERTYGET: + case DISPATCH_PROPERTYGET|DISPATCH_METHOD: + V_VT(pVarResult) = VT_BOOL; + return OLEFontImpl_get_Strikethrough(this, (BOOL*)&V_BOOL(pVarResult)); + case DISPATCH_PROPERTYPUT: + if (V_VT(&pDispParams->rgvarg[0]) != VT_BOOL) { + FIXME("DISPID_FONT_STRIKE/put, vt is %d, not VT_BOOL.\n",V_VT(&pDispParams->rgvarg[0])); + return E_FAIL; + } else { + xthis->description.fStrikethrough = V_BOOL(&pDispParams->rgvarg[0]); + return S_OK; + } + } + break; + case DISPID_FONT_SIZE: + switch (wFlags) { + case DISPATCH_PROPERTYPUT: { + assert (pDispParams->cArgs == 1); + xthis->description.cySize.s.Hi = 0; + if (V_VT(&pDispParams->rgvarg[0]) != VT_CY) { + if (V_VT(&pDispParams->rgvarg[0]) == VT_I2) { + xthis->description.cySize.s.Lo = V_I2(&pDispParams->rgvarg[0]) * 10000; + } else { + FIXME("property put for Size with vt %d unsupported!\n",V_VT(&pDispParams->rgvarg[0])); + } + } else { + xthis->description.cySize.s.Lo = V_CY(&pDispParams->rgvarg[0]).s.Lo; + } + return S_OK; + } + case DISPATCH_PROPERTYGET: + case DISPATCH_PROPERTYGET|DISPATCH_METHOD: + V_VT(pVarResult) = VT_CY; + return OLEFontImpl_get_Size(this, &V_CY(pVarResult)); + } + break; + case DISPID_FONT_CHARSET: + switch (wFlags) { + case DISPATCH_PROPERTYPUT: + assert (pDispParams->cArgs == 1); + if (V_VT(&pDispParams->rgvarg[0]) != VT_I2) + FIXME("varg of first disparg is not VT_I2, but %d\n",V_VT(&pDispParams->rgvarg[0])); + xthis->description.sCharset = V_I2(&pDispParams->rgvarg[0]); + return S_OK; + case DISPATCH_PROPERTYGET: + case DISPATCH_PROPERTYGET|DISPATCH_METHOD: + V_VT(pVarResult) = VT_I2; + return OLEFontImpl_get_Charset(this, &V_I2(pVarResult)); + } + break; + } + FIXME("%p->(%ld,%s,%lx,%x,%p,%p,%p,%p), unhandled dispid/flag!\n", + this,dispIdMember,debugstr_guid(riid),lcid, + wFlags,pDispParams,pVarResult,pExepInfo,puArgErr + ); + return S_OK; +} + +/************************************************************************ + * OLEFontImpl_IPersistStream_QueryInterface (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static HRESULT WINAPI OLEFontImpl_IPersistStream_QueryInterface( + IPersistStream* iface, + REFIID riid, + VOID** ppvoid) +{ + _ICOM_THIS_From_IPersistStream(IFont, iface); + + return IFont_QueryInterface(this, riid, ppvoid); +} + +/************************************************************************ + * OLEFontImpl_IPersistStream_Release (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static ULONG WINAPI OLEFontImpl_IPersistStream_Release( + IPersistStream* iface) +{ + _ICOM_THIS_From_IPersistStream(IFont, iface); + + return IFont_Release(this); +} + +/************************************************************************ + * OLEFontImpl_IPersistStream_AddRef (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static ULONG WINAPI OLEFontImpl_IPersistStream_AddRef( + IPersistStream* iface) +{ + _ICOM_THIS_From_IPersistStream(IFont, iface); + + return IFont_AddRef(this); +} + +/************************************************************************ + * OLEFontImpl_GetClassID (IPersistStream) + * + * See Windows documentation for more details on IPersistStream methods. + */ +static HRESULT WINAPI OLEFontImpl_GetClassID( + IPersistStream* iface, + CLSID* pClassID) +{ + TRACE("(%p,%p)\n",iface,pClassID); + if (pClassID==0) + return E_POINTER; + + memcpy(pClassID, &CLSID_StdFont, sizeof(CLSID_StdFont)); + + return S_OK; +} + +/************************************************************************ + * OLEFontImpl_IsDirty (IPersistStream) + * + * See Windows documentation for more details on IPersistStream methods. + */ +static HRESULT WINAPI OLEFontImpl_IsDirty( + IPersistStream* iface) +{ + TRACE("(%p)\n",iface); + return S_OK; +} + +/************************************************************************ + * OLEFontImpl_Load (IPersistStream) + * + * See Windows documentation for more details on IPersistStream methods. + * + * This is the format of the standard font serialization as far as I + * know + * + * Offset Type Value Comment + * 0x0000 Byte Unknown Probably a version number, contains 0x01 + * 0x0001 Short Charset Charset value from the FONTDESC structure + * 0x0003 Byte Attributes Flags defined as follows: + * 00000010 - Italic + * 00000100 - Underline + * 00001000 - Strikethrough + * 0x0004 Short Weight Weight value from FONTDESC structure + * 0x0006 DWORD size "Low" portion of the cySize member of the FONTDESC + * structure/ + * 0x000A Byte name length Length of the font name string (no null character) + * 0x000B String name Name of the font (ASCII, no nul character) + */ +static HRESULT WINAPI OLEFontImpl_Load( + IPersistStream* iface, + IStream* pLoadStream) +{ + char readBuffer[0x100]; + ULONG cbRead; + BYTE bVersion; + BYTE bAttributes; + BYTE bStringSize; + INT len; + + _ICOM_THIS_From_IPersistStream(OLEFontImpl, iface); + + /* + * Read the version byte + */ + IStream_Read(pLoadStream, &bVersion, 1, &cbRead); + + if ( (cbRead!=1) || + (bVersion!=0x01) ) + return E_FAIL; + + /* + * Charset + */ + IStream_Read(pLoadStream, &this->description.sCharset, 2, &cbRead); + + if (cbRead!=2) + return E_FAIL; + + /* + * Attributes + */ + IStream_Read(pLoadStream, &bAttributes, 1, &cbRead); + + if (cbRead!=1) + return E_FAIL; + + this->description.fItalic = (bAttributes & FONTPERSIST_ITALIC) != 0; + this->description.fStrikethrough = (bAttributes & FONTPERSIST_STRIKETHROUGH) != 0; + this->description.fUnderline = (bAttributes & FONTPERSIST_UNDERLINE) != 0; + + /* + * Weight + */ + IStream_Read(pLoadStream, &this->description.sWeight, 2, &cbRead); + + if (cbRead!=2) + return E_FAIL; + + /* + * Size + */ + IStream_Read(pLoadStream, &this->description.cySize.s.Lo, 4, &cbRead); + + if (cbRead!=4) + return E_FAIL; + + this->description.cySize.s.Hi = 0; + + /* + * FontName + */ + IStream_Read(pLoadStream, &bStringSize, 1, &cbRead); + + if (cbRead!=1) + return E_FAIL; + + IStream_Read(pLoadStream, readBuffer, bStringSize, &cbRead); + + if (cbRead!=bStringSize) + return E_FAIL; + + if (this->description.lpstrName!=0) + HeapFree(GetProcessHeap(), 0, this->description.lpstrName); + + len = MultiByteToWideChar( CP_ACP, 0, readBuffer, bStringSize, NULL, 0 ); + this->description.lpstrName = HeapAlloc( GetProcessHeap(), 0, (len+1) * sizeof(WCHAR) ); + MultiByteToWideChar( CP_ACP, 0, readBuffer, bStringSize, this->description.lpstrName, len ); + this->description.lpstrName[len] = 0; + + /* Ensure use of this font causes a new one to be created @@@@ */ + DeleteObject(this->gdiFont); + this->gdiFont = 0; + + return S_OK; +} + +/************************************************************************ + * OLEFontImpl_Save (IPersistStream) + * + * See Windows documentation for more details on IPersistStream methods. + */ +static HRESULT WINAPI OLEFontImpl_Save( + IPersistStream* iface, + IStream* pOutStream, + BOOL fClearDirty) +{ + char* writeBuffer = NULL; + ULONG cbWritten; + BYTE bVersion = 0x01; + BYTE bAttributes; + BYTE bStringSize; + + _ICOM_THIS_From_IPersistStream(OLEFontImpl, iface); + + /* + * Read the version byte + */ + IStream_Write(pOutStream, &bVersion, 1, &cbWritten); + + if (cbWritten!=1) + return E_FAIL; + + /* + * Charset + */ + IStream_Write(pOutStream, &this->description.sCharset, 2, &cbWritten); + + if (cbWritten!=2) + return E_FAIL; + + /* + * Attributes + */ + bAttributes = 0; + + if (this->description.fItalic) + bAttributes |= FONTPERSIST_ITALIC; + + if (this->description.fStrikethrough) + bAttributes |= FONTPERSIST_STRIKETHROUGH; + + if (this->description.fUnderline) + bAttributes |= FONTPERSIST_UNDERLINE; + + IStream_Write(pOutStream, &bAttributes, 1, &cbWritten); + + if (cbWritten!=1) + return E_FAIL; + + /* + * Weight + */ + IStream_Write(pOutStream, &this->description.sWeight, 2, &cbWritten); + + if (cbWritten!=2) + return E_FAIL; + + /* + * Size + */ + IStream_Write(pOutStream, &this->description.cySize.s.Lo, 4, &cbWritten); + + if (cbWritten!=4) + return E_FAIL; + + /* + * FontName + */ + if (this->description.lpstrName!=0) + bStringSize = WideCharToMultiByte( CP_ACP, 0, this->description.lpstrName, + strlenW(this->description.lpstrName), NULL, 0, NULL, NULL ); + else + bStringSize = 0; + + IStream_Write(pOutStream, &bStringSize, 1, &cbWritten); + + if (cbWritten!=1) + return E_FAIL; + + if (bStringSize!=0) + { + if (!(writeBuffer = HeapAlloc( GetProcessHeap(), 0, bStringSize ))) return E_OUTOFMEMORY; + WideCharToMultiByte( CP_ACP, 0, this->description.lpstrName, + strlenW(this->description.lpstrName), + writeBuffer, bStringSize, NULL, NULL ); + + IStream_Write(pOutStream, writeBuffer, bStringSize, &cbWritten); + HeapFree(GetProcessHeap(), 0, writeBuffer); + + if (cbWritten!=bStringSize) + return E_FAIL; + } + + return S_OK; +} + +/************************************************************************ + * OLEFontImpl_GetSizeMax (IPersistStream) + * + * See Windows documentation for more details on IPersistStream methods. + */ +static HRESULT WINAPI OLEFontImpl_GetSizeMax( + IPersistStream* iface, + ULARGE_INTEGER* pcbSize) +{ + _ICOM_THIS_From_IPersistStream(OLEFontImpl, iface); + + if (pcbSize==NULL) + return E_POINTER; + + pcbSize->u.HighPart = 0; + pcbSize->u.LowPart = 0; + + pcbSize->u.LowPart += sizeof(BYTE); /* Version */ + pcbSize->u.LowPart += sizeof(WORD); /* Lang code */ + pcbSize->u.LowPart += sizeof(BYTE); /* Flags */ + pcbSize->u.LowPart += sizeof(WORD); /* Weight */ + pcbSize->u.LowPart += sizeof(DWORD); /* Size */ + pcbSize->u.LowPart += sizeof(BYTE); /* StrLength */ + + if (this->description.lpstrName!=0) + pcbSize->u.LowPart += lstrlenW(this->description.lpstrName); + + return S_OK; +} + +/************************************************************************ + * OLEFontImpl_IConnectionPointContainer_QueryInterface (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static HRESULT WINAPI OLEFontImpl_IConnectionPointContainer_QueryInterface( + IConnectionPointContainer* iface, + REFIID riid, + VOID** ppvoid) +{ + _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface); + + return IFont_QueryInterface((IFont*)this, riid, ppvoid); +} + +/************************************************************************ + * OLEFontImpl_IConnectionPointContainer_Release (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_Release( + IConnectionPointContainer* iface) +{ + _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface); + + return IFont_Release((IFont*)this); +} + +/************************************************************************ + * OLEFontImpl_IConnectionPointContainer_AddRef (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_AddRef( + IConnectionPointContainer* iface) +{ + _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface); + + return IFont_AddRef((IFont*)this); +} + +/************************************************************************ + * OLEFontImpl_EnumConnectionPoints (IConnectionPointContainer) + * + * See Windows documentation for more details on IConnectionPointContainer + * methods. + */ +static HRESULT WINAPI OLEFontImpl_EnumConnectionPoints( + IConnectionPointContainer* iface, + IEnumConnectionPoints **ppEnum) +{ + _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface); + + FIXME("(%p)->(%p): stub\n", this, ppEnum); + return E_NOTIMPL; +} + +/************************************************************************ + * OLEFontImpl_FindConnectionPoint (IConnectionPointContainer) + * + * See Windows documentation for more details on IConnectionPointContainer + * methods. + */ +static HRESULT WINAPI OLEFontImpl_FindConnectionPoint( + IConnectionPointContainer* iface, + REFIID riid, + IConnectionPoint **ppCp) +{ + _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface); + TRACE("(%p)->(%s, %p): stub\n", this, debugstr_guid(riid), ppCp); + + if(memcmp(riid, &IID_IPropertyNotifySink, sizeof(IID_IPropertyNotifySink)) == 0) { + return IConnectionPoint_QueryInterface(this->pCP, &IID_IConnectionPoint, + (LPVOID)ppCp); + } else { + FIXME("Tried to find connection point on %s\n", debugstr_guid(riid)); + return E_NOINTERFACE; + } +} + +/************************************************************************ + * OLEFontImpl implementation of IPersistPropertyBag. + */ +static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_QueryInterface( + IPersistPropertyBag *iface, REFIID riid, LPVOID *ppvObj +) { + _ICOM_THIS_From_IPersistPropertyBag(IFont, iface); + return IFont_QueryInterface(this,riid,ppvObj); +} + +static ULONG WINAPI OLEFontImpl_IPersistPropertyBag_AddRef( + IPersistPropertyBag *iface +) { + _ICOM_THIS_From_IPersistPropertyBag(IFont, iface); + return IFont_AddRef(this); +} + +static ULONG WINAPI OLEFontImpl_IPersistPropertyBag_Release( + IPersistPropertyBag *iface +) { + _ICOM_THIS_From_IPersistPropertyBag(IFont, iface); + return IFont_Release(this); +} + +static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_GetClassID( + IPersistPropertyBag *iface, CLSID *classid +) { + FIXME("(%p,%p), stub!\n", iface, classid); + return E_FAIL; +} + +static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_InitNew( + IPersistPropertyBag *iface +) { + FIXME("(%p), stub!\n", iface); + return S_OK; +} + +static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_Load( + IPersistPropertyBag *iface, IPropertyBag* pPropBag, IErrorLog* pErrorLog +) { +/* (from Visual Basic 6 property bag) + Name = "MS Sans Serif" + Size = 13.8 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False +*/ + static const WCHAR sAttrName[] = {'N','a','m','e',0}; + static const WCHAR sAttrSize[] = {'S','i','z','e',0}; + static const WCHAR sAttrCharset[] = {'C','h','a','r','s','e','t',0}; + static const WCHAR sAttrWeight[] = {'W','e','i','g','h','t',0}; + static const WCHAR sAttrUnderline[] = {'U','n','d','e','r','l','i','n','e',0}; + static const WCHAR sAttrItalic[] = {'I','t','a','l','i','c',0}; + static const WCHAR sAttrStrikethrough[] = {'S','t','r','i','k','e','t','h','r','o','u','g','h',0}; + VARIANT rawAttr; + VARIANT valueAttr; + HRESULT iRes = S_OK; + _ICOM_THIS_From_IPersistPropertyBag(IFont, iface); + + VariantInit(&rawAttr); + VariantInit(&valueAttr); + + if (iRes == S_OK) { + iRes = IPropertyBag_Read(pPropBag, sAttrName, &rawAttr, pErrorLog); + if (iRes == S_OK) + { + iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_BSTR); + if (iRes == S_OK) + iRes = IFont_put_Name(this, V_BSTR(&valueAttr)); + } + else if (iRes == E_INVALIDARG) + iRes = S_OK; + VariantClear(&rawAttr); + VariantClear(&valueAttr); + } + + if (iRes == S_OK) { + iRes = IPropertyBag_Read(pPropBag, sAttrSize, &rawAttr, pErrorLog); + if (iRes == S_OK) + { + iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_CY); + if (iRes == S_OK) + iRes = IFont_put_Size(this, V_CY(&valueAttr)); + } + else if (iRes == E_INVALIDARG) + iRes = S_OK; + VariantClear(&rawAttr); + VariantClear(&valueAttr); + } + + if (iRes == S_OK) { + iRes = IPropertyBag_Read(pPropBag, sAttrCharset, &rawAttr, pErrorLog); + if (iRes == S_OK) + { + iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_I2); + if (iRes == S_OK) + iRes = IFont_put_Charset(this, V_I2(&valueAttr)); + } + else if (iRes == E_INVALIDARG) + iRes = S_OK; + VariantClear(&rawAttr); + VariantClear(&valueAttr); + } + + if (iRes == S_OK) { + iRes = IPropertyBag_Read(pPropBag, sAttrWeight, &rawAttr, pErrorLog); + if (iRes == S_OK) + { + iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_I2); + if (iRes == S_OK) + iRes = IFont_put_Weight(this, V_I2(&valueAttr)); + } + else if (iRes == E_INVALIDARG) + iRes = S_OK; + VariantClear(&rawAttr); + VariantClear(&valueAttr); + + } + + if (iRes == S_OK) { + iRes = IPropertyBag_Read(pPropBag, sAttrUnderline, &rawAttr, pErrorLog); + if (iRes == S_OK) + { + iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_BOOL); + if (iRes == S_OK) + iRes = IFont_put_Underline(this, V_BOOL(&valueAttr)); + } + else if (iRes == E_INVALIDARG) + iRes = S_OK; + VariantClear(&rawAttr); + VariantClear(&valueAttr); + } + + if (iRes == S_OK) { + iRes = IPropertyBag_Read(pPropBag, sAttrItalic, &rawAttr, pErrorLog); + if (iRes == S_OK) + { + iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_BOOL); + if (iRes == S_OK) + iRes = IFont_put_Italic(this, V_BOOL(&valueAttr)); + } + else if (iRes == E_INVALIDARG) + iRes = S_OK; + VariantClear(&rawAttr); + VariantClear(&valueAttr); + } + + if (iRes == S_OK) { + iRes = IPropertyBag_Read(pPropBag, sAttrStrikethrough, &rawAttr, pErrorLog); + if (iRes == S_OK) + { + iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_BOOL); + if (iRes == S_OK) + IFont_put_Strikethrough(this, V_BOOL(&valueAttr)); + } + else if (iRes == E_INVALIDARG) + iRes = S_OK; + VariantClear(&rawAttr); + VariantClear(&valueAttr); + } + + if (FAILED(iRes)) + WARN("-- 0x%08lx\n", iRes); + return iRes; +} + +static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_Save( + IPersistPropertyBag *iface, IPropertyBag* pPropBag, BOOL fClearDirty, + BOOL fSaveAllProperties +) { + FIXME("(%p,%p,%d,%d), stub!\n", iface, pPropBag, fClearDirty, fSaveAllProperties); + return E_FAIL; +} + +static IPersistPropertyBagVtbl OLEFontImpl_IPersistPropertyBag_VTable = +{ + OLEFontImpl_IPersistPropertyBag_QueryInterface, + OLEFontImpl_IPersistPropertyBag_AddRef, + OLEFontImpl_IPersistPropertyBag_Release, + + OLEFontImpl_IPersistPropertyBag_GetClassID, + OLEFontImpl_IPersistPropertyBag_InitNew, + OLEFontImpl_IPersistPropertyBag_Load, + OLEFontImpl_IPersistPropertyBag_Save +}; + +/************************************************************************ + * OLEFontImpl implementation of IPersistStreamInit. + */ +static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_QueryInterface( + IPersistStreamInit *iface, REFIID riid, LPVOID *ppvObj +) { + _ICOM_THIS_From_IPersistStreamInit(IFont, iface); + return IFont_QueryInterface(this,riid,ppvObj); +} + +static ULONG WINAPI OLEFontImpl_IPersistStreamInit_AddRef( + IPersistStreamInit *iface +) { + _ICOM_THIS_From_IPersistStreamInit(IFont, iface); + return IFont_AddRef(this); +} + +static ULONG WINAPI OLEFontImpl_IPersistStreamInit_Release( + IPersistStreamInit *iface +) { + _ICOM_THIS_From_IPersistStreamInit(IFont, iface); + return IFont_Release(this); +} + +static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_GetClassID( + IPersistStreamInit *iface, CLSID *classid +) { + FIXME("(%p,%p), stub!\n", iface, classid); + return E_FAIL; +} + +static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_IsDirty( + IPersistStreamInit *iface +) { + FIXME("(%p), stub!\n", iface); + return E_FAIL; +} + +static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_Load( + IPersistStreamInit *iface, LPSTREAM pStm +) { + FIXME("(%p,%p), stub!\n", iface, pStm); + return E_FAIL; +} + +static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_Save( + IPersistStreamInit *iface, LPSTREAM pStm, BOOL fClearDirty +) { + FIXME("(%p,%p,%d), stub!\n", iface, pStm, fClearDirty); + return E_FAIL; +} + +static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_GetSizeMax( + IPersistStreamInit *iface, ULARGE_INTEGER *pcbSize +) { + FIXME("(%p,%p), stub!\n", iface, pcbSize); + return E_FAIL; +} + +static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_InitNew( + IPersistStreamInit *iface +) { + FIXME("(%p), stub!\n", iface); + return S_OK; +} + +static IPersistStreamInitVtbl OLEFontImpl_IPersistStreamInit_VTable = +{ + OLEFontImpl_IPersistStreamInit_QueryInterface, + OLEFontImpl_IPersistStreamInit_AddRef, + OLEFontImpl_IPersistStreamInit_Release, + + OLEFontImpl_IPersistStreamInit_GetClassID, + OLEFontImpl_IPersistStreamInit_IsDirty, + OLEFontImpl_IPersistStreamInit_Load, + OLEFontImpl_IPersistStreamInit_Save, + OLEFontImpl_IPersistStreamInit_GetSizeMax, + OLEFontImpl_IPersistStreamInit_InitNew +}; + +/******************************************************************************* + * StdFont ClassFactory + */ +typedef struct +{ + /* IUnknown fields */ + IClassFactoryVtbl *lpVtbl; + DWORD ref; +} IClassFactoryImpl; + +static HRESULT WINAPI +SFCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) { + IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + + FIXME("(%p)->(%s,%p),stub!\n",This,debugstr_guid(riid),ppobj); + return E_NOINTERFACE; +} + +static ULONG WINAPI +SFCF_AddRef(LPCLASSFACTORY iface) { + IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + return InterlockedIncrement(&This->ref); +} + +static ULONG WINAPI SFCF_Release(LPCLASSFACTORY iface) { + IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + /* static class, won't be freed */ + return InterlockedDecrement(&This->ref); +} + +static HRESULT WINAPI SFCF_CreateInstance( + LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj +) { + return OleCreateFontIndirect(NULL,riid,ppobj); + +} + +static HRESULT WINAPI SFCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) { + IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + FIXME("(%p)->(%d),stub!\n",This,dolock); + return S_OK; +} + +static IClassFactoryVtbl SFCF_Vtbl = { + SFCF_QueryInterface, + SFCF_AddRef, + SFCF_Release, + SFCF_CreateInstance, + SFCF_LockServer +}; +static IClassFactoryImpl STDFONT_CF = {&SFCF_Vtbl, 1 }; + +void _get_STDFONT_CF(LPVOID *ppv) { *ppv = (LPVOID)&STDFONT_CF; } diff --git a/reactos/lib/oleaut32/olepicture.c b/reactos/lib/oleaut32/olepicture.c new file mode 100644 index 00000000000..317ae0730b4 --- /dev/null +++ b/reactos/lib/oleaut32/olepicture.c @@ -0,0 +1,2046 @@ +/* + * OLE Picture object + * + * Implementation of OLE IPicture and related interfaces + * + * Copyright 2000 Huw D M Davies for CodeWeavers. + * Copyright 2001 Marcus Meissner + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * BUGS + * + * Support PICTYPE_BITMAP and PICTYPE_ICON, altough only bitmaps very well.. + * Lots of methods are just stubs. + * + * + * NOTES (or things that msdn doesn't tell you) + * + * The width and height properties are returned in HIMETRIC units (0.01mm) + * IPicture::Render also uses these to select a region of the src picture. + * A bitmap's size is converted into these units by using the screen resolution + * thus an 8x8 bitmap on a 96dpi screen has a size of 212x212 (8/96 * 2540). + * + */ + +#include "config.h" +#include "wine/port.h" + +#ifdef HAVE_UNISTD_H +# include +#endif +#include +#include +#include + +/* Must be before wine includes, the header has things conflicting with + * WINE headers. + */ +#ifdef HAVE_GIF_LIB_H +# include +# ifndef SONAME_LIBUNGIF +# define SONAME_LIBUNGIF "libungif.so" +# endif +# ifndef SONAME_LIBGIF +# define SONAME_LIBGIF "libgif.so" +# endif +#endif + +#define COBJMACROS +#define NONAMELESSUNION +#define NONAMELESSSTRUCT + +#include "winerror.h" +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" +#include "ole2.h" +#include "olectl.h" +#include "oleauto.h" +#include "connpt.h" +#include "wine/debug.h" + +#include "wine/wingdi16.h" +#include "cursoricon.h" + +#ifdef HAVE_JPEGLIB_H +/* This is a hack, so jpeglib.h does not redefine INT32 and the like*/ +#define XMD_H +#define UINT8 JPEG_UINT8 +#define UINT16 JPEG_UINT16 +#undef FAR +# include +#undef UINT16 +#ifndef SONAME_LIBJPEG +#define SONAME_LIBJPEG "libjpeg.so" +#endif +#endif + +WINE_DEFAULT_DEBUG_CHANNEL(ole); + +/************************************************************************* + * Declaration of implementation class + */ + +typedef struct OLEPictureImpl { + + /* + * IPicture handles IUnknown + */ + + IPictureVtbl *lpvtbl1; + IDispatchVtbl *lpvtbl2; + IPersistStreamVtbl *lpvtbl3; + IConnectionPointContainerVtbl *lpvtbl4; + + /* Object referenece count */ + DWORD ref; + + /* We own the object and must destroy it ourselves */ + BOOL fOwn; + + /* Picture description */ + PICTDESC desc; + + /* These are the pixel size of a bitmap */ + DWORD origWidth; + DWORD origHeight; + + /* And these are the size of the picture converted into HIMETRIC units */ + OLE_XSIZE_HIMETRIC himetricWidth; + OLE_YSIZE_HIMETRIC himetricHeight; + + IConnectionPoint *pCP; + + BOOL keepOrigFormat; + HDC hDCCur; + + /* Bitmap transparency mask */ + HBITMAP hbmMask; + COLORREF rgbTrans; + + /* data */ + void* data; + int datalen; + BOOL bIsDirty; /* Set to TRUE if picture has changed */ + unsigned int loadtime_magic; /* If a length header was found, saves value */ + unsigned int loadtime_format; /* for PICTYPE_BITMAP only, keeps track of image format (GIF/BMP/JPEG) */ +} OLEPictureImpl; + +/* + * Macros to retrieve pointer to IUnknown (IPicture) from the other VTables. + */ +#define ICOM_THIS_From_IDispatch(impl, name) \ + impl *This = (impl*)(((char*)name)-sizeof(void*)); +#define ICOM_THIS_From_IPersistStream(impl, name) \ + impl *This = (impl*)(((char*)name)-2*sizeof(void*)); +#define ICOM_THIS_From_IConnectionPointContainer(impl, name) \ + impl *This = (impl*)(((char*)name)-3*sizeof(void*)); + +/* + * Predeclare VTables. They get initialized at the end. + */ +static IPictureVtbl OLEPictureImpl_VTable; +static IDispatchVtbl OLEPictureImpl_IDispatch_VTable; +static IPersistStreamVtbl OLEPictureImpl_IPersistStream_VTable; +static IConnectionPointContainerVtbl OLEPictureImpl_IConnectionPointContainer_VTable; + +/*********************************************************************** + * Implementation of the OLEPictureImpl class. + */ + +static void OLEPictureImpl_SetBitmap(OLEPictureImpl*This) { + BITMAP bm; + HDC hdcRef; + + TRACE("bitmap handle %p\n", This->desc.u.bmp.hbitmap); + if(GetObjectA(This->desc.u.bmp.hbitmap, sizeof(bm), &bm) != sizeof(bm)) { + ERR("GetObject fails\n"); + return; + } + This->origWidth = bm.bmWidth; + This->origHeight = bm.bmHeight; + /* The width and height are stored in HIMETRIC units (0.01 mm), + so we take our pixel width divide by pixels per inch and + multiply by 25.4 * 100 */ + /* Should we use GetBitmapDimension if available? */ + hdcRef = CreateCompatibleDC(0); + This->himetricWidth =(bm.bmWidth *2540)/GetDeviceCaps(hdcRef, LOGPIXELSX); + This->himetricHeight=(bm.bmHeight*2540)/GetDeviceCaps(hdcRef, LOGPIXELSY); + DeleteDC(hdcRef); +} + +/************************************************************************ + * OLEPictureImpl_Construct + * + * This method will construct a new instance of the OLEPictureImpl + * class. + * + * The caller of this method must release the object when it's + * done with it. + */ +static OLEPictureImpl* OLEPictureImpl_Construct(LPPICTDESC pictDesc, BOOL fOwn) +{ + OLEPictureImpl* newObject = 0; + + if (pictDesc) + TRACE("(%p) type = %d\n", pictDesc, pictDesc->picType); + + /* + * Allocate space for the object. + */ + newObject = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(OLEPictureImpl)); + + if (newObject==0) + return newObject; + + /* + * Initialize the virtual function table. + */ + newObject->lpvtbl1 = &OLEPictureImpl_VTable; + newObject->lpvtbl2 = &OLEPictureImpl_IDispatch_VTable; + newObject->lpvtbl3 = &OLEPictureImpl_IPersistStream_VTable; + newObject->lpvtbl4 = &OLEPictureImpl_IConnectionPointContainer_VTable; + + CreateConnectionPoint((IUnknown*)newObject,&IID_IPropertyNotifySink,&newObject->pCP); + + /* + * Start with one reference count. The caller of this function + * must release the interface pointer when it is done. + */ + newObject->ref = 1; + newObject->hDCCur = 0; + + newObject->fOwn = fOwn; + + /* dunno about original value */ + newObject->keepOrigFormat = TRUE; + + newObject->hbmMask = NULL; + newObject->loadtime_magic = 0xdeadbeef; + newObject->loadtime_format = 0; + newObject->bIsDirty = FALSE; + + if (pictDesc) { + if(pictDesc->cbSizeofstruct != sizeof(PICTDESC)) { + FIXME("struct size = %d\n", pictDesc->cbSizeofstruct); + } + memcpy(&newObject->desc, pictDesc, sizeof(PICTDESC)); + + + switch(pictDesc->picType) { + case PICTYPE_BITMAP: + OLEPictureImpl_SetBitmap(newObject); + break; + + case PICTYPE_METAFILE: + TRACE("metafile handle %p\n", pictDesc->u.wmf.hmeta); + newObject->himetricWidth = pictDesc->u.wmf.xExt; + newObject->himetricHeight = pictDesc->u.wmf.yExt; + break; + + case PICTYPE_NONE: + /* not sure what to do here */ + newObject->himetricWidth = newObject->himetricHeight = 0; + break; + + case PICTYPE_ICON: + case PICTYPE_ENHMETAFILE: + default: + FIXME("Unsupported type %d\n", pictDesc->picType); + newObject->himetricWidth = newObject->himetricHeight = 0; + break; + } + } else { + newObject->desc.picType = PICTYPE_UNINITIALIZED; + } + + TRACE("returning %p\n", newObject); + return newObject; +} + +/************************************************************************ + * OLEPictureImpl_Destroy + * + * This method is called by the Release method when the reference + * count goes down to 0. It will free all resources used by + * this object. */ +static void OLEPictureImpl_Destroy(OLEPictureImpl* Obj) +{ + TRACE("(%p)\n", Obj); + + if(Obj->fOwn) { /* We need to destroy the picture */ + switch(Obj->desc.picType) { + case PICTYPE_BITMAP: + DeleteObject(Obj->desc.u.bmp.hbitmap); + break; + case PICTYPE_METAFILE: + DeleteMetaFile(Obj->desc.u.wmf.hmeta); + break; + case PICTYPE_ICON: + DestroyIcon(Obj->desc.u.icon.hicon); + break; + case PICTYPE_ENHMETAFILE: + DeleteEnhMetaFile(Obj->desc.u.emf.hemf); + break; + default: + FIXME("Unsupported type %d - unable to delete\n", Obj->desc.picType); + break; + } + } + if (Obj->data) HeapFree(GetProcessHeap(), 0, Obj->data); + HeapFree(GetProcessHeap(), 0, Obj); +} + +static ULONG WINAPI OLEPictureImpl_AddRef(IPicture* iface); + +/************************************************************************ + * OLEPictureImpl_QueryInterface (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static HRESULT WINAPI OLEPictureImpl_QueryInterface( + IPicture* iface, + REFIID riid, + void** ppvObject) +{ + OLEPictureImpl *This = (OLEPictureImpl *)iface; + TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppvObject); + + /* + * Perform a sanity check on the parameters. + */ + if ( (This==0) || (ppvObject==0) ) + return E_INVALIDARG; + + /* + * Initialize the return parameter. + */ + *ppvObject = 0; + + /* + * Compare the riid with the interface IDs implemented by this object. + */ + if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0) + { + *ppvObject = (IPicture*)This; + } + else if (memcmp(&IID_IPicture, riid, sizeof(IID_IPicture)) == 0) + { + *ppvObject = (IPicture*)This; + } + else if (memcmp(&IID_IDispatch, riid, sizeof(IID_IDispatch)) == 0) + { + *ppvObject = (IDispatch*)&(This->lpvtbl2); + } + else if (memcmp(&IID_IPictureDisp, riid, sizeof(IID_IPictureDisp)) == 0) + { + *ppvObject = (IDispatch*)&(This->lpvtbl2); + } + else if (memcmp(&IID_IPersistStream, riid, sizeof(IID_IPersistStream)) == 0) + { + *ppvObject = (IPersistStream*)&(This->lpvtbl3); + } + else if (memcmp(&IID_IConnectionPointContainer, riid, sizeof(IID_IConnectionPointContainer)) == 0) + { + *ppvObject = (IConnectionPointContainer*)&(This->lpvtbl4); + } + /* + * Check that we obtained an interface. + */ + if ((*ppvObject)==0) + { + FIXME("() : asking for un supported interface %s\n",debugstr_guid(riid)); + return E_NOINTERFACE; + } + + /* + * Query Interface always increases the reference count by one when it is + * successful + */ + OLEPictureImpl_AddRef((IPicture*)This); + + return S_OK; +} +/*********************************************************************** + * OLEPicture_SendNotify (internal) + * + * Sends notification messages of changed properties to any interested + * connections. + */ +static void OLEPicture_SendNotify(OLEPictureImpl* this, DISPID dispID) +{ + IEnumConnections *pEnum; + CONNECTDATA CD; + + if (IConnectionPoint_EnumConnections(this->pCP, &pEnum)) + return; + while(IEnumConnections_Next(pEnum, 1, &CD, NULL) == S_OK) { + IPropertyNotifySink *sink; + + IUnknown_QueryInterface(CD.pUnk, &IID_IPropertyNotifySink, (LPVOID)&sink); + IPropertyNotifySink_OnChanged(sink, dispID); + IPropertyNotifySink_Release(sink); + IUnknown_Release(CD.pUnk); + } + IEnumConnections_Release(pEnum); + return; +} + +/************************************************************************ + * OLEPictureImpl_AddRef (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static ULONG WINAPI OLEPictureImpl_AddRef( + IPicture* iface) +{ + OLEPictureImpl *This = (OLEPictureImpl *)iface; + TRACE("(%p)->(ref=%ld)\n", This, This->ref); + return InterlockedIncrement(&This->ref); +} + +/************************************************************************ + * OLEPictureImpl_Release (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static ULONG WINAPI OLEPictureImpl_Release( + IPicture* iface) +{ + OLEPictureImpl *This = (OLEPictureImpl *)iface; + ULONG ret; + TRACE("(%p)->(ref=%ld)\n", This, This->ref); + + /* + * Decrease the reference count on this object. + */ + ret = InterlockedDecrement(&This->ref); + + /* + * If the reference count goes down to 0, perform suicide. + */ + if (ret==0) OLEPictureImpl_Destroy(This); + + return ret; +} + + +/************************************************************************ + * OLEPictureImpl_get_Handle + */ +static HRESULT WINAPI OLEPictureImpl_get_Handle(IPicture *iface, + OLE_HANDLE *phandle) +{ + OLEPictureImpl *This = (OLEPictureImpl *)iface; + TRACE("(%p)->(%p)\n", This, phandle); + switch(This->desc.picType) { + case PICTYPE_BITMAP: + *phandle = (OLE_HANDLE)This->desc.u.bmp.hbitmap; + break; + case PICTYPE_METAFILE: + *phandle = (OLE_HANDLE)This->desc.u.wmf.hmeta; + break; + case PICTYPE_ICON: + *phandle = (OLE_HANDLE)This->desc.u.icon.hicon; + break; + case PICTYPE_ENHMETAFILE: + *phandle = (OLE_HANDLE)This->desc.u.emf.hemf; + break; + default: + FIXME("Unimplemented type %d\n", This->desc.picType); + return E_NOTIMPL; + } + TRACE("returning handle %08x\n", *phandle); + return S_OK; +} + +/************************************************************************ + * OLEPictureImpl_get_hPal + */ +static HRESULT WINAPI OLEPictureImpl_get_hPal(IPicture *iface, + OLE_HANDLE *phandle) +{ + OLEPictureImpl *This = (OLEPictureImpl *)iface; + FIXME("(%p)->(%p): stub\n", This, phandle); + return E_NOTIMPL; +} + +/************************************************************************ + * OLEPictureImpl_get_Type + */ +static HRESULT WINAPI OLEPictureImpl_get_Type(IPicture *iface, + short *ptype) +{ + OLEPictureImpl *This = (OLEPictureImpl *)iface; + TRACE("(%p)->(%p): type is %d\n", This, ptype, This->desc.picType); + *ptype = This->desc.picType; + return S_OK; +} + +/************************************************************************ + * OLEPictureImpl_get_Width + */ +static HRESULT WINAPI OLEPictureImpl_get_Width(IPicture *iface, + OLE_XSIZE_HIMETRIC *pwidth) +{ + OLEPictureImpl *This = (OLEPictureImpl *)iface; + TRACE("(%p)->(%p): width is %ld\n", This, pwidth, This->himetricWidth); + *pwidth = This->himetricWidth; + return S_OK; +} + +/************************************************************************ + * OLEPictureImpl_get_Height + */ +static HRESULT WINAPI OLEPictureImpl_get_Height(IPicture *iface, + OLE_YSIZE_HIMETRIC *pheight) +{ + OLEPictureImpl *This = (OLEPictureImpl *)iface; + TRACE("(%p)->(%p): height is %ld\n", This, pheight, This->himetricHeight); + *pheight = This->himetricHeight; + return S_OK; +} + +/************************************************************************ + * OLEPictureImpl_Render + */ +static HRESULT WINAPI OLEPictureImpl_Render(IPicture *iface, HDC hdc, + LONG x, LONG y, LONG cx, LONG cy, + OLE_XPOS_HIMETRIC xSrc, + OLE_YPOS_HIMETRIC ySrc, + OLE_XSIZE_HIMETRIC cxSrc, + OLE_YSIZE_HIMETRIC cySrc, + LPCRECT prcWBounds) +{ + OLEPictureImpl *This = (OLEPictureImpl *)iface; + TRACE("(%p)->(%p, (%ld,%ld), (%ld,%ld) <- (%ld,%ld), (%ld,%ld), %p)\n", + This, hdc, x, y, cx, cy, xSrc, ySrc, cxSrc, cySrc, prcWBounds); + if(prcWBounds) + TRACE("prcWBounds (%ld,%ld) - (%ld,%ld)\n", prcWBounds->left, prcWBounds->top, + prcWBounds->right, prcWBounds->bottom); + + /* + * While the documentation suggests this to be here (or after rendering?) + * it does cause an endless recursion in my sample app. -MM 20010804 + OLEPicture_SendNotify(This,DISPID_PICT_RENDER); + */ + + switch(This->desc.picType) { + case PICTYPE_BITMAP: + { + HBITMAP hbmpOld; + HDC hdcBmp; + + /* Set a mapping mode that maps bitmap pixels into HIMETRIC units. + NB y-axis gets flipped */ + + hdcBmp = CreateCompatibleDC(0); + SetMapMode(hdcBmp, MM_ANISOTROPIC); + SetWindowOrgEx(hdcBmp, 0, 0, NULL); + SetWindowExtEx(hdcBmp, This->himetricWidth, This->himetricHeight, NULL); + SetViewportOrgEx(hdcBmp, 0, This->origHeight, NULL); + SetViewportExtEx(hdcBmp, This->origWidth, -This->origHeight, NULL); + + hbmpOld = SelectObject(hdcBmp, This->desc.u.bmp.hbitmap); + + if (This->hbmMask) { + HDC hdcMask = CreateCompatibleDC(0); + HBITMAP hOldbm = SelectObject(hdcMask, This->hbmMask); + + SetMapMode(hdcMask, MM_ANISOTROPIC); + SetWindowOrgEx(hdcMask, 0, 0, NULL); + SetWindowExtEx(hdcMask, This->himetricWidth, This->himetricHeight, NULL); + SetViewportOrgEx(hdcMask, 0, This->origHeight, NULL); + SetViewportExtEx(hdcMask, This->origWidth, -This->origHeight, NULL); + + SetBkColor(hdc, RGB(255, 255, 255)); + SetTextColor(hdc, RGB(0, 0, 0)); + StretchBlt(hdc, x, y, cx, cy, hdcMask, xSrc, ySrc, cxSrc, cySrc, SRCAND); + StretchBlt(hdc, x, y, cx, cy, hdcBmp, xSrc, ySrc, cxSrc, cySrc, SRCPAINT); + + SelectObject(hdcMask, hOldbm); + DeleteDC(hdcMask); + } else + StretchBlt(hdc, x, y, cx, cy, hdcBmp, xSrc, ySrc, cxSrc, cySrc, SRCCOPY); + + SelectObject(hdcBmp, hbmpOld); + DeleteDC(hdcBmp); + } + break; + case PICTYPE_ICON: + FIXME("Not quite correct implementation of rendering icons...\n"); + DrawIcon(hdc,x,y,This->desc.u.icon.hicon); + break; + + case PICTYPE_METAFILE: + case PICTYPE_ENHMETAFILE: + default: + FIXME("type %d not implemented\n", This->desc.picType); + return E_NOTIMPL; + } + return S_OK; +} + +/************************************************************************ + * OLEPictureImpl_set_hPal + */ +static HRESULT WINAPI OLEPictureImpl_set_hPal(IPicture *iface, + OLE_HANDLE hpal) +{ + OLEPictureImpl *This = (OLEPictureImpl *)iface; + FIXME("(%p)->(%08x): stub\n", This, hpal); + OLEPicture_SendNotify(This,DISPID_PICT_HPAL); + return E_NOTIMPL; +} + +/************************************************************************ + * OLEPictureImpl_get_CurDC + */ +static HRESULT WINAPI OLEPictureImpl_get_CurDC(IPicture *iface, + HDC *phdc) +{ + OLEPictureImpl *This = (OLEPictureImpl *)iface; + TRACE("(%p), returning %p\n", This, This->hDCCur); + if (phdc) *phdc = This->hDCCur; + return S_OK; +} + +/************************************************************************ + * OLEPictureImpl_SelectPicture + */ +static HRESULT WINAPI OLEPictureImpl_SelectPicture(IPicture *iface, + HDC hdcIn, + HDC *phdcOut, + OLE_HANDLE *phbmpOut) +{ + OLEPictureImpl *This = (OLEPictureImpl *)iface; + TRACE("(%p)->(%p, %p, %p)\n", This, hdcIn, phdcOut, phbmpOut); + if (This->desc.picType == PICTYPE_BITMAP) { + SelectObject(hdcIn,This->desc.u.bmp.hbitmap); + + if (phdcOut) + *phdcOut = This->hDCCur; + This->hDCCur = hdcIn; + if (phbmpOut) + *phbmpOut = (OLE_HANDLE)This->desc.u.bmp.hbitmap; + return S_OK; + } else { + FIXME("Don't know how to select picture type %d\n",This->desc.picType); + return E_FAIL; + } +} + +/************************************************************************ + * OLEPictureImpl_get_KeepOriginalFormat + */ +static HRESULT WINAPI OLEPictureImpl_get_KeepOriginalFormat(IPicture *iface, + BOOL *pfKeep) +{ + OLEPictureImpl *This = (OLEPictureImpl *)iface; + TRACE("(%p)->(%p)\n", This, pfKeep); + if (!pfKeep) + return E_POINTER; + *pfKeep = This->keepOrigFormat; + return S_OK; +} + +/************************************************************************ + * OLEPictureImpl_put_KeepOriginalFormat + */ +static HRESULT WINAPI OLEPictureImpl_put_KeepOriginalFormat(IPicture *iface, + BOOL keep) +{ + OLEPictureImpl *This = (OLEPictureImpl *)iface; + TRACE("(%p)->(%d)\n", This, keep); + This->keepOrigFormat = keep; + /* FIXME: what DISPID notification here? */ + return S_OK; +} + +/************************************************************************ + * OLEPictureImpl_PictureChanged + */ +static HRESULT WINAPI OLEPictureImpl_PictureChanged(IPicture *iface) +{ + OLEPictureImpl *This = (OLEPictureImpl *)iface; + TRACE("(%p)->()\n", This); + OLEPicture_SendNotify(This,DISPID_PICT_HANDLE); + This->bIsDirty = TRUE; + return S_OK; +} + +/************************************************************************ + * OLEPictureImpl_SaveAsFile + */ +static HRESULT WINAPI OLEPictureImpl_SaveAsFile(IPicture *iface, + IStream *pstream, + BOOL SaveMemCopy, + LONG *pcbSize) +{ + OLEPictureImpl *This = (OLEPictureImpl *)iface; + FIXME("(%p)->(%p, %d, %p), hacked stub.\n", This, pstream, SaveMemCopy, pcbSize); + return IStream_Write(pstream,This->data,This->datalen,(ULONG*)pcbSize); +} + +/************************************************************************ + * OLEPictureImpl_get_Attributes + */ +static HRESULT WINAPI OLEPictureImpl_get_Attributes(IPicture *iface, + DWORD *pdwAttr) +{ + OLEPictureImpl *This = (OLEPictureImpl *)iface; + TRACE("(%p)->(%p).\n", This, pdwAttr); + *pdwAttr = 0; + switch (This->desc.picType) { + case PICTYPE_BITMAP: break; /* not 'truely' scalable, see MSDN. */ + case PICTYPE_ICON: *pdwAttr = PICTURE_TRANSPARENT;break; + case PICTYPE_METAFILE: *pdwAttr = PICTURE_TRANSPARENT|PICTURE_SCALABLE;break; + default:FIXME("Unknown pictype %d\n",This->desc.picType);break; + } + return S_OK; +} + + +/************************************************************************ + * IConnectionPointContainer + */ + +static HRESULT WINAPI OLEPictureImpl_IConnectionPointContainer_QueryInterface( + IConnectionPointContainer* iface, + REFIID riid, + VOID** ppvoid +) { + ICOM_THIS_From_IConnectionPointContainer(IPicture,iface); + + return IPicture_QueryInterface(This,riid,ppvoid); +} + +static ULONG WINAPI OLEPictureImpl_IConnectionPointContainer_AddRef( + IConnectionPointContainer* iface) +{ + ICOM_THIS_From_IConnectionPointContainer(IPicture, iface); + + return IPicture_AddRef(This); +} + +static ULONG WINAPI OLEPictureImpl_IConnectionPointContainer_Release( + IConnectionPointContainer* iface) +{ + ICOM_THIS_From_IConnectionPointContainer(IPicture, iface); + + return IPicture_Release(This); +} + +static HRESULT WINAPI OLEPictureImpl_EnumConnectionPoints( + IConnectionPointContainer* iface, + IEnumConnectionPoints** ppEnum +) { + ICOM_THIS_From_IConnectionPointContainer(IPicture, iface); + + FIXME("(%p,%p), stub!\n",This,ppEnum); + return E_NOTIMPL; +} + +static HRESULT WINAPI OLEPictureImpl_FindConnectionPoint( + IConnectionPointContainer* iface, + REFIID riid, + IConnectionPoint **ppCP +) { + ICOM_THIS_From_IConnectionPointContainer(OLEPictureImpl, iface); + TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppCP); + if (!ppCP) + return E_POINTER; + *ppCP = NULL; + if (IsEqualGUID(riid,&IID_IPropertyNotifySink)) + return IConnectionPoint_QueryInterface(This->pCP,&IID_IConnectionPoint,(LPVOID)ppCP); + FIXME("tried to find connection point on %s?\n",debugstr_guid(riid)); + return 0x80040200; +} +/************************************************************************ + * IPersistStream + */ +/************************************************************************ + * OLEPictureImpl_IPersistStream_QueryInterface (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static HRESULT WINAPI OLEPictureImpl_IPersistStream_QueryInterface( + IPersistStream* iface, + REFIID riid, + VOID** ppvoid) +{ + ICOM_THIS_From_IPersistStream(IPicture, iface); + + return IPicture_QueryInterface(This, riid, ppvoid); +} + +/************************************************************************ + * OLEPictureImpl_IPersistStream_AddRef (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static ULONG WINAPI OLEPictureImpl_IPersistStream_AddRef( + IPersistStream* iface) +{ + ICOM_THIS_From_IPersistStream(IPicture, iface); + + return IPicture_AddRef(This); +} + +/************************************************************************ + * OLEPictureImpl_IPersistStream_Release (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static ULONG WINAPI OLEPictureImpl_IPersistStream_Release( + IPersistStream* iface) +{ + ICOM_THIS_From_IPersistStream(IPicture, iface); + + return IPicture_Release(This); +} + +/************************************************************************ + * OLEPictureImpl_IPersistStream_GetClassID + */ +static HRESULT WINAPI OLEPictureImpl_GetClassID( + IPersistStream* iface,CLSID* pClassID) +{ + ICOM_THIS_From_IPersistStream(IPicture, iface); + FIXME("(%p),stub!\n",This); + return E_FAIL; +} + +/************************************************************************ + * OLEPictureImpl_IPersistStream_IsDirty + */ +static HRESULT WINAPI OLEPictureImpl_IsDirty( + IPersistStream* iface) +{ + ICOM_THIS_From_IPersistStream(IPicture, iface); + FIXME("(%p),stub!\n",This); + return E_NOTIMPL; +} + +#ifdef HAVE_JPEGLIB_H + +static void *libjpeg_handle; +#define MAKE_FUNCPTR(f) static typeof(f) * p##f +MAKE_FUNCPTR(jpeg_std_error); +MAKE_FUNCPTR(jpeg_CreateDecompress); +MAKE_FUNCPTR(jpeg_read_header); +MAKE_FUNCPTR(jpeg_start_decompress); +MAKE_FUNCPTR(jpeg_read_scanlines); +MAKE_FUNCPTR(jpeg_finish_decompress); +MAKE_FUNCPTR(jpeg_destroy_decompress); +#undef MAKE_FUNCPTR + +static void *load_libjpeg(void) +{ + if((libjpeg_handle = wine_dlopen(SONAME_LIBJPEG, RTLD_NOW, NULL, 0)) != NULL) { + +#define LOAD_FUNCPTR(f) \ + if((p##f = wine_dlsym(libjpeg_handle, #f, NULL, 0)) == NULL) { \ + libjpeg_handle = NULL; \ + return NULL; \ + } + + LOAD_FUNCPTR(jpeg_std_error); + LOAD_FUNCPTR(jpeg_CreateDecompress); + LOAD_FUNCPTR(jpeg_read_header); + LOAD_FUNCPTR(jpeg_start_decompress); + LOAD_FUNCPTR(jpeg_read_scanlines); + LOAD_FUNCPTR(jpeg_finish_decompress); + LOAD_FUNCPTR(jpeg_destroy_decompress); +#undef LOAD_FUNCPTR + } + return libjpeg_handle; +} + +/* for the jpeg decompressor source manager. */ +static void _jpeg_init_source(j_decompress_ptr cinfo) { } + +static boolean _jpeg_fill_input_buffer(j_decompress_ptr cinfo) { + ERR("(), should not get here.\n"); + return FALSE; +} + +static void _jpeg_skip_input_data(j_decompress_ptr cinfo,long num_bytes) { + TRACE("Skipping %ld bytes...\n", num_bytes); + cinfo->src->next_input_byte += num_bytes; + cinfo->src->bytes_in_buffer -= num_bytes; +} + +static boolean _jpeg_resync_to_restart(j_decompress_ptr cinfo, int desired) { + ERR("(desired=%d), should not get here.\n",desired); + return FALSE; +} +static void _jpeg_term_source(j_decompress_ptr cinfo) { } +#endif /* HAVE_JPEGLIB_H */ + +#ifdef HAVE_GIF_LIB_H + +static void *libungif_handle; +#define MAKE_FUNCPTR(f) static typeof(f) * p##f +MAKE_FUNCPTR(DGifOpen); +MAKE_FUNCPTR(DGifSlurp); +MAKE_FUNCPTR(DGifCloseFile); +#undef MAKE_FUNCPTR + +struct gifdata { + unsigned char *data; + unsigned int curoff; + unsigned int len; +}; + +static void *load_libungif(void) +{ + if(((libungif_handle = wine_dlopen(SONAME_LIBUNGIF, RTLD_NOW, NULL, 0)) != NULL) || + ((libungif_handle = wine_dlopen(SONAME_LIBGIF , RTLD_NOW, NULL, 0)) != NULL) + ) { + +#define LOAD_FUNCPTR(f) \ + if((p##f = wine_dlsym(libungif_handle, #f, NULL, 0)) == NULL) { \ + libungif_handle = NULL; \ + return NULL; \ + } + + LOAD_FUNCPTR(DGifOpen); + LOAD_FUNCPTR(DGifSlurp); + LOAD_FUNCPTR(DGifCloseFile); +#undef LOAD_FUNCPTR + } + return libungif_handle; +} + +static int _gif_inputfunc(GifFileType *gif, GifByteType *data, int len) { + struct gifdata *gd = (struct gifdata*)gif->UserData; + + if (len+gd->curoff > gd->len) { + FIXME("Trying to read %d bytes, but only %d available.\n",len, gd->len-gd->curoff); + len = gd->len - gd->curoff; + } + memcpy(data, gd->data+gd->curoff, len); + gd->curoff += len; + return len; +} + +#endif /* HAVE_GIF_LIB_H */ + +/************************************************************************ + * OLEPictureImpl_IPersistStream_Load (IUnknown) + * + * Loads the binary data from the IStream. Starts at current position. + * There appears to be an 2 DWORD header: + * DWORD magic; + * DWORD len; + * + * Currently implemented: BITMAP, ICON, JPEG, GIF + */ +static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) { + HRESULT hr = E_FAIL; + ULONG xread; + BYTE *xbuf; + DWORD header[2]; + WORD magic; + STATSTG statstg; + ICOM_THIS_From_IPersistStream(OLEPictureImpl, iface); + + TRACE("(%p,%p)\n",This,pStm); + + /* Sometimes we have a header, sometimes we don't. Apply some guesses to find + * out whether we do. + * + * UPDATE: the IStream can be mapped to a plain file instead of a stream in a + * compound file. This may explain most, if not all, of the cases of "no header", + * and the header validation should take this into account. At least in Visual Basic 6, + * resource streams, valid headers are + * header[0] == "lt\0\0", + * header[1] == length_of_stream. + */ + hr=IStream_Stat(pStm,&statstg,STATFLAG_NONAME); + if (hr) + FIXME("Stat failed with hres %lx\n",hr); + hr=IStream_Read(pStm,header,8,&xread); + if (hr || xread!=8) { + FIXME("Failure while reading picture header (hr is %lx, nread is %ld).\n",hr,xread); + return hr; + } + if (!memcmp(&(header[0]), "GIF8", 4) || /* GIF header */ + !memcmp(&(header[0]), "BM", 2) || /* BMP header */ + !memcmp(&(header[0]), "\xff\xd8", 2) || /* JPEG header */ + header[1] > statstg.cbSize.QuadPart || (header[1]==0)) {/* Incorrect header, assume none. */ + xread = 8; + xbuf = This->data = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,statstg.cbSize.QuadPart); + memcpy(xbuf,&header,8); + This->datalen = statstg.cbSize.QuadPart; + while (xread < This->datalen) { + ULONG nread; + hr = IStream_Read(pStm,xbuf+xread,This->datalen-xread,&nread); + xread+=nread; + if (hr || !nread) + break; + } + if (xread != This->datalen) + FIXME("Could only read %ld of %d bytes in no-header case?\n",xread,This->datalen); + } else { + xread = 0; + xbuf = This->data = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,header[1]); + This->datalen = header[1]; + while (xread < header[1]) { + ULONG nread; + hr = IStream_Read(pStm,xbuf+xread,header[1]-xread,&nread); + xread+=nread; + if (hr || !nread) + break; + } + if (xread != header[1]) + FIXME("Could only read %ld of %ld bytes?\n",xread,header[1]); + } + magic = xbuf[0] + (xbuf[1]<<8); + switch (magic) { + case 0x4947: { /* GIF */ +#ifdef HAVE_GIF_LIB_H + struct gifdata gd; + GifFileType *gif; + BITMAPINFO *bmi; + HDC hdcref; + LPBYTE bytes; + int i,j,ret; + GifImageDesc *gid; + SavedImage *si; + ColorMapObject *cm; + int transparent = -1; + ExtensionBlock *eb; + int padding; + + if(!libungif_handle) { + if(!load_libungif()) { + FIXME("Failed reading GIF because unable to find %s/%s\n", SONAME_LIBUNGIF, SONAME_LIBGIF); + return E_FAIL; + } + } + + gd.data = xbuf; + gd.curoff = 0; + gd.len = xread; + gif = pDGifOpen((void*)&gd, _gif_inputfunc); + ret = pDGifSlurp(gif); + if (ret == GIF_ERROR) { + FIXME("Failed reading GIF using libgif.\n"); + return E_FAIL; + } + TRACE("screen height %d, width %d\n", gif->SWidth, gif->SHeight); + TRACE("color res %d, backgcolor %d\n", gif->SColorResolution, gif->SBackGroundColor); + TRACE("imgcnt %d\n", gif->ImageCount); + if (gif->ImageCount<1) { + FIXME("GIF stream does not have images inside?\n"); + return E_FAIL; + } + TRACE("curimage: %d x %d, on %dx%d, interlace %d\n", + gif->Image.Width, gif->Image.Height, + gif->Image.Left, gif->Image.Top, + gif->Image.Interlace + ); + /* */ + padding = (gif->SWidth+3) & ~3; + bmi = HeapAlloc(GetProcessHeap(),0,sizeof(BITMAPINFOHEADER)+(1<SColorResolution)*sizeof(RGBQUAD)); + bytes= HeapAlloc(GetProcessHeap(),0,padding*gif->SHeight); + si = gif->SavedImages+0; + gid = &(si->ImageDesc); + cm = gid->ColorMap; + if (!cm) cm = gif->SColorMap; + + /* look for the transparent color extension */ + for (i = 0; i < si->ExtensionBlockCount; ++i) { + eb = si->ExtensionBlocks + i; + if (eb->Function == 0xF9 && eb->ByteCount == 4) { + if ((eb->Bytes[0] & 1) == 1) { + transparent = eb->Bytes[3]; + } + } + } + + for (i=0;i<(1<SColorResolution);i++) { + bmi->bmiColors[i].rgbRed = cm->Colors[i].Red; + bmi->bmiColors[i].rgbGreen = cm->Colors[i].Green; + bmi->bmiColors[i].rgbBlue = cm->Colors[i].Blue; + if (i == transparent) { + This->rgbTrans = RGB(bmi->bmiColors[i].rgbRed, + bmi->bmiColors[i].rgbGreen, + bmi->bmiColors[i].rgbBlue); + } + } + + /* Map to in picture coordinates */ + for (i = 0, j = 0; i < gid->Height; i++) { + if (gif->Image.Interlace) { + memcpy( + bytes + (gid->Top + j) * padding + gid->Left, + si->RasterBits + i * gid->Width, + gid->Width); + + /* Lower bits of interlaced counter encode current interlace */ + if (j & 1) j += 2; /* Currently filling odd rows */ + else if (j & 2) j += 4; /* Currently filling even rows not multiples of 4 */ + else j += 8; /* Currently filling every 8th row or 4th row in-between */ + + if (j >= gid->Height && i < gid->Height && (j & 1) == 0) { + /* End of current interlace, go to next interlace */ + if (j & 2) j = 1; /* Next iteration fills odd rows */ + else if (j & 4) j = 2; /* Next iteration fills even rows not mod 4 and not mod 8 */ + else j = 4; /* Next iteration fills rows in-between rows mod 6 */ + } + } else { + memcpy( + bytes + (gid->Top + i) * padding + gid->Left, + si->RasterBits + i * gid->Width, + gid->Width); + } + } + + bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmi->bmiHeader.biWidth = gif->SWidth; + bmi->bmiHeader.biHeight = -gif->SHeight; + bmi->bmiHeader.biPlanes = 1; + bmi->bmiHeader.biBitCount = 8; + bmi->bmiHeader.biCompression = BI_RGB; + bmi->bmiHeader.biSizeImage = padding*gif->SHeight; + bmi->bmiHeader.biXPelsPerMeter = 0; + bmi->bmiHeader.biYPelsPerMeter = 0; + bmi->bmiHeader.biClrUsed = 1 << gif->SColorResolution; + bmi->bmiHeader.biClrImportant = 0; + + hdcref = GetDC(0); + This->desc.u.bmp.hbitmap=CreateDIBitmap( + hdcref, + &bmi->bmiHeader, + CBM_INIT, + bytes, + bmi, + DIB_RGB_COLORS + ); + + if (transparent > -1) { + /* Create the Mask */ + HDC hdc = CreateCompatibleDC(0); + HDC hdcMask = CreateCompatibleDC(0); + HBITMAP hOldbitmap; + HBITMAP hOldbitmapmask; + + This->hbmMask = CreateBitmap(bmi->bmiHeader.biWidth, bmi->bmiHeader.biHeight, 1, 1, NULL); + + hOldbitmap = SelectObject(hdc,This->desc.u.bmp.hbitmap); + hOldbitmapmask = SelectObject(hdcMask, This->hbmMask); + SetBkColor(hdc, This->rgbTrans); + BitBlt(hdcMask, 0, 0, bmi->bmiHeader.biWidth, bmi->bmiHeader.biHeight, hdc, 0, 0, SRCCOPY); + + /* We no longer need the original bitmap, so we apply the first + transformation with the mask to speed up the rendering */ + SetBkColor(hdc, RGB(0,0,0)); + SetTextColor(hdc, RGB(255,255,255)); + BitBlt(hdc, 0, 0, bmi->bmiHeader.biWidth, bmi->bmiHeader.biHeight, + hdcMask, 0, 0, SRCAND); + + SelectObject(hdc, hOldbitmap); + SelectObject(hdcMask, hOldbitmapmask); + DeleteDC(hdcMask); + DeleteDC(hdc); + } + + DeleteDC(hdcref); + This->desc.picType = PICTYPE_BITMAP; + OLEPictureImpl_SetBitmap(This); + pDGifCloseFile(gif); + HeapFree(GetProcessHeap(),0,bytes); + return S_OK; +#else + FIXME("Trying to load GIF, but no support for libgif/libungif compiled in.\n"); + return E_FAIL; +#endif + break; + } + case 0xd8ff: { /* JPEG */ +#ifdef HAVE_JPEGLIB_H + struct jpeg_decompress_struct jd; + struct jpeg_error_mgr jerr; + int ret; + JDIMENSION x; + JSAMPROW samprow,oldsamprow; + BITMAPINFOHEADER bmi; + LPBYTE bits; + HDC hdcref; + struct jpeg_source_mgr xjsm; + LPBYTE oldbits; + unsigned int i; + + if(!libjpeg_handle) { + if(!load_libjpeg()) { + FIXME("Failed reading JPEG because unable to find %s\n", SONAME_LIBJPEG); + return E_FAIL; + } + } + + /* This is basically so we can use in-memory data for jpeg decompression. + * We need to have all the functions. + */ + xjsm.next_input_byte = xbuf; + xjsm.bytes_in_buffer = xread; + xjsm.init_source = _jpeg_init_source; + xjsm.fill_input_buffer = _jpeg_fill_input_buffer; + xjsm.skip_input_data = _jpeg_skip_input_data; + xjsm.resync_to_restart = _jpeg_resync_to_restart; + xjsm.term_source = _jpeg_term_source; + + jd.err = pjpeg_std_error(&jerr); + /* jpeg_create_decompress is a macro that expands to jpeg_CreateDecompress - see jpeglib.h + * jpeg_create_decompress(&jd); */ + pjpeg_CreateDecompress(&jd, JPEG_LIB_VERSION, (size_t) sizeof(struct jpeg_decompress_struct)); + jd.src = &xjsm; + ret=pjpeg_read_header(&jd,TRUE); + jd.out_color_space = JCS_RGB; + pjpeg_start_decompress(&jd); + if (ret != JPEG_HEADER_OK) { + ERR("Jpeg image in stream has bad format, read header returned %d.\n",ret); + HeapFree(GetProcessHeap(),0,xbuf); + return E_FAIL; + } + + bits = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, + (jd.output_height+1) * ((jd.output_width*jd.output_components + 3) & ~3) ); + samprow=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,jd.output_width*jd.output_components); + + oldbits = bits; + oldsamprow = samprow; + while ( jd.output_scanlinedesc.u.bmp.hbitmap=CreateDIBitmap( + hdcref, + &bmi, + CBM_INIT, + bits, + (BITMAPINFO*)&bmi, + DIB_RGB_COLORS + ); + DeleteDC(hdcref); + This->desc.picType = PICTYPE_BITMAP; + OLEPictureImpl_SetBitmap(This); + hr = S_OK; + HeapFree(GetProcessHeap(),0,bits); +#else + ERR("Trying to load JPEG picture, but JPEG supported not compiled in.\n"); + hr = E_FAIL; +#endif + break; + } + case 0x4d42: { /* Bitmap */ + BITMAPFILEHEADER *bfh = (BITMAPFILEHEADER*)xbuf; + BITMAPINFO *bi = (BITMAPINFO*)(bfh+1); + HDC hdcref; + + /* Does not matter whether this is a coreheader or not, we only use + * components which are in both + */ + hdcref = GetDC(0); + This->desc.u.bmp.hbitmap = CreateDIBitmap( + hdcref, + &(bi->bmiHeader), + CBM_INIT, + xbuf+bfh->bfOffBits, + bi, + DIB_RGB_COLORS + ); + DeleteDC(hdcref); + This->desc.picType = PICTYPE_BITMAP; + OLEPictureImpl_SetBitmap(This); + hr = S_OK; + break; + } + case 0x0000: { /* ICON , first word is dwReserved */ + HICON hicon; + CURSORICONFILEDIR *cifd = (CURSORICONFILEDIR*)xbuf; + HDC hdcRef; + int i; + + /* + FIXME("icon.idReserved=%d\n",cifd->idReserved); + FIXME("icon.idType=%d\n",cifd->idType); + FIXME("icon.idCount=%d\n",cifd->idCount); + + for (i=0;iidCount;i++) { + FIXME("[%d] width %d\n",i,cifd->idEntries[i].bWidth); + FIXME("[%d] height %d\n",i,cifd->idEntries[i].bHeight); + FIXME("[%d] bColorCount %d\n",i,cifd->idEntries[i].bColorCount); + FIXME("[%d] bReserved %d\n",i,cifd->idEntries[i].bReserved); + FIXME("[%d] xHotspot %d\n",i,cifd->idEntries[i].xHotspot); + FIXME("[%d] yHotspot %d\n",i,cifd->idEntries[i].yHotspot); + FIXME("[%d] dwDIBSize %d\n",i,cifd->idEntries[i].dwDIBSize); + FIXME("[%d] dwDIBOffset %d\n",i,cifd->idEntries[i].dwDIBOffset); + } + */ + i=0; + /* If we have more than one icon, try to find the best. + * this currently means '32 pixel wide'. + */ + if (cifd->idCount!=1) { + for (i=0;iidCount;i++) { + if (cifd->idEntries[i].bWidth == 32) + break; + } + if (i==cifd->idCount) i=0; + } + + hicon = CreateIconFromResourceEx( + xbuf+cifd->idEntries[i].dwDIBOffset, + cifd->idEntries[i].dwDIBSize, + TRUE, /* is icon */ + 0x00030000, + cifd->idEntries[i].bWidth, + cifd->idEntries[i].bHeight, + 0 + ); + if (!hicon) { + FIXME("CreateIcon failed.\n"); + hr = E_FAIL; + } else { + This->desc.picType = PICTYPE_ICON; + This->desc.u.icon.hicon = hicon; + This->origWidth = cifd->idEntries[i].bWidth; + This->origHeight = cifd->idEntries[i].bHeight; + hdcRef = CreateCompatibleDC(0); + This->himetricWidth =(cifd->idEntries[i].bWidth *2540)/GetDeviceCaps(hdcRef, LOGPIXELSX); + This->himetricHeight=(cifd->idEntries[i].bHeight*2540)/GetDeviceCaps(hdcRef, LOGPIXELSY); + DeleteDC(hdcRef); + hr = S_OK; + } + break; + } + default: + { + unsigned int i; + FIXME("Unknown magic %04x, %ld read bytes:\n",magic,xread); + hr=E_FAIL; + for (i=0;ibIsDirty = FALSE; + + /* FIXME: this notify is not really documented */ + if (hr==S_OK) + OLEPicture_SendNotify(This,DISPID_PICT_TYPE); + return hr; +} + +static int serializeIcon(HICON hIcon, void ** ppBuffer, unsigned int * pLength); +static int serializeBMP(HBITMAP hBitmap, void ** ppBuffer, unsigned int * pLength); +static HRESULT WINAPI OLEPictureImpl_Save( + IPersistStream* iface,IStream*pStm,BOOL fClearDirty) +{ + HRESULT hResult = E_NOTIMPL; + void * pIconData; + unsigned int iDataSize; + ULONG dummy; + int iSerializeResult = 0; + + ICOM_THIS_From_IPersistStream(OLEPictureImpl, iface); + + switch (This->desc.picType) { + case PICTYPE_ICON: + if (This->bIsDirty) { + if (serializeIcon(This->desc.u.icon.hicon, &pIconData, &iDataSize)) { + if (This->loadtime_magic != 0xdeadbeef) { + DWORD header[2]; + + header[0] = This->loadtime_magic; + header[1] = iDataSize; + IStream_Write(pStm, header, 2 * sizeof(DWORD), &dummy); + } + IStream_Write(pStm, pIconData, iDataSize, &dummy); + + HeapFree(GetProcessHeap(), 0, This->data); + This->data = pIconData; + This->datalen = iDataSize; + hResult = S_OK; + } else { + FIXME("(%p,%p,%d), unable to serializeIcon()!\n",This,pStm,fClearDirty); + hResult = E_FAIL; + } + } else { + if (This->loadtime_magic != 0xdeadbeef) { + DWORD header[2]; + + header[0] = This->loadtime_magic; + header[1] = This->datalen; + IStream_Write(pStm, header, 2 * sizeof(DWORD), &dummy); + } + IStream_Write(pStm, This->data, This->datalen, &dummy); + hResult = S_OK; + } + break; + case PICTYPE_BITMAP: + if (This->bIsDirty) { + switch (This->keepOrigFormat ? This->loadtime_format : 0x4d42) { + case 0x4d42: + iSerializeResult = serializeBMP(This->desc.u.bmp.hbitmap, &pIconData, &iDataSize); + break; + case 0xd8ff: + FIXME("(%p,%p,%d), PICTYPE_BITMAP (format JPEG) not implemented!\n",This,pStm,fClearDirty); + break; + case 0x4947: + FIXME("(%p,%p,%d), PICTYPE_BITMAP (format GIF) not implemented!\n",This,pStm,fClearDirty); + break; + default: + FIXME("(%p,%p,%d), PICTYPE_BITMAP (format UNKNOWN, using BMP?) not implemented!\n",This,pStm,fClearDirty); + break; + } + if (iSerializeResult) { + /* + if (This->loadtime_magic != 0xdeadbeef) { + */ + if (1) { + DWORD header[2]; + + header[0] = (This->loadtime_magic != 0xdeadbeef) ? This->loadtime_magic : 0x0000746c; + header[1] = iDataSize; + IStream_Write(pStm, header, 2 * sizeof(DWORD), &dummy); + } + IStream_Write(pStm, pIconData, iDataSize, &dummy); + + HeapFree(GetProcessHeap(), 0, This->data); + This->data = pIconData; + This->datalen = iDataSize; + hResult = S_OK; + } + } else { + /* + if (This->loadtime_magic != 0xdeadbeef) { + */ + if (1) { + DWORD header[2]; + + header[0] = (This->loadtime_magic != 0xdeadbeef) ? This->loadtime_magic : 0x0000746c; + header[1] = This->datalen; + IStream_Write(pStm, header, 2 * sizeof(DWORD), &dummy); + } + IStream_Write(pStm, This->data, This->datalen, &dummy); + hResult = S_OK; + } + break; + case PICTYPE_METAFILE: + FIXME("(%p,%p,%d), PICTYPE_METAFILE not implemented!\n",This,pStm,fClearDirty); + break; + case PICTYPE_ENHMETAFILE: + FIXME("(%p,%p,%d),PICTYPE_ENHMETAFILE not implemented!\n",This,pStm,fClearDirty); + break; + default: + FIXME("(%p,%p,%d), [unknown type] not implemented!\n",This,pStm,fClearDirty); + break; + } + if (hResult == S_OK && fClearDirty) This->bIsDirty = FALSE; + return hResult; +} + +static int serializeBMP(HBITMAP hBitmap, void ** ppBuffer, unsigned int * pLength) +{ + int iSuccess = 0; + HDC hDC; + BITMAPINFO * pInfoBitmap; + int iNumPaletteEntries; + unsigned char * pPixelData; + BITMAPFILEHEADER * pFileHeader; + BITMAPINFO * pInfoHeader; + + pInfoBitmap = (BITMAPINFO *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)); + + /* Find out bitmap size and padded length */ + hDC = GetDC(0); + pInfoBitmap->bmiHeader.biSize = sizeof(pInfoBitmap->bmiHeader); + GetDIBits(hDC, hBitmap, 0, 0, NULL, pInfoBitmap, DIB_RGB_COLORS); + + /* Fetch bitmap palette & pixel data */ + + pPixelData = (unsigned char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + pInfoBitmap->bmiHeader.biSizeImage); + GetDIBits(hDC, hBitmap, 0, pInfoBitmap->bmiHeader.biHeight, pPixelData, pInfoBitmap, DIB_RGB_COLORS); + + /* Calculate the total length required for the BMP data */ + if (pInfoBitmap->bmiHeader.biClrUsed != 0) iNumPaletteEntries = pInfoBitmap->bmiHeader.biClrUsed; + else if (pInfoBitmap->bmiHeader.biBitCount <= 8) iNumPaletteEntries = 1 << pInfoBitmap->bmiHeader.biBitCount; + else iNumPaletteEntries = 0; + *pLength = + sizeof(BITMAPFILEHEADER) + + sizeof(BITMAPINFOHEADER) + + iNumPaletteEntries * sizeof(RGBQUAD) + + pInfoBitmap->bmiHeader.biSizeImage; + *ppBuffer = (void *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, *pLength); + + /* Fill the BITMAPFILEHEADER */ + pFileHeader = (BITMAPFILEHEADER *)(*ppBuffer); + pFileHeader->bfType = 0x4d42; + pFileHeader->bfSize = *pLength; + pFileHeader->bfOffBits = + sizeof(BITMAPFILEHEADER) + + sizeof(BITMAPINFOHEADER) + + iNumPaletteEntries * sizeof(RGBQUAD); + + /* Fill the BITMAPINFOHEADER and the palette data */ + pInfoHeader = (BITMAPINFO *)((unsigned char *)(*ppBuffer) + sizeof(BITMAPFILEHEADER)); + memcpy(pInfoHeader, pInfoBitmap, sizeof(BITMAPINFOHEADER) + iNumPaletteEntries * sizeof(RGBQUAD)); + memcpy( + (unsigned char *)(*ppBuffer) + + sizeof(BITMAPFILEHEADER) + + sizeof(BITMAPINFOHEADER) + + iNumPaletteEntries * sizeof(RGBQUAD), + pPixelData, pInfoBitmap->bmiHeader.biSizeImage); + iSuccess = 1; + + HeapFree(GetProcessHeap(), 0, pPixelData); + HeapFree(GetProcessHeap(), 0, pInfoBitmap); + return iSuccess; +} + +static int serializeIcon(HICON hIcon, void ** ppBuffer, unsigned int * pLength) +{ + ICONINFO infoIcon; + int iSuccess = 0; + + *ppBuffer = NULL; *pLength = 0; + if (GetIconInfo(hIcon, &infoIcon)) { + HDC hDC; + BITMAPINFO * pInfoBitmap; + unsigned char * pIconData = NULL; + unsigned int iDataSize = 0; + + pInfoBitmap = (BITMAPINFO *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)); + + /* Find out icon size */ + hDC = GetDC(0); + pInfoBitmap->bmiHeader.biSize = sizeof(pInfoBitmap->bmiHeader); + GetDIBits(hDC, infoIcon.hbmColor, 0, 0, NULL, pInfoBitmap, DIB_RGB_COLORS); + if (1) { + /* Auxiliary pointers */ + CURSORICONFILEDIR * pIconDir; + CURSORICONFILEDIRENTRY * pIconEntry; + BITMAPINFOHEADER * pIconBitmapHeader; + unsigned int iOffsetPalette; + unsigned int iOffsetColorData; + unsigned int iOffsetMaskData; + + unsigned int iLengthScanLineColor; + unsigned int iLengthScanLineMask; + unsigned int iNumEntriesPalette; + + iLengthScanLineMask = ((pInfoBitmap->bmiHeader.biWidth + 31) >> 5) << 2; + iLengthScanLineColor = ((pInfoBitmap->bmiHeader.biWidth * pInfoBitmap->bmiHeader.biBitCount + 31) >> 5) << 2; +/* + FIXME("DEBUG: bitmap size is %d x %d\n", + pInfoBitmap->bmiHeader.biWidth, + pInfoBitmap->bmiHeader.biHeight); + FIXME("DEBUG: bitmap bpp is %d\n", + pInfoBitmap->bmiHeader.biBitCount); + FIXME("DEBUG: bitmap nplanes is %d\n", + pInfoBitmap->bmiHeader.biPlanes); + FIXME("DEBUG: bitmap biSizeImage is %lu\n", + pInfoBitmap->bmiHeader.biSizeImage); +*/ + /* Let's start with one CURSORICONFILEDIR and one CURSORICONFILEDIRENTRY */ + iDataSize += 3 * sizeof(WORD) + sizeof(CURSORICONFILEDIRENTRY) + sizeof(BITMAPINFOHEADER); + pIconData = (unsigned char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, iDataSize); + + /* Fill out the CURSORICONFILEDIR */ + pIconDir = (CURSORICONFILEDIR *)pIconData; + pIconDir->idType = 1; + pIconDir->idCount = 1; + + /* Fill out the CURSORICONFILEDIRENTRY */ + pIconEntry = (CURSORICONFILEDIRENTRY *)(pIconData + 3 * sizeof(WORD)); + pIconEntry->bWidth = (unsigned char)pInfoBitmap->bmiHeader.biWidth; + pIconEntry->bHeight = (unsigned char)pInfoBitmap->bmiHeader.biHeight; + pIconEntry->bColorCount = + (pInfoBitmap->bmiHeader.biBitCount < 8) + ? 1 << pInfoBitmap->bmiHeader.biBitCount + : 0; + pIconEntry->xHotspot = pInfoBitmap->bmiHeader.biPlanes; + pIconEntry->yHotspot = pInfoBitmap->bmiHeader.biBitCount; + pIconEntry->dwDIBSize = 0; + pIconEntry->dwDIBOffset = 3 * sizeof(WORD) + sizeof(CURSORICONFILEDIRENTRY); + + /* Fill out the BITMAPINFOHEADER */ + pIconBitmapHeader = (BITMAPINFOHEADER *)(pIconData + 3 * sizeof(WORD) + sizeof(CURSORICONFILEDIRENTRY)); + memcpy(pIconBitmapHeader, &pInfoBitmap->bmiHeader, sizeof(BITMAPINFOHEADER)); + + /* Find out whether a palette exists for the bitmap */ + if ( (pInfoBitmap->bmiHeader.biBitCount == 16 && pInfoBitmap->bmiHeader.biCompression == BI_RGB) + || (pInfoBitmap->bmiHeader.biBitCount == 24) + || (pInfoBitmap->bmiHeader.biBitCount == 32 && pInfoBitmap->bmiHeader.biCompression == BI_RGB)) { + iNumEntriesPalette = pInfoBitmap->bmiHeader.biClrUsed; + } else if ((pInfoBitmap->bmiHeader.biBitCount == 16 || pInfoBitmap->bmiHeader.biBitCount == 32) + && pInfoBitmap->bmiHeader.biCompression == BI_BITFIELDS) { + iNumEntriesPalette = 3; + } else if (pInfoBitmap->bmiHeader.biBitCount <= 8) { + iNumEntriesPalette = 1 << pInfoBitmap->bmiHeader.biBitCount; + } else { + iNumEntriesPalette = 0; + } + + /* Add bitmap size and header size to icon data size. */ + iOffsetPalette = iDataSize; + iDataSize += iNumEntriesPalette * sizeof(DWORD); + iOffsetColorData = iDataSize; + iDataSize += pIconBitmapHeader->biSizeImage; + iOffsetMaskData = iDataSize; + iDataSize += pIconBitmapHeader->biHeight * iLengthScanLineMask; + pIconBitmapHeader->biSizeImage += pIconBitmapHeader->biHeight * iLengthScanLineMask; + pIconBitmapHeader->biHeight *= 2; + pIconData = (unsigned char *)HeapReAlloc(GetProcessHeap(), 0, pIconData, iDataSize); + pIconEntry = (CURSORICONFILEDIRENTRY *)(pIconData + 3 * sizeof(WORD)); + pIconBitmapHeader = (BITMAPINFOHEADER *)(pIconData + 3 * sizeof(WORD) + sizeof(CURSORICONFILEDIRENTRY)); + pIconEntry->dwDIBSize = iDataSize - (3 * sizeof(WORD) + sizeof(CURSORICONFILEDIRENTRY)); + + /* Get the actual bitmap data from the icon bitmap */ + GetDIBits(hDC, infoIcon.hbmColor, 0, pInfoBitmap->bmiHeader.biHeight, + pIconData + iOffsetColorData, pInfoBitmap, DIB_RGB_COLORS); + if (iNumEntriesPalette > 0) { + memcpy(pIconData + iOffsetPalette, pInfoBitmap->bmiColors, + iNumEntriesPalette * sizeof(RGBQUAD)); + } + + /* Reset all values so that GetDIBits call succeeds */ + memset(pIconData + iOffsetMaskData, 0, iDataSize - iOffsetMaskData); + memset(pInfoBitmap, 0, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)); + pInfoBitmap->bmiHeader.biSize = sizeof(pInfoBitmap->bmiHeader); +/* + if (!(GetDIBits(hDC, infoIcon.hbmMask, 0, 0, NULL, pInfoBitmap, DIB_RGB_COLORS) + && GetDIBits(hDC, infoIcon.hbmMask, 0, pIconEntry->bHeight, + pIconData + iOffsetMaskData, pInfoBitmap, DIB_RGB_COLORS))) { + + printf("ERROR: unable to get bitmap mask (error %lu)\n", + GetLastError()); + + } +*/ + GetDIBits(hDC, infoIcon.hbmMask, 0, 0, NULL, pInfoBitmap, DIB_RGB_COLORS); + GetDIBits(hDC, infoIcon.hbmMask, 0, pIconEntry->bHeight, pIconData + iOffsetMaskData, pInfoBitmap, DIB_RGB_COLORS); + + /* Write out everything produced so far to the stream */ + *ppBuffer = pIconData; *pLength = iDataSize; + iSuccess = 1; + } else { +/* + printf("ERROR: unable to get bitmap information via GetDIBits() (error %lu)\n", + GetLastError()); +*/ + } + /* + Remarks (from MSDN entry on GetIconInfo): + + GetIconInfo creates bitmaps for the hbmMask and hbmColor + members of ICONINFO. The calling application must manage + these bitmaps and delete them when they are no longer + necessary. + */ + if (hDC) ReleaseDC(0, hDC); + DeleteObject(infoIcon.hbmMask); + if (infoIcon.hbmColor) DeleteObject(infoIcon.hbmColor); + HeapFree(GetProcessHeap(), 0, pInfoBitmap); + } else { + printf("ERROR: Unable to get icon information (error %lu)\n", + GetLastError()); + } + return iSuccess; +} + +static HRESULT WINAPI OLEPictureImpl_GetSizeMax( + IPersistStream* iface,ULARGE_INTEGER*pcbSize) +{ + ICOM_THIS_From_IPersistStream(IPicture, iface); + FIXME("(%p,%p),stub!\n",This,pcbSize); + return E_NOTIMPL; +} + +/************************************************************************ + * IDispatch + */ +/************************************************************************ + * OLEPictureImpl_IDispatch_QueryInterface (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static HRESULT WINAPI OLEPictureImpl_IDispatch_QueryInterface( + IDispatch* iface, + REFIID riid, + VOID** ppvoid) +{ + ICOM_THIS_From_IDispatch(IPicture, iface); + + return IPicture_QueryInterface(This, riid, ppvoid); +} + +/************************************************************************ + * OLEPictureImpl_IDispatch_AddRef (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static ULONG WINAPI OLEPictureImpl_IDispatch_AddRef( + IDispatch* iface) +{ + ICOM_THIS_From_IDispatch(IPicture, iface); + + return IPicture_AddRef(This); +} + +/************************************************************************ + * OLEPictureImpl_IDispatch_Release (IUnknown) + * + * See Windows documentation for more details on IUnknown methods. + */ +static ULONG WINAPI OLEPictureImpl_IDispatch_Release( + IDispatch* iface) +{ + ICOM_THIS_From_IDispatch(IPicture, iface); + + return IPicture_Release(This); +} + +/************************************************************************ + * OLEPictureImpl_GetTypeInfoCount (IDispatch) + * + * See Windows documentation for more details on IDispatch methods. + */ +static HRESULT WINAPI OLEPictureImpl_GetTypeInfoCount( + IDispatch* iface, + unsigned int* pctinfo) +{ + FIXME("():Stub\n"); + + return E_NOTIMPL; +} + +/************************************************************************ + * OLEPictureImpl_GetTypeInfo (IDispatch) + * + * See Windows documentation for more details on IDispatch methods. + */ +static HRESULT WINAPI OLEPictureImpl_GetTypeInfo( + IDispatch* iface, + UINT iTInfo, + LCID lcid, + ITypeInfo** ppTInfo) +{ + FIXME("():Stub\n"); + + return E_NOTIMPL; +} + +/************************************************************************ + * OLEPictureImpl_GetIDsOfNames (IDispatch) + * + * See Windows documentation for more details on IDispatch methods. + */ +static HRESULT WINAPI OLEPictureImpl_GetIDsOfNames( + IDispatch* iface, + REFIID riid, + LPOLESTR* rgszNames, + UINT cNames, + LCID lcid, + DISPID* rgDispId) +{ + FIXME("():Stub\n"); + + return E_NOTIMPL; +} + +/************************************************************************ + * OLEPictureImpl_Invoke (IDispatch) + * + * See Windows documentation for more details on IDispatch methods. + */ +static HRESULT WINAPI OLEPictureImpl_Invoke( + IDispatch* iface, + DISPID dispIdMember, + REFIID riid, + LCID lcid, + WORD wFlags, + DISPPARAMS* pDispParams, + VARIANT* pVarResult, + EXCEPINFO* pExepInfo, + UINT* puArgErr) +{ + FIXME("(dispid: %ld):Stub\n",dispIdMember); + + VariantInit(pVarResult); + V_VT(pVarResult) = VT_BOOL; + V_UNION(pVarResult,boolVal) = FALSE; + return S_OK; +} + + +static IPictureVtbl OLEPictureImpl_VTable = +{ + OLEPictureImpl_QueryInterface, + OLEPictureImpl_AddRef, + OLEPictureImpl_Release, + OLEPictureImpl_get_Handle, + OLEPictureImpl_get_hPal, + OLEPictureImpl_get_Type, + OLEPictureImpl_get_Width, + OLEPictureImpl_get_Height, + OLEPictureImpl_Render, + OLEPictureImpl_set_hPal, + OLEPictureImpl_get_CurDC, + OLEPictureImpl_SelectPicture, + OLEPictureImpl_get_KeepOriginalFormat, + OLEPictureImpl_put_KeepOriginalFormat, + OLEPictureImpl_PictureChanged, + OLEPictureImpl_SaveAsFile, + OLEPictureImpl_get_Attributes +}; + +static IDispatchVtbl OLEPictureImpl_IDispatch_VTable = +{ + OLEPictureImpl_IDispatch_QueryInterface, + OLEPictureImpl_IDispatch_AddRef, + OLEPictureImpl_IDispatch_Release, + OLEPictureImpl_GetTypeInfoCount, + OLEPictureImpl_GetTypeInfo, + OLEPictureImpl_GetIDsOfNames, + OLEPictureImpl_Invoke +}; + +static IPersistStreamVtbl OLEPictureImpl_IPersistStream_VTable = +{ + OLEPictureImpl_IPersistStream_QueryInterface, + OLEPictureImpl_IPersistStream_AddRef, + OLEPictureImpl_IPersistStream_Release, + OLEPictureImpl_GetClassID, + OLEPictureImpl_IsDirty, + OLEPictureImpl_Load, + OLEPictureImpl_Save, + OLEPictureImpl_GetSizeMax +}; + +static IConnectionPointContainerVtbl OLEPictureImpl_IConnectionPointContainer_VTable = +{ + OLEPictureImpl_IConnectionPointContainer_QueryInterface, + OLEPictureImpl_IConnectionPointContainer_AddRef, + OLEPictureImpl_IConnectionPointContainer_Release, + OLEPictureImpl_EnumConnectionPoints, + OLEPictureImpl_FindConnectionPoint +}; + +/*********************************************************************** + * OleCreatePictureIndirect (OLEAUT32.419) + */ +HRESULT WINAPI OleCreatePictureIndirect(LPPICTDESC lpPictDesc, REFIID riid, + BOOL fOwn, LPVOID *ppvObj ) +{ + OLEPictureImpl* newPict = NULL; + HRESULT hr = S_OK; + + TRACE("(%p,%p,%d,%p)\n", lpPictDesc, riid, fOwn, ppvObj); + + /* + * Sanity check + */ + if (ppvObj==0) + return E_POINTER; + + *ppvObj = NULL; + + /* + * Try to construct a new instance of the class. + */ + newPict = OLEPictureImpl_Construct(lpPictDesc, fOwn); + + if (newPict == NULL) + return E_OUTOFMEMORY; + + /* + * Make sure it supports the interface required by the caller. + */ + hr = IPicture_QueryInterface((IPicture*)newPict, riid, ppvObj); + + /* + * Release the reference obtained in the constructor. If + * the QueryInterface was unsuccessful, it will free the class. + */ + IPicture_Release((IPicture*)newPict); + + return hr; +} + + +/*********************************************************************** + * OleLoadPicture (OLEAUT32.418) + */ +HRESULT WINAPI OleLoadPicture( LPSTREAM lpstream, LONG lSize, BOOL fRunmode, + REFIID riid, LPVOID *ppvObj ) +{ + LPPERSISTSTREAM ps; + IPicture *newpic; + HRESULT hr; + + TRACE("(%p,%ld,%d,%s,%p), partially implemented.\n", + lpstream, lSize, fRunmode, debugstr_guid(riid), ppvObj); + + hr = OleCreatePictureIndirect(NULL,riid,!fRunmode,(LPVOID*)&newpic); + if (hr) + return hr; + hr = IPicture_QueryInterface(newpic,&IID_IPersistStream, (LPVOID*)&ps); + if (hr) { + FIXME("Could not get IPersistStream iface from Ole Picture?\n"); + IPicture_Release(newpic); + *ppvObj = NULL; + return hr; + } + IPersistStream_Load(ps,lpstream); + IPersistStream_Release(ps); + hr = IPicture_QueryInterface(newpic,riid,ppvObj); + if (hr) + FIXME("Failed to get interface %s from IPicture.\n",debugstr_guid(riid)); + IPicture_Release(newpic); + return hr; +} + +/*********************************************************************** + * OleLoadPictureEx (OLEAUT32.401) + */ +HRESULT WINAPI OleLoadPictureEx( LPSTREAM lpstream, LONG lSize, BOOL fRunmode, + REFIID riid, DWORD xsiz, DWORD ysiz, DWORD flags, LPVOID *ppvObj ) +{ + LPPERSISTSTREAM ps; + IPicture *newpic; + HRESULT hr; + + FIXME("(%p,%ld,%d,%s,x=%ld,y=%ld,f=%lx,%p), partially implemented.\n", + lpstream, lSize, fRunmode, debugstr_guid(riid), xsiz, ysiz, flags, ppvObj); + + hr = OleCreatePictureIndirect(NULL,riid,!fRunmode,(LPVOID*)&newpic); + if (hr) + return hr; + hr = IPicture_QueryInterface(newpic,&IID_IPersistStream, (LPVOID*)&ps); + if (hr) { + FIXME("Could not get IPersistStream iface from Ole Picture?\n"); + IPicture_Release(newpic); + *ppvObj = NULL; + return hr; + } + IPersistStream_Load(ps,lpstream); + IPersistStream_Release(ps); + hr = IPicture_QueryInterface(newpic,riid,ppvObj); + if (hr) + FIXME("Failed to get interface %s from IPicture.\n",debugstr_guid(riid)); + IPicture_Release(newpic); + return hr; +} + +/******************************************************************************* + * StdPic ClassFactory + */ +typedef struct +{ + /* IUnknown fields */ + IClassFactoryVtbl *lpVtbl; + DWORD ref; +} IClassFactoryImpl; + +static HRESULT WINAPI +SPCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) { + IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + + FIXME("(%p)->(%s,%p),stub!\n",This,debugstr_guid(riid),ppobj); + return E_NOINTERFACE; +} + +static ULONG WINAPI +SPCF_AddRef(LPCLASSFACTORY iface) { + IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + return InterlockedIncrement(&This->ref); +} + +static ULONG WINAPI SPCF_Release(LPCLASSFACTORY iface) { + IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + /* static class, won't be freed */ + return InterlockedDecrement(&This->ref); +} + +static HRESULT WINAPI SPCF_CreateInstance( + LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj +) { + PICTDESC pd; + + FIXME("(%p,%p,%s,%p), creating stdpic with PICTYPE_NONE.\n",iface,pOuter,debugstr_guid(riid),ppobj); + pd.cbSizeofstruct = sizeof(pd); + pd.picType = PICTYPE_NONE; + return OleCreatePictureIndirect(&pd,riid,TRUE,ppobj); + +} + +static HRESULT WINAPI SPCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) { + IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + FIXME("(%p)->(%d),stub!\n",This,dolock); + return S_OK; +} + +static IClassFactoryVtbl SPCF_Vtbl = { + SPCF_QueryInterface, + SPCF_AddRef, + SPCF_Release, + SPCF_CreateInstance, + SPCF_LockServer +}; +static IClassFactoryImpl STDPIC_CF = {&SPCF_Vtbl, 1 }; + +void _get_STDPIC_CF(LPVOID *ppv) { *ppv = (LPVOID)&STDPIC_CF; } diff --git a/reactos/lib/oleaut32/regsvr.c b/reactos/lib/oleaut32/regsvr.c new file mode 100644 index 00000000000..6272f240d69 --- /dev/null +++ b/reactos/lib/oleaut32/regsvr.c @@ -0,0 +1,580 @@ +/* + * self-registerable dll functions for oleaut32.dll + * + * Copyright (C) 2003 John K. Hohm + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include + +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "winreg.h" +#include "winerror.h" + +#include "ole2.h" +#include "olectl.h" +#include "oleauto.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(ole); + +/* + * Near the bottom of this file are the exported DllRegisterServer and + * DllUnregisterServer, which make all this worthwhile. + */ + +/*********************************************************************** + * interface for self-registering + */ +struct regsvr_interface +{ + IID const *iid; /* NULL for end of list */ + LPCSTR name; /* can be NULL to omit */ + IID const *base_iid; /* can be NULL to omit */ + int num_methods; /* can be <0 to omit */ + CLSID const *ps_clsid; /* can be NULL to omit */ + CLSID const *ps_clsid32; /* can be NULL to omit */ +}; + +static HRESULT register_interfaces(struct regsvr_interface const *list); +static HRESULT unregister_interfaces(struct regsvr_interface const *list); + +struct regsvr_coclass +{ + CLSID const *clsid; /* NULL for end of list */ + LPCSTR name; /* can be NULL to omit */ + LPCSTR ips; /* can be NULL to omit */ + LPCSTR ips32; /* can be NULL to omit */ + LPCSTR ips32_tmodel; /* can be NULL to omit */ + LPCSTR clsid_str; /* can be NULL to omit */ + LPCSTR progid; /* can be NULL to omit */ +}; + +static HRESULT register_coclasses(struct regsvr_coclass const *list); +static HRESULT unregister_coclasses(struct regsvr_coclass const *list); + +/*********************************************************************** + * static string constants + */ +static WCHAR const interface_keyname[10] = { + 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', 'e', 0 }; +static WCHAR const base_ifa_keyname[14] = { + 'B', 'a', 's', 'e', 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', + 'e', 0 }; +static WCHAR const num_methods_keyname[11] = { + 'N', 'u', 'm', 'M', 'e', 't', 'h', 'o', 'd', 's', 0 }; +static WCHAR const ps_clsid_keyname[15] = { + 'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's', + 'i', 'd', 0 }; +static WCHAR const ps_clsid32_keyname[17] = { + 'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's', + 'i', 'd', '3', '2', 0 }; +static WCHAR const clsid_keyname[6] = { + 'C', 'L', 'S', 'I', 'D', 0 }; +static WCHAR const ips_keyname[13] = { + 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r', + 0 }; +static WCHAR const ips32_keyname[15] = { + 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r', + '3', '2', 0 }; +static WCHAR const progid_keyname[7] = { + 'P', 'r', 'o', 'g', 'I', 'D', 0 }; +static char const tmodel_valuename[] = "ThreadingModel"; + +/*********************************************************************** + * static helper functions + */ +static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid); +static LONG register_key_defvalueW(HKEY base, WCHAR const *name, + WCHAR const *value); +static LONG register_key_defvalueA(HKEY base, WCHAR const *name, + char const *value); +static LONG recursive_delete_key(HKEY key); +static LONG recursive_delete_keyA(HKEY base, char const *name); +static LONG recursive_delete_keyW(HKEY base, WCHAR const *name); + +/*********************************************************************** + * register_interfaces + */ +static HRESULT register_interfaces(struct regsvr_interface const *list) +{ + LONG res = ERROR_SUCCESS; + HKEY interface_key; + + res = RegCreateKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0, NULL, 0, + KEY_READ | KEY_WRITE, NULL, &interface_key, NULL); + if (res != ERROR_SUCCESS) goto error_return; + + for (; res == ERROR_SUCCESS && list->iid; ++list) { + WCHAR buf[39]; + HKEY iid_key; + + StringFromGUID2(list->iid, buf, 39); + res = RegCreateKeyExW(interface_key, buf, 0, NULL, 0, + KEY_READ | KEY_WRITE, NULL, &iid_key, NULL); + if (res != ERROR_SUCCESS) goto error_close_interface_key; + + if (list->name) { + res = RegSetValueExA(iid_key, NULL, 0, REG_SZ, + (CONST BYTE*)(list->name), + strlen(list->name) + 1); + if (res != ERROR_SUCCESS) goto error_close_iid_key; + } + + if (list->base_iid) { + register_key_guid(iid_key, base_ifa_keyname, list->base_iid); + if (res != ERROR_SUCCESS) goto error_close_iid_key; + } + + if (0 <= list->num_methods) { + static WCHAR const fmt[3] = { '%', 'd', 0 }; + HKEY key; + + res = RegCreateKeyExW(iid_key, num_methods_keyname, 0, NULL, 0, + KEY_READ | KEY_WRITE, NULL, &key, NULL); + if (res != ERROR_SUCCESS) goto error_close_iid_key; + + wsprintfW(buf, fmt, list->num_methods); + res = RegSetValueExW(key, NULL, 0, REG_SZ, + (CONST BYTE*)buf, + (lstrlenW(buf) + 1) * sizeof(WCHAR)); + RegCloseKey(key); + + if (res != ERROR_SUCCESS) goto error_close_iid_key; + } + + if (list->ps_clsid) { + register_key_guid(iid_key, ps_clsid_keyname, list->ps_clsid); + if (res != ERROR_SUCCESS) goto error_close_iid_key; + } + + if (list->ps_clsid32) { + register_key_guid(iid_key, ps_clsid32_keyname, list->ps_clsid32); + if (res != ERROR_SUCCESS) goto error_close_iid_key; + } + + error_close_iid_key: + RegCloseKey(iid_key); + } + +error_close_interface_key: + RegCloseKey(interface_key); +error_return: + return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; +} + +/*********************************************************************** + * unregister_interfaces + */ +static HRESULT unregister_interfaces(struct regsvr_interface const *list) +{ + LONG res = ERROR_SUCCESS; + HKEY interface_key; + + res = RegOpenKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0, + KEY_READ | KEY_WRITE, &interface_key); + if (res == ERROR_FILE_NOT_FOUND) return S_OK; + if (res != ERROR_SUCCESS) goto error_return; + + for (; res == ERROR_SUCCESS && list->iid; ++list) { + WCHAR buf[39]; + + StringFromGUID2(list->iid, buf, 39); + res = recursive_delete_keyW(interface_key, buf); + } + + RegCloseKey(interface_key); +error_return: + return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; +} + +/*********************************************************************** + * register_coclasses + */ +static HRESULT register_coclasses(struct regsvr_coclass const *list) +{ + LONG res = ERROR_SUCCESS; + HKEY coclass_key; + + res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0, + KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL); + if (res != ERROR_SUCCESS) goto error_return; + + for (; res == ERROR_SUCCESS && list->clsid; ++list) { + WCHAR buf[39]; + HKEY clsid_key; + + StringFromGUID2(list->clsid, buf, 39); + res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0, + KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL); + if (res != ERROR_SUCCESS) goto error_close_coclass_key; + + if (list->name) { + res = RegSetValueExA(clsid_key, NULL, 0, REG_SZ, + (CONST BYTE*)(list->name), + strlen(list->name) + 1); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + } + + if (list->ips) { + res = register_key_defvalueA(clsid_key, ips_keyname, list->ips); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + } + + if (list->ips32) { + HKEY ips32_key; + + res = RegCreateKeyExW(clsid_key, ips32_keyname, 0, NULL, 0, + KEY_READ | KEY_WRITE, NULL, + &ips32_key, NULL); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + + res = RegSetValueExA(ips32_key, NULL, 0, REG_SZ, + (CONST BYTE*)list->ips32, + lstrlenA(list->ips32) + 1); + if (res == ERROR_SUCCESS && list->ips32_tmodel) + res = RegSetValueExA(ips32_key, tmodel_valuename, 0, REG_SZ, + (CONST BYTE*)list->ips32_tmodel, + strlen(list->ips32_tmodel) + 1); + RegCloseKey(ips32_key); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + } + + if (list->clsid_str) { + res = register_key_defvalueA(clsid_key, clsid_keyname, + list->clsid_str); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + } + + if (list->progid) { + HKEY progid_key; + + res = register_key_defvalueA(clsid_key, progid_keyname, + list->progid); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + + res = RegCreateKeyExA(HKEY_CLASSES_ROOT, list->progid, 0, + NULL, 0, KEY_READ | KEY_WRITE, NULL, + &progid_key, NULL); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + + res = register_key_defvalueW(progid_key, clsid_keyname, buf); + RegCloseKey(progid_key); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + } + + error_close_clsid_key: + RegCloseKey(clsid_key); + } + +error_close_coclass_key: + RegCloseKey(coclass_key); +error_return: + return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; +} + +/*********************************************************************** + * unregister_coclasses + */ +static HRESULT unregister_coclasses(struct regsvr_coclass const *list) +{ + LONG res = ERROR_SUCCESS; + HKEY coclass_key; + + res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, + KEY_READ | KEY_WRITE, &coclass_key); + if (res == ERROR_FILE_NOT_FOUND) return S_OK; + if (res != ERROR_SUCCESS) goto error_return; + + for (; res == ERROR_SUCCESS && list->clsid; ++list) { + WCHAR buf[39]; + + StringFromGUID2(list->clsid, buf, 39); + res = recursive_delete_keyW(coclass_key, buf); + if (res != ERROR_SUCCESS) goto error_close_coclass_key; + + if (list->progid) { + res = recursive_delete_keyA(HKEY_CLASSES_ROOT, list->progid); + if (res != ERROR_SUCCESS) goto error_close_coclass_key; + } + } + +error_close_coclass_key: + RegCloseKey(coclass_key); +error_return: + return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; +} + +/*********************************************************************** + * regsvr_key_guid + */ +static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid) +{ + WCHAR buf[39]; + + StringFromGUID2(guid, buf, 39); + return register_key_defvalueW(base, name, buf); +} + +/*********************************************************************** + * regsvr_key_defvalueW + */ +static LONG register_key_defvalueW( + HKEY base, + WCHAR const *name, + WCHAR const *value) +{ + LONG res; + HKEY key; + + res = RegCreateKeyExW(base, name, 0, NULL, 0, + KEY_READ | KEY_WRITE, NULL, &key, NULL); + if (res != ERROR_SUCCESS) return res; + res = RegSetValueExW(key, NULL, 0, REG_SZ, (CONST BYTE*)value, + (lstrlenW(value) + 1) * sizeof(WCHAR)); + RegCloseKey(key); + return res; +} + +/*********************************************************************** + * regsvr_key_defvalueA + */ +static LONG register_key_defvalueA( + HKEY base, + WCHAR const *name, + char const *value) +{ + LONG res; + HKEY key; + + res = RegCreateKeyExW(base, name, 0, NULL, 0, + KEY_READ | KEY_WRITE, NULL, &key, NULL); + if (res != ERROR_SUCCESS) return res; + res = RegSetValueExA(key, NULL, 0, REG_SZ, (CONST BYTE*)value, + lstrlenA(value) + 1); + RegCloseKey(key); + return res; +} + +/*********************************************************************** + * recursive_delete_key + */ +static LONG recursive_delete_key(HKEY key) +{ + LONG res; + WCHAR subkey_name[MAX_PATH]; + DWORD cName; + HKEY subkey; + + for (;;) { + cName = sizeof(subkey_name) / sizeof(WCHAR); + res = RegEnumKeyExW(key, 0, subkey_name, &cName, + NULL, NULL, NULL, NULL); + if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) { + res = ERROR_SUCCESS; /* presumably we're done enumerating */ + break; + } + res = RegOpenKeyExW(key, subkey_name, 0, + KEY_READ | KEY_WRITE, &subkey); + if (res == ERROR_FILE_NOT_FOUND) continue; + if (res != ERROR_SUCCESS) break; + + res = recursive_delete_key(subkey); + RegCloseKey(subkey); + if (res != ERROR_SUCCESS) break; + } + + if (res == ERROR_SUCCESS) res = RegDeleteKeyW(key, 0); + return res; +} + +/*********************************************************************** + * recursive_delete_keyA + */ +static LONG recursive_delete_keyA(HKEY base, char const *name) +{ + LONG res; + HKEY key; + + res = RegOpenKeyExA(base, name, 0, KEY_READ | KEY_WRITE, &key); + if (res == ERROR_FILE_NOT_FOUND) return ERROR_SUCCESS; + if (res != ERROR_SUCCESS) return res; + res = recursive_delete_key(key); + RegCloseKey(key); + return res; +} + +/*********************************************************************** + * recursive_delete_keyW + */ +static LONG recursive_delete_keyW(HKEY base, WCHAR const *name) +{ + LONG res; + HKEY key; + + res = RegOpenKeyExW(base, name, 0, KEY_READ | KEY_WRITE, &key); + if (res == ERROR_FILE_NOT_FOUND) return ERROR_SUCCESS; + if (res != ERROR_SUCCESS) return res; + res = recursive_delete_key(key); + RegCloseKey(key); + return res; +} + +/*********************************************************************** + * coclass list + */ +static GUID const CLSID_RecordInfo = { + 0x0000002F, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} }; + +extern GUID const CLSID_PSDispatch; + +static GUID const CLSID_PSEnumVariant = { + 0x00020421, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} }; + +static GUID const CLSID_PSTypeInfo = { + 0x00020422, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} }; + +static GUID const CLSID_PSTypeLib = { + 0x00020423, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} }; + +extern GUID const CLSID_PSOAInterface; + +static GUID const CLSID_PSTypeComp = { + 0x00020425, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} }; + +static GUID const CLSID_OldFont = { + 0x46763EE0, 0xCAB2, 0x11CE, {0x8C,0x20,0x00,0xAA,0x00,0x51,0xE5,0xD4} }; + +static GUID const CLSID_PSFactoryBuffer = { + 0xB196B286, 0xBAB4, 0x101A, {0xB6,0x9C,0x00,0xAA,0x00,0x34,0x1D,0x07} }; + +static struct regsvr_coclass const coclass_list[] = { + { &CLSID_RecordInfo, + "CLSID_RecordInfo", + NULL, + "oleaut32.dll", + "Both" + }, + { &CLSID_PSDispatch, + "PSDispatch", + "ole2disp.dll", + "oleaut32.dll", + "Both" + }, + { &CLSID_StdFont, + "CLSID_StdFont", + NULL, + "oleaut32.dll", + "Both", + "Standard Font", + "StdFont" + }, + { &CLSID_StdPicture, + "CLSID_StdPict", + NULL, + "oleaut32.dll", + "Apartment", + "Standard Picture", + "StdPicture" + }, + { &CLSID_PSEnumVariant, + "PSEnumVariant", + "ole2disp.dll", + "oleaut32.dll", + "Both" + }, + { &CLSID_PSTypeInfo, + "PSTypeInfo", + "ole2disp.dll", + "oleaut32.dll", + "Both" + }, + { &CLSID_PSTypeLib, + "PSTypeLib", + "ole2disp.dll", + "oleaut32.dll", + "Both" + }, + { &CLSID_PSOAInterface, + "PSOAInterface", + "ole2disp.dll", + "oleaut32.dll", + "Both" + }, + { &CLSID_PSTypeComp, + "PSTypeComp", + "ole2disp.dll", + "oleaut32.dll", + "Both" + }, + { &CLSID_OldFont, + "Obsolete Font", + NULL, + "oleaut32.dll", + NULL, + "Obsolete Font", + "OldFont" + }, + { &CLSID_PSFactoryBuffer, + "PSFactoryBuffer", + NULL, + "oleaut32.dll", + "Both" + }, + { NULL } /* list terminator */ +}; + +/*********************************************************************** + * interface list + */ + +static struct regsvr_interface const interface_list[] = { + { NULL } /* list terminator */ +}; + +/*********************************************************************** + * DllRegisterServer (OLEAUT32.320) + */ +HRESULT WINAPI OLEAUT32_DllRegisterServer() +{ + HRESULT hr; + + TRACE("\n"); + + hr = register_coclasses(coclass_list); + if (SUCCEEDED(hr)) + hr = register_interfaces(interface_list); + return hr; +} + +/*********************************************************************** + * DllUnregisterServer (OLEAUT32.321) + */ +HRESULT WINAPI OLEAUT32_DllUnregisterServer() +{ + HRESULT hr; + + TRACE("\n"); + + hr = unregister_coclasses(coclass_list); + if (SUCCEEDED(hr)) + hr = unregister_interfaces(interface_list); + return hr; +} diff --git a/reactos/lib/oleaut32/resource.h b/reactos/lib/oleaut32/resource.h new file mode 100644 index 00000000000..b3adfe623c7 --- /dev/null +++ b/reactos/lib/oleaut32/resource.h @@ -0,0 +1,46 @@ +/* + * Resource defines for oleaut32 + * + * Copyright 2003 Jon Griffiths + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef WINE_OLEAUT32_RESOURCE_H +#define WINE_OLEAUT32_RESOURCE_H + +/* Localised boolean text */ +#define IDS_TRUE 100 +#define IDS_FALSE 101 +#define IDS_YES 102 +#define IDS_NO 103 +#define IDS_ON 104 +#define IDS_OFF 105 +/* Alternative month names. Note in XP these are localised only for Russian, + * Polish and Arabic. + */ +#define IDS_MTH_1 106 +#define IDS_MTH_2 107 +#define IDS_MTH_3 108 +#define IDS_MTH_4 109 +#define IDS_MTH_5 110 +#define IDS_MTH_6 111 +#define IDS_MTH_7 112 +#define IDS_MTH_8 113 +#define IDS_MTH_9 114 +#define IDS_MTH_10 115 +#define IDS_MTH_11 116 +#define IDS_MTH_12 117 + +#endif /* WINE_OLEAUT32_RESOURCE_H */ diff --git a/reactos/lib/oleaut32/safearray.c b/reactos/lib/oleaut32/safearray.c new file mode 100644 index 00000000000..dca1ba2298d --- /dev/null +++ b/reactos/lib/oleaut32/safearray.c @@ -0,0 +1,1734 @@ +/************************************************************************* + * OLE Automation - SafeArray + * + * This file contains the implementation of the SafeArray functions. + * + * Copyright 1999 Sylvain St-Germain + * Copyright 2002-2003 Marcus Meissner + * Copyright 2003 Jon Griffiths + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +/* Memory Layout of a SafeArray: + * + * -0x10: start of memory. + * -0x10: GUID for VT_DISPATCH and VT_UNKNOWN safearrays (if FADF_HAVEIID) + * -0x04: DWORD varianttype; (for all others, except VT_RECORD) (if FADF_HAVEVARTYPE) + * -0x4: IRecordInfo* iface; (if FADF_RECORD, for VT_RECORD (can be NULL)) + * 0x00: SAFEARRAY, + * 0x10: SAFEARRAYBOUNDS[0...] + */ + +#include "config.h" + +#include +#include +#include + +#define COBJMACROS + +#include "windef.h" +#include "winerror.h" +#include "winbase.h" +#include "variant.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(variant); + +/************************************************************************ + * SafeArray {OLEAUT32} + * + * NOTES + * The SafeArray data type provides the underlying interface for Ole + * Automations arrays, used for example to represent array types in + * Visual Basic(tm) and to gather user defined parameters for invocation through + * an IDispatch interface. + * + * Safe arrays provide bounds checking and automatically manage the data + * types they contain, for example handing reference counting and copying + * of interface pointers. User defined types can be stored in arrays + * using the IRecordInfo interface. + * + * There are two types of SafeArray, normal and vectors. Normal arrays can have + * multiple dimensions and the data for the array is allocated separately from + * the array header. This is the most flexible type of array. Vectors, on the + * other hand, are fixed in size and consist of a single allocated block, and a + * single dimension. + * + * DATATYPES + * The following types of data can be stored within a SafeArray. + * Numeric: + *| VT_I1, VT_UI1, VT_I2, VT_UI2, VT_I4, VT_UI4, VT_I8, VT_UI8, VT_INT, VT_UINT, + *| VT_R4, VT_R8, VT_CY, VT_DECIMAL + * Interfaces: + *| VT_DISPATCH, VT_UNKNOWN, VT_RECORD + * Other: + *| VT_VARIANT, VT_INT_PTR, VT_UINT_PTR, VT_BOOL, VT_ERROR, VT_DATE, VT_BSTR + * + * FUNCTIONS + * BstrFromVector() + * VectorFromBstr() + */ + +/* Undocumented hidden space before the start of a SafeArray descriptor */ +#define SAFEARRAY_HIDDEN_SIZE sizeof(GUID) + +/* Allocate memory */ +static inline LPVOID SAFEARRAY_Malloc(ULONG ulSize) +{ + /* FIXME: Memory should be allocated and freed using a per-thread IMalloc + * instance returned from CoGetMalloc(). + */ + return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ulSize); +} + +/* Free memory */ +static inline BOOL SAFEARRAY_Free(LPVOID lpData) +{ + return HeapFree(GetProcessHeap(), 0, lpData); +} + +/* Get the size of a supported VT type (0 means unsupported) */ +static DWORD SAFEARRAY_GetVTSize(VARTYPE vt) +{ + switch (vt) + { + case VT_I1: + case VT_UI1: return sizeof(BYTE); + case VT_BOOL: + case VT_I2: + case VT_UI2: return sizeof(SHORT); + case VT_I4: + case VT_UI4: + case VT_R4: + case VT_ERROR: return sizeof(LONG); + case VT_R8: + case VT_I8: + case VT_UI8: return sizeof(LONG64); + case VT_INT: + case VT_UINT: return sizeof(INT); + case VT_INT_PTR: + case VT_UINT_PTR: return sizeof(UINT_PTR); + case VT_CY: return sizeof(CY); + case VT_DATE: return sizeof(DATE); + case VT_BSTR: return sizeof(BSTR); + case VT_DISPATCH: return sizeof(LPDISPATCH); + case VT_VARIANT: return sizeof(VARIANT); + case VT_UNKNOWN: return sizeof(LPUNKNOWN); + case VT_DECIMAL: return sizeof(DECIMAL); + /* Note: Return a non-zero size to indicate vt is valid. The actual size + * of a UDT is taken from the result of IRecordInfo_GetSize(). + */ + case VT_RECORD: return 32; + } + return 0; +} + +/* Set the hidden data for an array */ +static inline void SAFEARRAY_SetHiddenDWORD(SAFEARRAY* psa, DWORD dw) +{ + /* Implementation data is stored in the 4 bytes before the header */ + LPDWORD lpDw = (LPDWORD)psa; + lpDw[-1] = dw; +} + +/* Get the hidden data from an array */ +static inline DWORD SAFEARRAY_GetHiddenDWORD(SAFEARRAY* psa) +{ + LPDWORD lpDw = (LPDWORD)psa; + return lpDw[-1]; +} + +/* Get the number of cells in a SafeArray */ +static ULONG SAFEARRAY_GetCellCount(const SAFEARRAY *psa) +{ + SAFEARRAYBOUND* psab = psa->rgsabound; + USHORT cCount = psa->cDims; + ULONG ulNumCells = 1; + + while (cCount--) + { + /* This is a valid bordercase. See testcases. -Marcus */ + if (!psab->cElements) + return 0; + ulNumCells *= psab->cElements; + psab++; + } + return ulNumCells; +} + +/* Get the 0 based index of an index into a dimension */ +static inline ULONG SAFEARRAY_GetDimensionIndex(SAFEARRAYBOUND *psab, ULONG ulIndex) +{ + return ulIndex - psab->lLbound; +} + +/* Get the size of a dimension in cells */ +static inline ULONG SAFEARRAY_GetDimensionCells(SAFEARRAY *psa, ULONG ulDim) +{ + ULONG size = psa->rgsabound[0].cElements; + + while (ulDim) + { + size *= psa->rgsabound[ulDim].cElements; + ulDim--; + } + return size; +} + +/* Allocate a descriptor for an array */ +static HRESULT SAFEARRAY_AllocDescriptor(ULONG ulSize, SAFEARRAY **ppsaOut) +{ + *ppsaOut = (SAFEARRAY*)((char*)SAFEARRAY_Malloc(ulSize + SAFEARRAY_HIDDEN_SIZE) + SAFEARRAY_HIDDEN_SIZE); + + if (!*ppsaOut) + return E_UNEXPECTED; + + return S_OK; +} + +/* Set the features of an array */ +static void SAFEARRAY_SetFeatures(VARTYPE vt, SAFEARRAY *psa) +{ + /* Set the IID if we have one, otherwise set the type */ + if (vt == VT_DISPATCH) + { + psa->fFeatures = FADF_HAVEIID; + SafeArraySetIID(psa, &IID_IDispatch); + } + else if (vt == VT_UNKNOWN) + { + psa->fFeatures = FADF_HAVEIID; + SafeArraySetIID(psa, &IID_IUnknown); + } + else if (vt == VT_RECORD) + psa->fFeatures = FADF_RECORD; + else + { + psa->fFeatures = FADF_HAVEVARTYPE; + SAFEARRAY_SetHiddenDWORD(psa, vt); + } +} + +/* Create an array */ +static SAFEARRAY* SAFEARRAY_Create(VARTYPE vt, UINT cDims, SAFEARRAYBOUND *rgsabound, ULONG ulSize) +{ + SAFEARRAY *psa = NULL; + + if (!rgsabound) + return NULL; + + if (SUCCEEDED(SafeArrayAllocDescriptorEx(vt, cDims, &psa))) + { + switch (vt) + { + case VT_BSTR: psa->fFeatures |= FADF_BSTR; break; + case VT_UNKNOWN: psa->fFeatures |= FADF_UNKNOWN; break; + case VT_DISPATCH: psa->fFeatures |= FADF_DISPATCH; break; + case VT_VARIANT: psa->fFeatures |= FADF_VARIANT; break; + } + + memcpy(psa->rgsabound, rgsabound, cDims * sizeof(SAFEARRAYBOUND)); + + if (ulSize) + psa->cbElements = ulSize; + + if (FAILED(SafeArrayAllocData(psa))) + { + SafeArrayDestroyDescriptor(psa); + psa = NULL; + } + } + return psa; +} + +/* Create an array as a vector */ +static SAFEARRAY* SAFEARRAY_CreateVector(VARTYPE vt, LONG lLbound, ULONG cElements, ULONG ulSize) +{ + SAFEARRAY *psa = NULL; + + if (ulSize || (vt == VT_RECORD)) + { + /* Allocate the header and data together */ + if (SUCCEEDED(SAFEARRAY_AllocDescriptor(sizeof(SAFEARRAY) + ulSize * cElements, &psa))) + { + SAFEARRAY_SetFeatures(vt, psa); + + psa->cDims = 1; + psa->fFeatures |= FADF_CREATEVECTOR; + psa->pvData = &psa[1]; /* Data follows the header */ + psa->cbElements = ulSize; + psa->rgsabound[0].cElements = cElements; + psa->rgsabound[0].lLbound = lLbound; + + switch (vt) + { + case VT_BSTR: psa->fFeatures |= FADF_BSTR; break; + case VT_UNKNOWN: psa->fFeatures |= FADF_UNKNOWN; break; + case VT_DISPATCH: psa->fFeatures |= FADF_DISPATCH; break; + case VT_VARIANT: psa->fFeatures |= FADF_VARIANT; break; + } + } + } + return psa; +} + +/* Free data items in an array */ +static HRESULT SAFEARRAY_DestroyData(SAFEARRAY *psa, ULONG ulStartCell) +{ + if (psa->pvData && !(psa->fFeatures & FADF_DATADELETED)) + { + ULONG ulCellCount = SAFEARRAY_GetCellCount(psa); + + if (ulStartCell > ulCellCount) { + FIXME("unexpted ulcellcount %ld, start %ld\n",ulCellCount,ulStartCell); + return E_UNEXPECTED; + } + + ulCellCount -= ulStartCell; + + if (psa->fFeatures & (FADF_UNKNOWN|FADF_DISPATCH)) + { + LPUNKNOWN *lpUnknown = (LPUNKNOWN *)psa->pvData + ulStartCell * psa->cbElements; + + while(ulCellCount--) + { + if (*lpUnknown) + IUnknown_Release(*lpUnknown); + lpUnknown++; + } + } + else if (psa->fFeatures & (FADF_RECORD)) + { + IRecordInfo *lpRecInfo; + + if (SUCCEEDED(SafeArrayGetRecordInfo(psa, &lpRecInfo))) + { + PBYTE pRecordData = (PBYTE)psa->pvData; + while(ulCellCount--) + { + IRecordInfo_RecordClear(lpRecInfo, pRecordData); + pRecordData += psa->cbElements; + } + IRecordInfo_Release(lpRecInfo); + } + } + else if (psa->fFeatures & FADF_BSTR) + { + BSTR* lpBstr = (BSTR*)psa->pvData + ulStartCell * psa->cbElements; + + while(ulCellCount--) + { + if (*lpBstr) + SysFreeString(*lpBstr); + lpBstr++; + } + } + else if (psa->fFeatures & FADF_VARIANT) + { + VARIANT* lpVariant = (VARIANT*)psa->pvData + ulStartCell * psa->cbElements; + + while(ulCellCount--) + { + HRESULT hRet = VariantClear(lpVariant); + + if (FAILED(hRet)) FIXME("VariantClear of element failed!\n"); + lpVariant++; + } + } + } + return S_OK; +} + +/* Copy data items from one array to another */ +static HRESULT SAFEARRAY_CopyData(SAFEARRAY *psa, SAFEARRAY *dest) +{ + if (!psa->pvData || !dest->pvData || psa->fFeatures & FADF_DATADELETED) + return E_INVALIDARG; + else + { + ULONG ulCellCount = SAFEARRAY_GetCellCount(psa); + + dest->fFeatures = (dest->fFeatures & FADF_CREATEVECTOR) | + (psa->fFeatures & ~(FADF_CREATEVECTOR|FADF_DATADELETED)); + + if (psa->fFeatures & FADF_VARIANT) + { + VARIANT* lpVariant = (VARIANT*)psa->pvData; + VARIANT* lpDest = (VARIANT*)dest->pvData; + + while(ulCellCount--) + { + HRESULT hRet; + + hRet = VariantCopy(lpDest, lpVariant); + if (FAILED(hRet)) FIXME("VariantCopy failed with 0x%lx\n", hRet); + lpVariant++; + lpDest++; + } + } + else if (psa->fFeatures & FADF_BSTR) + { + BSTR* lpBstr = (BSTR*)psa->pvData; + BSTR* lpDest = (BSTR*)dest->pvData; + + while(ulCellCount--) + { + if (*lpBstr) + { + *lpDest = SysAllocStringByteLen((char*)*lpBstr, SysStringByteLen(*lpBstr)); + if (!*lpDest) + return E_OUTOFMEMORY; + } + else + *lpDest = NULL; + lpBstr++; + lpDest++; + } + } + else + { + /* Copy the data over */ + memcpy(dest->pvData, psa->pvData, ulCellCount * psa->cbElements); + + if (psa->fFeatures & (FADF_UNKNOWN|FADF_DISPATCH)) + { + LPUNKNOWN *lpUnknown = (LPUNKNOWN *)dest->pvData; + + while(ulCellCount--) + { + if (*lpUnknown) + IUnknown_AddRef(*lpUnknown); + lpUnknown++; + } + } + } + + if (psa->fFeatures & FADF_RECORD) + { + IRecordInfo* pRecInfo = NULL; + + SafeArrayGetRecordInfo(psa, &pRecInfo); + SafeArraySetRecordInfo(dest, pRecInfo); + + if (pRecInfo) + { + /* Release because Get() adds a reference */ + IRecordInfo_Release(pRecInfo); + } + } + else if (psa->fFeatures & FADF_HAVEIID) + { + GUID guid; + SafeArrayGetIID(psa, &guid); + SafeArraySetIID(dest, &guid); + } + else if (psa->fFeatures & FADF_HAVEVARTYPE) + { + SAFEARRAY_SetHiddenDWORD(dest, SAFEARRAY_GetHiddenDWORD(psa)); + } + } + return S_OK; +} + +/************************************************************************* + * SafeArrayAllocDescriptor (OLEAUT32.36) + * + * Allocate and initialise a descriptor for a SafeArray. + * + * PARAMS + * cDims [I] Number of dimensions of the array + * ppsaOut [O] Destination for new descriptor + * + * RETURNS + * Success: S_OK. ppsaOut is filled with a newly allocated descriptor. + * Failure: An HRESULT error code indicating the error. + * + * NOTES + * See SafeArray. + */ +HRESULT WINAPI SafeArrayAllocDescriptor(UINT cDims, SAFEARRAY **ppsaOut) +{ + LONG allocSize; + + TRACE("(%d,%p)\n", cDims, ppsaOut); + + if (!cDims || cDims >= 0x10000) /* Maximum 65535 dimensions */ + return E_INVALIDARG; + + if (!ppsaOut) + return E_POINTER; + + /* We need enough space for the header and its bounds */ + allocSize = sizeof(SAFEARRAY) + sizeof(SAFEARRAYBOUND) * (cDims - 1); + + if (FAILED(SAFEARRAY_AllocDescriptor(allocSize, ppsaOut))) + return E_UNEXPECTED; + + (*ppsaOut)->cDims = cDims; + + TRACE("(%d): %lu bytes allocated for descriptor.\n", cDims, allocSize); + return S_OK; +} + +/************************************************************************* + * SafeArrayAllocDescriptorEx (OLEAUT32.41) + * + * Allocate and initialise a descriptor for a SafeArray of a given type. + * + * PARAMS + * vt [I] The type of items to store in the array + * cDims [I] Number of dimensions of the array + * ppsaOut [O] Destination for new descriptor + * + * RETURNS + * Success: S_OK. ppsaOut is filled with a newly allocated descriptor. + * Failure: An HRESULT error code indicating the error. + * + * NOTES + * - This function does not chack that vt is an allowed VARTYPE. + * - Unlike SafeArrayAllocDescriptor(), vt is associated with the array. + * See SafeArray. + */ +HRESULT WINAPI SafeArrayAllocDescriptorEx(VARTYPE vt, UINT cDims, SAFEARRAY **ppsaOut) +{ + ULONG cbElements; + HRESULT hRet = E_UNEXPECTED; + + TRACE("(%d->%s,%d,%p)\n", vt, debugstr_vt(vt), cDims, ppsaOut); + + cbElements = SAFEARRAY_GetVTSize(vt); + if (!cbElements) + WARN("Creating a descriptor with an invalid VARTYPE!\n"); + + hRet = SafeArrayAllocDescriptor(cDims, ppsaOut); + + if (SUCCEEDED(hRet)) + { + SAFEARRAY_SetFeatures(vt, *ppsaOut); + (*ppsaOut)->cbElements = cbElements; + } + return hRet; +} + +/************************************************************************* + * SafeArrayAllocData (OLEAUT32.37) + * + * Allocate the data area of a SafeArray. + * + * PARAMS + * psa [I] SafeArray to allocate the data area of. + * + * RETURNS + * Success: S_OK. The data area is allocated and initialised. + * Failure: An HRESULT error code indicating the error. + * + * NOTES + * See SafeArray. + */ +HRESULT WINAPI SafeArrayAllocData(SAFEARRAY *psa) +{ + HRESULT hRet = E_INVALIDARG; + + TRACE("(%p)\n", psa); + + if (psa) + { + ULONG ulSize = SAFEARRAY_GetCellCount(psa); + + hRet = E_OUTOFMEMORY; + + if (psa->cbElements) + { + psa->pvData = SAFEARRAY_Malloc(ulSize * psa->cbElements); + + if (psa->pvData) + { + hRet = S_OK; + TRACE("%lu bytes allocated for data at %p (%lu objects).\n", + ulSize * psa->cbElements, psa->pvData, ulSize); + } + } + } + return hRet; +} + +/************************************************************************* + * SafeArrayCreate (OLEAUT32.15) + * + * Create a new SafeArray. + * + * PARAMS + * vt [I] Type to store in the safe array + * cDims [I] Number of array dimensions + * rgsabound [I] Bounds of the array dimensions + * + * RETURNS + * Success: A pointer to a new array object. + * Failure: NULL, if any parameter is invalid or memory allocation fails. + * + * NOTES + * Win32 allows arrays with 0 sized dimensions. This bug is not reproduced + * in the Wine implementation. + * See SafeArray. + */ +SAFEARRAY* WINAPI SafeArrayCreate(VARTYPE vt, UINT cDims, SAFEARRAYBOUND *rgsabound) +{ + TRACE("(%d->%s,%d,%p)\n", vt, debugstr_vt(vt), cDims, rgsabound); + + if (vt == VT_RECORD) + return NULL; + + return SAFEARRAY_Create(vt, cDims, rgsabound, 0); +} + +/************************************************************************* + * SafeArrayCreateEx (OLEAUT32.15) + * + * Create a new SafeArray. + * + * PARAMS + * vt [I] Type to store in the safe array + * cDims [I] Number of array dimensions + * rgsabound [I] Bounds of the array dimensions + * pvExtra [I] Extra data + * + * RETURNS + * Success: A pointer to a new array object. + * Failure: NULL, if any parameter is invalid or memory allocation fails. + * + * NOTES + * See SafeArray. + */ +SAFEARRAY* WINAPI SafeArrayCreateEx(VARTYPE vt, UINT cDims, SAFEARRAYBOUND *rgsabound, LPVOID pvExtra) +{ + ULONG ulSize = 0; + IRecordInfo* iRecInfo = (IRecordInfo*)pvExtra; + SAFEARRAY* psa; + + TRACE("(%d->%s,%d,%p,%p)\n", vt, debugstr_vt(vt), cDims, rgsabound, pvExtra); + + if (vt == VT_RECORD) + { + if (!iRecInfo) + return NULL; + IRecordInfo_GetSize(iRecInfo, &ulSize); + } + psa = SAFEARRAY_Create(vt, cDims, rgsabound, ulSize); + + if (pvExtra) + { + switch(vt) + { + case VT_RECORD: + SafeArraySetRecordInfo(psa, pvExtra); + break; + case VT_UNKNOWN: + case VT_DISPATCH: + SafeArraySetIID(psa, pvExtra); + break; + } + } + return psa; +} + +/************************************************************************ + * SafeArrayCreateVector (OLEAUT32.411) + * + * Create a one dimensional, contigous SafeArray. + * + * PARAMS + * vt [I] Type to store in the safe array + * lLbound [I] Lower bound of the array + * cElements [I] Number of elements in the array + * + * RETURNS + * Success: A pointer to a new array object. + * Failure: NULL, if any parameter is invalid or memory allocation fails. + * + * NOTES + * See SafeArray. + */ +SAFEARRAY* WINAPI SafeArrayCreateVector(VARTYPE vt, LONG lLbound, ULONG cElements) +{ + TRACE("(%d->%s,%ld,%ld\n", vt, debugstr_vt(vt), lLbound, cElements); + + if (vt == VT_RECORD) + return NULL; + + return SAFEARRAY_CreateVector(vt, lLbound, cElements, SAFEARRAY_GetVTSize(vt)); +} + +/************************************************************************ + * SafeArrayCreateVectorEx (OLEAUT32.411) + * + * Create a one dimensional, contigous SafeArray. + * + * PARAMS + * vt [I] Type to store in the safe array + * lLbound [I] Lower bound of the array + * cElements [I] Number of elements in the array + * pvExtra [I] Extra data + * + * RETURNS + * Success: A pointer to a new array object. + * Failure: NULL, if any parameter is invalid or memory allocation fails. + * + * NOTES + * See SafeArray. + */ +SAFEARRAY* WINAPI SafeArrayCreateVectorEx(VARTYPE vt, LONG lLbound, ULONG cElements, LPVOID pvExtra) +{ + ULONG ulSize; + IRecordInfo* iRecInfo = (IRecordInfo*)pvExtra; + SAFEARRAY* psa; + + TRACE("(%d->%s,%ld,%ld,%p\n", vt, debugstr_vt(vt), lLbound, cElements, pvExtra); + + if (vt == VT_RECORD) + { + if (!iRecInfo) + return NULL; + IRecordInfo_GetSize(iRecInfo, &ulSize); + } + else + ulSize = SAFEARRAY_GetVTSize(vt); + + psa = SAFEARRAY_CreateVector(vt, lLbound, cElements, ulSize); + + if (pvExtra) + { + switch(vt) + { + case VT_RECORD: + SafeArraySetRecordInfo(psa, iRecInfo); + break; + case VT_UNKNOWN: + case VT_DISPATCH: + SafeArraySetIID(psa, pvExtra); + break; + } + } + return psa; +} + +/************************************************************************* + * SafeArrayDestroyDescriptor (OLEAUT32.38) + * + * Destroy a SafeArray. + * + * PARAMS + * psa [I] SafeArray to destroy. + * + * RETURNS + * Success: S_OK. The resources used by the array are freed. + * Failure: An HRESULT error code indicating the error. + * + * NOTES + * See SafeArray. + */ +HRESULT WINAPI SafeArrayDestroyDescriptor(SAFEARRAY *psa) +{ + TRACE("(%p)\n", psa); + + if (psa) + { + LPVOID lpv = (char*)psa - SAFEARRAY_HIDDEN_SIZE; + + if (psa->cLocks) + return DISP_E_ARRAYISLOCKED; /* Can't destroy a locked array */ + + if (psa->fFeatures & FADF_RECORD) + SafeArraySetRecordInfo(psa, NULL); + + if (psa->fFeatures & FADF_CREATEVECTOR && + !(psa->fFeatures & FADF_DATADELETED)) + SAFEARRAY_DestroyData(psa, 0); /* Data not previously deleted */ + + if (!SAFEARRAY_Free(lpv)) + return E_UNEXPECTED; + } + return S_OK; +} + +/************************************************************************* + * SafeArrayLock (OLEAUT32.21) + * + * Increment the lock counter of a SafeArray. + * + * PARAMS + * psa [O] SafeArray to lock + * + * RETURNS + * Success: S_OK. The array lock is incremented. + * Failure: E_INVALIDARG if psa is NULL, or E_UNEXPECTED if too many locks + * are held on the array at once. + * + * NOTES + * In Win32 these locks are not thread safe. + * See SafeArray. + */ +HRESULT WINAPI SafeArrayLock(SAFEARRAY *psa) +{ + ULONG ulLocks; + + TRACE("(%p)\n", psa); + + if (!psa) + return E_INVALIDARG; + + ulLocks = InterlockedIncrement(&psa->cLocks); + + if (ulLocks > 0xffff) /* Maximum of 16384 locks at a time */ + { + WARN("Out of locks!\n"); + InterlockedDecrement(&psa->cLocks); + return E_UNEXPECTED; + } + return S_OK; +} + +/************************************************************************* + * SafeArrayUnlock (OLEAUT32.22) + * + * Decrement the lock counter of a SafeArray. + * + * PARAMS + * psa [O] SafeArray to unlock + * + * RETURNS + * Success: S_OK. The array lock is decremented. + * Failure: E_INVALIDARG if psa is NULL, or E_UNEXPECTED if no locks are + * held on the array. + * + * NOTES + * See SafeArray. + */ +HRESULT WINAPI SafeArrayUnlock(SAFEARRAY *psa) +{ + TRACE("(%p)\n", psa); + + if (!psa) + return E_INVALIDARG; + + if ((LONG)InterlockedDecrement(&psa->cLocks) < 0) + { + WARN("Unlocked but no lock held!\n"); + InterlockedIncrement(&psa->cLocks); + return E_UNEXPECTED; + } + return S_OK; +} + +/************************************************************************* + * SafeArrayPutElement (OLEAUT32.26) + * + * Put an item into a SafeArray. + * + * PARAMS + * psa [I] SafeArray to insert into + * rgIndices [I] Indices to insert at + * pvData [I] Data to insert + * + * RETURNS + * Success: S_OK. The item is inserted + * Failure: An HRESULT error code indicating the error. + * + * NOTES + * See SafeArray. + */ +HRESULT WINAPI SafeArrayPutElement(SAFEARRAY *psa, LONG *rgIndices, void *pvData) +{ + HRESULT hRet; + + TRACE("(%p,%p,%p)\n", psa, rgIndices, pvData); + + if (!psa || !rgIndices) + return E_INVALIDARG; + + if (!pvData) + { + ERR("Invalid pvData would crash under Win32!\n"); + return E_INVALIDARG; + } + + hRet = SafeArrayLock(psa); + + if (SUCCEEDED(hRet)) + { + PVOID lpvDest; + + hRet = SafeArrayPtrOfIndex(psa, rgIndices, &lpvDest); + + if (SUCCEEDED(hRet)) + { + if (psa->fFeatures & FADF_VARIANT) + { + VARIANT* lpVariant = (VARIANT*)pvData; + VARIANT* lpDest = (VARIANT*)lpvDest; + + hRet = VariantClear(lpDest); + if (FAILED(hRet)) FIXME("VariantClear failed with 0x%lx\n", hRet); + hRet = VariantCopy(lpDest, lpVariant); + if (FAILED(hRet)) FIXME("VariantCopy failed with 0x%lx\n", hRet); + } + else if (psa->fFeatures & FADF_BSTR) + { + BSTR lpBstr = (BSTR)pvData; + BSTR* lpDest = (BSTR*)lpvDest; + + if (*lpDest) + SysFreeString(*lpDest); + + if (lpBstr) + { + *lpDest = SysAllocStringByteLen((char*)lpBstr, SysStringByteLen(lpBstr)); + if (!*lpDest) + hRet = E_OUTOFMEMORY; + } + else + *lpDest = NULL; + } + else + { + if (psa->fFeatures & (FADF_UNKNOWN|FADF_DISPATCH)) + { + LPUNKNOWN lpUnknown = (LPUNKNOWN)pvData; + LPUNKNOWN *lpDest = (LPUNKNOWN *)lpvDest; + + if (lpUnknown) + IUnknown_AddRef(lpUnknown); + if (*lpDest) + IUnknown_Release(*lpDest); + *lpDest = lpUnknown; + } else { + /* Copy the data over */ + memcpy(lpvDest, pvData, psa->cbElements); + } + } + } + SafeArrayUnlock(psa); + } + return hRet; +} + + +/************************************************************************* + * SafeArrayGetElement (OLEAUT32.25) + * + * Get an item from a SafeArray. + * + * PARAMS + * psa [I] SafeArray to get from + * rgIndices [I] Indices to get from + * pvData [O] Destination for data + * + * RETURNS + * Success: S_OK. The item data is returned in pvData. + * Failure: An HRESULT error code indicating the error. + * + * NOTES + * See SafeArray. + */ +HRESULT WINAPI SafeArrayGetElement(SAFEARRAY *psa, LONG *rgIndices, void *pvData) +{ + HRESULT hRet; + + TRACE("(%p,%p,%p)\n", psa, rgIndices, pvData); + + if (!psa || !rgIndices || !pvData) + return E_INVALIDARG; + + hRet = SafeArrayLock(psa); + + if (SUCCEEDED(hRet)) + { + PVOID lpvSrc; + + hRet = SafeArrayPtrOfIndex(psa, rgIndices, &lpvSrc); + + if (SUCCEEDED(hRet)) + { + if (psa->fFeatures & FADF_VARIANT) + { + VARIANT* lpVariant = (VARIANT*)lpvSrc; + VARIANT* lpDest = (VARIANT*)pvData; + + /* The original content of pvData is ignored. */ + V_VT(lpDest) = VT_EMPTY; + hRet = VariantCopy(lpDest, lpVariant); + if (FAILED(hRet)) FIXME("VariantCopy failed with 0x%lx\n", hRet); + } + else if (psa->fFeatures & FADF_BSTR) + { + BSTR* lpBstr = (BSTR*)lpvSrc; + BSTR* lpDest = (BSTR*)pvData; + + if (*lpBstr) + { + *lpDest = SysAllocStringByteLen((char*)*lpBstr, SysStringByteLen(*lpBstr)); + if (!*lpBstr) + hRet = E_OUTOFMEMORY; + } + else + *lpDest = NULL; + } + else + { + if (psa->fFeatures & (FADF_UNKNOWN|FADF_DISPATCH)) + { + LPUNKNOWN *lpUnknown = (LPUNKNOWN *)lpvSrc; + + if (*lpUnknown) + IUnknown_AddRef(*lpUnknown); + } + /* Copy the data over */ + memcpy(pvData, lpvSrc, psa->cbElements); + } + } + SafeArrayUnlock(psa); + } + return hRet; +} + +/************************************************************************* + * SafeArrayGetUBound (OLEAUT32.19) + * + * Get the upper bound for a given SafeArray dimension + * + * PARAMS + * psa [I] Array to get dimension upper bound from + * nDim [I] The dimension number to get the upper bound of + * plUbound [O] Destination for the upper bound + * + * RETURNS + * Success: S_OK. plUbound contains the dimensions upper bound. + * Failure: An HRESULT error code indicating the error. + * + * NOTES + * See SafeArray. + */ +HRESULT WINAPI SafeArrayGetUBound(SAFEARRAY *psa, UINT nDim, LONG *plUbound) +{ + TRACE("(%p,%d,%p)\n", psa, nDim, plUbound); + + if (!psa || !plUbound) + return E_INVALIDARG; + + if(!nDim || nDim > psa->cDims) + return DISP_E_BADINDEX; + + *plUbound = psa->rgsabound[nDim - 1].lLbound + + psa->rgsabound[nDim - 1].cElements - 1; + + return S_OK; +} + +/************************************************************************* + * SafeArrayGetLBound (OLEAUT32.20) + * + * Get the lower bound for a given SafeArray dimension + * + * PARAMS + * psa [I] Array to get dimension lower bound from + * nDim [I] The dimension number to get the lowe bound of + * plLbound [O] Destination for the lower bound + * + * RETURNS + * Success: S_OK. plUbound contains the dimensions lower bound. + * Failure: An HRESULT error code indicating the error. + * + * NOTES + * See SafeArray. + */ +HRESULT WINAPI SafeArrayGetLBound(SAFEARRAY *psa, UINT nDim, LONG *plLbound) +{ + TRACE("(%p,%d,%p)\n", psa, nDim, plLbound); + + if (!psa || !plLbound) + return E_INVALIDARG; + + if(!nDim || nDim > psa->cDims) + return DISP_E_BADINDEX; + + *plLbound = psa->rgsabound[nDim - 1].lLbound; + return S_OK; +} + +/************************************************************************* + * SafeArrayGetDim (OLEAUT32.17) + * + * Get the number of dimensions in a SafeArray. + * + * PARAMS + * psa [I] Array to get the dimensions of + * + * RETURNS + * The number of array dimensions in psa, or 0 if psa is NULL. + * + * NOTES + * See SafeArray. + */ +UINT WINAPI SafeArrayGetDim(SAFEARRAY *psa) +{ + TRACE("(%p) returning %ld\n", psa, psa ? psa->cDims : 0ul); + return psa ? psa->cDims : 0; +} + +/************************************************************************* + * SafeArrayGetElemsize (OLEAUT32.18) + * + * Get the size of an element in a SafeArray. + * + * PARAMS + * psa [I] Array to get the element size from + * + * RETURNS + * The size of a single element in psa, or 0 if psa is NULL. + * + * NOTES + * See SafeArray. + */ +UINT WINAPI SafeArrayGetElemsize(SAFEARRAY *psa) +{ + TRACE("(%p) returning %ld\n", psa, psa ? psa->cbElements : 0ul); + return psa ? psa->cbElements : 0; +} + +/************************************************************************* + * SafeArrayAccessData (OLEAUT32.23) + * + * Lock a SafeArray and return a pointer to its data. + * + * PARAMS + * psa [I] Array to get the data pointer from + * ppvData [O] Destination for the arrays data pointer + * + * RETURNS + * Success: S_OK. ppvData contains the arrays data pointer, and the array + * is locked. + * Failure: An HRESULT error code indicating the error. + * + * NOTES + * See SafeArray. + */ +HRESULT WINAPI SafeArrayAccessData(SAFEARRAY *psa, void **ppvData) +{ + TRACE("(%p,%p)\n", psa, ppvData); + + if(!psa || !ppvData) + return E_INVALIDARG; + + if (SUCCEEDED(SafeArrayLock(psa))) + { + *ppvData = psa->pvData; + return S_OK; + } + *ppvData = NULL; + return E_UNEXPECTED; +} + + +/************************************************************************* + * SafeArrayUnaccessData (OLEAUT32.24) + * + * Unlock a SafeArray after accessing its data. + * + * PARAMS + * psa [I] Array to unlock + * + * RETURNS + * Success: S_OK. The array is unlocked. + * Failure: An HRESULT error code indicating the error. + * + * NOTES + * See SafeArray. + */ +HRESULT WINAPI SafeArrayUnaccessData(SAFEARRAY *psa) +{ + TRACE("(%p)\n", psa); + return SafeArrayUnlock(psa); +} + +/************************************************************************ + * SafeArrayPtrOfIndex (OLEAUT32.148) + * + * Get the address of an item in a SafeArray. + * + * PARAMS + * psa [I] Array to get the items address from + * rgIndices [I] Index of the item in the array + * ppvData [O] Destination for item address + * + * RETURNS + * Success: S_OK. ppvData contains a pointer to the item. + * Failure: An HRESULT error code indicating the error. + * + * NOTES + * This function does not lock the array. + * + * NOTES + * See SafeArray. + */ +HRESULT WINAPI SafeArrayPtrOfIndex(SAFEARRAY *psa, LONG *rgIndices, void **ppvData) +{ + USHORT dim; + ULONG cell = 0, dimensionSize = 1; + SAFEARRAYBOUND* psab; + LONG c1; + + TRACE("(%p,%p,%p)\n", psa, rgIndices, ppvData); + + /* The general formula for locating the cell number of an entry in an n + * dimensional array (where cn = coordinate in dimension dn) is: + * + * c1 + c2 * sizeof(d1) + c3 * sizeof(d2) ... + cn * sizeof(c(n-1)) + * + * We calculate the size of the last dimension at each step through the + * dimensions to avoid recursing to calculate the last dimensions size. + */ + if (!psa || !rgIndices || !ppvData) + return E_INVALIDARG; + + psab = psa->rgsabound; + c1 = *rgIndices++; + + if (c1 < psab->lLbound || c1 >= psab->lLbound + (LONG)psab->cElements) + return DISP_E_BADINDEX; /* Initial index out of bounds */ + + for (dim = 1; dim < psa->cDims; dim++) + { + dimensionSize *= psab->cElements; + + psab++; + + if (!psab->cElements || + *rgIndices < psab->lLbound || + *rgIndices >= psab->lLbound + (LONG)psab->cElements) + return DISP_E_BADINDEX; /* Index out of bounds */ + + cell += (*rgIndices - psab->lLbound) * dimensionSize; + rgIndices++; + } + + cell += (c1 - psa->rgsabound[0].lLbound); + + *ppvData = (char*)psa->pvData + cell * psa->cbElements; + return S_OK; +} + +/************************************************************************ + * SafeArrayDestroyData (OLEAUT32.39) + * + * Destroy the data associated with a SafeArray. + * + * PARAMS + * psa [I] Array to delete the data from + * + * RETURNS + * Success: S_OK. All items and the item data are freed. + * Failure: An HRESULT error code indicating the error. + * + * NOTES + * See SafeArray. + */ +HRESULT WINAPI SafeArrayDestroyData(SAFEARRAY *psa) +{ + TRACE("(%p)\n", psa); + + if (!psa) + return E_INVALIDARG; + + if (psa->cLocks) + return DISP_E_ARRAYISLOCKED; /* Can't delete a locked array */ + + /* If static, keep pvData and don't free */ + if (psa->pvData && !(psa->fFeatures & FADF_STATIC)) + { + /* Delete the actual item data */ + if (FAILED(SAFEARRAY_DestroyData(psa, 0))) + return E_UNEXPECTED; + + /* If this is not a vector, free the data memory block */ + if (!(psa->fFeatures & FADF_CREATEVECTOR)) + { + if (!SAFEARRAY_Free(psa->pvData)) + return E_UNEXPECTED; + psa->pvData = NULL; + } + else + psa->fFeatures |= FADF_DATADELETED; /* Mark the data deleted */ + + } + return S_OK; +} + +/************************************************************************ + * SafeArrayCopyData (OLEAUT32.412) + * + * Copy all data from one SafeArray to another. + * + * PARAMS + * psaSource [I] Source for copy + * psaTarget [O] Destination for copy + * + * RETURNS + * Success: S_OK. psaTarget contains a copy of psaSource. + * Failure: An HRESULT error code indicating the error. + * + * NOTES + * The two arrays must have the same number of dimensions and elements. + * + * NOTES + * See SafeArray. + */ +HRESULT WINAPI SafeArrayCopyData(SAFEARRAY *psaSource, SAFEARRAY *psaTarget) +{ + int dim; + + TRACE("(%p,%p)\n", psaSource, psaTarget); + + if (!psaSource || !psaTarget || + psaSource->cDims != psaTarget->cDims || + psaSource->cbElements != psaTarget->cbElements) + return E_INVALIDARG; + + /* Each dimension must be the same size */ + for (dim = psaSource->cDims - 1; dim >= 0 ; dim--) + if (psaSource->rgsabound[dim].cElements != + psaTarget->rgsabound[dim].cElements) + return E_INVALIDARG; + + if (SUCCEEDED(SAFEARRAY_DestroyData(psaTarget, 0)) && + SUCCEEDED(SAFEARRAY_CopyData(psaSource, psaTarget))) + return S_OK; + return E_UNEXPECTED; +} + +/************************************************************************ + * SafeArrayDestroy (OLEAUT32.16) + * + * Destroy a SafeArray. + * + * PARAMS + * psa [I] Array to destroy + * + * RETURNS + * Success: S_OK. All resources used by the array are freed. + * Failure: An HRESULT error code indicating the error. + * + * NOTES + * See SafeArray. + */ +HRESULT WINAPI SafeArrayDestroy(SAFEARRAY *psa) +{ + TRACE("(%p)\n", psa); + + if(!psa) + return E_INVALIDARG; + + if(psa->cLocks > 0) + return DISP_E_ARRAYISLOCKED; + + /* Native doesn't check to see if the free succeeds */ + SafeArrayDestroyData(psa); + SafeArrayDestroyDescriptor(psa); + return S_OK; +} + +/************************************************************************ + * SafeArrayCopy (OLEAUT32.27) + * + * Make a duplicate of a SafeArray. + * + * PARAMS + * psa [I] Source for copy + * ppsaOut [O] Destination for new copy + * + * RETURNS + * Success: S_OK. ppsaOut contains a copy of the array. + * Failure: An HRESULT error code indicating the error. + * + * NOTES + * See SafeArray. + */ +HRESULT WINAPI SafeArrayCopy(SAFEARRAY *psa, SAFEARRAY **ppsaOut) +{ + HRESULT hRet; + + TRACE("(%p,%p)\n", psa, ppsaOut); + + if (!ppsaOut) + return E_INVALIDARG; + + *ppsaOut = NULL; + + if (!psa) + return S_OK; /* Handles copying of NULL arrays */ + + if (psa->fFeatures & (FADF_RECORD|FADF_HAVEIID|FADF_HAVEVARTYPE)) + { + VARTYPE vt; + if (FAILED(SafeArrayGetVartype(psa, &vt))) + hRet = E_UNEXPECTED; + else + hRet = SafeArrayAllocDescriptorEx(vt, psa->cDims, ppsaOut); + } + else + { + hRet = SafeArrayAllocDescriptor(psa->cDims, ppsaOut); + if (SUCCEEDED(hRet)) + { + (*ppsaOut)->fFeatures = psa->fFeatures & ~FADF_CREATEVECTOR; + (*ppsaOut)->cbElements = psa->cbElements; + } + } + + if (SUCCEEDED(hRet)) + { + /* Copy dimension bounds */ + memcpy((*ppsaOut)->rgsabound, psa->rgsabound, psa->cDims * sizeof(SAFEARRAYBOUND)); + + (*ppsaOut)->pvData = SAFEARRAY_Malloc(SAFEARRAY_GetCellCount(psa) * psa->cbElements); + + if ((*ppsaOut)->pvData) + { + hRet = SAFEARRAY_CopyData(psa, *ppsaOut); + + if (SUCCEEDED(hRet)) + return hRet; + + SAFEARRAY_Free((*ppsaOut)->pvData); + } + SafeArrayDestroyDescriptor(*ppsaOut); + } + *ppsaOut = NULL; + return hRet; +} + +/************************************************************************ + * SafeArrayRedim (OLEAUT32.40) + * + * Changes the characteristics of the last dimension of a SafeArray + * + * PARAMS + * psa [I] Array to change + * psabound [I] New bound details for the last dimension + * + * RETURNS + * Success: S_OK. psa is updated to reflect the new bounds. + * Failure: An HRESULT error code indicating the error. + * + * NOTES + * See SafeArray. + */ +HRESULT WINAPI SafeArrayRedim(SAFEARRAY *psa, SAFEARRAYBOUND *psabound) +{ + SAFEARRAYBOUND *oldBounds; + + TRACE("(%p,%p)\n", psa, psabound); + + if (!psa || psa->fFeatures & FADF_FIXEDSIZE || !psabound) + return E_INVALIDARG; + + if (psa->cLocks > 0) + return DISP_E_ARRAYISLOCKED; + + if (FAILED(SafeArrayLock(psa))) + return E_UNEXPECTED; + + oldBounds = &psa->rgsabound[psa->cDims - 1]; + oldBounds->lLbound = psabound->lLbound; + + if (psabound->cElements != oldBounds->cElements) + { + if (psabound->cElements < oldBounds->cElements) + { + /* Shorten the final dimension. */ + ULONG ulStartCell = psa->cDims == 1 ? 0 : SAFEARRAY_GetDimensionCells(psa, psa->cDims - 1); + + ulStartCell += psabound->cElements; + SAFEARRAY_DestroyData(psa, ulStartCell); + } + else + { + /* Lengthen the final dimension */ + ULONG ulOldSize, ulNewSize; + PVOID pvNewData; + + ulOldSize = SAFEARRAY_GetCellCount(psa) * psa->cbElements; + if (ulOldSize) + ulNewSize = (ulOldSize / oldBounds->cElements) * psabound->cElements; + else { + int oldelems = oldBounds->cElements; + oldBounds->cElements = psabound->cElements; + ulNewSize = SAFEARRAY_GetCellCount(psa) * psa->cbElements; + oldBounds->cElements = oldelems; + } + + if (!(pvNewData = SAFEARRAY_Malloc(ulNewSize))) + { + SafeArrayUnlock(psa); + return E_UNEXPECTED; + } + + memcpy(pvNewData, psa->pvData, ulOldSize); + SAFEARRAY_Free(psa->pvData); + psa->pvData = pvNewData; + } + oldBounds->cElements = psabound->cElements; + } + + SafeArrayUnlock(psa); + return S_OK; +} + +/************************************************************************ + * SafeArrayGetVartype (OLEAUT32.77) + * + * Get the type of the items in a SafeArray. + * + * PARAMS + * psa [I] Array to get the type from + * pvt [O] Destination for the type + * + * RETURNS + * Success: S_OK. pvt contains the type of the items. + * Failure: An HRESULT error code indicating the error. + * + * NOTES + * See SafeArray. + */ +HRESULT WINAPI SafeArrayGetVartype(SAFEARRAY* psa, VARTYPE* pvt) +{ + TRACE("(%p,%p)\n", psa, pvt); + + if (!psa || !pvt) + return E_INVALIDARG; + + if (psa->fFeatures & FADF_RECORD) + *pvt = VT_RECORD; + else if (psa->fFeatures & FADF_HAVEIID) + *pvt = VT_UNKNOWN; + else if (psa->fFeatures & FADF_HAVEVARTYPE) + { + VARTYPE vt = SAFEARRAY_GetHiddenDWORD(psa); + *pvt = vt; + } + else + return E_INVALIDARG; + + return S_OK; +} + +/************************************************************************ + * SafeArraySetRecordInfo (OLEAUT32.@) + * + * Set the record info for a SafeArray. + * + * PARAMS + * psa [I] Array to set the record info for + * pRinfo [I] Record info + * + * RETURNS + * Success: S_OK. The record info is stored with the array. + * Failure: An HRESULT error code indicating the error. + * + * NOTES + * See SafeArray. + */ +HRESULT WINAPI SafeArraySetRecordInfo(SAFEARRAY *psa, IRecordInfo *pRinfo) +{ + IRecordInfo** dest = (IRecordInfo**)psa; + + TRACE("(%p,%p)\n", psa, pRinfo); + + if (!psa || !(psa->fFeatures & FADF_RECORD)) + return E_INVALIDARG; + + if (pRinfo) + IRecordInfo_AddRef(pRinfo); + + if (dest[-1]) + IRecordInfo_Release(dest[-1]); + + dest[-1] = pRinfo; + return S_OK; +} + +/************************************************************************ + * SafeArrayGetRecordInfo (OLEAUT32.@) + * + * Get the record info from a SafeArray. + * + * PARAMS + * psa [I] Array to get the record info from + * pRinfo [O] Destination for the record info + * + * RETURNS + * Success: S_OK. pRinfo contains the record info, or NULL if there was none. + * Failure: An HRESULT error code indicating the error. + * + * NOTES + * See SafeArray. + */ +HRESULT WINAPI SafeArrayGetRecordInfo(SAFEARRAY *psa, IRecordInfo **pRinfo) +{ + IRecordInfo** src = (IRecordInfo**)psa; + + TRACE("(%p,%p)\n", psa, pRinfo); + + if (!psa || !pRinfo || !(psa->fFeatures & FADF_RECORD)) + return E_INVALIDARG; + + *pRinfo = src[-1]; + + if (*pRinfo) + IRecordInfo_AddRef(*pRinfo); + return S_OK; +} + +/************************************************************************ + * SafeArraySetIID (OLEAUT32.@) + * + * Set the IID for a SafeArray. + * + * PARAMS + * psa [I] Array to set the IID from + * guid [I] IID + * + * RETURNS + * Success: S_OK. The IID is stored with the array + * Failure: An HRESULT error code indicating the error. + * + * NOTES + * See SafeArray. + */ +HRESULT WINAPI SafeArraySetIID(SAFEARRAY *psa, REFGUID guid) +{ + GUID* dest = (GUID*)psa; + + TRACE("(%p,%s)\n", psa, debugstr_guid(guid)); + + if (!psa || !guid || !(psa->fFeatures & FADF_HAVEIID)) + return E_INVALIDARG; + + dest[-1] = *guid; + return S_OK; +} + +/************************************************************************ + * SafeArrayGetIID (OLEAUT32.@) + * + * Get the IID from a SafeArray. + * + * PARAMS + * psa [I] Array to get the ID from + * pGuid [O] Destination for the IID + * + * RETURNS + * Success: S_OK. pRinfo contains the IID, or NULL if there was none. + * Failure: An HRESULT error code indicating the error. + * + * NOTES + * See SafeArray. + */ +HRESULT WINAPI SafeArrayGetIID(SAFEARRAY *psa, GUID *pGuid) +{ + GUID* src = (GUID*)psa; + + TRACE("(%p,%p)\n", psa, pGuid); + + if (!psa || !pGuid || !(psa->fFeatures & FADF_HAVEIID)) + return E_INVALIDARG; + + *pGuid = src[-1]; + return S_OK; +} + +/************************************************************************ + * VectorFromBstr (OLEAUT32.@) + * + * Create a SafeArray Vector from the bytes of a BSTR. + * + * PARAMS + * bstr [I] String to get bytes from + * ppsa [O] Destination for the array + * + * RETURNS + * Success: S_OK. ppsa contains the strings bytes as a VT_UI1 array. + * Failure: An HRESULT error code indicating the error. + * + * NOTES + * See SafeArray. + */ +HRESULT WINAPI VectorFromBstr(BSTR bstr, SAFEARRAY **ppsa) +{ + SAFEARRAYBOUND sab; + + TRACE("(%p,%p)\n", bstr, ppsa); + + if (!ppsa) + return E_INVALIDARG; + + sab.lLbound = 0; + sab.cElements = SysStringByteLen(bstr); + + *ppsa = SAFEARRAY_Create(VT_UI1, 1, &sab, 0); + + if (*ppsa) + { + memcpy((*ppsa)->pvData, bstr, sab.cElements); + return S_OK; + } + return E_OUTOFMEMORY; +} + +/************************************************************************ + * BstrFromVector (OLEAUT32.@) + * + * Create a BSTR from a SafeArray. + * + * PARAMS + * psa [I] Source array + * pbstr [O] Destination for output BSTR + * + * RETURNS + * Success: S_OK. pbstr contains the arrays data. + * Failure: An HRESULT error code indicating the error. + * + * NOTES + * psa must be a 1 dimensional array of a 1 byte type. + * + * NOTES + * See SafeArray. + */ +HRESULT WINAPI BstrFromVector(SAFEARRAY *psa, BSTR *pbstr) +{ + TRACE("(%p,%p)\n", psa, pbstr); + + if (!pbstr) + return E_INVALIDARG; + + *pbstr = NULL; + + if (!psa || psa->cbElements != 1 || psa->cDims != 1) + return E_INVALIDARG; + + *pbstr = SysAllocStringByteLen(psa->pvData, psa->rgsabound[0].cElements); + if (!*pbstr) + return E_OUTOFMEMORY; + return S_OK; +} diff --git a/reactos/lib/oleaut32/stubs.c b/reactos/lib/oleaut32/stubs.c new file mode 100644 index 00000000000..3252bcd543b --- /dev/null +++ b/reactos/lib/oleaut32/stubs.c @@ -0,0 +1,66 @@ +/* + * OlePro32 Stubs + * + * Copyright 1999 Corel Corporation + * + * Sean Langley + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" +#include "wine/debug.h" +#include "ole2.h" +#include "olectl.h" + +WINE_DEFAULT_DEBUG_CHANNEL(ole); + +/*********************************************************************** + * OleIconToCursor (OLEAUT32.415) + */ +HCURSOR WINAPI OleIconToCursor( HINSTANCE hinstExe, HICON hicon) +{ + FIXME("(%p,%p), not implemented (olepro32.dll)\n",hinstExe,hicon); + return S_OK; +} + +/*********************************************************************** + * OleCreatePropertyFrameIndirect (OLEAUT32.416) + */ +HRESULT WINAPI OleCreatePropertyFrameIndirect( LPOCPFIPARAMS lpParams) +{ + FIXME("(%p), not implemented (olepro32.dll)\n",lpParams); + return S_OK; +} + +/*********************************************************************** + * OleCreatePropertyFrame (OLEAUT32.417) + */ +HRESULT WINAPI OleCreatePropertyFrame( + HWND hwndOwner, UINT x, UINT y, LPCOLESTR lpszCaption,ULONG cObjects, + LPUNKNOWN* ppUnk, ULONG cPages, LPCLSID pPageClsID, LCID lcid, + DWORD dwReserved, LPVOID pvReserved ) +{ + FIXME("(%p,%d,%d,%s,%ld,%p,%ld,%p,%x,%ld,%p), not implemented (olepro32.dll)\n", + hwndOwner,x,y,debugstr_w(lpszCaption),cObjects,ppUnk,cPages, + pPageClsID, (int)lcid,dwReserved,pvReserved); + return S_OK; +} + diff --git a/reactos/lib/oleaut32/tmarshal.c b/reactos/lib/oleaut32/tmarshal.c new file mode 100644 index 00000000000..288e4b341f7 --- /dev/null +++ b/reactos/lib/oleaut32/tmarshal.c @@ -0,0 +1,1822 @@ +/* + * TYPELIB Marshaler + * + * Copyright 2002 Marcus Meissner + * + * The olerelay debug channel allows you to see calls marshalled by + * the typelib marshaller. It is not a generic COM relaying system. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include + +#define COBJMACROS +#define NONAMELESSUNION +#define NONAMELESSSTRUCT + +#include "winerror.h" +#include "windef.h" +#include "winbase.h" +#include "winnls.h" +#include "winreg.h" +#include "winuser.h" + +#include "ole2.h" +#include "wine/unicode.h" +#include "ole2disp.h" +#include "typelib.h" +#include "wine/debug.h" +#include "winternl.h" + +static const WCHAR riidW[5] = {'r','i','i','d',0}; +static const WCHAR pdispparamsW[] = {'p','d','i','s','p','p','a','r','a','m','s',0}; +static const WCHAR ppvObjectW[] = {'p','p','v','O','b','j','e','c','t',0}; + +WINE_DEFAULT_DEBUG_CHANNEL(ole); +WINE_DECLARE_DEBUG_CHANNEL(olerelay); + +#define ICOM_THIS_MULTI(impl,field,iface) impl* const This=(impl*)((char*)(iface) - offsetof(impl,field)) + +typedef struct _marshal_state { + LPBYTE base; + int size; + int curoff; + + BOOL thisisiid; + IID iid; /* HACK: for VT_VOID */ +} marshal_state; + +/* used in the olerelay code to avoid having the L"" stuff added by debugstr_w */ +static char *relaystr(WCHAR *in) { + char *tmp = (char *)debugstr_w(in); + tmp += 2; + tmp[strlen(tmp)-1] = '\0'; + return tmp; +} + +static HRESULT +xbuf_add(marshal_state *buf, LPBYTE stuff, DWORD size) { + while (buf->size - buf->curoff < size) { + if (buf->base) { + buf->size += 100; + buf->base = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,buf->base,buf->size); + if (!buf->base) + return E_OUTOFMEMORY; + } else { + buf->base = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,32); + buf->size = 32; + if (!buf->base) + return E_OUTOFMEMORY; + } + } + memcpy(buf->base+buf->curoff,stuff,size); + buf->curoff += size; + return S_OK; +} + +static HRESULT +xbuf_get(marshal_state *buf, LPBYTE stuff, DWORD size) { + if (buf->size < buf->curoff+size) return E_FAIL; + memcpy(stuff,buf->base+buf->curoff,size); + buf->curoff += size; + return S_OK; +} + +static HRESULT +xbuf_skip(marshal_state *buf, DWORD size) { + if (buf->size < buf->curoff+size) return E_FAIL; + buf->curoff += size; + return S_OK; +} + +static HRESULT +_unmarshal_interface(marshal_state *buf, REFIID riid, LPUNKNOWN *pUnk) { + IStream *pStm; + ULARGE_INTEGER newpos; + LARGE_INTEGER seekto; + ULONG res; + HRESULT hres; + DWORD xsize; + + TRACE("...%s...\n",debugstr_guid(riid)); + *pUnk = NULL; + hres = xbuf_get(buf,(LPBYTE)&xsize,sizeof(xsize)); + if (hres) return hres; + if (xsize == 0) return S_OK; + hres = CreateStreamOnHGlobal(0,TRUE,&pStm); + if (hres) { + FIXME("Stream create failed %lx\n",hres); + return hres; + } + hres = IStream_Write(pStm,buf->base+buf->curoff,xsize,&res); + if (hres) { FIXME("stream write %lx\n",hres); return hres; } + memset(&seekto,0,sizeof(seekto)); + hres = IStream_Seek(pStm,seekto,SEEK_SET,&newpos); + if (hres) { FIXME("Failed Seek %lx\n",hres); return hres;} + hres = CoUnmarshalInterface(pStm,riid,(LPVOID*)pUnk); + if (hres) { + FIXME("Marshalling interface %s failed with %lx\n",debugstr_guid(riid),hres); + return hres; + } + IStream_Release(pStm); + return xbuf_skip(buf,xsize); +} + +static HRESULT +_marshal_interface(marshal_state *buf, REFIID riid, LPUNKNOWN pUnk) { + LPUNKNOWN newiface; + LPBYTE tempbuf; + IStream *pStm; + STATSTG ststg; + ULARGE_INTEGER newpos; + LARGE_INTEGER seekto; + ULONG res; + DWORD xsize; + HRESULT hres; + + hres = S_OK; + if (!pUnk) + goto fail; + + TRACE("...%s...\n",debugstr_guid(riid)); + hres=IUnknown_QueryInterface(pUnk,riid,(LPVOID*)&newiface); + if (hres) { + TRACE("%p does not support iface %s\n",pUnk,debugstr_guid(riid)); + goto fail; + } + hres = CreateStreamOnHGlobal(0,TRUE,&pStm); + if (hres) { + FIXME("Stream create failed %lx\n",hres); + goto fail; + } + hres = CoMarshalInterface(pStm,riid,newiface,0,NULL,0); + IUnknown_Release(newiface); + if (hres) { + FIXME("Marshalling interface %s failed with %lx\n", + debugstr_guid(riid),hres + ); + goto fail; + } + hres = IStream_Stat(pStm,&ststg,0); + tempbuf = HeapAlloc(GetProcessHeap(), 0, ststg.cbSize.u.LowPart); + memset(&seekto,0,sizeof(seekto)); + hres = IStream_Seek(pStm,seekto,SEEK_SET,&newpos); + if (hres) { FIXME("Failed Seek %lx\n",hres); goto fail;} + hres = IStream_Read(pStm,tempbuf,ststg.cbSize.u.LowPart,&res); + if (hres) { FIXME("Failed Read %lx\n",hres); goto fail;} + IStream_Release(pStm); + xsize = ststg.cbSize.u.LowPart; + xbuf_add(buf,(LPBYTE)&xsize,sizeof(xsize)); + hres = xbuf_add(buf,tempbuf,ststg.cbSize.u.LowPart); + HeapFree(GetProcessHeap(),0,tempbuf); + return hres; +fail: + xsize = 0; + xbuf_add(buf,(LPBYTE)&xsize,sizeof(xsize)); + return hres; +} + +/********************* OLE Proxy/Stub Factory ********************************/ +static HRESULT WINAPI +PSFacBuf_QueryInterface(LPPSFACTORYBUFFER iface, REFIID iid, LPVOID *ppv) { + if (IsEqualIID(iid,&IID_IPSFactoryBuffer)||IsEqualIID(iid,&IID_IUnknown)) { + *ppv = (LPVOID)iface; + /* No ref counting, static class */ + return S_OK; + } + FIXME("(%s) unknown IID?\n",debugstr_guid(iid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI PSFacBuf_AddRef(LPPSFACTORYBUFFER iface) { return 2; } +static ULONG WINAPI PSFacBuf_Release(LPPSFACTORYBUFFER iface) { return 1; } + +static HRESULT +_get_typeinfo_for_iid(REFIID riid, ITypeInfo**ti) { + HRESULT hres; + HKEY ikey; + char tlguid[200],typelibkey[300],interfacekey[300],ver[100]; + char tlfn[260]; + OLECHAR tlfnW[260]; + DWORD tlguidlen, verlen, type, tlfnlen; + ITypeLib *tl; + + sprintf( interfacekey, "Interface\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\Typelib", + riid->Data1, riid->Data2, riid->Data3, + riid->Data4[0], riid->Data4[1], riid->Data4[2], riid->Data4[3], + riid->Data4[4], riid->Data4[5], riid->Data4[6], riid->Data4[7] + ); + + if (RegOpenKeyA(HKEY_CLASSES_ROOT,interfacekey,&ikey)) { + FIXME("No %s key found.\n",interfacekey); + return E_FAIL; + } + type = (1<oVft/4 > max) + max = fdesc->oVft/4; + n++; + } + /*NOTREACHED*/ +} + +#ifdef __i386__ + +#include "pshpack1.h" + +typedef struct _TMAsmProxy { + BYTE popleax; + BYTE pushlval; + BYTE nr; + BYTE pushleax; + BYTE lcall; + DWORD xcall; + BYTE lret; + WORD bytestopop; +} TMAsmProxy; + +#include "poppack.h" + +#else /* __i386__ */ +# error You need to implement stubless proxies for your architecture +#endif + +typedef struct _TMProxyImpl { + LPVOID *lpvtbl; + IRpcProxyBufferVtbl *lpvtbl2; + ULONG ref; + + TMAsmProxy *asmstubs; + ITypeInfo* tinfo; + IRpcChannelBuffer* chanbuf; + IID iid; + CRITICAL_SECTION crit; +} TMProxyImpl; + +static HRESULT WINAPI +TMProxyImpl_QueryInterface(LPRPCPROXYBUFFER iface, REFIID riid, LPVOID *ppv) +{ + TRACE("()\n"); + if (IsEqualIID(riid,&IID_IUnknown)||IsEqualIID(riid,&IID_IRpcProxyBuffer)) { + *ppv = (LPVOID)iface; + IRpcProxyBuffer_AddRef(iface); + return S_OK; + } + FIXME("no interface for %s\n",debugstr_guid(riid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI +TMProxyImpl_AddRef(LPRPCPROXYBUFFER iface) +{ + ICOM_THIS_MULTI(TMProxyImpl,lpvtbl2,iface); + + TRACE("()\n"); + + return InterlockedIncrement(&This->ref); +} + +static ULONG WINAPI +TMProxyImpl_Release(LPRPCPROXYBUFFER iface) +{ + ULONG refs; + ICOM_THIS_MULTI(TMProxyImpl,lpvtbl2,iface); + + TRACE("()\n"); + + refs = InterlockedDecrement(&This->ref); + if (!refs) + { + DeleteCriticalSection(&This->crit); + if (This->chanbuf) IRpcChannelBuffer_Release(This->chanbuf); + VirtualFree(This->asmstubs, 0, MEM_RELEASE); + CoTaskMemFree(This); + } + return refs; +} + +static HRESULT WINAPI +TMProxyImpl_Connect( + LPRPCPROXYBUFFER iface,IRpcChannelBuffer* pRpcChannelBuffer) +{ + ICOM_THIS_MULTI(TMProxyImpl, lpvtbl2, iface); + + TRACE("(%p)\n", pRpcChannelBuffer); + + EnterCriticalSection(&This->crit); + + IRpcChannelBuffer_AddRef(pRpcChannelBuffer); + This->chanbuf = pRpcChannelBuffer; + + LeaveCriticalSection(&This->crit); + + return S_OK; +} + +static void WINAPI +TMProxyImpl_Disconnect(LPRPCPROXYBUFFER iface) +{ + ICOM_THIS_MULTI(TMProxyImpl, lpvtbl2, iface); + + TRACE("()\n"); + + EnterCriticalSection(&This->crit); + + IRpcChannelBuffer_Release(This->chanbuf); + This->chanbuf = NULL; + + LeaveCriticalSection(&This->crit); +} + + +static IRpcProxyBufferVtbl tmproxyvtable = { + TMProxyImpl_QueryInterface, + TMProxyImpl_AddRef, + TMProxyImpl_Release, + TMProxyImpl_Connect, + TMProxyImpl_Disconnect +}; + +/* how much space do we use on stack in DWORD steps. */ +int +_argsize(DWORD vt) { + switch (vt) { + case VT_DATE: + return sizeof(DATE)/sizeof(DWORD); + case VT_VARIANT: + return (sizeof(VARIANT)+3)/sizeof(DWORD); + default: + return 1; + } +} + +static int +_xsize(TYPEDESC *td) { + switch (td->vt) { + case VT_DATE: + return sizeof(DATE); + case VT_VARIANT: + return sizeof(VARIANT)+3; + case VT_CARRAY: { + int i, arrsize = 1; + ARRAYDESC *adesc = td->u.lpadesc; + + for (i=0;icDims;i++) + arrsize *= adesc->rgbounds[i].cElements; + return arrsize*_xsize(&adesc->tdescElem); + } + case VT_UI2: + case VT_I2: + return 2; + case VT_UI1: + case VT_I1: + return 1; + default: + return 4; + } +} + +static HRESULT +serialize_param( + ITypeInfo *tinfo, + BOOL writeit, + BOOL debugout, + BOOL dealloc, + TYPEDESC *tdesc, + DWORD *arg, + marshal_state *buf) +{ + HRESULT hres = S_OK; + + TRACE("(tdesc.vt %d)\n",tdesc->vt); + + switch (tdesc->vt) { + case VT_EMPTY: /* nothing. empty variant for instance */ + return S_OK; + case VT_BOOL: + case VT_ERROR: + case VT_UI4: + case VT_UINT: + case VT_I4: + case VT_R4: + case VT_UI2: + case VT_UI1: + hres = S_OK; + if (debugout) TRACE_(olerelay)("%lx",*arg); + if (writeit) + hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD)); + return hres; + case VT_VARIANT: { + TYPEDESC tdesc2; + VARIANT *vt = (VARIANT*)arg; + DWORD vttype = V_VT(vt); + + if (debugout) TRACE_(olerelay)("Vt(%ld)(",vttype); + tdesc2.vt = vttype; + if (writeit) { + hres = xbuf_add(buf,(LPBYTE)&vttype,sizeof(vttype)); + if (hres) return hres; + } + /* need to recurse since we need to free the stuff */ + hres = serialize_param(tinfo,writeit,debugout,dealloc,&tdesc2,&(V_I4(vt)),buf); + if (debugout) TRACE_(olerelay)(")"); + return hres; + } + case VT_BSTR: { + if (debugout) { + if (arg) + TRACE_(olerelay)("%s",relaystr((BSTR)*arg)); + else + TRACE_(olerelay)(""); + } + if (writeit) { + if (!*arg) { + DWORD fakelen = -1; + hres = xbuf_add(buf,(LPBYTE)&fakelen,4); + if (hres) + return hres; + } else { + DWORD *bstr = ((DWORD*)(*arg))-1; + + hres = xbuf_add(buf,(LPBYTE)bstr,bstr[0]+4); + if (hres) + return hres; + } + } + + if (dealloc && arg) + SysFreeString((BSTR)*arg); + return S_OK; + } + case VT_PTR: { + DWORD cookie; + + if (debugout) TRACE_(olerelay)("*"); + if (writeit) { + cookie = *arg ? 0x42424242 : 0; + hres = xbuf_add(buf,(LPBYTE)&cookie,sizeof(cookie)); + if (hres) + return hres; + } + if (!*arg) { + if (debugout) TRACE_(olerelay)("NULL"); + return S_OK; + } + hres = serialize_param(tinfo,writeit,debugout,dealloc,tdesc->u.lptdesc,(DWORD*)*arg,buf); + if (dealloc) HeapFree(GetProcessHeap(),0,(LPVOID)arg); + return hres; + } + case VT_UNKNOWN: + if (debugout) TRACE_(olerelay)("unk(0x%lx)",*arg); + if (writeit) + hres = _marshal_interface(buf,&IID_IUnknown,(LPUNKNOWN)*arg); + return hres; + case VT_DISPATCH: + if (debugout) TRACE_(olerelay)("idisp(0x%lx)",*arg); + if (writeit) + hres = _marshal_interface(buf,&IID_IDispatch,(LPUNKNOWN)*arg); + return hres; + case VT_VOID: + if (debugout) TRACE_(olerelay)(""); + return S_OK; + case VT_USERDEFINED: { + ITypeInfo *tinfo2; + TYPEATTR *tattr; + + hres = ITypeInfo_GetRefTypeInfo(tinfo,tdesc->u.hreftype,&tinfo2); + if (hres) { + FIXME("Could not get typeinfo of hreftype %lx for VT_USERDEFINED.\n",tdesc->u.hreftype); + return hres; + } + ITypeInfo_GetTypeAttr(tinfo2,&tattr); + switch (tattr->typekind) { + case TKIND_DISPATCH: + case TKIND_INTERFACE: + if (writeit) + hres=_marshal_interface(buf,&(tattr->guid),(LPUNKNOWN)arg); + break; + case TKIND_RECORD: { + int i; + if (debugout) TRACE_(olerelay)("{"); + for (i=0;icVars;i++) { + VARDESC *vdesc; + ELEMDESC *elem2; + TYPEDESC *tdesc2; + + hres = ITypeInfo2_GetVarDesc(tinfo2, i, &vdesc); + if (hres) { + FIXME("Could not get vardesc of %d\n",i); + return hres; + } + /* Need them for hack below */ + /* + memset(names,0,sizeof(names)); + hres = ITypeInfo_GetNames(tinfo2,vdesc->memid,names,sizeof(names)/sizeof(names[0]),&nrofnames); + if (nrofnames > sizeof(names)/sizeof(names[0])) { + ERR("Need more names!\n"); + } + if (!hres && debugout) + TRACE_(olerelay)("%s=",relaystr(names[0])); + */ + elem2 = &vdesc->elemdescVar; + tdesc2 = &elem2->tdesc; + hres = serialize_param( + tinfo2, + writeit, + debugout, + dealloc, + tdesc2, + (DWORD*)(((LPBYTE)arg)+vdesc->u.oInst), + buf + ); + if (hres!=S_OK) + return hres; + if (debugout && (i<(tattr->cVars-1))) + TRACE_(olerelay)(","); + } + if (buf->thisisiid && (tattr->cbSizeInstance==sizeof(GUID))) + memcpy(&(buf->iid),arg,sizeof(buf->iid)); + if (debugout) TRACE_(olerelay)("}"); + break; + } + default: + FIXME("Unhandled typekind %d\n",tattr->typekind); + hres = E_FAIL; + break; + } + ITypeInfo_Release(tinfo2); + return hres; + } + case VT_CARRAY: { + ARRAYDESC *adesc = tdesc->u.lpadesc; + int i, arrsize = 1; + + if (debugout) TRACE_(olerelay)("carr"); + for (i=0;icDims;i++) { + if (debugout) TRACE_(olerelay)("[%ld]",adesc->rgbounds[i].cElements); + arrsize *= adesc->rgbounds[i].cElements; + } + if (debugout) TRACE_(olerelay)("["); + for (i=0;itdescElem, (DWORD*)((LPBYTE)arg+i*_xsize(&adesc->tdescElem)), buf); + if (hres) + return hres; + if (debugout && (ivt); + return S_OK; + } +} + +static HRESULT +serialize_LPVOID_ptr( + ITypeInfo *tinfo, + BOOL writeit, + BOOL debugout, + BOOL dealloc, + TYPEDESC *tdesc, + DWORD *arg, + marshal_state *buf) +{ + HRESULT hres; + DWORD cookie; + + if ((tdesc->vt != VT_PTR) || + (tdesc->u.lptdesc->vt != VT_PTR) || + (tdesc->u.lptdesc->u.lptdesc->vt != VT_VOID) + ) { + FIXME("ppvObject not expressed as VT_PTR -> VT_PTR -> VT_VOID?\n"); + return E_FAIL; + } + cookie = (*arg) ? 0x42424242: 0x0; + if (writeit) { + hres = xbuf_add(buf, (LPVOID)&cookie, sizeof(cookie)); + if (hres) + return hres; + } + if (!*arg) { + if (debugout) TRACE_(olerelay)(""); + return S_OK; + } + if (debugout) + TRACE_(olerelay)("ppv(%p)",*(LPUNKNOWN*)*arg); + if (writeit) { + hres = _marshal_interface(buf,&(buf->iid),*(LPUNKNOWN*)*arg); + if (hres) + return hres; + } + if (dealloc) + HeapFree(GetProcessHeap(),0,(LPVOID)*arg); + return S_OK; +} + +static HRESULT +serialize_DISPPARAM_ptr( + ITypeInfo *tinfo, + BOOL writeit, + BOOL debugout, + BOOL dealloc, + TYPEDESC *tdesc, + DWORD *arg, + marshal_state *buf) +{ + DWORD cookie; + HRESULT hres; + DISPPARAMS *disp; + int i; + + if ((tdesc->vt != VT_PTR) || (tdesc->u.lptdesc->vt != VT_USERDEFINED)) { + FIXME("DISPPARAMS not expressed as VT_PTR -> VT_USERDEFINED?\n"); + return E_FAIL; + } + + cookie = *arg ? 0x42424242 : 0x0; + if (writeit) { + hres = xbuf_add(buf,(LPBYTE)&cookie,sizeof(cookie)); + if (hres) + return hres; + } + if (!*arg) { + if (debugout) TRACE_(olerelay)(""); + return S_OK; + } + disp = (DISPPARAMS*)*arg; + if (writeit) { + hres = xbuf_add(buf,(LPBYTE)&disp->cArgs,sizeof(disp->cArgs)); + if (hres) + return hres; + } + if (debugout) TRACE_(olerelay)("D{"); + for (i=0;icArgs;i++) { + TYPEDESC vtdesc; + + vtdesc.vt = VT_VARIANT; + serialize_param( + tinfo, + writeit, + debugout, + dealloc, + &vtdesc, + (DWORD*)(disp->rgvarg+i), + buf + ); + if (debugout && (icArgs-1)) + TRACE_(olerelay)(","); + } + if (dealloc) + HeapFree(GetProcessHeap(),0,disp->rgvarg); + if (writeit) { + hres = xbuf_add(buf,(LPBYTE)&disp->cNamedArgs,sizeof(disp->cNamedArgs)); + if (hres) + return hres; + } + if (debugout) TRACE_(olerelay)("}{"); + for (i=0;icNamedArgs;i++) { + TYPEDESC vtdesc; + + vtdesc.vt = VT_UINT; + serialize_param( + tinfo, + writeit, + debugout, + dealloc, + &vtdesc, + (DWORD*)(disp->rgdispidNamedArgs+i), + buf + ); + if (debugout && (icNamedArgs-1)) + TRACE_(olerelay)(","); + } + if (debugout) TRACE_(olerelay)("}"); + if (dealloc) { + HeapFree(GetProcessHeap(),0,disp->rgdispidNamedArgs); + HeapFree(GetProcessHeap(),0,disp); + } + return S_OK; +} + +static HRESULT +deserialize_param( + ITypeInfo *tinfo, + BOOL readit, + BOOL debugout, + BOOL alloc, + TYPEDESC *tdesc, + DWORD *arg, + marshal_state *buf) +{ + HRESULT hres = S_OK; + + TRACE("vt %d at %p\n",tdesc->vt,arg); + + while (1) { + switch (tdesc->vt) { + case VT_EMPTY: + if (debugout) TRACE_(olerelay)(""); + return S_OK; + case VT_NULL: + if (debugout) TRACE_(olerelay)(""); + return S_OK; + case VT_VARIANT: { + VARIANT *vt = (VARIANT*)arg; + + if (readit) { + DWORD vttype; + TYPEDESC tdesc2; + hres = xbuf_get(buf,(LPBYTE)&vttype,sizeof(vttype)); + if (hres) { + FIXME("vt type not read?\n"); + return hres; + } + memset(&tdesc2,0,sizeof(tdesc2)); + tdesc2.vt = vttype; + V_VT(vt) = vttype; + if (debugout) TRACE_(olerelay)("Vt(%ld)(",vttype); + hres = deserialize_param(tinfo, readit, debugout, alloc, &tdesc2, &(V_I4(vt)), buf); + TRACE_(olerelay)(")"); + return hres; + } else { + VariantInit(vt); + return S_OK; + } + } + case VT_ERROR: + case VT_BOOL: case VT_I4: case VT_UI4: case VT_UINT: case VT_R4: + case VT_UI2: + case VT_UI1: + if (readit) { + hres = xbuf_get(buf,(LPBYTE)arg,sizeof(DWORD)); + if (hres) FIXME("Failed to read integer 4 byte\n"); + } + if (debugout) TRACE_(olerelay)("%lx",*arg); + return hres; + case VT_BSTR: { + WCHAR *str; + DWORD len; + + if (readit) { + hres = xbuf_get(buf,(LPBYTE)&len,sizeof(DWORD)); + if (hres) { + FIXME("failed to read bstr klen\n"); + return hres; + } + if (len == -1) { + *arg = 0; + if (debugout) TRACE_(olerelay)(""); + } else { + str = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,len+sizeof(WCHAR)); + hres = xbuf_get(buf,(LPBYTE)str,len); + if (hres) { + FIXME("Failed to read BSTR.\n"); + return hres; + } + *arg = (DWORD)SysAllocStringLen(str,len); + if (debugout) TRACE_(olerelay)("%s",relaystr(str)); + HeapFree(GetProcessHeap(),0,str); + } + } else { + *arg = 0; + } + return S_OK; + } + case VT_PTR: { + DWORD cookie; + BOOL derefhere = 0; + + derefhere = (tdesc->u.lptdesc->vt != VT_USERDEFINED); + + if (readit) { + hres = xbuf_get(buf,(LPBYTE)&cookie,sizeof(cookie)); + if (hres) { + FIXME("Failed to load pointer cookie.\n"); + return hres; + } + if (cookie != 0x42424242) { + if (debugout) TRACE_(olerelay)("NULL"); + *arg = 0; + return S_OK; + } + if (debugout) TRACE_(olerelay)("*"); + } + if (alloc) { + if (derefhere) + *arg=(DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,_xsize(tdesc->u.lptdesc)); + } + if (derefhere) + return deserialize_param(tinfo, readit, debugout, alloc, tdesc->u.lptdesc, (LPDWORD)*arg, buf); + else + return deserialize_param(tinfo, readit, debugout, alloc, tdesc->u.lptdesc, arg, buf); + } + case VT_UNKNOWN: + /* FIXME: UNKNOWN is unknown ..., but allocate 4 byte for it */ + if (alloc) + *arg=(DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DWORD)); + hres = S_OK; + if (readit) + hres = _unmarshal_interface(buf,&IID_IUnknown,(LPUNKNOWN*)arg); + if (debugout) + TRACE_(olerelay)("unk(%p)",arg); + return hres; + case VT_DISPATCH: + hres = S_OK; + if (readit) + hres = _unmarshal_interface(buf,&IID_IDispatch,(LPUNKNOWN*)arg); + if (debugout) + TRACE_(olerelay)("idisp(%p)",arg); + return hres; + case VT_VOID: + if (debugout) TRACE_(olerelay)(""); + return S_OK; + case VT_USERDEFINED: { + ITypeInfo *tinfo2; + TYPEATTR *tattr; + + hres = ITypeInfo_GetRefTypeInfo(tinfo,tdesc->u.hreftype,&tinfo2); + if (hres) { + FIXME("Could not get typeinfo of hreftype %lx for VT_USERDEFINED.\n",tdesc->u.hreftype); + return hres; + } + hres = ITypeInfo_GetTypeAttr(tinfo2,&tattr); + if (hres) { + FIXME("Could not get typeattr in VT_USERDEFINED.\n"); + } else { + if (alloc) + *arg = (DWORD)HeapAlloc(GetProcessHeap(),0,tattr->cbSizeInstance); + switch (tattr->typekind) { + case TKIND_DISPATCH: + case TKIND_INTERFACE: + if (readit) + hres = _unmarshal_interface(buf,&(tattr->guid),(LPUNKNOWN*)arg); + break; + case TKIND_RECORD: { + int i; + + if (debugout) TRACE_(olerelay)("{"); + for (i=0;icVars;i++) { + VARDESC *vdesc; + + hres = ITypeInfo2_GetVarDesc(tinfo2, i, &vdesc); + if (hres) { + FIXME("Could not get vardesc of %d\n",i); + return hres; + } + hres = deserialize_param( + tinfo2, + readit, + debugout, + alloc, + &vdesc->elemdescVar.tdesc, + (DWORD*)(((LPBYTE)*arg)+vdesc->u.oInst), + buf + ); + if (debugout && (icVars-1)) TRACE_(olerelay)(","); + } + if (buf->thisisiid && (tattr->cbSizeInstance==sizeof(GUID))) + memcpy(&(buf->iid),(LPBYTE)*arg,sizeof(buf->iid)); + if (debugout) TRACE_(olerelay)("}"); + break; + } + default: + ERR("Unhandled typekind %d\n",tattr->typekind); + hres = E_FAIL; + break; + } + } + if (hres) + FIXME("failed to stuballoc in TKIND_RECORD.\n"); + ITypeInfo_Release(tinfo2); + return hres; + } + case VT_CARRAY: { + /* arg is pointing to the start of the array. */ + ARRAYDESC *adesc = tdesc->u.lpadesc; + int arrsize,i; + arrsize = 1; + if (adesc->cDims > 1) FIXME("cDims > 1 in VT_CARRAY. Does it work?\n"); + for (i=0;icDims;i++) + arrsize *= adesc->rgbounds[i].cElements; + for (i=0;itdescElem, + (DWORD*)((LPBYTE)(arg)+i*_xsize(&adesc->tdescElem)), + buf + ); + return S_OK; + } + default: + ERR("No handler for VT type %d!\n",tdesc->vt); + return S_OK; + } + } +} + +static HRESULT +deserialize_LPVOID_ptr( + ITypeInfo *tinfo, + BOOL readit, + BOOL debugout, + BOOL alloc, + TYPEDESC *tdesc, + DWORD *arg, + marshal_state *buf +) { + HRESULT hres; + DWORD cookie; + + if ((tdesc->vt != VT_PTR) || + (tdesc->u.lptdesc->vt != VT_PTR) || + (tdesc->u.lptdesc->u.lptdesc->vt != VT_VOID) + ) { + FIXME("ppvObject not expressed as VT_PTR -> VT_PTR -> VT_VOID?\n"); + return E_FAIL; + } + if (alloc) + *arg=(DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(LPVOID)); + if (readit) { + hres = xbuf_get(buf, (LPVOID)&cookie, sizeof(cookie)); + if (hres) + return hres; + if (cookie != 0x42424242) { + *(DWORD*)*arg = 0; + if (debugout) TRACE_(olerelay)(""); + return S_OK; + } + } + if (readit) { + hres = _unmarshal_interface(buf,&buf->iid,(LPUNKNOWN*)*arg); + if (hres) + return hres; + } + if (debugout) TRACE_(olerelay)("ppv(%p)",(LPVOID)*arg); + return S_OK; +} + +static HRESULT +deserialize_DISPPARAM_ptr( + ITypeInfo *tinfo, + BOOL readit, + BOOL debugout, + BOOL alloc, + TYPEDESC *tdesc, + DWORD *arg, + marshal_state *buf) +{ + DWORD cookie; + DISPPARAMS *disps; + HRESULT hres; + int i; + + if ((tdesc->vt != VT_PTR) || (tdesc->u.lptdesc->vt != VT_USERDEFINED)) { + FIXME("DISPPARAMS not expressed as VT_PTR -> VT_USERDEFINED?\n"); + return E_FAIL; + } + if (readit) { + hres = xbuf_get(buf,(LPBYTE)&cookie,sizeof(cookie)); + if (hres) + return hres; + if (cookie == 0) { + *arg = 0; + if (debugout) TRACE_(olerelay)(""); + return S_OK; + } + } + if (alloc) + *arg = (DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DISPPARAMS)); + disps = (DISPPARAMS*)*arg; + if (!readit) + return S_OK; + hres = xbuf_get(buf, (LPBYTE)&disps->cArgs, sizeof(disps->cArgs)); + if (hres) + return hres; + if (alloc) + disps->rgvarg = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(VARIANT)*disps->cArgs); + if (debugout) TRACE_(olerelay)("D{"); + for (i=0; i< disps->cArgs; i++) { + TYPEDESC vdesc; + + vdesc.vt = VT_VARIANT; + hres = deserialize_param( + tinfo, + readit, + debugout, + alloc, + &vdesc, + (DWORD*)(disps->rgvarg+i), + buf + ); + } + if (debugout) TRACE_(olerelay)("}{"); + hres = xbuf_get(buf, (LPBYTE)&disps->cNamedArgs, sizeof(disps->cNamedArgs)); + if (hres) + return hres; + if (disps->cNamedArgs) { + if (alloc) + disps->rgdispidNamedArgs = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DISPID)*disps->cNamedArgs); + for (i=0; i< disps->cNamedArgs; i++) { + TYPEDESC vdesc; + + vdesc.vt = VT_UINT; + hres = deserialize_param( + tinfo, + readit, + debugout, + alloc, + &vdesc, + (DWORD*)(disps->rgdispidNamedArgs+i), + buf + ); + if (debugout && i<(disps->cNamedArgs-1)) TRACE_(olerelay)(","); + } + } + if (debugout) TRACE_(olerelay)("}"); + return S_OK; +} + +/* Searches function, also in inherited interfaces */ +static HRESULT +_get_funcdesc( + ITypeInfo *tinfo, int iMethod, FUNCDESC **fdesc, BSTR *iname, BSTR *fname) +{ + int i = 0, j = 0; + HRESULT hres; + + if (fname) *fname = NULL; + if (iname) *iname = NULL; + + while (1) { + hres = ITypeInfo_GetFuncDesc(tinfo, i, fdesc); + if (hres) { + ITypeInfo *tinfo2; + HREFTYPE href; + TYPEATTR *attr; + + hres = ITypeInfo_GetTypeAttr(tinfo, &attr); + if (hres) { + FIXME("GetTypeAttr failed with %lx\n",hres); + return hres; + } + /* Not found, so look in inherited ifaces. */ + for (j=0;jcImplTypes;j++) { + hres = ITypeInfo_GetRefTypeOfImplType(tinfo, j, &href); + if (hres) { + FIXME("Did not find a reftype for interface offset %d?\n",j); + break; + } + hres = ITypeInfo_GetRefTypeInfo(tinfo, href, &tinfo2); + if (hres) { + FIXME("Did not find a typeinfo for reftype %ld?\n",href); + continue; + } + hres = _get_funcdesc(tinfo2,iMethod,fdesc,iname,fname); + ITypeInfo_Release(tinfo2); + if (!hres) return S_OK; + } + return E_FAIL; + } + if (((*fdesc)->oVft/4) == iMethod) { + if (fname) + ITypeInfo_GetDocumentation(tinfo,(*fdesc)->memid,fname,NULL,NULL,NULL); + if (iname) + ITypeInfo_GetDocumentation(tinfo,-1,iname,NULL,NULL,NULL); + return S_OK; + } + i++; + } + return E_FAIL; +} + +static DWORD +xCall(LPVOID retptr, int method, TMProxyImpl *tpinfo /*, args */) +{ + DWORD *args = ((DWORD*)&tpinfo)+1, *xargs; + FUNCDESC *fdesc; + HRESULT hres; + int i, relaydeb = TRACE_ON(olerelay); + marshal_state buf; + RPCOLEMESSAGE msg; + ULONG status; + BSTR fname,iname; + BSTR names[10]; + int nrofnames; + + EnterCriticalSection(&tpinfo->crit); + + hres = _get_funcdesc(tpinfo->tinfo,method,&fdesc,&iname,&fname); + if (hres) { + ERR("Did not find typeinfo/funcdesc entry for method %d!\n",method); + LeaveCriticalSection(&tpinfo->crit); + return E_FAIL; + } + + if (relaydeb) { + TRACE_(olerelay)("->"); + if (iname) + TRACE_(olerelay)("%s:",relaystr(iname)); + if (fname) + TRACE_(olerelay)("%s(%d)",relaystr(fname),method); + else + TRACE_(olerelay)("%d",method); + TRACE_(olerelay)("("); + if (iname) SysFreeString(iname); + if (fname) SysFreeString(fname); + } + /* Need them for hack below */ + memset(names,0,sizeof(names)); + if (ITypeInfo_GetNames(tpinfo->tinfo,fdesc->memid,names,sizeof(names)/sizeof(names[0]),&nrofnames)) + nrofnames = 0; + if (nrofnames > sizeof(names)/sizeof(names[0])) + ERR("Need more names!\n"); + + memset(&buf,0,sizeof(buf)); + buf.iid = IID_IUnknown; + if (method == 0) { + xbuf_add(&buf,(LPBYTE)args[0],sizeof(IID)); + if (relaydeb) TRACE_(olerelay)("riid=%s,[out]",debugstr_guid((REFIID)args[0])); + } else { + xargs = args; + for (i=0;icParams;i++) { + ELEMDESC *elem = fdesc->lprgelemdescParam+i; + BOOL isserialized = FALSE; + if (relaydeb) { + if (i) TRACE_(olerelay)(","); + if (i+1tinfo, + elem->u.paramdesc.wParamFlags & PARAMFLAG_FIN, + relaydeb, + FALSE, + &elem->tdesc, + xargs, + &buf + ); + isserialized = TRUE; + } + if (!lstrcmpW(names[i+1],ppvObjectW)) { + hres = serialize_LPVOID_ptr( + tpinfo->tinfo, + elem->u.paramdesc.wParamFlags & PARAMFLAG_FIN, + relaydeb, + FALSE, + &elem->tdesc, + xargs, + &buf + ); + if (hres == S_OK) + isserialized = TRUE; + } + } + if (!isserialized) + hres = serialize_param( + tpinfo->tinfo, + elem->u.paramdesc.wParamFlags & PARAMFLAG_FIN, + relaydeb, + FALSE, + &elem->tdesc, + xargs, + &buf + ); + + if (hres) { + FIXME("Failed to serialize param, hres %lx\n",hres); + break; + } + xargs+=_argsize(elem->tdesc.vt); + } + } + if (relaydeb) TRACE_(olerelay)(")"); + memset(&msg,0,sizeof(msg)); + msg.cbBuffer = buf.curoff; + msg.iMethod = method; + hres = IRpcChannelBuffer_GetBuffer(tpinfo->chanbuf,&msg,&(tpinfo->iid)); + if (hres) { + FIXME("RpcChannelBuffer GetBuffer failed, %lx\n",hres); + LeaveCriticalSection(&tpinfo->crit); + return hres; + } + memcpy(msg.Buffer,buf.base,buf.curoff); + if (relaydeb) TRACE_(olerelay)("\n"); + hres = IRpcChannelBuffer_SendReceive(tpinfo->chanbuf,&msg,&status); + if (hres) { + FIXME("RpcChannelBuffer SendReceive failed, %lx\n",hres); + LeaveCriticalSection(&tpinfo->crit); + return hres; + } + + if (relaydeb) TRACE_(olerelay)(" = %08lx (",status); + if (buf.base) + buf.base = HeapReAlloc(GetProcessHeap(),0,buf.base,msg.cbBuffer); + else + buf.base = HeapAlloc(GetProcessHeap(),0,msg.cbBuffer); + buf.size = msg.cbBuffer; + memcpy(buf.base,msg.Buffer,buf.size); + buf.curoff = 0; + if (method == 0) { + _unmarshal_interface(&buf,(REFIID)args[0],(LPUNKNOWN*)args[1]); + if (relaydeb) TRACE_(olerelay)("[in],%p",*((DWORD**)args[1])); + } else { + xargs = args; + for (i=0;icParams;i++) { + ELEMDESC *elem = fdesc->lprgelemdescParam+i; + BOOL isdeserialized = FALSE; + + if (relaydeb) { + if (i) TRACE_(olerelay)(","); + if (i+1tinfo, + elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT, + relaydeb, + FALSE, + &(elem->tdesc), + xargs, + &buf + ); + if (hres) { + FIXME("Failed to deserialize DISPPARAM*, hres %lx\n",hres); + break; + } + isdeserialized = TRUE; + } + if (!lstrcmpW(names[i+1],ppvObjectW)) { + hres = deserialize_LPVOID_ptr( + tpinfo->tinfo, + elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT, + relaydeb, + FALSE, + &elem->tdesc, + xargs, + &buf + ); + if (hres == S_OK) + isdeserialized = TRUE; + } + } + if (!isdeserialized) + hres = deserialize_param( + tpinfo->tinfo, + elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT, + relaydeb, + FALSE, + &(elem->tdesc), + xargs, + &buf + ); + if (hres) { + FIXME("Failed to unmarshall param, hres %lx\n",hres); + break; + } + xargs += _argsize(elem->tdesc.vt); + } + } + if (relaydeb) TRACE_(olerelay)(")\n"); + HeapFree(GetProcessHeap(),0,buf.base); + + LeaveCriticalSection(&tpinfo->crit); + + return status; +} + +static HRESULT WINAPI +PSFacBuf_CreateProxy( + LPPSFACTORYBUFFER iface, IUnknown* pUnkOuter, REFIID riid, + IRpcProxyBuffer **ppProxy, LPVOID *ppv) +{ + HRESULT hres; + ITypeInfo *tinfo; + int i, nroffuncs; + FUNCDESC *fdesc; + TMProxyImpl *proxy; + + TRACE("(...%s...)\n",debugstr_guid(riid)); + hres = _get_typeinfo_for_iid(riid,&tinfo); + if (hres) { + FIXME("No typeinfo for %s?\n",debugstr_guid(riid)); + return hres; + } + nroffuncs = _nroffuncs(tinfo); + proxy = CoTaskMemAlloc(sizeof(TMProxyImpl)); + if (!proxy) return E_OUTOFMEMORY; + + assert(sizeof(TMAsmProxy) == 12); + + proxy->asmstubs = VirtualAlloc(NULL, sizeof(TMAsmProxy) * nroffuncs, MEM_COMMIT, PAGE_EXECUTE_READWRITE); + if (!proxy->asmstubs) { + ERR("Could not commit pages for proxy thunks\n"); + CoTaskMemFree(proxy); + return E_OUTOFMEMORY; + } + + InitializeCriticalSection(&proxy->crit); + + proxy->lpvtbl = HeapAlloc(GetProcessHeap(),0,sizeof(LPBYTE)*nroffuncs); + for (i=0;iasmstubs+i; + + /* nrofargs without This */ + switch (i) { + case 0: nrofargs = 2; + break; + case 1: case 2: nrofargs = 0; + break; + default: { + int j; + hres = _get_funcdesc(tinfo,i,&fdesc,NULL,NULL); + if (hres) { + FIXME("GetFuncDesc %lx should not fail here.\n",hres); + return hres; + } + /* some args take more than 4 byte on the stack */ + nrofargs = 0; + for (j=0;jcParams;j++) + nrofargs += _argsize(fdesc->lprgelemdescParam[j].tdesc.vt); + + if (fdesc->callconv != CC_STDCALL) { + ERR("calling convention is not stdcall????\n"); + return E_FAIL; + } + break; + } + } +/* popl %eax - return ptr + * pushl + * pushl %eax + * call xCall + * lret (+4) + * + * + * arg3 arg2 arg1 + */ + xasm->popleax = 0x58; + xasm->pushlval = 0x6a; + xasm->nr = i; + xasm->pushleax = 0x50; + xasm->lcall = 0xe8; /* relative jump */ + xasm->xcall = (DWORD)xCall; + xasm->xcall -= (DWORD)&(xasm->lret); + xasm->lret = 0xc2; + xasm->bytestopop= (nrofargs+2)*4; /* pop args, This, iMethod */ + proxy->lpvtbl[i] = xasm; + } + proxy->lpvtbl2 = &tmproxyvtable; + /* 1 reference for the proxy and 1 for the object */ + proxy->ref = 2; + proxy->tinfo = tinfo; + memcpy(&proxy->iid,riid,sizeof(*riid)); + *ppv = (LPVOID)proxy; + *ppProxy = (IRpcProxyBuffer *)&(proxy->lpvtbl2); + return S_OK; +} + +typedef struct _TMStubImpl { + IRpcStubBufferVtbl *lpvtbl; + ULONG ref; + + LPUNKNOWN pUnk; + ITypeInfo *tinfo; + IID iid; +} TMStubImpl; + +static HRESULT WINAPI +TMStubImpl_QueryInterface(LPRPCSTUBBUFFER iface, REFIID riid, LPVOID *ppv) +{ + if (IsEqualIID(riid,&IID_IRpcStubBuffer)||IsEqualIID(riid,&IID_IUnknown)){ + *ppv = (LPVOID)iface; + IRpcStubBuffer_AddRef(iface); + return S_OK; + } + FIXME("%s, not supported IID.\n",debugstr_guid(riid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI +TMStubImpl_AddRef(LPRPCSTUBBUFFER iface) +{ + TMStubImpl *This = (TMStubImpl *)iface; + + TRACE("(%p) before %lu\n", This, This->ref); + + return InterlockedIncrement(&This->ref); +} + +static ULONG WINAPI +TMStubImpl_Release(LPRPCSTUBBUFFER iface) +{ + ULONG refs; + TMStubImpl *This = (TMStubImpl *)iface; + + TRACE("(%p) after %lu\n", This, This->ref-1); + + refs = InterlockedDecrement(&This->ref); + if (!refs) + { + IRpcStubBuffer_Disconnect(iface); + CoTaskMemFree(This); + } + return refs; +} + +static HRESULT WINAPI +TMStubImpl_Connect(LPRPCSTUBBUFFER iface, LPUNKNOWN pUnkServer) +{ + TMStubImpl *This = (TMStubImpl *)iface; + + TRACE("(%p)->(%p)\n", This, pUnkServer); + + IUnknown_AddRef(pUnkServer); + This->pUnk = pUnkServer; + return S_OK; +} + +static void WINAPI +TMStubImpl_Disconnect(LPRPCSTUBBUFFER iface) +{ + TMStubImpl *This = (TMStubImpl *)iface; + + TRACE("(%p)->()\n", This); + + IUnknown_Release(This->pUnk); + This->pUnk = NULL; + return; +} + +static HRESULT WINAPI +TMStubImpl_Invoke( + LPRPCSTUBBUFFER iface, RPCOLEMESSAGE* xmsg,IRpcChannelBuffer*rpcchanbuf) +{ + int i; + FUNCDESC *fdesc; + TMStubImpl *This = (TMStubImpl *)iface; + HRESULT hres; + DWORD *args, res, *xargs, nrofargs; + marshal_state buf; + int nrofnames; + BSTR names[10]; + + memset(&buf,0,sizeof(buf)); + buf.size = xmsg->cbBuffer; + buf.base = xmsg->Buffer; + buf.curoff = 0; + buf.iid = IID_IUnknown; + + TRACE("...\n"); + if (xmsg->iMethod == 0) { /* QI */ + IID xiid; + /* in: IID, out: */ + + xbuf_get(&buf,(LPBYTE)&xiid,sizeof(xiid)); + buf.curoff = 0; + hres = _marshal_interface(&buf,&xiid,This->pUnk); + xmsg->Buffer = buf.base; /* Might have been reallocated */ + xmsg->cbBuffer = buf.size; + return hres; + } + hres = _get_funcdesc(This->tinfo,xmsg->iMethod,&fdesc,NULL,NULL); + if (hres) { + FIXME("GetFuncDesc on method %ld failed with %lx\n",xmsg->iMethod,hres); + return hres; + } + /* Need them for hack below */ + memset(names,0,sizeof(names)); + ITypeInfo_GetNames(This->tinfo,fdesc->memid,names,sizeof(names)/sizeof(names[0]),&nrofnames); + if (nrofnames > sizeof(names)/sizeof(names[0])) { + ERR("Need more names!\n"); + } + + /*dump_FUNCDESC(fdesc);*/ + nrofargs = 0; + for (i=0;icParams;i++) + nrofargs += _argsize(fdesc->lprgelemdescParam[i].tdesc.vt); + args = HeapAlloc(GetProcessHeap(),0,(nrofargs+1)*sizeof(DWORD)); + if (!args) return E_OUTOFMEMORY; + + /* Allocate all stuff used by call. */ + xargs = args+1; + for (i=0;icParams;i++) { + ELEMDESC *elem = fdesc->lprgelemdescParam+i; + BOOL isdeserialized = FALSE; + + if (((i+1)tinfo, + elem->u.paramdesc.wParamFlags & PARAMFLAG_FIN, + FALSE, + TRUE, + &(elem->tdesc), + xargs, + &buf + ); + if (hres) { + FIXME("Failed to deserialize DISPPARAM*, hres %lx\n",hres); + break; + } + isdeserialized = TRUE; + } + if (!lstrcmpW(names[i+1],ppvObjectW)) { + hres = deserialize_LPVOID_ptr( + This->tinfo, + elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT, + FALSE, + TRUE, + &elem->tdesc, + xargs, + &buf + ); + if (hres == S_OK) + isdeserialized = TRUE; + } + } + if (!isdeserialized) + hres = deserialize_param( + This->tinfo, + elem->u.paramdesc.wParamFlags & PARAMFLAG_FIN, + FALSE, + TRUE, + &(elem->tdesc), + xargs, + &buf + ); + xargs += _argsize(elem->tdesc.vt); + if (hres) { + FIXME("Failed to deserialize param %s, hres %lx\n",relaystr(names[i+1]),hres); + break; + } + } + hres = IUnknown_QueryInterface(This->pUnk,&(This->iid),(LPVOID*)&(args[0])); + if (hres) { + ERR("Does not support iface %s\n",debugstr_guid(&(This->iid))); + return hres; + } + res = _invoke( + (*((FARPROC**)args[0]))[fdesc->oVft/4], + fdesc->callconv, + (xargs-args), + args + ); + IUnknown_Release((LPUNKNOWN)args[0]); + buf.curoff = 0; + xargs = args+1; + for (i=0;icParams;i++) { + ELEMDESC *elem = fdesc->lprgelemdescParam+i; + BOOL isserialized = FALSE; + + if (((i+1)tinfo, + elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT, + FALSE, + TRUE, + &elem->tdesc, + xargs, + &buf + ); + isserialized = TRUE; + } + if (!lstrcmpW(names[i+1],ppvObjectW)) { + hres = serialize_LPVOID_ptr( + This->tinfo, + elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT, + FALSE, + TRUE, + &elem->tdesc, + xargs, + &buf + ); + if (hres == S_OK) + isserialized = TRUE; + } + } + if (!isserialized) + hres = serialize_param( + This->tinfo, + elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT, + FALSE, + TRUE, + &elem->tdesc, + xargs, + &buf + ); + xargs += _argsize(elem->tdesc.vt); + if (hres) { + FIXME("Failed to stuballoc param, hres %lx\n",hres); + break; + } + } + /* might need to use IRpcChannelBuffer_GetBuffer ? */ + xmsg->cbBuffer = buf.curoff; + xmsg->Buffer = buf.base; + HeapFree(GetProcessHeap(),0,args); + return res; +} + +static LPRPCSTUBBUFFER WINAPI +TMStubImpl_IsIIDSupported(LPRPCSTUBBUFFER iface, REFIID riid) { + FIXME("Huh (%s)?\n",debugstr_guid(riid)); + return NULL; +} + +static ULONG WINAPI +TMStubImpl_CountRefs(LPRPCSTUBBUFFER iface) { + TMStubImpl *This = (TMStubImpl *)iface; + + return This->ref; /*FIXME? */ +} + +static HRESULT WINAPI +TMStubImpl_DebugServerQueryInterface(LPRPCSTUBBUFFER iface, LPVOID *ppv) { + return E_NOTIMPL; +} + +static void WINAPI +TMStubImpl_DebugServerRelease(LPRPCSTUBBUFFER iface, LPVOID ppv) { + return; +} + +IRpcStubBufferVtbl tmstubvtbl = { + TMStubImpl_QueryInterface, + TMStubImpl_AddRef, + TMStubImpl_Release, + TMStubImpl_Connect, + TMStubImpl_Disconnect, + TMStubImpl_Invoke, + TMStubImpl_IsIIDSupported, + TMStubImpl_CountRefs, + TMStubImpl_DebugServerQueryInterface, + TMStubImpl_DebugServerRelease +}; + +static HRESULT WINAPI +PSFacBuf_CreateStub( + LPPSFACTORYBUFFER iface, REFIID riid,IUnknown *pUnkServer, + IRpcStubBuffer** ppStub +) { + HRESULT hres; + ITypeInfo *tinfo; + TMStubImpl *stub; + + TRACE("(%s,%p,%p)\n",debugstr_guid(riid),pUnkServer,ppStub); + hres = _get_typeinfo_for_iid(riid,&tinfo); + if (hres) { + FIXME("No typeinfo for %s?\n",debugstr_guid(riid)); + return hres; + } + stub = CoTaskMemAlloc(sizeof(TMStubImpl)); + if (!stub) + return E_OUTOFMEMORY; + stub->lpvtbl = &tmstubvtbl; + stub->ref = 1; + stub->tinfo = tinfo; + memcpy(&(stub->iid),riid,sizeof(*riid)); + hres = IRpcStubBuffer_Connect((LPRPCSTUBBUFFER)stub,pUnkServer); + *ppStub = (LPRPCSTUBBUFFER)stub; + TRACE("IRpcStubBuffer: %p\n", stub); + if (hres) + FIXME("Connect to pUnkServer failed?\n"); + return hres; +} + +static IPSFactoryBufferVtbl psfacbufvtbl = { + PSFacBuf_QueryInterface, + PSFacBuf_AddRef, + PSFacBuf_Release, + PSFacBuf_CreateProxy, + PSFacBuf_CreateStub +}; + +/* This is the whole PSFactoryBuffer object, just the vtableptr */ +static IPSFactoryBufferVtbl *lppsfac = &psfacbufvtbl; + +/*********************************************************************** + * DllGetClassObject [OLE32.63] + */ +HRESULT WINAPI +TypeLibFac_DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv) +{ + if (IsEqualIID(iid,&IID_IPSFactoryBuffer)) { + *ppv = &lppsfac; + return S_OK; + } + return E_NOINTERFACE; +} diff --git a/reactos/lib/oleaut32/tmarshal.h b/reactos/lib/oleaut32/tmarshal.h new file mode 100644 index 00000000000..87c33063275 --- /dev/null +++ b/reactos/lib/oleaut32/tmarshal.h @@ -0,0 +1,24 @@ +/* + * Copyright 2002 Marcus Meissner + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef TMARSHAL_H +#define TMARSHAL_H +HRESULT WINAPI +TypeLibFac_DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv); + +#endif diff --git a/reactos/lib/oleaut32/typelib.c b/reactos/lib/oleaut32/typelib.c new file mode 100644 index 00000000000..4f8861178be --- /dev/null +++ b/reactos/lib/oleaut32/typelib.c @@ -0,0 +1,5923 @@ +/* + * TYPELIB + * + * Copyright 1997 Marcus Meissner + * 1999 Rein Klazes + * 2000 Francois Jacques + * 2001 Huw D M Davies for CodeWeavers + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * -------------------------------------------------------------------------------------- + * Known problems (2000, Francois Jacques) + * + * - Tested using OLEVIEW (Platform SDK tool) only. + * + * - dual interface dispinterfaces. vtable-interface ITypeInfo instances are + * creating by doing a straight copy of the dispinterface instance and just changing + * its typekind. Pointed structures aren't copied - only the address of the pointers. + * So when you release the dispinterface, you delete the vtable-interface structures + * as well... fortunately, clean up of structures is not implemented. + * + * - locale stuff is partially implemented but hasn't been tested. + * + * - typelib file is still read in its entirety, but it is released now. + * - some garbage is read from function names on some very rare occasions. + * + * -------------------------------------------------------------------------------------- + * Known problems left from previous implementation (1999, Rein Klazes) : + * + * -. Data structures are straightforward, but slow for look-ups. + * -. (related) nothing is hashed + * -. there are a number of stubs in ITypeLib and ITypeInfo interfaces. Most + * of them I don't know yet how to implement them. + * -. Most error return values are just guessed not checked with windows + * behaviour. + * -. didn't bother with a c++ interface + * -. lousy fatal error handling + * -. some methods just return pointers to internal data structures, this is + * partly laziness, partly I want to check how windows does it. + * + */ + +#include "config.h" +#include "wine/port.h" + +#include +#include +#include +#include +#include + +#define COBJMACROS +#define NONAMELESSUNION +#define NONAMELESSSTRUCT + +#include "winerror.h" +#include "windef.h" +#include "winbase.h" +#include "winnls.h" +#include "winreg.h" +#include "winuser.h" + +#include "wine/unicode.h" +#include "objbase.h" +#include "ole2disp.h" +#include "typelib.h" +#include "wine/debug.h" +#include "variant.h" + +WINE_DEFAULT_DEBUG_CHANNEL(ole); +WINE_DECLARE_DEBUG_CHANNEL(typelib); + +/* The OLE Automation ProxyStub Interface Class (aka Typelib Marshaler) */ +const GUID CLSID_PSOAInterface = { 0x00020424, 0, 0, { 0xC0, 0, 0, 0, 0, 0, 0, 0x46 } }; + +/**************************************************************************** + * FromLExxx + * + * Takes p_iVal (which is in little endian) and returns it + * in the host machine's byte order. + */ +#ifdef WORDS_BIGENDIAN +static WORD FromLEWord(WORD p_iVal) +{ + return (((p_iVal & 0x00FF) << 8) | + ((p_iVal & 0xFF00) >> 8)); +} + + +static DWORD FromLEDWord(DWORD p_iVal) +{ + return (((p_iVal & 0x000000FF) << 24) | + ((p_iVal & 0x0000FF00) << 8) | + ((p_iVal & 0x00FF0000) >> 8) | + ((p_iVal & 0xFF000000) >> 24)); +} +#else +#define FromLEWord(X) (X) +#define FromLEDWord(X) (X) +#endif + + +/**************************************************************************** + * FromLExxx + * + * Fix byte order in any structure if necessary + */ +#ifdef WORDS_BIGENDIAN +static void FromLEWords(void *p_Val, int p_iSize) +{ + WORD *Val = p_Val; + + p_iSize /= sizeof(WORD); + + while (p_iSize) { + *Val = FromLEWord(*Val); + Val++; + p_iSize--; + } +} + + +static void FromLEDWords(void *p_Val, int p_iSize) +{ + DWORD *Val = p_Val; + + p_iSize /= sizeof(DWORD); + + while (p_iSize) { + *Val = FromLEDWord(*Val); + Val++; + p_iSize--; + } +} +#else +#define FromLEWords(X,Y) /*nothing*/ +#define FromLEDWords(X,Y) /*nothing*/ +#endif + +/* get the path of a typelib key, in the form "Typelib\\\\." */ +/* buffer must be at least 60 characters long */ +static WCHAR *get_typelib_key( REFGUID guid, WORD wMaj, WORD wMin, WCHAR *buffer ) +{ + static const WCHAR TypelibW[] = {'T','y','p','e','l','i','b','\\',0}; + static const WCHAR VersionFormatW[] = {'\\','%','u','.','%','u',0}; + + memcpy( buffer, TypelibW, sizeof(TypelibW) ); + StringFromGUID2( guid, buffer + strlenW(buffer), 40 ); + sprintfW( buffer + strlenW(buffer), VersionFormatW, wMaj, wMin ); + return buffer; +} + +/* get the path of an interface key, in the form "Interface\\" */ +/* buffer must be at least 50 characters long */ +static WCHAR *get_interface_key( REFGUID guid, WCHAR *buffer ) +{ + static const WCHAR InterfaceW[] = {'I','n','t','e','r','f','a','c','e','\\',0}; + + memcpy( buffer, InterfaceW, sizeof(InterfaceW) ); + StringFromGUID2( guid, buffer + strlenW(buffer), 40 ); + return buffer; +} + +/* get the lcid subkey for a typelib, in the form "\\" */ +/* buffer must be at least 16 characters long */ +static WCHAR *get_lcid_subkey( LCID lcid, SYSKIND syskind, WCHAR *buffer ) +{ + static const WCHAR LcidFormatW[] = {'%','l','x','\\',0}; + static const WCHAR win16W[] = {'w','i','n','1','6',0}; + static const WCHAR win32W[] = {'w','i','n','3','2',0}; + + sprintfW( buffer, LcidFormatW, lcid ); + switch(syskind) + { + case SYS_WIN16: strcatW( buffer, win16W ); break; + case SYS_WIN32: strcatW( buffer, win32W ); break; + default: + TRACE("Typelib is for unsupported syskind %i\n", syskind); + return NULL; + } + return buffer; +} + + +/**************************************************************************** + * QueryPathOfRegTypeLib [OLEAUT32.164] + * RETURNS + * path of typelib + */ +HRESULT WINAPI +QueryPathOfRegTypeLib( + REFGUID guid, /* [in] referenced guid */ + WORD wMaj, /* [in] major version */ + WORD wMin, /* [in] minor version */ + LCID lcid, /* [in] locale id */ + LPBSTR path ) /* [out] path of typelib */ +{ + HRESULT hr = E_FAIL; + LCID myLCID = lcid; + HKEY hkey; + WCHAR buffer[60]; + WCHAR Path[MAX_PATH]; + + if ( !HIWORD(guid) ) + { + FIXME("(guid %p,%d,%d,0x%04lx,%p),stub!\n", guid, wMaj, wMin, lcid, path); + return E_FAIL; + } + + get_typelib_key( guid, wMaj, wMin, buffer ); + + if (RegOpenKeyW( HKEY_CLASSES_ROOT, buffer, &hkey ) != ERROR_SUCCESS) + { + TRACE_(typelib)("%s not found\n", debugstr_w(buffer)); + return E_FAIL; + } + + while (hr != S_OK) + { + DWORD dwPathLen = sizeof(Path); + + get_lcid_subkey( myLCID, SYS_WIN32, buffer ); + + if (RegQueryValueW(hkey, buffer, Path, &dwPathLen)) + { + if (!lcid) + break; + else if (myLCID == lcid) + { + /* try with sub-langid */ + myLCID = SUBLANGID(lcid); + } + else if ((myLCID == SUBLANGID(lcid)) && myLCID) + { + /* try with system langid */ + myLCID = 0; + } + else + { + break; + } + } + else + { + *path = SysAllocString( Path ); + hr = S_OK; + } + } + RegCloseKey( hkey ); + return hr; +} + +/****************************************************************************** + * CreateTypeLib [OLEAUT32.160] creates a typelib + * + * RETURNS + * Success: S_OK + * Failure: Status + */ +HRESULT WINAPI CreateTypeLib( + SYSKIND syskind, LPCOLESTR szFile, ICreateTypeLib** ppctlib +) { + FIXME("(%d,%s,%p), stub!\n",syskind,debugstr_w(szFile),ppctlib); + return E_FAIL; +} +/****************************************************************************** + * LoadTypeLib [OLEAUT32.161] + * Loads and registers a type library + * NOTES + * Docs: OLECHAR FAR* szFile + * Docs: iTypeLib FAR* FAR* pptLib + * + * RETURNS + * Success: S_OK + * Failure: Status + */ +int TLB_ReadTypeLib(LPCWSTR file, INT index, ITypeLib2 **ppTypelib); + +HRESULT WINAPI LoadTypeLib( + const OLECHAR *szFile,/* [in] Name of file to load from */ + ITypeLib * *pptLib) /* [out] Pointer to pointer to loaded type library */ +{ + TRACE("\n"); + return LoadTypeLibEx(szFile, REGKIND_DEFAULT, pptLib); +} + +/****************************************************************************** + * LoadTypeLibEx [OLEAUT32.183] + * Loads and optionally registers a type library + * + * RETURNS + * Success: S_OK + * Failure: Status + */ +HRESULT WINAPI LoadTypeLibEx( + LPCOLESTR szFile, /* [in] Name of file to load from */ + REGKIND regkind, /* [in] Specify kind of registration */ + ITypeLib **pptLib) /* [out] Pointer to pointer to loaded type library */ +{ + WCHAR szPath[MAX_PATH+1], szFileCopy[MAX_PATH+1]; + WCHAR *pIndexStr; + HRESULT res; + INT index = 1; + + TRACE("(%s,%d,%p)\n",debugstr_w(szFile), regkind, pptLib); + + *pptLib = NULL; + if(!SearchPathW(NULL,szFile,NULL,sizeof(szPath)/sizeof(WCHAR),szPath, + NULL)) { + + /* Look for a trailing '\\' followed by an index */ + pIndexStr = strrchrW(szFile, '\\'); + if(pIndexStr && pIndexStr != szFile && *++pIndexStr != '\0') { + index = atoiW(pIndexStr); + memcpy(szFileCopy, szFile, + (pIndexStr - szFile - 1) * sizeof(WCHAR)); + szFileCopy[pIndexStr - szFile - 1] = '\0'; + if(!SearchPathW(NULL,szFileCopy,NULL,sizeof(szPath)/sizeof(WCHAR), + szPath,NULL)) + return TYPE_E_CANTLOADLIBRARY; + if (GetFileAttributesW(szFileCopy) & FILE_ATTRIBUTE_DIRECTORY) + return TYPE_E_CANTLOADLIBRARY; + } else { + WCHAR tstpath[260]; + static const WCHAR stdole32tlb[] = { 's','t','d','o','l','e','3','2','.','t','l','b',0 }; + int i; + + lstrcpyW(tstpath,szFile); + CharLowerW(tstpath); + for (i=0;iguid, attr->wMajorVerNum, attr->wMinorVerNum, keyName ); + + res = S_OK; + if (RegCreateKeyExW(HKEY_CLASSES_ROOT, keyName, 0, NULL, 0, + KEY_WRITE, NULL, &key, NULL) == ERROR_SUCCESS) + { + LPOLESTR doc; + + /* Set the human-readable name of the typelib */ + if (SUCCEEDED(ITypeLib_GetDocumentation(ptlib, -1, NULL, &doc, NULL, NULL))) + { + if (RegSetValueExW(key, NULL, 0, REG_SZ, + (BYTE *)doc, (lstrlenW(doc)+1) * sizeof(OLECHAR)) != ERROR_SUCCESS) + res = E_FAIL; + + SysFreeString(doc); + } + else + res = E_FAIL; + + /* Make up the name of the typelib path subkey */ + if (!get_lcid_subkey( attr->lcid, attr->syskind, tmp )) res = E_FAIL; + + /* Create the typelib path subkey */ + if (res == S_OK && RegCreateKeyExW(key, tmp, 0, NULL, 0, + KEY_WRITE, NULL, &subKey, NULL) == ERROR_SUCCESS) + { + if (RegSetValueExW(subKey, NULL, 0, REG_SZ, + (BYTE *)szFullPath, (lstrlenW(szFullPath)+1) * sizeof(OLECHAR)) != ERROR_SUCCESS) + res = E_FAIL; + + RegCloseKey(subKey); + } + else + res = E_FAIL; + + /* Create the flags subkey */ + if (res == S_OK && RegCreateKeyExW(key, FLAGSW, 0, NULL, 0, + KEY_WRITE, NULL, &subKey, NULL) == ERROR_SUCCESS) + { + /* FIXME: is %u correct? */ + static const WCHAR formatW[] = {'%','u',0}; + WCHAR buf[20]; + sprintfW(buf, formatW, attr->wLibFlags); + if (RegSetValueExW(subKey, NULL, 0, REG_SZ, + (BYTE *)buf, (strlenW(buf) + 1)*sizeof(WCHAR) ) != ERROR_SUCCESS) + res = E_FAIL; + + RegCloseKey(subKey); + } + else + res = E_FAIL; + + /* create the helpdir subkey */ + if (res == S_OK && RegCreateKeyExW(key, HELPDIRW, 0, NULL, 0, + KEY_WRITE, NULL, &subKey, &disposition) == ERROR_SUCCESS) + { + BOOL freeHelpDir = FALSE; + OLECHAR* pIndexStr; + + /* if we created a new key, and helpDir was null, set the helpdir + to the directory which contains the typelib. However, + if we just opened an existing key, we leave the helpdir alone */ + if ((disposition == REG_CREATED_NEW_KEY) && (szHelpDir == NULL)) { + szHelpDir = SysAllocString(szFullPath); + pIndexStr = strrchrW(szHelpDir, '\\'); + if (pIndexStr) { + *pIndexStr = 0; + } + freeHelpDir = TRUE; + } + + /* if we have an szHelpDir, set it! */ + if (szHelpDir != NULL) { + if (RegSetValueExW(subKey, NULL, 0, REG_SZ, + (BYTE *)szHelpDir, (lstrlenW(szHelpDir)+1) * sizeof(OLECHAR)) != ERROR_SUCCESS) { + res = E_FAIL; + } + } + + /* tidy up */ + if (freeHelpDir) SysFreeString(szHelpDir); + RegCloseKey(subKey); + + } else { + res = E_FAIL; + } + + RegCloseKey(key); + } + else + res = E_FAIL; + + /* register OLE Automation-compatible interfaces for this typelib */ + types = ITypeLib_GetTypeInfoCount(ptlib); + for (tidx=0; tidxguid), + tattr->wTypeFlags); + + if (TRACE_ON(typelib)) { +#define XX(x) if (TYPEFLAG_##x & tattr->wTypeFlags) MESSAGE(#x"|"); + XX(FAPPOBJECT); + XX(FCANCREATE); + XX(FLICENSED); + XX(FPREDECLID); + XX(FHIDDEN); + XX(FCONTROL); + XX(FDUAL); + XX(FNONEXTENSIBLE); + XX(FOLEAUTOMATION); + XX(FRESTRICTED); + XX(FAGGREGATABLE); + XX(FREPLACEABLE); + XX(FDISPATCHABLE); + XX(FREVERSEBIND); + XX(FPROXY); +#undef XX + MESSAGE("\n"); + } + + /* + * FIXME: The 1 is just here until we implement rpcrt4 + * stub/proxy handling. Until then it helps IShield + * v6 to work. + */ + if (1 || (tattr->wTypeFlags & TYPEFLAG_FOLEAUTOMATION)) + { + if (!(tattr->wTypeFlags & TYPEFLAG_FOLEAUTOMATION)) { + FIXME("Registering non-oleautomation interface!\n"); + } + + /* register interface<->typelib coupling */ + get_interface_key( &tattr->guid, keyName ); + if (RegCreateKeyExW(HKEY_CLASSES_ROOT, keyName, 0, NULL, 0, + KEY_WRITE, NULL, &key, NULL) == ERROR_SUCCESS) + { + if (name) + RegSetValueExW(key, NULL, 0, REG_SZ, + (BYTE *)name, (strlenW(name)+1) * sizeof(OLECHAR)); + + if (RegCreateKeyExW(key, ProxyStubClsidW, 0, NULL, 0, + KEY_WRITE, NULL, &subKey, NULL) == ERROR_SUCCESS) { + RegSetValueExW(subKey, NULL, 0, REG_SZ, + (BYTE*)PSOA, sizeof PSOA); + RegCloseKey(subKey); + } + + if (RegCreateKeyExW(key, ProxyStubClsid32W, 0, NULL, 0, + KEY_WRITE, NULL, &subKey, NULL) == ERROR_SUCCESS) { + RegSetValueExW(subKey, NULL, 0, REG_SZ, + (BYTE*)PSOA, sizeof PSOA); + RegCloseKey(subKey); + } + + if (RegCreateKeyExW(key, TypeLibW, 0, NULL, 0, + KEY_WRITE, NULL, &subKey, NULL) == ERROR_SUCCESS) + { + WCHAR buffer[40]; + static const WCHAR fmtver[] = {'%','u','.','%','u',0 }; + static const WCHAR VersionW[] = {'V','e','r','s','i','o','n',0}; + + StringFromGUID2(&attr->guid, buffer, 40); + RegSetValueExW(subKey, NULL, 0, REG_SZ, + (BYTE *)buffer, (strlenW(buffer)+1) * sizeof(WCHAR)); + sprintfW(buffer, fmtver, attr->wMajorVerNum, attr->wMinorVerNum); + RegSetValueExW(subKey, VersionW, 0, REG_SZ, + (BYTE*)buffer, (strlenW(buffer)+1) * sizeof(WCHAR)); + RegCloseKey(subKey); + } + + RegCloseKey(key); + } + } + + ITypeInfo_ReleaseTypeAttr(tinfo, tattr); + } + + ITypeInfo_Release(tinfo); + } + + SysFreeString(name); + } + } + + ITypeLib_ReleaseTLibAttr(ptlib, attr); + + return res; +} + + +/****************************************************************************** + * UnRegisterTypeLib [OLEAUT32.186] + * Removes information about a type library from the System Registry + * NOTES + * + * RETURNS + * Success: S_OK + * Failure: Status + */ +HRESULT WINAPI UnRegisterTypeLib( + REFGUID libid, /* [in] Guid of the library */ + WORD wVerMajor, /* [in] major version */ + WORD wVerMinor, /* [in] minor version */ + LCID lcid, /* [in] locale id */ + SYSKIND syskind) +{ + BSTR tlibPath = NULL; + DWORD tmpLength; + WCHAR keyName[60]; + WCHAR subKeyName[50]; + int result = S_OK; + DWORD i = 0; + BOOL deleteOtherStuff; + HKEY key = NULL; + HKEY subKey = NULL; + TYPEATTR* typeAttr = NULL; + TYPEKIND kind; + ITypeInfo* typeInfo = NULL; + ITypeLib* typeLib = NULL; + int numTypes; + + TRACE("(IID: %s): stub\n",debugstr_guid(libid)); + + /* Create the path to the key */ + get_typelib_key( libid, wVerMajor, wVerMinor, keyName ); + + if (syskind != SYS_WIN16 && syskind != SYS_WIN32) + { + TRACE("Unsupported syskind %i\n", syskind); + result = E_INVALIDARG; + goto end; + } + + /* get the path to the typelib on disk */ + if (QueryPathOfRegTypeLib(libid, wVerMajor, wVerMinor, lcid, &tlibPath) != S_OK) { + result = E_INVALIDARG; + goto end; + } + + /* Try and open the key to the type library. */ + if (RegOpenKeyExW(HKEY_CLASSES_ROOT, keyName, 0, KEY_READ | KEY_WRITE, &key) != S_OK) { + result = E_INVALIDARG; + goto end; + } + + /* Try and load the type library */ + if (LoadTypeLibEx(tlibPath, REGKIND_NONE, &typeLib)) { + result = TYPE_E_INVALIDSTATE; + goto end; + } + + /* remove any types registered with this typelib */ + numTypes = ITypeLib_GetTypeInfoCount(typeLib); + for (i=0; iguid, subKeyName ); + + /* Delete its bits */ + if (RegOpenKeyExW(HKEY_CLASSES_ROOT, subKeyName, 0, KEY_WRITE, &subKey) != S_OK) { + goto enddeleteloop; + } + RegDeleteKeyW(subKey, ProxyStubClsidW); + RegDeleteKeyW(subKey, ProxyStubClsid32W); + RegDeleteKeyW(subKey, TypeLibW); + RegCloseKey(subKey); + subKey = NULL; + RegDeleteKeyW(HKEY_CLASSES_ROOT, subKeyName); + +enddeleteloop: + if (typeAttr) ITypeInfo_ReleaseTypeAttr(typeInfo, typeAttr); + typeAttr = NULL; + if (typeInfo) ITypeInfo_Release(typeInfo); + typeInfo = NULL; + } + + /* Now, delete the type library path subkey */ + get_lcid_subkey( lcid, syskind, subKeyName ); + RegDeleteKeyW(key, subKeyName); + *strrchrW( subKeyName, '\\' ) = 0; /* remove last path component */ + RegDeleteKeyW(key, subKeyName); + + /* check if there is anything besides the FLAGS/HELPDIR keys. + If there is, we don't delete them */ + tmpLength = sizeof(subKeyName)/sizeof(WCHAR); + deleteOtherStuff = TRUE; + i = 0; + while(RegEnumKeyExW(key, i++, subKeyName, &tmpLength, NULL, NULL, NULL, NULL) == S_OK) { + tmpLength = sizeof(subKeyName)/sizeof(WCHAR); + + /* if its not FLAGS or HELPDIR, then we must keep the rest of the key */ + if (!strcmpW(subKeyName, FLAGSW)) continue; + if (!strcmpW(subKeyName, HELPDIRW)) continue; + deleteOtherStuff = FALSE; + break; + } + + /* only delete the other parts of the key if we're absolutely sure */ + if (deleteOtherStuff) { + RegDeleteKeyW(key, FLAGSW); + RegDeleteKeyW(key, HELPDIRW); + RegCloseKey(key); + key = NULL; + + RegDeleteKeyW(HKEY_CLASSES_ROOT, keyName); + *strrchrW( keyName, '\\' ) = 0; /* remove last path component */ + RegDeleteKeyW(HKEY_CLASSES_ROOT, keyName); + } + +end: + if (tlibPath) SysFreeString(tlibPath); + if (typeLib) ITypeLib_Release(typeLib); + if (subKey) RegCloseKey(subKey); + if (key) RegCloseKey(key); + return result; +} + +/*======================= ITypeLib implementation =======================*/ + +typedef struct tagTLBCustData +{ + GUID guid; + VARIANT data; + struct tagTLBCustData* next; +} TLBCustData; + +/* data structure for import typelibs */ +typedef struct tagTLBImpLib +{ + int offset; /* offset in the file (MSFT) + offset in nametable (SLTG) + just used to identify library while reading + data from file */ + GUID guid; /* libid */ + BSTR name; /* name */ + + LCID lcid; /* lcid of imported typelib */ + + WORD wVersionMajor; /* major version number */ + WORD wVersionMinor; /* minor version number */ + + struct tagITypeLibImpl *pImpTypeLib; /* pointer to loaded typelib, or + NULL if not yet loaded */ + struct tagTLBImpLib * next; +} TLBImpLib; + +/* internal ITypeLib data */ +typedef struct tagITypeLibImpl +{ + ITypeLib2Vtbl *lpVtbl; + ITypeCompVtbl *lpVtblTypeComp; + UINT ref; + TLIBATTR LibAttr; /* guid,lcid,syskind,version,flags */ + + /* strings can be stored in tlb as multibyte strings BUT they are *always* + * exported to the application as a UNICODE string. + */ + BSTR Name; + BSTR DocString; + BSTR HelpFile; + BSTR HelpStringDll; + unsigned long dwHelpContext; + int TypeInfoCount; /* nr of typeinfo's in librarry */ + struct tagITypeInfoImpl *pTypeInfo; /* linked list of type info data */ + int ctCustData; /* number of items in cust data list */ + TLBCustData * pCustData; /* linked list to cust data */ + TLBImpLib * pImpLibs; /* linked list to all imported typelibs */ + TYPEDESC * pTypeDesc; /* array of TypeDescriptions found in the + libary. Only used while read MSFT + typelibs */ + + /* typelibs are cached, keyed by path, so store the linked list info within them */ + struct tagITypeLibImpl *next, *prev; + WCHAR *path; +} ITypeLibImpl; + +static struct ITypeLib2Vtbl tlbvt; +static struct ITypeCompVtbl tlbtcvt; + +#define _ITypeComp_Offset(impl) ((int)(&(((impl*)0)->lpVtblTypeComp))) +#define ICOM_THIS_From_ITypeComp(impl, iface) impl* This = (impl*)(((char*)iface)-_ITypeComp_Offset(impl)) + +/* ITypeLib methods */ +static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength); +static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength); + +/*======================= ITypeInfo implementation =======================*/ + +/* data for refernced types */ +typedef struct tagTLBRefType +{ + INT index; /* Type index for internal ref or for external ref + it the format is SLTG. -2 indicates to + use guid */ + + GUID guid; /* guid of the referenced type */ + /* if index == TLB_REF_USE_GUID */ + + HREFTYPE reference; /* The href of this ref */ + TLBImpLib *pImpTLInfo; /* If ref is external ptr to library data + TLB_REF_INTERNAL for internal refs + TLB_REF_NOT_FOUND for broken refs */ + + struct tagTLBRefType * next; +} TLBRefType; + +#define TLB_REF_USE_GUID -2 + +#define TLB_REF_INTERNAL (void*)-2 +#define TLB_REF_NOT_FOUND (void*)-1 + +/* internal Parameter data */ +typedef struct tagTLBParDesc +{ + BSTR Name; + int ctCustData; + TLBCustData * pCustData; /* linked list to cust data */ +} TLBParDesc; + +/* internal Function data */ +typedef struct tagTLBFuncDesc +{ + FUNCDESC funcdesc; /* lots of info on the function and its attributes. */ + BSTR Name; /* the name of this function */ + TLBParDesc *pParamDesc; /* array with param names and custom data */ + int helpcontext; + int HelpStringContext; + BSTR HelpString; + BSTR Entry; /* if its Hiword==0, it numeric; -1 is not present*/ + int ctCustData; + TLBCustData * pCustData; /* linked list to cust data; */ + struct tagTLBFuncDesc * next; +} TLBFuncDesc; + +/* internal Variable data */ +typedef struct tagTLBVarDesc +{ + VARDESC vardesc; /* lots of info on the variable and its attributes. */ + BSTR Name; /* the name of this variable */ + int HelpContext; + int HelpStringContext; /* FIXME: where? */ + BSTR HelpString; + int ctCustData; + TLBCustData * pCustData;/* linked list to cust data; */ + struct tagTLBVarDesc * next; +} TLBVarDesc; + +/* internal implemented interface data */ +typedef struct tagTLBImplType +{ + HREFTYPE hRef; /* hRef of interface */ + int implflags; /* IMPLFLAG_*s */ + int ctCustData; + TLBCustData * pCustData;/* linked list to custom data; */ + struct tagTLBImplType *next; +} TLBImplType; + +/* internal TypeInfo data */ +typedef struct tagITypeInfoImpl +{ + ITypeInfo2Vtbl *lpVtbl; + ITypeCompVtbl *lpVtblTypeComp; + UINT ref; + TYPEATTR TypeAttr ; /* _lots_ of type information. */ + ITypeLibImpl * pTypeLib; /* back pointer to typelib */ + int index; /* index in this typelib; */ + /* type libs seem to store the doc strings in ascii + * so why should we do it in unicode? + */ + BSTR Name; + BSTR DocString; + unsigned long dwHelpContext; + unsigned long dwHelpStringContext; + + /* functions */ + TLBFuncDesc * funclist; /* linked list with function descriptions */ + + /* variables */ + TLBVarDesc * varlist; /* linked list with variable descriptions */ + + /* Implemented Interfaces */ + TLBImplType * impltypelist; + + TLBRefType * reflist; + int ctCustData; + TLBCustData * pCustData; /* linked list to cust data; */ + struct tagITypeInfoImpl * next; +} ITypeInfoImpl; + +static struct ITypeInfo2Vtbl tinfvt; +static struct ITypeCompVtbl tcompvt; + +static ITypeInfo2 * WINAPI ITypeInfo_Constructor(); + +typedef struct tagTLBContext +{ + unsigned int oStart; /* start of TLB in file */ + unsigned int pos; /* current pos */ + unsigned int length; /* total length */ + void *mapping; /* memory mapping */ + MSFT_SegDir * pTblDir; + ITypeLibImpl* pLibInfo; +} TLBContext; + + +static void MSFT_DoRefType(TLBContext *pcx, ITypeInfoImpl *pTI, int offset); + +/* + debug +*/ +static void dump_TypeDesc(TYPEDESC *pTD,char *szVarType) { + if (pTD->vt & VT_RESERVED) + szVarType += strlen(strcpy(szVarType, "reserved | ")); + if (pTD->vt & VT_BYREF) + szVarType += strlen(strcpy(szVarType, "ref to ")); + if (pTD->vt & VT_ARRAY) + szVarType += strlen(strcpy(szVarType, "array of ")); + if (pTD->vt & VT_VECTOR) + szVarType += strlen(strcpy(szVarType, "vector of ")); + switch(pTD->vt & VT_TYPEMASK) { + case VT_UI1: sprintf(szVarType, "VT_UI1"); break; + case VT_I2: sprintf(szVarType, "VT_I2"); break; + case VT_I4: sprintf(szVarType, "VT_I4"); break; + case VT_R4: sprintf(szVarType, "VT_R4"); break; + case VT_R8: sprintf(szVarType, "VT_R8"); break; + case VT_BOOL: sprintf(szVarType, "VT_BOOL"); break; + case VT_ERROR: sprintf(szVarType, "VT_ERROR"); break; + case VT_CY: sprintf(szVarType, "VT_CY"); break; + case VT_DATE: sprintf(szVarType, "VT_DATE"); break; + case VT_BSTR: sprintf(szVarType, "VT_BSTR"); break; + case VT_UNKNOWN: sprintf(szVarType, "VT_UNKNOWN"); break; + case VT_DISPATCH: sprintf(szVarType, "VT_DISPATCH"); break; + case VT_I1: sprintf(szVarType, "VT_I1"); break; + case VT_UI2: sprintf(szVarType, "VT_UI2"); break; + case VT_UI4: sprintf(szVarType, "VT_UI4"); break; + case VT_INT: sprintf(szVarType, "VT_INT"); break; + case VT_UINT: sprintf(szVarType, "VT_UINT"); break; + case VT_VARIANT: sprintf(szVarType, "VT_VARIANT"); break; + case VT_VOID: sprintf(szVarType, "VT_VOID"); break; + case VT_HRESULT: sprintf(szVarType, "VT_HRESULT"); break; + case VT_USERDEFINED: sprintf(szVarType, "VT_USERDEFINED ref = %lx", + pTD->u.hreftype); break; + case VT_PTR: sprintf(szVarType, "ptr to "); + dump_TypeDesc(pTD->u.lptdesc, szVarType + 7); + break; + case VT_SAFEARRAY: sprintf(szVarType, "safearray of "); + dump_TypeDesc(pTD->u.lptdesc, szVarType + 13); + break; + case VT_CARRAY: sprintf(szVarType, "%d dim array of ", + pTD->u.lpadesc->cDims); /* FIXME print out sizes */ + dump_TypeDesc(&pTD->u.lpadesc->tdescElem, szVarType + strlen(szVarType)); + break; + + default: sprintf(szVarType, "unknown(%d)", pTD->vt & VT_TYPEMASK); break; + } +} + +void dump_ELEMDESC(ELEMDESC *edesc) { + char buf[200]; + dump_TypeDesc(&edesc->tdesc,buf); + MESSAGE("\t\ttdesc.vartype %d (%s)\n",edesc->tdesc.vt,buf); + MESSAGE("\t\tu.parmadesc.flags %x\n",edesc->u.paramdesc.wParamFlags); + MESSAGE("\t\tu.parmadesc.lpex %p\n",edesc->u.paramdesc.pparamdescex); +} +void dump_FUNCDESC(FUNCDESC *funcdesc) { + int i; + MESSAGE("memid is %08lx\n",funcdesc->memid); + for (i=0;icParams;i++) { + MESSAGE("Param %d:\n",i); + dump_ELEMDESC(funcdesc->lprgelemdescParam+i); + } + MESSAGE("\tfunckind: %d (",funcdesc->funckind); + switch (funcdesc->funckind) { + case FUNC_VIRTUAL: MESSAGE("virtual");break; + case FUNC_PUREVIRTUAL: MESSAGE("pure virtual");break; + case FUNC_NONVIRTUAL: MESSAGE("nonvirtual");break; + case FUNC_STATIC: MESSAGE("static");break; + case FUNC_DISPATCH: MESSAGE("dispatch");break; + default: MESSAGE("unknown");break; + } + MESSAGE(")\n\tinvkind: %d (",funcdesc->invkind); + switch (funcdesc->invkind) { + case INVOKE_FUNC: MESSAGE("func");break; + case INVOKE_PROPERTYGET: MESSAGE("property get");break; + case INVOKE_PROPERTYPUT: MESSAGE("property put");break; + case INVOKE_PROPERTYPUTREF: MESSAGE("property put ref");break; + } + MESSAGE(")\n\tcallconv: %d (",funcdesc->callconv); + switch (funcdesc->callconv) { + case CC_CDECL: MESSAGE("cdecl");break; + case CC_PASCAL: MESSAGE("pascal");break; + case CC_STDCALL: MESSAGE("stdcall");break; + case CC_SYSCALL: MESSAGE("syscall");break; + default:break; + } + MESSAGE(")\n\toVft: %d\n", funcdesc->oVft); + MESSAGE("\tcParamsOpt: %d\n", funcdesc->cParamsOpt); + MESSAGE("\twFlags: %x\n", funcdesc->wFuncFlags); + + MESSAGE("\telemdescFunc (return value type):\n"); + dump_ELEMDESC(&funcdesc->elemdescFunc); +} + +void dump_IDLDESC(IDLDESC *idl) { + MESSAGE("\t\twIdlflags: %d\n",idl->wIDLFlags); +} + +static const char * typekind_desc[] = +{ + "TKIND_ENUM", + "TKIND_RECORD", + "TKIND_MODULE", + "TKIND_INTERFACE", + "TKIND_DISPATCH", + "TKIND_COCLASS", + "TKIND_ALIAS", + "TKIND_UNION", + "TKIND_MAX" +}; + +void dump_TYPEATTR(TYPEATTR *tattr) { + char buf[200]; + MESSAGE("\tguid: %s\n",debugstr_guid(&tattr->guid)); + MESSAGE("\tlcid: %ld\n",tattr->lcid); + MESSAGE("\tmemidConstructor: %ld\n",tattr->memidConstructor); + MESSAGE("\tmemidDestructor: %ld\n",tattr->memidDestructor); + MESSAGE("\tschema: %s\n",debugstr_w(tattr->lpstrSchema)); + MESSAGE("\tsizeInstance: %ld\n",tattr->cbSizeInstance); + MESSAGE("\tkind:%s\n", typekind_desc[tattr->typekind]); + MESSAGE("\tcFuncs: %d\n", tattr->cFuncs); + MESSAGE("\tcVars: %d\n", tattr->cVars); + MESSAGE("\tcImplTypes: %d\n", tattr->cImplTypes); + MESSAGE("\tcbSizeVft: %d\n", tattr->cbSizeVft); + MESSAGE("\tcbAlignment: %d\n", tattr->cbAlignment); + MESSAGE("\twTypeFlags: %d\n", tattr->wTypeFlags); + MESSAGE("\tVernum: %d.%d\n", tattr->wMajorVerNum,tattr->wMinorVerNum); + dump_TypeDesc(&tattr->tdescAlias,buf); + MESSAGE("\ttypedesc: %s\n", buf); + dump_IDLDESC(&tattr->idldescType); +} + +static void dump_TLBFuncDescOne(TLBFuncDesc * pfd) +{ + int i; + if (!TRACE_ON(typelib)) + return; + MESSAGE("%s(%u)\n", debugstr_w(pfd->Name), pfd->funcdesc.cParams); + for (i=0;ifuncdesc.cParams;i++) + MESSAGE("\tparm%d: %s\n",i,debugstr_w(pfd->pParamDesc[i].Name)); + + + dump_FUNCDESC(&(pfd->funcdesc)); + + MESSAGE("\thelpstring: %s\n", debugstr_w(pfd->HelpString)); + MESSAGE("\tentry: %s\n", debugstr_w(pfd->Entry)); +} +static void dump_TLBFuncDesc(TLBFuncDesc * pfd) +{ + while (pfd) + { + dump_TLBFuncDescOne(pfd); + pfd = pfd->next; + }; +} +static void dump_TLBVarDesc(TLBVarDesc * pvd) +{ + while (pvd) + { + TRACE_(typelib)("%s\n", debugstr_w(pvd->Name)); + pvd = pvd->next; + }; +} + +static void dump_TLBImpLib(TLBImpLib *import) +{ + TRACE_(typelib)("%s %s\n", debugstr_guid(&(import->guid)), + debugstr_w(import->name)); + TRACE_(typelib)("v%d.%d lcid=%lx offset=%x\n", import->wVersionMajor, + import->wVersionMinor, import->lcid, import->offset); +} + +static void dump_TLBRefType(TLBRefType * prt) +{ + while (prt) + { + TRACE_(typelib)("href:0x%08lx\n", prt->reference); + if(prt->index == -1) + TRACE_(typelib)("%s\n", debugstr_guid(&(prt->guid))); + else + TRACE_(typelib)("type no: %d\n", prt->index); + + if(prt->pImpTLInfo != TLB_REF_INTERNAL && + prt->pImpTLInfo != TLB_REF_NOT_FOUND) { + TRACE_(typelib)("in lib\n"); + dump_TLBImpLib(prt->pImpTLInfo); + } + prt = prt->next; + }; +} + +static void dump_TLBImplType(TLBImplType * impl) +{ + while (impl) { + TRACE_(typelib)( + "implementing/inheriting interface hRef = %lx implflags %x\n", + impl->hRef, impl->implflags); + impl = impl->next; + } +} + +void dump_Variant(VARIANT * pvar) +{ + SYSTEMTIME st; + + TRACE("%p->{%s%s", pvar, debugstr_VT(pvar), debugstr_VF(pvar)); + + if (pvar) + { + if (V_ISBYREF(pvar) || V_TYPE(pvar) == VT_UNKNOWN || + V_TYPE(pvar) == VT_DISPATCH || V_TYPE(pvar) == VT_RECORD) + { + TRACE(",%p", V_BYREF(pvar)); + } + else if (V_ISARRAY(pvar) || V_ISVECTOR(pvar)) + { + TRACE(",FIXME"); + } + else switch (V_TYPE(pvar)) + { + case VT_I1: TRACE(",%d", V_I1(pvar)); break; + case VT_UI1: TRACE(",%d", V_UI1(pvar)); break; + case VT_I2: TRACE(",%d", V_I2(pvar)); break; + case VT_UI2: TRACE(",%d", V_UI2(pvar)); break; + case VT_INT: + case VT_I4: TRACE(",%ld", V_I4(pvar)); break; + case VT_UINT: + case VT_UI4: TRACE(",%ld", V_UI4(pvar)); break; + case VT_I8: TRACE(",0x%08lx,0x%08lx", (ULONG)(V_I8(pvar) >> 32), + (ULONG)(V_I8(pvar) & 0xffffffff)); break; + case VT_UI8: TRACE(",0x%08lx,0x%08lx", (ULONG)(V_UI8(pvar) >> 32), + (ULONG)(V_UI8(pvar) & 0xffffffff)); break; + case VT_R4: TRACE(",%3.3e", V_R4(pvar)); break; + case VT_R8: TRACE(",%3.3e", V_R8(pvar)); break; + case VT_BOOL: TRACE(",%s", V_BOOL(pvar) ? "TRUE" : "FALSE"); break; + case VT_BSTR: TRACE(",%s", debugstr_w(V_BSTR(pvar))); break; + case VT_CY: TRACE(",0x%08lx,0x%08lx", V_CY(pvar).s.Hi, + V_CY(pvar).s.Lo); break; + case VT_DATE: + if(!VariantTimeToSystemTime(V_DATE(pvar), &st)) + TRACE(","); + else + TRACE(",%04d/%02d/%02d %02d:%02d:%02d", st.wYear, st.wMonth, st.wDay, + st.wHour, st.wMinute, st.wSecond); + break; + case VT_ERROR: + case VT_VOID: + case VT_USERDEFINED: + case VT_EMPTY: + case VT_NULL: break; + default: TRACE(",?"); break; + } + } + TRACE("}\n"); +} + +static void dump_DispParms(DISPPARAMS * pdp) +{ + int index = 0; + + TRACE("args=%u named args=%u\n", pdp->cArgs, pdp->cNamedArgs); + + while (index < pdp->cArgs) + { + dump_Variant( &pdp->rgvarg[index] ); + ++index; + } +} + +static void dump_TypeInfo(ITypeInfoImpl * pty) +{ + TRACE("%p ref=%u\n", pty, pty->ref); + TRACE("attr:%s\n", debugstr_guid(&(pty->TypeAttr.guid))); + TRACE("kind:%s\n", typekind_desc[pty->TypeAttr.typekind]); + TRACE("fct:%u var:%u impl:%u\n", + pty->TypeAttr.cFuncs, pty->TypeAttr.cVars, pty->TypeAttr.cImplTypes); + TRACE("parent tlb:%p index in TLB:%u\n",pty->pTypeLib, pty->index); + TRACE("%s %s\n", debugstr_w(pty->Name), debugstr_w(pty->DocString)); + dump_TLBFuncDesc(pty->funclist); + dump_TLBVarDesc(pty->varlist); + dump_TLBImplType(pty->impltypelist); +} + +void dump_VARDESC(VARDESC *v) +{ + MESSAGE("memid %ld\n",v->memid); + MESSAGE("lpstrSchema %s\n",debugstr_w(v->lpstrSchema)); + MESSAGE("oInst %ld\n",v->u.oInst); + dump_ELEMDESC(&(v->elemdescVar)); + MESSAGE("wVarFlags %x\n",v->wVarFlags); + MESSAGE("varkind %d\n",v->varkind); +} + +static TYPEDESC stndTypeDesc[VT_LPWSTR+1]= +{ + /* VT_LPWSTR is largest type that */ + /* may appear in type description*/ + {{0}, 0},{{0}, 1},{{0}, 2},{{0}, 3},{{0}, 4}, + {{0}, 5},{{0}, 6},{{0}, 7},{{0}, 8},{{0}, 9}, + {{0},10},{{0},11},{{0},12},{{0},13},{{0},14}, + {{0},15},{{0},16},{{0},17},{{0},18},{{0},19}, + {{0},20},{{0},21},{{0},22},{{0},23},{{0},24}, + {{0},25},{{0},26},{{0},27},{{0},28},{{0},29}, + {{0},30},{{0},31} +}; + +static void TLB_abort() +{ + DebugBreak(); +} +static void * TLB_Alloc(unsigned size) +{ + void * ret; + if((ret=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,size))==NULL){ + /* FIXME */ + ERR("cannot allocate memory\n"); + } + return ret; +} + +static void TLB_Free(void * ptr) +{ + HeapFree(GetProcessHeap(), 0, ptr); +} + + +/********************************************************************** + * + * Functions for reading MSFT typelibs (those created by CreateTypeLib2) + */ +/* read function */ +DWORD MSFT_Read(void *buffer, DWORD count, TLBContext *pcx, long where ) +{ + TRACE_(typelib)("pos=0x%08x len=0x%08lx 0x%08x 0x%08x 0x%08lx\n", + pcx->pos, count, pcx->oStart, pcx->length, where); + + if (where != DO_NOT_SEEK) + { + where += pcx->oStart; + if (where > pcx->length) + { + /* FIXME */ + ERR("seek beyond end (%ld/%d)\n", where, pcx->length ); + TLB_abort(); + } + pcx->pos = where; + } + if (pcx->pos + count > pcx->length) count = pcx->length - pcx->pos; + memcpy( buffer, (char *)pcx->mapping + pcx->pos, count ); + pcx->pos += count; + return count; +} + +static DWORD MSFT_ReadLEDWords(void *buffer, DWORD count, TLBContext *pcx, + long where ) +{ + DWORD ret; + + ret = MSFT_Read(buffer, count, pcx, where); + FromLEDWords(buffer, ret); + + return ret; +} + +static DWORD MSFT_ReadLEWords(void *buffer, DWORD count, TLBContext *pcx, + long where ) +{ + DWORD ret; + + ret = MSFT_Read(buffer, count, pcx, where); + FromLEWords(buffer, ret); + + return ret; +} + +static void MSFT_ReadGuid( GUID *pGuid, int offset, TLBContext *pcx) +{ + if(offset<0 || pcx->pTblDir->pGuidTab.offset <0){ + memset(pGuid,0, sizeof(GUID)); + return; + } + MSFT_Read(pGuid, sizeof(GUID), pcx, pcx->pTblDir->pGuidTab.offset+offset ); + pGuid->Data1 = FromLEDWord(pGuid->Data1); + pGuid->Data2 = FromLEWord(pGuid->Data2); + pGuid->Data3 = FromLEWord(pGuid->Data3); + TRACE_(typelib)("%s\n", debugstr_guid(pGuid)); +} + +BSTR MSFT_ReadName( TLBContext *pcx, int offset) +{ + char * name; + MSFT_NameIntro niName; + int lengthInChars; + WCHAR* pwstring = NULL; + BSTR bstrName = NULL; + + MSFT_ReadLEDWords(&niName, sizeof(niName), pcx, + pcx->pTblDir->pNametab.offset+offset); + niName.namelen &= 0xFF; /* FIXME: correct ? */ + name=TLB_Alloc((niName.namelen & 0xff) +1); + MSFT_Read(name, (niName.namelen & 0xff), pcx, DO_NOT_SEEK); + name[niName.namelen & 0xff]='\0'; + + lengthInChars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED | MB_ERR_INVALID_CHARS, + name, -1, NULL, 0); + + /* no invalid characters in string */ + if (lengthInChars) + { + pwstring = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*lengthInChars); + + /* don't check for invalid character since this has been done previously */ + MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, name, -1, pwstring, lengthInChars); + + bstrName = SysAllocStringLen(pwstring, lengthInChars); + lengthInChars = SysStringLen(bstrName); + HeapFree(GetProcessHeap(), 0, pwstring); + } + + TRACE_(typelib)("%s %d\n", debugstr_w(bstrName), lengthInChars); + return bstrName; +} + +BSTR MSFT_ReadString( TLBContext *pcx, int offset) +{ + char * string; + INT16 length; + int lengthInChars; + BSTR bstr = NULL; + + if(offset<0) return NULL; + MSFT_ReadLEWords(&length, sizeof(INT16), pcx, pcx->pTblDir->pStringtab.offset+offset); + if(length <= 0) return 0; + string=TLB_Alloc(length +1); + MSFT_Read(string, length, pcx, DO_NOT_SEEK); + string[length]='\0'; + + lengthInChars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED | MB_ERR_INVALID_CHARS, + string, -1, NULL, 0); + + /* no invalid characters in string */ + if (lengthInChars) + { + WCHAR* pwstring = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*lengthInChars); + + /* don't check for invalid character since this has been done previously */ + MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, string, -1, pwstring, lengthInChars); + + bstr = SysAllocStringLen(pwstring, lengthInChars); + lengthInChars = SysStringLen(bstr); + HeapFree(GetProcessHeap(), 0, pwstring); + } + + TRACE_(typelib)("%s %d\n", debugstr_w(bstr), lengthInChars); + return bstr; +} +/* + * read a value and fill a VARIANT structure + */ +static void MSFT_ReadValue( VARIANT * pVar, int offset, TLBContext *pcx ) +{ + int size; + + TRACE_(typelib)("\n"); + + if(offset <0) { /* data are packed in here */ + V_VT(pVar) = (offset & 0x7c000000 )>> 26; + V_UNION(pVar, iVal) = offset & 0xffff; + return; + } + MSFT_ReadLEWords(&(V_VT(pVar)), sizeof(VARTYPE), pcx, + pcx->pTblDir->pCustData.offset + offset ); + TRACE_(typelib)("Vartype = %x\n", V_VT(pVar)); + switch (V_VT(pVar)){ + case VT_EMPTY: /* FIXME: is this right? */ + case VT_NULL: /* FIXME: is this right? */ + case VT_I2 : /* this should not happen */ + case VT_I4 : + case VT_R4 : + case VT_ERROR : + case VT_BOOL : + case VT_I1 : + case VT_UI1 : + case VT_UI2 : + case VT_UI4 : + case VT_INT : + case VT_UINT : + case VT_VOID : /* FIXME: is this right? */ + case VT_HRESULT : + size=4; break; + case VT_R8 : + case VT_CY : + case VT_DATE : + case VT_I8 : + case VT_UI8 : + case VT_DECIMAL : /* FIXME: is this right? */ + case VT_FILETIME : + size=8;break; + /* pointer types with known behaviour */ + case VT_BSTR :{ + char * ptr; + MSFT_ReadLEDWords(&size, sizeof(INT), pcx, DO_NOT_SEEK ); + if(size < 0) { + FIXME("BSTR length = %d?\n", size); + } else { + ptr=TLB_Alloc(size);/* allocate temp buffer */ + MSFT_Read(ptr, size, pcx, DO_NOT_SEEK);/* read string (ANSI) */ + V_UNION(pVar, bstrVal)=SysAllocStringLen(NULL,size); + /* FIXME: do we need a AtoW conversion here? */ + V_UNION(pVar, bstrVal[size])=L'\0'; + while(size--) V_UNION(pVar, bstrVal[size])=ptr[size]; + TLB_Free(ptr); + } + } + size=-4; break; + /* FIXME: this will not work AT ALL when the variant contains a pointer */ + case VT_DISPATCH : + case VT_VARIANT : + case VT_UNKNOWN : + case VT_PTR : + case VT_SAFEARRAY : + case VT_CARRAY : + case VT_USERDEFINED : + case VT_LPSTR : + case VT_LPWSTR : + case VT_BLOB : + case VT_STREAM : + case VT_STORAGE : + case VT_STREAMED_OBJECT : + case VT_STORED_OBJECT : + case VT_BLOB_OBJECT : + case VT_CF : + case VT_CLSID : + default: + size=0; + FIXME("VARTYPE %d is not supported, setting pointer to NULL\n", + V_VT(pVar)); + } + + if(size>0) /* (big|small) endian correct? */ + MSFT_Read(&(V_UNION(pVar, iVal)), size, pcx, DO_NOT_SEEK ); + return; +} +/* + * create a linked list with custom data + */ +static int MSFT_CustData( TLBContext *pcx, int offset, TLBCustData** ppCustData ) +{ + MSFT_CDGuid entry; + TLBCustData* pNew; + int count=0; + + TRACE_(typelib)("\n"); + + while(offset >=0){ + count++; + pNew=TLB_Alloc(sizeof(TLBCustData)); + MSFT_ReadLEDWords(&entry, sizeof(entry), pcx, pcx->pTblDir->pCDGuids.offset+offset); + MSFT_ReadGuid(&(pNew->guid), entry.GuidOffset , pcx); + MSFT_ReadValue(&(pNew->data), entry.DataOffset, pcx); + /* add new custom data at head of the list */ + pNew->next=*ppCustData; + *ppCustData=pNew; + offset = entry.next; + } + return count; +} + +static void MSFT_GetTdesc(TLBContext *pcx, INT type, TYPEDESC *pTd, + ITypeInfoImpl *pTI) +{ + if(type <0) + pTd->vt=type & VT_TYPEMASK; + else + *pTd=pcx->pLibInfo->pTypeDesc[type/(2*sizeof(INT))]; + + if(pTd->vt == VT_USERDEFINED) + MSFT_DoRefType(pcx, pTI, pTd->u.hreftype); + + TRACE_(typelib)("vt type = %X\n", pTd->vt); +} + +static void +MSFT_DoFuncs(TLBContext* pcx, + ITypeInfoImpl* pTI, + int cFuncs, + int cVars, + int offset, + TLBFuncDesc** pptfd) +{ + /* + * member information is stored in a data structure at offset + * indicated by the memoffset field of the typeinfo structure + * There are several distinctive parts. + * the first part starts with a field that holds the total length + * of this (first) part excluding this field. Then follow the records, + * for each member there is one record. + * + * First entry is always the length of the record (excluding this + * length word). + * Rest of the record depends on the type of the member. If there is + * a field indicating the member type (function variable intereface etc) + * I have not found it yet. At this time we depend on the information + * in the type info and the usual order how things are stored. + * + * Second follows an array sized nrMEM*sizeof(INT) with a memeber id + * for each member; + * + * Third is a equal sized array with file offsets to the name entry + * of each member. + * + * Forth and last (?) part is an array with offsets to the records in the + * first part of this file segment. + */ + + int infolen, nameoffset, reclength, nrattributes, i; + int recoffset = offset + sizeof(INT); + + char recbuf[512]; + MSFT_FuncRecord * pFuncRec=(MSFT_FuncRecord *) recbuf; + + TRACE_(typelib)("\n"); + + MSFT_ReadLEDWords(&infolen, sizeof(INT), pcx, offset); + + for ( i = 0; i < cFuncs ; i++ ) + { + *pptfd = TLB_Alloc(sizeof(TLBFuncDesc)); + + /* name, eventually add to a hash table */ + MSFT_ReadLEDWords(&nameoffset, sizeof(INT), pcx, + offset + infolen + (cFuncs + cVars + i + 1) * sizeof(INT)); + + (*pptfd)->Name = MSFT_ReadName(pcx, nameoffset); + + /* read the function information record */ + MSFT_ReadLEDWords(&reclength, sizeof(INT), pcx, recoffset); + + reclength &= 0x1ff; + + MSFT_ReadLEDWords(pFuncRec, reclength - sizeof(INT), pcx, DO_NOT_SEEK); + + /* do the attributes */ + nrattributes = (reclength - pFuncRec->nrargs * 3 * sizeof(int) - 0x18) + / sizeof(int); + + if ( nrattributes > 0 ) + { + (*pptfd)->helpcontext = pFuncRec->OptAttr[0] ; + + if ( nrattributes > 1 ) + { + (*pptfd)->HelpString = MSFT_ReadString(pcx, + pFuncRec->OptAttr[1]) ; + + if ( nrattributes > 2 ) + { + if ( pFuncRec->FKCCIC & 0x2000 ) + { + (*pptfd)->Entry = (WCHAR*) pFuncRec->OptAttr[2] ; + } + else + { + (*pptfd)->Entry = MSFT_ReadString(pcx, + pFuncRec->OptAttr[2]); + } + if( nrattributes > 5 ) + { + (*pptfd)->HelpStringContext = pFuncRec->OptAttr[5] ; + + if ( nrattributes > 6 && pFuncRec->FKCCIC & 0x80 ) + { + MSFT_CustData(pcx, + pFuncRec->OptAttr[6], + &(*pptfd)->pCustData); + } + } + } + } + } + + /* fill the FuncDesc Structure */ + MSFT_ReadLEDWords( & (*pptfd)->funcdesc.memid, sizeof(INT), pcx, + offset + infolen + ( i + 1) * sizeof(INT)); + + (*pptfd)->funcdesc.funckind = (pFuncRec->FKCCIC) & 0x7; + (*pptfd)->funcdesc.invkind = (pFuncRec->FKCCIC) >> 3 & 0xF; + (*pptfd)->funcdesc.callconv = (pFuncRec->FKCCIC) >> 8 & 0xF; + (*pptfd)->funcdesc.cParams = pFuncRec->nrargs ; + (*pptfd)->funcdesc.cParamsOpt = pFuncRec->nroargs ; + (*pptfd)->funcdesc.oVft = pFuncRec->VtableOffset ; + (*pptfd)->funcdesc.wFuncFlags = LOWORD(pFuncRec->Flags) ; + + MSFT_GetTdesc(pcx, + pFuncRec->DataType, + &(*pptfd)->funcdesc.elemdescFunc.tdesc, + pTI); + + /* do the parameters/arguments */ + if(pFuncRec->nrargs) + { + int j = 0; + MSFT_ParameterInfo paraminfo; + + (*pptfd)->funcdesc.lprgelemdescParam = + TLB_Alloc(pFuncRec->nrargs * sizeof(ELEMDESC)); + + (*pptfd)->pParamDesc = + TLB_Alloc(pFuncRec->nrargs * sizeof(TLBParDesc)); + + MSFT_ReadLEDWords(¶minfo, sizeof(paraminfo), pcx, + recoffset + reclength - pFuncRec->nrargs * sizeof(MSFT_ParameterInfo)); + + for ( j = 0 ; j < pFuncRec->nrargs ; j++ ) + { + TYPEDESC* lpArgTypeDesc = 0; + + MSFT_GetTdesc(pcx, + paraminfo.DataType, + &(*pptfd)->funcdesc.lprgelemdescParam[j].tdesc, + pTI); + + (*pptfd)->funcdesc.lprgelemdescParam[j].u.paramdesc.wParamFlags = paraminfo.Flags; + + (*pptfd)->pParamDesc[j].Name = (void *) paraminfo.oName; + + /* SEEK value = jump to offset, + * from there jump to the end of record, + * go back by (j-1) arguments + */ + MSFT_ReadLEDWords( ¶minfo , + sizeof(MSFT_ParameterInfo), pcx, + recoffset + reclength - ((pFuncRec->nrargs - j - 1) + * sizeof(MSFT_ParameterInfo))); + lpArgTypeDesc = + & ((*pptfd)->funcdesc.lprgelemdescParam[j].tdesc); + + while ( lpArgTypeDesc != NULL ) + { + switch ( lpArgTypeDesc->vt ) + { + case VT_PTR: + lpArgTypeDesc = lpArgTypeDesc->u.lptdesc; + break; + + case VT_CARRAY: + lpArgTypeDesc = & (lpArgTypeDesc->u.lpadesc->tdescElem); + break; + + case VT_USERDEFINED: + MSFT_DoRefType(pcx, pTI, + lpArgTypeDesc->u.hreftype); + + lpArgTypeDesc = NULL; + break; + + default: + lpArgTypeDesc = NULL; + } + } + } + + + /* parameter is the return value! */ + if ( paraminfo.Flags & PARAMFLAG_FRETVAL ) + { + TYPEDESC* lpArgTypeDesc; + + (*pptfd)->funcdesc.elemdescFunc = + (*pptfd)->funcdesc.lprgelemdescParam[j]; + + lpArgTypeDesc = & ((*pptfd)->funcdesc.elemdescFunc.tdesc) ; + + while ( lpArgTypeDesc != NULL ) + { + switch ( lpArgTypeDesc->vt ) + { + case VT_PTR: + lpArgTypeDesc = lpArgTypeDesc->u.lptdesc; + break; + case VT_CARRAY: + lpArgTypeDesc = + & (lpArgTypeDesc->u.lpadesc->tdescElem); + + break; + + case VT_USERDEFINED: + MSFT_DoRefType(pcx, + pTI, + lpArgTypeDesc->u.hreftype); + + lpArgTypeDesc = NULL; + break; + + default: + lpArgTypeDesc = NULL; + } + } + } + + /* second time around */ + for(j=0;jnrargs;j++) + { + /* name */ + (*pptfd)->pParamDesc[j].Name = + MSFT_ReadName( pcx, (int)(*pptfd)->pParamDesc[j].Name ); + + /* default value */ + if ( (PARAMFLAG_FHASDEFAULT & + (*pptfd)->funcdesc.lprgelemdescParam[j].u.paramdesc.wParamFlags) && + ((pFuncRec->FKCCIC) & 0x1000) ) + { + INT* pInt = (INT *)((char *)pFuncRec + + reclength - + (pFuncRec->nrargs * 4 + 1) * sizeof(INT) ); + + PARAMDESC* pParamDesc = & (*pptfd)->funcdesc.lprgelemdescParam[j].u.paramdesc; + + pParamDesc->pparamdescex = TLB_Alloc(sizeof(PARAMDESCEX)); + pParamDesc->pparamdescex->cBytes = sizeof(PARAMDESCEX); + + MSFT_ReadValue(&(pParamDesc->pparamdescex->varDefaultValue), + pInt[j], pcx); + } + /* custom info */ + if ( nrattributes > 7 + j && pFuncRec->FKCCIC & 0x80 ) + { + MSFT_CustData(pcx, + pFuncRec->OptAttr[7+j], + &(*pptfd)->pParamDesc[j].pCustData); + } + } + } + + /* scode is not used: archaic win16 stuff FIXME: right? */ + (*pptfd)->funcdesc.cScodes = 0 ; + (*pptfd)->funcdesc.lprgscode = NULL ; + + pptfd = & ((*pptfd)->next); + recoffset += reclength; + } +} + +static void MSFT_DoVars(TLBContext *pcx, ITypeInfoImpl *pTI, int cFuncs, + int cVars, int offset, TLBVarDesc ** pptvd) +{ + int infolen, nameoffset, reclength; + char recbuf[256]; + MSFT_VarRecord * pVarRec=(MSFT_VarRecord *) recbuf; + int i; + int recoffset; + + TRACE_(typelib)("\n"); + + MSFT_ReadLEDWords(&infolen,sizeof(INT), pcx, offset); + MSFT_ReadLEDWords(&recoffset,sizeof(INT), pcx, offset + infolen + + ((cFuncs+cVars)*2+cFuncs + 1)*sizeof(INT)); + recoffset += offset+sizeof(INT); + for(i=0;iName=MSFT_ReadName(pcx, nameoffset); + /* read the variable information record */ + MSFT_ReadLEDWords(&reclength, sizeof(INT), pcx, recoffset); + reclength &=0xff; + MSFT_ReadLEDWords(pVarRec, reclength - sizeof(INT), pcx, DO_NOT_SEEK); + /* Optional data */ + if(reclength >(6*sizeof(INT)) ) + (*pptvd)->HelpContext=pVarRec->HelpContext; + if(reclength >(7*sizeof(INT)) ) + (*pptvd)->HelpString = MSFT_ReadString(pcx, pVarRec->oHelpString) ; + if(reclength >(8*sizeof(INT)) ) + if(reclength >(9*sizeof(INT)) ) + (*pptvd)->HelpStringContext=pVarRec->HelpStringContext; + /* fill the VarDesc Structure */ + MSFT_ReadLEDWords(&(*pptvd)->vardesc.memid, sizeof(INT), pcx, + offset + infolen + ( i + 1) * sizeof(INT)); + (*pptvd)->vardesc.varkind = pVarRec->VarKind; + (*pptvd)->vardesc.wVarFlags = pVarRec->Flags; + MSFT_GetTdesc(pcx, pVarRec->DataType, + &(*pptvd)->vardesc.elemdescVar.tdesc, pTI); +/* (*pptvd)->vardesc.lpstrSchema; is reserved (SDK) FIXME?? */ + if(pVarRec->VarKind == VAR_CONST ){ + (*pptvd)->vardesc.u.lpvarValue=TLB_Alloc(sizeof(VARIANT)); + MSFT_ReadValue((*pptvd)->vardesc.u.lpvarValue, + pVarRec->OffsValue, pcx); + } else + (*pptvd)->vardesc.u.oInst=pVarRec->OffsValue; + pptvd=&((*pptvd)->next); + recoffset += reclength; + } +} +/* fill in data for a hreftype (offset). When the refernced type is contained + * in the typelib, it's just an (file) offset in the type info base dir. + * If comes from import, it's an offset+1 in the ImpInfo table + * */ +static void MSFT_DoRefType(TLBContext *pcx, ITypeInfoImpl *pTI, + int offset) +{ + int j; + TLBRefType **ppRefType = &pTI->reflist; + + TRACE_(typelib)("TLB context %p, TLB offset %x\n", pcx, offset); + + while(*ppRefType) { + if((*ppRefType)->reference == offset) + return; + ppRefType = &(*ppRefType)->next; + } + + *ppRefType = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + sizeof(**ppRefType)); + + if(!MSFT_HREFTYPE_INTHISFILE( offset)) { + /* external typelib */ + MSFT_ImpInfo impinfo; + TLBImpLib *pImpLib=(pcx->pLibInfo->pImpLibs); + + TRACE_(typelib)("offset %x, masked offset %x\n", offset, offset + (offset & 0xfffffffc)); + + MSFT_ReadLEDWords(&impinfo, sizeof(impinfo), pcx, + pcx->pTblDir->pImpInfo.offset + (offset & 0xfffffffc)); + for(j=0;pImpLib;j++){ /* search the known offsets of all import libraries */ + if(pImpLib->offset==impinfo.oImpFile) break; + pImpLib=pImpLib->next; + } + if(pImpLib){ + (*ppRefType)->reference=offset; + (*ppRefType)->pImpTLInfo = pImpLib; + MSFT_ReadGuid(&(*ppRefType)->guid, impinfo.oGuid, pcx); + (*ppRefType)->index = TLB_REF_USE_GUID; + }else{ + ERR("Cannot find a reference\n"); + (*ppRefType)->reference=-1; + (*ppRefType)->pImpTLInfo=TLB_REF_NOT_FOUND; + } + }else{ + /* in this typelib */ + (*ppRefType)->index = MSFT_HREFTYPE_INDEX(offset); + (*ppRefType)->reference=offset; + (*ppRefType)->pImpTLInfo=TLB_REF_INTERNAL; + } +} + +/* process Implemented Interfaces of a com class */ +static void MSFT_DoImplTypes(TLBContext *pcx, ITypeInfoImpl *pTI, int count, + int offset) +{ + int i; + MSFT_RefRecord refrec; + TLBImplType **ppImpl = &pTI->impltypelist; + + TRACE_(typelib)("\n"); + + for(i=0;ipTblDir->pRefTab.offset); + MSFT_DoRefType(pcx, pTI, refrec.reftype); + (*ppImpl)->hRef = refrec.reftype; + (*ppImpl)->implflags=refrec.flags; + (*ppImpl)->ctCustData= + MSFT_CustData(pcx, refrec.oCustData, &(*ppImpl)->pCustData); + offset=refrec.onext; + ppImpl=&((*ppImpl)->next); + } +} +/* + * process a typeinfo record + */ +ITypeInfoImpl * MSFT_DoTypeInfo( + TLBContext *pcx, + int count, + ITypeLibImpl * pLibInfo) +{ + MSFT_TypeInfoBase tiBase; + ITypeInfoImpl *ptiRet; + + TRACE_(typelib)("count=%u\n", count); + + ptiRet = (ITypeInfoImpl*) ITypeInfo_Constructor(); + MSFT_ReadLEDWords(&tiBase, sizeof(tiBase) ,pcx , + pcx->pTblDir->pTypeInfoTab.offset+count*sizeof(tiBase)); +/* this is where we are coming from */ + ptiRet->pTypeLib = pLibInfo; + ptiRet->index=count; +/* fill in the typeattr fields */ + WARN("Assign constructor/destructor memid\n"); + + MSFT_ReadGuid(&ptiRet->TypeAttr.guid, tiBase.posguid, pcx); + ptiRet->TypeAttr.lcid=pLibInfo->LibAttr.lcid; /* FIXME: correct? */ + ptiRet->TypeAttr.memidConstructor=MEMBERID_NIL ;/* FIXME */ + ptiRet->TypeAttr.memidDestructor=MEMBERID_NIL ; /* FIXME */ + ptiRet->TypeAttr.lpstrSchema=NULL; /* reserved */ + ptiRet->TypeAttr.cbSizeInstance=tiBase.size; + ptiRet->TypeAttr.typekind=tiBase.typekind & 0xF; + ptiRet->TypeAttr.cFuncs=LOWORD(tiBase.cElement); + ptiRet->TypeAttr.cVars=HIWORD(tiBase.cElement); + ptiRet->TypeAttr.cbAlignment=(tiBase.typekind >> 11 )& 0x1F; /* there are more flags there */ + ptiRet->TypeAttr.wTypeFlags=tiBase.flags; + ptiRet->TypeAttr.wMajorVerNum=LOWORD(tiBase.version); + ptiRet->TypeAttr.wMinorVerNum=HIWORD(tiBase.version); + ptiRet->TypeAttr.cImplTypes=tiBase.cImplTypes; + ptiRet->TypeAttr.cbSizeVft=tiBase.cbSizeVft; /* FIXME: this is only the non inherited part */ + if(ptiRet->TypeAttr.typekind == TKIND_ALIAS) + MSFT_GetTdesc(pcx, tiBase.datatype1, + &ptiRet->TypeAttr.tdescAlias, ptiRet); + +/* FIXME: */ +/* IDLDESC idldescType; *//* never saw this one != zero */ + +/* name, eventually add to a hash table */ + ptiRet->Name=MSFT_ReadName(pcx, tiBase.NameOffset); + TRACE_(typelib)("reading %s\n", debugstr_w(ptiRet->Name)); + /* help info */ + ptiRet->DocString=MSFT_ReadString(pcx, tiBase.docstringoffs); + ptiRet->dwHelpStringContext=tiBase.helpstringcontext; + ptiRet->dwHelpContext=tiBase.helpcontext; +/* note: InfoType's Help file and HelpStringDll come from the containing + * library. Further HelpString and Docstring appear to be the same thing :( + */ + /* functions */ + if(ptiRet->TypeAttr.cFuncs >0 ) + MSFT_DoFuncs(pcx, ptiRet, ptiRet->TypeAttr.cFuncs, + ptiRet->TypeAttr.cVars, + tiBase.memoffset, & ptiRet->funclist); + /* variables */ + if(ptiRet->TypeAttr.cVars >0 ) + MSFT_DoVars(pcx, ptiRet, ptiRet->TypeAttr.cFuncs, + ptiRet->TypeAttr.cVars, + tiBase.memoffset, & ptiRet->varlist); + if(ptiRet->TypeAttr.cImplTypes >0 ) { + switch(ptiRet->TypeAttr.typekind) + { + case TKIND_COCLASS: + MSFT_DoImplTypes(pcx, ptiRet, ptiRet->TypeAttr.cImplTypes , + tiBase.datatype1); + break; + case TKIND_DISPATCH: + ptiRet->impltypelist=TLB_Alloc(sizeof(TLBImplType)); + + if (tiBase.datatype1 != -1) + { + MSFT_DoRefType(pcx, ptiRet, tiBase.datatype1); + ptiRet->impltypelist->hRef = tiBase.datatype1; + } + else + { /* FIXME: This is a really bad hack to add IDispatch */ + const char* szStdOle = "stdole2.tlb\0"; + int nStdOleLen = strlen(szStdOle); + TLBRefType **ppRef = &ptiRet->reflist; + + while(*ppRef) { + if((*ppRef)->reference == -1) + break; + ppRef = &(*ppRef)->next; + } + if(!*ppRef) { + *ppRef = TLB_Alloc(sizeof(**ppRef)); + (*ppRef)->guid = IID_IDispatch; + (*ppRef)->reference = -1; + (*ppRef)->index = TLB_REF_USE_GUID; + (*ppRef)->pImpTLInfo = TLB_Alloc(sizeof(TLBImpLib)); + (*ppRef)->pImpTLInfo->guid = IID_StdOle; + (*ppRef)->pImpTLInfo->name = SysAllocStringLen(NULL, + nStdOleLen + 1); + + MultiByteToWideChar(CP_ACP, + MB_PRECOMPOSED, + szStdOle, + -1, + (*ppRef)->pImpTLInfo->name, + SysStringLen((*ppRef)->pImpTLInfo->name)); + + (*ppRef)->pImpTLInfo->lcid = 0; + (*ppRef)->pImpTLInfo->wVersionMajor = 2; + (*ppRef)->pImpTLInfo->wVersionMinor = 0; + } + } + break; + default: + ptiRet->impltypelist=TLB_Alloc(sizeof(TLBImplType)); + MSFT_DoRefType(pcx, ptiRet, tiBase.datatype1); + ptiRet->impltypelist->hRef = tiBase.datatype1; + break; + } + } + ptiRet->ctCustData= + MSFT_CustData(pcx, tiBase.oCustData, &ptiRet->pCustData); + + TRACE_(typelib)("%s guid: %s kind:%s\n", + debugstr_w(ptiRet->Name), + debugstr_guid(&ptiRet->TypeAttr.guid), + typekind_desc[ptiRet->TypeAttr.typekind]); + + return ptiRet; +} + +/* Because type library parsing has some degree of overhead, and some apps repeatedly load the same + * typelibs over and over, we cache them here. According to MSDN Microsoft have a similar scheme in + * place. This will cause a deliberate memory leak, but generally losing RAM for cycles is an acceptable + * tradeoff here. + */ +static ITypeLibImpl *tlb_cache_first; +static CRITICAL_SECTION cache_section; +static CRITICAL_SECTION_DEBUG cache_section_debug = +{ + 0, 0, &cache_section, + { &cache_section_debug.ProcessLocksList, &cache_section_debug.ProcessLocksList }, + 0, 0, { 0, (DWORD)(__FILE__ ": typelib loader cache") } +}; +static CRITICAL_SECTION cache_section = { &cache_section_debug, -1, 0, 0, 0, 0 }; + + +/**************************************************************************** + * TLB_ReadTypeLib + * + * find the type of the typelib file and map the typelib resource into + * the memory + */ +#define MSFT_SIGNATURE 0x5446534D /* "MSFT" */ +#define SLTG_SIGNATURE 0x47544c53 /* "SLTG" */ +int TLB_ReadTypeLib(LPCWSTR pszFileName, INT index, ITypeLib2 **ppTypeLib) +{ + ITypeLibImpl *entry; + int ret = TYPE_E_CANTLOADLIBRARY; + DWORD dwSignature = 0; + HANDLE hFile; + + TRACE_(typelib)("%s:%d\n", debugstr_w(pszFileName), index); + + *ppTypeLib = NULL; + + /* We look the path up in the typelib cache. If found, we just addref it, and return the pointer. */ + EnterCriticalSection(&cache_section); + for (entry = tlb_cache_first; entry != NULL; entry = entry->next) + { + if (!strcmpiW(entry->path, pszFileName)) + { + TRACE("cache hit\n"); + *ppTypeLib = (ITypeLib2*)entry; + ITypeLib_AddRef(*ppTypeLib); + LeaveCriticalSection(&cache_section); + return S_OK; + } + } + LeaveCriticalSection(&cache_section); + + /* check the signature of the file */ + hFile = CreateFileW( pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 ); + if (INVALID_HANDLE_VALUE != hFile) + { + HANDLE hMapping = CreateFileMappingW( hFile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL ); + if (hMapping) + { + LPVOID pBase = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0); + if(pBase) + { + /* retrieve file size */ + DWORD dwTLBLength = GetFileSize(hFile, NULL); + + /* first try to load as *.tlb */ + dwSignature = FromLEDWord(*((DWORD*) pBase)); + if ( dwSignature == MSFT_SIGNATURE) + { + *ppTypeLib = ITypeLib2_Constructor_MSFT(pBase, dwTLBLength); + } + else if ( dwSignature == SLTG_SIGNATURE) + { + *ppTypeLib = ITypeLib2_Constructor_SLTG(pBase, dwTLBLength); + } + UnmapViewOfFile(pBase); + } + CloseHandle(hMapping); + } + CloseHandle(hFile); + } + + if( (WORD)dwSignature == IMAGE_DOS_SIGNATURE ) + { + /* find the typelibrary resource*/ + HINSTANCE hinstDLL = LoadLibraryExW(pszFileName, 0, DONT_RESOLVE_DLL_REFERENCES| + LOAD_LIBRARY_AS_DATAFILE|LOAD_WITH_ALTERED_SEARCH_PATH); + if (hinstDLL) + { + static const WCHAR TYPELIBW[] = {'T','Y','P','E','L','I','B',0}; + HRSRC hrsrc = FindResourceW(hinstDLL, MAKEINTRESOURCEW(index), TYPELIBW); + if (hrsrc) + { + HGLOBAL hGlobal = LoadResource(hinstDLL, hrsrc); + if (hGlobal) + { + LPVOID pBase = LockResource(hGlobal); + DWORD dwTLBLength = SizeofResource(hinstDLL, hrsrc); + + if (pBase) + { + /* try to load as incore resource */ + dwSignature = FromLEDWord(*((DWORD*) pBase)); + if ( dwSignature == MSFT_SIGNATURE) + { + *ppTypeLib = ITypeLib2_Constructor_MSFT(pBase, dwTLBLength); + } + else if ( dwSignature == SLTG_SIGNATURE) + { + *ppTypeLib = ITypeLib2_Constructor_SLTG(pBase, dwTLBLength); + } + else + { + FIXME("Header type magic 0x%08lx not supported.\n",dwSignature); + } + } + FreeResource( hGlobal ); + } + } + FreeLibrary(hinstDLL); + } + } + + if(*ppTypeLib) { + ITypeLibImpl *impl = (ITypeLibImpl*)*ppTypeLib; + + TRACE("adding to cache\n"); + impl->path = HeapAlloc(GetProcessHeap(), 0, (strlenW(pszFileName)+1) * sizeof(WCHAR)); + lstrcpyW(impl->path, pszFileName); + /* We should really canonicalise the path here. */ + + /* FIXME: check if it has added already in the meantime */ + EnterCriticalSection(&cache_section); + if ((impl->next = tlb_cache_first) != NULL) impl->next->prev = impl; + impl->prev = NULL; + tlb_cache_first = impl; + LeaveCriticalSection(&cache_section); + ret = S_OK; + } else + ERR("Loading of typelib %s failed with error %ld\n", debugstr_w(pszFileName), GetLastError()); + + return ret; +} + +/*================== ITypeLib(2) Methods ===================================*/ + +/**************************************************************************** + * ITypeLib2_Constructor_MSFT + * + * loading an MSFT typelib from an in-memory image + */ +static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength) +{ + TLBContext cx; + long lPSegDir; + MSFT_Header tlbHeader; + MSFT_SegDir tlbSegDir; + ITypeLibImpl * pTypeLibImpl; + + TRACE("%p, TLB length = %ld\n", pLib, dwTLBLength); + + pTypeLibImpl = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ITypeLibImpl)); + if (!pTypeLibImpl) return NULL; + + pTypeLibImpl->lpVtbl = &tlbvt; + pTypeLibImpl->lpVtblTypeComp = &tlbtcvt; + pTypeLibImpl->ref = 1; + + /* get pointer to beginning of typelib data */ + cx.pos = 0; + cx.oStart=0; + cx.mapping = pLib; + cx.pLibInfo = pTypeLibImpl; + cx.length = dwTLBLength; + + /* read header */ + MSFT_ReadLEDWords((void*)&tlbHeader, sizeof(tlbHeader), &cx, 0); + TRACE("header:\n"); + TRACE("\tmagic1=0x%08x ,magic2=0x%08x\n",tlbHeader.magic1,tlbHeader.magic2 ); + if (tlbHeader.magic1 != MSFT_SIGNATURE) { + FIXME("Header type magic 0x%08x not supported.\n",tlbHeader.magic1); + return NULL; + } + /* there is a small amount of information here until the next important + * part: + * the segment directory . Try to calculate the amount of data */ + lPSegDir = sizeof(tlbHeader) + (tlbHeader.nrtypeinfos)*4 + ((tlbHeader.varflags & HELPDLLFLAG)? 4 :0); + + /* now read the segment directory */ + TRACE("read segment directory (at %ld)\n",lPSegDir); + MSFT_ReadLEDWords(&tlbSegDir, sizeof(tlbSegDir), &cx, lPSegDir); + cx.pTblDir = &tlbSegDir; + + /* just check two entries */ + if ( tlbSegDir.pTypeInfoTab.res0c != 0x0F || tlbSegDir.pImpInfo.res0c != 0x0F) + { + ERR("cannot find the table directory, ptr=0x%lx\n",lPSegDir); + HeapFree(GetProcessHeap(),0,pTypeLibImpl); + return NULL; + } + + /* now fill our internal data */ + /* TLIBATTR fields */ + MSFT_ReadGuid(&pTypeLibImpl->LibAttr.guid, tlbHeader.posguid, &cx); + + /* pTypeLibImpl->LibAttr.lcid = tlbHeader.lcid;*/ + /* Windows seems to have zero here, is this correct? */ + if(SUBLANGID(tlbHeader.lcid) == SUBLANG_NEUTRAL) + pTypeLibImpl->LibAttr.lcid = MAKELCID(MAKELANGID(PRIMARYLANGID(tlbHeader.lcid),0),0); + else + pTypeLibImpl->LibAttr.lcid = 0; + + pTypeLibImpl->LibAttr.syskind = tlbHeader.varflags & 0x0f; /* check the mask */ + pTypeLibImpl->LibAttr.wMajorVerNum = LOWORD(tlbHeader.version); + pTypeLibImpl->LibAttr.wMinorVerNum = HIWORD(tlbHeader.version); + pTypeLibImpl->LibAttr.wLibFlags = (WORD) tlbHeader.flags & 0xffff;/* check mask */ + + /* name, eventually add to a hash table */ + pTypeLibImpl->Name = MSFT_ReadName(&cx, tlbHeader.NameOffset); + + /* help info */ + pTypeLibImpl->DocString = MSFT_ReadString(&cx, tlbHeader.helpstring); + pTypeLibImpl->HelpFile = MSFT_ReadString(&cx, tlbHeader.helpfile); + + if( tlbHeader.varflags & HELPDLLFLAG) + { + int offset; + MSFT_ReadLEDWords(&offset, sizeof(offset), &cx, sizeof(tlbHeader)); + pTypeLibImpl->HelpStringDll = MSFT_ReadString(&cx, offset); + } + + pTypeLibImpl->dwHelpContext = tlbHeader.helpstringcontext; + + /* custom data */ + if(tlbHeader.CustomDataOffset >= 0) + { + pTypeLibImpl->ctCustData = MSFT_CustData(&cx, tlbHeader.CustomDataOffset, &pTypeLibImpl->pCustData); + } + + /* fill in typedescriptions */ + if(tlbSegDir.pTypdescTab.length > 0) + { + int i, j, cTD = tlbSegDir.pTypdescTab.length / (2*sizeof(INT)); + INT16 td[4]; + pTypeLibImpl->pTypeDesc = TLB_Alloc( cTD * sizeof(TYPEDESC)); + MSFT_ReadLEWords(td, sizeof(td), &cx, tlbSegDir.pTypdescTab.offset); + for(i=0; ipTypeDesc[i].vt = td[0] & VT_TYPEMASK; + if(td[0] == VT_PTR || td[0] == VT_SAFEARRAY) + { + /* FIXME: check safearray */ + if(td[3] < 0) + pTypeLibImpl->pTypeDesc[i].u.lptdesc= & stndTypeDesc[td[2]]; + else + pTypeLibImpl->pTypeDesc[i].u.lptdesc= & pTypeLibImpl->pTypeDesc[td[2]/8]; + } + else if(td[0] == VT_CARRAY) + { + /* array descr table here */ + pTypeLibImpl->pTypeDesc[i].u.lpadesc = (void *)((int) td[2]); /* temp store offset in*/ + } + else if(td[0] == VT_USERDEFINED) + { + pTypeLibImpl->pTypeDesc[i].u.hreftype = MAKELONG(td[2],td[3]); + } + if(++ipTypeDesc[i].vt != VT_CARRAY) continue; + if(tlbSegDir.pArrayDescriptions.offset>0) + { + MSFT_ReadLEWords(td, sizeof(td), &cx, tlbSegDir.pArrayDescriptions.offset + (int) pTypeLibImpl->pTypeDesc[i].u.lpadesc); + pTypeLibImpl->pTypeDesc[i].u.lpadesc = TLB_Alloc(sizeof(ARRAYDESC)+sizeof(SAFEARRAYBOUND)*(td[3]-1)); + + if(td[1]<0) + pTypeLibImpl->pTypeDesc[i].u.lpadesc->tdescElem.vt = td[0] & VT_TYPEMASK; + else + pTypeLibImpl->pTypeDesc[i].u.lpadesc->tdescElem = stndTypeDesc[td[0]/8]; + + pTypeLibImpl->pTypeDesc[i].u.lpadesc->cDims = td[2]; + + for(j = 0; jpTypeDesc[i].u.lpadesc->rgbounds[j].cElements, + sizeof(INT), &cx, DO_NOT_SEEK); + MSFT_ReadLEDWords(& pTypeLibImpl->pTypeDesc[i].u.lpadesc->rgbounds[j].lLbound, + sizeof(INT), &cx, DO_NOT_SEEK); + } + } + else + { + pTypeLibImpl->pTypeDesc[i].u.lpadesc = NULL; + ERR("didn't find array description data\n"); + } + } + } + + /* imported type libs */ + if(tlbSegDir.pImpFiles.offset>0) + { + TLBImpLib **ppImpLib = &(pTypeLibImpl->pImpLibs); + int oGuid, offset = tlbSegDir.pImpFiles.offset; + UINT16 size; + + while(offset < tlbSegDir.pImpFiles.offset +tlbSegDir.pImpFiles.length) + { + char *name; + DWORD len; + + *ppImpLib = TLB_Alloc(sizeof(TLBImpLib)); + (*ppImpLib)->offset = offset - tlbSegDir.pImpFiles.offset; + MSFT_ReadLEDWords(&oGuid, sizeof(INT), &cx, offset); + + MSFT_ReadLEDWords(&(*ppImpLib)->lcid, sizeof(LCID), &cx, DO_NOT_SEEK); + MSFT_ReadLEWords(&(*ppImpLib)->wVersionMajor, sizeof(WORD), &cx, DO_NOT_SEEK); + MSFT_ReadLEWords(&(*ppImpLib)->wVersionMinor, sizeof(WORD), &cx, DO_NOT_SEEK); + MSFT_ReadLEWords(& size, sizeof(UINT16), &cx, DO_NOT_SEEK); + + size >>= 2; + name = TLB_Alloc(size+1); + MSFT_Read(name, size, &cx, DO_NOT_SEEK); + len = MultiByteToWideChar(CP_ACP, 0, name, -1, NULL, 0 ); + (*ppImpLib)->name = TLB_Alloc(len * sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, name, -1, (*ppImpLib)->name, len ); + TLB_Free(name); + + MSFT_ReadGuid(&(*ppImpLib)->guid, oGuid, &cx); + offset = (offset + sizeof(INT) + sizeof(DWORD) + sizeof(LCID) + sizeof(UINT16) + size + 3) & ~3; + + ppImpLib = &(*ppImpLib)->next; + } + } + + /* type info's */ + if(tlbHeader.nrtypeinfos >= 0 ) + { + /*pTypeLibImpl->TypeInfoCount=tlbHeader.nrtypeinfos; */ + ITypeInfoImpl **ppTI = &(pTypeLibImpl->pTypeInfo); + int i; + + for(i = 0; i<(int)tlbHeader.nrtypeinfos; i++) + { + *ppTI = MSFT_DoTypeInfo(&cx, i, pTypeLibImpl); + + ppTI = &((*ppTI)->next); + (pTypeLibImpl->TypeInfoCount)++; + } + } + + TRACE("(%p)\n", pTypeLibImpl); + return (ITypeLib2*) pTypeLibImpl; +} + + +static BSTR TLB_MultiByteToBSTR(char *ptr) +{ + DWORD len; + WCHAR *nameW; + BSTR ret; + + len = MultiByteToWideChar(CP_ACP, 0, ptr, -1, NULL, 0); + nameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, ptr, -1, nameW, len); + ret = SysAllocString(nameW); + HeapFree(GetProcessHeap(), 0, nameW); + return ret; +} + +static BOOL TLB_GUIDFromString(char *str, GUID *guid) +{ + char b[3]; + int i; + short s; + + if(sscanf(str, "%lx-%hx-%hx-%hx", &guid->Data1, &guid->Data2, &guid->Data3, &s) != 4) { + FIXME("Can't parse guid %s\n", debugstr_guid(guid)); + return FALSE; + } + + guid->Data4[0] = s >> 8; + guid->Data4[1] = s & 0xff; + + b[2] = '\0'; + for(i = 0; i < 6; i++) { + memcpy(b, str + 24 + 2 * i, 2); + guid->Data4[i + 2] = strtol(b, NULL, 16); + } + return TRUE; +} + +static WORD SLTG_ReadString(char *ptr, BSTR *pBstr) +{ + WORD bytelen; + DWORD len; + WCHAR *nameW; + + *pBstr = NULL; + bytelen = *(WORD*)ptr; + if(bytelen == 0xffff) return 2; + len = MultiByteToWideChar(CP_ACP, 0, ptr + 2, bytelen, NULL, 0); + nameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + len = MultiByteToWideChar(CP_ACP, 0, ptr + 2, bytelen, nameW, len); + *pBstr = SysAllocStringLen(nameW, len); + HeapFree(GetProcessHeap(), 0, nameW); + return bytelen + 2; +} + +static WORD SLTG_ReadStringA(char *ptr, char **str) +{ + WORD bytelen; + + *str = NULL; + bytelen = *(WORD*)ptr; + if(bytelen == 0xffff) return 2; + *str = HeapAlloc(GetProcessHeap(), 0, bytelen + 1); + memcpy(*str, ptr + 2, bytelen); + (*str)[bytelen] = '\0'; + return bytelen + 2; +} + +static DWORD SLTG_ReadLibBlk(LPVOID pLibBlk, ITypeLibImpl *pTypeLibImpl) +{ + char *ptr = pLibBlk; + WORD w; + + if((w = *(WORD*)ptr) != SLTG_LIBBLK_MAGIC) { + FIXME("libblk magic = %04x\n", w); + return 0; + } + + ptr += 6; + if((w = *(WORD*)ptr) != 0xffff) { + FIXME("LibBlk.res06 = %04x. Assumung string and skipping\n", w); + ptr += w; + } + ptr += 2; + + ptr += SLTG_ReadString(ptr, &pTypeLibImpl->DocString); + + ptr += SLTG_ReadString(ptr, &pTypeLibImpl->HelpFile); + + pTypeLibImpl->dwHelpContext = *(DWORD*)ptr; + ptr += 4; + + pTypeLibImpl->LibAttr.syskind = *(WORD*)ptr; + ptr += 2; + + if(SUBLANGID(*(WORD*)ptr) == SUBLANG_NEUTRAL) + pTypeLibImpl->LibAttr.lcid = MAKELCID(MAKELANGID(PRIMARYLANGID(*(WORD*)ptr),0),0); + else + pTypeLibImpl->LibAttr.lcid = 0; + ptr += 2; + + ptr += 4; /* skip res12 */ + + pTypeLibImpl->LibAttr.wLibFlags = *(WORD*)ptr; + ptr += 2; + + pTypeLibImpl->LibAttr.wMajorVerNum = *(WORD*)ptr; + ptr += 2; + + pTypeLibImpl->LibAttr.wMinorVerNum = *(WORD*)ptr; + ptr += 2; + + memcpy(&pTypeLibImpl->LibAttr.guid, ptr, sizeof(GUID)); + ptr += sizeof(GUID); + + return ptr - (char*)pLibBlk; +} + +static WORD *SLTG_DoType(WORD *pType, char *pBlk, ELEMDESC *pElem) +{ + BOOL done = FALSE; + TYPEDESC *pTD = &pElem->tdesc; + + /* Handle [in/out] first */ + if((*pType & 0xc000) == 0xc000) + pElem->u.paramdesc.wParamFlags = PARAMFLAG_NONE; + else if(*pType & 0x8000) + pElem->u.paramdesc.wParamFlags = PARAMFLAG_FIN | PARAMFLAG_FOUT; + else if(*pType & 0x4000) + pElem->u.paramdesc.wParamFlags = PARAMFLAG_FOUT; + else + pElem->u.paramdesc.wParamFlags = PARAMFLAG_FIN; + + if(*pType & 0x2000) + pElem->u.paramdesc.wParamFlags |= PARAMFLAG_FLCID; + + if(*pType & 0x80) + pElem->u.paramdesc.wParamFlags |= PARAMFLAG_FRETVAL; + + while(!done) { + if((*pType & 0xe00) == 0xe00) { + pTD->vt = VT_PTR; + pTD->u.lptdesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + sizeof(TYPEDESC)); + pTD = pTD->u.lptdesc; + } + switch(*pType & 0x7f) { + case VT_PTR: + pTD->vt = VT_PTR; + pTD->u.lptdesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + sizeof(TYPEDESC)); + pTD = pTD->u.lptdesc; + break; + + case VT_USERDEFINED: + pTD->vt = VT_USERDEFINED; + pTD->u.hreftype = *(++pType) / 4; + done = TRUE; + break; + + case VT_CARRAY: + { + /* *(pType+1) is offset to a SAFEARRAY, *(pType+2) is type of + array */ + + SAFEARRAY *pSA = (SAFEARRAY *)(pBlk + *(++pType)); + + pTD->vt = VT_CARRAY; + pTD->u.lpadesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + sizeof(ARRAYDESC) + + (pSA->cDims - 1) * sizeof(SAFEARRAYBOUND)); + pTD->u.lpadesc->cDims = pSA->cDims; + memcpy(pTD->u.lpadesc->rgbounds, pSA->rgsabound, + pSA->cDims * sizeof(SAFEARRAYBOUND)); + + pTD = &pTD->u.lpadesc->tdescElem; + break; + } + + case VT_SAFEARRAY: + { + /* FIXME: *(pType+1) gives an offset to SAFEARRAY, is this + useful? */ + + pType++; + pTD->vt = VT_SAFEARRAY; + pTD->u.lptdesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + sizeof(TYPEDESC)); + pTD = pTD->u.lptdesc; + break; + } + default: + pTD->vt = *pType & 0x7f; + done = TRUE; + break; + } + pType++; + } + return pType; +} + + +static void SLTG_DoRefs(SLTG_RefInfo *pRef, ITypeInfoImpl *pTI, + char *pNameTable) +{ + int ref; + char *name; + TLBRefType **ppRefType; + + if(pRef->magic != SLTG_REF_MAGIC) { + FIXME("Ref magic = %x\n", pRef->magic); + return; + } + name = ( (char*)(&pRef->names) + pRef->number); + + ppRefType = &pTI->reflist; + for(ref = 0; ref < pRef->number >> 3; ref++) { + char *refname; + unsigned int lib_offs, type_num; + + *ppRefType = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + sizeof(**ppRefType)); + + name += SLTG_ReadStringA(name, &refname); + if(sscanf(refname, "*\\R%x*#%x", &lib_offs, &type_num) != 2) + FIXME("Can't sscanf ref\n"); + if(lib_offs != 0xffff) { + TLBImpLib **import = &pTI->pTypeLib->pImpLibs; + + while(*import) { + if((*import)->offset == lib_offs) + break; + import = &(*import)->next; + } + if(!*import) { + char fname[MAX_PATH+1]; + int len; + + *import = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + sizeof(**import)); + (*import)->offset = lib_offs; + TLB_GUIDFromString( pNameTable + lib_offs + 4, + &(*import)->guid); + if(sscanf(pNameTable + lib_offs + 40, "}#%hd.%hd#%lx#%s", + &(*import)->wVersionMajor, + &(*import)->wVersionMinor, + &(*import)->lcid, fname) != 4) { + FIXME("can't sscanf ref %s\n", + pNameTable + lib_offs + 40); + } + len = strlen(fname); + if(fname[len-1] != '#') + FIXME("fname = %s\n", fname); + fname[len-1] = '\0'; + (*import)->name = TLB_MultiByteToBSTR(fname); + } + (*ppRefType)->pImpTLInfo = *import; + } else { /* internal ref */ + (*ppRefType)->pImpTLInfo = TLB_REF_INTERNAL; + } + (*ppRefType)->reference = ref; + (*ppRefType)->index = type_num; + + HeapFree(GetProcessHeap(), 0, refname); + ppRefType = &(*ppRefType)->next; + } + if((BYTE)*name != SLTG_REF_MAGIC) + FIXME("End of ref block magic = %x\n", *name); + dump_TLBRefType(pTI->reflist); +} + +static char *SLTG_DoImpls(char *pBlk, ITypeInfoImpl *pTI, + BOOL OneOnly) +{ + SLTG_ImplInfo *info; + TLBImplType **ppImplType = &pTI->impltypelist; + /* I don't really get this structure, usually it's 0x16 bytes + long, but iuser.tlb contains some that are 0x18 bytes long. + That's ok because we can use the next ptr to jump to the next + one. But how do we know the length of the last one? The WORD + at offs 0x8 might be the clue. For now I'm just assuming that + the last one is the regular 0x16 bytes. */ + + info = (SLTG_ImplInfo*)pBlk; + while(1) { + *ppImplType = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + sizeof(**ppImplType)); + (*ppImplType)->hRef = info->ref; + (*ppImplType)->implflags = info->impltypeflags; + pTI->TypeAttr.cImplTypes++; + ppImplType = &(*ppImplType)->next; + + if(info->next == 0xffff) + break; + if(OneOnly) + FIXME("Interface inheriting more than one interface\n"); + info = (SLTG_ImplInfo*)(pBlk + info->next); + } + info++; /* see comment at top of function */ + return (char*)info; +} + +static SLTG_TypeInfoTail *SLTG_ProcessCoClass(char *pBlk, ITypeInfoImpl *pTI, + char *pNameTable) +{ + SLTG_TypeInfoHeader *pTIHeader = (SLTG_TypeInfoHeader*)pBlk; + SLTG_MemberHeader *pMemHeader; + char *pFirstItem, *pNextItem; + + if(pTIHeader->href_table != 0xffffffff) { + SLTG_DoRefs((SLTG_RefInfo*)(pBlk + pTIHeader->href_table), pTI, + pNameTable); + } + + + pMemHeader = (SLTG_MemberHeader*)(pBlk + pTIHeader->elem_table); + + pFirstItem = pNextItem = (char*)(pMemHeader + 1); + + if(*(WORD*)pFirstItem == SLTG_IMPL_MAGIC) { + pNextItem = SLTG_DoImpls(pFirstItem, pTI, FALSE); + } + + return (SLTG_TypeInfoTail*)(pFirstItem + pMemHeader->cbExtra); +} + + +static SLTG_TypeInfoTail *SLTG_ProcessInterface(char *pBlk, ITypeInfoImpl *pTI, + char *pNameTable) +{ + SLTG_TypeInfoHeader *pTIHeader = (SLTG_TypeInfoHeader*)pBlk; + SLTG_MemberHeader *pMemHeader; + SLTG_Function *pFunc; + char *pFirstItem, *pNextItem; + TLBFuncDesc **ppFuncDesc = &pTI->funclist; + int num = 0; + + if(pTIHeader->href_table != 0xffffffff) { + SLTG_DoRefs((SLTG_RefInfo*)(pBlk + pTIHeader->href_table), pTI, + pNameTable); + } + + pMemHeader = (SLTG_MemberHeader*)(pBlk + pTIHeader->elem_table); + + pFirstItem = pNextItem = (char*)(pMemHeader + 1); + + if(*(WORD*)pFirstItem == SLTG_IMPL_MAGIC) { + pNextItem = SLTG_DoImpls(pFirstItem, pTI, TRUE); + } + + for(pFunc = (SLTG_Function*)pNextItem, num = 1; 1; + pFunc = (SLTG_Function*)(pFirstItem + pFunc->next), num++) { + + int param; + WORD *pType, *pArg; + + if(pFunc->magic != SLTG_FUNCTION_MAGIC && + pFunc->magic != SLTG_FUNCTION_WITH_FLAGS_MAGIC) { + FIXME("func magic = %02x\n", pFunc->magic); + return NULL; + } + *ppFuncDesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + sizeof(**ppFuncDesc)); + (*ppFuncDesc)->Name = TLB_MultiByteToBSTR(pFunc->name + pNameTable); + + (*ppFuncDesc)->funcdesc.memid = pFunc->dispid; + (*ppFuncDesc)->funcdesc.invkind = pFunc->inv >> 4; + (*ppFuncDesc)->funcdesc.callconv = pFunc->nacc & 0x7; + (*ppFuncDesc)->funcdesc.cParams = pFunc->nacc >> 3; + (*ppFuncDesc)->funcdesc.cParamsOpt = (pFunc->retnextopt & 0x7e) >> 1; + (*ppFuncDesc)->funcdesc.oVft = pFunc->vtblpos; + + if(pFunc->magic == SLTG_FUNCTION_WITH_FLAGS_MAGIC) + (*ppFuncDesc)->funcdesc.wFuncFlags = pFunc->funcflags; + + if(pFunc->retnextopt & 0x80) + pType = &pFunc->rettype; + else + pType = (WORD*)(pFirstItem + pFunc->rettype); + + + SLTG_DoType(pType, pFirstItem, &(*ppFuncDesc)->funcdesc.elemdescFunc); + + (*ppFuncDesc)->funcdesc.lprgelemdescParam = + HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + (*ppFuncDesc)->funcdesc.cParams * sizeof(ELEMDESC)); + (*ppFuncDesc)->pParamDesc = + HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + (*ppFuncDesc)->funcdesc.cParams * sizeof(TLBParDesc)); + + pArg = (WORD*)(pFirstItem + pFunc->arg_off); + + for(param = 0; param < (*ppFuncDesc)->funcdesc.cParams; param++) { + char *paramName = pNameTable + *pArg; + BOOL HaveOffs; + /* If arg type follows then paramName points to the 2nd + letter of the name, else the next WORD is an offset to + the arg type and paramName points to the first letter. + So let's take one char off paramName and see if we're + pointing at an alpha-numeric char. However if *pArg is + 0xffff or 0xfffe then the param has no name, the former + meaning that the next WORD is the type, the latter + meaning the the next WORD is an offset to the type. */ + + HaveOffs = FALSE; + if(*pArg == 0xffff) + paramName = NULL; + else if(*pArg == 0xfffe) { + paramName = NULL; + HaveOffs = TRUE; + } + else if(!isalnum(*(paramName-1))) + HaveOffs = TRUE; + + pArg++; + + if(HaveOffs) { /* the next word is an offset to type */ + pType = (WORD*)(pFirstItem + *pArg); + SLTG_DoType(pType, pFirstItem, + &(*ppFuncDesc)->funcdesc.lprgelemdescParam[param]); + pArg++; + } else { + if(paramName) + paramName--; + pArg = SLTG_DoType(pArg, pFirstItem, + &(*ppFuncDesc)->funcdesc.lprgelemdescParam[param]); + } + + /* Are we an optional param ? */ + if((*ppFuncDesc)->funcdesc.cParams - param <= + (*ppFuncDesc)->funcdesc.cParamsOpt) + (*ppFuncDesc)->funcdesc.lprgelemdescParam[param].u.paramdesc.wParamFlags |= PARAMFLAG_FOPT; + + if(paramName) { + (*ppFuncDesc)->pParamDesc[param].Name = + TLB_MultiByteToBSTR(paramName); + } + } + + ppFuncDesc = &((*ppFuncDesc)->next); + if(pFunc->next == 0xffff) break; + } + pTI->TypeAttr.cFuncs = num; + dump_TLBFuncDesc(pTI->funclist); + return (SLTG_TypeInfoTail*)(pFirstItem + pMemHeader->cbExtra); +} + +static SLTG_TypeInfoTail *SLTG_ProcessRecord(char *pBlk, ITypeInfoImpl *pTI, + char *pNameTable) +{ + SLTG_TypeInfoHeader *pTIHeader = (SLTG_TypeInfoHeader*)pBlk; + SLTG_MemberHeader *pMemHeader; + SLTG_RecordItem *pItem; + char *pFirstItem; + TLBVarDesc **ppVarDesc = &pTI->varlist; + int num = 0; + WORD *pType; + char buf[300]; + + pMemHeader = (SLTG_MemberHeader*)(pBlk + pTIHeader->elem_table); + + pFirstItem = (char*)(pMemHeader + 1); + for(pItem = (SLTG_RecordItem *)pFirstItem, num = 1; 1; + pItem = (SLTG_RecordItem *)(pFirstItem + pItem->next), num++) { + if(pItem->magic != SLTG_RECORD_MAGIC) { + FIXME("record magic = %02x\n", pItem->magic); + return NULL; + } + *ppVarDesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + sizeof(**ppVarDesc)); + (*ppVarDesc)->Name = TLB_MultiByteToBSTR(pItem->name + pNameTable); + (*ppVarDesc)->vardesc.memid = pItem->memid; + (*ppVarDesc)->vardesc.u.oInst = pItem->byte_offs; + (*ppVarDesc)->vardesc.varkind = VAR_PERINSTANCE; + + if(pItem->typepos == 0x02) + pType = &pItem->type; + else if(pItem->typepos == 0x00) + pType = (WORD*)(pFirstItem + pItem->type); + else { + FIXME("typepos = %02x\n", pItem->typepos); + break; + } + + SLTG_DoType(pType, pFirstItem, + &(*ppVarDesc)->vardesc.elemdescVar); + + /* FIXME("helpcontext, helpstring\n"); */ + + dump_TypeDesc(&(*ppVarDesc)->vardesc.elemdescVar.tdesc, buf); + + ppVarDesc = &((*ppVarDesc)->next); + if(pItem->next == 0xffff) break; + } + pTI->TypeAttr.cVars = num; + return (SLTG_TypeInfoTail*)(pFirstItem + pMemHeader->cbExtra); +} + +static SLTG_TypeInfoTail *SLTG_ProcessAlias(char *pBlk, ITypeInfoImpl *pTI, + char *pNameTable) +{ + SLTG_TypeInfoHeader *pTIHeader = (SLTG_TypeInfoHeader*)pBlk; + SLTG_MemberHeader *pMemHeader; + SLTG_AliasItem *pItem; + int i, mustbelast; + + pMemHeader = (SLTG_MemberHeader*)(pBlk + pTIHeader->elem_table); + pItem = (SLTG_AliasItem*)(pMemHeader + 1); + + mustbelast = 0; + /* This is used for creating a TYPEDESC chain in case of VT_USERDEFINED */ + for (i = 0 ; icbExtra/4 ; i++) { + if (pItem->vt == 0xffff) { + if (i<(pMemHeader->cbExtra/4-1)) + FIXME("Endmarker too early in process alias data!\n"); + break; + } + if (mustbelast) { + FIXME("Chain extends over last entry?\n"); + break; + } + if (pItem->vt == VT_USERDEFINED) { + pTI->TypeAttr.tdescAlias.vt = pItem->vt; + /* guessing here ... */ + FIXME("Guessing TKIND_ALIAS of VT_USERDEFINED with hreftype 0x%x\n",pItem->res02); + pTI->TypeAttr.tdescAlias.u.hreftype = pItem->res02; + mustbelast = 1; + } else { + FIXME("alias %d: 0x%x\n",i,pItem->vt); + FIXME("alias %d: 0x%x\n",i,pItem->res02); + } + pItem++; + } + return (SLTG_TypeInfoTail*)((char*)(pMemHeader + 1)+pMemHeader->cbExtra); +} + +static SLTG_TypeInfoTail *SLTG_ProcessDispatch(char *pBlk, ITypeInfoImpl *pTI, + char *pNameTable) +{ + SLTG_TypeInfoHeader *pTIHeader = (SLTG_TypeInfoHeader*)pBlk; + SLTG_MemberHeader *pMemHeader; + SLTG_AliasItem *pItem; + + pMemHeader = (SLTG_MemberHeader*)(pBlk + pTIHeader->elem_table); + pItem = (SLTG_AliasItem*)(pMemHeader + 1); + FIXME("memh.cbExtra is %ld\n",pMemHeader->cbExtra); + FIXME("offset 0 0x%x\n",*(WORD*)pItem); + return (SLTG_TypeInfoTail*)((char*)(pMemHeader + 1)+pMemHeader->cbExtra); +} + +static SLTG_TypeInfoTail *SLTG_ProcessEnum(char *pBlk, ITypeInfoImpl *pTI, + char *pNameTable) +{ + SLTG_TypeInfoHeader *pTIHeader = (SLTG_TypeInfoHeader*)pBlk; + SLTG_MemberHeader *pMemHeader; + SLTG_EnumItem *pItem; + char *pFirstItem; + TLBVarDesc **ppVarDesc = &pTI->varlist; + int num = 0; + + pMemHeader = (SLTG_MemberHeader*)(pBlk + pTIHeader->elem_table); + + pFirstItem = (char*)(pMemHeader + 1); + for(pItem = (SLTG_EnumItem *)pFirstItem, num = 1; 1; + pItem = (SLTG_EnumItem *)(pFirstItem + pItem->next), num++) { + if(pItem->magic != SLTG_ENUMITEM_MAGIC) { + FIXME("enumitem magic = %04x\n", pItem->magic); + return NULL; + } + *ppVarDesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + sizeof(**ppVarDesc)); + (*ppVarDesc)->Name = TLB_MultiByteToBSTR(pItem->name + pNameTable); + (*ppVarDesc)->vardesc.memid = pItem->memid; + (*ppVarDesc)->vardesc.u.lpvarValue = HeapAlloc(GetProcessHeap(), 0, + sizeof(VARIANT)); + V_VT((*ppVarDesc)->vardesc.u.lpvarValue) = VT_INT; + V_UNION((*ppVarDesc)->vardesc.u.lpvarValue, intVal) = + *(INT*)(pItem->value + pFirstItem); + (*ppVarDesc)->vardesc.elemdescVar.tdesc.vt = VT_I4; + (*ppVarDesc)->vardesc.varkind = VAR_CONST; + /* FIXME("helpcontext, helpstring\n"); */ + + ppVarDesc = &((*ppVarDesc)->next); + if(pItem->next == 0xffff) break; + } + pTI->TypeAttr.cVars = num; + return (SLTG_TypeInfoTail*)(pFirstItem + pMemHeader->cbExtra); +} + +/* Because SLTG_OtherTypeInfo is such a painfull struct, we make a more + managable copy of it into this */ +typedef struct { + WORD small_no; + char *index_name; + char *other_name; + WORD res1a; + WORD name_offs; + WORD more_bytes; + char *extra; + WORD res20; + DWORD helpcontext; + WORD res26; + GUID uuid; +} SLTG_InternalOtherTypeInfo; + +/**************************************************************************** + * ITypeLib2_Constructor_SLTG + * + * loading a SLTG typelib from an in-memory image + */ +static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength) +{ + ITypeLibImpl *pTypeLibImpl; + SLTG_Header *pHeader; + SLTG_BlkEntry *pBlkEntry; + SLTG_Magic *pMagic; + SLTG_Index *pIndex; + SLTG_Pad9 *pPad9; + LPVOID pBlk, pFirstBlk; + SLTG_LibBlk *pLibBlk; + SLTG_InternalOtherTypeInfo *pOtherTypeInfoBlks; + char *pAfterOTIBlks = NULL; + char *pNameTable, *ptr; + int i; + DWORD len, order; + ITypeInfoImpl **ppTypeInfoImpl; + + TRACE("%p, TLB length = %ld\n", pLib, dwTLBLength); + + pTypeLibImpl = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ITypeLibImpl)); + if (!pTypeLibImpl) return NULL; + + pTypeLibImpl->lpVtbl = &tlbvt; + pTypeLibImpl->ref = 1; + + pHeader = pLib; + + TRACE("header:\n"); + TRACE("\tmagic=0x%08lx, file blocks = %d\n", pHeader->SLTG_magic, + pHeader->nrOfFileBlks ); + if (pHeader->SLTG_magic != SLTG_SIGNATURE) { + FIXME("Header type magic 0x%08lx not supported.\n", + pHeader->SLTG_magic); + return NULL; + } + + /* There are pHeader->nrOfFileBlks - 2 TypeInfo records in this typelib */ + pTypeLibImpl->TypeInfoCount = pHeader->nrOfFileBlks - 2; + + /* This points to pHeader->nrOfFileBlks - 1 of SLTG_BlkEntry */ + pBlkEntry = (SLTG_BlkEntry*)(pHeader + 1); + + /* Next we have a magic block */ + pMagic = (SLTG_Magic*)(pBlkEntry + pHeader->nrOfFileBlks - 1); + + /* Let's see if we're still in sync */ + if(memcmp(pMagic->CompObj_magic, SLTG_COMPOBJ_MAGIC, + sizeof(SLTG_COMPOBJ_MAGIC))) { + FIXME("CompObj magic = %s\n", pMagic->CompObj_magic); + return NULL; + } + if(memcmp(pMagic->dir_magic, SLTG_DIR_MAGIC, + sizeof(SLTG_DIR_MAGIC))) { + FIXME("dir magic = %s\n", pMagic->dir_magic); + return NULL; + } + + pIndex = (SLTG_Index*)(pMagic+1); + + pPad9 = (SLTG_Pad9*)(pIndex + pTypeLibImpl->TypeInfoCount); + + pFirstBlk = (LPVOID)(pPad9 + 1); + + /* We'll set up a ptr to the main library block, which is the last one. */ + + for(pBlk = pFirstBlk, order = pHeader->first_blk - 1, i = 0; + pBlkEntry[order].next != 0; + order = pBlkEntry[order].next - 1, i++) { + pBlk = (char*)pBlk + pBlkEntry[order].len; + } + pLibBlk = pBlk; + + len = SLTG_ReadLibBlk(pLibBlk, pTypeLibImpl); + + /* Now there's 0x40 bytes of 0xffff with the numbers 0 to TypeInfoCount + interspersed */ + + len += 0x40; + + /* And now TypeInfoCount of SLTG_OtherTypeInfo */ + + pOtherTypeInfoBlks = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + sizeof(*pOtherTypeInfoBlks) * + pTypeLibImpl->TypeInfoCount); + + + ptr = (char*)pLibBlk + len; + + for(i = 0; i < pTypeLibImpl->TypeInfoCount; i++) { + WORD w, extra; + len = 0; + + pOtherTypeInfoBlks[i].small_no = *(WORD*)ptr; + + w = *(WORD*)(ptr + 2); + if(w != 0xffff) { + len += w; + pOtherTypeInfoBlks[i].index_name = HeapAlloc(GetProcessHeap(),0, + w+1); + memcpy(pOtherTypeInfoBlks[i].index_name, ptr + 4, w); + pOtherTypeInfoBlks[i].index_name[w] = '\0'; + } + w = *(WORD*)(ptr + 4 + len); + if(w != 0xffff) { + TRACE("\twith %s\n", debugstr_an(ptr + 6 + len, w)); + len += w; + pOtherTypeInfoBlks[i].other_name = HeapAlloc(GetProcessHeap(),0, + w+1); + memcpy(pOtherTypeInfoBlks[i].other_name, ptr + 6 + len, w); + pOtherTypeInfoBlks[i].other_name[w] = '\0'; + } + pOtherTypeInfoBlks[i].res1a = *(WORD*)(ptr + len + 6); + pOtherTypeInfoBlks[i].name_offs = *(WORD*)(ptr + len + 8); + extra = pOtherTypeInfoBlks[i].more_bytes = *(WORD*)(ptr + 10 + len); + if(extra) { + pOtherTypeInfoBlks[i].extra = HeapAlloc(GetProcessHeap(),0, + extra); + memcpy(pOtherTypeInfoBlks[i].extra, ptr + 12, extra); + len += extra; + } + pOtherTypeInfoBlks[i].res20 = *(WORD*)(ptr + 12 + len); + pOtherTypeInfoBlks[i].helpcontext = *(DWORD*)(ptr + 14 + len); + pOtherTypeInfoBlks[i].res26 = *(WORD*)(ptr + 18 + len); + memcpy(&pOtherTypeInfoBlks[i].uuid, ptr + 20 + len, sizeof(GUID)); + len += sizeof(SLTG_OtherTypeInfo); + ptr += len; + } + + pAfterOTIBlks = ptr; + + /* Skip this WORD and get the next DWORD */ + len = *(DWORD*)(pAfterOTIBlks + 2); + + /* Now add this to pLibBLk look at what we're pointing at and + possibly add 0x20, then add 0x216, sprinkle a bit a magic + dust and we should be pointing at the beginning of the name + table */ + + pNameTable = (char*)pLibBlk + len; + + switch(*(WORD*)pNameTable) { + case 0xffff: + break; + case 0x0200: + pNameTable += 0x20; + break; + default: + FIXME("pNameTable jump = %x\n", *(WORD*)pNameTable); + break; + } + + pNameTable += 0x216; + + pNameTable += 2; + + TRACE("Library name is %s\n", pNameTable + pLibBlk->name); + + pTypeLibImpl->Name = TLB_MultiByteToBSTR(pNameTable + pLibBlk->name); + + + /* Hopefully we now have enough ptrs set up to actually read in + some TypeInfos. It's not clear which order to do them in, so + I'll just follow the links along the BlkEntry chain and read + them in in the order in which they're in the file */ + + ppTypeInfoImpl = &(pTypeLibImpl->pTypeInfo); + + for(pBlk = pFirstBlk, order = pHeader->first_blk - 1, i = 0; + pBlkEntry[order].next != 0; + order = pBlkEntry[order].next - 1, i++) { + + SLTG_TypeInfoHeader *pTIHeader; + SLTG_TypeInfoTail *pTITail; + + if(strcmp(pBlkEntry[order].index_string + (char*)pMagic, + pOtherTypeInfoBlks[i].index_name)) { + FIXME("Index strings don't match\n"); + return NULL; + } + + pTIHeader = pBlk; + if(pTIHeader->magic != SLTG_TIHEADER_MAGIC) { + FIXME("TypeInfoHeader magic = %04x\n", pTIHeader->magic); + return NULL; + } + *ppTypeInfoImpl = (ITypeInfoImpl*)ITypeInfo_Constructor(); + (*ppTypeInfoImpl)->pTypeLib = pTypeLibImpl; + (*ppTypeInfoImpl)->index = i; + (*ppTypeInfoImpl)->Name = TLB_MultiByteToBSTR( + pOtherTypeInfoBlks[i].name_offs + + pNameTable); + (*ppTypeInfoImpl)->dwHelpContext = pOtherTypeInfoBlks[i].helpcontext; + memcpy(&((*ppTypeInfoImpl)->TypeAttr.guid), &pOtherTypeInfoBlks[i].uuid, + sizeof(GUID)); + (*ppTypeInfoImpl)->TypeAttr.typekind = pTIHeader->typekind; + (*ppTypeInfoImpl)->TypeAttr.wMajorVerNum = pTIHeader->major_version; + (*ppTypeInfoImpl)->TypeAttr.wMinorVerNum = pTIHeader->minor_version; + (*ppTypeInfoImpl)->TypeAttr.wTypeFlags = + (pTIHeader->typeflags1 >> 3) | (pTIHeader->typeflags2 << 5); + + if((pTIHeader->typeflags1 & 7) != 2) + FIXME("typeflags1 = %02x\n", pTIHeader->typeflags1); + if(pTIHeader->typeflags3 != 2) + FIXME("typeflags3 = %02x\n", pTIHeader->typeflags3); + + TRACE("TypeInfo %s of kind %s guid %s typeflags %04x\n", + debugstr_w((*ppTypeInfoImpl)->Name), + typekind_desc[pTIHeader->typekind], + debugstr_guid(&(*ppTypeInfoImpl)->TypeAttr.guid), + (*ppTypeInfoImpl)->TypeAttr.wTypeFlags); + + switch(pTIHeader->typekind) { + case TKIND_ENUM: + pTITail = SLTG_ProcessEnum(pBlk, *ppTypeInfoImpl, pNameTable); + break; + + case TKIND_RECORD: + pTITail = SLTG_ProcessRecord(pBlk, *ppTypeInfoImpl, pNameTable); + break; + + case TKIND_INTERFACE: + pTITail = SLTG_ProcessInterface(pBlk, *ppTypeInfoImpl, pNameTable); + break; + + case TKIND_COCLASS: + pTITail = SLTG_ProcessCoClass(pBlk, *ppTypeInfoImpl, pNameTable); + break; + + case TKIND_ALIAS: + pTITail = SLTG_ProcessAlias(pBlk, *ppTypeInfoImpl, pNameTable); + if (pTITail->tdescalias_vt) + (*ppTypeInfoImpl)->TypeAttr.tdescAlias.vt = pTITail->tdescalias_vt; + break; + + case TKIND_DISPATCH: + pTITail = SLTG_ProcessDispatch(pBlk, *ppTypeInfoImpl, pNameTable); + break; + + default: + FIXME("Not processing typekind %d\n", pTIHeader->typekind); + pTITail = NULL; + break; + + } + + if(pTITail) { /* could get cFuncs, cVars and cImplTypes from here + but we've already set those */ + (*ppTypeInfoImpl)->TypeAttr.cbAlignment = pTITail->cbAlignment; + (*ppTypeInfoImpl)->TypeAttr.cbSizeInstance = pTITail->cbSizeInstance; + (*ppTypeInfoImpl)->TypeAttr.cbSizeVft = pTITail->cbSizeVft; + +#define X(x) TRACE("tt "#x": %x\n",pTITail->res##x); + X(06); + X(08); + X(0a); + X(0c); + X(0e); + X(10); + X(12); + X(16); + X(18); + X(1a); + X(1c); + X(1e); + X(24); + X(26); + X(2a); + X(2c); + X(2e); + X(30); + X(32); + X(34); + } + ppTypeInfoImpl = &((*ppTypeInfoImpl)->next); + pBlk = (char*)pBlk + pBlkEntry[order].len; + } + + if(i != pTypeLibImpl->TypeInfoCount) { + FIXME("Somehow processed %d TypeInfos\n", i); + return NULL; + } + + HeapFree(GetProcessHeap(), 0, pOtherTypeInfoBlks); + return (ITypeLib2*)pTypeLibImpl; +} + +/* ITypeLib::QueryInterface + */ +static HRESULT WINAPI ITypeLib2_fnQueryInterface( + ITypeLib2 * iface, + REFIID riid, + VOID **ppvObject) +{ + ITypeLibImpl *This = (ITypeLibImpl *)iface; + + TRACE("(%p)->(IID: %s)\n",This,debugstr_guid(riid)); + + *ppvObject=NULL; + if(IsEqualIID(riid, &IID_IUnknown) || + IsEqualIID(riid,&IID_ITypeLib)|| + IsEqualIID(riid,&IID_ITypeLib2)) + { + *ppvObject = This; + } + + if(*ppvObject) + { + ITypeLib2_AddRef(iface); + TRACE("-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject); + return S_OK; + } + TRACE("-- Interface: E_NOINTERFACE\n"); + return E_NOINTERFACE; +} + +/* ITypeLib::AddRef + */ +static ULONG WINAPI ITypeLib2_fnAddRef( ITypeLib2 *iface) +{ + ITypeLibImpl *This = (ITypeLibImpl *)iface; + + TRACE("(%p)->ref was %u\n",This, This->ref); + + return ++(This->ref); +} + +/* ITypeLib::Release + */ +static ULONG WINAPI ITypeLib2_fnRelease( ITypeLib2 *iface) +{ + ITypeLibImpl *This = (ITypeLibImpl *)iface; + + --(This->ref); + + TRACE("(%p)->(%u)\n",This, This->ref); + + if (!This->ref) + { + /* remove cache entry */ + TRACE("removing from cache list\n"); + EnterCriticalSection(&cache_section); + if (This->next) This->next->prev = This->prev; + if (This->prev) This->prev->next = This->next; + else tlb_cache_first = This->next; + LeaveCriticalSection(&cache_section); + + /* FIXME destroy child objects */ + TRACE(" destroying ITypeLib(%p)\n",This); + + if (This->Name) + { + SysFreeString(This->Name); + This->Name = NULL; + } + + if (This->DocString) + { + SysFreeString(This->DocString); + This->DocString = NULL; + } + + if (This->HelpFile) + { + SysFreeString(This->HelpFile); + This->HelpFile = NULL; + } + + if (This->HelpStringDll) + { + SysFreeString(This->HelpStringDll); + This->HelpStringDll = NULL; + } + + if (This->pTypeInfo) /* can be NULL */ + ITypeInfo_Release((ITypeInfo*) This->pTypeInfo); + HeapFree(GetProcessHeap(),0,This); + return 0; + } + + return This->ref; +} + +/* ITypeLib::GetTypeInfoCount + * + * Returns the number of type descriptions in the type library + */ +static UINT WINAPI ITypeLib2_fnGetTypeInfoCount( ITypeLib2 *iface) +{ + ITypeLibImpl *This = (ITypeLibImpl *)iface; + TRACE("(%p)->count is %d\n",This, This->TypeInfoCount); + return This->TypeInfoCount; +} + +/* ITypeLib::GetTypeInfo + * + * retrieves the specified type description in the library. + */ +static HRESULT WINAPI ITypeLib2_fnGetTypeInfo( + ITypeLib2 *iface, + UINT index, + ITypeInfo **ppTInfo) +{ + int i; + + ITypeLibImpl *This = (ITypeLibImpl *)iface; + ITypeInfoImpl *pTypeInfo = This->pTypeInfo; + + TRACE("(%p)->(index=%d) \n", This, index); + + if (!ppTInfo) return E_INVALIDARG; + + /* search element n in list */ + for(i=0; i < index; i++) + { + pTypeInfo = pTypeInfo->next; + if (!pTypeInfo) + { + TRACE("-- element not found\n"); + return TYPE_E_ELEMENTNOTFOUND; + } + } + + *ppTInfo = (ITypeInfo *) pTypeInfo; + + ITypeInfo_AddRef(*ppTInfo); + TRACE("-- found (%p)\n",*ppTInfo); + return S_OK; +} + + +/* ITypeLibs::GetTypeInfoType + * + * Retrieves the type of a type description. + */ +static HRESULT WINAPI ITypeLib2_fnGetTypeInfoType( + ITypeLib2 *iface, + UINT index, + TYPEKIND *pTKind) +{ + ITypeLibImpl *This = (ITypeLibImpl *)iface; + int i; + ITypeInfoImpl *pTInfo = This->pTypeInfo; + + TRACE("(%p) index %d \n",This, index); + + if(!pTKind) return E_INVALIDARG; + + /* search element n in list */ + for(i=0; i < index; i++) + { + if(!pTInfo) + { + TRACE("-- element not found\n"); + return TYPE_E_ELEMENTNOTFOUND; + } + pTInfo = pTInfo->next; + } + + *pTKind = pTInfo->TypeAttr.typekind; + TRACE("-- found Type (%d)\n", *pTKind); + return S_OK; +} + +/* ITypeLib::GetTypeInfoOfGuid + * + * Retrieves the type description that corresponds to the specified GUID. + * + */ +static HRESULT WINAPI ITypeLib2_fnGetTypeInfoOfGuid( + ITypeLib2 *iface, + REFGUID guid, + ITypeInfo **ppTInfo) +{ + ITypeLibImpl *This = (ITypeLibImpl *)iface; + ITypeInfoImpl *pTypeInfo = This->pTypeInfo; /* head of list */ + + TRACE("(%p)\n\tguid:\t%s)\n",This,debugstr_guid(guid)); + + if (!pTypeInfo) return TYPE_E_ELEMENTNOTFOUND; + + /* search linked list for guid */ + while( !IsEqualIID(guid,&pTypeInfo->TypeAttr.guid) ) + { + pTypeInfo = pTypeInfo->next; + + if (!pTypeInfo) + { + /* end of list reached */ + TRACE("-- element not found\n"); + return TYPE_E_ELEMENTNOTFOUND; + } + } + + TRACE("-- found (%p, %s)\n", + pTypeInfo, + debugstr_w(pTypeInfo->Name)); + + *ppTInfo = (ITypeInfo*)pTypeInfo; + ITypeInfo_AddRef(*ppTInfo); + return S_OK; +} + +/* ITypeLib::GetLibAttr + * + * Retrieves the structure that contains the library's attributes. + * + */ +static HRESULT WINAPI ITypeLib2_fnGetLibAttr( + ITypeLib2 *iface, + LPTLIBATTR *ppTLibAttr) +{ + ITypeLibImpl *This = (ITypeLibImpl *)iface; + TRACE("(%p)\n",This); + *ppTLibAttr = HeapAlloc(GetProcessHeap(), 0, sizeof(**ppTLibAttr)); + memcpy(*ppTLibAttr, &This->LibAttr, sizeof(**ppTLibAttr)); + return S_OK; +} + +/* ITypeLib::GetTypeComp + * + * Enables a client compiler to bind to a library's types, variables, + * constants, and global functions. + * + */ +static HRESULT WINAPI ITypeLib2_fnGetTypeComp( + ITypeLib2 *iface, + ITypeComp **ppTComp) +{ + ITypeLibImpl *This = (ITypeLibImpl *)iface; + + TRACE("(%p)->(%p)\n",This,ppTComp); + *ppTComp = (ITypeComp *)&This->lpVtblTypeComp; + ITypeComp_AddRef(*ppTComp); + + return S_OK; +} + +/* ITypeLib::GetDocumentation + * + * Retrieves the library's documentation string, the complete Help file name + * and path, and the context identifier for the library Help topic in the Help + * file. + * + * On a successful return all non-null BSTR pointers will have been set, + * possibly to NULL. + */ +static HRESULT WINAPI ITypeLib2_fnGetDocumentation( + ITypeLib2 *iface, + INT index, + BSTR *pBstrName, + BSTR *pBstrDocString, + DWORD *pdwHelpContext, + BSTR *pBstrHelpFile) +{ + ITypeLibImpl *This = (ITypeLibImpl *)iface; + + HRESULT result = E_INVALIDARG; + + ITypeInfo *pTInfo; + + + TRACE("(%p) index %d Name(%p) DocString(%p) HelpContext(%p) HelpFile(%p)\n", + This, index, + pBstrName, pBstrDocString, + pdwHelpContext, pBstrHelpFile); + + if(index<0) + { + /* documentation for the typelib */ + if(pBstrName) + { + if (This->Name) + if(!(*pBstrName = SysAllocString(This->Name))) goto memerr1;else; + else + *pBstrName = NULL; + } + if(pBstrDocString) + { + if (This->DocString) + if(!(*pBstrDocString = SysAllocString(This->DocString))) goto memerr2;else; + else if (This->Name) + if(!(*pBstrDocString = SysAllocString(This->Name))) goto memerr2;else; + else + *pBstrDocString = NULL; + } + if(pdwHelpContext) + { + *pdwHelpContext = This->dwHelpContext; + } + if(pBstrHelpFile) + { + if (This->HelpFile) + if(!(*pBstrHelpFile = SysAllocString(This->HelpFile))) goto memerr3;else; + else + *pBstrHelpFile = NULL; + } + + result = S_OK; + } + else + { + /* for a typeinfo */ + result = ITypeLib2_fnGetTypeInfo(iface, index, &pTInfo); + + if(SUCCEEDED(result)) + { + result = ITypeInfo_GetDocumentation(pTInfo, + MEMBERID_NIL, + pBstrName, + pBstrDocString, + pdwHelpContext, pBstrHelpFile); + + ITypeInfo_Release(pTInfo); + } + } + return result; +memerr3: + if (pBstrDocString) SysFreeString (*pBstrDocString); +memerr2: + if (pBstrName) SysFreeString (*pBstrName); +memerr1: + return STG_E_INSUFFICIENTMEMORY; +} + +/* ITypeLib::IsName + * + * Indicates whether a passed-in string contains the name of a type or member + * described in the library. + * + */ +static HRESULT WINAPI ITypeLib2_fnIsName( + ITypeLib2 *iface, + LPOLESTR szNameBuf, + ULONG lHashVal, + BOOL *pfName) +{ + ITypeLibImpl *This = (ITypeLibImpl *)iface; + ITypeInfoImpl *pTInfo; + TLBFuncDesc *pFInfo; + TLBVarDesc *pVInfo; + int i; + UINT nNameBufLen = SysStringLen(szNameBuf); + + TRACE("(%p)->(%s,%08lx,%p)\n", This, debugstr_w(szNameBuf), lHashVal, + pfName); + + *pfName=TRUE; + for(pTInfo=This->pTypeInfo;pTInfo;pTInfo=pTInfo->next){ + if(!memcmp(szNameBuf,pTInfo->Name, nNameBufLen)) goto ITypeLib2_fnIsName_exit; + for(pFInfo=pTInfo->funclist;pFInfo;pFInfo=pFInfo->next) { + if(!memcmp(szNameBuf,pFInfo->Name, nNameBufLen)) goto ITypeLib2_fnIsName_exit; + for(i=0;ifuncdesc.cParams;i++) + if(!memcmp(szNameBuf,pFInfo->pParamDesc[i].Name, nNameBufLen)) + goto ITypeLib2_fnIsName_exit; + } + for(pVInfo=pTInfo->varlist;pVInfo;pVInfo=pVInfo->next) + if(!memcmp(szNameBuf,pVInfo->Name, nNameBufLen)) goto ITypeLib2_fnIsName_exit; + + } + *pfName=FALSE; + +ITypeLib2_fnIsName_exit: + TRACE("(%p)slow! search for %s: %s found!\n", This, + debugstr_w(szNameBuf), *pfName?"NOT":""); + + return S_OK; +} + +/* ITypeLib::FindName + * + * Finds occurrences of a type description in a type library. This may be used + * to quickly verify that a name exists in a type library. + * + */ +static HRESULT WINAPI ITypeLib2_fnFindName( + ITypeLib2 *iface, + LPOLESTR szNameBuf, + ULONG lHashVal, + ITypeInfo **ppTInfo, + MEMBERID *rgMemId, + UINT16 *pcFound) +{ + ITypeLibImpl *This = (ITypeLibImpl *)iface; + ITypeInfoImpl *pTInfo; + TLBFuncDesc *pFInfo; + TLBVarDesc *pVInfo; + int i,j = 0; + + UINT nNameBufLen = SysStringLen(szNameBuf); + + for(pTInfo=This->pTypeInfo;pTInfo && j<*pcFound; pTInfo=pTInfo->next){ + if(!memcmp(szNameBuf,pTInfo->Name, nNameBufLen)) goto ITypeLib2_fnFindName_exit; + for(pFInfo=pTInfo->funclist;pFInfo;pFInfo=pFInfo->next) { + if(!memcmp(szNameBuf,pFInfo->Name,nNameBufLen)) goto ITypeLib2_fnFindName_exit; + for(i=0;ifuncdesc.cParams;i++) + if(!memcmp(szNameBuf,pFInfo->pParamDesc[i].Name,nNameBufLen)) + goto ITypeLib2_fnFindName_exit; + } + for(pVInfo=pTInfo->varlist;pVInfo;pVInfo=pVInfo->next) + if(!memcmp(szNameBuf,pVInfo->Name, nNameBufLen)) goto ITypeLib2_fnFindName_exit; + continue; +ITypeLib2_fnFindName_exit: + ITypeInfo_AddRef((ITypeInfo*)pTInfo); + ppTInfo[j]=(LPTYPEINFO)pTInfo; + j++; + } + TRACE("(%p)slow! search for %d with %s: found %d TypeInfo's!\n", + This, *pcFound, debugstr_w(szNameBuf), j); + + *pcFound=j; + + return S_OK; +} + +/* ITypeLib::ReleaseTLibAttr + * + * Releases the TLIBATTR originally obtained from ITypeLib::GetLibAttr. + * + */ +static VOID WINAPI ITypeLib2_fnReleaseTLibAttr( + ITypeLib2 *iface, + TLIBATTR *pTLibAttr) +{ + ITypeLibImpl *This = (ITypeLibImpl *)iface; + TRACE("freeing (%p)\n",This); + HeapFree(GetProcessHeap(),0,pTLibAttr); + +} + +/* ITypeLib2::GetCustData + * + * gets the custom data + */ +static HRESULT WINAPI ITypeLib2_fnGetCustData( + ITypeLib2 * iface, + REFGUID guid, + VARIANT *pVarVal) +{ + ITypeLibImpl *This = (ITypeLibImpl *)iface; + TLBCustData *pCData; + + for(pCData=This->pCustData; pCData; pCData = pCData->next) + { + if( IsEqualIID(guid, &pCData->guid)) break; + } + + TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT"); + + if(pCData) + { + VariantInit( pVarVal); + VariantCopy( pVarVal, &pCData->data); + return S_OK; + } + return E_INVALIDARG; /* FIXME: correct? */ +} + +/* ITypeLib2::GetLibStatistics + * + * Returns statistics about a type library that are required for efficient + * sizing of hash tables. + * + */ +static HRESULT WINAPI ITypeLib2_fnGetLibStatistics( + ITypeLib2 * iface, + ULONG *pcUniqueNames, + ULONG *pcchUniqueNames) +{ + ITypeLibImpl *This = (ITypeLibImpl *)iface; + + FIXME("(%p): stub!\n", This); + + if(pcUniqueNames) *pcUniqueNames=1; + if(pcchUniqueNames) *pcchUniqueNames=1; + return S_OK; +} + +/* ITypeLib2::GetDocumentation2 + * + * Retrieves the library's documentation string, the complete Help file name + * and path, the localization context to use, and the context ID for the + * library Help topic in the Help file. + * + */ +static HRESULT WINAPI ITypeLib2_fnGetDocumentation2( + ITypeLib2 * iface, + INT index, + LCID lcid, + BSTR *pbstrHelpString, + DWORD *pdwHelpStringContext, + BSTR *pbstrHelpStringDll) +{ + ITypeLibImpl *This = (ITypeLibImpl *)iface; + HRESULT result; + ITypeInfo *pTInfo; + + FIXME("(%p) index %d lcid %ld half implemented stub!\n", This, index, lcid); + + /* the help string should be obtained from the helpstringdll, + * using the _DLLGetDocumentation function, based on the supplied + * lcid. Nice to do sometime... + */ + if(index<0) + { + /* documentation for the typelib */ + if(pbstrHelpString) + *pbstrHelpString=SysAllocString(This->DocString); + if(pdwHelpStringContext) + *pdwHelpStringContext=This->dwHelpContext; + if(pbstrHelpStringDll) + *pbstrHelpStringDll=SysAllocString(This->HelpStringDll); + + result = S_OK; + } + else + { + /* for a typeinfo */ + result=ITypeLib2_GetTypeInfo(iface, index, &pTInfo); + + if(SUCCEEDED(result)) + { + ITypeInfo2 * pTInfo2; + result = ITypeInfo_QueryInterface(pTInfo, + &IID_ITypeInfo2, + (LPVOID*) &pTInfo2); + + if(SUCCEEDED(result)) + { + result = ITypeInfo2_GetDocumentation2(pTInfo2, + MEMBERID_NIL, + lcid, + pbstrHelpString, + pdwHelpStringContext, + pbstrHelpStringDll); + + ITypeInfo2_Release(pTInfo2); + } + + ITypeInfo_Release(pTInfo); + } + } + return result; +} + +/* ITypeLib2::GetAllCustData + * + * Gets all custom data items for the library. + * + */ +static HRESULT WINAPI ITypeLib2_fnGetAllCustData( + ITypeLib2 * iface, + CUSTDATA *pCustData) +{ + ITypeLibImpl *This = (ITypeLibImpl *)iface; + TLBCustData *pCData; + int i; + TRACE("(%p) returning %d items\n", This, This->ctCustData); + pCustData->prgCustData = TLB_Alloc(This->ctCustData * sizeof(CUSTDATAITEM)); + if(pCustData->prgCustData ){ + pCustData->cCustData=This->ctCustData; + for(i=0, pCData=This->pCustData; pCData; i++, pCData = pCData->next){ + pCustData->prgCustData[i].guid=pCData->guid; + VariantCopy(& pCustData->prgCustData[i].varValue, & pCData->data); + } + }else{ + ERR(" OUT OF MEMORY! \n"); + return E_OUTOFMEMORY; + } + return S_OK; +} + +static ITypeLib2Vtbl tlbvt = { + ITypeLib2_fnQueryInterface, + ITypeLib2_fnAddRef, + ITypeLib2_fnRelease, + ITypeLib2_fnGetTypeInfoCount, + ITypeLib2_fnGetTypeInfo, + ITypeLib2_fnGetTypeInfoType, + ITypeLib2_fnGetTypeInfoOfGuid, + ITypeLib2_fnGetLibAttr, + ITypeLib2_fnGetTypeComp, + ITypeLib2_fnGetDocumentation, + ITypeLib2_fnIsName, + ITypeLib2_fnFindName, + ITypeLib2_fnReleaseTLibAttr, + + ITypeLib2_fnGetCustData, + ITypeLib2_fnGetLibStatistics, + ITypeLib2_fnGetDocumentation2, + ITypeLib2_fnGetAllCustData + }; + + +static HRESULT WINAPI ITypeLibComp_fnQueryInterface(ITypeComp * iface, REFIID riid, LPVOID * ppv) +{ + ICOM_THIS_From_ITypeComp(ITypeLibImpl, iface); + + return ITypeInfo_QueryInterface((ITypeInfo *)This, riid, ppv); +} + +static ULONG WINAPI ITypeLibComp_fnAddRef(ITypeComp * iface) +{ + ICOM_THIS_From_ITypeComp(ITypeLibImpl, iface); + + return ITypeInfo_AddRef((ITypeInfo *)This); +} + +static ULONG WINAPI ITypeLibComp_fnRelease(ITypeComp * iface) +{ + ICOM_THIS_From_ITypeComp(ITypeLibImpl, iface); + + return ITypeInfo_Release((ITypeInfo *)This); +} + +static HRESULT WINAPI ITypeLibComp_fnBind( + ITypeComp * iface, + OLECHAR * szName, + ULONG lHash, + WORD wFlags, + ITypeInfo ** ppTInfo, + DESCKIND * pDescKind, + BINDPTR * pBindPtr) +{ + FIXME("(%s, %lx, 0x%x, %p, %p, %p): stub\n", debugstr_w(szName), lHash, wFlags, ppTInfo, pDescKind, pBindPtr); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITypeLibComp_fnBindType( + ITypeComp * iface, + OLECHAR * szName, + ULONG lHash, + ITypeInfo ** ppTInfo, + ITypeComp ** ppTComp) +{ + FIXME("(%s, %lx, %p, %p): stub\n", debugstr_w(szName), lHash, ppTInfo, ppTComp); + return E_NOTIMPL; +} + +static ITypeCompVtbl tlbtcvt = +{ + + ITypeLibComp_fnQueryInterface, + ITypeLibComp_fnAddRef, + ITypeLibComp_fnRelease, + + ITypeLibComp_fnBind, + ITypeLibComp_fnBindType +}; + +/*================== ITypeInfo(2) Methods ===================================*/ +static ITypeInfo2 * WINAPI ITypeInfo_Constructor(void) +{ + ITypeInfoImpl * pTypeInfoImpl; + + pTypeInfoImpl = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ITypeInfoImpl)); + if (pTypeInfoImpl) + { + pTypeInfoImpl->lpVtbl = &tinfvt; + pTypeInfoImpl->lpVtblTypeComp = &tcompvt; + pTypeInfoImpl->ref=1; + } + TRACE("(%p)\n", pTypeInfoImpl); + return (ITypeInfo2*) pTypeInfoImpl; +} + +/* ITypeInfo::QueryInterface + */ +static HRESULT WINAPI ITypeInfo_fnQueryInterface( + ITypeInfo2 *iface, + REFIID riid, + VOID **ppvObject) +{ + ITypeLibImpl *This = (ITypeLibImpl *)iface; + + TRACE("(%p)->(IID: %s)\n",This,debugstr_guid(riid)); + + *ppvObject=NULL; + if(IsEqualIID(riid, &IID_IUnknown) || + IsEqualIID(riid,&IID_ITypeInfo)|| + IsEqualIID(riid,&IID_ITypeInfo2)) + *ppvObject = This; + + if(*ppvObject){ + ITypeInfo_AddRef(iface); + TRACE("-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject); + return S_OK; + } + TRACE("-- Interface: E_NOINTERFACE\n"); + return E_NOINTERFACE; +} + +/* ITypeInfo::AddRef + */ +static ULONG WINAPI ITypeInfo_fnAddRef( ITypeInfo2 *iface) +{ + ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + + ++(This->ref); + ITypeLib2_AddRef((ITypeLib2*)This->pTypeLib); + + TRACE("(%p)->ref is %u\n",This, This->ref); + return This->ref; +} + +/* ITypeInfo::Release + */ +static ULONG WINAPI ITypeInfo_fnRelease(ITypeInfo2 *iface) +{ + ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + + --(This->ref); + + TRACE("(%p)->(%u)\n",This, This->ref); + + if (This->ref) { + /* We don't release ITypeLib when ref=0 becouse + it means that funtion is called by ITypeLi2_Release */ + ITypeLib2_Release((ITypeLib2*)This->pTypeLib); + } else { + FIXME("destroy child objects\n"); + + TRACE("destroying ITypeInfo(%p)\n",This); + if (This->Name) + { + SysFreeString(This->Name); + This->Name = 0; + } + + if (This->DocString) + { + SysFreeString(This->DocString); + This->DocString = 0; + } + + if (This->next) + { + ITypeInfo_Release((ITypeInfo*)This->next); + } + + HeapFree(GetProcessHeap(),0,This); + return 0; + } + return This->ref; +} + +/* ITypeInfo::GetTypeAttr + * + * Retrieves a TYPEATTR structure that contains the attributes of the type + * description. + * + */ +static HRESULT WINAPI ITypeInfo_fnGetTypeAttr( ITypeInfo2 *iface, + LPTYPEATTR *ppTypeAttr) +{ + ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + TRACE("(%p)\n",This); + /* FIXME: must do a copy here */ + *ppTypeAttr=&This->TypeAttr; + return S_OK; +} + +/* ITypeInfo::GetTypeComp + * + * Retrieves the ITypeComp interface for the type description, which enables a + * client compiler to bind to the type description's members. + * + */ +static HRESULT WINAPI ITypeInfo_fnGetTypeComp( ITypeInfo2 *iface, + ITypeComp * *ppTComp) +{ + ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + + TRACE("(%p)->(%p) stub!\n", This, ppTComp); + + *ppTComp = (ITypeComp *)&This->lpVtblTypeComp; + ITypeComp_AddRef(*ppTComp); + return S_OK; +} + +/* ITypeInfo::GetFuncDesc + * + * Retrieves the FUNCDESC structure that contains information about a + * specified function. + * + */ +static HRESULT WINAPI ITypeInfo_fnGetFuncDesc( ITypeInfo2 *iface, UINT index, + LPFUNCDESC *ppFuncDesc) +{ + ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + int i; + TLBFuncDesc * pFDesc; + TRACE("(%p) index %d\n", This, index); + for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++, pFDesc=pFDesc->next) + ; + if(pFDesc){ + /* FIXME: must do a copy here */ + *ppFuncDesc=&pFDesc->funcdesc; + return S_OK; + } + return E_INVALIDARG; +} + +/* ITypeInfo::GetVarDesc + * + * Retrieves a VARDESC structure that describes the specified variable. + * + */ +static HRESULT WINAPI ITypeInfo_fnGetVarDesc( ITypeInfo2 *iface, UINT index, + LPVARDESC *ppVarDesc) +{ + ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + int i; + TLBVarDesc * pVDesc; + TRACE("(%p) index %d\n", This, index); + for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++, pVDesc=pVDesc->next) + ; + if(pVDesc){ + /* FIXME: must do a copy here */ + *ppVarDesc=&pVDesc->vardesc; + return S_OK; + } + return E_INVALIDARG; +} + +/* ITypeInfo_GetNames + * + * Retrieves the variable with the specified member ID (or the name of the + * property or method and its parameters) that correspond to the specified + * function ID. + */ +static HRESULT WINAPI ITypeInfo_fnGetNames( ITypeInfo2 *iface, MEMBERID memid, + BSTR *rgBstrNames, UINT cMaxNames, UINT *pcNames) +{ + ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + TLBFuncDesc * pFDesc; + TLBVarDesc * pVDesc; + int i; + TRACE("(%p) memid=0x%08lx Maxname=%d\n", This, memid, cMaxNames); + for(pFDesc=This->funclist; pFDesc && pFDesc->funcdesc.memid != memid; pFDesc=pFDesc->next); + if(pFDesc) + { + /* function found, now return function and parameter names */ + for(i=0; ifuncdesc.cParams; i++) + { + if(!i) + *rgBstrNames=SysAllocString(pFDesc->Name); + else + rgBstrNames[i]=SysAllocString(pFDesc->pParamDesc[i-1].Name); + } + *pcNames=i; + } + else + { + for(pVDesc=This->varlist; pVDesc && pVDesc->vardesc.memid != memid; pVDesc=pVDesc->next); + if(pVDesc) + { + *rgBstrNames=SysAllocString(pVDesc->Name); + *pcNames=1; + } + else + { + if(This->TypeAttr.cImplTypes && + (This->TypeAttr.typekind==TKIND_INTERFACE || This->TypeAttr.typekind==TKIND_DISPATCH)) { + /* recursive search */ + ITypeInfo *pTInfo; + HRESULT result; + result=ITypeInfo_GetRefTypeInfo(iface, This->impltypelist->hRef, + &pTInfo); + if(SUCCEEDED(result)) + { + result=ITypeInfo_GetNames(pTInfo, memid, rgBstrNames, cMaxNames, pcNames); + ITypeInfo_Release(pTInfo); + return result; + } + WARN("Could not search inherited interface!\n"); + } + else + { + WARN("no names found\n"); + } + *pcNames=0; + return TYPE_E_ELEMENTNOTFOUND; + } + } + return S_OK; +} + + +/* ITypeInfo::GetRefTypeOfImplType + * + * If a type description describes a COM class, it retrieves the type + * description of the implemented interface types. For an interface, + * GetRefTypeOfImplType returns the type information for inherited interfaces, + * if any exist. + * + */ +static HRESULT WINAPI ITypeInfo_fnGetRefTypeOfImplType( + ITypeInfo2 *iface, + UINT index, + HREFTYPE *pRefType) +{ + ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + int(i); + TLBImplType *pImpl = This->impltypelist; + + TRACE("(%p) index %d\n", This, index); + if (TRACE_ON(ole)) dump_TypeInfo(This); + + if(index==(UINT)-1) + { + /* only valid on dual interfaces; + retrieve the associated TKIND_INTERFACE handle for the current TKIND_DISPATCH + */ + if( This->TypeAttr.typekind != TKIND_DISPATCH) return E_INVALIDARG; + + if (This->TypeAttr.wTypeFlags & TYPEFLAG_FDISPATCHABLE && + This->TypeAttr.wTypeFlags & TYPEFLAG_FDUAL ) + { + *pRefType = -1; + } + else + { + if (!pImpl) return TYPE_E_ELEMENTNOTFOUND; + *pRefType = pImpl->hRef; + } + } + else + { + /* get element n from linked list */ + for(i=0; pImpl && inext; + } + + if (!pImpl) return TYPE_E_ELEMENTNOTFOUND; + + *pRefType = pImpl->hRef; + + TRACE("-- 0x%08lx\n", pImpl->hRef ); + } + + return S_OK; + +} + +/* ITypeInfo::GetImplTypeFlags + * + * Retrieves the IMPLTYPEFLAGS enumeration for one implemented interface + * or base interface in a type description. + */ +static HRESULT WINAPI ITypeInfo_fnGetImplTypeFlags( ITypeInfo2 *iface, + UINT index, INT *pImplTypeFlags) +{ + ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + int i; + TLBImplType *pImpl; + + TRACE("(%p) index %d\n", This, index); + for(i=0, pImpl=This->impltypelist; inext) + ; + if(i==index && pImpl){ + *pImplTypeFlags=pImpl->implflags; + return S_OK; + } + *pImplTypeFlags=0; + return TYPE_E_ELEMENTNOTFOUND; +} + +/* GetIDsOfNames + * Maps between member names and member IDs, and parameter names and + * parameter IDs. + */ +static HRESULT WINAPI ITypeInfo_fnGetIDsOfNames( ITypeInfo2 *iface, + LPOLESTR *rgszNames, UINT cNames, MEMBERID *pMemId) +{ + ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + TLBFuncDesc * pFDesc; + TLBVarDesc * pVDesc; + HRESULT ret=S_OK; + + TRACE("(%p) Name %s cNames %d\n", This, debugstr_w(*rgszNames), + cNames); + for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next) { + int i, j; + if(!lstrcmpiW(*rgszNames, pFDesc->Name)) { + if(cNames) *pMemId=pFDesc->funcdesc.memid; + for(i=1; i < cNames; i++){ + for(j=0; jfuncdesc.cParams; j++) + if(!lstrcmpiW(rgszNames[i],pFDesc->pParamDesc[j].Name)) + break; + if( jfuncdesc.cParams) + pMemId[i]=j; + else + ret=DISP_E_UNKNOWNNAME; + }; + return ret; + } + } + for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next) { + if(!lstrcmpiW(*rgszNames, pVDesc->Name)) { + if(cNames) *pMemId=pVDesc->vardesc.memid; + return ret; + } + } + /* not found, see if this is and interface with an inheritance */ + if(This->TypeAttr.cImplTypes && + (This->TypeAttr.typekind==TKIND_INTERFACE || This->TypeAttr.typekind==TKIND_DISPATCH)) { + /* recursive search */ + ITypeInfo *pTInfo; + ret=ITypeInfo_GetRefTypeInfo(iface, + This->impltypelist->hRef, &pTInfo); + if(SUCCEEDED(ret)){ + ret=ITypeInfo_GetIDsOfNames(pTInfo, rgszNames, cNames, pMemId ); + ITypeInfo_Release(pTInfo); + return ret; + } + WARN("Could not search inherited interface!\n"); + } else + WARN("no names found\n"); + return DISP_E_UNKNOWNNAME; +} + +/* ITypeInfo::Invoke + * + * Invokes a method, or accesses a property of an object, that implements the + * interface described by the type description. + */ +DWORD +_invoke(FARPROC func,CALLCONV callconv, int nrargs, DWORD *args) { + DWORD res; + + if (TRACE_ON(ole)) { + int i; + TRACE("Calling %p(",func); + for (i=0;iu.lptdesc->vt == VT_VARIANT)) { + memcpy(argpos,&arg,sizeof(void*)); + return S_OK; + } + + if (V_VT(arg) == vt) { + memcpy(argpos, &V_UNION(arg,lVal), arglen); + return S_OK; + } + + if (V_ISARRAY(arg) && (vt == VT_SAFEARRAY)) { + memcpy(argpos, &V_UNION(arg,parray), sizeof(SAFEARRAY*)); + return S_OK; + } + + if (vt == VT_VARIANT) { + memcpy(argpos, arg, arglen); + return S_OK; + } + /* Deref BYREF vars if there is need */ + if(V_ISBYREF(arg) && ((V_VT(arg) & ~VT_BYREF)==vt)) { + memcpy(argpos,(void*)V_UNION(arg,lVal), arglen); + return S_OK; + } + if (vt==VT_UNKNOWN && V_VT(arg)==VT_DISPATCH) { + /* in this context, if the type lib specifies IUnknown*, giving an + IDispatch* is correct; so, don't invoke VariantChangeType */ + memcpy(argpos,&V_UNION(arg,lVal), arglen); + return S_OK; + } + if ((vt == VT_PTR) && tdesc) + return _copy_arg(tinfo, tdesc->u.lptdesc, argpos, arg, tdesc->u.lptdesc->vt); + + if ((vt == VT_USERDEFINED) && tdesc && tinfo) { + ITypeInfo *tinfo2 = NULL; + TYPEATTR *tattr = NULL; + HRESULT hres; + + hres = ITypeInfo_GetRefTypeInfo(tinfo,tdesc->u.hreftype,&tinfo2); + if (hres) { + FIXME("Could not get typeinfo of hreftype %lx for VT_USERDEFINED, " + "while coercing from vt 0x%x. Copying 4 byte.\n", + tdesc->u.hreftype,V_VT(arg)); + memcpy(argpos, &V_UNION(arg,lVal), 4); + return S_OK; + } + hres = ITypeInfo_GetTypeAttr(tinfo2,&tattr); + if( hres ) + { + ERR("GetTypeAttr failed\n"); + ITypeInfo_Release(tinfo2); + return hres; + } + switch (tattr->typekind) { + case TKIND_ENUM: + switch ( V_VT( arg ) ) { + case VT_I2: + *argpos = V_UNION(arg,iVal); + hres = S_OK; + break; + case VT_I4: + memcpy(argpos, &V_UNION(arg,lVal), 4); + hres = S_OK; + break; + default: + FIXME("vt 0x%x -> TKIND_ENUM unhandled.\n",V_VT(arg)); + hres = E_FAIL; + break; + } + break; + + case TKIND_ALIAS: + tdesc = &(tattr->tdescAlias); + hres = _copy_arg((ITypeInfo2*)tinfo2, tdesc, argpos, arg, tdesc->vt); + break; + + case TKIND_INTERFACE: + if (V_VT(arg) == VT_DISPATCH) { + IDispatch *disp; + if (IsEqualIID(&IID_IDispatch,&(tattr->guid))) { + memcpy(argpos, &V_UNION(arg,pdispVal), 4); + hres = S_OK; + break; + } + hres=IUnknown_QueryInterface(V_UNION(arg,pdispVal), + &IID_IDispatch,(LPVOID*)&disp); + if (SUCCEEDED(hres)) { + memcpy(argpos,&disp,4); + IUnknown_Release(V_UNION(arg,pdispVal)); + hres = S_OK; + break; + } + FIXME("Failed to query IDispatch interface from %s while " + "converting to VT_DISPATCH!\n",debugstr_guid(&(tattr->guid))); + hres = E_FAIL; + break; + } + if (V_VT(arg) == VT_UNKNOWN) { + memcpy(argpos, &V_UNION(arg,punkVal), 4); + hres = S_OK; + break; + } + FIXME("vt 0x%x -> TKIND_INTERFACE(%s) unhandled\n", + V_VT(arg),debugstr_guid(&(tattr->guid))); + hres = E_FAIL; + break; + + case TKIND_DISPATCH: + if (V_VT(arg) == VT_DISPATCH) { + memcpy(argpos, &V_UNION(arg,pdispVal), 4); + hres = S_OK; + } + else { + hres = E_FAIL; + FIXME("TKIND_DISPATCH unhandled for target vt 0x%x.\n",V_VT(arg)); + } + break; + case TKIND_RECORD: + FIXME("TKIND_RECORD unhandled.\n"); + hres = E_FAIL; + break; + default: + FIXME("TKIND %d unhandled.\n",tattr->typekind); + hres = E_FAIL; + break; + } + ITypeInfo_ReleaseTypeAttr(tinfo2, tattr); + ITypeInfo_Release(tinfo2); + return hres; + } + + oldvt = V_VT(arg); + VariantInit(&va); + if (VariantChangeType(&va,arg,0,vt)==S_OK) { + memcpy(argpos,&V_UNION(&va,lVal), arglen); + FIXME("Should not use VariantChangeType here." + " (conversion from 0x%x -> 0x%x) %08lx\n", + V_VT(arg), vt, *argpos + ); + return S_OK; + } + ERR("Set arg to disparg type 0x%x vs 0x%x\n",V_VT(arg),vt); + return E_FAIL; +} + +/*********************************************************************** + * DispCallFunc (OLEAUT32.@) + */ +HRESULT WINAPI +DispCallFunc( + void* pvInstance, ULONG oVft, CALLCONV cc, VARTYPE vtReturn, UINT cActuals, + VARTYPE* prgvt, VARIANTARG** prgpvarg, VARIANT* pvargResult +) { + int i, argsize, argspos; + DWORD *args; + HRESULT hres; + + TRACE("(%p, %ld, %d, %d, %d, %p, %p, %p (vt=%d))\n", + pvInstance, oVft, cc, vtReturn, cActuals, prgvt, prgpvarg, pvargResult, V_VT(pvargResult) + ); + /* DispCallFunc is only used to invoke methods belonging to an IDispatch-derived COM interface. + So we need to add a first parameter to the list of arguments, to supply the interface pointer */ + argsize = 1; + for (i=0;ifunclist; pFDesc; pFDesc=pFDesc->next) + if (pFDesc->funcdesc.memid == memid) { + if (pFDesc->funcdesc.invkind & dwFlags) + break; + } + + if (pFDesc) { + if (TRACE_ON(typelib)) dump_TLBFuncDescOne(pFDesc); + /* dump_FUNCDESC(&pFDesc->funcdesc);*/ + switch (pFDesc->funcdesc.funckind) { + case FUNC_PUREVIRTUAL: + case FUNC_VIRTUAL: { + DWORD res; + int numargs, numargs2, argspos, args2pos; + DWORD *args , *args2; + VARIANT *rgvarg = HeapAlloc(GetProcessHeap(),0,sizeof(VARIANT)*pFDesc->funcdesc.cParams); + memcpy(rgvarg,pDispParams->rgvarg,sizeof(VARIANT)*pDispParams->cArgs); + + numargs = 1; numargs2 = 0; + for (i=0;ifuncdesc.cParams;i++) { + if (icArgs) + numargs += _argsize(pFDesc->funcdesc.lprgelemdescParam[i].tdesc.vt); + else { + numargs += 1; /* sizeof(lpvoid) */ + numargs2 += _argsize(pFDesc->funcdesc.lprgelemdescParam[i].tdesc.vt); + } + } + + args = (DWORD*)HeapAlloc(GetProcessHeap(),0,sizeof(DWORD)*numargs); + args2 = (DWORD*)HeapAlloc(GetProcessHeap(),0,sizeof(DWORD)*numargs2); + + args[0] = (DWORD)pIUnk; + argspos = 1; args2pos = 0; + for (i=0;ifuncdesc.cParams;i++) { + int arglen = _argsize(pFDesc->funcdesc.lprgelemdescParam[i].tdesc.vt); + if (icArgs) { + VARIANT *arg = &rgvarg[pDispParams->cArgs-i-1]; + TYPEDESC *tdesc = &pFDesc->funcdesc.lprgelemdescParam[i].tdesc; + USHORT paramFlags = pFDesc->funcdesc.lprgelemdescParam[i].u.paramdesc.wParamFlags; + if (paramFlags & PARAMFLAG_FOPT) { + if(i < pFDesc->funcdesc.cParams-pFDesc->funcdesc.cParamsOpt) + ERR("Parameter has PARAMFLAG_FOPT flag but is not one of last cParamOpt parameters\n"); + if(V_VT(arg) == VT_EMPTY + || ((V_VT(arg) & VT_BYREF) && !V_BYREF(arg))) { + /* FIXME: Documentation says that we do this when parameter is left unspecified. + How to determine it? */ + + if(paramFlags & PARAMFLAG_FHASDEFAULT) + FIXME("PARAMFLAG_FHASDEFAULT flag not supported\n"); + V_VT(arg) = VT_ERROR; + V_ERROR(arg) = DISP_E_PARAMNOTFOUND; + arglen = _argsize(VT_ERROR); + } + } + hres = _copy_arg(iface, tdesc, &args[argspos], arg, tdesc->vt); + if (FAILED(hres)) return hres; + argspos += arglen; + } else if(pFDesc->funcdesc.lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FOPT) { + VARIANT *arg = &rgvarg[i]; + TYPEDESC *tdesc = &pFDesc->funcdesc.lprgelemdescParam[i].tdesc; + if(i < pFDesc->funcdesc.cParams-pFDesc->funcdesc.cParamsOpt) + ERR("Parameter has PARAMFLAG_FOPT flag but is not one of last cParamOpt parameters\n"); + if(pFDesc->funcdesc.lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT) + FIXME("PARAMFLAG_FHASDEFAULT flag not supported\n"); + V_VT(arg) = VT_ERROR; + V_ERROR(arg) = DISP_E_PARAMNOTFOUND; + arglen = _argsize(VT_ERROR); + hres = _copy_arg(iface, tdesc, &args[argspos], arg, tdesc->vt); + if (FAILED(hres)) return hres; + argspos += arglen; + } else { + TYPEDESC *tdesc = &(pFDesc->funcdesc.lprgelemdescParam[i].tdesc); + if (tdesc->vt != VT_PTR) + FIXME("set %d to pointer for get (type is %d)\n",i,tdesc->vt); + /*FIXME: give pointers for the rest, so propertyget works*/ + args[argspos] = (DWORD)&args2[args2pos]; + + /* If pointer to variant, pass reference it. */ + if ((tdesc->vt == VT_PTR) && + (tdesc->u.lptdesc->vt == VT_VARIANT) && + pVarResult + ) + args[argspos]= (DWORD)pVarResult; + argspos += 1; + args2pos += arglen; + } + } + if (pFDesc->funcdesc.cParamsOpt < 0) + FIXME("Does not support optional parameters (%d)\n", + pFDesc->funcdesc.cParamsOpt + ); + + res = _invoke((*(FARPROC**)pIUnk)[pFDesc->funcdesc.oVft/4], + pFDesc->funcdesc.callconv, + numargs, + args + ); + + HeapFree(GetProcessHeap(), 0, rgvarg); + + if (pVarResult && (dwFlags & (DISPATCH_PROPERTYGET))) { + args2pos = 0; + for (i=0;ifuncdesc.cParams-pDispParams->cArgs;i++) { + int arglen = _argsize(pFDesc->funcdesc.lprgelemdescParam[i].tdesc.vt); + TYPEDESC *tdesc = &(pFDesc->funcdesc.lprgelemdescParam[i+pDispParams->cArgs].tdesc); + TYPEDESC i4_tdesc; + i4_tdesc.vt = VT_I4; + + /* If we are a pointer to a variant, we are done already */ + if ((tdesc->vt==VT_PTR)&&(tdesc->u.lptdesc->vt==VT_VARIANT)) + continue; + + VariantInit(pVarResult); + memcpy(&V_UNION(pVarResult,intVal),&args2[args2pos],arglen*sizeof(DWORD)); + + if (tdesc->vt == VT_PTR) + tdesc = tdesc->u.lptdesc; + if (tdesc->vt == VT_USERDEFINED) { + ITypeInfo *tinfo2; + TYPEATTR *tattr; + + hres = ITypeInfo_GetRefTypeInfo(iface,tdesc->u.hreftype,&tinfo2); + if (hres) { + FIXME("Could not get typeinfo of hreftype %lx for VT_USERDEFINED, while coercing. Copying 4 byte.\n",tdesc->u.hreftype); + return E_FAIL; + } + ITypeInfo_GetTypeAttr(tinfo2,&tattr); + switch (tattr->typekind) { + case TKIND_ENUM: + /* force the return type to be VT_I4 */ + tdesc = &i4_tdesc; + break; + case TKIND_ALIAS: + TRACE("TKIND_ALIAS to vt 0x%x\n",tattr->tdescAlias.vt); + tdesc = &(tattr->tdescAlias); + break; + + case TKIND_INTERFACE: + FIXME("TKIND_INTERFACE unhandled.\n"); + break; + case TKIND_DISPATCH: + FIXME("TKIND_DISPATCH unhandled.\n"); + break; + case TKIND_RECORD: + FIXME("TKIND_RECORD unhandled.\n"); + break; + default: + FIXME("TKIND %d unhandled.\n",tattr->typekind); + break; + } + ITypeInfo_Release(tinfo2); + } + V_VT(pVarResult) = tdesc->vt; + + /* HACK: VB5 likes this. + * I do not know why. There is 1 example in MSDN which uses + * this which appears broken (mixes int vals and + * IDispatch*.). + */ + if ((tdesc->vt == VT_PTR) && (dwFlags & DISPATCH_METHOD)) + V_VT(pVarResult) = VT_DISPATCH; + TRACE("storing into variant:\n"); + dump_Variant(pVarResult); + args2pos += arglen; + } + } + HeapFree(GetProcessHeap(),0,args2); + HeapFree(GetProcessHeap(),0,args); + return S_OK; + } + case FUNC_DISPATCH: { + IDispatch *disp; + HRESULT hr; + + hr = IUnknown_QueryInterface((LPUNKNOWN)pIUnk,&IID_IDispatch,(LPVOID*)&disp); + if (hr) { + FIXME("FUNC_DISPATCH used on object without IDispatch iface?\n"); + return hr; + } + FIXME("Calling Invoke in IDispatch iface. untested!\n"); + hr = IDispatch_Invoke( + disp,memid,&IID_NULL,LOCALE_USER_DEFAULT,dwFlags,pDispParams, + pVarResult,pExcepInfo,pArgErr + ); + if (hr) + FIXME("IDispatch::Invoke failed with %08lx. (Could be not a real error?)\n",hr); + IDispatch_Release(disp); + return hr; + } + default: + FIXME("Unknown function invocation type %d\n",pFDesc->funcdesc.funckind); + return E_FAIL; + } + } else { + for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next) { + if (pVDesc->vardesc.memid == memid) { + FIXME("varseek: Found memid name %s, but variable-based invoking not supported\n",debugstr_w(((LPWSTR)pVDesc->Name))); + dump_TLBVarDesc(pVDesc); + break; + } + } + } + /* not found, look for it in inherited interfaces */ + if (This->TypeAttr.cImplTypes && + (This->TypeAttr.typekind==TKIND_INTERFACE || This->TypeAttr.typekind==TKIND_DISPATCH)) { + /* recursive search */ + ITypeInfo *pTInfo; + HRESULT hr; + hr=ITypeInfo_GetRefTypeInfo(iface, This->impltypelist->hRef, &pTInfo); + if(SUCCEEDED(hr)){ + hr=ITypeInfo_Invoke(pTInfo,pIUnk,memid,dwFlags,pDispParams,pVarResult,pExcepInfo,pArgErr); + ITypeInfo_Release(pTInfo); + return hr; + } + WARN("Could not search inherited interface!\n"); + } + ERR("did not find member id %d, flags %d!\n", (int)memid, dwFlags); + return DISP_E_MEMBERNOTFOUND; +} + +/* ITypeInfo::GetDocumentation + * + * Retrieves the documentation string, the complete Help file name and path, + * and the context ID for the Help topic for a specified type description. + * + * (Can be tested by the Visual Basic Editor in Word for instance.) + */ +static HRESULT WINAPI ITypeInfo_fnGetDocumentation( ITypeInfo2 *iface, + MEMBERID memid, BSTR *pBstrName, BSTR *pBstrDocString, + DWORD *pdwHelpContext, BSTR *pBstrHelpFile) +{ + ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + TLBFuncDesc * pFDesc; + TLBVarDesc * pVDesc; + TRACE("(%p) memid %ld Name(%p) DocString(%p)" + " HelpContext(%p) HelpFile(%p)\n", + This, memid, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile); + if(memid==MEMBERID_NIL){ /* documentation for the typeinfo */ + if(pBstrName) + *pBstrName=SysAllocString(This->Name); + if(pBstrDocString) + *pBstrDocString=SysAllocString(This->DocString); + if(pdwHelpContext) + *pdwHelpContext=This->dwHelpContext; + if(pBstrHelpFile) + *pBstrHelpFile=SysAllocString(This->DocString);/* FIXME */ + return S_OK; + }else {/* for a member */ + for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next) + if(pFDesc->funcdesc.memid==memid){ + if(pBstrName) + *pBstrName = SysAllocString(pFDesc->Name); + if(pBstrDocString) + *pBstrDocString=SysAllocString(pFDesc->HelpString); + if(pdwHelpContext) + *pdwHelpContext=pFDesc->helpcontext; + return S_OK; + } + for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next) + if(pVDesc->vardesc.memid==memid){ + if(pBstrName) + *pBstrName = SysAllocString(pVDesc->Name); + if(pBstrDocString) + *pBstrDocString=SysAllocString(pVDesc->HelpString); + if(pdwHelpContext) + *pdwHelpContext=pVDesc->HelpContext; + return S_OK; + } + } + return TYPE_E_ELEMENTNOTFOUND; +} + +/* ITypeInfo::GetDllEntry + * + * Retrieves a description or specification of an entry point for a function + * in a DLL. + */ +static HRESULT WINAPI ITypeInfo_fnGetDllEntry( ITypeInfo2 *iface, MEMBERID memid, + INVOKEKIND invKind, BSTR *pBstrDllName, BSTR *pBstrName, + WORD *pwOrdinal) +{ + ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + TLBFuncDesc *pFDesc; + + FIXME("(%p, memid %lx, %d, %p, %p, %p), partial stub!\n", This, memid, invKind, pBstrDllName, pBstrName, pwOrdinal); + + for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next) + if(pFDesc->funcdesc.memid==memid){ + dump_TypeInfo(This); + dump_TLBFuncDescOne(pFDesc); + + /* FIXME: This is wrong, but how do you find that out? */ + if (pBstrDllName) { + static const WCHAR oleaut32W[] = {'O','L','E','A','U','T','3','2','.','D','L','L',0}; + *pBstrDllName = SysAllocString(oleaut32W); + } + + if (HIWORD(pFDesc->Entry) && (pFDesc->Entry != (void*)-1)) { + if (pBstrName) + *pBstrName = SysAllocString(pFDesc->Entry); + if (pwOrdinal) + *pwOrdinal = -1; + return S_OK; + } + if (pBstrName) + *pBstrName = NULL; + if (pwOrdinal) + *pwOrdinal = (DWORD)pFDesc->Entry; + return S_OK; + } + return E_FAIL; +} + +/* ITypeInfo::GetRefTypeInfo + * + * If a type description references other type descriptions, it retrieves + * the referenced type descriptions. + */ +static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo( + ITypeInfo2 *iface, + HREFTYPE hRefType, + ITypeInfo **ppTInfo) +{ + ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + HRESULT result = E_FAIL; + + + if (hRefType == -1 && + (((ITypeInfoImpl*) This)->TypeAttr.typekind == TKIND_DISPATCH) && + (((ITypeInfoImpl*) This)->TypeAttr.wTypeFlags & TYPEFLAG_FDUAL)) + { + /* when we meet a DUAL dispinterface, we must create the interface + * version of it. + */ + ITypeInfoImpl* pTypeInfoImpl = (ITypeInfoImpl*) ITypeInfo_Constructor(); + + + /* the interface version contains the same information as the dispinterface + * copy the contents of the structs. + */ + *pTypeInfoImpl = *This; + pTypeInfoImpl->ref = 1; + + /* change the type to interface */ + pTypeInfoImpl->TypeAttr.typekind = TKIND_INTERFACE; + + *ppTInfo = (ITypeInfo*) pTypeInfoImpl; + + ITypeInfo_AddRef((ITypeInfo*) pTypeInfoImpl); + + result = S_OK; + + } else { + TLBRefType *pRefType; + for(pRefType = This->reflist; pRefType; pRefType = pRefType->next) { + if(pRefType->reference == hRefType) + break; + } + if(!pRefType) + FIXME("Can't find pRefType for ref %lx\n", hRefType); + if(pRefType && hRefType != -1) { + ITypeLib *pTLib = NULL; + + if(pRefType->pImpTLInfo == TLB_REF_INTERNAL) { + int Index; + result = ITypeInfo_GetContainingTypeLib(iface, &pTLib, &Index); + } else { + if(pRefType->pImpTLInfo->pImpTypeLib) { + TRACE("typeinfo in imported typelib that is already loaded\n"); + pTLib = (ITypeLib*)pRefType->pImpTLInfo->pImpTypeLib; + ITypeLib2_AddRef((ITypeLib*) pTLib); + result = S_OK; + } else { + TRACE("typeinfo in imported typelib that isn't already loaded\n"); + result = LoadRegTypeLib( &pRefType->pImpTLInfo->guid, + pRefType->pImpTLInfo->wVersionMajor, + pRefType->pImpTLInfo->wVersionMinor, + pRefType->pImpTLInfo->lcid, + &pTLib); + + if(!SUCCEEDED(result)) { + BSTR libnam=SysAllocString(pRefType->pImpTLInfo->name); + result=LoadTypeLib(libnam, &pTLib); + SysFreeString(libnam); + } + if(SUCCEEDED(result)) { + pRefType->pImpTLInfo->pImpTypeLib = (ITypeLibImpl*)pTLib; + ITypeLib2_AddRef(pTLib); + } + } + } + if(SUCCEEDED(result)) { + if(pRefType->index == TLB_REF_USE_GUID) + result = ITypeLib2_GetTypeInfoOfGuid(pTLib, + &pRefType->guid, + ppTInfo); + else + result = ITypeLib2_GetTypeInfo(pTLib, pRefType->index, + ppTInfo); + } + if (pTLib != NULL) + ITypeLib2_Release(pTLib); + } + } + + TRACE("(%p) hreftype 0x%04lx loaded %s (%p)\n", This, hRefType, + SUCCEEDED(result)? "SUCCESS":"FAILURE", *ppTInfo); + return result; +} + +/* ITypeInfo::AddressOfMember + * + * Retrieves the addresses of static functions or variables, such as those + * defined in a DLL. + */ +static HRESULT WINAPI ITypeInfo_fnAddressOfMember( ITypeInfo2 *iface, + MEMBERID memid, INVOKEKIND invKind, PVOID *ppv) +{ + ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + FIXME("(%p) stub!\n", This); + return S_OK; +} + +/* ITypeInfo::CreateInstance + * + * Creates a new instance of a type that describes a component object class + * (coclass). + */ +static HRESULT WINAPI ITypeInfo_fnCreateInstance( ITypeInfo2 *iface, + IUnknown *pUnk, REFIID riid, VOID **ppvObj) +{ + ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + FIXME("(%p) stub!\n", This); + return S_OK; +} + +/* ITypeInfo::GetMops + * + * Retrieves marshalling information. + */ +static HRESULT WINAPI ITypeInfo_fnGetMops( ITypeInfo2 *iface, MEMBERID memid, + BSTR *pBstrMops) +{ + ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + FIXME("(%p) stub!\n", This); + return S_OK; +} + +/* ITypeInfo::GetContainingTypeLib + * + * Retrieves the containing type library and the index of the type description + * within that type library. + */ +static HRESULT WINAPI ITypeInfo_fnGetContainingTypeLib( ITypeInfo2 *iface, + ITypeLib * *ppTLib, UINT *pIndex) +{ + ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + + /* If a pointer is null, we simply ignore it, the ATL in particular passes pIndex as 0 */ + if (pIndex) { + *pIndex=This->index; + TRACE("returning pIndex=%d\n", *pIndex); + } + + if (ppTLib) { + *ppTLib=(LPTYPELIB )(This->pTypeLib); + ITypeLib2_AddRef(*ppTLib); + TRACE("returning ppTLib=%p\n", *ppTLib); + } + + return S_OK; +} + +/* ITypeInfo::ReleaseTypeAttr + * + * Releases a TYPEATTR previously returned by GetTypeAttr. + * + */ +static void WINAPI ITypeInfo_fnReleaseTypeAttr( ITypeInfo2 *iface, + TYPEATTR* pTypeAttr) +{ + ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + TRACE("(%p)->(%p)\n", This, pTypeAttr); +} + +/* ITypeInfo::ReleaseFuncDesc + * + * Releases a FUNCDESC previously returned by GetFuncDesc. * + */ +static void WINAPI ITypeInfo_fnReleaseFuncDesc( + ITypeInfo2 *iface, + FUNCDESC *pFuncDesc) +{ + ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + TRACE("(%p)->(%p)\n", This, pFuncDesc); +} + +/* ITypeInfo::ReleaseVarDesc + * + * Releases a VARDESC previously returned by GetVarDesc. + */ +static void WINAPI ITypeInfo_fnReleaseVarDesc( ITypeInfo2 *iface, + VARDESC *pVarDesc) +{ + ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + TRACE("(%p)->(%p)\n", This, pVarDesc); +} + +/* ITypeInfo2::GetTypeKind + * + * Returns the TYPEKIND enumeration quickly, without doing any allocations. + * + */ +static HRESULT WINAPI ITypeInfo2_fnGetTypeKind( ITypeInfo2 * iface, + TYPEKIND *pTypeKind) +{ + ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + *pTypeKind=This->TypeAttr.typekind; + TRACE("(%p) type 0x%0x\n", This,*pTypeKind); + return S_OK; +} + +/* ITypeInfo2::GetTypeFlags + * + * Returns the type flags without any allocations. This returns a DWORD type + * flag, which expands the type flags without growing the TYPEATTR (type + * attribute). + * + */ +static HRESULT WINAPI ITypeInfo2_fnGetTypeFlags( ITypeInfo2 *iface, ULONG *pTypeFlags) +{ + ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + *pTypeFlags=This->TypeAttr.wTypeFlags; + TRACE("(%p) flags 0x%lx\n", This,*pTypeFlags); + return S_OK; +} + +/* ITypeInfo2::GetFuncIndexOfMemId + * Binds to a specific member based on a known DISPID, where the member name + * is not known (for example, when binding to a default member). + * + */ +static HRESULT WINAPI ITypeInfo2_fnGetFuncIndexOfMemId( ITypeInfo2 * iface, + MEMBERID memid, INVOKEKIND invKind, UINT *pFuncIndex) +{ + ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + TLBFuncDesc *pFuncInfo; + int i; + HRESULT result; + /* FIXME: should check for invKind??? */ + for(i=0, pFuncInfo=This->funclist;pFuncInfo && + memid != pFuncInfo->funcdesc.memid; i++, pFuncInfo=pFuncInfo->next); + if(pFuncInfo){ + *pFuncIndex=i; + result= S_OK; + }else{ + *pFuncIndex=0; + result=E_INVALIDARG; + } + TRACE("(%p) memid 0x%08lx invKind 0x%04x -> %s\n", This, + memid, invKind, SUCCEEDED(result)? "SUCCES":"FAILED"); + return result; +} + +/* TypeInfo2::GetVarIndexOfMemId + * + * Binds to a specific member based on a known DISPID, where the member name + * is not known (for example, when binding to a default member). + * + */ +static HRESULT WINAPI ITypeInfo2_fnGetVarIndexOfMemId( ITypeInfo2 * iface, + MEMBERID memid, UINT *pVarIndex) +{ + ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + TLBVarDesc *pVarInfo; + int i; + HRESULT result; + for(i=0, pVarInfo=This->varlist; pVarInfo && + memid != pVarInfo->vardesc.memid; i++, pVarInfo=pVarInfo->next) + ; + if(pVarInfo){ + *pVarIndex=i; + result= S_OK; + }else{ + *pVarIndex=0; + result=E_INVALIDARG; + } + TRACE("(%p) memid 0x%08lx -> %s\n", This, + memid, SUCCEEDED(result)? "SUCCES":"FAILED"); + return result; +} + +/* ITypeInfo2::GetCustData + * + * Gets the custom data + */ +static HRESULT WINAPI ITypeInfo2_fnGetCustData( + ITypeInfo2 * iface, + REFGUID guid, + VARIANT *pVarVal) +{ + ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + TLBCustData *pCData; + + for(pCData=This->pCustData; pCData; pCData = pCData->next) + if( IsEqualIID(guid, &pCData->guid)) break; + + TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT"); + + if(pCData) + { + VariantInit( pVarVal); + VariantCopy( pVarVal, &pCData->data); + return S_OK; + } + return E_INVALIDARG; /* FIXME: correct? */ +} + +/* ITypeInfo2::GetFuncCustData + * + * Gets the custom data + */ +static HRESULT WINAPI ITypeInfo2_fnGetFuncCustData( + ITypeInfo2 * iface, + UINT index, + REFGUID guid, + VARIANT *pVarVal) +{ + ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + TLBCustData *pCData=NULL; + TLBFuncDesc * pFDesc; + int i; + for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++, + pFDesc=pFDesc->next); + + if(pFDesc) + for(pCData=pFDesc->pCustData; pCData; pCData = pCData->next) + if( IsEqualIID(guid, &pCData->guid)) break; + + TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT"); + + if(pCData){ + VariantInit( pVarVal); + VariantCopy( pVarVal, &pCData->data); + return S_OK; + } + return E_INVALIDARG; /* FIXME: correct? */ +} + +/* ITypeInfo2::GetParamCustData + * + * Gets the custom data + */ +static HRESULT WINAPI ITypeInfo2_fnGetParamCustData( + ITypeInfo2 * iface, + UINT indexFunc, + UINT indexParam, + REFGUID guid, + VARIANT *pVarVal) +{ + ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + TLBCustData *pCData=NULL; + TLBFuncDesc * pFDesc; + int i; + + for(i=0, pFDesc=This->funclist; i!=indexFunc && pFDesc; i++,pFDesc=pFDesc->next); + + if(pFDesc && indexParam >=0 && indexParamfuncdesc.cParams) + for(pCData=pFDesc->pParamDesc[indexParam].pCustData; pCData; + pCData = pCData->next) + if( IsEqualIID(guid, &pCData->guid)) break; + + TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT"); + + if(pCData) + { + VariantInit( pVarVal); + VariantCopy( pVarVal, &pCData->data); + return S_OK; + } + return E_INVALIDARG; /* FIXME: correct? */ +} + +/* ITypeInfo2::GetVarCustData + * + * Gets the custom data + */ +static HRESULT WINAPI ITypeInfo2_fnGetVarCustData( + ITypeInfo2 * iface, + UINT index, + REFGUID guid, + VARIANT *pVarVal) +{ + ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + TLBCustData *pCData=NULL; + TLBVarDesc * pVDesc; + int i; + + for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++, pVDesc=pVDesc->next); + + if(pVDesc) + { + for(pCData=pVDesc->pCustData; pCData; pCData = pCData->next) + { + if( IsEqualIID(guid, &pCData->guid)) break; + } + } + + TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT"); + + if(pCData) + { + VariantInit( pVarVal); + VariantCopy( pVarVal, &pCData->data); + return S_OK; + } + return E_INVALIDARG; /* FIXME: correct? */ +} + +/* ITypeInfo2::GetImplCustData + * + * Gets the custom data + */ +static HRESULT WINAPI ITypeInfo2_fnGetImplTypeCustData( + ITypeInfo2 * iface, + UINT index, + REFGUID guid, + VARIANT *pVarVal) +{ + ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + TLBCustData *pCData=NULL; + TLBImplType * pRDesc; + int i; + + for(i=0, pRDesc=This->impltypelist; i!=index && pRDesc; i++, pRDesc=pRDesc->next); + + if(pRDesc) + { + for(pCData=pRDesc->pCustData; pCData; pCData = pCData->next) + { + if( IsEqualIID(guid, &pCData->guid)) break; + } + } + + TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT"); + + if(pCData) + { + VariantInit( pVarVal); + VariantCopy( pVarVal, &pCData->data); + return S_OK; + } + return E_INVALIDARG; /* FIXME: correct? */ +} + +/* ITypeInfo2::GetDocumentation2 + * + * Retrieves the documentation string, the complete Help file name and path, + * the localization context to use, and the context ID for the library Help + * topic in the Help file. + * + */ +static HRESULT WINAPI ITypeInfo2_fnGetDocumentation2( + ITypeInfo2 * iface, + MEMBERID memid, + LCID lcid, + BSTR *pbstrHelpString, + DWORD *pdwHelpStringContext, + BSTR *pbstrHelpStringDll) +{ + ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + TLBFuncDesc * pFDesc; + TLBVarDesc * pVDesc; + TRACE("(%p) memid %ld lcid(0x%lx) HelpString(%p) " + "HelpStringContext(%p) HelpStringDll(%p)\n", + This, memid, lcid, pbstrHelpString, pdwHelpStringContext, + pbstrHelpStringDll ); + /* the help string should be obtained from the helpstringdll, + * using the _DLLGetDocumentation function, based on the supplied + * lcid. Nice to do sometime... + */ + if(memid==MEMBERID_NIL){ /* documentation for the typeinfo */ + if(pbstrHelpString) + *pbstrHelpString=SysAllocString(This->Name); + if(pdwHelpStringContext) + *pdwHelpStringContext=This->dwHelpStringContext; + if(pbstrHelpStringDll) + *pbstrHelpStringDll= + SysAllocString(This->pTypeLib->HelpStringDll);/* FIXME */ + return S_OK; + }else {/* for a member */ + for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next) + if(pFDesc->funcdesc.memid==memid){ + if(pbstrHelpString) + *pbstrHelpString=SysAllocString(pFDesc->HelpString); + if(pdwHelpStringContext) + *pdwHelpStringContext=pFDesc->HelpStringContext; + if(pbstrHelpStringDll) + *pbstrHelpStringDll= + SysAllocString(This->pTypeLib->HelpStringDll);/* FIXME */ + return S_OK; + } + for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next) + if(pVDesc->vardesc.memid==memid){ + if(pbstrHelpString) + *pbstrHelpString=SysAllocString(pVDesc->HelpString); + if(pdwHelpStringContext) + *pdwHelpStringContext=pVDesc->HelpStringContext; + if(pbstrHelpStringDll) + *pbstrHelpStringDll= + SysAllocString(This->pTypeLib->HelpStringDll);/* FIXME */ + return S_OK; + } + } + return TYPE_E_ELEMENTNOTFOUND; +} + +/* ITypeInfo2::GetAllCustData + * + * Gets all custom data items for the Type info. + * + */ +static HRESULT WINAPI ITypeInfo2_fnGetAllCustData( + ITypeInfo2 * iface, + CUSTDATA *pCustData) +{ + ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + TLBCustData *pCData; + int i; + + TRACE("(%p) returning %d items\n", This, This->ctCustData); + + pCustData->prgCustData = TLB_Alloc(This->ctCustData * sizeof(CUSTDATAITEM)); + if(pCustData->prgCustData ){ + pCustData->cCustData=This->ctCustData; + for(i=0, pCData=This->pCustData; pCData; i++, pCData = pCData->next){ + pCustData->prgCustData[i].guid=pCData->guid; + VariantCopy(& pCustData->prgCustData[i].varValue, & pCData->data); + } + }else{ + ERR(" OUT OF MEMORY! \n"); + return E_OUTOFMEMORY; + } + return S_OK; +} + +/* ITypeInfo2::GetAllFuncCustData + * + * Gets all custom data items for the specified Function + * + */ +static HRESULT WINAPI ITypeInfo2_fnGetAllFuncCustData( + ITypeInfo2 * iface, + UINT index, + CUSTDATA *pCustData) +{ + ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + TLBCustData *pCData; + TLBFuncDesc * pFDesc; + int i; + TRACE("(%p) index %d\n", This, index); + for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++, + pFDesc=pFDesc->next) + ; + if(pFDesc){ + pCustData->prgCustData = + TLB_Alloc(pFDesc->ctCustData * sizeof(CUSTDATAITEM)); + if(pCustData->prgCustData ){ + pCustData->cCustData=pFDesc->ctCustData; + for(i=0, pCData=pFDesc->pCustData; pCData; i++, + pCData = pCData->next){ + pCustData->prgCustData[i].guid=pCData->guid; + VariantCopy(& pCustData->prgCustData[i].varValue, + & pCData->data); + } + }else{ + ERR(" OUT OF MEMORY! \n"); + return E_OUTOFMEMORY; + } + return S_OK; + } + return TYPE_E_ELEMENTNOTFOUND; +} + +/* ITypeInfo2::GetAllParamCustData + * + * Gets all custom data items for the Functions + * + */ +static HRESULT WINAPI ITypeInfo2_fnGetAllParamCustData( ITypeInfo2 * iface, + UINT indexFunc, UINT indexParam, CUSTDATA *pCustData) +{ + ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + TLBCustData *pCData=NULL; + TLBFuncDesc * pFDesc; + int i; + TRACE("(%p) index %d\n", This, indexFunc); + for(i=0, pFDesc=This->funclist; i!=indexFunc && pFDesc; i++, + pFDesc=pFDesc->next) + ; + if(pFDesc && indexParam >=0 && indexParamfuncdesc.cParams){ + pCustData->prgCustData = + TLB_Alloc(pFDesc->pParamDesc[indexParam].ctCustData * + sizeof(CUSTDATAITEM)); + if(pCustData->prgCustData ){ + pCustData->cCustData=pFDesc->pParamDesc[indexParam].ctCustData; + for(i=0, pCData=pFDesc->pParamDesc[indexParam].pCustData; + pCData; i++, pCData = pCData->next){ + pCustData->prgCustData[i].guid=pCData->guid; + VariantCopy(& pCustData->prgCustData[i].varValue, + & pCData->data); + } + }else{ + ERR(" OUT OF MEMORY! \n"); + return E_OUTOFMEMORY; + } + return S_OK; + } + return TYPE_E_ELEMENTNOTFOUND; +} + +/* ITypeInfo2::GetAllVarCustData + * + * Gets all custom data items for the specified Variable + * + */ +static HRESULT WINAPI ITypeInfo2_fnGetAllVarCustData( ITypeInfo2 * iface, + UINT index, CUSTDATA *pCustData) +{ + ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + TLBCustData *pCData; + TLBVarDesc * pVDesc; + int i; + TRACE("(%p) index %d\n", This, index); + for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++, + pVDesc=pVDesc->next) + ; + if(pVDesc){ + pCustData->prgCustData = + TLB_Alloc(pVDesc->ctCustData * sizeof(CUSTDATAITEM)); + if(pCustData->prgCustData ){ + pCustData->cCustData=pVDesc->ctCustData; + for(i=0, pCData=pVDesc->pCustData; pCData; i++, + pCData = pCData->next){ + pCustData->prgCustData[i].guid=pCData->guid; + VariantCopy(& pCustData->prgCustData[i].varValue, + & pCData->data); + } + }else{ + ERR(" OUT OF MEMORY! \n"); + return E_OUTOFMEMORY; + } + return S_OK; + } + return TYPE_E_ELEMENTNOTFOUND; +} + +/* ITypeInfo2::GetAllImplCustData + * + * Gets all custom data items for the specified implementation type + * + */ +static HRESULT WINAPI ITypeInfo2_fnGetAllImplTypeCustData( + ITypeInfo2 * iface, + UINT index, + CUSTDATA *pCustData) +{ + ITypeInfoImpl *This = (ITypeInfoImpl *)iface; + TLBCustData *pCData; + TLBImplType * pRDesc; + int i; + TRACE("(%p) index %d\n", This, index); + for(i=0, pRDesc=This->impltypelist; i!=index && pRDesc; i++, + pRDesc=pRDesc->next) + ; + if(pRDesc){ + pCustData->prgCustData = + TLB_Alloc(pRDesc->ctCustData * sizeof(CUSTDATAITEM)); + if(pCustData->prgCustData ){ + pCustData->cCustData=pRDesc->ctCustData; + for(i=0, pCData=pRDesc->pCustData; pCData; i++, + pCData = pCData->next){ + pCustData->prgCustData[i].guid=pCData->guid; + VariantCopy(& pCustData->prgCustData[i].varValue, + & pCData->data); + } + }else{ + ERR(" OUT OF MEMORY! \n"); + return E_OUTOFMEMORY; + } + return S_OK; + } + return TYPE_E_ELEMENTNOTFOUND; +} + +static ITypeInfo2Vtbl tinfvt = +{ + + ITypeInfo_fnQueryInterface, + ITypeInfo_fnAddRef, + ITypeInfo_fnRelease, + + ITypeInfo_fnGetTypeAttr, + ITypeInfo_fnGetTypeComp, + ITypeInfo_fnGetFuncDesc, + ITypeInfo_fnGetVarDesc, + ITypeInfo_fnGetNames, + ITypeInfo_fnGetRefTypeOfImplType, + ITypeInfo_fnGetImplTypeFlags, + ITypeInfo_fnGetIDsOfNames, + ITypeInfo_fnInvoke, + ITypeInfo_fnGetDocumentation, + ITypeInfo_fnGetDllEntry, + ITypeInfo_fnGetRefTypeInfo, + ITypeInfo_fnAddressOfMember, + ITypeInfo_fnCreateInstance, + ITypeInfo_fnGetMops, + ITypeInfo_fnGetContainingTypeLib, + ITypeInfo_fnReleaseTypeAttr, + ITypeInfo_fnReleaseFuncDesc, + ITypeInfo_fnReleaseVarDesc, + + ITypeInfo2_fnGetTypeKind, + ITypeInfo2_fnGetTypeFlags, + ITypeInfo2_fnGetFuncIndexOfMemId, + ITypeInfo2_fnGetVarIndexOfMemId, + ITypeInfo2_fnGetCustData, + ITypeInfo2_fnGetFuncCustData, + ITypeInfo2_fnGetParamCustData, + ITypeInfo2_fnGetVarCustData, + ITypeInfo2_fnGetImplTypeCustData, + ITypeInfo2_fnGetDocumentation2, + ITypeInfo2_fnGetAllCustData, + ITypeInfo2_fnGetAllFuncCustData, + ITypeInfo2_fnGetAllParamCustData, + ITypeInfo2_fnGetAllVarCustData, + ITypeInfo2_fnGetAllImplTypeCustData, +}; + +/****************************************************************************** + * CreateDispTypeInfo [OLEAUT32.31] + * + * Build type information for an object so it can be called through an + * IDispatch interface. + * + * RETURNS + * Success: S_OK. pptinfo contains the created ITypeInfo object. + * Failure: E_INVALIDARG, if one or more arguments is invalid. + * + * NOTES + * This call allows an objects methods to be accessed through IDispatch, by + * building an ITypeInfo object that IDispatch can use to call through. + */ +HRESULT WINAPI CreateDispTypeInfo( + INTERFACEDATA *pidata, /* [I] Description of the interface to build type info for */ + LCID lcid, /* [I] Locale Id */ + ITypeInfo **pptinfo) /* [O] Destination for created ITypeInfo object */ +{ + ITypeInfoImpl *pTIImpl; + int param, func; + TLBFuncDesc **ppFuncDesc; + + pTIImpl = (ITypeInfoImpl*)ITypeInfo_Constructor(); + pTIImpl->pTypeLib = NULL; + pTIImpl->index = 0; + pTIImpl->Name = NULL; + pTIImpl->dwHelpContext = -1; + memset(&pTIImpl->TypeAttr.guid, 0, sizeof(GUID)); + pTIImpl->TypeAttr.lcid = lcid; + pTIImpl->TypeAttr.typekind = TKIND_COCLASS; + pTIImpl->TypeAttr.wMajorVerNum = 0; + pTIImpl->TypeAttr.wMinorVerNum = 0; + pTIImpl->TypeAttr.cbAlignment = 2; + pTIImpl->TypeAttr.cbSizeInstance = -1; + pTIImpl->TypeAttr.cbSizeVft = -1; + pTIImpl->TypeAttr.cFuncs = 0; + pTIImpl->TypeAttr.cImplTypes = 1; + pTIImpl->TypeAttr.cVars = 0; + pTIImpl->TypeAttr.wTypeFlags = 0; + + ppFuncDesc = &pTIImpl->funclist; + for(func = 0; func < pidata->cMembers; func++) { + METHODDATA *md = pidata->pmethdata + func; + *ppFuncDesc = HeapAlloc(GetProcessHeap(), 0, sizeof(**ppFuncDesc)); + (*ppFuncDesc)->Name = SysAllocString(md->szName); + (*ppFuncDesc)->funcdesc.memid = md->dispid; + (*ppFuncDesc)->funcdesc.invkind = md->wFlags; + (*ppFuncDesc)->funcdesc.callconv = md->cc; + (*ppFuncDesc)->funcdesc.cParams = md->cArgs; + (*ppFuncDesc)->funcdesc.cParamsOpt = 0; + (*ppFuncDesc)->funcdesc.oVft = md->iMeth; + (*ppFuncDesc)->funcdesc.wFuncFlags = 0; /*??*/ + (*ppFuncDesc)->funcdesc.elemdescFunc.tdesc.vt = md->vtReturn; + (*ppFuncDesc)->funcdesc.lprgelemdescParam = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + md->cArgs * sizeof(ELEMDESC)); + (*ppFuncDesc)->pParamDesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + md->cArgs * sizeof(TLBParDesc)); + for(param = 0; param < md->cArgs; param++) { + (*ppFuncDesc)->funcdesc.lprgelemdescParam[param].tdesc.vt = md->ppdata[param].vt; + (*ppFuncDesc)->pParamDesc[param].Name = SysAllocString(md->ppdata[param].szName); + } + ppFuncDesc = &(*ppFuncDesc)->next; + } + *pptinfo = (ITypeInfo*)pTIImpl; + return S_OK; + +} + +static HRESULT WINAPI ITypeComp_fnQueryInterface(ITypeComp * iface, REFIID riid, LPVOID * ppv) +{ + ICOM_THIS_From_ITypeComp(ITypeInfoImpl, iface); + + return ITypeInfo_QueryInterface((ITypeInfo *)This, riid, ppv); +} + +static ULONG WINAPI ITypeComp_fnAddRef(ITypeComp * iface) +{ + ICOM_THIS_From_ITypeComp(ITypeInfoImpl, iface); + + return ITypeInfo_AddRef((ITypeInfo *)This); +} + +static ULONG WINAPI ITypeComp_fnRelease(ITypeComp * iface) +{ + ICOM_THIS_From_ITypeComp(ITypeInfoImpl, iface); + + return ITypeInfo_Release((ITypeInfo *)This); +} + +static HRESULT WINAPI ITypeComp_fnBind( + ITypeComp * iface, + OLECHAR * szName, + ULONG lHash, + WORD wFlags, + ITypeInfo ** ppTInfo, + DESCKIND * pDescKind, + BINDPTR * pBindPtr) +{ + ICOM_THIS_From_ITypeComp(ITypeInfoImpl, iface); + TLBFuncDesc * pFDesc; + TLBVarDesc * pVDesc; + + TRACE("(%s, %lx, 0x%x, %p, %p, %p)\n", debugstr_w(szName), lHash, wFlags, ppTInfo, pDescKind, pBindPtr); + + for(pFDesc = This->funclist; pFDesc; pFDesc = pFDesc->next) + if (pFDesc->funcdesc.invkind & wFlags) + if (!strcmpW(pFDesc->Name, szName)) { + break; + } + + if (pFDesc) + { + *pDescKind = DESCKIND_FUNCDESC; + pBindPtr->lpfuncdesc = &pFDesc->funcdesc; + *ppTInfo = (ITypeInfo *)&This->lpVtbl; + return S_OK; + } else { + if (!(wFlags & ~(INVOKE_PROPERTYGET))) + { + for(pVDesc = This->varlist; pVDesc; pVDesc = pVDesc->next) { + if (!strcmpW(pVDesc->Name, szName)) { + *pDescKind = DESCKIND_VARDESC; + pBindPtr->lpvardesc = &pVDesc->vardesc; + *ppTInfo = (ITypeInfo *)&This->lpVtbl; + return S_OK; + } + } + } + } + /* not found, look for it in inherited interfaces */ + if (This->TypeAttr.cImplTypes && + (This->TypeAttr.typekind == TKIND_INTERFACE || This->TypeAttr.typekind == TKIND_DISPATCH)) { + /* recursive search */ + ITypeInfo *pTInfo; + ITypeComp *pTComp; + HRESULT hr; + hr=ITypeInfo_GetRefTypeInfo((ITypeInfo *)&This->lpVtbl, This->impltypelist->hRef, &pTInfo); + if (SUCCEEDED(hr)) + { + hr = ITypeInfo_GetTypeComp(pTInfo,&pTComp); + ITypeInfo_Release(pTInfo); + } + if (SUCCEEDED(hr)) + { + hr = ITypeComp_Bind(pTComp, szName, lHash, wFlags, ppTInfo, pDescKind, pBindPtr); + ITypeComp_Release(pTComp); + return hr; + } + WARN("Could not search inherited interface!\n"); + } + ERR("did not find member with name %s, flags 0x%x!\n", debugstr_w(szName), wFlags); + *pDescKind = DESCKIND_NONE; + pBindPtr->lpfuncdesc = NULL; + *ppTInfo = NULL; + return DISP_E_MEMBERNOTFOUND; +} + +static HRESULT WINAPI ITypeComp_fnBindType( + ITypeComp * iface, + OLECHAR * szName, + ULONG lHash, + ITypeInfo ** ppTInfo, + ITypeComp ** ppTComp) +{ + TRACE("(%s, %lx, %p, %p)\n", debugstr_w(szName), lHash, ppTInfo, ppTComp); + + /* strange behaviour (does nothing) but like the + * original */ + + if (!ppTInfo || !ppTComp) + return E_POINTER; + + *ppTInfo = NULL; + *ppTComp = NULL; + + return S_OK; +} + +static ITypeCompVtbl tcompvt = +{ + + ITypeComp_fnQueryInterface, + ITypeComp_fnAddRef, + ITypeComp_fnRelease, + + ITypeComp_fnBind, + ITypeComp_fnBindType +}; diff --git a/reactos/lib/oleaut32/typelib.h b/reactos/lib/oleaut32/typelib.h new file mode 100644 index 00000000000..0c0a3856c46 --- /dev/null +++ b/reactos/lib/oleaut32/typelib.h @@ -0,0 +1,600 @@ +/* + * typelib.h internal wine data structures + * used to decode typelib's + * + * Copyright 1999 Rein KLazes + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef _WINE_TYPELIB_H +#define _WINE_TYPELIB_H + +#include + +#include "windef.h" +#include "winbase.h" +#include "oleauto.h" +#include "wine/windef16.h" + +#define HELPDLLFLAG (0x0100) +#define DO_NOT_SEEK (-1) + +#define MSFT_HREFTYPE_INTHISFILE(href) (!((href) & 3)) +#define MSFT_HREFTYPE_INDEX(href) ((href) /sizeof(MSFT_TypeInfoBase)) + +/*-------------------------FILE STRUCTURES-----------------------------------*/ + +/* There are two known file formats, those created with ICreateTypeLib + * have the signature "SLTG" as their first four bytes, while those created + * with ICreateTypeLib2 have "MSFT". + */ + +/***************************************************** + * MSFT typelibs + * + * These are TypeLibs created with ICreateTypeLib2 + * + */ + +/* + * structure of the typelib type2 header + * it is at the beginning of a type lib file + * + */ +typedef struct tagMSFT_Header { +/*0x00*/INT magic1; /* 0x5446534D "MSFT" */ + INT magic2; /* 0x00010002 version nr? */ + INT posguid; /* position of libid in guid table */ + /* (should be, else -1) */ + INT lcid; /* locale id */ +/*0x10*/INT lcid2; + INT varflags; /* (largely) unknown flags ,seems to be always 41 */ + /* becomes 0x51 with a helpfile defined */ + /* if help dll defined it's 0x151 */ + /* update : the lower nibble is syskind */ + INT version; /* set with SetVersion() */ + INT flags; /* set with SetFlags() */ +/*0x20*/INT nrtypeinfos; /* number of typeinfo's (till so far) */ + INT helpstring; /* position of help string in stringtable */ + INT helpstringcontext; + INT helpcontext; +/*0x30*/INT nametablecount; /* number of names in name table */ + INT nametablechars; /* nr of characters in name table */ + INT NameOffset; /* offset of name in name table */ + INT helpfile; /* position of helpfile in stringtable */ +/*0x40*/INT CustomDataOffset; /* if -1 no custom data, else it is offset */ + /* in customer data/guid offset table */ + INT res44; /* unknown always: 0x20 (guid hash size?) */ + INT res48; /* unknown always: 0x80 (name hash size?) */ + INT dispatchpos; /* HREFTYPE to IDispatch, or -1 if no IDispatch */ +/*0x50*/INT res50; /* is zero becomes one when an interface is derived */ +} MSFT_Header; + +/* segments in the type lib file have a structure like this: */ +typedef struct tagMSFT_pSeg { + INT offset; /* absolute offset in file */ + INT length; /* length of segment */ + INT res08; /* unknown always -1 */ + INT res0c; /* unknown always 0x0f in the header */ + /* 0x03 in the typeinfo_data */ +} MSFT_pSeg; + +/* layout of the main segment directory */ +typedef struct tagMSFT_SegDir { +/*1*/MSFT_pSeg pTypeInfoTab; /* each type info get an entry of 0x64 bytes */ + /* (25 ints) */ +/*2*/MSFT_pSeg pImpInfo; /* table with info for imported types */ +/*3*/MSFT_pSeg pImpFiles; /* import libaries */ +/*4*/MSFT_pSeg pRefTab; /* References table */ +/*5*/MSFT_pSeg pLibtab; /* always exists, alway same size (0x80) */ + /* hash table w offsets to guid????? */ +/*6*/MSFT_pSeg pGuidTab; /* all guids are stored here together with */ + /* offset in some table???? */ +/*7*/MSFT_pSeg res07; /* always created, alway same size (0x200) */ + /* purpose largely unknown */ +/*8*/MSFT_pSeg pNametab; /* name tables */ +/*9*/MSFT_pSeg pStringtab; /* string table */ +/*A*/MSFT_pSeg pTypdescTab; /* table with type descriptors */ +/*B*/MSFT_pSeg pArrayDescriptions; +/*C*/MSFT_pSeg pCustData; /* data table, used for custom data and default */ + /* parameter values */ +/*D*/MSFT_pSeg pCDGuids; /* table with offsets for the guids and into */ + /* the customer data table */ +/*E*/MSFT_pSeg res0e; /* unknown */ +/*F*/MSFT_pSeg res0f; /* unknown */ +} MSFT_SegDir; + + +/* base type info data */ +typedef struct tagMSFT_TypeInfoBase { +/*000*/ INT typekind; /* it is the TKIND_xxx */ + /* some byte alignment stuf */ + INT memoffset; /* points past the file, if no elements */ + INT res2; /* zero if no element, N*0x40 */ + INT res3; /* -1 if no lement, (N-1)*0x38 */ +/*010*/ INT res4; /* always? 3 */ + INT res5; /* always? zero */ + INT cElement; /* counts elements, HI=cVars, LO=cFuncs */ + INT res7; /* always? zero */ +/*020*/ INT res8; /* always? zero */ + INT res9; /* always? zero */ + INT resA; /* always? zero */ + INT posguid; /* position in guid table */ +/*030*/ INT flags; /* Typeflags */ + INT NameOffset; /* offset in name table */ + INT version; /* element version */ + INT docstringoffs; /* offset of docstring in string tab */ +/*040*/ INT helpstringcontext; /* */ + INT helpcontext; /* */ + INT oCustData; /* offset in customer data table */ +#ifdef WORDS_BIGENDIAN + INT16 cbSizeVft; /* virtual table size, not including inherits */ + INT16 cImplTypes; /* nr of implemented interfaces */ +#else + INT16 cImplTypes; /* nr of implemented interfaces */ + INT16 cbSizeVft; /* virtual table size, not including inherits */ +#endif +/*050*/ INT size; /* size in bytes, at least for structures */ + /* FIXME: name of this field */ + INT datatype1; /* position in type description table */ + /* or in base intefaces */ + /* if coclass: offset in reftable */ + /* if interface: reference to inherited if */ + INT datatype2; /* if 0x8000, entry above is valid */ + /* actually dunno */ + /* else it is zero? */ + INT res18; /* always? 0 */ +/*060*/ INT res19; /* always? -1 */ + } MSFT_TypeInfoBase; + +/* layout of an entry with information on imported types */ +typedef struct tagMSFT_ImpInfo { + INT res0; /* unknown */ + INT oImpFile; /* offset inthe Import File table */ + INT oGuid; /* offset in Guid table */ + } MSFT_ImpInfo; + +/* function description data */ +typedef struct { +/* INT recsize; record size including some xtra stuff */ + INT DataType; /* data type of the memeber, eg return of function */ + INT Flags; /* something to do with attribute flags (LOWORD) */ +#ifdef WORDS_BIGENDIAN + INT16 funcdescsize; /* size of reconstituted FUNCDESC and related structs */ + INT16 VtableOffset; /* offset in vtable */ +#else + INT16 VtableOffset; /* offset in vtable */ + INT16 funcdescsize; /* size of reconstituted FUNCDESC and related structs */ +#endif + INT FKCCIC; /* bit string with the following */ + /* meaning (bit 0 is the msb): */ + /* bit 2 indicates that oEntry is numeric */ + /* bit 3 that parameter has default values */ + /* calling convention (bits 4-7 ) */ + /* bit 8 indicates that custom data is present */ + /* Invokation kind (bits 9-12 ) */ + /* function kind (eg virtual), bits 13-15 */ +#ifdef WORDS_BIGENDIAN + INT16 nroargs; /* nr of optional arguments */ + INT16 nrargs; /* number of arguments (including optional ????) */ +#else + INT16 nrargs; /* number of arguments (including optional ????) */ + INT16 nroargs; /* nr of optional arguments */ +#endif + /* optional attribute fields, the number of them is variable */ + INT OptAttr[1]; +/* +0* INT helpcontext; +1* INT oHelpString; +2* INT oEntry; // either offset in string table or numeric as it is // +3* INT res9; // unknown (-1) // +4* INT resA; // unknown (-1) // +5* INT HelpStringContext; + // these are controlled by a bit set in the FKCCIC field // +6* INT oCustData; // custom data for function // +7* INT oArgCustData[1]; // custom data per argument // +*/ +} MSFT_FuncRecord; + +/* after this may follow an array with default value pointers if the + * appropriate bit in the FKCCIC field has been set: + * INT oDefautlValue[nrargs]; + */ + + /* Parameter info one per argument*/ +typedef struct { + INT DataType; + INT oName; + INT Flags; + } MSFT_ParameterInfo; + +/* Variable description data */ +typedef struct { +/* INT recsize; // record size including some xtra stuff */ + INT DataType; /* data type of the variable */ + INT Flags; /* VarFlags (LOWORD) */ +#ifdef WORDS_BIGENDIAN + INT16 vardescsize; /* size of reconstituted VARDESC and related structs */ + INT16 VarKind; /* VarKind */ +#else + INT16 VarKind; /* VarKind */ + INT16 vardescsize; /* size of reconstituted VARDESC and related structs */ +#endif + INT OffsValue; /* value of the variable or the offset */ + /* in the data structure */ + /* optional attribute fields, the number of them is variable */ + /* controlled by record length */ + INT HelpContext; + INT oHelpString; + INT res9; /* unknown (-1) */ + INT oCustData; /* custom data for variable */ + INT HelpStringContext; + +} MSFT_VarRecord; + +/* Structure of the reference data */ +typedef struct { + INT reftype; /* either offset in type info table, then it's */ + /* a multiple of 64 */ + /* or offset in the external reference table */ + /* with an offset of 1 */ + INT flags; + INT oCustData; /* custom data */ + INT onext; /* next offset, -1 if last */ +} MSFT_RefRecord; + +/* this is how a guid is stored */ +typedef struct { + GUID guid; + INT hreftype; /* -2 for the typelib guid, typeinfo offset + for typeinfo guid, low two bits are 01 if + this is an imported typeinfo, low two bits + are 10 if this is an imported typelib (used + by imported typeinfos) */ + INT next_hash; /* offset to next guid in the hash bucket */ +} MSFT_GuidEntry; +/* some data preceding entries in the name table */ +typedef struct { + INT hreftype; /* is -1 if name is for neither a typeinfo, + a variable, or a function (that is, name + is for a typelib or a function parameter). + otherwise is the offset of the first + typeinfo that this name refers to (either + to the typeinfo itself or to a member of + the typeinfo */ + INT next_hash; /* offset to next name in the hash bucket */ + INT namelen; /* only lower 8 bits are valid, + lower-middle 8 bits are unknown (flags?), + upper 16 bits are hash code */ +} MSFT_NameIntro; +/* the custom data table directory has enties like this */ +typedef struct { + INT GuidOffset; + INT DataOffset; + INT next; /* next offset in the table, -1 if it's the last */ +} MSFT_CDGuid; + + +/*********************************************************** + * + * SLTG typelibs. + * + * These are created with ICreateTypeLib + * + */ + +#include "pshpack1.h" + +typedef struct { +/*00*/ DWORD SLTG_magic; /* 0x47544c53 == "SLTG" */ +/*04*/ WORD nrOfFileBlks; /* no of SLTG_BlkEntry's + 1 */ +/*06*/ WORD res06; /* ?? always 9 */ +/*08*/ WORD res08; /* some kind of len/offset ?? */ +/*0a*/ WORD first_blk; /* 1 based index into blk entries that + corresponds to first block in file */ +/*0c*/ DWORD res0c; /* always 0x000204ff */ +/*10*/ DWORD res10; /* always 0x00000000 */ +/*14*/ DWORD res14; /* always 0x000000c0 */ +/*18*/ DWORD res18; /* always 0x46000000 */ +/*1c*/ DWORD res1c; /* always 0x00000044 */ +/*20*/ DWORD res20; /* always 0xffff0000 */ +} SLTG_Header; + +/* This gets followed by a list of block entries */ +typedef struct { +/*00*/ DWORD len; +/*04*/ WORD index_string; /* offs from start of SLTG_Magic to index string */ +/*06*/ WORD next; +} SLTG_BlkEntry; + +/* The order of the blocks in the file is given by starting at Block + entry firt_blk and stepping through using the next pointer */ + +/* These then get followed by this magic */ +typedef struct { +/*00*/ BYTE res00; /* always 0x01 */ +/*01*/ CHAR CompObj_magic[8]; /* always "CompObj" */ +/*09*/ CHAR dir_magic[4]; /* always "dir" */ +} SLTG_Magic; + +#define SLTG_COMPOBJ_MAGIC "CompObj" +#define SLTG_DIR_MAGIC "dir" + +/* Next we have SLTG_Header.nrOfFileBlks - 2 of Index strings. These +are presumably unique to within the file and look something like +"AAAAAAAAAA" with the first character incremented from 'A' to ensure +uniqueness. I guess successive chars increment when we need to wrap +the first one. */ + +typedef struct { +/*00*/ CHAR string[11]; +} SLTG_Index; + + +/* This is followed by SLTG_pad9 */ +typedef struct { +/*00*/ CHAR pad[9]; /* 9 '\0's */ +} SLTG_Pad9; + + +/* Now we have the noOfFileBlks - 1 worth of blocks. The length of +each block is given by its entry in SLTG_BlkEntry. */ + +/* type SLTG_NAME in rather like a BSTR except that the length in +bytes is given by the first WORD and the string contains 8bit chars */ + +typedef WORD SLTG_Name; + +/* The main library block looks like this. This one seems to come last */ + +typedef struct { +/*00*/ WORD magic; /* 0x51cc */ +/*02*/ WORD res02; /* 0x0003, 0x0004 */ +/*04*/ WORD name; /* offset to name in name table */ +/*06*/ SLTG_Name res06; /* maybe this is just WORD == 0xffff */ + SLTG_Name helpstring; + SLTG_Name helpfile; + DWORD helpcontext; + WORD syskind; /* == 1 for win32, 0 for win16 */ + WORD lcid; /* == 0x409, 0x809 etc */ + DWORD res12; /* == 0 */ + WORD libflags; /* LIBFLAG_* */ + WORD maj_vers; + WORD min_vers; + GUID uuid; +} SLTG_LibBlk; + +#define SLTG_LIBBLK_MAGIC 0x51cc + +/* we then get 0x40 bytes worth of 0xffff or small numbers followed by + nrOfFileBlks - 2 of these */ +typedef struct { + WORD small_no; + SLTG_Name index_name; /* This refers to a name in the directory */ + SLTG_Name other_name; /* Another one of these weird names */ + WORD res1a; /* 0xffff */ + WORD name_offs; /* offset to name in name table */ + WORD more_bytes; /* if this is non-zero we get this many + bytes before the next element, which seem + to reference the docstring of the type ? */ + WORD res20; /* 0xffff */ + DWORD helpcontext; + WORD res26; /* 0xffff */ + GUID uuid; +} SLTG_OtherTypeInfo; + +/* Next we get WORD 0x0003 followed by a DWORD which if we add to +0x216 gives the offset to the name table from the start of the LibBlk +struct */ + +typedef struct { +/*00*/ WORD magic; /* 0x0501 */ +/*02*/ DWORD href_table; /* if not 0xffffffff, then byte offset from + beginning of struct to href table */ +/*06*/ DWORD res06; /* 0xffffffff */ +/*0a*/ DWORD elem_table; /* offset to members */ +/*0e*/ DWORD res0e; /* 0xffffffff */ +/*12*/ WORD major_version; /* major version number */ +/*14*/ WORD minor_version; /* minor version number */ +/*16*/ DWORD res16; /* 0xfffe0000 */ +/*1a*/ BYTE typeflags1;/* 0x02 | top 5 bits hold l5sbs of TYPEFLAGS */ +/*1b*/ BYTE typeflags2;/* TYPEFLAGS >> 5 */ +/*1c*/ BYTE typeflags3;/* 0x02*/ +/*1d*/ BYTE typekind; /* 0x03 == TKIND_INTERFACE etc. */ +/*1e*/ DWORD res1e; /* 0x00000000 or 0xffffffff */ +} SLTG_TypeInfoHeader; + +#define SLTG_TIHEADER_MAGIC 0x0501 + +typedef struct { +/*00*/ WORD cFuncs; +/*02*/ WORD cVars; +/*04*/ WORD cImplTypes; +/*06*/ WORD res06; +/*08*/ WORD res08; +/*0a*/ WORD res0a; +/*0c*/ WORD res0c; +/*0e*/ WORD res0e; +/*10*/ WORD res10; +/*12*/ WORD res12; +/*14*/ WORD tdescalias_vt; /* for TKIND_ALIAS */ +/*16*/ WORD res16; +/*18*/ WORD res18; +/*1a*/ WORD res1a; +/*1c*/ WORD res1c; +/*1e*/ WORD res1e; +/*20*/ WORD cbSizeInstance; +/*22*/ WORD cbAlignment; +/*24*/ WORD res24; +/*26*/ WORD res26; +/*28*/ WORD cbSizeVft; +/*2a*/ WORD res2a; +/*2c*/ WORD res2c; +/*2e*/ WORD res2e; +/*30*/ WORD res30; +/*32*/ WORD res32; +/*34*/ WORD res34; +} SLTG_TypeInfoTail; + +typedef struct { +/*00*/ WORD res00; /* 0x0001 sometimes 0x0003 ?? */ +/*02*/ WORD res02; /* 0xffff */ +/*04*/ BYTE res04; /* 0x01 */ +/*05*/ DWORD cbExtra; /* No of bytes that follow */ +} SLTG_MemberHeader; + +typedef struct { +/*00*/ WORD magic; /* 0x120a */ +/*02*/ WORD next; /* offset in bytes to next block from start of block + group, 0xffff if last item */ +/*04*/ WORD name; /* offset to name within name table */ +/*06*/ WORD value; /* offset to value from start of block group */ +/*08*/ WORD res08; /* 0x56 */ +/*0a*/ DWORD memid; /* memid */ +/*0e*/ WORD helpcontext;/* 0xfffe == no context, 0x0001 == stored in EnumInfo struct, else offset + to value from start of block group */ +/*10*/ WORD helpstring;/* offset from start of block group to string offset */ +} SLTG_EnumItem; + +#define SLTG_ENUMITEM_MAGIC 0x120a + +typedef struct { +/*00*/ WORD vt; /* vartype, 0xffff marks end. */ +/*02*/ WORD res02; /* ?, 0xffff marks end */ +} SLTG_AliasItem; + +#define SLTG_ALIASITEM_MAGIC 0x001d + + +typedef struct { + BYTE magic; /* 0x4c or 0x6c */ + BYTE inv; /* high nibble is INVOKE_KIND, low nibble = 2 */ + WORD next; /* byte offset from beginning of group to next fn */ + WORD name; /* Offset within name table to name */ + DWORD dispid; /* dispid */ + WORD helpcontext; /* helpcontext (again 1 is special) */ + WORD helpstring;/* helpstring offset to offset */ + WORD arg_off; /* offset to args from start of block */ + BYTE nacc; /* lowest 3bits are CALLCONV, rest are no of args */ + BYTE retnextopt;/* if 0x80 bit set ret type follows else next WORD + is offset to ret type. No of optional args is + middle 6 bits */ + WORD rettype; /* return type VT_?? or offset to ret type */ + WORD vtblpos; /* position in vtbl? */ + WORD funcflags; /* present if magic == 0x6c */ +/* Param list starts, repeat next two as required */ +#if 0 + WORD name; /* offset to 2nd letter of name */ + WORD+ type; /* VT_ of param */ +#endif +} SLTG_Function; + +#define SLTG_FUNCTION_MAGIC 0x4c +#define SLTG_FUNCTION_WITH_FLAGS_MAGIC 0x6c + +typedef struct { +/*00*/ BYTE magic; /* 0xdf */ +/*01*/ BYTE res01; /* 0x00 */ +/*02*/ DWORD res02; /* 0xffffffff */ +/*06*/ DWORD res06; /* 0xffffffff */ +/*0a*/ DWORD res0a; /* 0xffffffff */ +/*0e*/ DWORD res0e; /* 0xffffffff */ +/*12*/ DWORD res12; /* 0xffffffff */ +/*16*/ DWORD res16; /* 0xffffffff */ +/*1a*/ DWORD res1a; /* 0xffffffff */ +/*1e*/ DWORD res1e; /* 0xffffffff */ +/*22*/ DWORD res22; /* 0xffffffff */ +/*26*/ DWORD res26; /* 0xffffffff */ +/*2a*/ DWORD res2a; /* 0xffffffff */ +/*2e*/ DWORD res2e; /* 0xffffffff */ +/*32*/ DWORD res32; /* 0xffffffff */ +/*36*/ DWORD res36; /* 0xffffffff */ +/*3a*/ DWORD res3a; /* 0xffffffff */ +/*3e*/ DWORD res3e; /* 0xffffffff */ +/*42*/ WORD res42; /* 0xffff */ +/*44*/ DWORD number; /* this is 8 times the number of refs */ +/*48*/ /* Now we have number bytes (8 for each ref) of SLTG_UnknownRefInfo */ + +/*50*/ WORD res50; /* 0xffff */ +/*52*/ BYTE res52; /* 0x01 */ +/*53*/ DWORD res53; /* 0x00000000 */ +/*57*/ SLTG_Name names[1]; + /* Now we have number/8 SLTG_Names (first WORD is no of bytes in the ascii + * string). Strings look like "*\Rxxxx*#n". If xxxx == ffff then the + * ref refers to the nth type listed in this library (0 based). Else + * the xxxx (which maybe fewer than 4 digits) is the offset into the name + * table to a string "*\G{}#1.0#0#C:\WINNT\System32\stdole32.tlb#" + * The guid is the typelib guid; the ref again refers to the nth type of + * the imported typelib. + */ + +/*xx*/ BYTE resxx; /* 0xdf */ + +} SLTG_RefInfo; + +#define SLTG_REF_MAGIC 0xdf + +typedef struct { + WORD res00; /* 0x0001 */ + BYTE res02; /* 0x02 */ + BYTE res03; /* 0x40 if internal ref, 0x00 if external ? */ + WORD res04; /* 0xffff */ + WORD res06; /* 0x0000, 0x0013 or 0xffff ?? */ +} SLTG_UnknownRefInfo; + +typedef struct { + WORD res00; /* 0x004a */ + WORD next; /* byte offs to next interface */ + WORD res04; /* 0xffff */ + BYTE impltypeflags; /* IMPLTYPEFLAG_* */ + BYTE res07; /* 0x80 */ + WORD res08; /* 0x0012, 0x0028 ?? */ + WORD ref; /* number in ref table ? */ + WORD res0c; /* 0x4000 */ + WORD res0e; /* 0xfffe */ + WORD res10; /* 0xffff */ + WORD res12; /* 0x001d */ + WORD pos_in_table; /* 0x0, 0x4, ? */ +} SLTG_ImplInfo; + +#define SLTG_IMPL_MAGIC 0x004a + +typedef struct { + BYTE magic; /* 0x0a */ + BYTE typepos; + WORD next; + WORD name; + WORD byte_offs; /* pos in struct */ + WORD type; /* if typepos == 0x02 this is the type, else offset to type */ + DWORD memid; + WORD helpcontext; /* ?? */ + WORD helpstring; /* ?? */ +} SLTG_RecordItem; + +#define SLTG_RECORD_MAGIC 0x0a + + +/* CARRAYs look like this +WORD type == VT_CARRAY +WORD offset from start of block to SAFEARRAY +WORD typeofarray +*/ + +extern DWORD _invoke(FARPROC func,CALLCONV callconv, int nrargs, DWORD *args); +extern void dump_Variant(VARIANT * pvar); +#include "poppack.h" + +/*---------------------------END--------------------------------------------*/ +#endif diff --git a/reactos/lib/oleaut32/typelib.spec b/reactos/lib/oleaut32/typelib.spec new file mode 100644 index 00000000000..e01b58dc553 --- /dev/null +++ b/reactos/lib/oleaut32/typelib.spec @@ -0,0 +1,12 @@ +2 stub CREATETYPELIB +3 pascal LoadTypeLib(ptr ptr) LoadTypeLib16 +4 stub LHASHVALOFNAMESYS +5 stub _IID_ICREATETYPEINFO +6 stub _IID_ICREATETYPELIB +7 stub _IID_ITYPECOMP +8 stub _IID_ITYPEINFO +9 stub _IID_ITYPELIB +10 stub REGISTERTYPELIB +11 stub LOADREGTYPELIB +14 pascal QueryPathOfRegTypeLib(ptr word word word ptr) QueryPathOfRegTypeLib16 +15 pascal OaBuildVersion() OaBuildVersion16 diff --git a/reactos/lib/oleaut32/typelib16.c b/reactos/lib/oleaut32/typelib16.c new file mode 100644 index 00000000000..7750d2761b4 --- /dev/null +++ b/reactos/lib/oleaut32/typelib16.c @@ -0,0 +1,180 @@ +/* + * TYPELIB 16bit part. + * + * Copyright 1997 Marcus Meissner + * Copyright 1999 Rein Klazes + * Copyright 2000 Francois Jacques + * Copyright 2001 Huw D M Davies for CodeWeavers + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "config.h" +#include "wine/port.h" + +#include +#include +#include +#include +#include + +#include "winerror.h" +#include "windef.h" +#include "winbase.h" +#include "winnls.h" +#include "winreg.h" +#include "winuser.h" + +#include "objbase.h" +#include "ole2disp.h" +#include "typelib.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(ole); + +/************************************************************************* + * TYPELIB {TYPELIB} + * + * This dll is the 16 bit version of the Typelib API, part the original + * implementation of Ole automation. It and its companion ole2disp.dll were + * superseded by oleaut32.dll which provides 32 bit implementations of these + * functions and greatly extends the Ole Api. + * + * Winelib developers cannot use these functions directly, they are implemented + * solely for backwards compatibility with existing legacy applications. + * + * SEE ALSO + * oleaut32(), ole2disp(). + */ + +/**************************************************************************** + * QueryPathOfRegTypeLib [TYPELIB.14] + * + * Get the registry key of a registered type library. + * + * RETURNS + * Success: S_OK. path is updated with the key name + * Failure: E_FAIL, if guid was not found in the registry + * + * NOTES + * The key takes the form "Classes\Typelib\\.\\win16\" + */ +HRESULT WINAPI +QueryPathOfRegTypeLib16( + REFGUID guid, /* [in] Guid to get the key name for */ + WORD wMaj, /* [in] Major version */ + WORD wMin, /* [in] Minor version */ + LCID lcid, /* [in] Locale Id */ + LPBSTR16 path) /* [out] Destination for the registry key name */ +{ + char xguid[80]; + char typelibkey[100],pathname[260]; + DWORD plen; + + TRACE("\n"); + + if (HIWORD(guid)) { + sprintf( typelibkey, "SOFTWARE\\Classes\\Typelib\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\%d.%d\\%lx\\win16", + guid->Data1, guid->Data2, guid->Data3, + guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3], + guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7], + wMaj,wMin,lcid); + } else { + sprintf(xguid,"",(DWORD)guid); + FIXME("(%s,%d,%d,0x%04lx,%p),can't handle non-string guids.\n",xguid,wMaj,wMin,(DWORD)lcid,path); + return E_FAIL; + } + plen = sizeof(pathname); + if (RegQueryValueA(HKEY_LOCAL_MACHINE,typelibkey,pathname,&plen)) { + /* try again without lang specific id */ + if (SUBLANGID(lcid)) + return QueryPathOfRegTypeLib16(guid,wMaj,wMin,PRIMARYLANGID(lcid),path); + FIXME("key %s not found\n",typelibkey); + return E_FAIL; + } + *path = SysAllocString16(pathname); + return S_OK; +} + +/****************************************************************************** + * LoadTypeLib [TYPELIB.3] + * + * Load and register a type library. + * + * RETURNS + * Success: S_OK. pptLib contains the type libraries ITypeLib interface. + * Failure: An HRESULT error code. + * + * NOTES + * Both parameters are FAR pointers. + */ +HRESULT WINAPI LoadTypeLib16( + LPOLESTR szFile, /* [in] Name of file to load from */ + ITypeLib** pptLib) /* [out] Destination for loaded ITypeLib interface */ +{ + FIXME("(%s,%p): stub\n",debugstr_w((LPWSTR)szFile),pptLib); + + if (pptLib!=0) + *pptLib=0; + + return E_FAIL; +} + +/**************************************************************************** + * OaBuildVersion (TYPELIB.15) + * + * Get the Ole Automation build version. + * + * PARAMS + * None + * + * RETURNS + * The build version. + * + * NOTES + * Known typelib.dll versions: + *| OLE Ver. Comments Date Build Ver. + *| -------- ------------------------- ---- --------- + *| OLE 2.01 Call not available 1993 N/A + *| OLE 2.02 1993-94 02 3002 + *| OLE 2.03 23 730 + *| OLE 2.03 03 3025 + *| OLE 2.03 W98 SE orig. file !! 1993-95 10 3024 + *| OLE 2.1 NT 1993-95 ?? ??? + *| OLE 2.3.1 W95 23 700 + *| OLE2 4.0 NT4SP6 1993-98 40 4277 + */ +DWORD WINAPI OaBuildVersion16(void) +{ + /* FIXME: I'd like to return the highest currently known version value + * in case the user didn't force a --winver, but I don't know how + * to retrieve the "versionForced" info from misc/version.c :( + * (this would be useful in other places, too) */ + FIXME("If you get version error messages, please report them\n"); + switch(GetVersion() & 0x8000ffff) /* mask off build number */ + { + case 0x80000a03: /* WIN31 */ + return MAKELONG(3027, 3); /* WfW 3.11 */ + case 0x80000004: /* WIN95 */ + return MAKELONG(700, 23); /* Win95A */ + case 0x80000a04: /* WIN98 */ + return MAKELONG(3024, 10); /* W98 SE */ + case 0x00000004: /* NT4 */ + return MAKELONG(4277, 40); /* NT4 SP6 */ + default: + FIXME("Version value not known yet. Please investigate it!\n"); + return 0; + } +} diff --git a/reactos/lib/oleaut32/typelib2.c b/reactos/lib/oleaut32/typelib2.c new file mode 100644 index 00000000000..72f37bda2f3 --- /dev/null +++ b/reactos/lib/oleaut32/typelib2.c @@ -0,0 +1,3913 @@ +/* + * TYPELIB2 + * + * Copyright 2004 Alastair Bridgewater + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * -------------------------------------------------------------------------------------- + * Known problems: + * + * Badly incomplete. + * + * Only works on little-endian systems. + * + */ + +#include "config.h" +#include "wine/port.h" + +#include +#include +#include +#include +#include + +#define COBJMACROS +#define NONAMELESSUNION +#define NONAMELESSSTRUCT + +#include "winerror.h" +#include "windef.h" +#include "winbase.h" +#include "winnls.h" +#include "winreg.h" +#include "winuser.h" + +#include "wine/unicode.h" +#include "objbase.h" +#include "ole2disp.h" +#include "typelib.h" +#include "wine/debug.h" +#include "variant.h" + +WINE_DEFAULT_DEBUG_CHANNEL(typelib2); +/* WINE_DEFAULT_DEBUG_CHANNEL(ole); */ + + +/****************************************************************************** + * ICreateTypeLib2 {OLEAUT32} + * + * NOTES + * The ICreateTypeLib2 interface provides an interface whereby one may create + * new type library (.tlb) files. + * + * This interface inherits from ICreateTypeLib, and can be freely cast back + * and forth between an ICreateTypeLib and an ICreateTypeLib2 on local clients. + * This dispensation applies only to ICreateTypeLib objects obtained on MSFT + * format type libraries (those made through CreateTypeLib2). + * + * METHODS + */ + +/****************************************************************************** + * ICreateTypeInfo2 {OLEAUT32} + * + * NOTES + * The ICreateTypeInfo2 interface provides an interface whereby one may add + * type information to type library (.tlb) files. + * + * This interface inherits from ICreateTypeInfo, and can be freely cast back + * and forth between an ICreateTypeInfo and an ICreateTypeInfo2 on local clients. + * This dispensation applies only to ICreateTypeInfo objects obtained on MSFT + * format type libraries (those made through CreateTypeLib2). + * + * METHODS + */ + +/****************************************************************************** + * ITypeLib2 {OLEAUT32} + * + * NOTES + * The ITypeLib2 interface provides an interface whereby one may query MSFT + * format type library (.tlb) files. + * + * This interface inherits from ITypeLib, and can be freely cast back and + * forth between an ITypeLib and an ITypeLib2 on local clients. This + * dispensation applies only to ITypeLib objects obtained on MSFT format type + * libraries (those made through CreateTypeLib2). + * + * METHODS + */ + +/****************************************************************************** + * ITypeInfo2 {OLEAUT32} + * + * NOTES + * The ITypeInfo2 interface provides an interface whereby one may query type + * information stored in MSFT format type library (.tlb) files. + * + * This interface inherits from ITypeInfo, and can be freely cast back and + * forth between an ITypeInfo and an ITypeInfo2 on local clients. This + * dispensation applies only to ITypeInfo objects obtained on MSFT format type + * libraries (those made through CreateTypeLib2). + * + * METHODS + */ + +/*================== Implementation Structures ===================================*/ + +enum MSFT_segment_index { + MSFT_SEG_TYPEINFO = 0, /* type information */ + MSFT_SEG_IMPORTINFO, /* import information */ + MSFT_SEG_IMPORTFILES, /* import filenames */ + MSFT_SEG_REFERENCES, /* references (?) */ + MSFT_SEG_GUIDHASH, /* hash table for guids? */ + MSFT_SEG_GUID, /* guid storage */ + MSFT_SEG_NAMEHASH, /* hash table for names */ + MSFT_SEG_NAME, /* name storage */ + MSFT_SEG_STRING, /* string storage */ + MSFT_SEG_TYPEDESC, /* type descriptions */ + MSFT_SEG_ARRAYDESC, /* array descriptions */ + MSFT_SEG_CUSTDATA, /* custom data */ + MSFT_SEG_CUSTDATAGUID, /* custom data guids */ + MSFT_SEG_UNKNOWN, /* ??? */ + MSFT_SEG_UNKNOWN2, /* ??? */ + MSFT_SEG_MAX /* total number of segments */ +}; + +typedef struct tagMSFT_ImpFile { + int guid; + LCID lcid; + int version; + char filename[0]; /* preceeded by two bytes of encoded (length << 2) + flags in the low two bits. */ +} MSFT_ImpFile; + +typedef struct tagICreateTypeLib2Impl +{ + ICreateTypeLib2Vtbl *lpVtbl; + ITypeLib2Vtbl *lpVtblTypeLib2; + + UINT ref; + + WCHAR *filename; + + MSFT_Header typelib_header; + MSFT_pSeg typelib_segdir[MSFT_SEG_MAX]; + char *typelib_segment_data[MSFT_SEG_MAX]; + int typelib_segment_block_length[MSFT_SEG_MAX]; + + INT typelib_typeinfo_offsets[0x200]; /* Hope that's enough. */ + + INT *typelib_namehash_segment; + INT *typelib_guidhash_segment; + + struct tagICreateTypeInfo2Impl *typeinfos; + struct tagICreateTypeInfo2Impl *last_typeinfo; +} ICreateTypeLib2Impl; + +#define _ITypeLib2_Offset(impl) ((int)(&(((impl*)0)->lpVtblTypeLib2))) +#define ICOM_THIS_From_ITypeLib2(impl, iface) impl* This = (impl*)(((char*)iface)-_ITypeLib2_Offset(impl)) + +typedef struct tagICreateTypeInfo2Impl +{ + ICreateTypeInfo2Vtbl *lpVtbl; + ITypeInfo2Vtbl *lpVtblTypeInfo2; + + UINT ref; + + ICreateTypeLib2Impl *typelib; + MSFT_TypeInfoBase *typeinfo; + + INT *typedata; + int typedata_allocated; + int typedata_length; + + int indices[42]; + int names[42]; + int offsets[42]; + + int datawidth; + + struct tagICreateTypeInfo2Impl *next_typeinfo; +} ICreateTypeInfo2Impl; + +#define _ITypeInfo2_Offset(impl) ((int)(&(((impl*)0)->lpVtblTypeInfo2))) +#define ICOM_THIS_From_ITypeInfo2(impl, iface) impl* This = (impl*)(((char*)iface)-_ITypeInfo2_Offset(impl)) + +static ULONG WINAPI ICreateTypeLib2_fnRelease(ICreateTypeLib2 *iface); + + +/*================== Internal functions ===================================*/ + +/**************************************************************************** + * ctl2_init_header + * + * Initializes the type library header of a new typelib. + */ +static void ctl2_init_header( + ICreateTypeLib2Impl *This) /* [I] The typelib to initialize. */ +{ + This->typelib_header.magic1 = 0x5446534d; + This->typelib_header.magic2 = 0x00010002; + This->typelib_header.posguid = -1; + This->typelib_header.lcid = 0x0409; /* or do we use the current one? */ + This->typelib_header.lcid2 = 0x0409; + This->typelib_header.varflags = 0x40; + This->typelib_header.version = 0; + This->typelib_header.flags = 0; + This->typelib_header.nrtypeinfos = 0; + This->typelib_header.helpstring = -1; + This->typelib_header.helpstringcontext = 0; + This->typelib_header.helpcontext = 0; + This->typelib_header.nametablecount = 0; + This->typelib_header.nametablechars = 0; + This->typelib_header.NameOffset = -1; + This->typelib_header.helpfile = -1; + This->typelib_header.CustomDataOffset = -1; + This->typelib_header.res44 = 0x20; + This->typelib_header.res48 = 0x80; + This->typelib_header.dispatchpos = -1; + This->typelib_header.res50 = 0; +} + +/**************************************************************************** + * ctl2_init_segdir + * + * Initializes the segment directory of a new typelib. + */ +static void ctl2_init_segdir( + ICreateTypeLib2Impl *This) /* [I] The typelib to initialize. */ +{ + int i; + MSFT_pSeg *segdir; + + segdir = &This->typelib_segdir[MSFT_SEG_TYPEINFO]; + + for (i = 0; i < 15; i++) { + segdir[i].offset = -1; + segdir[i].length = 0; + segdir[i].res08 = -1; + segdir[i].res0c = 0x0f; + } +} + +/**************************************************************************** + * ctl2_hash_guid + * + * Generates a hash key from a GUID. + * + * RETURNS + * + * The hash key for the GUID. + */ +static int ctl2_hash_guid( + REFGUID guid) /* [I] The guid to find. */ +{ + int hash; + int i; + + hash = 0; + for (i = 0; i < 8; i ++) { + hash ^= ((const short *)guid)[i]; + } + + return (hash & 0xf) | ((hash & 0x10) & (0 - !!(hash & 0xe0))); +} + +/**************************************************************************** + * ctl2_find_guid + * + * Locates a guid in a type library. + * + * RETURNS + * + * The offset into the GUID segment of the guid, or -1 if not found. + */ +static int ctl2_find_guid( + ICreateTypeLib2Impl *This, /* [I] The typelib to operate against. */ + int hash_key, /* [I] The hash key for the guid. */ + REFGUID guid) /* [I] The guid to find. */ +{ + int offset; + MSFT_GuidEntry *guidentry; + + offset = This->typelib_guidhash_segment[hash_key]; + while (offset != -1) { + guidentry = (MSFT_GuidEntry *)&This->typelib_segment_data[MSFT_SEG_GUID][offset]; + + if (!memcmp(guidentry, guid, sizeof(GUID))) return offset; + + offset = guidentry->next_hash; + } + + return offset; +} + +/**************************************************************************** + * ctl2_find_name + * + * Locates a name in a type library. + * + * RETURNS + * + * The offset into the NAME segment of the name, or -1 if not found. + * + * NOTES + * + * The name must be encoded as with ctl2_encode_name(). + */ +static int ctl2_find_name( + ICreateTypeLib2Impl *This, /* [I] The typelib to operate against. */ + char *name) /* [I] The encoded name to find. */ +{ + int offset; + int *namestruct; + + offset = This->typelib_namehash_segment[name[2] & 0x7f]; + while (offset != -1) { + namestruct = (int *)&This->typelib_segment_data[MSFT_SEG_NAME][offset]; + + if (!((namestruct[2] ^ *((int *)name)) & 0xffff00ff)) { + /* hash codes and lengths match, final test */ + if (!strncasecmp(name+4, (void *)(namestruct+3), name[0])) break; + } + + /* move to next item in hash bucket */ + offset = namestruct[1]; + } + + return offset; +} + +/**************************************************************************** + * ctl2_encode_name + * + * Encodes a name string to a form suitable for storing into a type library + * or comparing to a name stored in a type library. + * + * RETURNS + * + * The length of the encoded name, including padding and length+hash fields. + * + * NOTES + * + * Will throw an exception if name or result are NULL. Is not multithread + * safe in the slightest. + */ +static int ctl2_encode_name( + ICreateTypeLib2Impl *This, /* [I] The typelib to operate against (used for LCID only). */ + const WCHAR *name, /* [I] The name string to encode. */ + char **result) /* [O] A pointer to a pointer to receive the encoded name. */ +{ + int length; + static char converted_name[0x104]; + int offset; + int value; + + length = WideCharToMultiByte(CP_ACP, 0, name, strlenW(name), converted_name+4, 0x100, NULL, NULL); + converted_name[0] = length & 0xff; + + converted_name[length + 4] = 0; + + converted_name[1] = 0x00; + + value = LHashValOfNameSysA(This->typelib_header.varflags & 0x0f, This->typelib_header.lcid, converted_name + 4); + + converted_name[2] = value; + converted_name[3] = value >> 8; + + for (offset = (4 - length) & 3; offset; offset--) converted_name[length + offset + 3] = 0x57; + + *result = converted_name; + + return (length + 7) & ~3; +} + +/**************************************************************************** + * ctl2_encode_string + * + * Encodes a string to a form suitable for storing into a type library or + * comparing to a string stored in a type library. + * + * RETURNS + * + * The length of the encoded string, including padding and length fields. + * + * NOTES + * + * Will throw an exception if string or result are NULL. Is not multithread + * safe in the slightest. + */ +static int ctl2_encode_string( + ICreateTypeLib2Impl *This, /* [I] The typelib to operate against (not used?). */ + const WCHAR *string, /* [I] The string to encode. */ + char **result) /* [O] A pointer to a pointer to receive the encoded string. */ +{ + int length; + static char converted_string[0x104]; + int offset; + + length = WideCharToMultiByte(CP_ACP, 0, string, strlenW(string), converted_string+2, 0x102, NULL, NULL); + converted_string[0] = length & 0xff; + converted_string[1] = (length >> 8) & 0xff; + + for (offset = (4 - (length + 2)) & 3; offset; offset--) converted_string[length + offset + 1] = 0x57; + + *result = converted_string; + + return (length + 5) & ~3; +} + +/**************************************************************************** + * ctl2_alloc_segment + * + * Allocates memory from a segment in a type library. + * + * RETURNS + * + * Success: The offset within the segment of the new data area. + * Failure: -1 (this is invariably an out of memory condition). + * + * BUGS + * + * Does not (yet) handle the case where the allocated segment memory needs to grow. + */ +static int ctl2_alloc_segment( + ICreateTypeLib2Impl *This, /* [I] The type library in which to allocate. */ + enum MSFT_segment_index segment, /* [I] The segment in which to allocate. */ + int size, /* [I] The amount to allocate. */ + int block_size) /* [I] Initial allocation block size, or 0 for default. */ +{ + int offset; + + if(!This->typelib_segment_data[segment]) { + if (!block_size) block_size = 0x2000; + + This->typelib_segment_block_length[segment] = block_size; + This->typelib_segment_data[segment] = HeapAlloc(GetProcessHeap(), 0, block_size); + if (!This->typelib_segment_data[segment]) return -1; + memset(This->typelib_segment_data[segment], 0x57, block_size); + } + + while ((This->typelib_segdir[segment].length + size) > This->typelib_segment_block_length[segment]) { + char *block; + + block_size = This->typelib_segment_block_length[segment]; + block = HeapReAlloc(GetProcessHeap(), 0, This->typelib_segment_data[segment], block_size << 1); + if (!block) return -1; + + if (segment == MSFT_SEG_TYPEINFO) { + /* TypeInfos have a direct pointer to their memory space, so we have to fix them up. */ + ICreateTypeInfo2Impl *typeinfo; + + for (typeinfo = This->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) { + typeinfo->typeinfo = (void *)&block[((char *)typeinfo->typeinfo) - This->typelib_segment_data[segment]]; + } + } + + memset(block + block_size, 0x57, block_size); + This->typelib_segment_block_length[segment] = block_size << 1; + This->typelib_segment_data[segment] = block; + } + + offset = This->typelib_segdir[segment].length; + This->typelib_segdir[segment].length += size; + + return offset; +} + +/**************************************************************************** + * ctl2_alloc_typeinfo + * + * Allocates and initializes a typeinfo structure in a type library. + * + * RETURNS + * + * Success: The offset of the new typeinfo. + * Failure: -1 (this is invariably an out of memory condition). + */ +static int ctl2_alloc_typeinfo( + ICreateTypeLib2Impl *This, /* [I] The type library to allocate in. */ + int nameoffset) /* [I] The offset of the name for this typeinfo. */ +{ + int offset; + MSFT_TypeInfoBase *typeinfo; + + offset = ctl2_alloc_segment(This, MSFT_SEG_TYPEINFO, sizeof(MSFT_TypeInfoBase), 0); + if (offset == -1) return -1; + + This->typelib_typeinfo_offsets[This->typelib_header.nrtypeinfos++] = offset; + + typeinfo = (void *)(This->typelib_segment_data[MSFT_SEG_TYPEINFO] + offset); + + typeinfo->typekind = (This->typelib_header.nrtypeinfos - 1) << 16; + typeinfo->memoffset = -1; /* should be EOF if no elements */ + typeinfo->res2 = 0; + typeinfo->res3 = -1; + typeinfo->res4 = 3; + typeinfo->res5 = 0; + typeinfo->cElement = 0; + typeinfo->res7 = 0; + typeinfo->res8 = 0; + typeinfo->res9 = 0; + typeinfo->resA = 0; + typeinfo->posguid = -1; + typeinfo->flags = 0; + typeinfo->NameOffset = nameoffset; + typeinfo->version = 0; + typeinfo->docstringoffs = -1; + typeinfo->helpstringcontext = 0; + typeinfo->helpcontext = 0; + typeinfo->oCustData = -1; + typeinfo->cbSizeVft = 0; + typeinfo->cImplTypes = 0; + typeinfo->size = 0; + typeinfo->datatype1 = -1; + typeinfo->datatype2 = 0; + typeinfo->res18 = 0; + typeinfo->res19 = -1; + + return offset; +} + +/**************************************************************************** + * ctl2_alloc_guid + * + * Allocates and initializes a GUID structure in a type library. Also updates + * the GUID hash table as needed. + * + * RETURNS + * + * Success: The offset of the new GUID. + * Failure: -1 (this is invariably an out of memory condition). + */ +static int ctl2_alloc_guid( + ICreateTypeLib2Impl *This, /* [I] The type library to allocate in. */ + MSFT_GuidEntry *guid) /* [I] The GUID to store. */ +{ + int offset; + MSFT_GuidEntry *guid_space; + int hash_key; + + hash_key = ctl2_hash_guid(&guid->guid); + + offset = ctl2_find_guid(This, hash_key, &guid->guid); + if (offset != -1) return offset; + + offset = ctl2_alloc_segment(This, MSFT_SEG_GUID, sizeof(MSFT_GuidEntry), 0); + if (offset == -1) return -1; + + guid_space = (void *)(This->typelib_segment_data[MSFT_SEG_GUID] + offset); + *guid_space = *guid; + + guid_space->next_hash = This->typelib_guidhash_segment[hash_key]; + This->typelib_guidhash_segment[hash_key] = offset; + + return offset; +} + +/**************************************************************************** + * ctl2_alloc_name + * + * Allocates and initializes a name within a type library. Also updates the + * name hash table as needed. + * + * RETURNS + * + * Success: The offset within the segment of the new name. + * Failure: -1 (this is invariably an out of memory condition). + */ +static int ctl2_alloc_name( + ICreateTypeLib2Impl *This, /* [I] The type library to allocate in. */ + const WCHAR *name) /* [I] The name to store. */ +{ + int length; + int offset; + MSFT_NameIntro *name_space; + char *encoded_name; + + length = ctl2_encode_name(This, name, &encoded_name); + + offset = ctl2_find_name(This, encoded_name); + if (offset != -1) return offset; + + offset = ctl2_alloc_segment(This, MSFT_SEG_NAME, length + 8, 0); + if (offset == -1) return -1; + + name_space = (void *)(This->typelib_segment_data[MSFT_SEG_NAME] + offset); + name_space->hreftype = -1; + name_space->next_hash = -1; + memcpy(&name_space->namelen, encoded_name, length); + + if (This->typelib_namehash_segment[encoded_name[2] & 0x7f] != -1) + name_space->next_hash = This->typelib_namehash_segment[encoded_name[2] & 0x7f]; + + This->typelib_namehash_segment[encoded_name[2] & 0x7f] = offset; + + This->typelib_header.nametablecount += 1; + This->typelib_header.nametablechars += *encoded_name; + + return offset; +} + +/**************************************************************************** + * ctl2_alloc_string + * + * Allocates and initializes a string in a type library. + * + * RETURNS + * + * Success: The offset within the segment of the new string. + * Failure: -1 (this is invariably an out of memory condition). + */ +static int ctl2_alloc_string( + ICreateTypeLib2Impl *This, /* [I] The type library to allocate in. */ + const WCHAR *string) /* [I] The string to store. */ +{ + int length; + int offset; + char *string_space; + char *encoded_string; + + length = ctl2_encode_string(This, string, &encoded_string); + + for (offset = 0; offset < This->typelib_segdir[MSFT_SEG_STRING].length; + offset += ((((This->typelib_segment_data[MSFT_SEG_STRING][offset + 1] << 8) & 0xff) + | (This->typelib_segment_data[MSFT_SEG_STRING][offset + 0] & 0xff)) + 5) & ~3) { + if (!memcmp(encoded_string, This->typelib_segment_data[MSFT_SEG_STRING] + offset, length)) return offset; + } + + offset = ctl2_alloc_segment(This, MSFT_SEG_STRING, length, 0); + if (offset == -1) return -1; + + string_space = This->typelib_segment_data[MSFT_SEG_STRING] + offset; + memcpy(string_space, encoded_string, length); + + return offset; +} + +/**************************************************************************** + * ctl2_alloc_importinfo + * + * Allocates and initializes an import information structure in a type library. + * + * RETURNS + * + * Success: The offset of the new importinfo. + * Failure: -1 (this is invariably an out of memory condition). + */ +static int ctl2_alloc_importinfo( + ICreateTypeLib2Impl *This, /* [I] The type library to allocate in. */ + MSFT_ImpInfo *impinfo) /* [I] The import information to store. */ +{ + int offset; + MSFT_ImpInfo *impinfo_space; + + for (offset = 0; + offset < This->typelib_segdir[MSFT_SEG_IMPORTINFO].length; + offset += sizeof(MSFT_ImpInfo)) { + if (!memcmp(&(This->typelib_segment_data[MSFT_SEG_IMPORTINFO][offset]), + impinfo, sizeof(MSFT_ImpInfo))) { + return offset; + } + } + + offset = ctl2_alloc_segment(This, MSFT_SEG_IMPORTINFO, sizeof(MSFT_ImpInfo), 0); + if (offset == -1) return -1; + + impinfo_space = (void *)(This->typelib_segment_data[MSFT_SEG_IMPORTINFO] + offset); + *impinfo_space = *impinfo; + + return offset; +} + +/**************************************************************************** + * ctl2_alloc_importfile + * + * Allocates and initializes an import file definition in a type library. + * + * RETURNS + * + * Success: The offset of the new importinfo. + * Failure: -1 (this is invariably an out of memory condition). + */ +static int ctl2_alloc_importfile( + ICreateTypeLib2Impl *This, /* [I] The type library to allocate in. */ + int guidoffset, /* [I] The offset to the GUID for the imported library. */ + int major_version, /* [I] The major version number of the imported library. */ + int minor_version, /* [I] The minor version number of the imported library. */ + const WCHAR *filename) /* [I] The filename of the imported library. */ +{ + int length; + int offset; + MSFT_ImpFile *importfile; + char *encoded_string; + + length = ctl2_encode_string(This, filename, &encoded_string); + + encoded_string[0] <<= 2; + encoded_string[0] |= 1; + + for (offset = 0; offset < This->typelib_segdir[MSFT_SEG_IMPORTFILES].length; + offset += ((((This->typelib_segment_data[MSFT_SEG_IMPORTFILES][offset + 0xd] << 8) & 0xff) + | (This->typelib_segment_data[MSFT_SEG_IMPORTFILES][offset + 0xc] & 0xff)) >> 2) + 0xc) { + if (!memcmp(encoded_string, This->typelib_segment_data[MSFT_SEG_IMPORTFILES] + offset + 0xc, length)) return offset; + } + + offset = ctl2_alloc_segment(This, MSFT_SEG_IMPORTFILES, length + 0xc, 0); + if (offset == -1) return -1; + + importfile = (MSFT_ImpFile *)&This->typelib_segment_data[MSFT_SEG_IMPORTFILES][offset]; + importfile->guid = guidoffset; + importfile->lcid = This->typelib_header.lcid2; + importfile->version = major_version | (minor_version << 16); + memcpy(&importfile->filename, encoded_string, length); + + return offset; +} + +/**************************************************************************** + * ctl2_alloc_custdata + * + * Allocates and initializes a "custom data" value in a type library. + * + * RETURNS + * + * Success: The offset of the new custdata. + * Failure: + * + * -1: Out of memory. + * -2: Unable to encode VARIANT data (typically a bug). + */ +static int ctl2_alloc_custdata( + ICreateTypeLib2Impl *This, /* [I] The type library in which to encode the value. */ + VARIANT *pVarVal) /* [I] The value to encode. */ +{ + int offset; + + TRACE("(%p,%p(%d))\n",This,pVarVal,V_VT(pVarVal)); + + switch (V_VT(pVarVal)) { + case VT_UI4: + offset = ctl2_alloc_segment(This, MSFT_SEG_CUSTDATA, 8, 0); + if (offset == -1) return offset; + + *((unsigned short *)&This->typelib_segment_data[MSFT_SEG_CUSTDATA][offset]) = VT_UI4; + *((unsigned long *)&This->typelib_segment_data[MSFT_SEG_CUSTDATA][offset+2]) = V_UI4(pVarVal); + break; + + default: + FIXME("Unknown variable encoding vt %d.\n", V_VT(pVarVal)); + return -2; + } + + return offset; +} + +/**************************************************************************** + * ctl2_set_custdata + * + * Adds a custom data element to an object in a type library. + * + * RETURNS + * + * Success: S_OK. + * Failure: One of E_INVALIDARG or E_OUTOFMEMORY. + */ +static HRESULT ctl2_set_custdata( + ICreateTypeLib2Impl *This, /* [I] The type library to store the custom data in. */ + REFGUID guid, /* [I] The GUID used as a key to retrieve the custom data. */ + VARIANT *pVarVal, /* [I] The custom data itself. */ + int *offset) /* [I/O] The list of custom data to prepend to. */ +{ + MSFT_GuidEntry guidentry; + int dataoffset; + int guidoffset; + int custoffset; + int *custdata; + + guidentry.guid = *guid; + + guidentry.hreftype = -1; + guidentry.next_hash = -1; + + guidoffset = ctl2_alloc_guid(This, &guidentry); + if (guidoffset == -1) return E_OUTOFMEMORY; + dataoffset = ctl2_alloc_custdata(This, pVarVal); + if (dataoffset == -1) return E_OUTOFMEMORY; + if (dataoffset == -2) return E_INVALIDARG; + + custoffset = ctl2_alloc_segment(This, MSFT_SEG_CUSTDATAGUID, 12, 0); + if (custoffset == -1) return E_OUTOFMEMORY; + + custdata = (int *)&This->typelib_segment_data[MSFT_SEG_CUSTDATAGUID][custoffset]; + custdata[0] = guidoffset; + custdata[1] = dataoffset; + custdata[2] = *offset; + *offset = custoffset; + + return S_OK; +} + +/**************************************************************************** + * ctl2_encode_typedesc + * + * Encodes a type description, storing information in the TYPEDESC and ARRAYDESC + * segments as needed. + * + * RETURNS + * + * Success: 0. + * Failure: -1. + */ +static int ctl2_encode_typedesc( + ICreateTypeLib2Impl *This, /* [I] The type library in which to encode the TYPEDESC. */ + TYPEDESC *tdesc, /* [I] The type description to encode. */ + int *encoded_tdesc, /* [O] The encoded type description. */ + int *width, /* [O] The width of the type, or NULL. */ + int *alignment, /* [O] The alignment of the type, or NULL. */ + int *decoded_size) /* [O] The total size of the unencoded TYPEDESCs, including nested descs. */ +{ + int default_tdesc; + int scratch; + int typeoffset; + int arrayoffset; + int *typedata; + int *arraydata; + int target_type; + int child_size; + + default_tdesc = 0x80000000 | (tdesc->vt << 16) | tdesc->vt; + if (!width) width = &scratch; + if (!alignment) alignment = &scratch; + if (!decoded_size) decoded_size = &scratch; + + *decoded_size = 0; + + switch (tdesc->vt) { + case VT_UI1: + case VT_I1: + *encoded_tdesc = default_tdesc; + *width = 1; + *alignment = 1; + break; + + case VT_INT: + *encoded_tdesc = 0x80000000 | (VT_I4 << 16) | VT_INT; + if ((This->typelib_header.varflags & 0x0f) == SYS_WIN16) { + *width = 2; + *alignment = 2; + } else { + *width = 4; + *alignment = 4; + } + break; + + case VT_UINT: + *encoded_tdesc = 0x80000000 | (VT_UI4 << 16) | VT_UINT; + if ((This->typelib_header.varflags & 0x0f) == SYS_WIN16) { + *width = 2; + *alignment = 2; + } else { + *width = 4; + *alignment = 4; + } + break; + + case VT_UI2: + case VT_I2: + case VT_BOOL: + *encoded_tdesc = default_tdesc; + *width = 2; + *alignment = 2; + break; + + case VT_I4: + case VT_UI4: + case VT_R4: + case VT_ERROR: + case VT_BSTR: + case VT_HRESULT: + *encoded_tdesc = default_tdesc; + *width = 4; + *alignment = 4; + break; + + case VT_CY: + *encoded_tdesc = default_tdesc; + *width = 8; + *alignment = 4; /* guess? */ + break; + + case VT_VOID: + *encoded_tdesc = 0x80000000 | (VT_EMPTY << 16) | tdesc->vt; + *width = 0; + *alignment = 1; + break; + + case VT_PTR: + /* FIXME: Make with the error checking. */ + FIXME("PTR vartype, may not work correctly.\n"); + + ctl2_encode_typedesc(This, tdesc->u.lptdesc, &target_type, NULL, NULL, &child_size); + + for (typeoffset = 0; typeoffset < This->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) { + typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; + if (((typedata[0] & 0xffff) == VT_PTR) && (typedata[1] == target_type)) break; + } + + if (typeoffset == This->typelib_segdir[MSFT_SEG_TYPEDESC].length) { + int mix_field; + + if (target_type & 0x80000000) { + mix_field = ((target_type >> 16) & 0x3fff) | VT_BYREF; + } else { + typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][target_type]; + mix_field = ((typedata[0] >> 16) == 0x7fff)? 0x7fff: 0x7ffe; + } + + typeoffset = ctl2_alloc_segment(This, MSFT_SEG_TYPEDESC, 8, 0); + typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; + + typedata[0] = (mix_field << 16) | VT_PTR; + typedata[1] = target_type; + } + + *encoded_tdesc = typeoffset; + + *width = 4; + *alignment = 4; + *decoded_size = sizeof(TYPEDESC) + child_size; + break; + + case VT_SAFEARRAY: + /* FIXME: Make with the error checking. */ + FIXME("SAFEARRAY vartype, may not work correctly.\n"); + + ctl2_encode_typedesc(This, tdesc->u.lptdesc, &target_type, NULL, NULL, &child_size); + + for (typeoffset = 0; typeoffset < This->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) { + typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; + if (((typedata[0] & 0xffff) == VT_SAFEARRAY) && (typedata[1] == target_type)) break; + } + + if (typeoffset == This->typelib_segdir[MSFT_SEG_TYPEDESC].length) { + int mix_field; + + if (target_type & 0x80000000) { + mix_field = ((target_type >> 16) & VT_TYPEMASK) | VT_ARRAY; + } else { + typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][target_type]; + mix_field = ((typedata[0] >> 16) == 0x7fff)? 0x7fff: 0x7ffe; + } + + typeoffset = ctl2_alloc_segment(This, MSFT_SEG_TYPEDESC, 8, 0); + typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; + + typedata[0] = (mix_field << 16) | VT_SAFEARRAY; + typedata[1] = target_type; + } + + *encoded_tdesc = typeoffset; + + *width = 4; + *alignment = 4; + *decoded_size = sizeof(TYPEDESC) + child_size; + break; + + case VT_CARRAY: + /* FIXME: Make with the error checking. */ + FIXME("Array vartype, hacking badly.\n"); + + ctl2_encode_typedesc(This, &tdesc->u.lpadesc->tdescElem, &target_type, width, alignment, NULL); + arrayoffset = ctl2_alloc_segment(This, MSFT_SEG_ARRAYDESC, 16, 0); + arraydata = (void *)&This->typelib_segment_data[MSFT_SEG_ARRAYDESC][arrayoffset]; + + arraydata[0] = target_type; + arraydata[1] = 0x00080001; + arraydata[2] = 0x8; + arraydata[3] = 0; + + typeoffset = ctl2_alloc_segment(This, MSFT_SEG_TYPEDESC, 8, 0); + typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; + + typedata[0] = (0x7ffe << 16) | VT_CARRAY; + typedata[1] = arrayoffset; + + *encoded_tdesc = typeoffset; + *width = 8; + *alignment = 1; + *decoded_size = sizeof(ARRAYDESC); + + break; + + case VT_USERDEFINED: + TRACE("USERDEFINED.\n"); + for (typeoffset = 0; typeoffset < This->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) { + typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; + if ((typedata[0] == ((0x7fff << 16) | VT_USERDEFINED)) && (typedata[1] == tdesc->u.hreftype)) break; + } + + if (typeoffset == This->typelib_segdir[MSFT_SEG_TYPEDESC].length) { + typeoffset = ctl2_alloc_segment(This, MSFT_SEG_TYPEDESC, 8, 0); + typedata = (void *)&This->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; + + typedata[0] = (0x7fff << 16) | VT_USERDEFINED; + typedata[1] = tdesc->u.hreftype; + } + + *encoded_tdesc = typeoffset; + *width = 0; + *alignment = 1; + break; + + default: + FIXME("Unrecognized type %d.\n", tdesc->vt); + *encoded_tdesc = default_tdesc; + *width = 0; + *alignment = 1; + break; + } + + return 0; +} + +/**************************************************************************** + * ctl2_find_nth_reference + * + * Finds a reference by index into the linked list of reference records. + * + * RETURNS + * + * Success: Offset of the desired reference record. + * Failure: -1. + */ +static int ctl2_find_nth_reference( + ICreateTypeLib2Impl *This, /* [I] The type library in which to search. */ + int offset, /* [I] The starting offset of the reference list. */ + int index) /* [I] The index of the reference to find. */ +{ + MSFT_RefRecord *ref; + + for (; index && (offset != -1); index--) { + ref = (MSFT_RefRecord *)&This->typelib_segment_data[MSFT_SEG_REFERENCES][offset]; + offset = ref->onext; + } + + return offset; +} + +/**************************************************************************** + * ctl2_find_typeinfo_from_offset + * + * Finds an ITypeInfo given an offset into the TYPEINFO segment. + * + * RETURNS + * + * Success: S_OK. + * Failure: TYPE_E_ELEMENTNOTFOUND. + */ +static HRESULT ctl2_find_typeinfo_from_offset( + ICreateTypeLib2Impl *This, /* [I] The typelib to find the typeinfo in. */ + int offset, /* [I] The offset of the desired typeinfo. */ + ITypeInfo **ppTinfo) /* [I] The typeinfo found. */ +{ + void *typeinfodata; + ICreateTypeInfo2Impl *typeinfo; + + typeinfodata = &This->typelib_segment_data[MSFT_SEG_TYPEINFO][offset]; + + for (typeinfo = This->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) { + if (typeinfo->typeinfo == typeinfodata) { + *ppTinfo = (ITypeInfo *)&typeinfo->lpVtblTypeInfo2; + ITypeInfo2_AddRef(*ppTinfo); + return S_OK; + } + } + + ERR("Failed to find typeinfo, invariant varied.\n"); + + return TYPE_E_ELEMENTNOTFOUND; +} + +/*================== ICreateTypeInfo2 Implementation ===================================*/ + +/****************************************************************************** + * ICreateTypeInfo2_QueryInterface {OLEAUT32} + * + * See IUnknown_QueryInterface. + */ +static HRESULT WINAPI ICreateTypeInfo2_fnQueryInterface( + ICreateTypeInfo2 * iface, + REFIID riid, + VOID **ppvObject) +{ + ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; + + TRACE("(%p)->(IID: %s)\n",This,debugstr_guid(riid)); + + *ppvObject=NULL; + if(IsEqualIID(riid, &IID_IUnknown) || + IsEqualIID(riid,&IID_ICreateTypeInfo)|| + IsEqualIID(riid,&IID_ICreateTypeInfo2)) + { + *ppvObject = This; + } else if (IsEqualIID(riid, &IID_ITypeInfo) || + IsEqualIID(riid, &IID_ITypeInfo2)) { + *ppvObject = &This->lpVtblTypeInfo2; + } + + if(*ppvObject) + { + ICreateTypeLib2_AddRef(iface); + TRACE("-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject); + return S_OK; + } + TRACE("-- Interface: E_NOINTERFACE\n"); + return E_NOINTERFACE; +} + +/****************************************************************************** + * ICreateTypeInfo2_AddRef {OLEAUT32} + * + * See IUnknown_AddRef. + */ +static ULONG WINAPI ICreateTypeInfo2_fnAddRef(ICreateTypeInfo2 *iface) +{ + ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; + + TRACE("(%p)->ref was %u\n",This, This->ref); + + return ++(This->ref); +} + +/****************************************************************************** + * ICreateTypeInfo2_Release {OLEAUT32} + * + * See IUnknown_Release. + */ +static ULONG WINAPI ICreateTypeInfo2_fnRelease(ICreateTypeInfo2 *iface) +{ + ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; + + --(This->ref); + + TRACE("(%p)->(%u)\n",This, This->ref); + + if (!This->ref) { + if (This->typelib) { + ICreateTypeLib2_fnRelease((ICreateTypeLib2 *)This->typelib); + This->typelib = NULL; + } + + /* ICreateTypeLib2 frees all ICreateTypeInfos when it releases. */ + /* HeapFree(GetProcessHeap(),0,This); */ + return 0; + } + + return This->ref; +} + + +/****************************************************************************** + * ICreateTypeInfo2_SetGuid {OLEAUT32} + * + * See ICreateTypeInfo_SetGuid. + */ +static HRESULT WINAPI ICreateTypeInfo2_fnSetGuid(ICreateTypeInfo2 *iface, REFGUID guid) +{ + ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; + + MSFT_GuidEntry guidentry; + int offset; + + TRACE("(%p,%s)\n", iface, debugstr_guid(guid)); + + guidentry.guid = *guid; + guidentry.hreftype = This->typelib->typelib_typeinfo_offsets[This->typeinfo->typekind >> 16]; + guidentry.next_hash = -1; + + offset = ctl2_alloc_guid(This->typelib, &guidentry); + + if (offset == -1) return E_OUTOFMEMORY; + + This->typeinfo->posguid = offset; + + if (IsEqualIID(guid, &IID_IDispatch)) { + This->typelib->typelib_header.dispatchpos = This->typelib->typelib_typeinfo_offsets[This->typeinfo->typekind >> 16]; + } + + return S_OK; +} + +/****************************************************************************** + * ICreateTypeInfo2_SetTypeFlags {OLEAUT32} + * + * See ICreateTypeInfo_SetTypeFlags. + */ +static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeFlags(ICreateTypeInfo2 *iface, UINT uTypeFlags) +{ + ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; + + TRACE("(%p,0x%x)\n", iface, uTypeFlags); + + This->typeinfo->flags = uTypeFlags; + + if (uTypeFlags & 0x1000) { + MSFT_GuidEntry foo; + int guidoffset; + int fileoffset; + MSFT_ImpInfo impinfo; + static const WCHAR stdole2tlb[] = { 's','t','d','o','l','e','2','.','t','l','b',0 }; + + foo.guid = IID_StdOle; + foo.hreftype = 2; + foo.next_hash = -1; + guidoffset = ctl2_alloc_guid(This->typelib, &foo); + if (guidoffset == -1) return E_OUTOFMEMORY; + + fileoffset = ctl2_alloc_importfile(This->typelib, guidoffset, 2, 0, stdole2tlb); + if (fileoffset == -1) return E_OUTOFMEMORY; + + foo.guid = IID_IDispatch; + foo.hreftype = 1; + foo.next_hash = -1; + guidoffset = ctl2_alloc_guid(This->typelib, &foo); + if (guidoffset == -1) return E_OUTOFMEMORY; + + impinfo.res0 = 0x03010000; + impinfo.oImpFile = fileoffset; + impinfo.oGuid = guidoffset; + ctl2_alloc_importinfo(This->typelib, &impinfo); + + This->typelib->typelib_header.dispatchpos = 1; + This->typelib->typelib_header.res50 = 1; + + This->typeinfo->typekind |= 0x10; + This->typeinfo->typekind &= ~0x0f; + This->typeinfo->typekind |= TKIND_DISPATCH; + } + + return S_OK; +} + +/****************************************************************************** + * ICreateTypeInfo2_SetDocString {OLEAUT32} + * + * See ICreateTypeInfo_SetDocString. + */ +static HRESULT WINAPI ICreateTypeInfo2_fnSetDocString( + ICreateTypeInfo2* iface, + LPOLESTR pStrDoc) +{ + ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; + + int offset; + + TRACE("(%p,%s)\n", iface, debugstr_w(pStrDoc)); + + offset = ctl2_alloc_string(This->typelib, pStrDoc); + if (offset == -1) return E_OUTOFMEMORY; + This->typeinfo->docstringoffs = offset; + return S_OK; +} + +/****************************************************************************** + * ICreateTypeInfo2_SetHelpContext {OLEAUT32} + * + * See ICreateTypeInfo_SetHelpContext. + */ +static HRESULT WINAPI ICreateTypeInfo2_fnSetHelpContext( + ICreateTypeInfo2* iface, + DWORD dwHelpContext) +{ + ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; + + TRACE("(%p,%ld)\n", iface, dwHelpContext); + + This->typeinfo->helpcontext = dwHelpContext; + + return S_OK; +} + +/****************************************************************************** + * ICreateTypeInfo2_SetVersion {OLEAUT32} + * + * See ICreateTypeInfo_SetVersion. + */ +static HRESULT WINAPI ICreateTypeInfo2_fnSetVersion( + ICreateTypeInfo2* iface, + WORD wMajorVerNum, + WORD wMinorVerNum) +{ + ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; + + TRACE("(%p,%d,%d)\n", iface, wMajorVerNum, wMinorVerNum); + + This->typeinfo->version = wMajorVerNum | (wMinorVerNum << 16); + return S_OK; +} + +/****************************************************************************** + * ICreateTypeInfo2_AddRefTypeInfo {OLEAUT32} + * + * See ICreateTypeInfo_AddRefTypeInfo. + */ +static HRESULT WINAPI ICreateTypeInfo2_fnAddRefTypeInfo( + ICreateTypeInfo2* iface, + ITypeInfo* pTInfo, + HREFTYPE* phRefType) +{ + ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; + + ITypeLib *container; + int index; + HRESULT res; + + TRACE("(%p,%p,%p)\n", iface, pTInfo, phRefType); + + /* + * If this is one of ours, we set *phRefType to the TYPEINFO offset of + * the referred TypeInfo. Otherwise, we presumably have more magic to do. + * + * Unfortunately, we can't rely on the passed-in TypeInfo even having the + * same internal structure as one of ours. It could be from another + * implementation of ITypeInfo. So we need to do the following... + */ + res = ITypeInfo_GetContainingTypeLib(pTInfo, &container, &index); + if (!SUCCEEDED(res)) { + TRACE("failed to find containing typelib.\n"); + return res; + } + + if (container == (ITypeLib *)&This->typelib->lpVtblTypeLib2) { + *phRefType = This->typelib->typelib_typeinfo_offsets[index]; + } else { + FIXME("(%p,%p,%p), pTInfo from different typelib.\n", iface, pTInfo, phRefType); + } + + ITypeLib_Release(container); + return S_OK; +} + +/****************************************************************************** + * ICreateTypeInfo2_AddFuncDesc {OLEAUT32} + * + * See ICreateTypeInfo_AddFuncDesc. + */ +static HRESULT WINAPI ICreateTypeInfo2_fnAddFuncDesc( + ICreateTypeInfo2* iface, + UINT index, + FUNCDESC* pFuncDesc) +{ + ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; + + int offset; + int *typedata; + int i; + int decoded_size; + + FIXME("(%p,%d,%p), stub!\n", iface, index, pFuncDesc); + FIXME("{%ld,%p,%p,%d,%d,%d,%d,%d,%d,%d,{%d},%d}\n", pFuncDesc->memid, pFuncDesc->lprgscode, pFuncDesc->lprgelemdescParam, pFuncDesc->funckind, pFuncDesc->invkind, pFuncDesc->callconv, pFuncDesc->cParams, pFuncDesc->cParamsOpt, pFuncDesc->oVft, pFuncDesc->cScodes, pFuncDesc->elemdescFunc.tdesc.vt, pFuncDesc->wFuncFlags); +/* FIXME("{%d, %d}\n", pFuncDesc->lprgelemdescParam[0].tdesc.vt, pFuncDesc->lprgelemdescParam[1].tdesc.vt); */ +/* return E_OUTOFMEMORY; */ + + if (!This->typedata) { + This->typedata = HeapAlloc(GetProcessHeap(), 0, 0x2000); + This->typedata[0] = 0; + } + + /* allocate type data space for us */ + offset = This->typedata[0]; + This->typedata[0] += 0x18 + (pFuncDesc->cParams * 12); + typedata = This->typedata + (offset >> 2) + 1; + + /* fill out the basic type information */ + typedata[0] = (0x18 + (pFuncDesc->cParams * 12)) | (index << 16); + ctl2_encode_typedesc(This->typelib, &pFuncDesc->elemdescFunc.tdesc, &typedata[1], NULL, NULL, &decoded_size); + typedata[2] = pFuncDesc->wFuncFlags; + typedata[3] = ((sizeof(FUNCDESC) + decoded_size) << 16) | This->typeinfo->cbSizeVft; + typedata[4] = (index << 16) | (pFuncDesc->callconv << 8) | 9; + typedata[5] = pFuncDesc->cParams; + + /* NOTE: High word of typedata[3] is total size of FUNCDESC + size of all ELEMDESCs for params + TYPEDESCs for pointer params and return types. */ + /* That is, total memory allocation required to reconstitute the FUNCDESC in its entirety. */ + typedata[3] += (sizeof(ELEMDESC) * pFuncDesc->cParams) << 16; + + for (i = 0; i < pFuncDesc->cParams; i++) { + ctl2_encode_typedesc(This->typelib, &pFuncDesc->lprgelemdescParam[i].tdesc, &typedata[6+(i*3)], NULL, NULL, &decoded_size); + typedata[7+(i*3)] = -1; + typedata[8+(i*3)] = pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags; + typedata[3] += decoded_size << 16; + +#if 0 + /* FIXME: Doesn't work. Doesn't even come up with usable VTs for varDefaultValue. */ + if (pFuncDesc->lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT) { + ctl2_alloc_custdata(This->typelib, &pFuncDesc->lprgelemdescParam[i].u.paramdesc.pparamdescex->varDefaultValue); + } +#endif + } + + /* update the index data */ + This->indices[index] = ((0x6000 | This->typeinfo->cImplTypes) << 16) | index; + This->names[index] = -1; + This->offsets[index] = offset; + + /* ??? */ + if (!This->typeinfo->res2) This->typeinfo->res2 = 0x20; + This->typeinfo->res2 <<= 1; + + /* ??? */ + if (This->typeinfo->res3 == -1) This->typeinfo->res3 = 0; + This->typeinfo->res3 += 0x38; + + /* ??? */ + if (index < 2) This->typeinfo->res2 += pFuncDesc->cParams << 4; + This->typeinfo->res3 += pFuncDesc->cParams << 4; + + /* adjust size of VTBL */ + This->typeinfo->cbSizeVft += 4; + + /* Increment the number of function elements */ + This->typeinfo->cElement += 1; + + return S_OK; +} + +/****************************************************************************** + * ICreateTypeInfo2_AddImplType {OLEAUT32} + * + * See ICreateTypeInfo_AddImplType. + */ +static HRESULT WINAPI ICreateTypeInfo2_fnAddImplType( + ICreateTypeInfo2* iface, + UINT index, + HREFTYPE hRefType) +{ + ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; + + TRACE("(%p,%d,%ld)\n", iface, index, hRefType); + + if ((This->typeinfo->typekind & 15) == TKIND_COCLASS) { + int offset; + MSFT_RefRecord *ref; + + if (index == 0) { + if (This->typeinfo->datatype1 != -1) return TYPE_E_ELEMENTNOTFOUND; + + offset = ctl2_alloc_segment(This->typelib, MSFT_SEG_REFERENCES, sizeof(MSFT_RefRecord), 0); + if (offset == -1) return E_OUTOFMEMORY; + + This->typeinfo->datatype1 = offset; + } else { + int lastoffset; + + lastoffset = ctl2_find_nth_reference(This->typelib, This->typeinfo->datatype1, index - 1); + if (lastoffset == -1) return TYPE_E_ELEMENTNOTFOUND; + + ref = (MSFT_RefRecord *)&This->typelib->typelib_segment_data[MSFT_SEG_REFERENCES][lastoffset]; + if (ref->onext != -1) return TYPE_E_ELEMENTNOTFOUND; + + offset = ctl2_alloc_segment(This->typelib, MSFT_SEG_REFERENCES, sizeof(MSFT_RefRecord), 0); + if (offset == -1) return E_OUTOFMEMORY; + + ref->onext = offset; + } + + ref = (MSFT_RefRecord *)&This->typelib->typelib_segment_data[MSFT_SEG_REFERENCES][offset]; + + ref->reftype = hRefType; + ref->flags = 0; + ref->oCustData = -1; + ref->onext = -1; + } else if ((This->typeinfo->typekind & 15) == TKIND_DISPATCH) { + FIXME("dispatch case unhandled.\n"); + } else if ((This->typeinfo->typekind & 15) == TKIND_INTERFACE) { + if (This->typeinfo->cImplTypes) { + return (index == 1)? TYPE_E_BADMODULEKIND: TYPE_E_ELEMENTNOTFOUND; + } + + if (index != 0) return TYPE_E_ELEMENTNOTFOUND; + + This->typeinfo->cImplTypes++; + + /* hacked values for IDispatch only, and maybe only for stdole. */ + This->typeinfo->cbSizeVft += 0x0c; /* hack */ + This->typeinfo->datatype1 = hRefType; + This->typeinfo->datatype2 = (3 << 16) | 1; /* ? */ + } else { + FIXME("AddImplType unsupported on typekind %d\n", This->typeinfo->typekind & 15); + return E_OUTOFMEMORY; + } + + return S_OK; +} + +/****************************************************************************** + * ICreateTypeInfo2_SetImplTypeFlags {OLEAUT32} + * + * See ICreateTypeInfo_SetImplTypeFlags. + */ +static HRESULT WINAPI ICreateTypeInfo2_fnSetImplTypeFlags( + ICreateTypeInfo2* iface, + UINT index, + INT implTypeFlags) +{ + ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; + int offset; + MSFT_RefRecord *ref; + + TRACE("(%p,%d,0x%x)\n", iface, index, implTypeFlags); + + if ((This->typeinfo->typekind & 15) != TKIND_COCLASS) { + return TYPE_E_BADMODULEKIND; + } + + offset = ctl2_find_nth_reference(This->typelib, This->typeinfo->datatype1, index); + if (offset == -1) return TYPE_E_ELEMENTNOTFOUND; + + ref = (MSFT_RefRecord *)&This->typelib->typelib_segment_data[MSFT_SEG_REFERENCES][offset]; + ref->flags = implTypeFlags; + + return S_OK; +} + +/****************************************************************************** + * ICreateTypeInfo2_SetAlignment {OLEAUT32} + * + * See ICreateTypeInfo_SetAlignment. + */ +static HRESULT WINAPI ICreateTypeInfo2_fnSetAlignment( + ICreateTypeInfo2* iface, + WORD cbAlignment) +{ + ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; + + TRACE("(%p,%d)\n", iface, cbAlignment); + + if (!cbAlignment) return E_INVALIDARG; + if (cbAlignment > 16) return E_INVALIDARG; + + This->typeinfo->typekind &= ~0xffc0; + This->typeinfo->typekind |= cbAlignment << 6; + + /* FIXME: There's probably some way to simplify this. */ + switch (This->typeinfo->typekind & 15) { + case TKIND_ALIAS: + default: + break; + + case TKIND_ENUM: + case TKIND_INTERFACE: + case TKIND_DISPATCH: + case TKIND_COCLASS: + if (cbAlignment > 4) cbAlignment = 4; + break; + + case TKIND_RECORD: + case TKIND_MODULE: + case TKIND_UNION: + cbAlignment = 1; + break; + } + + This->typeinfo->typekind |= cbAlignment << 11; + + return S_OK; +} + +/****************************************************************************** + * ICreateTypeInfo2_SetSchema {OLEAUT32} + * + * See ICreateTypeInfo_SetSchema. + */ +static HRESULT WINAPI ICreateTypeInfo2_fnSetSchema( + ICreateTypeInfo2* iface, + LPOLESTR pStrSchema) +{ + FIXME("(%p,%s), stub!\n", iface, debugstr_w(pStrSchema)); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ICreateTypeInfo2_AddVarDesc {OLEAUT32} + * + * See ICreateTypeInfo_AddVarDesc. + */ +static HRESULT WINAPI ICreateTypeInfo2_fnAddVarDesc( + ICreateTypeInfo2* iface, + UINT index, + VARDESC* pVarDesc) +{ + ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; + int offset; + INT *typedata; + int var_datawidth; + int var_alignment; + int var_type_size; + int alignment; + + TRACE("(%p,%d,%p), stub!\n", iface, index, pVarDesc); + TRACE("%ld, %p, %ld, {{%lx, %d}, {%p, %x}}, 0x%x, %d\n", pVarDesc->memid, pVarDesc->lpstrSchema, pVarDesc->u.oInst, + pVarDesc->elemdescVar.tdesc.u.hreftype, pVarDesc->elemdescVar.tdesc.vt, + pVarDesc->elemdescVar.u.paramdesc.pparamdescex, pVarDesc->elemdescVar.u.paramdesc.wParamFlags, + pVarDesc->wVarFlags, pVarDesc->varkind); + + if ((This->typeinfo->cElement >> 16) != index) { + TRACE("Out-of-order element.\n"); + return TYPE_E_ELEMENTNOTFOUND; + } + + if (!This->typedata) { + This->typedata = HeapAlloc(GetProcessHeap(), 0, 0x2000); + This->typedata[0] = 0; + } + + /* allocate type data space for us */ + offset = This->typedata[0]; + This->typedata[0] += 0x14; + typedata = This->typedata + (offset >> 2) + 1; + + /* fill out the basic type information */ + typedata[0] = 0x14 | (index << 16); + typedata[2] = pVarDesc->wVarFlags; + typedata[3] = (sizeof(VARDESC) << 16) | 0; + + /* update the index data */ + This->indices[index] = 0x40000000 + index; + This->names[index] = -1; + This->offsets[index] = offset; + + /* figure out type widths and whatnot */ + ctl2_encode_typedesc(This->typelib, &pVarDesc->elemdescVar.tdesc, + &typedata[1], &var_datawidth, &var_alignment, + &var_type_size); + + /* pad out starting position to data width */ + This->datawidth += var_alignment - 1; + This->datawidth &= ~(var_alignment - 1); + typedata[4] = This->datawidth; + + /* add the new variable to the total data width */ + This->datawidth += var_datawidth; + + /* add type description size to total required allocation */ + typedata[3] += var_type_size << 16; + + /* fix type alignment */ + alignment = (This->typeinfo->typekind >> 11) & 0x1f; + if (alignment < var_alignment) { + alignment = var_alignment; + This->typeinfo->typekind &= ~0xf800; + This->typeinfo->typekind |= alignment << 11; + } + + /* ??? */ + if (!This->typeinfo->res2) This->typeinfo->res2 = 0x1a; + if ((index == 0) || (index == 1) || (index == 2) || (index == 4) || (index == 9)) { + This->typeinfo->res2 <<= 1; + } + + /* ??? */ + if (This->typeinfo->res3 == -1) This->typeinfo->res3 = 0; + This->typeinfo->res3 += 0x2c; + + /* increment the number of variable elements */ + This->typeinfo->cElement += 0x10000; + + /* pad data width to alignment */ + This->typeinfo->size = (This->datawidth + (alignment - 1)) & ~(alignment - 1); + + return S_OK; +} + +/****************************************************************************** + * ICreateTypeInfo2_SetFuncAndParamNames {OLEAUT32} + * + * See ICreateTypeInfo_SetFuncAndParamNames. + */ +static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncAndParamNames( + ICreateTypeInfo2* iface, + UINT index, + LPOLESTR* rgszNames, + UINT cNames) +{ + ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; + + int i; + int offset; + char *namedata; + + FIXME("(%p,%d,%s,%d), stub!\n", iface, index, debugstr_w(*rgszNames), cNames); + + offset = ctl2_alloc_name(This->typelib, rgszNames[0]); + This->names[index] = offset; + + namedata = This->typelib->typelib_segment_data[MSFT_SEG_NAME] + offset; + namedata[9] &= ~0x10; + if (*((INT *)namedata) == -1) { + *((INT *)namedata) = This->typelib->typelib_typeinfo_offsets[This->typeinfo->typekind >> 16]; + } + + for (i = 1; i < cNames; i++) { + /* FIXME: Almost certainly easy to break */ + int *paramdata = &This->typedata[This->offsets[index] >> 2]; + + offset = ctl2_alloc_name(This->typelib, rgszNames[i]); + paramdata[(i * 3) + 5] = offset; + } + + return S_OK; +} + +/****************************************************************************** + * ICreateTypeInfo2_SetVarName {OLEAUT32} + * + * See ICreateTypeInfo_SetVarName. + */ +static HRESULT WINAPI ICreateTypeInfo2_fnSetVarName( + ICreateTypeInfo2* iface, + UINT index, + LPOLESTR szName) +{ + ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; + int offset; + char *namedata; + + TRACE("(%p,%d,%s), stub!\n", iface, index, debugstr_w(szName)); + + if ((This->typeinfo->cElement >> 16) <= index) { + TRACE("Out-of-order element.\n"); + return TYPE_E_ELEMENTNOTFOUND; + } + + offset = ctl2_alloc_name(This->typelib, szName); + if (offset == -1) return E_OUTOFMEMORY; + + namedata = This->typelib->typelib_segment_data[MSFT_SEG_NAME] + offset; + if (*((INT *)namedata) == -1) { + *((INT *)namedata) = This->typelib->typelib_typeinfo_offsets[This->typeinfo->typekind >> 16]; + namedata[9] |= 0x10; + } + if ((This->typeinfo->typekind & 15) == TKIND_ENUM) { + namedata[9] |= 0x20; + } + This->names[index] = offset; + + return S_OK; +} + +/****************************************************************************** + * ICreateTypeInfo2_SetTypeDescAlias {OLEAUT32} + * + * See ICreateTypeInfo_SetTypeDescAlias. + */ +static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeDescAlias( + ICreateTypeInfo2* iface, + TYPEDESC* pTDescAlias) +{ + ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; + + int encoded_typedesc; + int width; + + if ((This->typeinfo->typekind & 15) != TKIND_ALIAS) { + return TYPE_E_WRONGTYPEKIND; + } + + FIXME("(%p,%p), hack!\n", iface, pTDescAlias); + + if (ctl2_encode_typedesc(This->typelib, pTDescAlias, &encoded_typedesc, &width, NULL, NULL) == -1) { + return E_OUTOFMEMORY; + } + + This->typeinfo->size = width; + This->typeinfo->datatype1 = encoded_typedesc; + + return S_OK; +} + +/****************************************************************************** + * ICreateTypeInfo2_DefineFuncAsDllEntry {OLEAUT32} + * + * See ICreateTypeInfo_DefineFuncAsDllEntry. + */ +static HRESULT WINAPI ICreateTypeInfo2_fnDefineFuncAsDllEntry( + ICreateTypeInfo2* iface, + UINT index, + LPOLESTR szDllName, + LPOLESTR szProcName) +{ + FIXME("(%p,%d,%s,%s), stub!\n", iface, index, debugstr_w(szDllName), debugstr_w(szProcName)); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ICreateTypeInfo2_SetFuncDocString {OLEAUT32} + * + * See ICreateTypeInfo_SetFuncDocString. + */ +static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncDocString( + ICreateTypeInfo2* iface, + UINT index, + LPOLESTR szDocString) +{ + FIXME("(%p,%d,%s), stub!\n", iface, index, debugstr_w(szDocString)); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ICreateTypeInfo2_SetVarDocString {OLEAUT32} + * + * See ICreateTypeInfo_SetVarDocString. + */ +static HRESULT WINAPI ICreateTypeInfo2_fnSetVarDocString( + ICreateTypeInfo2* iface, + UINT index, + LPOLESTR szDocString) +{ + ICreateTypeInfo2Impl *This = (ICreateTypeInfo2Impl *)iface; + + FIXME("(%p,%d,%s), stub!\n", iface, index, debugstr_w(szDocString)); + + ctl2_alloc_string(This->typelib, szDocString); + + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ICreateTypeInfo2_SetFuncHelpContext {OLEAUT32} + * + * See ICreateTypeInfo_SetFuncHelpContext. + */ +static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncHelpContext( + ICreateTypeInfo2* iface, + UINT index, + DWORD dwHelpContext) +{ + FIXME("(%p,%d,%ld), stub!\n", iface, index, dwHelpContext); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ICreateTypeInfo2_SetVarHelpContext {OLEAUT32} + * + * See ICreateTypeInfo_SetVarHelpContext. + */ +static HRESULT WINAPI ICreateTypeInfo2_fnSetVarHelpContext( + ICreateTypeInfo2* iface, + UINT index, + DWORD dwHelpContext) +{ + FIXME("(%p,%d,%ld), stub!\n", iface, index, dwHelpContext); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ICreateTypeInfo2_SetMops {OLEAUT32} + * + * See ICreateTypeInfo_SetMops. + */ +static HRESULT WINAPI ICreateTypeInfo2_fnSetMops( + ICreateTypeInfo2* iface, + UINT index, + BSTR bstrMops) +{ + FIXME("(%p,%d,%p), stub!\n", iface, index, bstrMops); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ICreateTypeInfo2_SetTypeIdldesc {OLEAUT32} + * + * See ICreateTypeInfo_SetTypeIdldesc. + */ +static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeIdldesc( + ICreateTypeInfo2* iface, + IDLDESC* pIdlDesc) +{ + FIXME("(%p,%p), stub!\n", iface, pIdlDesc); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ICreateTypeInfo2_LayOut {OLEAUT32} + * + * See ICreateTypeInfo_LayOut. + */ +static HRESULT WINAPI ICreateTypeInfo2_fnLayOut( + ICreateTypeInfo2* iface) +{ + TRACE("(%p), stub!\n", iface); +/* return E_OUTOFMEMORY; */ + return S_OK; +} + +/****************************************************************************** + * ICreateTypeInfo2_DeleteFuncDesc {OLEAUT32} + * + * Delete a function description from a type. + * + * RETURNS + * + * Success: S_OK. + * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. + */ +static HRESULT WINAPI ICreateTypeInfo2_fnDeleteFuncDesc( + ICreateTypeInfo2* iface, /* [I] The typeinfo from which to delete a function. */ + UINT index) /* [I] The index of the function to delete. */ +{ + FIXME("(%p,%d), stub!\n", iface, index); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ICreateTypeInfo2_DeleteFuncDescByMemId {OLEAUT32} + * + * Delete a function description from a type. + * + * RETURNS + * + * Success: S_OK. + * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. + */ +static HRESULT WINAPI ICreateTypeInfo2_fnDeleteFuncDescByMemId( + ICreateTypeInfo2* iface, /* [I] The typeinfo from which to delete a function. */ + MEMBERID memid, /* [I] The member id of the function to delete. */ + INVOKEKIND invKind) /* [I] The invocation type of the function to delete. (?) */ +{ + FIXME("(%p,%ld,%d), stub!\n", iface, memid, invKind); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ICreateTypeInfo2_DeleteVarDesc {OLEAUT32} + * + * Delete a variable description from a type. + * + * RETURNS + * + * Success: S_OK. + * Failure: One of E_OUTOFMEMORY, E_INVALIDARG, TYPE_E_IOERROR, + * TYPE_E_INVDATAREAD, TYPE_E_UNSUPFORMAT or TYPE_E_INVALIDSTATE. + */ +static HRESULT WINAPI ICreateTypeInfo2_fnDeleteVarDesc( + ICreateTypeInfo2* iface, /* [I] The typeinfo from which to delete the variable description. */ + UINT index) /* [I] The index of the variable description to delete. */ +{ + FIXME("(%p,%d), stub!\n", iface, index); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ICreateTypeInfo2_DeleteVarDescByMemId {OLEAUT32} + * + * Delete a variable description from a type. + * + * RETURNS + * + * Success: S_OK. + * Failure: One of E_OUTOFMEMORY, E_INVALIDARG, TYPE_E_IOERROR, + * TYPE_E_INVDATAREAD, TYPE_E_UNSUPFORMAT or TYPE_E_INVALIDSTATE. + */ +static HRESULT WINAPI ICreateTypeInfo2_fnDeleteVarDescByMemId( + ICreateTypeInfo2* iface, /* [I] The typeinfo from which to delete the variable description. */ + MEMBERID memid) /* [I] The member id of the variable description to delete. */ +{ + FIXME("(%p,%ld), stub!\n", iface, memid); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ICreateTypeInfo2_DeleteImplType {OLEAUT32} + * + * Delete an interface implementation from a type. (?) + * + * RETURNS + * + * Success: S_OK. + * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. + */ +static HRESULT WINAPI ICreateTypeInfo2_fnDeleteImplType( + ICreateTypeInfo2* iface, /* [I] The typeinfo from which to delete. */ + UINT index) /* [I] The index of the interface to delete. */ +{ + FIXME("(%p,%d), stub!\n", iface, index); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ICreateTypeInfo2_SetCustData {OLEAUT32} + * + * Set the custom data for a type. + * + * RETURNS + * + * Success: S_OK. + * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. + */ +static HRESULT WINAPI ICreateTypeInfo2_fnSetCustData( + ICreateTypeInfo2* iface, /* [I] The typeinfo in which to set the custom data. */ + REFGUID guid, /* [I] The GUID used as a key to retrieve the custom data. */ + VARIANT* pVarVal) /* [I] The custom data. */ +{ + FIXME("(%p,%s,%p), stub!\n", iface, debugstr_guid(guid), pVarVal); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ICreateTypeInfo2_SetFuncCustData {OLEAUT32} + * + * Set the custom data for a function. + * + * RETURNS + * + * Success: S_OK. + * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. + */ +static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncCustData( + ICreateTypeInfo2* iface, /* [I] The typeinfo in which to set the custom data. */ + UINT index, /* [I] The index of the function for which to set the custom data. */ + REFGUID guid, /* [I] The GUID used as a key to retrieve the custom data. */ + VARIANT* pVarVal) /* [I] The custom data. */ +{ + FIXME("(%p,%d,%s,%p), stub!\n", iface, index, debugstr_guid(guid), pVarVal); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ICreateTypeInfo2_SetParamCustData {OLEAUT32} + * + * Set the custom data for a function parameter. + * + * RETURNS + * + * Success: S_OK. + * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. + */ +static HRESULT WINAPI ICreateTypeInfo2_fnSetParamCustData( + ICreateTypeInfo2* iface, /* [I] The typeinfo in which to set the custom data. */ + UINT indexFunc, /* [I] The index of the function on which the parameter resides. */ + UINT indexParam, /* [I] The index of the paramter on which to set the custom data. */ + REFGUID guid, /* [I] The GUID used as a key to retrieve the custom data. */ + VARIANT* pVarVal) /* [I] The custom data. */ +{ + FIXME("(%p,%d,%d,%s,%p), stub!\n", iface, indexFunc, indexParam, debugstr_guid(guid), pVarVal); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ICreateTypeInfo2_SetVarCustData {OLEAUT32} + * + * Set the custom data for a variable. + * + * RETURNS + * + * Success: S_OK. + * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. + */ +static HRESULT WINAPI ICreateTypeInfo2_fnSetVarCustData( + ICreateTypeInfo2* iface, /* [I] The typeinfo in which to set the custom data. */ + UINT index, /* [I] The index of the variable on which to set the custom data. */ + REFGUID guid, /* [I] The GUID used as a key to retrieve the custom data. */ + VARIANT* pVarVal) /* [I] The custom data. */ +{ + FIXME("(%p,%d,%s,%p), stub!\n", iface, index, debugstr_guid(guid), pVarVal); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ICreateTypeInfo2_SetImplTypeCustData {OLEAUT32} + * + * Set the custom data for an implemented interface. + * + * RETURNS + * + * Success: S_OK. + * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. + */ +static HRESULT WINAPI ICreateTypeInfo2_fnSetImplTypeCustData( + ICreateTypeInfo2* iface, /* [I] The typeinfo on which to set the custom data. */ + UINT index, /* [I] The index of the implemented interface on which to set the custom data. */ + REFGUID guid, /* [I] The GUID used as a key to retrieve the custom data. */ + VARIANT* pVarVal) /* [I] The custom data. */ +{ + FIXME("(%p,%d,%s,%p), stub!\n", iface, index, debugstr_guid(guid), pVarVal); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ICreateTypeInfo2_SetHelpStringContext {OLEAUT32} + * + * Set the help string context for the typeinfo. + * + * RETURNS + * + * Success: S_OK. + * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. + */ +static HRESULT WINAPI ICreateTypeInfo2_fnSetHelpStringContext( + ICreateTypeInfo2* iface, /* [I] The typeinfo on which to set the help string context. */ + ULONG dwHelpStringContext) /* [I] The help string context. */ +{ + FIXME("(%p,%ld), stub!\n", iface, dwHelpStringContext); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ICreateTypeInfo2_SetFuncHelpStringContext {OLEAUT32} + * + * Set the help string context for a function. + * + * RETURNS + * + * Success: S_OK. + * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. + */ +static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncHelpStringContext( + ICreateTypeInfo2* iface, /* [I] The typeinfo on which to set the help string context. */ + UINT index, /* [I] The index for the function on which to set the help string context. */ + ULONG dwHelpStringContext) /* [I] The help string context. */ +{ + FIXME("(%p,%d,%ld), stub!\n", iface, index, dwHelpStringContext); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ICreateTypeInfo2_SetVarHelpStringContext {OLEAUT32} + * + * Set the help string context for a variable. + * + * RETURNS + * + * Success: S_OK. + * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. + */ +static HRESULT WINAPI ICreateTypeInfo2_fnSetVarHelpStringContext( + ICreateTypeInfo2* iface, /* [I] The typeinfo on which to set the help string context. */ + UINT index, /* [I] The index of the variable on which to set the help string context. */ + ULONG dwHelpStringContext) /* [I] The help string context */ +{ + FIXME("(%p,%d,%ld), stub!\n", iface, index, dwHelpStringContext); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ICreateTypeInfo2_Invalidate {OLEAUT32} + * + * Undocumented function. (!) + */ +static HRESULT WINAPI ICreateTypeInfo2_fnInvalidate( + ICreateTypeInfo2* iface) +{ + FIXME("(%p), stub!\n", iface); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ICreateTypeInfo2_SetName {OLEAUT32} + * + * Set the name for a typeinfo. + * + * RETURNS + * + * Success: S_OK. + * Failure: One of STG_E_INSUFFICIENTMEMORY, E_OUTOFMEMORY, E_INVALIDARG or TYPE_E_INVALIDSTATE. + */ +static HRESULT WINAPI ICreateTypeInfo2_fnSetName( + ICreateTypeInfo2* iface, + LPOLESTR szName) +{ + FIXME("(%p,%s), stub!\n", iface, debugstr_w(szName)); + return E_OUTOFMEMORY; +} + +/*================== ITypeInfo2 Implementation ===================================*/ + +/****************************************************************************** + * ITypeInfo2_QueryInterface {OLEAUT32} + * + * See IUnknown_QueryInterface. + */ +static HRESULT WINAPI ITypeInfo2_fnQueryInterface(ITypeInfo2 * iface, REFIID riid, LPVOID * ppv) +{ + ICOM_THIS_From_ITypeInfo2(ICreateTypeInfo2Impl, iface); + + return ICreateTypeInfo2_QueryInterface((ICreateTypeInfo2 *)This, riid, ppv); +} + +/****************************************************************************** + * ITypeInfo2_AddRef {OLEAUT32} + * + * See IUnknown_AddRef. + */ +static ULONG WINAPI ITypeInfo2_fnAddRef(ITypeInfo2 * iface) +{ + ICOM_THIS_From_ITypeInfo2(ICreateTypeInfo2Impl, iface); + + return ICreateTypeInfo2_AddRef((ICreateTypeInfo2 *)This); +} + +/****************************************************************************** + * ITypeInfo2_Release {OLEAUT32} + * + * See IUnknown_Release. + */ +static ULONG WINAPI ITypeInfo2_fnRelease(ITypeInfo2 * iface) +{ + ICOM_THIS_From_ITypeInfo2(ICreateTypeInfo2Impl, iface); + + return ICreateTypeInfo2_Release((ICreateTypeInfo2 *)This); +} + +/****************************************************************************** + * ITypeInfo2_GetTypeAttr {OLEAUT32} + * + * See ITypeInfo_GetTypeAttr. + */ +static HRESULT WINAPI ITypeInfo2_fnGetTypeAttr( + ITypeInfo2* iface, + TYPEATTR** ppTypeAttr) +{ + FIXME("(%p,%p), stub!\n", iface, ppTypeAttr); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ITypeInfo2_GetTypeComp {OLEAUT32} + * + * See ITypeInfo_GetTypeComp. + */ +static HRESULT WINAPI ITypeInfo2_fnGetTypeComp( + ITypeInfo2* iface, + ITypeComp** ppTComp) +{ + FIXME("(%p,%p), stub!\n", iface, ppTComp); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ITypeInfo2_GetFuncDesc {OLEAUT32} + * + * See ITypeInfo_GetFuncDesc. + */ +static HRESULT WINAPI ITypeInfo2_fnGetFuncDesc( + ITypeInfo2* iface, + UINT index, + FUNCDESC** ppFuncDesc) +{ + FIXME("(%p,%d,%p), stub!\n", iface, index, ppFuncDesc); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ITypeInfo2_GetVarDesc {OLEAUT32} + * + * See ITypeInfo_GetVarDesc. + */ +static HRESULT WINAPI ITypeInfo2_fnGetVarDesc( + ITypeInfo2* iface, + UINT index, + VARDESC** ppVarDesc) +{ + FIXME("(%p,%d,%p), stub!\n", iface, index, ppVarDesc); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ITypeInfo2_GetNames {OLEAUT32} + * + * See ITypeInfo_GetNames. + */ +static HRESULT WINAPI ITypeInfo2_fnGetNames( + ITypeInfo2* iface, + MEMBERID memid, + BSTR* rgBstrNames, + UINT cMaxNames, + UINT* pcNames) +{ + FIXME("(%p,%ld,%p,%d,%p), stub!\n", iface, memid, rgBstrNames, cMaxNames, pcNames); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ITypeInfo2_GetRefTypeOfImplType {OLEAUT32} + * + * See ITypeInfo_GetRefTypeOfImplType. + */ +static HRESULT WINAPI ITypeInfo2_fnGetRefTypeOfImplType( + ITypeInfo2* iface, + UINT index, + HREFTYPE* pRefType) +{ + FIXME("(%p,%d,%p), stub!\n", iface, index, pRefType); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ITypeInfo2_GetImplTypeFlags {OLEAUT32} + * + * See ITypeInfo_GetImplTypeFlags. + */ +static HRESULT WINAPI ITypeInfo2_fnGetImplTypeFlags( + ITypeInfo2* iface, + UINT index, + INT* pImplTypeFlags) +{ + FIXME("(%p,%d,%p), stub!\n", iface, index, pImplTypeFlags); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ITypeInfo2_GetIDsOfNames {OLEAUT32} + * + * See ITypeInfo_GetIDsOfNames. + */ +static HRESULT WINAPI ITypeInfo2_fnGetIDsOfNames( + ITypeInfo2* iface, + LPOLESTR* rgszNames, + UINT cNames, + MEMBERID* pMemId) +{ + FIXME("(%p,%p,%d,%p), stub!\n", iface, rgszNames, cNames, pMemId); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ITypeInfo2_Invoke {OLEAUT32} + * + * See ITypeInfo_Invoke. + */ +static HRESULT WINAPI ITypeInfo2_fnInvoke( + ITypeInfo2* iface, + PVOID pvInstance, + MEMBERID memid, + WORD wFlags, + DISPPARAMS* pDispParams, + VARIANT* pVarResult, + EXCEPINFO* pExcepInfo, + UINT* puArgErr) +{ + FIXME("(%p,%p,%ld,%x,%p,%p,%p,%p), stub!\n", iface, pvInstance, memid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ITypeInfo2_GetDocumentation {OLEAUT32} + * + * See ITypeInfo_GetDocumentation. + */ +static HRESULT WINAPI ITypeInfo2_fnGetDocumentation( + ITypeInfo2* iface, + MEMBERID memid, + BSTR* pBstrName, + BSTR* pBstrDocString, + DWORD* pdwHelpContext, + BSTR* pBstrHelpFile) +{ + FIXME("(%p,%ld,%p,%p,%p,%p), stub!\n", iface, memid, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ITypeInfo2_GetDllEntry {OLEAUT32} + * + * See ITypeInfo_GetDllEntry. + */ +static HRESULT WINAPI ITypeInfo2_fnGetDllEntry( + ITypeInfo2* iface, + MEMBERID memid, + INVOKEKIND invKind, + BSTR* pBstrDllName, + BSTR* pBstrName, + WORD* pwOrdinal) +{ + FIXME("(%p,%ld,%d,%p,%p,%p), stub!\n", iface, memid, invKind, pBstrDllName, pBstrName, pwOrdinal); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ITypeInfo2_GetRefTypeInfo {OLEAUT32} + * + * See ITypeInfo_GetRefTypeInfo. + */ +static HRESULT WINAPI ITypeInfo2_fnGetRefTypeInfo( + ITypeInfo2* iface, + HREFTYPE hRefType, + ITypeInfo** ppTInfo) +{ + FIXME("(%p,%ld,%p), stub!\n", iface, hRefType, ppTInfo); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ITypeInfo2_AddressOfMember {OLEAUT32} + * + * See ITypeInfo_AddressOfMember. + */ +static HRESULT WINAPI ITypeInfo2_fnAddressOfMember( + ITypeInfo2* iface, + MEMBERID memid, + INVOKEKIND invKind, + PVOID* ppv) +{ + FIXME("(%p,%ld,%d,%p), stub!\n", iface, memid, invKind, ppv); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ITypeInfo2_CreateInstance {OLEAUT32} + * + * See ITypeInfo_CreateInstance. + */ +static HRESULT WINAPI ITypeInfo2_fnCreateInstance( + ITypeInfo2* iface, + IUnknown* pUnkOuter, + REFIID riid, + PVOID* ppvObj) +{ + FIXME("(%p,%p,%s,%p), stub!\n", iface, pUnkOuter, debugstr_guid(riid), ppvObj); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ITypeInfo2_GetMops {OLEAUT32} + * + * See ITypeInfo_GetMops. + */ +static HRESULT WINAPI ITypeInfo2_fnGetMops( + ITypeInfo2* iface, + MEMBERID memid, + BSTR* pBstrMops) +{ + FIXME("(%p,%ld,%p), stub!\n", iface, memid, pBstrMops); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ITypeInfo2_GetContainingTypeLib {OLEAUT32} + * + * See ITypeInfo_GetContainingTypeLib. + */ +static HRESULT WINAPI ITypeInfo2_fnGetContainingTypeLib( + ITypeInfo2* iface, + ITypeLib** ppTLib, + UINT* pIndex) +{ + ICOM_THIS_From_ITypeInfo2(ICreateTypeInfo2Impl, iface); + + TRACE("(%p,%p,%p)\n", iface, ppTLib, pIndex); + + *ppTLib = (ITypeLib *)&This->typelib->lpVtblTypeLib2; + This->typelib->ref++; + *pIndex = This->typeinfo->typekind >> 16; + + return S_OK; +} + +/****************************************************************************** + * ITypeInfo2_ReleaseTypeAttr {OLEAUT32} + * + * See ITypeInfo_ReleaseTypeAttr. + */ +static void WINAPI ITypeInfo2_fnReleaseTypeAttr( + ITypeInfo2* iface, + TYPEATTR* pTypeAttr) +{ + FIXME("(%p,%p), stub!\n", iface, pTypeAttr); +} + +/****************************************************************************** + * ITypeInfo2_ReleaseFuncDesc {OLEAUT32} + * + * See ITypeInfo_ReleaseFuncDesc. + */ +static void WINAPI ITypeInfo2_fnReleaseFuncDesc( + ITypeInfo2* iface, + FUNCDESC* pFuncDesc) +{ + FIXME("(%p,%p), stub!\n", iface, pFuncDesc); +} + +/****************************************************************************** + * ITypeInfo2_ReleaseVarDesc {OLEAUT32} + * + * See ITypeInfo_ReleaseVarDesc. + */ +static void WINAPI ITypeInfo2_fnReleaseVarDesc( + ITypeInfo2* iface, + VARDESC* pVarDesc) +{ + FIXME("(%p,%p), stub!\n", iface, pVarDesc); +} + +/****************************************************************************** + * ITypeInfo2_GetTypeKind {OLEAUT32} + * + * Get the TYPEKIND value for a TypeInfo. + * + * RETURNS + * + * Success: S_OK. + * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. + */ +static HRESULT WINAPI ITypeInfo2_fnGetTypeKind( + ITypeInfo2* iface, /* [I] The TypeInfo to obtain the typekind for. */ + TYPEKIND* pTypeKind) /* [O] The typekind for this TypeInfo. */ +{ + FIXME("(%p,%p), stub!\n", iface, pTypeKind); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ITypeInfo2_GetTypeFlags {OLEAUT32} + * + * Get the Type Flags for a TypeInfo. + * + * RETURNS + * + * Success: S_OK. + * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. + */ +static HRESULT WINAPI ITypeInfo2_fnGetTypeFlags( + ITypeInfo2* iface, /* [I] The TypeInfo to obtain the typeflags for. */ + ULONG* pTypeFlags) /* [O] The type flags for this TypeInfo. */ +{ + FIXME("(%p,%p), stub!\n", iface, pTypeFlags); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ITypeInfo2_GetFuncIndexOfMemId {OLEAUT32} + * + * Gets the index of a function given its member id. + * + * RETURNS + * + * Success: S_OK. + * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. + */ +static HRESULT WINAPI ITypeInfo2_fnGetFuncIndexOfMemId( + ITypeInfo2* iface, /* [I] The TypeInfo in which to find the function. */ + MEMBERID memid, /* [I] The member id for the function. */ + INVOKEKIND invKind, /* [I] The invocation kind for the function. */ + UINT* pFuncIndex) /* [O] The index of the function. */ +{ + FIXME("(%p,%ld,%d,%p), stub!\n", iface, memid, invKind, pFuncIndex); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ITypeInfo2_GetVarIndexOfMemId {OLEAUT32} + * + * Gets the index of a variable given its member id. + * + * RETURNS + * + * Success: S_OK. + * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. + */ +static HRESULT WINAPI ITypeInfo2_fnGetVarIndexOfMemId( + ITypeInfo2* iface, /* [I] The TypeInfo in which to find the variable. */ + MEMBERID memid, /* [I] The member id for the variable. */ + UINT* pVarIndex) /* [O] The index of the variable. */ +{ + FIXME("(%p,%ld,%p), stub!\n", iface, memid, pVarIndex); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ITypeInfo2_GetCustData {OLEAUT32} + * + * Gets a custom data element from a TypeInfo. + * + * RETURNS + * + * Success: S_OK. + * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. + */ +static HRESULT WINAPI ITypeInfo2_fnGetCustData( + ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */ + REFGUID guid, /* [I] The GUID under which the custom data is stored. */ + VARIANT* pVarVal) /* [O] The custom data. */ +{ + FIXME("(%p,%s,%p), stub!\n", iface, debugstr_guid(guid), pVarVal); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ITypeInfo2_GetFuncCustData {OLEAUT32} + * + * Gets a custom data element from a function. + * + * RETURNS + * + * Success: S_OK. + * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. + */ +static HRESULT WINAPI ITypeInfo2_fnGetFuncCustData( + ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */ + UINT index, /* [I] The index of the function for which to retrieve the custom data. */ + REFGUID guid, /* [I] The GUID under which the custom data is stored. */ + VARIANT* pVarVal) /* [O] The custom data. */ +{ + FIXME("(%p,%d,%s,%p), stub!\n", iface, index, debugstr_guid(guid), pVarVal); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ITypeInfo2_GetParamCustData {OLEAUT32} + * + * Gets a custom data element from a parameter. + * + * RETURNS + * + * Success: S_OK. + * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. + */ +static HRESULT WINAPI ITypeInfo2_fnGetParamCustData( + ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */ + UINT indexFunc, /* [I] The index of the function for which to retrieve the custom data. */ + UINT indexParam, /* [I] The index of the parameter for which to retrieve the custom data. */ + REFGUID guid, /* [I] The GUID under which the custom data is stored. */ + VARIANT* pVarVal) /* [O] The custom data. */ +{ + FIXME("(%p,%d,%d,%s,%p), stub!\n", iface, indexFunc, indexParam, debugstr_guid(guid), pVarVal); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ITypeInfo2_GetVarCustData {OLEAUT32} + * + * Gets a custom data element from a variable. + * + * RETURNS + * + * Success: S_OK. + * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. + */ +static HRESULT WINAPI ITypeInfo2_fnGetVarCustData( + ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */ + UINT index, /* [I] The index of the variable for which to retrieve the custom data. */ + REFGUID guid, /* [I] The GUID under which the custom data is stored. */ + VARIANT* pVarVal) /* [O] The custom data. */ +{ + FIXME("(%p,%d,%s,%p), stub!\n", iface, index, debugstr_guid(guid), pVarVal); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ITypeInfo2_GetImplTypeCustData {OLEAUT32} + * + * Gets a custom data element from an implemented type of a TypeInfo. + * + * RETURNS + * + * Success: S_OK. + * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. + */ +static HRESULT WINAPI ITypeInfo2_fnGetImplTypeCustData( + ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */ + UINT index, /* [I] The index of the implemented type for which to retrieve the custom data. */ + REFGUID guid, /* [I] The GUID under which the custom data is stored. */ + VARIANT* pVarVal) /* [O] The custom data. */ +{ + FIXME("(%p,%d,%s,%p), stub!\n", iface, index, debugstr_guid(guid), pVarVal); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ITypeInfo2_GetDocumentation2 {OLEAUT32} + * + * Gets some documentation from a TypeInfo in a locale-aware fashion. + * + * RETURNS + * + * Success: S_OK. + * Failure: One of STG_E_INSUFFICIENTMEMORY or E_INVALIDARG. + */ +static HRESULT WINAPI ITypeInfo2_fnGetDocumentation2( + ITypeInfo2* iface, /* [I] The TypeInfo to retrieve the documentation from. */ + MEMBERID memid, /* [I] The member id (why?). */ + LCID lcid, /* [I] The locale (why?). */ + BSTR* pbstrHelpString, /* [O] The help string. */ + DWORD* pdwHelpStringContext, /* [O] The help string context. */ + BSTR* pbstrHelpStringDll) /* [O] The help file name. */ +{ + FIXME("(%p,%ld,%ld,%p,%p,%p), stub!\n", iface, memid, lcid, pbstrHelpString, pdwHelpStringContext, pbstrHelpStringDll); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ITypeInfo2_GetAllCustData {OLEAUT32} + * + * Gets all of the custom data associated with a TypeInfo. + * + * RETURNS + * + * Success: S_OK. + * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. + */ +static HRESULT WINAPI ITypeInfo2_fnGetAllCustData( + ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */ + CUSTDATA* pCustData) /* [O] A pointer to the custom data. */ +{ + FIXME("(%p,%p), stub!\n", iface, pCustData); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ITypeInfo2_GetAllFuncCustData {OLEAUT32} + * + * Gets all of the custom data associated with a function. + * + * RETURNS + * + * Success: S_OK. + * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. + */ +static HRESULT WINAPI ITypeInfo2_fnGetAllFuncCustData( + ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */ + UINT index, /* [I] The index of the function for which to retrieve the custom data. */ + CUSTDATA* pCustData) /* [O] A pointer to the custom data. */ +{ + FIXME("(%p,%d,%p), stub!\n", iface, index, pCustData); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ITypeInfo2_GetAllParamCustData {OLEAUT32} + * + * Gets all of the custom data associated with a parameter. + * + * RETURNS + * + * Success: S_OK. + * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. + */ +static HRESULT WINAPI ITypeInfo2_fnGetAllParamCustData( + ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */ + UINT indexFunc, /* [I] The index of the function for which to retrieve the custom data. */ + UINT indexParam, /* [I] The index of the parameter for which to retrieve the custom data. */ + CUSTDATA* pCustData) /* [O] A pointer to the custom data. */ +{ + FIXME("(%p,%d,%d,%p), stub!\n", iface, indexFunc, indexParam, pCustData); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ITypeInfo2_GetAllVarCustData {OLEAUT32} + * + * Gets all of the custom data associated with a variable. + * + * RETURNS + * + * Success: S_OK. + * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. + */ +static HRESULT WINAPI ITypeInfo2_fnGetAllVarCustData( + ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */ + UINT index, /* [I] The index of the variable for which to retrieve the custom data. */ + CUSTDATA* pCustData) /* [O] A pointer to the custom data. */ +{ + FIXME("(%p,%d,%p), stub!\n", iface, index, pCustData); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ITypeInfo2_GetAllImplTypeCustData {OLEAUT32} + * + * Gets all of the custom data associated with an implemented type. + * + * RETURNS + * + * Success: S_OK. + * Failure: One of E_OUTOFMEMORY or E_INVALIDARG. + */ +static HRESULT WINAPI ITypeInfo2_fnGetAllImplTypeCustData( + ITypeInfo2* iface, /* [I] The TypeInfo in which to find the custom data. */ + UINT index, /* [I] The index of the implemented type for which to retrieve the custom data. */ + CUSTDATA* pCustData) /* [O] A pointer to the custom data. */ +{ + FIXME("(%p,%d,%p), stub!\n", iface, index, pCustData); + return E_OUTOFMEMORY; +} + + +/*================== ICreateTypeInfo2 & ITypeInfo2 VTABLEs And Creation ===================================*/ + +static ICreateTypeInfo2Vtbl ctypeinfo2vt = +{ + + ICreateTypeInfo2_fnQueryInterface, + ICreateTypeInfo2_fnAddRef, + ICreateTypeInfo2_fnRelease, + + ICreateTypeInfo2_fnSetGuid, + ICreateTypeInfo2_fnSetTypeFlags, + ICreateTypeInfo2_fnSetDocString, + ICreateTypeInfo2_fnSetHelpContext, + ICreateTypeInfo2_fnSetVersion, + ICreateTypeInfo2_fnAddRefTypeInfo, + ICreateTypeInfo2_fnAddFuncDesc, + ICreateTypeInfo2_fnAddImplType, + ICreateTypeInfo2_fnSetImplTypeFlags, + ICreateTypeInfo2_fnSetAlignment, + ICreateTypeInfo2_fnSetSchema, + ICreateTypeInfo2_fnAddVarDesc, + ICreateTypeInfo2_fnSetFuncAndParamNames, + ICreateTypeInfo2_fnSetVarName, + ICreateTypeInfo2_fnSetTypeDescAlias, + ICreateTypeInfo2_fnDefineFuncAsDllEntry, + ICreateTypeInfo2_fnSetFuncDocString, + ICreateTypeInfo2_fnSetVarDocString, + ICreateTypeInfo2_fnSetFuncHelpContext, + ICreateTypeInfo2_fnSetVarHelpContext, + ICreateTypeInfo2_fnSetMops, + ICreateTypeInfo2_fnSetTypeIdldesc, + ICreateTypeInfo2_fnLayOut, + + ICreateTypeInfo2_fnDeleteFuncDesc, + ICreateTypeInfo2_fnDeleteFuncDescByMemId, + ICreateTypeInfo2_fnDeleteVarDesc, + ICreateTypeInfo2_fnDeleteVarDescByMemId, + ICreateTypeInfo2_fnDeleteImplType, + ICreateTypeInfo2_fnSetCustData, + ICreateTypeInfo2_fnSetFuncCustData, + ICreateTypeInfo2_fnSetParamCustData, + ICreateTypeInfo2_fnSetVarCustData, + ICreateTypeInfo2_fnSetImplTypeCustData, + ICreateTypeInfo2_fnSetHelpStringContext, + ICreateTypeInfo2_fnSetFuncHelpStringContext, + ICreateTypeInfo2_fnSetVarHelpStringContext, + ICreateTypeInfo2_fnInvalidate, + ICreateTypeInfo2_fnSetName +}; + +static ITypeInfo2Vtbl typeinfo2vt = +{ + + ITypeInfo2_fnQueryInterface, + ITypeInfo2_fnAddRef, + ITypeInfo2_fnRelease, + + ITypeInfo2_fnGetTypeAttr, + ITypeInfo2_fnGetTypeComp, + ITypeInfo2_fnGetFuncDesc, + ITypeInfo2_fnGetVarDesc, + ITypeInfo2_fnGetNames, + ITypeInfo2_fnGetRefTypeOfImplType, + ITypeInfo2_fnGetImplTypeFlags, + ITypeInfo2_fnGetIDsOfNames, + ITypeInfo2_fnInvoke, + ITypeInfo2_fnGetDocumentation, + ITypeInfo2_fnGetDllEntry, + ITypeInfo2_fnGetRefTypeInfo, + ITypeInfo2_fnAddressOfMember, + ITypeInfo2_fnCreateInstance, + ITypeInfo2_fnGetMops, + ITypeInfo2_fnGetContainingTypeLib, + ITypeInfo2_fnReleaseTypeAttr, + ITypeInfo2_fnReleaseFuncDesc, + ITypeInfo2_fnReleaseVarDesc, + + ITypeInfo2_fnGetTypeKind, + ITypeInfo2_fnGetTypeFlags, + ITypeInfo2_fnGetFuncIndexOfMemId, + ITypeInfo2_fnGetVarIndexOfMemId, + ITypeInfo2_fnGetCustData, + ITypeInfo2_fnGetFuncCustData, + ITypeInfo2_fnGetParamCustData, + ITypeInfo2_fnGetVarCustData, + ITypeInfo2_fnGetImplTypeCustData, + ITypeInfo2_fnGetDocumentation2, + ITypeInfo2_fnGetAllCustData, + ITypeInfo2_fnGetAllFuncCustData, + ITypeInfo2_fnGetAllParamCustData, + ITypeInfo2_fnGetAllVarCustData, + ITypeInfo2_fnGetAllImplTypeCustData, +}; + +static ICreateTypeInfo2 *ICreateTypeInfo2_Constructor(ICreateTypeLib2Impl *typelib, WCHAR *szName, TYPEKIND tkind) +{ + ICreateTypeInfo2Impl *pCreateTypeInfo2Impl; + + int nameoffset; + int typeinfo_offset; + MSFT_TypeInfoBase *typeinfo; + + TRACE("Constructing ICreateTypeInfo2 for %s with tkind %d\n", debugstr_w(szName), tkind); + + pCreateTypeInfo2Impl = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ICreateTypeInfo2Impl)); + if (!pCreateTypeInfo2Impl) return NULL; + + pCreateTypeInfo2Impl->lpVtbl = &ctypeinfo2vt; + pCreateTypeInfo2Impl->lpVtblTypeInfo2 = &typeinfo2vt; + pCreateTypeInfo2Impl->ref = 1; + + pCreateTypeInfo2Impl->typelib = typelib; + typelib->ref++; + + nameoffset = ctl2_alloc_name(typelib, szName); + typeinfo_offset = ctl2_alloc_typeinfo(typelib, nameoffset); + typeinfo = (MSFT_TypeInfoBase *)&typelib->typelib_segment_data[MSFT_SEG_TYPEINFO][typeinfo_offset]; + + typelib->typelib_segment_data[MSFT_SEG_NAME][nameoffset + 9] = 0x38; + *((int *)&typelib->typelib_segment_data[MSFT_SEG_NAME][nameoffset]) = typeinfo_offset; + + pCreateTypeInfo2Impl->typeinfo = typeinfo; + + typeinfo->typekind |= tkind | 0x20; + ICreateTypeInfo2_SetAlignment((ICreateTypeInfo2 *)pCreateTypeInfo2Impl, 4); + + switch (tkind) { + case TKIND_ENUM: + case TKIND_INTERFACE: + case TKIND_DISPATCH: + case TKIND_COCLASS: + typeinfo->size = 4; + break; + + case TKIND_RECORD: + case TKIND_UNION: + typeinfo->size = 0; + break; + + case TKIND_MODULE: + typeinfo->size = 2; + break; + + case TKIND_ALIAS: + typeinfo->size = -0x75; + break; + + default: + FIXME("(%s,%d), unrecognized typekind %d\n", debugstr_w(szName), tkind, tkind); + typeinfo->size = 0xdeadbeef; + break; + } + + if (typelib->last_typeinfo) typelib->last_typeinfo->next_typeinfo = pCreateTypeInfo2Impl; + typelib->last_typeinfo = pCreateTypeInfo2Impl; + if (!typelib->typeinfos) typelib->typeinfos = pCreateTypeInfo2Impl; + + TRACE(" -- %p\n", pCreateTypeInfo2Impl); + + return (ICreateTypeInfo2 *)pCreateTypeInfo2Impl; +} + + +/*================== ICreateTypeLib2 Implementation ===================================*/ + +/****************************************************************************** + * ICreateTypeLib2_QueryInterface {OLEAUT32} + * + * See IUnknown_QueryInterface. + */ +static HRESULT WINAPI ICreateTypeLib2_fnQueryInterface( + ICreateTypeLib2 * iface, + REFIID riid, + VOID **ppvObject) +{ + ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface; + + TRACE("(%p)->(IID: %s)\n",This,debugstr_guid(riid)); + + *ppvObject=NULL; + if(IsEqualIID(riid, &IID_IUnknown) || + IsEqualIID(riid,&IID_ICreateTypeLib)|| + IsEqualIID(riid,&IID_ICreateTypeLib2)) + { + *ppvObject = This; + } else if (IsEqualIID(riid, &IID_ITypeLib) || + IsEqualIID(riid, &IID_ITypeLib2)) { + *ppvObject = &This->lpVtblTypeLib2; + } + + if(*ppvObject) + { + ICreateTypeLib2_AddRef(iface); + TRACE("-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject); + return S_OK; + } + TRACE("-- Interface: E_NOINTERFACE\n"); + return E_NOINTERFACE; +} + +/****************************************************************************** + * ICreateTypeLib2_AddRef {OLEAUT32} + * + * See IUnknown_AddRef. + */ +static ULONG WINAPI ICreateTypeLib2_fnAddRef(ICreateTypeLib2 *iface) +{ + ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface; + + TRACE("(%p)->ref was %u\n",This, This->ref); + + return ++(This->ref); +} + +/****************************************************************************** + * ICreateTypeLib2_Release {OLEAUT32} + * + * See IUnknown_Release. + */ +static ULONG WINAPI ICreateTypeLib2_fnRelease(ICreateTypeLib2 *iface) +{ + ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface; + + --(This->ref); + + TRACE("(%p)->(%u)\n",This, This->ref); + + if (!This->ref) { + int i; + + for (i = 0; i < MSFT_SEG_MAX; i++) { + if (This->typelib_segment_data[i]) { + HeapFree(GetProcessHeap(), 0, This->typelib_segment_data[i]); + This->typelib_segment_data[i] = NULL; + } + } + + if (This->filename) { + HeapFree(GetProcessHeap(), 0, This->filename); + This->filename = NULL; + } + + while (This->typeinfos) { + ICreateTypeInfo2Impl *typeinfo = This->typeinfos; + This->typeinfos = typeinfo->next_typeinfo; + if (typeinfo->typedata) HeapFree(GetProcessHeap(), 0, typeinfo->typedata); + HeapFree(GetProcessHeap(), 0, typeinfo); + } + + HeapFree(GetProcessHeap(),0,This); + return 0; + } + + return This->ref; +} + + +/****************************************************************************** + * ICreateTypeLib2_CreateTypeInfo {OLEAUT32} + * + * See ICreateTypeLib_CreateTypeInfo. + */ +static HRESULT WINAPI ICreateTypeLib2_fnCreateTypeInfo( + ICreateTypeLib2 * iface, + LPOLESTR szName, + TYPEKIND tkind, + ICreateTypeInfo **ppCTInfo) +{ + ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface; + + TRACE("(%p,%s,%d,%p)\n", iface, debugstr_w(szName), tkind, ppCTInfo); + + *ppCTInfo = (ICreateTypeInfo *)ICreateTypeInfo2_Constructor(This, szName, tkind); + + if (!*ppCTInfo) return E_OUTOFMEMORY; + + return S_OK; +} + +/****************************************************************************** + * ICreateTypeLib2_SetName {OLEAUT32} + * + * See ICreateTypeLib_SetName. + */ +static HRESULT WINAPI ICreateTypeLib2_fnSetName( + ICreateTypeLib2 * iface, + LPOLESTR szName) +{ + ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface; + + int offset; + + TRACE("(%p,%s)\n", iface, debugstr_w(szName)); + + offset = ctl2_alloc_name(This, szName); + if (offset == -1) return E_OUTOFMEMORY; + This->typelib_header.NameOffset = offset; + return S_OK; +} + +/****************************************************************************** + * ICreateTypeLib2_SetVersion {OLEAUT32} + * + * See ICreateTypeLib_SetVersion. + */ +static HRESULT WINAPI ICreateTypeLib2_fnSetVersion(ICreateTypeLib2 * iface, WORD wMajorVerNum, WORD wMinorVerNum) +{ + ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface; + + TRACE("(%p,%d,%d)\n", iface, wMajorVerNum, wMinorVerNum); + + This->typelib_header.version = wMajorVerNum | (wMinorVerNum << 16); + return S_OK; +} + +/****************************************************************************** + * ICreateTypeLib2_SetGuid {OLEAUT32} + * + * See ICreateTypeLib_SetGuid. + */ +static HRESULT WINAPI ICreateTypeLib2_fnSetGuid(ICreateTypeLib2 * iface, REFGUID guid) +{ + ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface; + + MSFT_GuidEntry guidentry; + int offset; + + TRACE("(%p,%s)\n", iface, debugstr_guid(guid)); + + guidentry.guid = *guid; + guidentry.hreftype = -2; + guidentry.next_hash = -1; + + offset = ctl2_alloc_guid(This, &guidentry); + + if (offset == -1) return E_OUTOFMEMORY; + + This->typelib_header.posguid = offset; + + return S_OK; +} + +/****************************************************************************** + * ICreateTypeLib2_SetDocString {OLEAUT32} + * + * See ICreateTypeLib_SetDocString. + */ +static HRESULT WINAPI ICreateTypeLib2_fnSetDocString(ICreateTypeLib2 * iface, LPOLESTR szDoc) +{ + ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface; + + int offset; + + TRACE("(%p,%s)\n", iface, debugstr_w(szDoc)); + + offset = ctl2_alloc_string(This, szDoc); + if (offset == -1) return E_OUTOFMEMORY; + This->typelib_header.helpstring = offset; + return S_OK; +} + +/****************************************************************************** + * ICreateTypeLib2_SetHelpFileName {OLEAUT32} + * + * See ICreateTypeLib_SetHelpFileName. + */ +static HRESULT WINAPI ICreateTypeLib2_fnSetHelpFileName(ICreateTypeLib2 * iface, LPOLESTR szHelpFileName) +{ + ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface; + + int offset; + + TRACE("(%p,%s)\n", iface, debugstr_w(szHelpFileName)); + + offset = ctl2_alloc_string(This, szHelpFileName); + if (offset == -1) return E_OUTOFMEMORY; + This->typelib_header.helpfile = offset; + This->typelib_header.varflags |= 0x10; + return S_OK; +} + +/****************************************************************************** + * ICreateTypeLib2_SetHelpContext {OLEAUT32} + * + * See ICreateTypeLib_SetHelpContext. + */ +static HRESULT WINAPI ICreateTypeLib2_fnSetHelpContext(ICreateTypeLib2 * iface, DWORD dwHelpContext) +{ + FIXME("(%p,%ld), stub!\n", iface, dwHelpContext); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ICreateTypeLib2_SetLcid {OLEAUT32} + * + * See ICreateTypeLib_SetLcid. + */ +static HRESULT WINAPI ICreateTypeLib2_fnSetLcid(ICreateTypeLib2 * iface, LCID lcid) +{ + ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface; + + TRACE("(%p,%ld)\n", iface, lcid); + + This->typelib_header.lcid2 = lcid; + + return S_OK; +} + +/****************************************************************************** + * ICreateTypeLib2_SetLibFlags {OLEAUT32} + * + * See ICreateTypeLib_SetLibFlags. + */ +static HRESULT WINAPI ICreateTypeLib2_fnSetLibFlags(ICreateTypeLib2 * iface, UINT uLibFlags) +{ + ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface; + + TRACE("(%p,0x%x)\n", iface, uLibFlags); + + This->typelib_header.flags = uLibFlags; + + return S_OK; +} + +static int ctl2_write_chunk(HANDLE hFile, void *segment, int length) +{ + DWORD dwWritten; + if (!WriteFile(hFile, segment, length, &dwWritten, 0)) { + CloseHandle(hFile); + return 0; + } + return -1; +} + +static int ctl2_write_segment(ICreateTypeLib2Impl *This, HANDLE hFile, int segment) +{ + DWORD dwWritten; + if (!WriteFile(hFile, This->typelib_segment_data[segment], + This->typelib_segdir[segment].length, &dwWritten, 0)) { + CloseHandle(hFile); + return 0; + } + + return -1; +} + +static void ctl2_finalize_typeinfos(ICreateTypeLib2Impl *This, int filesize) +{ + ICreateTypeInfo2Impl *typeinfo; + + for (typeinfo = This->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) { + typeinfo->typeinfo->memoffset = filesize; + if (typeinfo->typedata) { + ICreateTypeInfo2_fnLayOut((ICreateTypeInfo2 *)typeinfo); + filesize += typeinfo->typedata[0] + ((typeinfo->typeinfo->cElement >> 16) * 12) + ((typeinfo->typeinfo->cElement & 0xffff) * 12) + 4; + } + } +} + +static int ctl2_finalize_segment(ICreateTypeLib2Impl *This, int filepos, int segment) +{ + if (This->typelib_segdir[segment].length) { + This->typelib_segdir[segment].offset = filepos; + } else { + This->typelib_segdir[segment].offset = -1; + } + + return This->typelib_segdir[segment].length; +} + +static void ctl2_write_typeinfos(ICreateTypeLib2Impl *This, HANDLE hFile) +{ + ICreateTypeInfo2Impl *typeinfo; + + for (typeinfo = This->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) { + if (!typeinfo->typedata) continue; + + ctl2_write_chunk(hFile, typeinfo->typedata, typeinfo->typedata[0] + 4); + ctl2_write_chunk(hFile, typeinfo->indices, ((typeinfo->typeinfo->cElement & 0xffff) + (typeinfo->typeinfo->cElement >> 16)) * 4); + ctl2_write_chunk(hFile, typeinfo->names, ((typeinfo->typeinfo->cElement & 0xffff) + (typeinfo->typeinfo->cElement >> 16)) * 4); + ctl2_write_chunk(hFile, typeinfo->offsets, ((typeinfo->typeinfo->cElement & 0xffff) + (typeinfo->typeinfo->cElement >> 16)) * 4); + } +} + +/****************************************************************************** + * ICreateTypeLib2_SaveAllChanges {OLEAUT32} + * + * See ICreateTypeLib_SaveAllChanges. + */ +static HRESULT WINAPI ICreateTypeLib2_fnSaveAllChanges(ICreateTypeLib2 * iface) +{ + ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface; + + int retval; + int filepos; + HANDLE hFile; + + TRACE("(%p)\n", iface); + + retval = TYPE_E_IOERROR; + + hFile = CreateFileW(This->filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); + if (hFile == INVALID_HANDLE_VALUE) return retval; + + filepos = sizeof(MSFT_Header) + sizeof(MSFT_SegDir); + filepos += This->typelib_header.nrtypeinfos * 4; + + filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_TYPEINFO); + filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_GUIDHASH); + filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_GUID); + filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_IMPORTINFO); + filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_IMPORTFILES); + filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_REFERENCES); + filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_NAMEHASH); + filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_NAME); + filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_STRING); + filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_TYPEDESC); + filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_ARRAYDESC); + filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_CUSTDATA); + filepos += ctl2_finalize_segment(This, filepos, MSFT_SEG_CUSTDATAGUID); + + ctl2_finalize_typeinfos(This, filepos); + + if (!ctl2_write_chunk(hFile, &This->typelib_header, sizeof(This->typelib_header))) return retval; + if (!ctl2_write_chunk(hFile, This->typelib_typeinfo_offsets, This->typelib_header.nrtypeinfos * 4)) return retval; + if (!ctl2_write_chunk(hFile, &This->typelib_segdir, sizeof(This->typelib_segdir))) return retval; + if (!ctl2_write_segment(This, hFile, MSFT_SEG_TYPEINFO )) return retval; + if (!ctl2_write_segment(This, hFile, MSFT_SEG_GUIDHASH )) return retval; + if (!ctl2_write_segment(This, hFile, MSFT_SEG_GUID )) return retval; + if (!ctl2_write_segment(This, hFile, MSFT_SEG_IMPORTINFO )) return retval; + if (!ctl2_write_segment(This, hFile, MSFT_SEG_IMPORTFILES )) return retval; + if (!ctl2_write_segment(This, hFile, MSFT_SEG_REFERENCES )) return retval; + if (!ctl2_write_segment(This, hFile, MSFT_SEG_NAMEHASH )) return retval; + if (!ctl2_write_segment(This, hFile, MSFT_SEG_NAME )) return retval; + if (!ctl2_write_segment(This, hFile, MSFT_SEG_STRING )) return retval; + if (!ctl2_write_segment(This, hFile, MSFT_SEG_TYPEDESC )) return retval; + if (!ctl2_write_segment(This, hFile, MSFT_SEG_ARRAYDESC )) return retval; + if (!ctl2_write_segment(This, hFile, MSFT_SEG_CUSTDATA )) return retval; + if (!ctl2_write_segment(This, hFile, MSFT_SEG_CUSTDATAGUID)) return retval; + + ctl2_write_typeinfos(This, hFile); + + if (!CloseHandle(hFile)) return retval; + + retval = S_OK; + return retval; +} + + +/****************************************************************************** + * ICreateTypeLib2_DeleteTypeInfo {OLEAUT32} + * + * Deletes a named TypeInfo from a type library. + * + * RETURNS + * + * Success: S_OK + * Failure: E_OUTOFMEMORY or E_INVALIDARG. + */ +static HRESULT WINAPI ICreateTypeLib2_fnDeleteTypeInfo( + ICreateTypeLib2 * iface, /* [I] The type library to delete from. */ + LPOLESTR szName) /* [I] The name of the typeinfo to delete. */ +{ + FIXME("(%p,%s), stub!\n", iface, debugstr_w(szName)); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ICreateTypeLib2_SetCustData {OLEAUT32} + * + * Sets custom data for a type library. + * + * RETURNS + * + * Success: S_OK + * Failure: E_OUTOFMEMORY or E_INVALIDARG. + */ +static HRESULT WINAPI ICreateTypeLib2_fnSetCustData( + ICreateTypeLib2 * iface, /* [I] The type library to store the custom data in. */ + REFGUID guid, /* [I] The GUID used as a key to retrieve the custom data. */ + VARIANT *pVarVal) /* [I] The custom data itself. */ +{ + ICreateTypeLib2Impl *This = (ICreateTypeLib2Impl *)iface; + + TRACE("(%p,%s,%p)\n", iface, debugstr_guid(guid), pVarVal); + + return ctl2_set_custdata(This, guid, pVarVal, &This->typelib_header.CustomDataOffset); +} + +/****************************************************************************** + * ICreateTypeLib2_SetHelpStringContext {OLEAUT32} + * + * Sets a context number for the library help string. + * + * RETURNS + * + * Success: S_OK + * Failure: E_OUTOFMEMORY or E_INVALIDARG. + */ +static HRESULT WINAPI ICreateTypeLib2_fnSetHelpStringContext( + ICreateTypeLib2 * iface, /* [I] The type library to set the help string context for. */ + ULONG dwHelpStringContext) /* [I] The help string context. */ +{ + FIXME("(%p,%ld), stub!\n", iface, dwHelpStringContext); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ICreateTypeLib2_SetHelpStringDll {OLEAUT32} + * + * Sets the DLL used to look up localized help strings. + * + * RETURNS + * + * Success: S_OK + * Failure: E_OUTOFMEMORY or E_INVALIDARG. + */ +static HRESULT WINAPI ICreateTypeLib2_fnSetHelpStringDll( + ICreateTypeLib2 * iface, /* [I] The type library to set the help DLL for. */ + LPOLESTR szFileName) /* [I] The name of the help DLL. */ +{ + FIXME("(%p,%s), stub!\n", iface, debugstr_w(szFileName)); + return E_OUTOFMEMORY; +} + +/*================== ITypeLib2 Implementation ===================================*/ + +/****************************************************************************** + * ITypeLib2_QueryInterface {OLEAUT32} + * + * See IUnknown_QueryInterface. + */ +static HRESULT WINAPI ITypeLib2_fnQueryInterface(ITypeLib2 * iface, REFIID riid, LPVOID * ppv) +{ + ICOM_THIS_From_ITypeLib2(ICreateTypeLib2Impl, iface); + + return ICreateTypeLib2_QueryInterface((ICreateTypeLib2 *)This, riid, ppv); +} + +/****************************************************************************** + * ITypeLib2_AddRef {OLEAUT32} + * + * See IUnknown_AddRef. + */ +static ULONG WINAPI ITypeLib2_fnAddRef(ITypeLib2 * iface) +{ + ICOM_THIS_From_ITypeLib2(ICreateTypeLib2Impl, iface); + + return ICreateTypeLib2_AddRef((ICreateTypeLib2 *)This); +} + +/****************************************************************************** + * ITypeLib2_Release {OLEAUT32} + * + * See IUnknown_Release. + */ +static ULONG WINAPI ITypeLib2_fnRelease(ITypeLib2 * iface) +{ + ICOM_THIS_From_ITypeLib2(ICreateTypeLib2Impl, iface); + + return ICreateTypeLib2_Release((ICreateTypeLib2 *)This); +} + +/****************************************************************************** + * ITypeLib2_GetTypeInfoCount {OLEAUT32} + * + * See ITypeLib_GetTypeInfoCount. + */ +static UINT WINAPI ITypeLib2_fnGetTypeInfoCount( + ITypeLib2 * iface) +{ + ICOM_THIS_From_ITypeLib2(ICreateTypeLib2Impl, iface); + + TRACE("(%p)\n", iface); + + return This->typelib_header.nrtypeinfos; +} + +/****************************************************************************** + * ITypeLib2_GetTypeInfo {OLEAUT32} + * + * See ITypeLib_GetTypeInfo. + */ +static HRESULT WINAPI ITypeLib2_fnGetTypeInfo( + ITypeLib2 * iface, + UINT index, + ITypeInfo** ppTInfo) +{ + ICOM_THIS_From_ITypeLib2(ICreateTypeLib2Impl, iface); + + TRACE("(%p,%d,%p)\n", iface, index, ppTInfo); + + if ((index < 0) || (index >= This->typelib_header.nrtypeinfos)) { + return TYPE_E_ELEMENTNOTFOUND; + } + + return ctl2_find_typeinfo_from_offset(This, This->typelib_typeinfo_offsets[index], ppTInfo); +} + +/****************************************************************************** + * ITypeLib2_GetTypeInfoType {OLEAUT32} + * + * See ITypeLib_GetTypeInfoType. + */ +static HRESULT WINAPI ITypeLib2_fnGetTypeInfoType( + ITypeLib2 * iface, + UINT index, + TYPEKIND* pTKind) +{ + ICOM_THIS_From_ITypeLib2(ICreateTypeLib2Impl, iface); + + TRACE("(%p,%d,%p)\n", iface, index, pTKind); + + if ((index < 0) || (index >= This->typelib_header.nrtypeinfos)) { + return TYPE_E_ELEMENTNOTFOUND; + } + + *pTKind = (This->typelib_segment_data[MSFT_SEG_TYPEINFO][This->typelib_typeinfo_offsets[index]]) & 15; + + return S_OK; +} + +/****************************************************************************** + * ITypeLib2_GetTypeInfoOfGuid {OLEAUT32} + * + * See ITypeLib_GetTypeInfoOfGuid. + */ +static HRESULT WINAPI ITypeLib2_fnGetTypeInfoOfGuid( + ITypeLib2 * iface, + REFGUID guid, + ITypeInfo** ppTinfo) +{ + ICOM_THIS_From_ITypeLib2(ICreateTypeLib2Impl, iface); + + int guidoffset; + int typeinfo; + + TRACE("(%p,%s,%p)\n", iface, debugstr_guid(guid), ppTinfo); + + guidoffset = ctl2_find_guid(This, ctl2_hash_guid(guid), guid); + if (guidoffset == -1) return TYPE_E_ELEMENTNOTFOUND; + + typeinfo = ((MSFT_GuidEntry *)&This->typelib_segment_data[MSFT_SEG_GUID][guidoffset])->hreftype; + if (typeinfo < 0) return TYPE_E_ELEMENTNOTFOUND; + + return ctl2_find_typeinfo_from_offset(This, typeinfo, ppTinfo); +} + +/****************************************************************************** + * ITypeLib2_GetLibAttr {OLEAUT32} + * + * See ITypeLib_GetLibAttr. + */ +static HRESULT WINAPI ITypeLib2_fnGetLibAttr( + ITypeLib2 * iface, + TLIBATTR** ppTLibAttr) +{ +/* ICOM_THIS_From_ITypeLib2(ICreateTypeLib2Impl, iface); */ + + FIXME("(%p,%p), stub!\n", iface, ppTLibAttr); + + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ITypeLib2_GetTypeComp {OLEAUT32} + * + * See ITypeLib_GetTypeComp. + */ +static HRESULT WINAPI ITypeLib2_fnGetTypeComp( + ITypeLib2 * iface, + ITypeComp** ppTComp) +{ +/* ICOM_THIS_From_ITypeLib2(ICreateTypeLib2Impl, iface); */ + + FIXME("(%p,%p), stub!\n", iface, ppTComp); + + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ITypeLib2_GetDocumentation {OLEAUT32} + * + * See ITypeLib_GetDocumentation. + */ +static HRESULT WINAPI ITypeLib2_fnGetDocumentation( + ITypeLib2 * iface, + INT index, + BSTR* pBstrName, + BSTR* pBstrDocString, + DWORD* pdwHelpContext, + BSTR* pBstrHelpFile) +{ +/* ICOM_THIS_From_ITypeLib2(ICreateTypeLib2Impl, iface); */ + + FIXME("(%p,%d,%p,%p,%p,%p), stub!\n", iface, index, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile); + + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ITypeLib2_IsName {OLEAUT32} + * + * See ITypeLib_IsName. + */ +static HRESULT WINAPI ITypeLib2_fnIsName( + ITypeLib2 * iface, + LPOLESTR szNameBuf, + ULONG lHashVal, + BOOL* pfName) +{ + ICOM_THIS_From_ITypeLib2(ICreateTypeLib2Impl, iface); + + char *encoded_name; + int nameoffset; + MSFT_NameIntro *nameintro; + + TRACE("(%p,%s,%lx,%p)\n", iface, debugstr_w(szNameBuf), lHashVal, pfName); + + ctl2_encode_name(This, szNameBuf, &encoded_name); + nameoffset = ctl2_find_name(This, encoded_name); + + *pfName = 0; + + if (nameoffset == -1) return S_OK; + + nameintro = (MSFT_NameIntro *)(&This->typelib_segment_data[MSFT_SEG_NAME][nameoffset]); + if (nameintro->hreftype == -1) return S_OK; + + *pfName = 1; + + FIXME("Should be decoding our copy of the name over szNameBuf.\n"); + + return S_OK; +} + +/****************************************************************************** + * ITypeLib2_FindName {OLEAUT32} + * + * See ITypeLib_FindName. + */ +static HRESULT WINAPI ITypeLib2_fnFindName( + ITypeLib2 * iface, + LPOLESTR szNameBuf, + ULONG lHashVal, + ITypeInfo** ppTInfo, + MEMBERID* rgMemId, + USHORT* pcFound) +{ +/* ICOM_THIS_From_ITypeLib2(ICreateTypeLib2Impl, iface); */ + + FIXME("(%p,%s,%lx,%p,%p,%p), stub!\n", iface, debugstr_w(szNameBuf), lHashVal, ppTInfo, rgMemId, pcFound); + + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ITypeLib2_ReleaseTLibAttr {OLEAUT32} + * + * See ITypeLib_ReleaseTLibAttr. + */ +static void WINAPI ITypeLib2_fnReleaseTLibAttr( + ITypeLib2 * iface, + TLIBATTR* pTLibAttr) +{ +/* ICOM_THIS_From_ITypeLib2(ICreateTypeLib2Impl, iface); */ + + FIXME("(%p,%p), stub!\n", iface, pTLibAttr); +} + +/****************************************************************************** + * ICreateTypeLib2_GetCustData {OLEAUT32} + * + * Retrieves a custom data value stored on a type library. + * + * RETURNS + * + * Success: S_OK + * Failure: E_OUTOFMEMORY or E_INVALIDARG. + */ +static HRESULT WINAPI ITypeLib2_fnGetCustData( + ITypeLib2 * iface, /* [I] The type library in which to find the custom data. */ + REFGUID guid, /* [I] The GUID under which the custom data is stored. */ + VARIANT* pVarVal) /* [O] The custom data. */ +{ +/* ICOM_THIS_From_ITypeLib2(ICreateTypeLib2Impl, iface); */ + + FIXME("(%p,%s,%p), stub!\n", iface, debugstr_guid(guid), pVarVal); + + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ICreateTypeLib2_GetLibStatistics {OLEAUT32} + * + * Retrieves some statistics about names in a type library, supposedly for + * hash table optimization purposes. + * + * RETURNS + * + * Success: S_OK + * Failure: E_OUTOFMEMORY or E_INVALIDARG. + */ +static HRESULT WINAPI ITypeLib2_fnGetLibStatistics( + ITypeLib2 * iface, /* [I] The type library to get statistics about. */ + ULONG* pcUniqueNames, /* [O] The number of unique names in the type library. */ + ULONG* pcchUniqueNames) /* [O] The number of changed (?) characters in names in the type library. */ +{ +/* ICOM_THIS_From_ITypeLib2(ICreateTypeLib2Impl, iface); */ + + FIXME("(%p,%p,%p), stub!\n", iface, pcUniqueNames, pcchUniqueNames); + + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ICreateTypeLib2_GetDocumentation2 {OLEAUT32} + * + * Obtain locale-aware help string information. + * + * RETURNS + * + * Success: S_OK + * Failure: STG_E_INSUFFICIENTMEMORY or E_INVALIDARG. + */ +static HRESULT WINAPI ITypeLib2_fnGetDocumentation2( + ITypeLib2 * iface, + INT index, + LCID lcid, + BSTR* pbstrHelpString, + DWORD* pdwHelpStringContext, + BSTR* pbstrHelpStringDll) +{ +/* ICOM_THIS_From_ITypeLib2(ICreateTypeLib2Impl, iface); */ + + FIXME("(%p,%d,%ld,%p,%p,%p), stub!\n", iface, index, lcid, pbstrHelpString, pdwHelpStringContext, pbstrHelpStringDll); + + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * ICreateTypeLib2_GetAllCustData {OLEAUT32} + * + * Retrieve all of the custom data for a type library. + * + * RETURNS + * + * Success: S_OK + * Failure: E_OUTOFMEMORY or E_INVALIDARG. + */ +static HRESULT WINAPI ITypeLib2_fnGetAllCustData( + ITypeLib2 * iface, /* [I] The type library in which to find the custom data. */ + CUSTDATA* pCustData) /* [O] The structure in which to place the custom data. */ +{ +/* ICOM_THIS_From_ITypeLib2(ICreateTypeLib2Impl, iface); */ + + FIXME("(%p,%p), stub!\n", iface, pCustData); + + return E_OUTOFMEMORY; +} + + +/*================== ICreateTypeLib2 & ITypeLib2 VTABLEs And Creation ===================================*/ + +static ICreateTypeLib2Vtbl ctypelib2vt = +{ + + ICreateTypeLib2_fnQueryInterface, + ICreateTypeLib2_fnAddRef, + ICreateTypeLib2_fnRelease, + + ICreateTypeLib2_fnCreateTypeInfo, + ICreateTypeLib2_fnSetName, + ICreateTypeLib2_fnSetVersion, + ICreateTypeLib2_fnSetGuid, + ICreateTypeLib2_fnSetDocString, + ICreateTypeLib2_fnSetHelpFileName, + ICreateTypeLib2_fnSetHelpContext, + ICreateTypeLib2_fnSetLcid, + ICreateTypeLib2_fnSetLibFlags, + ICreateTypeLib2_fnSaveAllChanges, + + ICreateTypeLib2_fnDeleteTypeInfo, + ICreateTypeLib2_fnSetCustData, + ICreateTypeLib2_fnSetHelpStringContext, + ICreateTypeLib2_fnSetHelpStringDll +}; + +static ITypeLib2Vtbl typelib2vt = +{ + + ITypeLib2_fnQueryInterface, + ITypeLib2_fnAddRef, + ITypeLib2_fnRelease, + + ITypeLib2_fnGetTypeInfoCount, + ITypeLib2_fnGetTypeInfo, + ITypeLib2_fnGetTypeInfoType, + ITypeLib2_fnGetTypeInfoOfGuid, + ITypeLib2_fnGetLibAttr, + ITypeLib2_fnGetTypeComp, + ITypeLib2_fnGetDocumentation, + ITypeLib2_fnIsName, + ITypeLib2_fnFindName, + ITypeLib2_fnReleaseTLibAttr, + + ITypeLib2_fnGetCustData, + ITypeLib2_fnGetLibStatistics, + ITypeLib2_fnGetDocumentation2, + ITypeLib2_fnGetAllCustData, +}; + +static ICreateTypeLib2 *ICreateTypeLib2_Constructor(SYSKIND syskind, LPCOLESTR szFile) +{ + ICreateTypeLib2Impl *pCreateTypeLib2Impl; + int failed = 0; + + TRACE("Constructing ICreateTypeLib2 (%d, %s)\n", syskind, debugstr_w(szFile)); + + pCreateTypeLib2Impl = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ICreateTypeLib2Impl)); + if (!pCreateTypeLib2Impl) return NULL; + + pCreateTypeLib2Impl->filename = HeapAlloc(GetProcessHeap(), 0, (strlenW(szFile) + 1) * sizeof(WCHAR)); + if (!pCreateTypeLib2Impl->filename) { + HeapFree(GetProcessHeap(), 0, pCreateTypeLib2Impl); + return NULL; + } + strcpyW(pCreateTypeLib2Impl->filename, szFile); + + ctl2_init_header(pCreateTypeLib2Impl); + ctl2_init_segdir(pCreateTypeLib2Impl); + + pCreateTypeLib2Impl->typelib_header.varflags |= syskind; + + /* + * The following two calls return an offset or -1 if out of memory. We + * specifically need an offset of 0, however, so... + */ + if (ctl2_alloc_segment(pCreateTypeLib2Impl, MSFT_SEG_GUIDHASH, 0x80, 0x80)) { failed = 1; } + if (ctl2_alloc_segment(pCreateTypeLib2Impl, MSFT_SEG_NAMEHASH, 0x200, 0x200)) { failed = 1; } + + pCreateTypeLib2Impl->typelib_guidhash_segment = (int *)pCreateTypeLib2Impl->typelib_segment_data[MSFT_SEG_GUIDHASH]; + pCreateTypeLib2Impl->typelib_namehash_segment = (int *)pCreateTypeLib2Impl->typelib_segment_data[MSFT_SEG_NAMEHASH]; + + memset(pCreateTypeLib2Impl->typelib_guidhash_segment, 0xff, 0x80); + memset(pCreateTypeLib2Impl->typelib_namehash_segment, 0xff, 0x200); + + pCreateTypeLib2Impl->lpVtbl = &ctypelib2vt; + pCreateTypeLib2Impl->lpVtblTypeLib2 = &typelib2vt; + pCreateTypeLib2Impl->ref = 1; + + if (failed) { + ICreateTypeLib2_fnRelease((ICreateTypeLib2 *)pCreateTypeLib2Impl); + return 0; + } + + return (ICreateTypeLib2 *)pCreateTypeLib2Impl; +} + +/****************************************************************************** + * CreateTypeLib2 [OLEAUT32.180] + * + * Obtains an ICreateTypeLib2 object for creating a new-style (MSFT) type + * library. + * + * NOTES + * + * See also CreateTypeLib. + * + * RETURNS + * Success: S_OK + * Failure: Status + */ +HRESULT WINAPI CreateTypeLib2( + SYSKIND syskind, /* [I] System type library is for */ + LPCOLESTR szFile, /* [I] Type library file name */ + ICreateTypeLib2** ppctlib) /* [O] Storage for object returned */ +{ + TRACE("(%d,%s,%p)\n", syskind, debugstr_w(szFile), ppctlib); + + if (!szFile) return E_INVALIDARG; + *ppctlib = ICreateTypeLib2_Constructor(syskind, szFile); + return (*ppctlib)? S_OK: E_OUTOFMEMORY; +} + +/****************************************************************************** + * ClearCustData (OLEAUT32.171) + * + * Clear a custom data types' data. + * + * PARAMS + * lpCust [I] The custom data type instance + * + * RETURNS + * Nothing. + */ +void WINAPI ClearCustData(LPCUSTDATA lpCust) +{ + if (lpCust && lpCust->cCustData) + { + if (lpCust->prgCustData) + { + DWORD i; + + for (i = 0; i < lpCust->cCustData; i++) + VariantClear(&lpCust->prgCustData[i].varValue); + + /* FIXME - Should be using a per-thread IMalloc */ + HeapFree(GetProcessHeap(), 0, lpCust->prgCustData); + lpCust->prgCustData = NULL; + } + lpCust->cCustData = 0; + } +} diff --git a/reactos/lib/oleaut32/usrmarshal.c b/reactos/lib/oleaut32/usrmarshal.c new file mode 100644 index 00000000000..10c2a3eb912 --- /dev/null +++ b/reactos/lib/oleaut32/usrmarshal.c @@ -0,0 +1,1181 @@ +/* + * Misc marshalling routines + * + * Copyright 2002 Ove Kaaven + * Copyright 2003 Mike Hearn + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include + +#define COBJMACROS +#define NONAMELESSUNION +#define NONAMELESSSTRUCT + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" +#include "winerror.h" + +#include "ole2.h" +#include "oleauto.h" +#include "rpcproxy.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(ole); + +/* FIXME: not supposed to be here */ + +const CLSID CLSID_PSDispatch = { + 0x20420, 0, 0, {0xC0, 0, 0, 0, 0, 0, 0, 0x46} +}; + +static CStdPSFactoryBuffer PSFactoryBuffer; + +CSTDSTUBBUFFERRELEASE(&PSFactoryBuffer) + +extern const ExtendedProxyFileInfo oaidl_ProxyFileInfo; + +const ProxyFileInfo* OLEAUT32_ProxyFileList[] = { + &oaidl_ProxyFileInfo, + NULL +}; + +HRESULT OLEAUTPS_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) +{ + return NdrDllGetClassObject(rclsid, riid, ppv, OLEAUT32_ProxyFileList, + &CLSID_PSDispatch, &PSFactoryBuffer); +} + +/* CLEANLOCALSTORAGE */ +/* I'm not sure how this is supposed to work yet */ + +unsigned long WINAPI CLEANLOCALSTORAGE_UserSize(unsigned long *pFlags, unsigned long Start, CLEANLOCALSTORAGE *pstg) +{ + return Start + sizeof(DWORD); +} + +unsigned char * WINAPI CLEANLOCALSTORAGE_UserMarshal(unsigned long *pFlags, unsigned char *Buffer, CLEANLOCALSTORAGE *pstg) +{ + *(DWORD*)Buffer = 0; + return Buffer + sizeof(DWORD); +} + +unsigned char * WINAPI CLEANLOCALSTORAGE_UserUnmarshal(unsigned long *pFlags, unsigned char *Buffer, CLEANLOCALSTORAGE *pstr) +{ + return Buffer + sizeof(DWORD); +} + +void WINAPI CLEANLOCALSTORAGE_UserFree(unsigned long *pFlags, CLEANLOCALSTORAGE *pstr) +{ +} + +/* BSTR */ + +unsigned long WINAPI BSTR_UserSize(unsigned long *pFlags, unsigned long Start, BSTR *pstr) +{ + TRACE("(%lx,%ld,%p) => %p\n", *pFlags, Start, pstr, *pstr); + if (*pstr) TRACE("string=%s\n", debugstr_w(*pstr)); + Start += sizeof(FLAGGED_WORD_BLOB) + sizeof(OLECHAR) * (SysStringLen(*pstr) - 1); + TRACE("returning %ld\n", Start); + return Start; +} + +unsigned char * WINAPI BSTR_UserMarshal(unsigned long *pFlags, unsigned char *Buffer, BSTR *pstr) +{ + wireBSTR str = (wireBSTR)Buffer; + + TRACE("(%lx,%p,%p) => %p\n", *pFlags, Buffer, pstr, *pstr); + if (*pstr) TRACE("string=%s\n", debugstr_w(*pstr)); + str->fFlags = 0; + str->clSize = SysStringLen(*pstr); + if (str->clSize) + memcpy(&str->asData, *pstr, sizeof(OLECHAR) * str->clSize); + return Buffer + sizeof(FLAGGED_WORD_BLOB) + sizeof(OLECHAR) * (str->clSize - 1); +} + +unsigned char * WINAPI BSTR_UserUnmarshal(unsigned long *pFlags, unsigned char *Buffer, BSTR *pstr) +{ + wireBSTR str = (wireBSTR)Buffer; + TRACE("(%lx,%p,%p) => %p\n", *pFlags, Buffer, pstr, *pstr); + if (str->clSize) { + SysReAllocStringLen(pstr, (OLECHAR*)&str->asData, str->clSize); + } + else if (*pstr) { + SysFreeString(*pstr); + *pstr = NULL; + } + if (*pstr) TRACE("string=%s\n", debugstr_w(*pstr)); + return Buffer + sizeof(FLAGGED_WORD_BLOB) + sizeof(OLECHAR) * (str->clSize - 1); +} + +void WINAPI BSTR_UserFree(unsigned long *pFlags, BSTR *pstr) +{ + TRACE("(%lx,%p) => %p\n", *pFlags, pstr, *pstr); + if (*pstr) { + SysFreeString(*pstr); + *pstr = NULL; + } +} + +/* VARIANT */ +/* I'm not too sure how to do this yet */ + +#define VARIANT_wiresize sizeof(struct _wireVARIANT) + +static unsigned wire_size(VARTYPE vt) +{ + if (vt & VT_ARRAY) return 0; + + switch (vt & ~VT_BYREF) { + case VT_EMPTY: + case VT_NULL: + return 0; + case VT_I1: + case VT_UI1: + return sizeof(CHAR); + case VT_I2: + case VT_UI2: + return sizeof(SHORT); + case VT_I4: + case VT_UI4: + return sizeof(LONG); + case VT_INT: + case VT_UINT: + return sizeof(INT); + case VT_R4: + return sizeof(FLOAT); + case VT_R8: + return sizeof(DOUBLE); + case VT_BOOL: + return sizeof(VARIANT_BOOL); + case VT_ERROR: + return sizeof(SCODE); + case VT_DATE: + return sizeof(DATE); + case VT_CY: + return sizeof(CY); + case VT_DECIMAL: + return sizeof(DECIMAL); + case VT_BSTR: + case VT_VARIANT: + case VT_UNKNOWN: + case VT_DISPATCH: + case VT_SAFEARRAY: + case VT_RECORD: + return 0; + default: + FIXME("unhandled VT %d\n", vt); + return 0; + } +} + +static unsigned wire_extra(unsigned long *pFlags, VARIANT *pvar) +{ + ULONG size; + HRESULT hr; + + if (V_VT(pvar) & VT_ARRAY) { + FIXME("wire-size safearray\n"); + return 0; + } + switch (V_VT(pvar)) { + case VT_BSTR: + return BSTR_UserSize(pFlags, 0, &V_BSTR(pvar)); + case VT_BSTR | VT_BYREF: + return BSTR_UserSize(pFlags, 0, V_BSTRREF(pvar)); + case VT_SAFEARRAY: + case VT_SAFEARRAY | VT_BYREF: + FIXME("wire-size safearray\n"); + return 0; + case VT_VARIANT | VT_BYREF: + return VARIANT_UserSize(pFlags, 0, V_VARIANTREF(pvar)); + case VT_UNKNOWN: + case VT_DISPATCH: + /* find the buffer size of the marshalled dispatch interface */ + hr = CoGetMarshalSizeMax(&size, &IID_IDispatch, (IUnknown*)V_DISPATCH(pvar), LOWORD(*pFlags), NULL, MSHLFLAGS_NORMAL); + if (FAILED(hr)) { + ERR("Dispatch variant buffer size calculation failed, HRESULT=0x%lx\n", hr); + return 0; + } + size += sizeof(ULONG); /* we have to store the buffersize in the stream */ + TRACE("wire-size extra of dispatch variant is %ld\n", size); + return size; + case VT_RECORD: + FIXME("wire-size record\n"); + return 0; + default: + return 0; + } +} + +/* helper: called for VT_DISPATCH variants to marshal the IDispatch* into the buffer. returns Buffer on failure, new position otherwise */ +static unsigned char* dispatch_variant_marshal(unsigned long *pFlags, unsigned char *Buffer, VARIANT *pvar) { + IStream *working; + HGLOBAL working_mem; + void *working_memlocked; + unsigned char *oldpos; + ULONG size; + HRESULT hr; + + TRACE("pFlags=%ld, Buffer=%p, pvar=%p\n", *pFlags, Buffer, pvar); + + oldpos = Buffer; + + /* CoMarshalInterface needs a stream, whereas at this level we are operating in terms of buffers. + * We create a stream on an HGLOBAL, so we can simply do a memcpy to move it to the buffer. + * in rpcrt4/ndr_ole.c, a simple IStream implementation is wrapped around the buffer object, + * but that would be overkill here, hence this implementation. We save the size because the unmarshal + * code has no way to know how long the marshalled buffer is. */ + + size = wire_extra(pFlags, pvar); + + working_mem = GlobalAlloc(0, size); + if (!working_mem) return oldpos; + + hr = CreateStreamOnHGlobal(working_mem, TRUE, &working); + if (hr != S_OK) { + GlobalFree(working_mem); + return oldpos; + } + + hr = CoMarshalInterface(working, &IID_IDispatch, (IUnknown*)V_DISPATCH(pvar), LOWORD(*pFlags), NULL, MSHLFLAGS_NORMAL); + if (hr != S_OK) { + IStream_Release(working); /* this also releases the hglobal */ + return oldpos; + } + + working_memlocked = GlobalLock(working_mem); + memcpy(Buffer, &size, sizeof(ULONG)); /* copy the buffersize */ + Buffer += sizeof(ULONG); + memcpy(Buffer, working_memlocked, size); + GlobalUnlock(working_mem); + + IStream_Release(working); + + TRACE("done, size=%ld\n", sizeof(ULONG) + size); + return Buffer + sizeof(ULONG) + size; +} + +/* helper: called for VT_DISPATCH variants to unmarshal the buffer back into a dispatch variant. returns Buffer on failure, new position otherwise */ +static unsigned char *dispatch_variant_unmarshal(unsigned long *pFlags, unsigned char *Buffer, VARIANT *pvar) { + IStream *working; + HGLOBAL working_mem; + void *working_memlocked; + unsigned char *oldpos; + ULONG size; + HRESULT hr; + + TRACE("pFlags=%ld, Buffer=%p, pvar=%p\n", *pFlags, Buffer, pvar); + + oldpos = Buffer; + + /* get the buffersize */ + memcpy(&size, Buffer, sizeof(ULONG)); + TRACE("buffersize=%ld\n", size); + Buffer += sizeof(ULONG); + + working_mem = GlobalAlloc(0, size); + if (!working_mem) return oldpos; + + hr = CreateStreamOnHGlobal(working_mem, TRUE, &working); + if (hr != S_OK) { + GlobalFree(working_mem); + return oldpos; + } + + working_memlocked = GlobalLock(working_mem); + + /* now we copy the contents of the marshalling buffer to working_memlocked, unlock it, and demarshal the stream */ + memcpy(working_memlocked, Buffer, size); + GlobalUnlock(working_mem); + + hr = CoUnmarshalInterface(working, &IID_IDispatch, (void**)&V_DISPATCH(pvar)); + if (hr != S_OK) { + IStream_Release(working); + return oldpos; + } + + IStream_Release(working); /* this also frees the underlying hglobal */ + + TRACE("done, processed=%ld bytes\n", sizeof(ULONG) + size); + return Buffer + sizeof(ULONG) + size; +} + + +unsigned long WINAPI VARIANT_UserSize(unsigned long *pFlags, unsigned long Start, VARIANT *pvar) +{ + TRACE("(%lx,%ld,%p)\n", *pFlags, Start, pvar); + TRACE("vt=%04x\n", V_VT(pvar)); + Start += VARIANT_wiresize + wire_extra(pFlags, pvar); + TRACE("returning %ld\n", Start); + return Start; +} + +unsigned char * WINAPI VARIANT_UserMarshal(unsigned long *pFlags, unsigned char *Buffer, VARIANT *pvar) +{ + wireVARIANT var = (wireVARIANT)Buffer; + unsigned size, extra; + unsigned char *Pos = Buffer + VARIANT_wiresize; + + TRACE("(%lx,%p,%p)\n", *pFlags, Buffer, pvar); + TRACE("vt=%04x\n", V_VT(pvar)); + + memset(var, 0, sizeof(*var)); + var->clSize = sizeof(*var); + var->vt = pvar->n1.n2.vt; + + var->rpcReserved = var->vt; + if ((var->vt & VT_ARRAY) || + ((var->vt & VT_TYPEMASK) == VT_SAFEARRAY)) + var->vt = VT_ARRAY | (var->vt & VT_BYREF); + + if (var->vt == VT_DECIMAL) { + /* special case because decVal is on a different level */ + var->u.decVal = pvar->n1.decVal; + return Pos; + } + + size = wire_size(V_VT(pvar)); + extra = wire_extra(pFlags, pvar); + var->wReserved1 = pvar->n1.n2.wReserved1; + var->wReserved2 = pvar->n1.n2.wReserved2; + var->wReserved3 = pvar->n1.n2.wReserved3; + if (size) { + if (var->vt & VT_BYREF) + memcpy(&var->u.cVal, pvar->n1.n2.n3.byref, size); + else + memcpy(&var->u.cVal, &pvar->n1.n2.n3, size); + } + if (!extra) return Pos; + + switch (var->vt) { + case VT_BSTR: + Pos = BSTR_UserMarshal(pFlags, Pos, &V_BSTR(pvar)); + break; + case VT_BSTR | VT_BYREF: + Pos = BSTR_UserMarshal(pFlags, Pos, V_BSTRREF(pvar)); + break; + case VT_VARIANT | VT_BYREF: + Pos = VARIANT_UserMarshal(pFlags, Pos, V_VARIANTREF(pvar)); + break; + case VT_DISPATCH | VT_BYREF: + FIXME("handle DISPATCH by ref\n"); + break; + case VT_DISPATCH: + /* this should probably call WdtpInterfacePointer_UserMarshal in ole32.dll */ + Pos = dispatch_variant_marshal(pFlags, Pos, pvar); + break; + case VT_RECORD: + FIXME("handle BRECORD by val\n"); + break; + case VT_RECORD | VT_BYREF: + FIXME("handle BRECORD by ref\n"); + break; + default: + FIXME("handle unknown complex type\n"); + break; + } + var->clSize = Pos - Buffer; + TRACE("marshalled size=%ld\n", var->clSize); + return Pos; +} + +unsigned char * WINAPI VARIANT_UserUnmarshal(unsigned long *pFlags, unsigned char *Buffer, VARIANT *pvar) +{ + wireVARIANT var = (wireVARIANT)Buffer; + unsigned size; + unsigned char *Pos = Buffer + VARIANT_wiresize; + + TRACE("(%lx,%p,%p)\n", *pFlags, Buffer, pvar); + VariantInit(pvar); + pvar->n1.n2.vt = var->rpcReserved; + TRACE("marshalled: clSize=%ld, vt=%04x\n", var->clSize, var->vt); + TRACE("vt=%04x\n", V_VT(pvar)); + TRACE("reserved: %d, %d, %d\n", var->wReserved1, var->wReserved2, var->wReserved3); + TRACE("val: %ld\n", var->u.lVal); + + if (var->vt == VT_DECIMAL) { + /* special case because decVal is on a different level */ + pvar->n1.decVal = var->u.decVal; + return Pos; + } + + size = wire_size(V_VT(pvar)); + pvar->n1.n2.wReserved1 = var->wReserved1; + pvar->n1.n2.wReserved2 = var->wReserved2; + pvar->n1.n2.wReserved3 = var->wReserved3; + if (size) { + if (var->vt & VT_BYREF) { + pvar->n1.n2.n3.byref = CoTaskMemAlloc(size); + memcpy(pvar->n1.n2.n3.byref, &var->u.cVal, size); + } + else + memcpy(&pvar->n1.n2.n3, &var->u.cVal, size); + } + if (var->clSize <= VARIANT_wiresize) return Pos; + + switch (var->vt) { + case VT_BSTR: + Pos = BSTR_UserUnmarshal(pFlags, Pos, &V_BSTR(pvar)); + break; + case VT_BSTR | VT_BYREF: + pvar->n1.n2.n3.byref = CoTaskMemAlloc(sizeof(BSTR)); + *(BSTR*)pvar->n1.n2.n3.byref = NULL; + Pos = BSTR_UserUnmarshal(pFlags, Pos, V_BSTRREF(pvar)); + break; + case VT_VARIANT | VT_BYREF: + pvar->n1.n2.n3.byref = CoTaskMemAlloc(sizeof(VARIANT)); + Pos = VARIANT_UserUnmarshal(pFlags, Pos, V_VARIANTREF(pvar)); + break; + case VT_RECORD: + FIXME("handle BRECORD by val\n"); + break; + case VT_RECORD | VT_BYREF: + FIXME("handle BRECORD by ref\n"); + break; + case VT_DISPATCH: + Pos = dispatch_variant_unmarshal(pFlags, Pos, pvar); + break; + case VT_DISPATCH | VT_BYREF: + FIXME("handle DISPATCH by ref\n"); + default: + FIXME("handle unknown complex type\n"); + break; + } + if (Pos != Buffer + var->clSize) { + ERR("size difference during unmarshal\n"); + } + return Buffer + var->clSize; +} + +void WINAPI VARIANT_UserFree(unsigned long *pFlags, VARIANT *pvar) +{ + VARTYPE vt = V_VT(pvar); + PVOID ref = NULL; + + TRACE("(%lx,%p)\n", *pFlags, pvar); + TRACE("vt=%04x\n", V_VT(pvar)); + + if (vt & VT_BYREF) ref = pvar->n1.n2.n3.byref; + + VariantClear(pvar); + if (!ref) return; + + switch (vt) { + case VT_BSTR | VT_BYREF: + BSTR_UserFree(pFlags, ref); + break; + case VT_VARIANT | VT_BYREF: + VARIANT_UserFree(pFlags, ref); + break; + case VT_RECORD | VT_BYREF: + FIXME("handle BRECORD by ref\n"); + break; + default: + FIXME("handle unknown complex type\n"); + break; + } + + CoTaskMemFree(ref); +} + +/* IDispatch */ +/* exactly how Invoke is marshalled is not very clear to me yet, + * but the way I've done it seems to work for me */ + +HRESULT CALLBACK IDispatch_Invoke_Proxy( + IDispatch* This, + DISPID dispIdMember, + REFIID riid, + LCID lcid, + WORD wFlags, + DISPPARAMS* pDispParams, + VARIANT* pVarResult, + EXCEPINFO* pExcepInfo, + UINT* puArgErr) +{ + HRESULT hr; + VARIANT VarResult; + UINT* rgVarRefIdx = NULL; + VARIANTARG* rgVarRef = NULL; + UINT u, cVarRef; + + TRACE("(%p)->(%ld,%s,%lx,%x,%p,%p,%p,%p)\n", This, + dispIdMember, debugstr_guid(riid), + lcid, wFlags, pDispParams, pVarResult, + pExcepInfo, puArgErr); + + /* [out] args can't be null, use dummy vars if needed */ + if (!pVarResult) pVarResult = &VarResult; + + /* count by-ref args */ + for (cVarRef=0,u=0; ucArgs; u++) { + VARIANTARG* arg = &pDispParams->rgvarg[u]; + if (V_VT(arg) & VT_BYREF) { + cVarRef++; + } + } + if (cVarRef) { + rgVarRefIdx = CoTaskMemAlloc(sizeof(UINT)*cVarRef); + rgVarRef = CoTaskMemAlloc(sizeof(VARIANTARG)*cVarRef); + /* make list of by-ref args */ + for (cVarRef=0,u=0; ucArgs; u++) { + VARIANTARG* arg = &pDispParams->rgvarg[u]; + if (V_VT(arg) & VT_BYREF) { + rgVarRefIdx[cVarRef] = u; + VariantInit(&rgVarRef[cVarRef]); + cVarRef++; + } + } + } else { + /* [out] args still can't be null, + * but we can point these anywhere in this case, + * since they won't be written to when cVarRef is 0 */ + rgVarRefIdx = puArgErr; + rgVarRef = pVarResult; + } + TRACE("passed by ref: %d args\n", cVarRef); + hr = IDispatch_RemoteInvoke_Proxy(This, + dispIdMember, + riid, + lcid, + wFlags, + pDispParams, + pVarResult, + pExcepInfo, + puArgErr, + cVarRef, + rgVarRefIdx, + rgVarRef); + if (cVarRef) { + for (u=0; urgvarg[i], + &rgVarRef[u]); + VariantClear(&rgVarRef[u]); + } + CoTaskMemFree(rgVarRef); + CoTaskMemFree(rgVarRefIdx); + } + return hr; +} + +HRESULT __RPC_STUB IDispatch_Invoke_Stub( + IDispatch* This, + DISPID dispIdMember, + REFIID riid, + LCID lcid, + DWORD dwFlags, + DISPPARAMS* pDispParams, + VARIANT* pVarResult, + EXCEPINFO* pExcepInfo, + UINT* pArgErr, + UINT cVarRef, + UINT* rgVarRefIdx, + VARIANTARG* rgVarRef) +{ + HRESULT hr; + VARIANTARG *rgvarg, *arg; + UINT u; + + /* let the real Invoke operate on a copy of the in parameters, + * so we don't risk losing pointers to allocated memory */ + rgvarg = pDispParams->rgvarg; + arg = CoTaskMemAlloc(sizeof(VARIANTARG)*pDispParams->cArgs); + for (u=0; ucArgs; u++) { + VariantInit(&arg[u]); + VariantCopy(&arg[u], &rgvarg[u]); + } + pDispParams->rgvarg = arg; + + /* initialize out parameters, so that they can be marshalled + * in case the real Invoke doesn't initialize them */ + VariantInit(pVarResult); + memset(pExcepInfo, 0, sizeof(*pExcepInfo)); + *pArgErr = 0; + + hr = IDispatch_Invoke(This, + dispIdMember, + riid, + lcid, + dwFlags, + pDispParams, + pVarResult, + pExcepInfo, + pArgErr); + + /* copy ref args to out list */ + for (u=0; ucArgs; u++) { + VariantClear(&arg[u]); + } + pDispParams->rgvarg = rgvarg; + CoTaskMemFree(arg); + + return hr; +} + +/* IEnumVARIANT */ + +HRESULT CALLBACK IEnumVARIANT_Next_Proxy( + IEnumVARIANT* This, + ULONG celt, + VARIANT* rgVar, + ULONG* pCeltFetched) +{ + ULONG fetched; + if (!pCeltFetched) + pCeltFetched = &fetched; + return IEnumVARIANT_RemoteNext_Proxy(This, + celt, + rgVar, + pCeltFetched); +} + +HRESULT __RPC_STUB IEnumVARIANT_Next_Stub( + IEnumVARIANT* This, + ULONG celt, + VARIANT* rgVar, + ULONG* pCeltFetched) +{ + HRESULT hr; + *pCeltFetched = 0; + hr = IEnumVARIANT_Next(This, + celt, + rgVar, + pCeltFetched); + if (hr == S_OK) *pCeltFetched = celt; + return hr; +} + +/* ITypeComp */ + +HRESULT CALLBACK ITypeComp_Bind_Proxy( + ITypeComp* This, + LPOLESTR szName, + ULONG lHashVal, + WORD wFlags, + ITypeInfo** ppTInfo, + DESCKIND* pDescKind, + BINDPTR* pBindPtr) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + +HRESULT __RPC_STUB ITypeComp_Bind_Stub( + ITypeComp* This, + LPOLESTR szName, + ULONG lHashVal, + WORD wFlags, + ITypeInfo** ppTInfo, + DESCKIND* pDescKind, + LPFUNCDESC* ppFuncDesc, + LPVARDESC* ppVarDesc, + ITypeComp** ppTypeComp, + CLEANLOCALSTORAGE* pDummy) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + +HRESULT CALLBACK ITypeComp_BindType_Proxy( + ITypeComp* This, + LPOLESTR szName, + ULONG lHashVal, + ITypeInfo** ppTInfo, + ITypeComp** ppTComp) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + +HRESULT __RPC_STUB ITypeComp_BindType_Stub( + ITypeComp* This, + LPOLESTR szName, + ULONG lHashVal, + ITypeInfo** ppTInfo) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + +/* ITypeInfo */ + +HRESULT CALLBACK ITypeInfo_GetTypeAttr_Proxy( + ITypeInfo* This, + TYPEATTR** ppTypeAttr) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + +HRESULT __RPC_STUB ITypeInfo_GetTypeAttr_Stub( + ITypeInfo* This, + LPTYPEATTR* ppTypeAttr, + CLEANLOCALSTORAGE* pDummy) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + +HRESULT CALLBACK ITypeInfo_GetFuncDesc_Proxy( + ITypeInfo* This, + UINT index, + FUNCDESC** ppFuncDesc) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + +HRESULT __RPC_STUB ITypeInfo_GetFuncDesc_Stub( + ITypeInfo* This, + UINT index, + LPFUNCDESC* ppFuncDesc, + CLEANLOCALSTORAGE* pDummy) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + +HRESULT CALLBACK ITypeInfo_GetVarDesc_Proxy( + ITypeInfo* This, + UINT index, + VARDESC** ppVarDesc) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + +HRESULT __RPC_STUB ITypeInfo_GetVarDesc_Stub( + ITypeInfo* This, + UINT index, + LPVARDESC* ppVarDesc, + CLEANLOCALSTORAGE* pDummy) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + +HRESULT CALLBACK ITypeInfo_GetNames_Proxy( + ITypeInfo* This, + MEMBERID memid, + BSTR* rgBstrNames, + UINT cMaxNames, + UINT* pcNames) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + +HRESULT __RPC_STUB ITypeInfo_GetNames_Stub( + ITypeInfo* This, + MEMBERID memid, + BSTR* rgBstrNames, + UINT cMaxNames, + UINT* pcNames) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + +HRESULT CALLBACK ITypeInfo_GetIDsOfNames_Proxy( + ITypeInfo* This, + LPOLESTR* rgszNames, + UINT cNames, + MEMBERID* pMemId) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + +HRESULT __RPC_STUB ITypeInfo_GetIDsOfNames_Stub( + ITypeInfo* This) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + +HRESULT CALLBACK ITypeInfo_Invoke_Proxy( + ITypeInfo* This, + PVOID pvInstance, + MEMBERID memid, + WORD wFlags, + DISPPARAMS* pDispParams, + VARIANT* pVarResult, + EXCEPINFO* pExcepInfo, + UINT* puArgErr) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + +HRESULT __RPC_STUB ITypeInfo_Invoke_Stub( + ITypeInfo* This) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + +HRESULT CALLBACK ITypeInfo_GetDocumentation_Proxy( + ITypeInfo* This, + MEMBERID memid, + BSTR* pBstrName, + BSTR* pBstrDocString, + DWORD* pdwHelpContext, + BSTR* pBstrHelpFile) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + +HRESULT __RPC_STUB ITypeInfo_GetDocumentation_Stub( + ITypeInfo* This, + MEMBERID memid, + DWORD refPtrFlags, + BSTR* pBstrName, + BSTR* pBstrDocString, + DWORD* pdwHelpContext, + BSTR* pBstrHelpFile) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + +HRESULT CALLBACK ITypeInfo_GetDllEntry_Proxy( + ITypeInfo* This, + MEMBERID memid, + INVOKEKIND invKind, + BSTR* pBstrDllName, + BSTR* pBstrName, + WORD* pwOrdinal) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + +HRESULT __RPC_STUB ITypeInfo_GetDllEntry_Stub( + ITypeInfo* This, + MEMBERID memid, + INVOKEKIND invKind, + DWORD refPtrFlags, + BSTR* pBstrDllName, + BSTR* pBstrName, + WORD* pwOrdinal) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + +HRESULT CALLBACK ITypeInfo_AddressOfMember_Proxy( + ITypeInfo* This, + MEMBERID memid, + INVOKEKIND invKind, + PVOID* ppv) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + +HRESULT __RPC_STUB ITypeInfo_AddressOfMember_Stub( + ITypeInfo* This) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + +HRESULT CALLBACK ITypeInfo_CreateInstance_Proxy( + ITypeInfo* This, + IUnknown* pUnkOuter, + REFIID riid, + PVOID* ppvObj) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + +HRESULT __RPC_STUB ITypeInfo_CreateInstance_Stub( + ITypeInfo* This, + REFIID riid, + IUnknown** ppvObj) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + +HRESULT CALLBACK ITypeInfo_GetContainingTypeLib_Proxy( + ITypeInfo* This, + ITypeLib** ppTLib, + UINT* pIndex) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + +HRESULT __RPC_STUB ITypeInfo_GetContainingTypeLib_Stub( + ITypeInfo* This, + ITypeLib** ppTLib, + UINT* pIndex) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + +void CALLBACK ITypeInfo_ReleaseTypeAttr_Proxy( + ITypeInfo* This, + TYPEATTR* pTypeAttr) +{ + FIXME("not implemented\n"); +} + +HRESULT __RPC_STUB ITypeInfo_ReleaseTypeAttr_Stub( + ITypeInfo* This) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + +void CALLBACK ITypeInfo_ReleaseFuncDesc_Proxy( + ITypeInfo* This, + FUNCDESC* pFuncDesc) +{ + FIXME("not implemented\n"); +} + +HRESULT __RPC_STUB ITypeInfo_ReleaseFuncDesc_Stub( + ITypeInfo* This) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + +void CALLBACK ITypeInfo_ReleaseVarDesc_Proxy( + ITypeInfo* This, + VARDESC* pVarDesc) +{ + FIXME("not implemented\n"); +} + +HRESULT __RPC_STUB ITypeInfo_ReleaseVarDesc_Stub( + ITypeInfo* This) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + + +/* ITypeInfo2 */ + +HRESULT CALLBACK ITypeInfo2_GetDocumentation2_Proxy( + ITypeInfo2* This, + MEMBERID memid, + LCID lcid, + BSTR* pbstrHelpString, + DWORD* pdwHelpStringContext, + BSTR* pbstrHelpStringDll) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + +HRESULT __RPC_STUB ITypeInfo2_GetDocumentation2_Stub( + ITypeInfo2* This, + MEMBERID memid, + LCID lcid, + DWORD refPtrFlags, + BSTR* pbstrHelpString, + DWORD* pdwHelpStringContext, + BSTR* pbstrHelpStringDll) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + +/* ITypeLib */ + +UINT CALLBACK ITypeLib_GetTypeInfoCount_Proxy( + ITypeLib* This) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + +HRESULT __RPC_STUB ITypeLib_GetTypeInfoCount_Stub( + ITypeLib* This, + UINT* pcTInfo) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + +HRESULT CALLBACK ITypeLib_GetLibAttr_Proxy( + ITypeLib* This, + TLIBATTR** ppTLibAttr) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + +HRESULT __RPC_STUB ITypeLib_GetLibAttr_Stub( + ITypeLib* This, + LPTLIBATTR* ppTLibAttr, + CLEANLOCALSTORAGE* pDummy) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + +HRESULT CALLBACK ITypeLib_GetDocumentation_Proxy( + ITypeLib* This, + INT index, + BSTR* pBstrName, + BSTR* pBstrDocString, + DWORD* pdwHelpContext, + BSTR* pBstrHelpFile) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + +HRESULT __RPC_STUB ITypeLib_GetDocumentation_Stub( + ITypeLib* This, + INT index, + DWORD refPtrFlags, + BSTR* pBstrName, + BSTR* pBstrDocString, + DWORD* pdwHelpContext, + BSTR* pBstrHelpFile) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + +HRESULT CALLBACK ITypeLib_IsName_Proxy( + ITypeLib* This, + LPOLESTR szNameBuf, + ULONG lHashVal, + BOOL* pfName) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + +HRESULT __RPC_STUB ITypeLib_IsName_Stub( + ITypeLib* This, + LPOLESTR szNameBuf, + ULONG lHashVal, + BOOL* pfName, + BSTR* pBstrLibName) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + +HRESULT CALLBACK ITypeLib_FindName_Proxy( + ITypeLib* This, + LPOLESTR szNameBuf, + ULONG lHashVal, + ITypeInfo** ppTInfo, + MEMBERID* rgMemId, + USHORT* pcFound) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + +HRESULT __RPC_STUB ITypeLib_FindName_Stub( + ITypeLib* This, + LPOLESTR szNameBuf, + ULONG lHashVal, + ITypeInfo** ppTInfo, + MEMBERID* rgMemId, + USHORT* pcFound, + BSTR* pBstrLibName) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + +void CALLBACK ITypeLib_ReleaseTLibAttr_Proxy( + ITypeLib* This, + TLIBATTR* pTLibAttr) +{ + FIXME("not implemented\n"); +} + +HRESULT __RPC_STUB ITypeLib_ReleaseTLibAttr_Stub( + ITypeLib* This) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + + +/* ITypeLib2 */ + +HRESULT CALLBACK ITypeLib2_GetLibStatistics_Proxy( + ITypeLib2* This, + ULONG* pcUniqueNames, + ULONG* pcchUniqueNames) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + +HRESULT __RPC_STUB ITypeLib2_GetLibStatistics_Stub( + ITypeLib2* This, + ULONG* pcUniqueNames, + ULONG* pcchUniqueNames) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + +HRESULT CALLBACK ITypeLib2_GetDocumentation2_Proxy( + ITypeLib2* This, + INT index, + LCID lcid, + BSTR* pbstrHelpString, + DWORD* pdwHelpStringContext, + BSTR* pbstrHelpStringDll) +{ + FIXME("not implemented\n"); + return E_FAIL; +} + +HRESULT __RPC_STUB ITypeLib2_GetDocumentation2_Stub( + ITypeLib2* This, + INT index, + LCID lcid, + DWORD refPtrFlags, + BSTR* pbstrHelpString, + DWORD* pdwHelpStringContext, + BSTR* pbstrHelpStringDll) +{ + FIXME("not implemented\n"); + return E_FAIL; +} diff --git a/reactos/lib/oleaut32/varformat.c b/reactos/lib/oleaut32/varformat.c new file mode 100644 index 00000000000..de43577dcd2 --- /dev/null +++ b/reactos/lib/oleaut32/varformat.c @@ -0,0 +1,2412 @@ +/* + * Variant formatting functions + * + * Copyright 2003 Jon Griffiths + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * NOTES + * Since the formatting functions aren't properly documented, I used the + * Visual Basic documentation as a guide to implementing these functions. This + * means that some named or user-defined formats may work slightly differently. + * Please submit a test case if you find a difference. + */ + +#include "config.h" + +#include +#include +#include +#include + +#define NONAMELESSUNION +#define NONAMELESSSTRUCT +#include "windef.h" +#include "winbase.h" +#include "wine/unicode.h" +#include "winerror.h" +#include "variant.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(variant); + +/* Make sure internal conversions to strings use the '.','+'/'-' and ',' + * format chars from the US locale. This enables us to parse the created + * strings to determine the number of decimal places, exponent, etc. + */ +#define LCID_US MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT) + +static const WCHAR szPercent_d[] = { '%','d','\0' }; +static const WCHAR szPercentZeroTwo_d[] = { '%','0','2','d','\0' }; +static const WCHAR szPercentZeroFour_d[] = { '%','0','4','d','\0' }; +static const WCHAR szPercentZeroStar_d[] = { '%','0','*','d','\0' }; + +#if 0 +#define dump_tokens(rgb) do { \ + int i_; TRACE("Tokens->{ \n"); \ + for (i_ = 0; i_ < rgb[0]; i_++) \ + TRACE("%s0x%02x", i_?",":"",rgb[i_]); \ + TRACE(" }\n"); \ + } while(0) +#endif + +/****************************************************************************** + * Variant-Formats {OLEAUT32} + * + * NOTES + * When formatting a variant a variety of format strings may be used to generate + * different kinds of formatted output. A format string consists of either a named + * format, or a user-defined format. + * + * The following named formats are defined: + *| Name Description + *| ---- ----------- + *| General Date Display Date, and time for non-integer values + *| Short Date Short date format as defined by locale settings + *| Medium Date Medium date format as defined by locale settings + *| Long Date Long date format as defined by locale settings + *| Short Time Short Time format as defined by locale settings + *| Medium Time Medium time format as defined by locale settings + *| Long Time Long time format as defined by locale settings + *| True/False Localised text of "True" or "False" + *| Yes/No Localised text of "Yes" or "No" + *| On/Off Localised text of "On" or "Off" + *| General Number No thousands separator. No decimal points for integers + *| Currency General currency format using localised characters + *| Fixed At least one whole and two fractional digits + *| Standard Same as 'Fixed', but including decimal separators + *| Percent Multiply by 100 and display a trailing '%' character + *| Scientific Display with exponent + * + * User-defined formats consist of a combination of tokens and literal + * characters. Literal characters are copied unmodified to the formatted + * output at the position they occupy in the format string. Any character + * that is not recognised as a token is treated as a literal. A literal can + * also be specified by preceeding it with a backslash character + * (e.g. "\L\i\t\e\r\a\l") or enclosing it in double quotes. + * + * A user-defined format can have up to 4 sections, depending on the type of + * format. The following table lists sections and their meaning: + *| Format Type Sections Meaning + *| ----------- -------- ------- + *| Number 1 Use the same format for all numbers + *| Number 2 Use format 1 for positive and 2 for negative numbers + *| Number 3 Use format 1 for positive, 2 for zero, and 3 + *| for negative numbers. + *| Number 4 Use format 1 for positive, 2 for zero, 3 for + *| negative, and 4 for null numbers. + *| String 1 Use the same format for all strings + *| String 2 Use format 2 for null and empty strings, otherwise + *| use format 1. + *| Date 1 Use the same format for all dates + * + * The formatting tokens fall into several categories depending on the type + * of formatted output. For more information on each type, see + * VarFormat-Dates(), VarFormat-Strings() and VarFormat-Numbers(). + * + * SEE ALSO + * VarTokenizeFormatString(), VarFormatFromTokens(), VarFormat(), + * VarFormatDateTime(), VarFormatNumber(), VarFormatCurrency(). + */ + +/****************************************************************************** + * VarFormat-Strings {OLEAUT32} + * + * NOTES + * When formatting a variant as a string, it is first converted to a VT_BSTR. + * The user-format string defines which characters are copied into which + * positions in the output string. Literals may be inserted in the format + * string. When creating the formatted string, excess characters in the string + * (those not consumed by a token) are appended to the end of the output. If + * there are more tokens than characters in the string to format, spaces will + * be inserted at the start of the string if the '@' token was used. + * + * By default strings are converted to lowercase, or uppercase if the '>' token + * is encountered. This applies to the whole string: it is not possible to + * generate a mixed-case output string. + * + * In user-defined string formats, the following tokens are recognised: + *| Token Description + *| ----- ----------- + *| '@' Copy a char from the source, or a space if no chars are left. + *| '&' Copy a char from the source, or write nothing if no chars are left. + *| '<' Output the whole string as lower-case (the default). + *| '>' Output the whole string as upper-case. + *| '!' MSDN indicates that this character should cause right-to-left + *| copying, however tests show that it is tokenised but not processed. + */ + +/* + * Common format definitions + */ + + /* Fomat types */ +#define FMT_TYPE_UNKNOWN 0x0 +#define FMT_TYPE_GENERAL 0x1 +#define FMT_TYPE_NUMBER 0x2 +#define FMT_TYPE_DATE 0x3 +#define FMT_TYPE_STRING 0x4 + +#define FMT_TO_STRING 0x0 /* If header->size == this, act like VB's Str() fn */ + +typedef struct tagFMT_SHORT_HEADER +{ + BYTE size; /* Size of tokenised block (including header), or FMT_TO_STRING */ + BYTE type; /* Allowable types (FMT_TYPE_*) */ + BYTE offset[1]; /* Offset of the first (and only) format section */ +} FMT_SHORT_HEADER; + +typedef struct tagFMT_HEADER +{ + BYTE size; /* Total size of the whole tokenised block (including header) */ + BYTE type; /* Allowable types (FMT_TYPE_*) */ + BYTE starts[4]; /* Offset of each of the 4 format sections, or 0 if none */ +} FMT_HEADER; + +#define FmtGetPositive(x) (x->starts[0]) +#define FmtGetNegative(x) (x->starts[1] ? x->starts[1] : x->starts[0]) +#define FmtGetZero(x) (x->starts[2] ? x->starts[2] : x->starts[0]) +#define FmtGetNull(x) (x->starts[3] ? x->starts[3] : x->starts[0]) + +/* + * String formats + */ + +#define FMT_FLAG_LT 0x1 /* Has '<' (lower case) */ +#define FMT_FLAG_GT 0x2 /* Has '>' (upper case) */ +#define FMT_FLAG_RTL 0x4 /* Has '!' (Copy right to left) */ + +typedef struct tagFMT_STRING_HEADER +{ + BYTE flags; /* LT, GT, RTL */ + BYTE unknown1; + BYTE unknown2; + BYTE copy_chars; /* Number of chars to be copied */ + BYTE unknown3; +} FMT_STRING_HEADER; + +/* + * Number formats + */ + +#define FMT_FLAG_PERCENT 0x1 /* Has '%' (Percentage) */ +#define FMT_FLAG_EXPONENT 0x2 /* Has 'e' (Exponent/Scientific notation) */ +#define FMT_FLAG_THOUSANDS 0x4 /* Has ',' (Standard use of the thousands separator) */ +#define FMT_FLAG_BOOL 0x20 /* Boolean format */ + +typedef struct tagFMT_NUMBER_HEADER +{ + BYTE flags; /* PERCENT, EXPONENT, THOUSANDS, BOOL */ + BYTE multiplier; /* Multiplier, 100 for percentages */ + BYTE divisor; /* Divisor, 1000 if '%%' was used */ + BYTE whole; /* Number of digits before the decimal point */ + BYTE fractional; /* Number of digits after the decimal point */ +} FMT_NUMBER_HEADER; + +/* + * Date Formats + */ +typedef struct tagFMT_DATE_HEADER +{ + BYTE flags; + BYTE unknown1; + BYTE unknown2; + BYTE unknown3; + BYTE unknown4; +} FMT_DATE_HEADER; + +/* + * Format token values + */ +#define FMT_GEN_COPY 0x00 /* \n, "lit" => 0,pos,len: Copy len chars from input+pos */ +#define FMT_GEN_INLINE 0x01 /* => 1,len,[chars]: Copy len chars from token stream */ +#define FMT_GEN_END 0x02 /* \0,; => 2: End of the tokenised format */ +#define FMT_DATE_TIME_SEP 0x03 /* Time separator char */ +#define FMT_DATE_DATE_SEP 0x04 /* Date separator char */ +#define FMT_DATE_GENERAL 0x05 /* General format date */ +#define FMT_DATE_QUARTER 0x06 /* Quarter of the year from 1-4 */ +#define FMT_DATE_TIME_SYS 0x07 /* System long time format */ +#define FMT_DATE_DAY 0x08 /* Day with no leading 0 */ +#define FMT_DATE_DAY_0 0x09 /* Day with leading 0 */ +#define FMT_DATE_DAY_SHORT 0x0A /* Short day name */ +#define FMT_DATE_DAY_LONG 0x0B /* Long day name */ +#define FMT_DATE_SHORT 0x0C /* Short date format */ +#define FMT_DATE_LONG 0x0D /* Long date format */ +#define FMT_DATE_MEDIUM 0x0E /* Medium date format */ +#define FMT_DATE_DAY_WEEK 0x0F /* First day of the week */ +#define FMT_DATE_WEEK_YEAR 0x10 /* First week of the year */ +#define FMT_DATE_MON 0x11 /* Month with no leading 0 */ +#define FMT_DATE_MON_0 0x12 /* Month with leading 0 */ +#define FMT_DATE_MON_SHORT 0x13 /* Short month name */ +#define FMT_DATE_MON_LONG 0x14 /* Long month name */ +#define FMT_DATE_YEAR_DOY 0x15 /* Day of the year with no leading 0 */ +#define FMT_DATE_YEAR_0 0x16 /* 2 digit year with leading 0 */ +/* NOTE: token 0x17 is not defined, 'yyy' is not valid */ +#define FMT_DATE_YEAR_LONG 0x18 /* 4 digit year */ +#define FMT_DATE_MIN 0x1A /* Minutes with no leading 0 */ +#define FMT_DATE_MIN_0 0x1B /* Minutes with leading 0 */ +#define FMT_DATE_SEC 0x1C /* Seconds with no leading 0 */ +#define FMT_DATE_SEC_0 0x1D /* Seconds with leading 0 */ +#define FMT_DATE_HOUR 0x1E /* Hours with no leading 0 */ +#define FMT_DATE_HOUR_0 0x1F /* Hours with leading 0 */ +#define FMT_DATE_HOUR_12 0x20 /* Hours with no leading 0, 12 hour clock */ +#define FMT_DATE_HOUR_12_0 0x21 /* Hours with leading 0, 12 hour clock */ +#define FMT_DATE_TIME_UNK2 0x23 +/* FIXME: probably missing some here */ +#define FMT_DATE_AMPM_SYS1 0x2E /* AM/PM as defined by system settings */ +#define FMT_DATE_AMPM_UPPER 0x2F /* Upper-case AM or PM */ +#define FMT_DATE_A_UPPER 0x30 /* Upper-case A or P */ +#define FMT_DATE_AMPM_SYS2 0x31 /* AM/PM as defined by system settings */ +#define FMT_DATE_AMPM_LOWER 0x32 /* Lower-case AM or PM */ +#define FMT_DATE_A_LOWER 0x33 /* Lower-case A or P */ +#define FMT_NUM_COPY_ZERO 0x34 /* Copy 1 digit or 0 if no digit */ +#define FMT_NUM_COPY_SKIP 0x35 /* Copy 1 digit or skip if no digit */ +#define FMT_NUM_DECIMAL 0x36 /* Decimal separator */ +#define FMT_NUM_EXP_POS_U 0x37 /* Scientific notation, uppercase, + sign */ +#define FMT_NUM_EXP_NEG_U 0x38 /* Scientific notation, lowercase, - sign */ +#define FMT_NUM_EXP_POS_L 0x39 /* Scientific notation, uppercase, + sign */ +#define FMT_NUM_EXP_NEG_L 0x3A /* Scientific notation, lowercase, - sign */ +#define FMT_NUM_CURRENCY 0x3B /* Currency symbol */ +#define FMT_NUM_TRUE_FALSE 0x3D /* Convert to "True" or "False" */ +#define FMT_NUM_YES_NO 0x3E /* Convert to "Yes" or "No" */ +#define FMT_NUM_ON_OFF 0x3F /* Convert to "On" or "Off" */ +#define FMT_STR_COPY_SPACE 0x40 /* Copy len chars with space if no char */ +#define FMT_STR_COPY_SKIP 0x41 /* Copy len chars or skip if no char */ +/* Wine additions */ +#define FMT_WINE_HOURS_12 0x81 /* Hours using 12 hour clockhourCopy len chars or skip if no char */ + +/* Named Formats and their tokenised values */ +static const WCHAR szGeneralDate[] = { 'G','e','n','e','r','a','l',' ','D','a','t','e','\0' }; +static const BYTE fmtGeneralDate[0x0a] = +{ + 0x0a,FMT_TYPE_DATE,sizeof(FMT_SHORT_HEADER), + 0x0,0x0,0x0,0x0,0x0, + FMT_DATE_GENERAL,FMT_GEN_END +}; + +static const WCHAR szShortDate[] = { 'S','h','o','r','t',' ','D','a','t','e','\0' }; +static const BYTE fmtShortDate[0x0a] = +{ + 0x0a,FMT_TYPE_DATE,sizeof(FMT_SHORT_HEADER), + 0x0,0x0,0x0,0x0,0x0, + FMT_DATE_SHORT,FMT_GEN_END +}; + +static const WCHAR szMediumDate[] = { 'M','e','d','i','u','m',' ','D','a','t','e','\0' }; +static const BYTE fmtMediumDate[0x0a] = +{ + 0x0a,FMT_TYPE_DATE,sizeof(FMT_SHORT_HEADER), + 0x0,0x0,0x0,0x0,0x0, + FMT_DATE_MEDIUM,FMT_GEN_END +}; + +static const WCHAR szLongDate[] = { 'L','o','n','g',' ','D','a','t','e','\0' }; +static const BYTE fmtLongDate[0x0a] = +{ + 0x0a,FMT_TYPE_DATE,sizeof(FMT_SHORT_HEADER), + 0x0,0x0,0x0,0x0,0x0, + FMT_DATE_LONG,FMT_GEN_END +}; + +static const WCHAR szShortTime[] = { 'S','h','o','r','t',' ','T','i','m','e','\0' }; +static const BYTE fmtShortTime[0x0c] = +{ + 0x0c,FMT_TYPE_DATE,sizeof(FMT_SHORT_HEADER), + 0x0,0x0,0x0,0x0,0x0, + FMT_DATE_TIME_UNK2,FMT_DATE_TIME_SEP,FMT_DATE_MIN_0,FMT_GEN_END +}; + +static const WCHAR szMediumTime[] = { 'M','e','d','i','u','m',' ','T','i','m','e','\0' }; +static const BYTE fmtMediumTime[0x11] = +{ + 0x11,FMT_TYPE_DATE,sizeof(FMT_SHORT_HEADER), + 0x0,0x0,0x0,0x0,0x0, + FMT_DATE_HOUR_12_0,FMT_DATE_TIME_SEP,FMT_DATE_MIN_0, + FMT_GEN_INLINE,0x01,' ','\0',FMT_DATE_AMPM_SYS1,FMT_GEN_END +}; + +static const WCHAR szLongTime[] = { 'L','o','n','g',' ','T','i','m','e','\0' }; +static const BYTE fmtLongTime[0x0d] = +{ + 0x0a,FMT_TYPE_DATE,sizeof(FMT_SHORT_HEADER), + 0x0,0x0,0x0,0x0,0x0, + FMT_DATE_TIME_SYS,FMT_GEN_END +}; + +static const WCHAR szTrueFalse[] = { 'T','r','u','e','/','F','a','l','s','e','\0' }; +static const BYTE fmtTrueFalse[0x0d] = +{ + 0x0d,FMT_TYPE_NUMBER,sizeof(FMT_HEADER),0x0,0x0,0x0, + FMT_FLAG_BOOL,0x0,0x0,0x0,0x0, + FMT_NUM_TRUE_FALSE,FMT_GEN_END +}; + +static const WCHAR szYesNo[] = { 'Y','e','s','/','N','o','\0' }; +static const BYTE fmtYesNo[0x0d] = +{ + 0x0d,FMT_TYPE_NUMBER,sizeof(FMT_HEADER),0x0,0x0,0x0, + FMT_FLAG_BOOL,0x0,0x0,0x0,0x0, + FMT_NUM_YES_NO,FMT_GEN_END +}; + +static const WCHAR szOnOff[] = { 'O','n','/','O','f','f','\0' }; +static const BYTE fmtOnOff[0x0d] = +{ + 0x0d,FMT_TYPE_NUMBER,sizeof(FMT_HEADER),0x0,0x0,0x0, + FMT_FLAG_BOOL,0x0,0x0,0x0,0x0, + FMT_NUM_ON_OFF,FMT_GEN_END +}; + +static const WCHAR szGeneralNumber[] = { 'G','e','n','e','r','a','l',' ','N','u','m','b','e','r','\0' }; +static const BYTE fmtGeneralNumber[sizeof(FMT_HEADER)] = +{ + sizeof(FMT_HEADER),FMT_TYPE_GENERAL,sizeof(FMT_HEADER),0x0,0x0,0x0 +}; + +static const WCHAR szCurrency[] = { 'C','u','r','r','e','n','c','y','\0' }; +static const BYTE fmtCurrency[0x26] = +{ + 0x26,FMT_TYPE_NUMBER,sizeof(FMT_HEADER),0x12,0x0,0x0, + /* Positive numbers */ + FMT_FLAG_THOUSANDS,0xcc,0x0,0x1,0x2, + FMT_NUM_CURRENCY,FMT_NUM_COPY_ZERO,0x1,FMT_NUM_DECIMAL,FMT_NUM_COPY_ZERO,0x2, + FMT_GEN_END, + /* Negative numbers */ + FMT_FLAG_THOUSANDS,0xcc,0x0,0x1,0x2, + FMT_GEN_INLINE,0x1,'(','\0',FMT_NUM_CURRENCY,FMT_NUM_COPY_ZERO,0x1, + FMT_NUM_DECIMAL,FMT_NUM_COPY_ZERO,0x2,FMT_GEN_INLINE,0x1,')','\0', + FMT_GEN_END +}; + +static const WCHAR szFixed[] = { 'F','i','x','e','d','\0' }; +static const BYTE fmtFixed[0x11] = +{ + 0x11,FMT_TYPE_NUMBER,sizeof(FMT_HEADER),0x0,0x0,0x0, + 0x0,0x0,0x0,0x1,0x2, + FMT_NUM_COPY_ZERO,0x1,FMT_NUM_DECIMAL,FMT_NUM_COPY_ZERO,0x2,FMT_GEN_END +}; + +static const WCHAR szStandard[] = { 'S','t','a','n','d','a','r','d','\0' }; +static const BYTE fmtStandard[0x11] = +{ + 0x11,FMT_TYPE_NUMBER,sizeof(FMT_HEADER),0x0,0x0,0x0, + FMT_FLAG_THOUSANDS,0x0,0x0,0x1,0x2, + FMT_NUM_COPY_ZERO,0x1,FMT_NUM_DECIMAL,FMT_NUM_COPY_ZERO,0x2,FMT_GEN_END +}; + +static const WCHAR szPercent[] = { 'P','e','r','c','e','n','t','\0' }; +static const BYTE fmtPercent[0x15] = +{ + 0x15,FMT_TYPE_NUMBER,sizeof(FMT_HEADER),0x0,0x0,0x0, + FMT_FLAG_PERCENT,0x1,0x0,0x1,0x2, + FMT_NUM_COPY_ZERO,0x1,FMT_NUM_DECIMAL,FMT_NUM_COPY_ZERO,0x2, + FMT_GEN_INLINE,0x1,'%','\0',FMT_GEN_END +}; + +static const WCHAR szScientific[] = { 'S','c','i','e','n','t','i','f','i','c','\0' }; +static const BYTE fmtScientific[0x13] = +{ + 0x13,FMT_TYPE_NUMBER,sizeof(FMT_HEADER),0x0,0x0,0x0, + FMT_FLAG_EXPONENT,0x0,0x0,0x1,0x2, + FMT_NUM_COPY_ZERO,0x1,FMT_NUM_DECIMAL,FMT_NUM_COPY_ZERO,0x2,FMT_NUM_EXP_POS_U,0x2,FMT_GEN_END +}; + +typedef struct tagNAMED_FORMAT +{ + LPCWSTR name; + const BYTE* format; +} NAMED_FORMAT; + +/* Format name to tokenised format. Must be kept sorted by name */ +static const NAMED_FORMAT VARIANT_NamedFormats[] = +{ + { szCurrency, fmtCurrency }, + { szFixed, fmtFixed }, + { szGeneralDate, fmtGeneralDate }, + { szGeneralNumber, fmtGeneralNumber }, + { szLongDate, fmtLongDate }, + { szLongTime, fmtLongTime }, + { szMediumDate, fmtMediumDate }, + { szMediumTime, fmtMediumTime }, + { szOnOff, fmtOnOff }, + { szPercent, fmtPercent }, + { szScientific, fmtScientific }, + { szShortDate, fmtShortDate }, + { szShortTime, fmtShortTime }, + { szStandard, fmtStandard }, + { szTrueFalse, fmtTrueFalse }, + { szYesNo, fmtYesNo } +}; +typedef const NAMED_FORMAT *LPCNAMED_FORMAT; + +static int FormatCompareFn(const void *l, const void *r) +{ + return strcmpiW(((LPCNAMED_FORMAT)l)->name, ((LPCNAMED_FORMAT)r)->name); +} + +static inline const BYTE *VARIANT_GetNamedFormat(LPCWSTR lpszFormat) +{ + NAMED_FORMAT key; + LPCNAMED_FORMAT fmt; + + key.name = lpszFormat; + fmt = (LPCNAMED_FORMAT)bsearch(&key, VARIANT_NamedFormats, + sizeof(VARIANT_NamedFormats)/sizeof(NAMED_FORMAT), + sizeof(NAMED_FORMAT), FormatCompareFn); + return fmt ? fmt->format : NULL; +} + +/* Return an error if the token for the value will not fit in the destination */ +#define NEED_SPACE(x) if (cbTok < (int)(x)) return TYPE_E_BUFFERTOOSMALL; cbTok -= (x) + +/* Non-zero if the format is unknown or a given type */ +#define COULD_BE(typ) ((!fmt_number && header->type==FMT_TYPE_UNKNOWN)||header->type==typ) + +/* State during tokenising */ +#define FMT_STATE_OPEN_COPY 0x1 /* Last token written was a copy */ +#define FMT_STATE_WROTE_DECIMAL 0x2 /* Already wrote a decimal separator */ +#define FMT_STATE_SEEN_HOURS 0x4 /* See the hh specifier */ +#define FMT_STATE_WROTE_MINUTES 0x8 /* Wrote minutes */ + +/********************************************************************** + * VarTokenizeFormatString [OLEAUT32.140] + * + * Convert a format string into tokenised form. + * + * PARAMS + * lpszFormat [I] Format string to tokenise + * rgbTok [O] Destination for tokenised format + * cbTok [I] Size of rgbTok in bytes + * nFirstDay [I] First day of the week (1-7, or 0 for current system default) + * nFirstWeek [I] How to treat the first week (see notes) + * lcid [I] Locale Id of the format string + * pcbActual [O] If non-NULL, filled with the first token generated + * + * RETURNS + * Success: S_OK. rgbTok contains the tokenised format. + * Failure: E_INVALIDARG, if any argument is invalid. + * TYPE_E_BUFFERTOOSMALL, if rgbTok is not large enough. + * + * NOTES + * Valid values for the nFirstWeek parameter are: + *| Value Meaning + *| ----- ------- + *| 0 Use the current system default + *| 1 The first week is that containing Jan 1 + *| 2 Four or more days of the first week are in the current year + *| 3 The first week is 7 days long + * See Variant-Formats(), VarFormatFromTokens(). + */ +HRESULT WINAPI VarTokenizeFormatString(LPOLESTR lpszFormat, LPBYTE rgbTok, + int cbTok, int nFirstDay, int nFirstWeek, + LCID lcid, int *pcbActual) +{ + /* Note: none of these strings should be NUL terminated */ + static const WCHAR szTTTTT[] = { 't','t','t','t','t' }; + static const WCHAR szAMPM[] = { 'A','M','P','M' }; + static const WCHAR szampm[] = { 'a','m','p','m' }; + static const WCHAR szAMSlashPM[] = { 'A','M','/','P','M' }; + static const WCHAR szamSlashpm[] = { 'a','m','/','p','m' }; + const BYTE *namedFmt; + FMT_HEADER *header = (FMT_HEADER*)rgbTok; + FMT_STRING_HEADER *str_header = (FMT_STRING_HEADER*)(rgbTok + sizeof(FMT_HEADER)); + FMT_NUMBER_HEADER *num_header = (FMT_NUMBER_HEADER*)str_header; + FMT_DATE_HEADER *date_header = (FMT_DATE_HEADER*)str_header; + BYTE* pOut = rgbTok + sizeof(FMT_HEADER) + sizeof(FMT_STRING_HEADER); + BYTE* pLastHours = NULL; + BYTE fmt_number = 0; + DWORD fmt_state = 0; + LPCWSTR pFormat = lpszFormat; + + TRACE("(%s,%p,%d,%d,%d,0x%08lx,%p)\n", debugstr_w(lpszFormat), rgbTok, cbTok, + nFirstDay, nFirstWeek, lcid, pcbActual); + + if (!rgbTok || + nFirstDay < 0 || nFirstDay > 7 || nFirstWeek < 0 || nFirstWeek > 3) + return E_INVALIDARG; + + if (!lpszFormat || !*lpszFormat) + { + /* An empty string means 'general format' */ + NEED_SPACE(sizeof(BYTE)); + *rgbTok = FMT_TO_STRING; + if (pcbActual) + *pcbActual = FMT_TO_STRING; + return S_OK; + } + + if (cbTok > 255) + cbTok = 255; /* Ensure we error instead of wrapping */ + + /* Named formats */ + namedFmt = VARIANT_GetNamedFormat(lpszFormat); + if (namedFmt) + { + NEED_SPACE(namedFmt[0]); + memcpy(rgbTok, namedFmt, namedFmt[0]); + TRACE("Using pre-tokenised named format %s\n", debugstr_w(lpszFormat)); + /* FIXME: pcbActual */ + return S_OK; + } + + /* Insert header */ + NEED_SPACE(sizeof(FMT_HEADER) + sizeof(FMT_STRING_HEADER)); + memset(header, 0, sizeof(FMT_HEADER)); + memset(str_header, 0, sizeof(FMT_STRING_HEADER)); + + header->starts[fmt_number] = sizeof(FMT_HEADER); + + while (*pFormat) + { + /* -------------- + * General tokens + * -------------- + */ + if (*pFormat == ';') + { + while (*pFormat == ';') + { + TRACE(";\n"); + if (++fmt_number > 3) + return E_INVALIDARG; /* too many formats */ + pFormat++; + } + if (*pFormat) + { + TRACE("New header\n"); + NEED_SPACE(sizeof(BYTE) + sizeof(FMT_STRING_HEADER)); + *pOut++ = FMT_GEN_END; + + header->starts[fmt_number] = pOut - rgbTok; + str_header = (FMT_STRING_HEADER*)pOut; + num_header = (FMT_NUMBER_HEADER*)pOut; + date_header = (FMT_DATE_HEADER*)pOut; + memset(str_header, 0, sizeof(FMT_STRING_HEADER)); + pOut += sizeof(FMT_STRING_HEADER); + fmt_state = 0; + pLastHours = NULL; + } + } + else if (*pFormat == '\\') + { + /* Escaped character */ + if (pFormat[1]) + { + NEED_SPACE(3 * sizeof(BYTE)); + pFormat++; + *pOut++ = FMT_GEN_COPY; + *pOut++ = pFormat - lpszFormat; + *pOut++ = 0x1; + fmt_state |= FMT_STATE_OPEN_COPY; + TRACE("'\\'\n"); + } + else + fmt_state &= ~FMT_STATE_OPEN_COPY; + pFormat++; + } + else if (*pFormat == '"') + { + /* Escaped string + * Note: Native encodes "" as a copy of length zero. That's just dumb, so + * here we avoid encoding anything in this case. + */ + if (!pFormat[1]) + pFormat++; + else if (pFormat[1] == '"') + { + pFormat += 2; + } + else + { + LPCWSTR start = ++pFormat; + while (*pFormat && *pFormat != '"') + pFormat++; + NEED_SPACE(3 * sizeof(BYTE)); + *pOut++ = FMT_GEN_COPY; + *pOut++ = start - lpszFormat; + *pOut++ = pFormat - start; + if (*pFormat == '"') + pFormat++; + TRACE("Quoted string pos %d, len %d\n", pOut[-2], pOut[-1]); + } + fmt_state &= ~FMT_STATE_OPEN_COPY; + } + /* ------------- + * Number tokens + * ------------- + */ + else if (*pFormat == '0' && COULD_BE(FMT_TYPE_NUMBER)) + { + /* Number formats: Digit from number or '0' if no digits + * Other formats: Literal + * Types the format if found + */ + header->type = FMT_TYPE_NUMBER; + NEED_SPACE(2 * sizeof(BYTE)); + *pOut++ = FMT_NUM_COPY_ZERO; + *pOut = 0x0; + while (*pFormat == '0') + { + *pOut = *pOut + 1; + pFormat++; + } + if (fmt_state & FMT_STATE_WROTE_DECIMAL) + num_header->fractional += *pOut; + else + num_header->whole += *pOut; + TRACE("%d 0's\n", *pOut); + pOut++; + fmt_state &= ~FMT_STATE_OPEN_COPY; + } + else if (*pFormat == '#' && COULD_BE(FMT_TYPE_NUMBER)) + { + /* Number formats: Digit from number or blank if no digits + * Other formats: Literal + * Types the format if found + */ + header->type = FMT_TYPE_NUMBER; + NEED_SPACE(2 * sizeof(BYTE)); + *pOut++ = FMT_NUM_COPY_SKIP; + *pOut = 0x0; + while (*pFormat == '#') + { + *pOut = *pOut + 1; + pFormat++; + } + if (fmt_state & FMT_STATE_WROTE_DECIMAL) + num_header->fractional += *pOut; + else + num_header->whole += *pOut; + TRACE("%d #'s\n", *pOut); + pOut++; + fmt_state &= ~FMT_STATE_OPEN_COPY; + } + else if (*pFormat == '.' && COULD_BE(FMT_TYPE_NUMBER) && + !(fmt_state & FMT_STATE_WROTE_DECIMAL)) + { + /* Number formats: Decimal separator when 1st seen, literal thereafter + * Other formats: Literal + * Types the format if found + */ + header->type = FMT_TYPE_NUMBER; + NEED_SPACE(sizeof(BYTE)); + *pOut++ = FMT_NUM_DECIMAL; + fmt_state |= FMT_STATE_WROTE_DECIMAL; + fmt_state &= ~FMT_STATE_OPEN_COPY; + pFormat++; + TRACE("decimal sep\n"); + } + /* FIXME: E+ E- e+ e- => Exponent */ + /* FIXME: %% => Divide by 1000 */ + else if (*pFormat == ',' && header->type == FMT_TYPE_NUMBER) + { + /* Number formats: Use the thousands separator + * Other formats: Literal + */ + num_header->flags |= FMT_FLAG_THOUSANDS; + pFormat++; + fmt_state &= ~FMT_STATE_OPEN_COPY; + TRACE("thousands sep\n"); + } + /* ----------- + * Date tokens + * ----------- + */ + else if (*pFormat == '/' && COULD_BE(FMT_TYPE_DATE)) + { + /* Date formats: Date separator + * Other formats: Literal + * Types the format if found + */ + header->type = FMT_TYPE_DATE; + NEED_SPACE(sizeof(BYTE)); + *pOut++ = FMT_DATE_DATE_SEP; + pFormat++; + fmt_state &= ~FMT_STATE_OPEN_COPY; + TRACE("date sep\n"); + } + else if (*pFormat == ':' && COULD_BE(FMT_TYPE_DATE)) + { + /* Date formats: Time separator + * Other formats: Literal + * Types the format if found + */ + header->type = FMT_TYPE_DATE; + NEED_SPACE(sizeof(BYTE)); + *pOut++ = FMT_DATE_TIME_SEP; + pFormat++; + fmt_state &= ~FMT_STATE_OPEN_COPY; + TRACE("time sep\n"); + } + else if ((*pFormat == 'a' || *pFormat == 'A') && + !strncmpiW(pFormat, szAMPM, sizeof(szAMPM)/sizeof(WCHAR))) + { + /* Date formats: System AM/PM designation + * Other formats: Literal + * Types the format if found + */ + header->type = FMT_TYPE_DATE; + NEED_SPACE(sizeof(BYTE)); + pFormat += sizeof(szAMPM)/sizeof(WCHAR); + if (!strncmpW(pFormat, szampm, sizeof(szampm)/sizeof(WCHAR))) + *pOut++ = FMT_DATE_AMPM_SYS2; + else + *pOut++ = FMT_DATE_AMPM_SYS1; + if (pLastHours) + *pLastHours = *pLastHours + 2; + TRACE("ampm\n"); + } + else if (*pFormat == 'a' && pFormat[1] == '/' && + (pFormat[2] == 'p' || pFormat[2] == 'P')) + { + /* Date formats: lowercase a or p designation + * Other formats: Literal + * Types the format if found + */ + header->type = FMT_TYPE_DATE; + NEED_SPACE(sizeof(BYTE)); + pFormat += 3; + *pOut++ = FMT_DATE_A_LOWER; + if (pLastHours) + *pLastHours = *pLastHours + 2; + TRACE("a/p\n"); + } + else if (*pFormat == 'A' && pFormat[1] == '/' && + (pFormat[2] == 'p' || pFormat[2] == 'P')) + { + /* Date formats: Uppercase a or p designation + * Other formats: Literal + * Types the format if found + */ + header->type = FMT_TYPE_DATE; + NEED_SPACE(sizeof(BYTE)); + pFormat += 3; + *pOut++ = FMT_DATE_A_UPPER; + if (pLastHours) + *pLastHours = *pLastHours + 2; + TRACE("A/P\n"); + } + else if (*pFormat == 'a' && + !strncmpW(pFormat, szamSlashpm, sizeof(szamSlashpm)/sizeof(WCHAR))) + { + /* Date formats: lowercase AM or PM designation + * Other formats: Literal + * Types the format if found + */ + header->type = FMT_TYPE_DATE; + NEED_SPACE(sizeof(BYTE)); + pFormat += sizeof(szamSlashpm)/sizeof(WCHAR); + *pOut++ = FMT_DATE_AMPM_LOWER; + if (pLastHours) + *pLastHours = *pLastHours + 2; + TRACE("AM/PM\n"); + } + else if (*pFormat == 'A' && + !strncmpW(pFormat, szAMSlashPM, sizeof(szAMSlashPM)/sizeof(WCHAR))) + { + /* Date formats: Uppercase AM or PM designation + * Other formats: Literal + * Types the format if found + */ + header->type = FMT_TYPE_DATE; + NEED_SPACE(sizeof(BYTE)); + pFormat += sizeof(szAMSlashPM)/sizeof(WCHAR); + *pOut++ = FMT_DATE_AMPM_UPPER; + TRACE("AM/PM\n"); + } + else if (*pFormat == 'c' || *pFormat == 'C') + { + /* Date formats: General date format + * Other formats: Literal + * Types the format if found + */ + header->type = FMT_TYPE_DATE; + NEED_SPACE(sizeof(BYTE)); + pFormat += sizeof(szAMSlashPM)/sizeof(WCHAR); + *pOut++ = FMT_DATE_GENERAL; + TRACE("gen date\n"); + } + else if ((*pFormat == 'd' || *pFormat == 'D') && COULD_BE(FMT_TYPE_DATE)) + { + /* Date formats: Day specifier + * Other formats: Literal + * Types the format if found + */ + int count = -1; + header->type = FMT_TYPE_DATE; + while ((*pFormat == 'd' || *pFormat == 'D') && count < 6) + { + pFormat++; + count++; + } + NEED_SPACE(sizeof(BYTE)); + *pOut++ = FMT_DATE_DAY + count; + fmt_state &= ~FMT_STATE_OPEN_COPY; + /* When we find the days token, reset the seen hours state so that + * 'mm' is again written as month when encountered. + */ + fmt_state &= ~FMT_STATE_SEEN_HOURS; + TRACE("%d d's\n", count + 1); + } + else if ((*pFormat == 'h' || *pFormat == 'H') && COULD_BE(FMT_TYPE_DATE)) + { + /* Date formats: Hour specifier + * Other formats: Literal + * Types the format if found + */ + header->type = FMT_TYPE_DATE; + NEED_SPACE(sizeof(BYTE)); + pFormat++; + /* Record the position of the hours specifier - if we encounter + * an am/pm specifier we will change the hours from 24 to 12. + */ + pLastHours = pOut; + if (*pFormat == 'h' || *pFormat == 'H') + { + pFormat++; + *pOut++ = FMT_DATE_HOUR_0; + TRACE("hh\n"); + } + else + { + *pOut++ = FMT_DATE_HOUR; + TRACE("h\n"); + } + fmt_state &= ~FMT_STATE_OPEN_COPY; + /* Note that now we have seen an hours token, the next occurence of + * 'mm' indicates minutes, not months. + */ + fmt_state |= FMT_STATE_SEEN_HOURS; + } + else if ((*pFormat == 'm' || *pFormat == 'M') && COULD_BE(FMT_TYPE_DATE)) + { + /* Date formats: Month specifier (or Minute specifier, after hour specifier) + * Other formats: Literal + * Types the format if found + */ + int count = -1; + header->type = FMT_TYPE_DATE; + while ((*pFormat == 'm' || *pFormat == 'M') && count < 4) + { + pFormat++; + count++; + } + NEED_SPACE(sizeof(BYTE)); + if (count <= 1 && fmt_state & FMT_STATE_SEEN_HOURS && + !(fmt_state & FMT_STATE_WROTE_MINUTES)) + { + /* We have seen an hours specifier and not yet written a minutes + * specifier. Write this as minutes and thereafter as months. + */ + *pOut++ = count == 1 ? FMT_DATE_MIN_0 : FMT_DATE_MIN; + fmt_state |= FMT_STATE_WROTE_MINUTES; /* Hereafter write months */ + } + else + *pOut++ = FMT_DATE_MON + count; /* Months */ + fmt_state &= ~FMT_STATE_OPEN_COPY; + TRACE("%d m's\n", count + 1); + } + else if ((*pFormat == 'n' || *pFormat == 'N') && COULD_BE(FMT_TYPE_DATE)) + { + /* Date formats: Minute specifier + * Other formats: Literal + * Types the format if found + */ + header->type = FMT_TYPE_DATE; + NEED_SPACE(sizeof(BYTE)); + pFormat++; + if (*pFormat == 'n' || *pFormat == 'N') + { + pFormat++; + *pOut++ = FMT_DATE_MIN_0; + TRACE("nn\n"); + } + else + { + *pOut++ = FMT_DATE_MIN; + TRACE("n\n"); + } + fmt_state &= ~FMT_STATE_OPEN_COPY; + } + else if ((*pFormat == 'q' || *pFormat == 'q') && COULD_BE(FMT_TYPE_DATE)) + { + /* Date formats: Quarter specifier + * Other formats: Literal + * Types the format if found + */ + header->type = FMT_TYPE_DATE; + NEED_SPACE(sizeof(BYTE)); + *pOut++ = FMT_DATE_QUARTER; + pFormat++; + fmt_state &= ~FMT_STATE_OPEN_COPY; + TRACE("quarter\n"); + } + else if ((*pFormat == 's' || *pFormat == 'S') && COULD_BE(FMT_TYPE_DATE)) + { + /* Date formats: Second specifier + * Other formats: Literal + * Types the format if found + */ + header->type = FMT_TYPE_DATE; + NEED_SPACE(sizeof(BYTE)); + pFormat++; + if (*pFormat == 's' || *pFormat == 'S') + { + pFormat++; + *pOut++ = FMT_DATE_SEC_0; + TRACE("ss\n"); + } + else + { + *pOut++ = FMT_DATE_SEC; + TRACE("s\n"); + } + fmt_state &= ~FMT_STATE_OPEN_COPY; + } + else if ((*pFormat == 't' || *pFormat == 'T') && + !strncmpiW(pFormat, szTTTTT, sizeof(szTTTTT)/sizeof(WCHAR))) + { + /* Date formats: System time specifier + * Other formats: Literal + * Types the format if found + */ + header->type = FMT_TYPE_DATE; + pFormat += sizeof(szTTTTT)/sizeof(WCHAR); + NEED_SPACE(sizeof(BYTE)); + *pOut++ = FMT_DATE_TIME_SYS; + fmt_state &= ~FMT_STATE_OPEN_COPY; + } + else if ((*pFormat == 'w' || *pFormat == 'W') && COULD_BE(FMT_TYPE_DATE)) + { + /* Date formats: Week of the year/Day of the week + * Other formats: Literal + * Types the format if found + */ + header->type = FMT_TYPE_DATE; + pFormat++; + if (*pFormat == 'w' || *pFormat == 'W') + { + NEED_SPACE(3 * sizeof(BYTE)); + pFormat++; + *pOut++ = FMT_DATE_WEEK_YEAR; + *pOut++ = nFirstDay; + *pOut++ = nFirstWeek; + TRACE("ww\n"); + } + else + { + NEED_SPACE(2 * sizeof(BYTE)); + *pOut++ = FMT_DATE_DAY_WEEK; + *pOut++ = nFirstDay; + TRACE("w\n"); + } + + fmt_state &= ~FMT_STATE_OPEN_COPY; + } + else if ((*pFormat == 'y' || *pFormat == 'Y') && COULD_BE(FMT_TYPE_DATE)) + { + /* Date formats: Day of year/Year specifier + * Other formats: Literal + * Types the format if found + */ + int count = -1; + header->type = FMT_TYPE_DATE; + while ((*pFormat == 'y' || *pFormat == 'Y') && count < 4) + { + pFormat++; + count++; + } + if (count == 2) + { + count--; /* 'yyy' has no meaning, despite what MSDN says */ + pFormat--; + } + NEED_SPACE(sizeof(BYTE)); + *pOut++ = FMT_DATE_YEAR_DOY + count; + fmt_state &= ~FMT_STATE_OPEN_COPY; + TRACE("%d y's\n", count + 1); + } + /* ------------- + * String tokens + * ------------- + */ + else if (*pFormat == '@' && COULD_BE(FMT_TYPE_STRING)) + { + /* String formats: Character from string or space if no char + * Other formats: Literal + * Types the format if found + */ + header->type = FMT_TYPE_STRING; + NEED_SPACE(2 * sizeof(BYTE)); + *pOut++ = FMT_STR_COPY_SPACE; + *pOut = 0x0; + while (*pFormat == '@') + { + *pOut = *pOut + 1; + str_header->copy_chars++; + pFormat++; + } + TRACE("%d @'s\n", *pOut); + pOut++; + fmt_state &= ~FMT_STATE_OPEN_COPY; + } + else if (*pFormat == '&' && COULD_BE(FMT_TYPE_STRING)) + { + /* String formats: Character from string or skip if no char + * Other formats: Literal + * Types the format if found + */ + header->type = FMT_TYPE_STRING; + NEED_SPACE(2 * sizeof(BYTE)); + *pOut++ = FMT_STR_COPY_SKIP; + *pOut = 0x0; + while (*pFormat == '&') + { + *pOut = *pOut + 1; + str_header->copy_chars++; + pFormat++; + } + TRACE("%d &'s\n", *pOut); + pOut++; + fmt_state &= ~FMT_STATE_OPEN_COPY; + } + else if ((*pFormat == '<' || *pFormat == '>') && COULD_BE(FMT_TYPE_STRING)) + { + /* String formats: Use upper/lower case + * Other formats: Literal + * Types the format if found + */ + header->type = FMT_TYPE_STRING; + if (*pFormat == '<') + str_header->flags |= FMT_FLAG_LT; + else + str_header->flags |= FMT_FLAG_GT; + TRACE("to %s case\n", *pFormat == '<' ? "lower" : "upper"); + pFormat++; + fmt_state &= ~FMT_STATE_OPEN_COPY; + } + else if (*pFormat == '!' && COULD_BE(FMT_TYPE_STRING)) + { + /* String formats: Copy right to left + * Other formats: Literal + * Types the format if found + */ + header->type = FMT_TYPE_STRING; + str_header->flags |= FMT_FLAG_RTL; + pFormat++; + fmt_state &= ~FMT_STATE_OPEN_COPY; + TRACE("copy right-to-left\n"); + } + /* -------- + * Literals + * -------- + */ + /* FIXME: [ seems to be ignored */ + else + { + if (*pFormat == '%' && header->type == FMT_TYPE_NUMBER) + { + /* Number formats: Percentage indicator, also a literal + * Other formats: Literal + * Doesn't type the format + */ + num_header->flags |= FMT_FLAG_PERCENT; + } + + if (fmt_state & FMT_STATE_OPEN_COPY) + { + pOut[-1] = pOut[-1] + 1; /* Increase the length of the open copy */ + TRACE("extend copy (char '%c'), length now %d\n", *pFormat, pOut[-1]); + } + else + { + /* Create a new open copy */ + TRACE("New copy (char '%c')\n", *pFormat); + NEED_SPACE(3 * sizeof(BYTE)); + *pOut++ = FMT_GEN_COPY; + *pOut++ = pFormat - lpszFormat; + *pOut++ = 0x1; + fmt_state |= FMT_STATE_OPEN_COPY; + } + pFormat++; + } + } + + *pOut++ = FMT_GEN_END; + + header->size = pOut - rgbTok; + if (pcbActual) + *pcbActual = header->size; + + return S_OK; +} + +/* Number formatting state flags */ +#define NUM_WROTE_DEC 0x01 /* Written the decimal separator */ + +/* Format a variant using a number format */ +static HRESULT VARIANT_FormatNumber(LPVARIANT pVarIn, LPOLESTR lpszFormat, + LPBYTE rgbTok, ULONG dwFlags, + BSTR *pbstrOut, LCID lcid) +{ + BYTE rgbDig[256]; + NUMPARSE np; + int wholeNumberDigits, fractionalDigits, divisor10 = 0, multiplier10 = 0; + WCHAR buff[256], *pBuff = buff; + VARIANT vString, vBool; + DWORD dwState = 0; + FMT_HEADER *header = (FMT_HEADER*)rgbTok; + FMT_NUMBER_HEADER *numHeader; + const BYTE* pToken = NULL; + HRESULT hRes = S_OK; + + TRACE("(%p->(%s%s),%s,%p,0x%08lx,%p,0x%08lx)\n", pVarIn, debugstr_VT(pVarIn), + debugstr_VF(pVarIn), debugstr_w(lpszFormat), rgbTok, dwFlags, pbstrOut, + lcid); + + V_VT(&vString) = VT_EMPTY; + V_VT(&vBool) = VT_BOOL; + + if (V_TYPE(pVarIn) == VT_EMPTY || V_TYPE(pVarIn) == VT_NULL) + { + wholeNumberDigits = fractionalDigits = 0; + numHeader = (FMT_NUMBER_HEADER*)(rgbTok + FmtGetNull(header)); + V_BOOL(&vBool) = VARIANT_FALSE; + } + else + { + /* Get a number string from pVarIn, and parse it */ + hRes = VariantChangeTypeEx(&vString, pVarIn, LCID_US, VARIANT_NOUSEROVERRIDE, VT_BSTR); + if (FAILED(hRes)) + return hRes; + + np.cDig = sizeof(rgbDig); + np.dwInFlags = NUMPRS_STD; + hRes = VarParseNumFromStr(V_BSTR(&vString), LCID_US, 0, &np, rgbDig); + if (FAILED(hRes)) + return hRes; + + if (np.nPwr10 < 0) + { + if (-np.nPwr10 >= np.cDig) + { + /* A real number < +/- 1.0 e.g. 0.1024 or 0.01024 */ + wholeNumberDigits = 0; + fractionalDigits = np.cDig; + divisor10 = -np.nPwr10; + } + else + { + /* An exactly represented real number e.g. 1.024 */ + wholeNumberDigits = np.cDig + np.nPwr10; + fractionalDigits = np.cDig - wholeNumberDigits; + divisor10 = np.cDig - wholeNumberDigits; + } + } + else if (np.nPwr10 == 0) + { + /* An exactly represented whole number e.g. 1024 */ + wholeNumberDigits = np.cDig; + fractionalDigits = 0; + } + else /* np.nPwr10 > 0 */ + { + /* A whole number followed by nPwr10 0's e.g. 102400 */ + wholeNumberDigits = np.cDig; + fractionalDigits = 0; + multiplier10 = np.nPwr10; + } + + /* Figure out which format to use */ + if (np.dwOutFlags & NUMPRS_NEG) + { + numHeader = (FMT_NUMBER_HEADER*)(rgbTok + FmtGetNegative(header)); + V_BOOL(&vBool) = VARIANT_TRUE; + } + else if (wholeNumberDigits == 1 && !fractionalDigits && !multiplier10 && + !divisor10 && rgbDig[0] == 0) + { + numHeader = (FMT_NUMBER_HEADER*)(rgbTok + FmtGetZero(header)); + V_BOOL(&vBool) = VARIANT_FALSE; + } + else + { + numHeader = (FMT_NUMBER_HEADER*)(rgbTok + FmtGetPositive(header)); + V_BOOL(&vBool) = VARIANT_TRUE; + } + + TRACE("num header: flags = 0x%x, mult=%d, div=%d, whole=%d, fract=%d\n", + numHeader->flags, numHeader->multiplier, numHeader->divisor, + numHeader->whole, numHeader->fractional); + + if (numHeader->flags & FMT_FLAG_PERCENT && + !(wholeNumberDigits == 1 && !fractionalDigits && !multiplier10 && + !divisor10 && rgbDig[0] == 0)) + { + /* *100 for %'s. Try to 'steal' fractional digits if we can */ + TRACE("Fraction - multiply by 100\n"); + if (!fractionalDigits) + multiplier10 += 2; + else + { + fractionalDigits--; + wholeNumberDigits++; + if (!fractionalDigits) + multiplier10++; + else + { + fractionalDigits--; + wholeNumberDigits++; + } + } + } + TRACE("cDig %d; nPwr10 %d, whole %d, frac %d ", np.cDig, + np.nPwr10, wholeNumberDigits, fractionalDigits); + TRACE("mult %d; div %d\n", multiplier10, divisor10); + + } + pToken = (const BYTE*)numHeader + sizeof(FMT_NUMBER_HEADER); + + while (SUCCEEDED(hRes) && *pToken != FMT_GEN_END) + { + WCHAR defaultChar = '?'; + DWORD boolFlag, localeValue = 0; + + if (pToken - rgbTok > header->size) + { + ERR("Ran off the end of the format!\n"); + hRes = E_INVALIDARG; + goto VARIANT_FormatNumber_Exit; + } + + switch (*pToken) + { + case FMT_GEN_COPY: + TRACE("copy %s\n", debugstr_wn(lpszFormat + pToken[1], pToken[2])); + memcpy(pBuff, lpszFormat + pToken[1], pToken[2] * sizeof(WCHAR)); + pBuff += pToken[2]; + pToken += 2; + break; + + case FMT_GEN_INLINE: + pToken += 2; + TRACE("copy %s\n", debugstr_a(pToken)); + while (*pToken) + *pBuff++ = *pToken++; + break; + + case FMT_NUM_YES_NO: + boolFlag = VAR_BOOLYESNO; + goto VARIANT_FormatNumber_Bool; + break; + + case FMT_NUM_ON_OFF: + boolFlag = VAR_BOOLONOFF; + goto VARIANT_FormatNumber_Bool; + break; + + case FMT_NUM_TRUE_FALSE: + boolFlag = VAR_LOCALBOOL; + +VARIANT_FormatNumber_Bool: + { + BSTR boolStr = NULL; + + if (pToken[1] != FMT_GEN_END) + { + ERR("Boolean token not at end of format!\n"); + hRes = E_INVALIDARG; + goto VARIANT_FormatNumber_Exit; + } + hRes = VarBstrFromBool(V_BOOL(&vBool), lcid, boolFlag, &boolStr); + if (SUCCEEDED(hRes)) + { + strcpyW(pBuff, boolStr); + SysFreeString(boolStr); + while (*pBuff) + pBuff++; + } + } + break; + + case FMT_NUM_DECIMAL: + TRACE("write decimal separator\n"); + localeValue = LOCALE_SDECIMAL; + defaultChar = '.'; + dwState |= NUM_WROTE_DEC; + break; + + case FMT_NUM_CURRENCY: + TRACE("write currency symbol\n"); + localeValue = LOCALE_SCURRENCY; + defaultChar = '$'; + break; + + case FMT_NUM_EXP_POS_U: + case FMT_NUM_EXP_POS_L: + case FMT_NUM_EXP_NEG_U: + case FMT_NUM_EXP_NEG_L: + if (*pToken == FMT_NUM_EXP_POS_L || *pToken == FMT_NUM_EXP_NEG_L) + *pBuff++ = 'e'; + else + *pBuff++ = 'E'; + if (divisor10) + { + *pBuff++ = '-'; + sprintfW(pBuff, szPercentZeroStar_d, pToken[1], divisor10); + } + else + { + if (*pToken == FMT_NUM_EXP_POS_L || *pToken == FMT_NUM_EXP_POS_U) + *pBuff++ = '+'; + sprintfW(pBuff, szPercentZeroStar_d, pToken[1], multiplier10); + } + while (*pBuff) + pBuff++; + pToken++; + break; + + case FMT_NUM_COPY_SKIP: + if (dwState & NUM_WROTE_DEC) + { + int count; + + TRACE("write %d fractional digits or skip\n", pToken[1]); + + for (count = 0; count < fractionalDigits; count++) + pBuff[count] = '0' + rgbDig[wholeNumberDigits + count]; + pBuff += fractionalDigits; + } + else + { + int count; + + TRACE("write %d digits or skip\n", pToken[1]); + + if (wholeNumberDigits > 1 || rgbDig[0] > 0) + { + TRACE("write %d whole number digits\n", wholeNumberDigits); + for (count = 0; count < wholeNumberDigits; count++) + *pBuff++ = '0' + rgbDig[count]; + TRACE("write %d whole trailing 0's\n", multiplier10); + for (count = 0; count < multiplier10; count++) + *pBuff++ = '0'; /* Write trailing zeros for multiplied values */ + } + } + pToken++; + break; + + case FMT_NUM_COPY_ZERO: + if (dwState & NUM_WROTE_DEC) + { + int count; + + TRACE("write %d fractional digits or 0's\n", pToken[1]); + + for (count = 0; count < fractionalDigits; count++) + pBuff[count] = '0' + rgbDig[wholeNumberDigits + count]; + pBuff += fractionalDigits; + if (pToken[1] > fractionalDigits) + { + count = pToken[1] - fractionalDigits; + while (count--) + *pBuff++ = '0'; /* Write trailing zeros for missing digits */ + } + } + else + { + int count; + + TRACE("write %d digits or 0's\n", pToken[1]); + + if (pToken[1] > (wholeNumberDigits + multiplier10)) + { + count = pToken[1] - (wholeNumberDigits + multiplier10); + TRACE("write %d leading zeros\n", count); + while(count--) + *pBuff++ = '0'; /* Write leading zeros for missing digits */ + } + TRACE("write %d whole number digits\n", wholeNumberDigits); + for (count = 0; count < wholeNumberDigits; count++) + *pBuff++ = '0' + rgbDig[count]; + TRACE("write %d whole trailing 0's\n", multiplier10); + for (count = 0; count < multiplier10; count++) + *pBuff++ = '0'; /* Write trailing zeros for multiplied values */ + } + pToken++; + break; + + default: + ERR("Unknown token 0x%02x!\n", *pToken); + hRes = E_INVALIDARG; + goto VARIANT_FormatNumber_Exit; + break; + } + if (localeValue) + { + if (GetLocaleInfoW(lcid, localeValue, pBuff, + sizeof(buff)/sizeof(WCHAR)-(pBuff-buff))) + { + TRACE("added %s\n", debugstr_w(pBuff)); + while (*pBuff) + pBuff++; + } + else + { + TRACE("added %d '%c'\n", defaultChar, defaultChar); + *pBuff++ = defaultChar; + } + } + pToken++; + } + +VARIANT_FormatNumber_Exit: + VariantClear(&vString); + *pBuff = '\0'; + TRACE("buff is %s\n", debugstr_w(buff)); + if (SUCCEEDED(hRes)) + { + *pbstrOut = SysAllocString(buff); + if (!*pbstrOut) + hRes = E_OUTOFMEMORY; + } + return hRes; +} + +/* Format a variant using a date format */ +static HRESULT VARIANT_FormatDate(LPVARIANT pVarIn, LPOLESTR lpszFormat, + LPBYTE rgbTok, ULONG dwFlags, + BSTR *pbstrOut, LCID lcid) +{ + WCHAR buff[256], *pBuff = buff; + VARIANT vDate; + UDATE udate; + FMT_HEADER *header = (FMT_HEADER*)rgbTok; + FMT_DATE_HEADER *dateHeader; + const BYTE* pToken = NULL; + HRESULT hRes; + + TRACE("(%p->(%s%s),%s,%p,0x%08lx,%p,0x%08lx)\n", pVarIn, debugstr_VT(pVarIn), + debugstr_VF(pVarIn), debugstr_w(lpszFormat), rgbTok, dwFlags, pbstrOut, + lcid); + + V_VT(&vDate) = VT_EMPTY; + + if (V_TYPE(pVarIn) == VT_EMPTY || V_TYPE(pVarIn) == VT_NULL) + { + dateHeader = (FMT_DATE_HEADER*)(rgbTok + FmtGetNegative(header)); + V_DATE(&vDate) = 0; + } + else + { + USHORT usFlags = dwFlags & VARIANT_CALENDAR_HIJRI ? VAR_CALENDAR_HIJRI : 0; + + hRes = VariantChangeTypeEx(&vDate, pVarIn, LCID_US, usFlags, VT_DATE); + if (FAILED(hRes)) + return hRes; + dateHeader = (FMT_DATE_HEADER*)(rgbTok + FmtGetPositive(header)); + } + + hRes = VarUdateFromDate(V_DATE(&vDate), 0 /* FIXME: flags? */, &udate); + if (FAILED(hRes)) + return hRes; + pToken = (const BYTE*)dateHeader + sizeof(FMT_DATE_HEADER); + + while (*pToken != FMT_GEN_END) + { + DWORD dwVal = 0, localeValue = 0, dwFmt = 0; + LPCWSTR szPrintFmt = NULL; + WCHAR defaultChar = '?'; + + if (pToken - rgbTok > header->size) + { + ERR("Ran off the end of the format!\n"); + hRes = E_INVALIDARG; + goto VARIANT_FormatDate_Exit; + } + + switch (*pToken) + { + case FMT_GEN_COPY: + TRACE("copy %s\n", debugstr_wn(lpszFormat + pToken[1], pToken[2])); + memcpy(pBuff, lpszFormat + pToken[1], pToken[2] * sizeof(WCHAR)); + pBuff += pToken[2]; + pToken += 2; + break; + + case FMT_DATE_TIME_SEP: + TRACE("time separator\n"); + localeValue = LOCALE_STIME; + defaultChar = ':'; + break; + + case FMT_DATE_DATE_SEP: + TRACE("date separator\n"); + localeValue = LOCALE_SDATE; + defaultChar = '/'; + break; + + case FMT_DATE_GENERAL: + { + BSTR date = NULL; + WCHAR *pDate = date; + hRes = VarBstrFromDate(V_DATE(&vDate), lcid, 0, pbstrOut); + if (FAILED(hRes)) + goto VARIANT_FormatDate_Exit; + while (*pDate) + *pBuff++ = *pDate++; + SysFreeString(date); + } + break; + + case FMT_DATE_QUARTER: + if (udate.st.wMonth <= 3) + *pBuff++ = '1'; + else if (udate.st.wMonth <= 6) + *pBuff++ = '2'; + else if (udate.st.wMonth <= 9) + *pBuff++ = '3'; + else + *pBuff++ = '4'; + break; + + case FMT_DATE_TIME_SYS: + { + /* FIXME: VARIANT_CALENDAR HIJRI should cause Hijri output */ + BSTR date = NULL; + WCHAR *pDate = date; + hRes = VarBstrFromDate(V_DATE(&vDate), lcid, VAR_TIMEVALUEONLY, pbstrOut); + if (FAILED(hRes)) + goto VARIANT_FormatDate_Exit; + while (*pDate) + *pBuff++ = *pDate++; + SysFreeString(date); + } + break; + + case FMT_DATE_DAY: + szPrintFmt = szPercent_d; + dwVal = udate.st.wDay; + break; + + case FMT_DATE_DAY_0: + szPrintFmt = szPercentZeroTwo_d; + dwVal = udate.st.wDay; + break; + + case FMT_DATE_DAY_SHORT: + /* FIXME: VARIANT_CALENDAR HIJRI should cause Hijri output */ + TRACE("short day\n"); + localeValue = LOCALE_SABBREVDAYNAME1 + udate.st.wMonth - 1; + defaultChar = '?'; + break; + + case FMT_DATE_DAY_LONG: + /* FIXME: VARIANT_CALENDAR HIJRI should cause Hijri output */ + TRACE("long day\n"); + localeValue = LOCALE_SDAYNAME1 + udate.st.wMonth - 1; + defaultChar = '?'; + break; + + case FMT_DATE_SHORT: + /* FIXME: VARIANT_CALENDAR HIJRI should cause Hijri output */ + dwFmt = LOCALE_SSHORTDATE; + break; + + case FMT_DATE_LONG: + /* FIXME: VARIANT_CALENDAR HIJRI should cause Hijri output */ + dwFmt = LOCALE_SLONGDATE; + break; + + case FMT_DATE_MEDIUM: + FIXME("Medium date treated as long date\n"); + dwFmt = LOCALE_SLONGDATE; + break; + + case FMT_DATE_DAY_WEEK: + szPrintFmt = szPercent_d; + if (pToken[1]) + dwVal = udate.st.wDayOfWeek + 2 - pToken[1]; + else + { + GetLocaleInfoW(lcid,LOCALE_RETURN_NUMBER|LOCALE_IFIRSTDAYOFWEEK, + (LPWSTR)&dwVal, sizeof(dwVal)/sizeof(WCHAR)); + dwVal = udate.st.wDayOfWeek + 1 - dwVal; + } + pToken++; + break; + + case FMT_DATE_WEEK_YEAR: + szPrintFmt = szPercent_d; + dwVal = udate.wDayOfYear / 7 + 1; + pToken += 2; + FIXME("Ignoring nFirstDay of %d, nFirstWeek of %d\n", pToken[0], pToken[1]); + break; + + case FMT_DATE_MON: + szPrintFmt = szPercent_d; + dwVal = udate.st.wMonth; + break; + + case FMT_DATE_MON_0: + szPrintFmt = szPercentZeroTwo_d; + dwVal = udate.st.wMonth; + break; + + case FMT_DATE_MON_SHORT: + /* FIXME: VARIANT_CALENDAR HIJRI should cause Hijri output */ + TRACE("short month\n"); + localeValue = LOCALE_SABBREVMONTHNAME1 + udate.st.wMonth - 1; + defaultChar = '?'; + break; + + case FMT_DATE_MON_LONG: + /* FIXME: VARIANT_CALENDAR HIJRI should cause Hijri output */ + TRACE("long month\n"); + localeValue = LOCALE_SMONTHNAME1 + udate.st.wMonth - 1; + defaultChar = '?'; + break; + + case FMT_DATE_YEAR_DOY: + szPrintFmt = szPercent_d; + dwVal = udate.wDayOfYear; + break; + + case FMT_DATE_YEAR_0: + szPrintFmt = szPercentZeroTwo_d; + dwVal = udate.st.wYear % 100; + break; + + case FMT_DATE_YEAR_LONG: + szPrintFmt = szPercent_d; + dwVal = udate.st.wYear; + break; + + case FMT_DATE_MIN: + szPrintFmt = szPercent_d; + dwVal = udate.st.wMinute; + break; + + case FMT_DATE_MIN_0: + szPrintFmt = szPercentZeroTwo_d; + dwVal = udate.st.wMinute; + break; + + case FMT_DATE_SEC: + szPrintFmt = szPercent_d; + dwVal = udate.st.wSecond; + break; + + case FMT_DATE_SEC_0: + szPrintFmt = szPercentZeroTwo_d; + dwVal = udate.st.wSecond; + break; + + case FMT_DATE_HOUR: + szPrintFmt = szPercent_d; + dwVal = udate.st.wHour; + break; + + case FMT_DATE_HOUR_0: + szPrintFmt = szPercentZeroTwo_d; + dwVal = udate.st.wHour; + break; + + case FMT_DATE_HOUR_12: + szPrintFmt = szPercent_d; + dwVal = udate.st.wHour ? udate.st.wHour > 12 ? udate.st.wHour - 12 : udate.st.wHour : 12; + break; + + case FMT_DATE_HOUR_12_0: + szPrintFmt = szPercentZeroTwo_d; + dwVal = udate.st.wHour ? udate.st.wHour > 12 ? udate.st.wHour - 12 : udate.st.wHour : 12; + break; + + case FMT_DATE_AMPM_SYS1: + case FMT_DATE_AMPM_SYS2: + localeValue = udate.st.wHour < 12 ? LOCALE_S1159 : LOCALE_S2359; + defaultChar = '?'; + break; + + case FMT_DATE_AMPM_UPPER: + *pBuff++ = udate.st.wHour < 12 ? 'A' : 'P'; + *pBuff++ = 'M'; + break; + + case FMT_DATE_A_UPPER: + *pBuff++ = udate.st.wHour < 12 ? 'A' : 'P'; + break; + + case FMT_DATE_AMPM_LOWER: + *pBuff++ = udate.st.wHour < 12 ? 'a' : 'p'; + *pBuff++ = 'm'; + break; + + case FMT_DATE_A_LOWER: + *pBuff++ = udate.st.wHour < 12 ? 'a' : 'p'; + break; + + default: + ERR("Unknown token 0x%02x!\n", *pToken); + hRes = E_INVALIDARG; + goto VARIANT_FormatDate_Exit; + break; + } + if (localeValue) + { + *pBuff = '\0'; + if (GetLocaleInfoW(lcid, localeValue, pBuff, + sizeof(buff)/sizeof(WCHAR)-(pBuff-buff))) + { + TRACE("added %s\n", debugstr_w(pBuff)); + while (*pBuff) + pBuff++; + } + else + { + TRACE("added %d %c\n", defaultChar, defaultChar); + *pBuff++ = defaultChar; + } + } + else if (dwFmt) + { + WCHAR fmt_buff[80]; + + if (!GetLocaleInfoW(lcid, dwFmt, fmt_buff, sizeof(fmt_buff)/sizeof(WCHAR)) || + !GetDateFormatW(lcid, 0, &udate.st, fmt_buff, pBuff, + sizeof(buff)/sizeof(WCHAR)-(pBuff-buff))) + { + hRes = E_INVALIDARG; + goto VARIANT_FormatDate_Exit; + } + while (*pBuff) + pBuff++; + } + else if (szPrintFmt) + { + sprintfW(pBuff, szPrintFmt, dwVal); + while (*pBuff) + pBuff++; + } + pToken++; + } + +VARIANT_FormatDate_Exit: + *pBuff = '\0'; + TRACE("buff is %s\n", debugstr_w(buff)); + if (SUCCEEDED(hRes)) + { + *pbstrOut = SysAllocString(buff); + if (!*pbstrOut) + hRes = E_OUTOFMEMORY; + } + return hRes; +} + +/* Format a variant using a string format */ +static HRESULT VARIANT_FormatString(LPVARIANT pVarIn, LPOLESTR lpszFormat, + LPBYTE rgbTok, ULONG dwFlags, + BSTR *pbstrOut, LCID lcid) +{ + static const WCHAR szEmpty[] = { '\0' }; + WCHAR buff[256], *pBuff = buff; + WCHAR *pSrc; + FMT_HEADER *header = (FMT_HEADER*)rgbTok; + FMT_STRING_HEADER *strHeader; + const BYTE* pToken = NULL; + VARIANT vStr; + int blanks_first; + BOOL bUpper = FALSE; + HRESULT hRes = S_OK; + + TRACE("(%p->(%s%s),%s,%p,0x%08lx,%p,0x%08lx)\n", pVarIn, debugstr_VT(pVarIn), + debugstr_VF(pVarIn), debugstr_w(lpszFormat), rgbTok, dwFlags, pbstrOut, + lcid); + + V_VT(&vStr) = VT_EMPTY; + + if (V_TYPE(pVarIn) == VT_EMPTY || V_TYPE(pVarIn) == VT_NULL) + { + strHeader = (FMT_STRING_HEADER*)(rgbTok + FmtGetNegative(header)); + V_BSTR(&vStr) = (WCHAR*)szEmpty; + } + else + { + hRes = VariantChangeTypeEx(&vStr, pVarIn, LCID_US, VARIANT_NOUSEROVERRIDE, VT_BSTR); + if (FAILED(hRes)) + return hRes; + + if (V_BSTR(pVarIn)[0] == '\0') + strHeader = (FMT_STRING_HEADER*)(rgbTok + FmtGetNegative(header)); + else + strHeader = (FMT_STRING_HEADER*)(rgbTok + FmtGetPositive(header)); + } + pSrc = V_BSTR(&vStr); + if ((strHeader->flags & (FMT_FLAG_LT|FMT_FLAG_GT)) == FMT_FLAG_GT) + bUpper = TRUE; + blanks_first = strHeader->copy_chars - strlenW(pSrc); + pToken = (const BYTE*)strHeader + sizeof(FMT_DATE_HEADER); + + while (*pToken != FMT_GEN_END) + { + int dwCount = 0; + + if (pToken - rgbTok > header->size) + { + ERR("Ran off the end of the format!\n"); + hRes = E_INVALIDARG; + goto VARIANT_FormatString_Exit; + } + + switch (*pToken) + { + case FMT_GEN_COPY: + TRACE("copy %s\n", debugstr_wn(lpszFormat + pToken[1], pToken[2])); + memcpy(pBuff, lpszFormat + pToken[1], pToken[2] * sizeof(WCHAR)); + pBuff += pToken[2]; + pToken += 2; + break; + + case FMT_STR_COPY_SPACE: + case FMT_STR_COPY_SKIP: + dwCount = pToken[1]; + if (*pToken == FMT_STR_COPY_SPACE && blanks_first > 0) + { + TRACE("insert %d initial spaces\n", blanks_first); + while (dwCount > 0 && blanks_first > 0) + { + *pBuff++ = ' '; + dwCount--; + blanks_first--; + } + } + TRACE("copy %d chars%s\n", dwCount, + *pToken == FMT_STR_COPY_SPACE ? " with space" :""); + while (dwCount > 0 && *pSrc) + { + if (bUpper) + *pBuff++ = toupperW(*pSrc); + else + *pBuff++ = tolowerW(*pSrc); + dwCount--; + pSrc++; + } + if (*pToken == FMT_STR_COPY_SPACE && dwCount > 0) + { + TRACE("insert %d spaces\n", dwCount); + while (dwCount-- > 0) + *pBuff++ = ' '; + } + pToken++; + break; + + default: + ERR("Unknown token 0x%02x!\n", *pToken); + hRes = E_INVALIDARG; + goto VARIANT_FormatString_Exit; + break; + } + pToken++; + } + +VARIANT_FormatString_Exit: + /* Copy out any remaining chars */ + while (*pSrc) + { + if (bUpper) + *pBuff++ = toupperW(*pSrc); + else + *pBuff++ = tolowerW(*pSrc); + pSrc++; + } + VariantClear(&vStr); + *pBuff = '\0'; + TRACE("buff is %s\n", debugstr_w(buff)); + if (SUCCEEDED(hRes)) + { + *pbstrOut = SysAllocString(buff); + if (!*pbstrOut) + hRes = E_OUTOFMEMORY; + } + return hRes; +} + +#define NUMBER_VTBITS (VTBIT_I1|VTBIT_UI1|VTBIT_I2|VTBIT_UI2| \ + VTBIT_I4|VTBIT_UI4|VTBIT_I8|VTBIT_UI8| \ + VTBIT_R4|VTBIT_R8|VTBIT_CY|VTBIT_DECIMAL| \ + (1<type == FMT_TYPE_GENERAL) + { + /* According to MSDN, general format acts somewhat like the 'Str' + * function in Visual Basic. + */ +VarFormatFromTokens_AsStr: + V_VT(&vTmp) = VT_EMPTY; + hres = VariantChangeTypeEx(&vTmp, pVarIn, lcid, dwFlags, VT_BSTR); + *pbstrOut = V_BSTR(&vTmp); + } + else + { + if (header->type == FMT_TYPE_NUMBER || + (header->type == FMT_TYPE_UNKNOWN && ((1 << V_TYPE(pVarIn)) & NUMBER_VTBITS))) + { + hres = VARIANT_FormatNumber(pVarIn, lpszFormat, rgbTok, dwFlags, pbstrOut, lcid); + } + else if (header->type == FMT_TYPE_DATE || + (header->type == FMT_TYPE_UNKNOWN && V_TYPE(pVarIn) == VT_DATE)) + { + hres = VARIANT_FormatDate(pVarIn, lpszFormat, rgbTok, dwFlags, pbstrOut, lcid); + } + else if (header->type == FMT_TYPE_STRING || V_TYPE(pVarIn) == VT_BSTR) + { + hres = VARIANT_FormatString(pVarIn, lpszFormat, rgbTok, dwFlags, pbstrOut, lcid); + } + else + { + ERR("unrecognised format type 0x%02x\n", header->type); + return E_INVALIDARG; + } + /* If the coercion failed, still try to create output, unless the + * VAR_FORMAT_NOSUBSTITUTE flag is set. + */ + if ((hres == DISP_E_OVERFLOW || hres == DISP_E_TYPEMISMATCH) && + !(dwFlags & VAR_FORMAT_NOSUBSTITUTE)) + goto VarFormatFromTokens_AsStr; + } + + return hres; +} + +/********************************************************************** + * VarFormat [OLEAUT32.87] + * + * Format a variant from a format string. + * + * PARAMS + * pVarIn [I] Variant to format + * lpszFormat [I] Format string (see notes) + * nFirstDay [I] First day of the week, (See VarTokenizeFormatString() for details) + * nFirstWeek [I] First week of the year (See VarTokenizeFormatString() for details) + * dwFlags [I] Flags for the format (VAR_ flags from "oleauto.h") + * pbstrOut [O] Destination for formatted string. + * + * RETURNS + * Success: S_OK. pbstrOut contains the formatted value. + * Failure: E_INVALIDARG, if any parameter is invalid. + * E_OUTOFMEMORY, if enough memory cannot be allocated. + * DISP_E_TYPEMISMATCH, if the variant cannot be formatted. + * + * NOTES + * - See Variant-Formats for details concerning creating format strings. + * - This function uses LOCALE_USER_DEFAULT when calling VarTokenizeFormatString() + * and VarFormatFromTokens(). + */ +HRESULT WINAPI VarFormat(LPVARIANT pVarIn, LPOLESTR lpszFormat, + int nFirstDay, int nFirstWeek, ULONG dwFlags, + BSTR *pbstrOut) +{ + BYTE buff[256]; + HRESULT hres; + + TRACE("(%p->(%s%s),%s,%d,%d,0x%08lx,%p)\n", pVarIn, debugstr_VT(pVarIn), + debugstr_VF(pVarIn), debugstr_w(lpszFormat), nFirstDay, nFirstWeek, + dwFlags, pbstrOut); + + if (!pbstrOut) + return E_INVALIDARG; + *pbstrOut = NULL; + + hres = VarTokenizeFormatString(lpszFormat, buff, sizeof(buff), nFirstDay, + nFirstWeek, LOCALE_USER_DEFAULT, NULL); + if (SUCCEEDED(hres)) + hres = VarFormatFromTokens(pVarIn, lpszFormat, buff, dwFlags, + pbstrOut, LOCALE_USER_DEFAULT); + TRACE("returning 0x%08lx, %s\n", hres, debugstr_w(*pbstrOut)); + return hres; +} + +/********************************************************************** + * VarFormatDateTime [OLEAUT32.97] + * + * Format a variant value as a date and/or time. + * + * PARAMS + * pVarIn [I] Variant to format + * nFormat [I] Format type (see notes) + * dwFlags [I] Flags for the format (VAR_ flags from "oleauto.h") + * pbstrOut [O] Destination for formatted string. + * + * RETURNS + * Success: S_OK. pbstrOut contains the formatted value. + * Failure: E_INVALIDARG, if any parameter is invalid. + * E_OUTOFMEMORY, if enough memory cannot be allocated. + * DISP_E_TYPEMISMATCH, if the variant cannot be formatted. + * + * NOTES + * This function uses LOCALE_USER_DEFAULT when determining the date format + * characters to use. + * Possible values for the nFormat parameter are: + *| Value Meaning + *| ----- ------- + *| 0 General date format + *| 1 Long date format + *| 2 Short date format + *| 3 Long time format + *| 4 Short time format + */ +HRESULT WINAPI VarFormatDateTime(LPVARIANT pVarIn, INT nFormat, ULONG dwFlags, BSTR *pbstrOut) +{ + static const WCHAR szEmpty[] = { '\0' }; + const BYTE* lpFmt = NULL; + + TRACE("(%p->(%s%s),%d,0x%08lx,%p)\n", pVarIn, debugstr_VT(pVarIn), + debugstr_VF(pVarIn), nFormat, dwFlags, pbstrOut); + + if (!pVarIn || !pbstrOut || nFormat < 0 || nFormat > 4) + return E_INVALIDARG; + + switch (nFormat) + { + case 0: lpFmt = fmtGeneralDate; break; + case 1: lpFmt = fmtLongDate; break; + case 2: lpFmt = fmtShortDate; break; + case 3: lpFmt = fmtLongTime; break; + case 4: lpFmt = fmtShortTime; break; + } + return VarFormatFromTokens(pVarIn, (LPWSTR)szEmpty, (BYTE*)lpFmt, dwFlags, + pbstrOut, LOCALE_USER_DEFAULT); +} + +#define GETLOCALENUMBER(type,field) GetLocaleInfoW(LOCALE_USER_DEFAULT, \ + type|LOCALE_RETURN_NUMBER, \ + (LPWSTR)&numfmt.field, \ + sizeof(numfmt.field)/sizeof(WCHAR)) + +/********************************************************************** + * VarFormatNumber [OLEAUT32.107] + * + * Format a variant value as a number. + * + * PARAMS + * pVarIn [I] Variant to format + * nDigits [I] Number of digits following the decimal point (-1 = user default) + * nLeading [I] Use a leading zero (-2 = user default, -1 = yes, 0 = no) + * nParens [I] Use brackets for values < 0 (-2 = user default, -1 = yes, 0 = no) + * nGrouping [I] Use grouping characters (-2 = user default, -1 = yes, 0 = no) + * dwFlags [I] Currently unused, set to zero + * pbstrOut [O] Destination for formatted string. + * + * RETURNS + * Success: S_OK. pbstrOut contains the formatted value. + * Failure: E_INVALIDARG, if any parameter is invalid. + * E_OUTOFMEMORY, if enough memory cannot be allocated. + * DISP_E_TYPEMISMATCH, if the variant cannot be formatted. + * + * NOTES + * This function uses LOCALE_USER_DEFAULT when determining the number format + * characters to use. + */ +HRESULT WINAPI VarFormatNumber(LPVARIANT pVarIn, INT nDigits, INT nLeading, INT nParens, + INT nGrouping, ULONG dwFlags, BSTR *pbstrOut) +{ + HRESULT hRet; + VARIANT vStr; + + TRACE("(%p->(%s%s),%d,%d,%d,%d,0x%08lx,%p)\n", pVarIn, debugstr_VT(pVarIn), + debugstr_VF(pVarIn), nDigits, nLeading, nParens, nGrouping, dwFlags, pbstrOut); + + if (!pVarIn || !pbstrOut || nDigits > 9) + return E_INVALIDARG; + + *pbstrOut = NULL; + + V_VT(&vStr) = VT_EMPTY; + hRet = VariantCopyInd(&vStr, pVarIn); + + if (SUCCEEDED(hRet)) + hRet = VariantChangeTypeEx(&vStr, &vStr, LOCALE_USER_DEFAULT, 0, VT_BSTR); + + if (SUCCEEDED(hRet)) + { + WCHAR buff[256], decimal[8], thousands[8]; + NUMBERFMTW numfmt; + + /* Although MSDN makes it clear that the native versions of these functions + * are implemented using VarTokenizeFormatString()/VarFormatFromTokens(), + * using NLS gives us the same result. + */ + if (nDigits < 0) + GETLOCALENUMBER(LOCALE_IDIGITS, NumDigits); + else + numfmt.NumDigits = nDigits; + + if (nLeading == -2) + GETLOCALENUMBER(LOCALE_ILZERO, LeadingZero); + else if (nLeading == -1) + numfmt.LeadingZero = 1; + else + numfmt.LeadingZero = 0; + + if (nGrouping == -2) + { + WCHAR grouping[16]; + grouping[2] = '\0'; + GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, grouping, + sizeof(grouping)/sizeof(WCHAR)); + numfmt.Grouping = grouping[2] == '2' ? 32 : grouping[0] - '0'; + } + else if (nGrouping == -1) + numfmt.Grouping = 3; /* 3 = "n,nnn.nn" */ + else + numfmt.Grouping = 0; /* 0 = No grouping */ + + if (nParens == -2) + GETLOCALENUMBER(LOCALE_INEGNUMBER, NegativeOrder); + else if (nParens == -1) + numfmt.NegativeOrder = 0; /* 0 = "(xxx)" */ + else + numfmt.NegativeOrder = 1; /* 1 = "-xxx" */ + + numfmt.lpDecimalSep = decimal; + GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, decimal, + sizeof(decimal)/sizeof(WCHAR)); + numfmt.lpThousandSep = thousands; + GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, thousands, + sizeof(thousands)/sizeof(WCHAR)); + + if (GetNumberFormatW(LOCALE_USER_DEFAULT, 0, V_BSTR(&vStr), &numfmt, + buff, sizeof(buff)/sizeof(WCHAR))) + { + *pbstrOut = SysAllocString(buff); + if (!*pbstrOut) + hRet = E_OUTOFMEMORY; + } + else + hRet = DISP_E_TYPEMISMATCH; + + SysFreeString(V_BSTR(&vStr)); + } + return hRet; +} + +/********************************************************************** + * VarFormatPercent [OLEAUT32.117] + * + * Format a variant value as a percentage. + * + * PARAMS + * pVarIn [I] Variant to format + * nDigits [I] Number of digits following the decimal point (-1 = user default) + * nLeading [I] Use a leading zero (-2 = user default, -1 = yes, 0 = no) + * nParens [I] Use brackets for values < 0 (-2 = user default, -1 = yes, 0 = no) + * nGrouping [I] Use grouping characters (-2 = user default, -1 = yes, 0 = no) + * dwFlags [I] Currently unused, set to zero + * pbstrOut [O] Destination for formatted string. + * + * RETURNS + * Success: S_OK. pbstrOut contains the formatted value. + * Failure: E_INVALIDARG, if any parameter is invalid. + * E_OUTOFMEMORY, if enough memory cannot be allocated. + * DISP_E_OVERFLOW, if overflow occurs during the conversion. + * DISP_E_TYPEMISMATCH, if the variant cannot be formatted. + * + * NOTES + * This function uses LOCALE_USER_DEFAULT when determining the number format + * characters to use. + */ +HRESULT WINAPI VarFormatPercent(LPVARIANT pVarIn, INT nDigits, INT nLeading, INT nParens, + INT nGrouping, ULONG dwFlags, BSTR *pbstrOut) +{ + static const WCHAR szPercent[] = { '%','\0' }; + static const WCHAR szPercentBracket[] = { '%',')','\0' }; + WCHAR buff[256]; + HRESULT hRet; + VARIANT vDbl; + + TRACE("(%p->(%s%s),%d,%d,%d,%d,0x%08lx,%p)\n", pVarIn, debugstr_VT(pVarIn), + debugstr_VF(pVarIn), nDigits, nLeading, nParens, nGrouping, + dwFlags, pbstrOut); + + if (!pVarIn || !pbstrOut || nDigits > 9) + return E_INVALIDARG; + + *pbstrOut = NULL; + + V_VT(&vDbl) = VT_EMPTY; + hRet = VariantCopyInd(&vDbl, pVarIn); + + if (SUCCEEDED(hRet)) + { + hRet = VariantChangeTypeEx(&vDbl, &vDbl, LOCALE_USER_DEFAULT, 0, VT_R8); + + if (SUCCEEDED(hRet)) + { + if (V_R8(&vDbl) > (R8_MAX / 100.0)) + return DISP_E_OVERFLOW; + + V_R8(&vDbl) *= 100.0; + hRet = VarFormatNumber(&vDbl, nDigits, nLeading, nParens, + nGrouping, dwFlags, pbstrOut); + + if (SUCCEEDED(hRet)) + { + DWORD dwLen = strlenW(*pbstrOut); + BOOL bBracket = (*pbstrOut)[dwLen] == ')' ? TRUE : FALSE; + + dwLen -= bBracket; + memcpy(buff, *pbstrOut, dwLen * sizeof(WCHAR)); + strcpyW(buff + dwLen, bBracket ? szPercentBracket : szPercent); + SysFreeString(*pbstrOut); + *pbstrOut = SysAllocString(buff); + if (!*pbstrOut) + hRet = E_OUTOFMEMORY; + } + } + } + return hRet; +} + +/********************************************************************** + * VarFormatCurrency [OLEAUT32.127] + * + * Format a variant value as a currency. + * + * PARAMS + * pVarIn [I] Variant to format + * nDigits [I] Number of digits following the decimal point (-1 = user default) + * nLeading [I] Use a leading zero (-2 = user default, -1 = yes, 0 = no) + * nParens [I] Use brackets for values < 0 (-2 = user default, -1 = yes, 0 = no) + * nGrouping [I] Use grouping characters (-2 = user default, -1 = yes, 0 = no) + * dwFlags [I] Currently unused, set to zero + * pbstrOut [O] Destination for formatted string. + * + * RETURNS + * Success: S_OK. pbstrOut contains the formatted value. + * Failure: E_INVALIDARG, if any parameter is invalid. + * E_OUTOFMEMORY, if enough memory cannot be allocated. + * DISP_E_TYPEMISMATCH, if the variant cannot be formatted. + * + * NOTES + * This function uses LOCALE_USER_DEFAULT when determining the currency format + * characters to use. + */ +HRESULT WINAPI VarFormatCurrency(LPVARIANT pVarIn, INT nDigits, INT nLeading, + INT nParens, INT nGrouping, ULONG dwFlags, + BSTR *pbstrOut) +{ + HRESULT hRet; + VARIANT vStr; + + TRACE("(%p->(%s%s),%d,%d,%d,%d,0x%08lx,%p)\n", pVarIn, debugstr_VT(pVarIn), + debugstr_VF(pVarIn), nDigits, nLeading, nParens, nGrouping, dwFlags, pbstrOut); + + if (!pVarIn || !pbstrOut || nDigits > 9) + return E_INVALIDARG; + + *pbstrOut = NULL; + + V_VT(&vStr) = VT_EMPTY; + hRet = VariantCopyInd(&vStr, pVarIn); + + if (SUCCEEDED(hRet)) + hRet = VariantChangeTypeEx(&vStr, &vStr, LOCALE_USER_DEFAULT, 0, VT_BSTR); + + if (SUCCEEDED(hRet)) + { + WCHAR buff[256], decimal[8], thousands[8], currency[8]; + CURRENCYFMTW numfmt; + + if (nDigits < 0) + GETLOCALENUMBER(LOCALE_IDIGITS, NumDigits); + else + numfmt.NumDigits = nDigits; + + if (nLeading == -2) + GETLOCALENUMBER(LOCALE_ILZERO, LeadingZero); + else if (nLeading == -1) + numfmt.LeadingZero = 1; + else + numfmt.LeadingZero = 0; + + if (nGrouping == -2) + { + WCHAR nGrouping[16]; + nGrouping[2] = '\0'; + GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, nGrouping, + sizeof(nGrouping)/sizeof(WCHAR)); + numfmt.Grouping = nGrouping[2] == '2' ? 32 : nGrouping[0] - '0'; + } + else if (nGrouping == -1) + numfmt.Grouping = 3; /* 3 = "n,nnn.nn" */ + else + numfmt.Grouping = 0; /* 0 = No grouping */ + + if (nParens == -2) + GETLOCALENUMBER(LOCALE_INEGCURR, NegativeOrder); + else if (nParens == -1) + numfmt.NegativeOrder = 0; /* 0 = "(xxx)" */ + else + numfmt.NegativeOrder = 1; /* 1 = "-xxx" */ + + GETLOCALENUMBER(LOCALE_ICURRENCY, PositiveOrder); + + numfmt.lpDecimalSep = decimal; + GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, decimal, + sizeof(decimal)/sizeof(WCHAR)); + numfmt.lpThousandSep = thousands; + GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, thousands, + sizeof(thousands)/sizeof(WCHAR)); + numfmt.lpCurrencySymbol = currency; + GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, currency, + sizeof(currency)/sizeof(WCHAR)); + + /* use NLS as per VarFormatNumber() */ + if (GetCurrencyFormatW(LOCALE_USER_DEFAULT, 0, V_BSTR(&vStr), &numfmt, + buff, sizeof(buff)/sizeof(WCHAR))) + { + *pbstrOut = SysAllocString(buff); + if (!*pbstrOut) + hRet = E_OUTOFMEMORY; + } + else + hRet = DISP_E_TYPEMISMATCH; + + SysFreeString(V_BSTR(&vStr)); + } + return hRet; +} diff --git a/reactos/lib/oleaut32/variant.c b/reactos/lib/oleaut32/variant.c new file mode 100644 index 00000000000..3ace2b7bdf7 --- /dev/null +++ b/reactos/lib/oleaut32/variant.c @@ -0,0 +1,4401 @@ +/* + * VARIANT + * + * Copyright 1998 Jean-Claude Cote + * Copyright 2003 Jon Griffiths + * The alorithm for conversion from Julian days to day/month/year is based on + * that devised by Henry Fliegel, as implemented in PostgreSQL, which is + * Copyright 1994-7 Regents of the University of California + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "config.h" + +#include +#include +#include + +#define COBJMACROS +#define NONAMELESSUNION +#define NONAMELESSSTRUCT + +#include "windef.h" +#include "winbase.h" +#include "wine/unicode.h" +#include "winerror.h" +#include "variant.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(variant); + +const char* wine_vtypes[VT_CLSID] = +{ + "VT_EMPTY","VT_NULL","VT_I2","VT_I4","VT_R4","VT_R8","VT_CY","VT_DATE", + "VT_BSTR","VT_DISPATCH","VT_ERROR","VT_BOOL","VT_VARIANT","VT_UNKNOWN", + "VT_DECIMAL","15","VT_I1","VT_UI1","VT_UI2","VT_UI4","VT_I8","VT_UI8", + "VT_INT","VT_UINT","VT_VOID","VT_HRESULT","VT_PTR","VT_SAFEARRAY", + "VT_CARRAY","VT_USERDEFINED","VT_LPSTR","VT_LPWSTR""32","33","34","35", + "VT_RECORD","VT_INT_PTR","VT_UINT_PTR","39","40","41","42","43","44","45", + "46","47","48","49","50","51","52","53","54","55","56","57","58","59","60", + "61","62","63","VT_FILETIME","VT_BLOB","VT_STREAM","VT_STORAGE", + "VT_STREAMED_OBJECT","VT_STORED_OBJECT","VT_BLOB_OBJECT","VT_CF","VT_CLSID" +}; + +const char* wine_vflags[16] = +{ + "", + "|VT_VECTOR", + "|VT_ARRAY", + "|VT_VECTOR|VT_ARRAY", + "|VT_BYREF", + "|VT_VECTOR|VT_ARRAY", + "|VT_ARRAY|VT_BYREF", + "|VT_VECTOR|VT_ARRAY|VT_BYREF", + "|VT_HARDTYPE", + "|VT_VECTOR|VT_HARDTYPE", + "|VT_ARRAY|VT_HARDTYPE", + "|VT_VECTOR|VT_ARRAY|VT_HARDTYPE", + "|VT_BYREF|VT_HARDTYPE", + "|VT_VECTOR|VT_ARRAY|VT_HARDTYPE", + "|VT_ARRAY|VT_BYREF|VT_HARDTYPE", + "|VT_VECTOR|VT_ARRAY|VT_BYREF|VT_HARDTYPE", +}; + +/* Convert a variant from one type to another */ +static inline HRESULT VARIANT_Coerce(VARIANTARG* pd, LCID lcid, USHORT wFlags, + VARIANTARG* ps, VARTYPE vt) +{ + HRESULT res = DISP_E_TYPEMISMATCH; + VARTYPE vtFrom = V_TYPE(ps); + BOOL bIgnoreOverflow = FALSE; + DWORD dwFlags = 0; + + TRACE("(%p->(%s%s),0x%08lx,0x%04x,%p->(%s%s),%s%s)\n", pd, debugstr_VT(pd), + debugstr_VF(pd), lcid, wFlags, ps, debugstr_VT(ps), debugstr_VF(ps), + debugstr_vt(vt), debugstr_vf(vt)); + + if (vt == VT_BSTR || vtFrom == VT_BSTR) + { + /* All flags passed to low level function are only used for + * changing to or from strings. Map these here. + */ + if (wFlags & VARIANT_LOCALBOOL) + dwFlags |= VAR_LOCALBOOL; + if (wFlags & VARIANT_CALENDAR_HIJRI) + dwFlags |= VAR_CALENDAR_HIJRI; + if (wFlags & VARIANT_CALENDAR_THAI) + dwFlags |= VAR_CALENDAR_THAI; + if (wFlags & VARIANT_CALENDAR_GREGORIAN) + dwFlags |= VAR_CALENDAR_GREGORIAN; + if (wFlags & VARIANT_NOUSEROVERRIDE) + dwFlags |= LOCALE_NOUSEROVERRIDE; + if (wFlags & VARIANT_USE_NLS) + dwFlags |= LOCALE_USE_NLS; + } + + /* Map int/uint to i4/ui4 */ + if (vt == VT_INT) + vt = VT_I4; + else if (vt == VT_UINT) + vt = VT_UI4; + + if (vtFrom == VT_INT) + vtFrom = VT_I4; + else if (vtFrom == VT_UINT) + { + vtFrom = VT_UI4; + if (vt == VT_I4) + bIgnoreOverflow = TRUE; + } + + if (vt == vtFrom) + return VariantCopy(pd, ps); + + if (wFlags & VARIANT_NOVALUEPROP && vtFrom == VT_DISPATCH && vt != VT_UNKNOWN) + { + /* VARIANT_NOVALUEPROP prevents IDispatch objects from being coerced by + * accessing the default object property. + */ + return DISP_E_TYPEMISMATCH; + } + + switch (vt) + { + case VT_EMPTY: + if (vtFrom == VT_NULL) + return DISP_E_TYPEMISMATCH; + /* ... Fall through */ + case VT_NULL: + if (vtFrom <= VT_UINT && vtFrom != (VARTYPE)15 && vtFrom != VT_ERROR) + { + res = VariantClear( pd ); + if (vt == VT_NULL && SUCCEEDED(res)) + V_VT(pd) = VT_NULL; + } + return res; + + case VT_I1: + switch (vtFrom) + { + case VT_EMPTY: V_I1(pd) = 0; return S_OK; + case VT_I2: return VarI1FromI2(V_I2(ps), &V_I1(pd)); + case VT_I4: return VarI1FromI4(V_I4(ps), &V_I1(pd)); + case VT_UI1: return VarI1FromUI1(V_UI1(ps), &V_I1(pd)); + case VT_UI2: return VarI1FromUI2(V_UI2(ps), &V_I1(pd)); + case VT_UI4: return VarI1FromUI4(V_UI4(ps), &V_I1(pd)); + case VT_I8: return VarI1FromI8(V_I8(ps), &V_I1(pd)); + case VT_UI8: return VarI1FromUI8(V_UI8(ps), &V_I1(pd)); + case VT_R4: return VarI1FromR4(V_R4(ps), &V_I1(pd)); + case VT_R8: return VarI1FromR8(V_R8(ps), &V_I1(pd)); + case VT_DATE: return VarI1FromDate(V_DATE(ps), &V_I1(pd)); + case VT_BOOL: return VarI1FromBool(V_BOOL(ps), &V_I1(pd)); + case VT_CY: return VarI1FromCy(V_CY(ps), &V_I1(pd)); + case VT_DECIMAL: return VarI1FromDec(&V_DECIMAL(ps), &V_I1(pd) ); + case VT_DISPATCH: return VarI1FromDisp(V_DISPATCH(ps), lcid, &V_I1(pd) ); + case VT_BSTR: return VarI1FromStr(V_BSTR(ps), lcid, dwFlags, &V_I1(pd) ); + } + break; + + case VT_I2: + switch (vtFrom) + { + case VT_EMPTY: V_I2(pd) = 0; return S_OK; + case VT_I1: return VarI2FromI1(V_I1(ps), &V_I2(pd)); + case VT_I4: return VarI2FromI4(V_I4(ps), &V_I2(pd)); + case VT_UI1: return VarI2FromUI1(V_UI1(ps), &V_I2(pd)); + case VT_UI2: return VarI2FromUI2(V_UI2(ps), &V_I2(pd)); + case VT_UI4: return VarI2FromUI4(V_UI4(ps), &V_I2(pd)); + case VT_I8: return VarI2FromI8(V_I8(ps), &V_I2(pd)); + case VT_UI8: return VarI2FromUI8(V_UI8(ps), &V_I2(pd)); + case VT_R4: return VarI2FromR4(V_R4(ps), &V_I2(pd)); + case VT_R8: return VarI2FromR8(V_R8(ps), &V_I2(pd)); + case VT_DATE: return VarI2FromDate(V_DATE(ps), &V_I2(pd)); + case VT_BOOL: return VarI2FromBool(V_BOOL(ps), &V_I2(pd)); + case VT_CY: return VarI2FromCy(V_CY(ps), &V_I2(pd)); + case VT_DECIMAL: return VarI2FromDec(&V_DECIMAL(ps), &V_I2(pd)); + case VT_DISPATCH: return VarI2FromDisp(V_DISPATCH(ps), lcid, &V_I2(pd)); + case VT_BSTR: return VarI2FromStr(V_BSTR(ps), lcid, dwFlags, &V_I2(pd)); + } + break; + + case VT_I4: + switch (vtFrom) + { + case VT_EMPTY: V_I4(pd) = 0; return S_OK; + case VT_I1: return VarI4FromI1(V_I1(ps), &V_I4(pd)); + case VT_I2: return VarI4FromI2(V_I2(ps), &V_I4(pd)); + case VT_UI1: return VarI4FromUI1(V_UI1(ps), &V_I4(pd)); + case VT_UI2: return VarI4FromUI2(V_UI2(ps), &V_I4(pd)); + case VT_UI4: + if (bIgnoreOverflow) + { + V_VT(pd) = VT_I4; + V_I4(pd) = V_I4(ps); + return S_OK; + } + return VarI4FromUI4(V_UI4(ps), &V_I4(pd)); + case VT_I8: return VarI4FromI8(V_I8(ps), &V_I4(pd)); + case VT_UI8: return VarI4FromUI8(V_UI8(ps), &V_I4(pd)); + case VT_R4: return VarI4FromR4(V_R4(ps), &V_I4(pd)); + case VT_R8: return VarI4FromR8(V_R8(ps), &V_I4(pd)); + case VT_DATE: return VarI4FromDate(V_DATE(ps), &V_I4(pd)); + case VT_BOOL: return VarI4FromBool(V_BOOL(ps), &V_I4(pd)); + case VT_CY: return VarI4FromCy(V_CY(ps), &V_I4(pd)); + case VT_DECIMAL: return VarI4FromDec(&V_DECIMAL(ps), &V_I4(pd)); + case VT_DISPATCH: return VarI4FromDisp(V_DISPATCH(ps), lcid, &V_I4(pd)); + case VT_BSTR: return VarI4FromStr(V_BSTR(ps), lcid, dwFlags, &V_I4(pd)); + } + break; + + case VT_UI1: + switch (vtFrom) + { + case VT_EMPTY: V_UI1(pd) = 0; return S_OK; + case VT_I1: return VarUI1FromI1(V_I1(ps), &V_UI1(pd)); + case VT_I2: return VarUI1FromI2(V_I2(ps), &V_UI1(pd)); + case VT_I4: return VarUI1FromI4(V_I4(ps), &V_UI1(pd)); + case VT_UI2: return VarUI1FromUI2(V_UI2(ps), &V_UI1(pd)); + case VT_UI4: return VarUI1FromUI4(V_UI4(ps), &V_UI1(pd)); + case VT_I8: return VarUI1FromI8(V_I8(ps), &V_UI1(pd)); + case VT_UI8: return VarUI1FromUI8(V_UI8(ps), &V_UI1(pd)); + case VT_R4: return VarUI1FromR4(V_R4(ps), &V_UI1(pd)); + case VT_R8: return VarUI1FromR8(V_R8(ps), &V_UI1(pd)); + case VT_DATE: return VarUI1FromDate(V_DATE(ps), &V_UI1(pd)); + case VT_BOOL: return VarUI1FromBool(V_BOOL(ps), &V_UI1(pd)); + case VT_CY: return VarUI1FromCy(V_CY(ps), &V_UI1(pd)); + case VT_DECIMAL: return VarUI1FromDec(&V_DECIMAL(ps), &V_UI1(pd)); + case VT_DISPATCH: return VarUI1FromDisp(V_DISPATCH(ps), lcid, &V_UI1(pd)); + case VT_BSTR: return VarUI1FromStr(V_BSTR(ps), lcid, dwFlags, &V_UI1(pd)); + } + break; + + case VT_UI2: + switch (vtFrom) + { + case VT_EMPTY: V_UI2(pd) = 0; return S_OK; + case VT_I1: return VarUI2FromI1(V_I1(ps), &V_UI2(pd)); + case VT_I2: return VarUI2FromI2(V_I2(ps), &V_UI2(pd)); + case VT_I4: return VarUI2FromI4(V_I4(ps), &V_UI2(pd)); + case VT_UI1: return VarUI2FromUI1(V_UI1(ps), &V_UI2(pd)); + case VT_UI4: return VarUI2FromUI4(V_UI4(ps), &V_UI2(pd)); + case VT_I8: return VarUI4FromI8(V_I8(ps), &V_UI4(pd)); + case VT_UI8: return VarUI4FromUI8(V_UI8(ps), &V_UI4(pd)); + case VT_R4: return VarUI2FromR4(V_R4(ps), &V_UI2(pd)); + case VT_R8: return VarUI2FromR8(V_R8(ps), &V_UI2(pd)); + case VT_DATE: return VarUI2FromDate(V_DATE(ps), &V_UI2(pd)); + case VT_BOOL: return VarUI2FromBool(V_BOOL(ps), &V_UI2(pd)); + case VT_CY: return VarUI2FromCy(V_CY(ps), &V_UI2(pd)); + case VT_DECIMAL: return VarUI2FromDec(&V_DECIMAL(ps), &V_UI2(pd)); + case VT_DISPATCH: return VarUI2FromDisp(V_DISPATCH(ps), lcid, &V_UI2(pd)); + case VT_BSTR: return VarUI2FromStr(V_BSTR(ps), lcid, dwFlags, &V_UI2(pd)); + } + break; + + case VT_UI4: + switch (vtFrom) + { + case VT_EMPTY: V_UI4(pd) = 0; return S_OK; + case VT_I1: return VarUI4FromI1(V_I1(ps), &V_UI4(pd)); + case VT_I2: return VarUI4FromI2(V_I2(ps), &V_UI4(pd)); + case VT_I4: return VarUI4FromI4(V_I4(ps), &V_UI4(pd)); + case VT_UI1: return VarUI4FromUI1(V_UI1(ps), &V_UI4(pd)); + case VT_UI2: return VarUI4FromUI2(V_UI2(ps), &V_UI4(pd)); + case VT_I8: return VarUI4FromI8(V_I8(ps), &V_UI4(pd)); + case VT_UI8: return VarUI4FromUI8(V_UI8(ps), &V_UI4(pd)); + case VT_R4: return VarUI4FromR4(V_R4(ps), &V_UI4(pd)); + case VT_R8: return VarUI4FromR8(V_R8(ps), &V_UI4(pd)); + case VT_DATE: return VarUI4FromDate(V_DATE(ps), &V_UI4(pd)); + case VT_BOOL: return VarUI4FromBool(V_BOOL(ps), &V_UI4(pd)); + case VT_CY: return VarUI4FromCy(V_CY(ps), &V_UI4(pd)); + case VT_DECIMAL: return VarUI4FromDec(&V_DECIMAL(ps), &V_UI4(pd)); + case VT_DISPATCH: return VarUI4FromDisp(V_DISPATCH(ps), lcid, &V_UI4(pd)); + case VT_BSTR: return VarUI4FromStr(V_BSTR(ps), lcid, dwFlags, &V_UI4(pd)); + } + break; + + case VT_UI8: + switch (vtFrom) + { + case VT_EMPTY: V_UI8(pd) = 0; return S_OK; + case VT_I4: if (V_I4(ps) < 0) return DISP_E_OVERFLOW; V_UI8(pd) = V_I4(ps); return S_OK; + case VT_I1: return VarUI8FromI1(V_I1(ps), &V_UI8(pd)); + case VT_I2: return VarUI8FromI2(V_I2(ps), &V_UI8(pd)); + case VT_UI1: return VarUI8FromUI1(V_UI1(ps), &V_UI8(pd)); + case VT_UI2: return VarUI8FromUI2(V_UI2(ps), &V_UI8(pd)); + case VT_UI4: return VarUI8FromUI4(V_UI4(ps), &V_UI8(pd)); + case VT_I8: return VarUI8FromI8(V_I8(ps), &V_UI8(pd)); + case VT_R4: return VarUI8FromR4(V_R4(ps), &V_UI8(pd)); + case VT_R8: return VarUI8FromR8(V_R8(ps), &V_UI8(pd)); + case VT_DATE: return VarUI8FromDate(V_DATE(ps), &V_UI8(pd)); + case VT_BOOL: return VarUI8FromBool(V_BOOL(ps), &V_UI8(pd)); + case VT_CY: return VarUI8FromCy(V_CY(ps), &V_UI8(pd)); + case VT_DECIMAL: return VarUI8FromDec(&V_DECIMAL(ps), &V_UI8(pd)); + case VT_DISPATCH: return VarUI8FromDisp(V_DISPATCH(ps), lcid, &V_UI8(pd)); + case VT_BSTR: return VarUI8FromStr(V_BSTR(ps), lcid, dwFlags, &V_UI8(pd)); + } + break; + + case VT_I8: + switch (vtFrom) + { + case VT_EMPTY: V_I8(pd) = 0; return S_OK; + case VT_I4: V_I8(pd) = V_I4(ps); return S_OK; + case VT_I1: return VarI8FromI1(V_I1(ps), &V_I8(pd)); + case VT_I2: return VarI8FromI2(V_I2(ps), &V_I8(pd)); + case VT_UI1: return VarI8FromUI1(V_UI1(ps), &V_I8(pd)); + case VT_UI2: return VarI8FromUI2(V_UI2(ps), &V_I8(pd)); + case VT_UI4: return VarI8FromUI4(V_UI4(ps), &V_I8(pd)); + case VT_UI8: return VarI8FromUI8(V_I8(ps), &V_I8(pd)); + case VT_R4: return VarI8FromR4(V_R4(ps), &V_I8(pd)); + case VT_R8: return VarI8FromR8(V_R8(ps), &V_I8(pd)); + case VT_DATE: return VarI8FromDate(V_DATE(ps), &V_I8(pd)); + case VT_BOOL: return VarI8FromBool(V_BOOL(ps), &V_I8(pd)); + case VT_CY: return VarI8FromCy(V_CY(ps), &V_I8(pd)); + case VT_DECIMAL: return VarI8FromDec(&V_DECIMAL(ps), &V_I8(pd)); + case VT_DISPATCH: return VarI8FromDisp(V_DISPATCH(ps), lcid, &V_I8(pd)); + case VT_BSTR: return VarI8FromStr(V_BSTR(ps), lcid, dwFlags, &V_I8(pd)); + } + break; + + case VT_R4: + switch (vtFrom) + { + case VT_EMPTY: V_R4(pd) = 0.0f; return S_OK; + case VT_I1: return VarR4FromI1(V_I1(ps), &V_R4(pd)); + case VT_I2: return VarR4FromI2(V_I2(ps), &V_R4(pd)); + case VT_I4: return VarR4FromI4(V_I4(ps), &V_R4(pd)); + case VT_UI1: return VarR4FromUI1(V_UI1(ps), &V_R4(pd)); + case VT_UI2: return VarR4FromUI2(V_UI2(ps), &V_R4(pd)); + case VT_UI4: return VarR4FromUI4(V_UI4(ps), &V_R4(pd)); + case VT_I8: return VarR4FromI8(V_I8(ps), &V_R4(pd)); + case VT_UI8: return VarR4FromUI8(V_UI8(ps), &V_R4(pd)); + case VT_R8: return VarR4FromR8(V_R8(ps), &V_R4(pd)); + case VT_DATE: return VarR4FromDate(V_DATE(ps), &V_R4(pd)); + case VT_BOOL: return VarR4FromBool(V_BOOL(ps), &V_R4(pd)); + case VT_CY: return VarR4FromCy(V_CY(ps), &V_R4(pd)); + case VT_DECIMAL: return VarR4FromDec(&V_DECIMAL(ps), &V_R4(pd)); + case VT_DISPATCH: return VarR4FromDisp(V_DISPATCH(ps), lcid, &V_R4(pd)); + case VT_BSTR: return VarR4FromStr(V_BSTR(ps), lcid, dwFlags, &V_R4(pd)); + } + break; + + case VT_R8: + switch (vtFrom) + { + case VT_EMPTY: V_R8(pd) = 0.0; return S_OK; + case VT_I1: return VarR8FromI1(V_I1(ps), &V_R8(pd)); + case VT_I2: return VarR8FromI2(V_I2(ps), &V_R8(pd)); + case VT_I4: return VarR8FromI4(V_I4(ps), &V_R8(pd)); + case VT_UI1: return VarR8FromUI1(V_UI1(ps), &V_R8(pd)); + case VT_UI2: return VarR8FromUI2(V_UI2(ps), &V_R8(pd)); + case VT_UI4: return VarR8FromUI4(V_UI4(ps), &V_R8(pd)); + case VT_I8: return VarR8FromI8(V_I8(ps), &V_R8(pd)); + case VT_UI8: return VarR8FromUI8(V_UI8(ps), &V_R8(pd)); + case VT_R4: return VarR8FromR4(V_R4(ps), &V_R8(pd)); + case VT_DATE: return VarR8FromDate(V_DATE(ps), &V_R8(pd)); + case VT_BOOL: return VarR8FromBool(V_BOOL(ps), &V_R8(pd)); + case VT_CY: return VarR8FromCy(V_CY(ps), &V_R8(pd)); + case VT_DECIMAL: return VarR8FromDec(&V_DECIMAL(ps), &V_R8(pd)); + case VT_DISPATCH: return VarR8FromDisp(V_DISPATCH(ps), lcid, &V_R8(pd)); + case VT_BSTR: return VarR8FromStr(V_BSTR(ps), lcid, dwFlags, &V_R8(pd)); + } + break; + + case VT_DATE: + switch (vtFrom) + { + case VT_EMPTY: V_DATE(pd) = 0.0; return S_OK; + case VT_I1: return VarDateFromI1(V_I1(ps), &V_DATE(pd)); + case VT_I2: return VarDateFromI2(V_I2(ps), &V_DATE(pd)); + case VT_I4: return VarDateFromI4(V_I4(ps), &V_DATE(pd)); + case VT_UI1: return VarDateFromUI1(V_UI1(ps), &V_DATE(pd)); + case VT_UI2: return VarDateFromUI2(V_UI2(ps), &V_DATE(pd)); + case VT_UI4: return VarDateFromUI4(V_UI4(ps), &V_DATE(pd)); + case VT_I8: return VarDateFromI8(V_I8(ps), &V_DATE(pd)); + case VT_UI8: return VarDateFromUI8(V_UI8(ps), &V_DATE(pd)); + case VT_R4: return VarDateFromR4(V_R4(ps), &V_DATE(pd)); + case VT_R8: return VarDateFromR8(V_R8(ps), &V_DATE(pd)); + case VT_BOOL: return VarDateFromBool(V_BOOL(ps), &V_DATE(pd)); + case VT_CY: return VarDateFromCy(V_CY(ps), &V_DATE(pd)); + case VT_DECIMAL: return VarDateFromDec(&V_DECIMAL(ps), &V_DATE(pd)); + case VT_DISPATCH: return VarDateFromDisp(V_DISPATCH(ps), lcid, &V_DATE(pd)); + case VT_BSTR: return VarDateFromStr(V_BSTR(ps), lcid, dwFlags, &V_DATE(pd)); + } + break; + + case VT_BOOL: + switch (vtFrom) + { + case VT_EMPTY: V_BOOL(pd) = 0; return S_OK; + case VT_I1: return VarBoolFromI1(V_I1(ps), &V_BOOL(pd)); + case VT_I2: return VarBoolFromI2(V_I2(ps), &V_BOOL(pd)); + case VT_I4: return VarBoolFromI4(V_I4(ps), &V_BOOL(pd)); + case VT_UI1: return VarBoolFromUI1(V_UI1(ps), &V_BOOL(pd)); + case VT_UI2: return VarBoolFromUI2(V_UI2(ps), &V_BOOL(pd)); + case VT_UI4: return VarBoolFromUI4(V_UI4(ps), &V_BOOL(pd)); + case VT_I8: return VarBoolFromI8(V_I8(ps), &V_BOOL(pd)); + case VT_UI8: return VarBoolFromUI8(V_UI8(ps), &V_BOOL(pd)); + case VT_R4: return VarBoolFromR4(V_R4(ps), &V_BOOL(pd)); + case VT_R8: return VarBoolFromR8(V_R8(ps), &V_BOOL(pd)); + case VT_DATE: return VarBoolFromDate(V_DATE(ps), &V_BOOL(pd)); + case VT_CY: return VarBoolFromCy(V_CY(ps), &V_BOOL(pd)); + case VT_DECIMAL: return VarBoolFromDec(&V_DECIMAL(ps), &V_BOOL(pd)); + case VT_DISPATCH: return VarBoolFromDisp(V_DISPATCH(ps), lcid, &V_BOOL(pd)); + case VT_BSTR: return VarBoolFromStr(V_BSTR(ps), lcid, dwFlags, &V_BOOL(pd)); + } + break; + + case VT_BSTR: + switch (vtFrom) + { + case VT_EMPTY: + V_BSTR(pd) = SysAllocStringLen(NULL, 0); + return V_BSTR(pd) ? S_OK : E_OUTOFMEMORY; + case VT_BOOL: + if (wFlags & (VARIANT_ALPHABOOL|VARIANT_LOCALBOOL)) + return VarBstrFromBool(V_BOOL(ps), lcid, dwFlags, &V_BSTR(pd)); + return VarBstrFromI2(V_BOOL(ps), lcid, dwFlags, &V_BSTR(pd)); + case VT_I1: return VarBstrFromI1(V_I1(ps), lcid, dwFlags, &V_BSTR(pd)); + case VT_I2: return VarBstrFromI2(V_I2(ps), lcid, dwFlags, &V_BSTR(pd)); + case VT_I4: return VarBstrFromI4(V_I4(ps), lcid, dwFlags, &V_BSTR(pd)); + case VT_UI1: return VarBstrFromUI1(V_UI1(ps), lcid, dwFlags, &V_BSTR(pd)); + case VT_UI2: return VarBstrFromUI2(V_UI2(ps), lcid, dwFlags, &V_BSTR(pd)); + case VT_UI4: return VarBstrFromUI4(V_UI4(ps), lcid, dwFlags, &V_BSTR(pd)); + case VT_I8: return VarBstrFromI8(V_I8(ps), lcid, dwFlags, &V_BSTR(pd)); + case VT_UI8: return VarBstrFromUI8(V_UI8(ps), lcid, dwFlags, &V_BSTR(pd)); + case VT_R4: return VarBstrFromR4(V_R4(ps), lcid, dwFlags, &V_BSTR(pd)); + case VT_R8: return VarBstrFromR8(V_R8(ps), lcid, dwFlags, &V_BSTR(pd)); + case VT_DATE: return VarBstrFromDate(V_DATE(ps), lcid, dwFlags, &V_BSTR(pd)); + case VT_CY: return VarBstrFromCy(V_CY(ps), lcid, dwFlags, &V_BSTR(pd)); + case VT_DECIMAL: return VarBstrFromDec(&V_DECIMAL(ps), lcid, dwFlags, &V_BSTR(pd)); +/* case VT_DISPATCH: return VarBstrFromDisp(V_DISPATCH(ps), lcid, dwFlags, &V_BSTR(pd)); */ + } + break; + + case VT_CY: + switch (vtFrom) + { + case VT_EMPTY: V_CY(pd).int64 = 0; return S_OK; + case VT_I1: return VarCyFromI1(V_I1(ps), &V_CY(pd)); + case VT_I2: return VarCyFromI2(V_I2(ps), &V_CY(pd)); + case VT_I4: return VarCyFromI4(V_I4(ps), &V_CY(pd)); + case VT_UI1: return VarCyFromUI1(V_UI1(ps), &V_CY(pd)); + case VT_UI2: return VarCyFromUI2(V_UI2(ps), &V_CY(pd)); + case VT_UI4: return VarCyFromUI4(V_UI4(ps), &V_CY(pd)); + case VT_I8: return VarCyFromI8(V_I8(ps), &V_CY(pd)); + case VT_UI8: return VarCyFromUI8(V_UI8(ps), &V_CY(pd)); + case VT_R4: return VarCyFromR4(V_R4(ps), &V_CY(pd)); + case VT_R8: return VarCyFromR8(V_R8(ps), &V_CY(pd)); + case VT_DATE: return VarCyFromDate(V_DATE(ps), &V_CY(pd)); + case VT_BOOL: return VarCyFromBool(V_BOOL(ps), &V_CY(pd)); + case VT_DECIMAL: return VarCyFromDec(&V_DECIMAL(ps), &V_CY(pd)); + case VT_DISPATCH: return VarCyFromDisp(V_DISPATCH(ps), lcid, &V_CY(pd)); + case VT_BSTR: return VarCyFromStr(V_BSTR(ps), lcid, dwFlags, &V_CY(pd)); + } + break; + + case VT_DECIMAL: + switch (vtFrom) + { + case VT_EMPTY: + case VT_BOOL: + DEC_SIGNSCALE(&V_DECIMAL(pd)) = SIGNSCALE(DECIMAL_POS,0); + DEC_HI32(&V_DECIMAL(pd)) = 0; + DEC_MID32(&V_DECIMAL(pd)) = 0; + /* VarDecFromBool() coerces to -1/0, ChangeTypeEx() coerces to 1/0. + * VT_NULL and VT_EMPTY always give a 0 value. + */ + DEC_LO32(&V_DECIMAL(pd)) = vtFrom == VT_BOOL && V_BOOL(ps) ? 1 : 0; + return S_OK; + case VT_I1: return VarDecFromI1(V_I1(ps), &V_DECIMAL(pd)); + case VT_I2: return VarDecFromI2(V_I2(ps), &V_DECIMAL(pd)); + case VT_I4: return VarDecFromI4(V_I4(ps), &V_DECIMAL(pd)); + case VT_UI1: return VarDecFromUI1(V_UI1(ps), &V_DECIMAL(pd)); + case VT_UI2: return VarDecFromUI2(V_UI2(ps), &V_DECIMAL(pd)); + case VT_UI4: return VarDecFromUI4(V_UI4(ps), &V_DECIMAL(pd)); + case VT_I8: return VarDecFromI8(V_I8(ps), &V_DECIMAL(pd)); + case VT_UI8: return VarDecFromUI8(V_UI8(ps), &V_DECIMAL(pd)); + case VT_R4: return VarDecFromR4(V_R4(ps), &V_DECIMAL(pd)); + case VT_R8: return VarDecFromR8(V_R8(ps), &V_DECIMAL(pd)); + case VT_DATE: return VarDecFromDate(V_DATE(ps), &V_DECIMAL(pd)); + case VT_CY: return VarDecFromCy(V_CY(pd), &V_DECIMAL(ps)); + case VT_DISPATCH: return VarDecFromDisp(V_DISPATCH(ps), lcid, &V_DECIMAL(ps)); + case VT_BSTR: return VarDecFromStr(V_BSTR(ps), lcid, dwFlags, &V_DECIMAL(pd)); + } + break; + + case VT_UNKNOWN: + switch (vtFrom) + { + case VT_DISPATCH: + if (V_DISPATCH(ps) == NULL) + V_UNKNOWN(pd) = NULL; + else + res = IDispatch_QueryInterface(V_DISPATCH(ps), &IID_IUnknown, (LPVOID*)&V_UNKNOWN(pd)); + break; + } + break; + + case VT_DISPATCH: + switch (vtFrom) + { + case VT_UNKNOWN: + if (V_UNKNOWN(ps) == NULL) + V_DISPATCH(pd) = NULL; + else + res = IUnknown_QueryInterface(V_UNKNOWN(ps), &IID_IDispatch, (LPVOID*)&V_DISPATCH(pd)); + break; + } + break; + + case VT_RECORD: + break; + } + return res; +} + +/* Coerce to/from an array */ +static inline HRESULT VARIANT_CoerceArray(VARIANTARG* pd, VARIANTARG* ps, VARTYPE vt) +{ + if (vt == VT_BSTR && V_VT(ps) == (VT_ARRAY|VT_UI1)) + return BstrFromVector(V_ARRAY(ps), &V_BSTR(pd)); + + if (V_VT(ps) == VT_BSTR && vt == (VT_ARRAY|VT_UI1)) + return VectorFromBstr(V_BSTR(ps), &V_ARRAY(ps)); + + if (V_VT(ps) == vt) + return SafeArrayCopy(V_ARRAY(ps), &V_ARRAY(pd)); + + return DISP_E_TYPEMISMATCH; +} + +/****************************************************************************** + * Check if a variants type is valid. + */ +static inline HRESULT VARIANT_ValidateType(VARTYPE vt) +{ + VARTYPE vtExtra = vt & VT_EXTRA_TYPE; + + vt &= VT_TYPEMASK; + + if (!(vtExtra & (VT_VECTOR|VT_RESERVED))) + { + if (vt < VT_VOID || vt == VT_RECORD || vt == VT_CLSID) + { + if ((vtExtra & (VT_BYREF|VT_ARRAY)) && vt <= VT_NULL) + return DISP_E_BADVARTYPE; + if (vt != (VARTYPE)15) + return S_OK; + } + } + return DISP_E_BADVARTYPE; +} + +/****************************************************************************** + * VariantInit [OLEAUT32.8] + * + * Initialise a variant. + * + * PARAMS + * pVarg [O] Variant to initialise + * + * RETURNS + * Nothing. + * + * NOTES + * This function simply sets the type of the variant to VT_EMPTY. It does not + * free any existing value, use VariantClear() for that. + */ +void WINAPI VariantInit(VARIANTARG* pVarg) +{ + TRACE("(%p)\n", pVarg); + + V_VT(pVarg) = VT_EMPTY; /* Native doesn't set any other fields */ +} + +/****************************************************************************** + * VariantClear [OLEAUT32.9] + * + * Clear a variant. + * + * PARAMS + * pVarg [I/O] Variant to clear + * + * RETURNS + * Success: S_OK. Any previous value in pVarg is freed and its type is set to VT_EMPTY. + * Failure: DISP_E_BADVARTYPE, if the variant is a not a valid variant type. + */ +HRESULT WINAPI VariantClear(VARIANTARG* pVarg) +{ + HRESULT hres = S_OK; + + TRACE("(%p->(%s%s))\n", pVarg, debugstr_VT(pVarg), debugstr_VF(pVarg)); + + hres = VARIANT_ValidateType(V_VT(pVarg)); + + if (SUCCEEDED(hres)) + { + if (!V_ISBYREF(pVarg)) + { + if (V_ISARRAY(pVarg) || V_VT(pVarg) == VT_SAFEARRAY) + { + if (V_ARRAY(pVarg)) + hres = SafeArrayDestroy(V_ARRAY(pVarg)); + } + else if (V_VT(pVarg) == VT_BSTR) + { + if (V_BSTR(pVarg)) + SysFreeString(V_BSTR(pVarg)); + } + else if (V_VT(pVarg) == VT_RECORD) + { + struct __tagBRECORD* pBr = &V_UNION(pVarg,brecVal); + if (pBr->pRecInfo) + { + IRecordInfo_RecordClear(pBr->pRecInfo, pBr->pvRecord); + IRecordInfo_Release(pBr->pRecInfo); + } + } + else if (V_VT(pVarg) == VT_DISPATCH || + V_VT(pVarg) == VT_UNKNOWN) + { + if (V_UNKNOWN(pVarg)) + IUnknown_Release(V_UNKNOWN(pVarg)); + } + else if (V_VT(pVarg) == VT_VARIANT) + { + if (V_VARIANTREF(pVarg)) + VariantClear(V_VARIANTREF(pVarg)); + } + } + V_VT(pVarg) = VT_EMPTY; + } + return hres; +} + +/****************************************************************************** + * Copy an IRecordInfo object contained in a variant. + */ +static HRESULT VARIANT_CopyIRecordInfo(struct __tagBRECORD* pBr) +{ + HRESULT hres = S_OK; + + if (pBr->pRecInfo) + { + ULONG ulSize; + + hres = IRecordInfo_GetSize(pBr->pRecInfo, &ulSize); + if (SUCCEEDED(hres)) + { + PVOID pvRecord = HeapAlloc(GetProcessHeap(), 0, ulSize); + if (!pvRecord) + hres = E_OUTOFMEMORY; + else + { + memcpy(pvRecord, pBr->pvRecord, ulSize); + pBr->pvRecord = pvRecord; + + hres = IRecordInfo_RecordCopy(pBr->pRecInfo, pvRecord, pvRecord); + if (SUCCEEDED(hres)) + IRecordInfo_AddRef(pBr->pRecInfo); + } + } + } + else if (pBr->pvRecord) + hres = E_INVALIDARG; + return hres; +} + +/****************************************************************************** + * VariantCopy [OLEAUT32.10] + * + * Copy a variant. + * + * PARAMS + * pvargDest [O] Destination for copy + * pvargSrc [I] Source variant to copy + * + * RETURNS + * Success: S_OK. pvargDest contains a copy of pvargSrc. + * Failure: DISP_E_BADVARTYPE, if either variant has an invalid type. + * E_OUTOFMEMORY, if memory cannot be allocated. Otherwise an + * HRESULT error code from SafeArrayCopy(), IRecordInfo_GetSize(), + * or IRecordInfo_RecordCopy(), depending on the type of pvargSrc. + * + * NOTES + * - If pvargSrc == pvargDest, this function does nothing, and succeeds if + * pvargSrc is valid. Otherwise, pvargDest is always cleared using + * VariantClear() before pvargSrc is copied to it. If clearing pvargDest + * fails, so does this function. + * - VT_CLSID is a valid type type for pvargSrc, but not for pvargDest. + * - For by-value non-intrinsic types, a deep copy is made, i.e. The whole value + * is copied rather than just any pointers to it. + * - For by-value object types the object pointer is copied and the objects + * reference count increased using IUnknown_AddRef(). + * - For all by-reference types, only the referencing pointer is copied. + */ +HRESULT WINAPI VariantCopy(VARIANTARG* pvargDest, VARIANTARG* pvargSrc) +{ + HRESULT hres = S_OK; + + TRACE("(%p->(%s%s),%p->(%s%s))\n", pvargDest, debugstr_VT(pvargDest), + debugstr_VF(pvargDest), pvargSrc, debugstr_VT(pvargSrc), + debugstr_VF(pvargSrc)); + + if (V_TYPE(pvargSrc) == VT_CLSID || /* VT_CLSID is a special case */ + FAILED(VARIANT_ValidateType(V_VT(pvargSrc)))) + return DISP_E_BADVARTYPE; + + if (pvargSrc != pvargDest && + SUCCEEDED(hres = VariantClear(pvargDest))) + { + *pvargDest = *pvargSrc; /* Shallow copy the value */ + + if (!V_ISBYREF(pvargSrc)) + { + if (V_ISARRAY(pvargSrc)) + { + if (V_ARRAY(pvargSrc)) + hres = SafeArrayCopy(V_ARRAY(pvargSrc), &V_ARRAY(pvargDest)); + } + else if (V_VT(pvargSrc) == VT_BSTR) + { + if (V_BSTR(pvargSrc)) + { + V_BSTR(pvargDest) = SysAllocStringByteLen((char*)V_BSTR(pvargSrc), SysStringByteLen(V_BSTR(pvargSrc))); + if (!V_BSTR(pvargDest)) + { + TRACE("!V_BSTR(pvargDest), SysAllocStringByteLen() failed to allocate %d bytes\n", SysStringByteLen(V_BSTR(pvargSrc))); + hres = E_OUTOFMEMORY; + } + } + } + else if (V_VT(pvargSrc) == VT_RECORD) + { + hres = VARIANT_CopyIRecordInfo(&V_UNION(pvargDest,brecVal)); + } + else if (V_VT(pvargSrc) == VT_DISPATCH || + V_VT(pvargSrc) == VT_UNKNOWN) + { + if (V_UNKNOWN(pvargSrc)) + IUnknown_AddRef(V_UNKNOWN(pvargSrc)); + } + } + } + return hres; +} + +/* Return the byte size of a variants data */ +static inline size_t VARIANT_DataSize(const VARIANT* pv) +{ + switch (V_TYPE(pv)) + { + case VT_I1: + case VT_UI1: return sizeof(BYTE); break; + case VT_I2: + case VT_UI2: return sizeof(SHORT); break; + case VT_INT: + case VT_UINT: + case VT_I4: + case VT_UI4: return sizeof(LONG); break; + case VT_I8: + case VT_UI8: return sizeof(LONGLONG); break; + case VT_R4: return sizeof(float); break; + case VT_R8: return sizeof(double); break; + case VT_DATE: return sizeof(DATE); break; + case VT_BOOL: return sizeof(VARIANT_BOOL); break; + case VT_DISPATCH: + case VT_UNKNOWN: + case VT_BSTR: return sizeof(void*); break; + case VT_CY: return sizeof(CY); break; + case VT_ERROR: return sizeof(SCODE); break; + } + TRACE("Shouldn't be called for vt %s%s!\n", debugstr_VT(pv), debugstr_VF(pv)); + return 0; +} + +/****************************************************************************** + * VariantCopyInd [OLEAUT32.11] + * + * Copy a variant, dereferencing it it is by-reference. + * + * PARAMS + * pvargDest [O] Destination for copy + * pvargSrc [I] Source variant to copy + * + * RETURNS + * Success: S_OK. pvargDest contains a copy of pvargSrc. + * Failure: An HRESULT error code indicating the error. + * + * NOTES + * Failure: DISP_E_BADVARTYPE, if either variant has an invalid by-value type. + * E_INVALIDARG, if pvargSrc is an invalid by-reference type. + * E_OUTOFMEMORY, if memory cannot be allocated. Otherwise an + * HRESULT error code from SafeArrayCopy(), IRecordInfo_GetSize(), + * or IRecordInfo_RecordCopy(), depending on the type of pvargSrc. + * + * NOTES + * - If pvargSrc is by-value, this function behaves exactly as VariantCopy(). + * - If pvargSrc is by-reference, the value copied to pvargDest is the pointed-to + * value. + * - if pvargSrc == pvargDest, this function dereferences in place. Otherwise, + * pvargDest is always cleared using VariantClear() before pvargSrc is copied + * to it. If clearing pvargDest fails, so does this function. + */ +HRESULT WINAPI VariantCopyInd(VARIANT* pvargDest, VARIANTARG* pvargSrc) +{ + VARIANTARG vTmp, *pSrc = pvargSrc; + VARTYPE vt; + HRESULT hres = S_OK; + + TRACE("(%p->(%s%s),%p->(%s%s))\n", pvargDest, debugstr_VT(pvargDest), + debugstr_VF(pvargDest), pvargSrc, debugstr_VT(pvargSrc), + debugstr_VF(pvargSrc)); + + if (!V_ISBYREF(pvargSrc)) + return VariantCopy(pvargDest, pvargSrc); + + /* Argument checking is more lax than VariantCopy()... */ + vt = V_TYPE(pvargSrc); + if (V_ISARRAY(pvargSrc) || + (vt > VT_NULL && vt != (VARTYPE)15 && vt < VT_VOID && + !(V_VT(pvargSrc) & (VT_VECTOR|VT_RESERVED)))) + { + /* OK */ + } + else + return E_INVALIDARG; /* ...And the return value for invalid types differs too */ + + if (pvargSrc == pvargDest) + { + /* In place copy. Use a shallow copy of pvargSrc & init pvargDest. + * This avoids an expensive VariantCopy() call - e.g. SafeArrayCopy(). + */ + vTmp = *pvargSrc; + pSrc = &vTmp; + V_VT(pvargDest) = VT_EMPTY; + } + else + { + /* Copy into another variant. Free the variant in pvargDest */ + if (FAILED(hres = VariantClear(pvargDest))) + { + TRACE("VariantClear() of destination failed\n"); + return hres; + } + } + + if (V_ISARRAY(pSrc)) + { + /* Native doesn't check that *V_ARRAYREF(pSrc) is valid */ + hres = SafeArrayCopy(*V_ARRAYREF(pSrc), &V_ARRAY(pvargDest)); + } + else if (V_VT(pSrc) == (VT_BSTR|VT_BYREF)) + { + /* Native doesn't check that *V_BSTRREF(pSrc) is valid */ + V_BSTR(pvargDest) = SysAllocStringByteLen((char*)*V_BSTRREF(pSrc), SysStringByteLen(*V_BSTRREF(pSrc))); + } + else if (V_VT(pSrc) == (VT_RECORD|VT_BYREF)) + { + V_UNION(pvargDest,brecVal) = V_UNION(pvargSrc,brecVal); + hres = VARIANT_CopyIRecordInfo(&V_UNION(pvargDest,brecVal)); + } + else if (V_VT(pSrc) == (VT_DISPATCH|VT_BYREF) || + V_VT(pSrc) == (VT_UNKNOWN|VT_BYREF)) + { + /* Native doesn't check that *V_UNKNOWNREF(pSrc) is valid */ + V_UNKNOWN(pvargDest) = *V_UNKNOWNREF(pSrc); + if (*V_UNKNOWNREF(pSrc)) + IUnknown_AddRef(*V_UNKNOWNREF(pSrc)); + } + else if (V_VT(pSrc) == (VT_VARIANT|VT_BYREF)) + { + /* Native doesn't check that *V_VARIANTREF(pSrc) is valid */ + if (V_VT(V_VARIANTREF(pSrc)) == (VT_VARIANT|VT_BYREF)) + hres = E_INVALIDARG; /* Don't dereference more than one level */ + else + hres = VariantCopyInd(pvargDest, V_VARIANTREF(pSrc)); + + /* Use the dereferenced variants type value, not VT_VARIANT */ + goto VariantCopyInd_Return; + } + else if (V_VT(pSrc) == (VT_DECIMAL|VT_BYREF)) + { + memcpy(&DEC_SCALE(&V_DECIMAL(pvargDest)), &DEC_SCALE(V_DECIMALREF(pSrc)), + sizeof(DECIMAL) - sizeof(USHORT)); + } + else + { + /* Copy the pointed to data into this variant */ + memcpy(&V_BYREF(pvargDest), V_BYREF(pSrc), VARIANT_DataSize(pSrc)); + } + + V_VT(pvargDest) = V_VT(pSrc) & ~VT_BYREF; + +VariantCopyInd_Return: + + if (pSrc != pvargSrc) + VariantClear(pSrc); + + TRACE("returning 0x%08lx, %p->(%s%s)\n", hres, pvargDest, + debugstr_VT(pvargDest), debugstr_VF(pvargDest)); + return hres; +} + +/****************************************************************************** + * VariantChangeType [OLEAUT32.12] + * + * Change the type of a variant. + * + * PARAMS + * pvargDest [O] Destination for the converted variant + * pvargSrc [O] Source variant to change the type of + * wFlags [I] VARIANT_ flags from "oleauto.h" + * vt [I] Variant type to change pvargSrc into + * + * RETURNS + * Success: S_OK. pvargDest contains the converted value. + * Failure: An HRESULT error code describing the failure. + * + * NOTES + * The LCID used for the conversion is LOCALE_USER_DEFAULT. + * See VariantChangeTypeEx. + */ +HRESULT WINAPI VariantChangeType(VARIANTARG* pvargDest, VARIANTARG* pvargSrc, + USHORT wFlags, VARTYPE vt) +{ + return VariantChangeTypeEx( pvargDest, pvargSrc, LOCALE_USER_DEFAULT, wFlags, vt ); +} + +/****************************************************************************** + * VariantChangeTypeEx [OLEAUT32.147] + * + * Change the type of a variant. + * + * PARAMS + * pvargDest [O] Destination for the converted variant + * pvargSrc [O] Source variant to change the type of + * lcid [I] LCID for the conversion + * wFlags [I] VARIANT_ flags from "oleauto.h" + * vt [I] Variant type to change pvargSrc into + * + * RETURNS + * Success: S_OK. pvargDest contains the converted value. + * Failure: An HRESULT error code describing the failure. + * + * NOTES + * pvargDest and pvargSrc can point to the same variant to perform an in-place + * conversion. If the conversion is successful, pvargSrc will be freed. + */ +HRESULT WINAPI VariantChangeTypeEx(VARIANTARG* pvargDest, VARIANTARG* pvargSrc, + LCID lcid, USHORT wFlags, VARTYPE vt) +{ + HRESULT res = S_OK; + + TRACE("(%p->(%s%s),%p->(%s%s),0x%08lx,0x%04x,%s%s)\n", pvargDest, + debugstr_VT(pvargDest), debugstr_VF(pvargDest), pvargSrc, + debugstr_VT(pvargSrc), debugstr_VF(pvargSrc), lcid, wFlags, + debugstr_vt(vt), debugstr_vf(vt)); + + if (vt == VT_CLSID) + res = DISP_E_BADVARTYPE; + else + { + res = VARIANT_ValidateType(V_VT(pvargSrc)); + + if (SUCCEEDED(res)) + { + res = VARIANT_ValidateType(vt); + + if (SUCCEEDED(res)) + { + VARIANTARG vTmp, vSrcDeref; + + if(V_VT(pvargSrc)&VT_BYREF && !V_BYREF(pvargSrc)) + res = DISP_E_TYPEMISMATCH; + else + { + V_VT(&vTmp) = VT_EMPTY; + V_VT(&vSrcDeref) = VT_EMPTY; + VariantClear(&vTmp); + VariantClear(&vSrcDeref); + } + + if (SUCCEEDED(res)) + { + res = VariantCopyInd(&vSrcDeref, pvargSrc); + if (SUCCEEDED(res)) + { + if (V_ISARRAY(&vSrcDeref) || (vt & VT_ARRAY)) + res = VARIANT_CoerceArray(&vTmp, &vSrcDeref, vt); + else + res = VARIANT_Coerce(&vTmp, lcid, wFlags, &vSrcDeref, vt); + + if (SUCCEEDED(res)) { + V_VT(&vTmp) = vt; + VariantCopy(pvargDest, &vTmp); + } + VariantClear(&vTmp); + VariantClear(&vSrcDeref); + } + } + } + } + } + + TRACE("returning 0x%08lx, %p->(%s%s)\n", res, pvargDest, + debugstr_VT(pvargDest), debugstr_VF(pvargDest)); + return res; +} + +/* Date Conversions */ + +#define IsLeapYear(y) (((y % 4) == 0) && (((y % 100) != 0) || ((y % 400) == 0))) + +/* Convert a VT_DATE value to a Julian Date */ +static inline int VARIANT_JulianFromDate(int dateIn) +{ + int julianDays = dateIn; + + julianDays -= DATE_MIN; /* Convert to + days from 1 Jan 100 AD */ + julianDays += 1757585; /* Convert to + days from 23 Nov 4713 BC (Julian) */ + return julianDays; +} + +/* Convert a Julian Date to a VT_DATE value */ +static inline int VARIANT_DateFromJulian(int dateIn) +{ + int julianDays = dateIn; + + julianDays -= 1757585; /* Convert to + days from 1 Jan 100 AD */ + julianDays += DATE_MIN; /* Convert to +/- days from 1 Jan 1899 AD */ + return julianDays; +} + +/* Convert a Julian date to Day/Month/Year - from PostgreSQL */ +static inline void VARIANT_DMYFromJulian(int jd, USHORT *year, USHORT *month, USHORT *day) +{ + int j, i, l, n; + + l = jd + 68569; + n = l * 4 / 146097; + l -= (n * 146097 + 3) / 4; + i = (4000 * (l + 1)) / 1461001; + l += 31 - (i * 1461) / 4; + j = (l * 80) / 2447; + *day = l - (j * 2447) / 80; + l = j / 11; + *month = (j + 2) - (12 * l); + *year = 100 * (n - 49) + i + l; +} + +/* Convert Day/Month/Year to a Julian date - from PostgreSQL */ +static inline double VARIANT_JulianFromDMY(USHORT year, USHORT month, USHORT day) +{ + int m12 = (month - 14) / 12; + + return ((1461 * (year + 4800 + m12)) / 4 + (367 * (month - 2 - 12 * m12)) / 12 - + (3 * ((year + 4900 + m12) / 100)) / 4 + day - 32075); +} + +/* Macros for accessing DOS format date/time fields */ +#define DOS_YEAR(x) (1980 + (x >> 9)) +#define DOS_MONTH(x) ((x >> 5) & 0xf) +#define DOS_DAY(x) (x & 0x1f) +#define DOS_HOUR(x) (x >> 11) +#define DOS_MINUTE(x) ((x >> 5) & 0x3f) +#define DOS_SECOND(x) ((x & 0x1f) << 1) +/* Create a DOS format date/time */ +#define DOS_DATE(d,m,y) (d | (m << 5) | ((y-1980) << 9)) +#define DOS_TIME(h,m,s) ((s >> 1) | (m << 5) | (h << 11)) + +/* Roll a date forwards or backwards to correct it */ +static HRESULT VARIANT_RollUdate(UDATE *lpUd) +{ + static const BYTE days[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + + TRACE("Raw date: %d/%d/%d %d:%d:%d\n", lpUd->st.wDay, lpUd->st.wMonth, + lpUd->st.wYear, lpUd->st.wHour, lpUd->st.wMinute, lpUd->st.wSecond); + + /* Years < 100 are treated as 1900 + year */ + if (lpUd->st.wYear < 100) + lpUd->st.wYear += 1900; + + if (!lpUd->st.wMonth) + { + /* Roll back to December of the previous year */ + lpUd->st.wMonth = 12; + lpUd->st.wYear--; + } + else while (lpUd->st.wMonth > 12) + { + /* Roll forward the correct number of months */ + lpUd->st.wYear++; + lpUd->st.wMonth -= 12; + } + + if (lpUd->st.wYear > 9999 || lpUd->st.wHour > 23 || + lpUd->st.wMinute > 59 || lpUd->st.wSecond > 59) + return E_INVALIDARG; /* Invalid values */ + + if (!lpUd->st.wDay) + { + /* Roll back the date one day */ + if (lpUd->st.wMonth == 1) + { + /* Roll back to December 31 of the previous year */ + lpUd->st.wDay = 31; + lpUd->st.wMonth = 12; + lpUd->st.wYear--; + } + else + { + lpUd->st.wMonth--; /* Previous month */ + if (lpUd->st.wMonth == 2 && IsLeapYear(lpUd->st.wYear)) + lpUd->st.wDay = 29; /* Februaury has 29 days on leap years */ + else + lpUd->st.wDay = days[lpUd->st.wMonth]; /* Last day of the month */ + } + } + else if (lpUd->st.wDay > 28) + { + int rollForward = 0; + + /* Possibly need to roll the date forward */ + if (lpUd->st.wMonth == 2 && IsLeapYear(lpUd->st.wYear)) + rollForward = lpUd->st.wDay - 29; /* Februaury has 29 days on leap years */ + else + rollForward = lpUd->st.wDay - days[lpUd->st.wMonth]; + + if (rollForward > 0) + { + lpUd->st.wDay = rollForward; + lpUd->st.wMonth++; + if (lpUd->st.wMonth > 12) + { + lpUd->st.wMonth = 1; /* Roll forward into January of the next year */ + lpUd->st.wYear++; + } + } + } + TRACE("Rolled date: %d/%d/%d %d:%d:%d\n", lpUd->st.wDay, lpUd->st.wMonth, + lpUd->st.wYear, lpUd->st.wHour, lpUd->st.wMinute, lpUd->st.wSecond); + return S_OK; +} + +/********************************************************************** + * DosDateTimeToVariantTime [OLEAUT32.14] + * + * Convert a Dos format date and time into variant VT_DATE format. + * + * PARAMS + * wDosDate [I] Dos format date + * wDosTime [I] Dos format time + * pDateOut [O] Destination for VT_DATE format + * + * RETURNS + * Success: TRUE. pDateOut contains the converted time. + * Failure: FALSE, if wDosDate or wDosTime are invalid (see notes). + * + * NOTES + * - Dos format dates can only hold dates from 1-Jan-1980 to 31-Dec-2099. + * - Dos format times are accurate to only 2 second precision. + * - The format of a Dos Date is: + *| Bits Values Meaning + *| ---- ------ ------- + *| 0-4 1-31 Day of the week. 0 rolls back one day. A value greater than + *| the days in the month rolls forward the extra days. + *| 5-8 1-12 Month of the year. 0 rolls back to December of the previous + *| year. 13-15 are invalid. + *| 9-15 0-119 Year based from 1980 (Max 2099). 120-127 are invalid. + * - The format of a Dos Time is: + *| Bits Values Meaning + *| ---- ------ ------- + *| 0-4 0-29 Seconds/2. 30 and 31 are invalid. + *| 5-10 0-59 Minutes. 60-63 are invalid. + *| 11-15 0-23 Hours (24 hour clock). 24-32 are invalid. + */ +INT WINAPI DosDateTimeToVariantTime(USHORT wDosDate, USHORT wDosTime, + double *pDateOut) +{ + UDATE ud; + + TRACE("(0x%x(%d/%d/%d),0x%x(%d:%d:%d),%p)\n", + wDosDate, DOS_YEAR(wDosDate), DOS_MONTH(wDosDate), DOS_DAY(wDosDate), + wDosTime, DOS_HOUR(wDosTime), DOS_MINUTE(wDosTime), DOS_SECOND(wDosTime), + pDateOut); + + ud.st.wYear = DOS_YEAR(wDosDate); + ud.st.wMonth = DOS_MONTH(wDosDate); + if (ud.st.wYear > 2099 || ud.st.wMonth > 12) + return FALSE; + ud.st.wDay = DOS_DAY(wDosDate); + ud.st.wHour = DOS_HOUR(wDosTime); + ud.st.wMinute = DOS_MINUTE(wDosTime); + ud.st.wSecond = DOS_SECOND(wDosTime); + ud.st.wDayOfWeek = ud.st.wMilliseconds = 0; + + return !VarDateFromUdate(&ud, 0, pDateOut); +} + +/********************************************************************** + * VariantTimeToDosDateTime [OLEAUT32.13] + * + * Convert a variant format date into a Dos format date and time. + * + * dateIn [I] VT_DATE time format + * pwDosDate [O] Destination for Dos format date + * pwDosTime [O] Destination for Dos format time + * + * RETURNS + * Success: TRUE. pwDosDate and pwDosTime contains the converted values. + * Failure: FALSE, if dateIn cannot be represented in Dos format. + * + * NOTES + * See DosDateTimeToVariantTime() for Dos format details and bugs. + */ +INT WINAPI VariantTimeToDosDateTime(double dateIn, USHORT *pwDosDate, USHORT *pwDosTime) +{ + UDATE ud; + + TRACE("(%g,%p,%p)\n", dateIn, pwDosDate, pwDosTime); + + if (FAILED(VarUdateFromDate(dateIn, 0, &ud))) + return FALSE; + + if (ud.st.wYear < 1980 || ud.st.wYear > 2099) + return FALSE; + + *pwDosDate = DOS_DATE(ud.st.wDay, ud.st.wMonth, ud.st.wYear); + *pwDosTime = DOS_TIME(ud.st.wHour, ud.st.wMinute, ud.st.wSecond); + + TRACE("Returning 0x%x(%d/%d/%d), 0x%x(%d:%d:%d)\n", + *pwDosDate, DOS_YEAR(*pwDosDate), DOS_MONTH(*pwDosDate), DOS_DAY(*pwDosDate), + *pwDosTime, DOS_HOUR(*pwDosTime), DOS_MINUTE(*pwDosTime), DOS_SECOND(*pwDosTime)); + return TRUE; +} + +/*********************************************************************** + * SystemTimeToVariantTime [OLEAUT32.184] + * + * Convert a System format date and time into variant VT_DATE format. + * + * PARAMS + * lpSt [I] System format date and time + * pDateOut [O] Destination for VT_DATE format date + * + * RETURNS + * Success: TRUE. *pDateOut contains the converted value. + * Failure: FALSE, if lpSt cannot be represented in VT_DATE format. + */ +INT WINAPI SystemTimeToVariantTime(LPSYSTEMTIME lpSt, double *pDateOut) +{ + UDATE ud; + + TRACE("(%p->%d/%d/%d %d:%d:%d,%p)\n", lpSt, lpSt->wDay, lpSt->wMonth, + lpSt->wYear, lpSt->wHour, lpSt->wMinute, lpSt->wSecond, pDateOut); + + if (lpSt->wMonth > 12) + return FALSE; + + memcpy(&ud.st, lpSt, sizeof(ud.st)); + return !VarDateFromUdate(&ud, 0, pDateOut); +} + +/*********************************************************************** + * VariantTimeToSystemTime [OLEAUT32.185] + * + * Convert a variant VT_DATE into a System format date and time. + * + * PARAMS + * datein [I] Variant VT_DATE format date + * lpSt [O] Destination for System format date and time + * + * RETURNS + * Success: TRUE. *lpSt contains the converted value. + * Failure: FALSE, if dateIn is too large or small. + */ +INT WINAPI VariantTimeToSystemTime(double dateIn, LPSYSTEMTIME lpSt) +{ + UDATE ud; + + TRACE("(%g,%p)\n", dateIn, lpSt); + + if (FAILED(VarUdateFromDate(dateIn, 0, &ud))) + return FALSE; + + memcpy(lpSt, &ud.st, sizeof(ud.st)); + return TRUE; +} + +/*********************************************************************** + * VarDateFromUdateEx [OLEAUT32.319] + * + * Convert an unpacked format date and time to a variant VT_DATE. + * + * PARAMS + * pUdateIn [I] Unpacked format date and time to convert + * lcid [I] Locale identifier for the conversion + * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h") + * pDateOut [O] Destination for variant VT_DATE. + * + * RETURNS + * Success: S_OK. *pDateOut contains the converted value. + * Failure: E_INVALIDARG, if pUdateIn cannot be represented in VT_DATE format. + */ +HRESULT WINAPI VarDateFromUdateEx(UDATE *pUdateIn, LCID lcid, ULONG dwFlags, DATE *pDateOut) +{ + UDATE ud; + double dateVal; + + TRACE("(%p->%d/%d/%d %d:%d:%d:%d %d %d,0x%08lx,0x%08lx,%p)\n", pUdateIn, + pUdateIn->st.wMonth, pUdateIn->st.wDay, pUdateIn->st.wYear, + pUdateIn->st.wHour, pUdateIn->st.wMinute, pUdateIn->st.wSecond, + pUdateIn->st.wMilliseconds, pUdateIn->st.wDayOfWeek, + pUdateIn->wDayOfYear, lcid, dwFlags, pDateOut); + + if (lcid != MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT)) + FIXME("lcid possibly not handled, treating as en-us\n"); + + memcpy(&ud, pUdateIn, sizeof(ud)); + + if (dwFlags & VAR_VALIDDATE) + WARN("Ignoring VAR_VALIDDATE\n"); + + if (FAILED(VARIANT_RollUdate(&ud))) + return E_INVALIDARG; + + /* Date */ + dateVal = VARIANT_DateFromJulian(VARIANT_JulianFromDMY(ud.st.wYear, ud.st.wMonth, ud.st.wDay)); + + /* Time */ + dateVal += ud.st.wHour / 24.0; + dateVal += ud.st.wMinute / 1440.0; + dateVal += ud.st.wSecond / 86400.0; + dateVal += ud.st.wMilliseconds / 86400000.0; + + TRACE("Returning %g\n", dateVal); + *pDateOut = dateVal; + return S_OK; +} + +/*********************************************************************** + * VarDateFromUdate [OLEAUT32.330] + * + * Convert an unpacked format date and time to a variant VT_DATE. + * + * PARAMS + * pUdateIn [I] Unpacked format date and time to convert + * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h") + * pDateOut [O] Destination for variant VT_DATE. + * + * RETURNS + * Success: S_OK. *pDateOut contains the converted value. + * Failure: E_INVALIDARG, if pUdateIn cannot be represented in VT_DATE format. + * + * NOTES + * This function uses the United States English locale for the conversion. Use + * VarDateFromUdateEx() for alternate locales. + */ +HRESULT WINAPI VarDateFromUdate(UDATE *pUdateIn, ULONG dwFlags, DATE *pDateOut) +{ + LCID lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT); + + return VarDateFromUdateEx(pUdateIn, lcid, dwFlags, pDateOut); +} + +/*********************************************************************** + * VarUdateFromDate [OLEAUT32.331] + * + * Convert a variant VT_DATE into an unpacked format date and time. + * + * PARAMS + * datein [I] Variant VT_DATE format date + * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h") + * lpUdate [O] Destination for unpacked format date and time + * + * RETURNS + * Success: S_OK. *lpUdate contains the converted value. + * Failure: E_INVALIDARG, if dateIn is too large or small. + */ +HRESULT WINAPI VarUdateFromDate(DATE dateIn, ULONG dwFlags, UDATE *lpUdate) +{ + /* Cumulative totals of days per month */ + static const USHORT cumulativeDays[] = + { + 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 + }; + double datePart, timePart; + int julianDays; + + TRACE("(%g,0x%08lx,%p)\n", dateIn, dwFlags, lpUdate); + + if (dateIn <= (DATE_MIN - 1.0) || dateIn >= (DATE_MAX + 1.0)) + return E_INVALIDARG; + + datePart = dateIn < 0.0 ? ceil(dateIn) : floor(dateIn); + /* Compensate for int truncation (always downwards) */ + timePart = dateIn - datePart + 0.00000000001; + if (timePart >= 1.0) + timePart -= 0.00000000001; + + /* Date */ + julianDays = VARIANT_JulianFromDate(dateIn); + VARIANT_DMYFromJulian(julianDays, &lpUdate->st.wYear, &lpUdate->st.wMonth, + &lpUdate->st.wDay); + + datePart = (datePart + 1.5) / 7.0; + lpUdate->st.wDayOfWeek = (datePart - floor(datePart)) * 7; + if (lpUdate->st.wDayOfWeek == 0) + lpUdate->st.wDayOfWeek = 5; + else if (lpUdate->st.wDayOfWeek == 1) + lpUdate->st.wDayOfWeek = 6; + else + lpUdate->st.wDayOfWeek -= 2; + + if (lpUdate->st.wMonth > 2 && IsLeapYear(lpUdate->st.wYear)) + lpUdate->wDayOfYear = 1; /* After February, in a leap year */ + else + lpUdate->wDayOfYear = 0; + + lpUdate->wDayOfYear += cumulativeDays[lpUdate->st.wMonth]; + lpUdate->wDayOfYear += lpUdate->st.wDay; + + /* Time */ + timePart *= 24.0; + lpUdate->st.wHour = timePart; + timePart -= lpUdate->st.wHour; + timePart *= 60.0; + lpUdate->st.wMinute = timePart; + timePart -= lpUdate->st.wMinute; + timePart *= 60.0; + lpUdate->st.wSecond = timePart; + timePart -= lpUdate->st.wSecond; + lpUdate->st.wMilliseconds = 0; + if (timePart > 0.5) + { + /* Round the milliseconds, adjusting the time/date forward if needed */ + if (lpUdate->st.wSecond < 59) + lpUdate->st.wSecond++; + else + { + lpUdate->st.wSecond = 0; + if (lpUdate->st.wMinute < 59) + lpUdate->st.wMinute++; + else + { + lpUdate->st.wMinute = 0; + if (lpUdate->st.wHour < 23) + lpUdate->st.wHour++; + else + { + lpUdate->st.wHour = 0; + /* Roll over a whole day */ + if (++lpUdate->st.wDay > 28) + VARIANT_RollUdate(lpUdate); + } + } + } + } + return S_OK; +} + +#define GET_NUMBER_TEXT(fld,name) \ + buff[0] = 0; \ + if (!GetLocaleInfoW(lcid, lctype|fld, buff, 2)) \ + WARN("buffer too small for " #fld "\n"); \ + else \ + if (buff[0]) lpChars->name = buff[0]; \ + TRACE("lcid 0x%lx, " #name "=%d '%c'\n", lcid, lpChars->name, lpChars->name) + +/* Get the valid number characters for an lcid */ +void VARIANT_GetLocalisedNumberChars(VARIANT_NUMBER_CHARS *lpChars, LCID lcid, DWORD dwFlags) +{ + static const VARIANT_NUMBER_CHARS defaultChars = { '-','+','.',',','$',0,'.',',' }; + LCTYPE lctype = dwFlags & LOCALE_NOUSEROVERRIDE; + WCHAR buff[4]; + + memcpy(lpChars, &defaultChars, sizeof(defaultChars)); + GET_NUMBER_TEXT(LOCALE_SNEGATIVESIGN, cNegativeSymbol); + GET_NUMBER_TEXT(LOCALE_SPOSITIVESIGN, cPositiveSymbol); + GET_NUMBER_TEXT(LOCALE_SDECIMAL, cDecimalPoint); + GET_NUMBER_TEXT(LOCALE_STHOUSAND, cDigitSeperator); + GET_NUMBER_TEXT(LOCALE_SMONDECIMALSEP, cCurrencyDecimalPoint); + GET_NUMBER_TEXT(LOCALE_SMONTHOUSANDSEP, cCurrencyDigitSeperator); + + /* Local currency symbols are often 2 characters */ + lpChars->cCurrencyLocal2 = '\0'; + switch(GetLocaleInfoW(lcid, lctype|LOCALE_SCURRENCY, buff, sizeof(buff)/sizeof(WCHAR))) + { + case 3: lpChars->cCurrencyLocal2 = buff[1]; /* Fall through */ + case 2: lpChars->cCurrencyLocal = buff[0]; + break; + default: WARN("buffer too small for LOCALE_SCURRENCY\n"); + } + TRACE("lcid 0x%lx, cCurrencyLocal =%d,%d '%c','%c'\n", lcid, lpChars->cCurrencyLocal, + lpChars->cCurrencyLocal2, lpChars->cCurrencyLocal, lpChars->cCurrencyLocal2); +} + +/* Number Parsing States */ +#define B_PROCESSING_EXPONENT 0x1 +#define B_NEGATIVE_EXPONENT 0x2 +#define B_EXPONENT_START 0x4 +#define B_INEXACT_ZEROS 0x8 +#define B_LEADING_ZERO 0x10 +#define B_PROCESSING_HEX 0x20 +#define B_PROCESSING_OCT 0x40 + +/********************************************************************** + * VarParseNumFromStr [OLEAUT32.46] + * + * Parse a string containing a number into a NUMPARSE structure. + * + * PARAMS + * lpszStr [I] String to parse number from + * lcid [I] Locale Id for the conversion + * dwFlags [I] 0, or LOCALE_NOUSEROVERRIDE to use system default number chars + * pNumprs [I/O] Destination for parsed number + * rgbDig [O] Destination for digits read in + * + * RETURNS + * Success: S_OK. pNumprs and rgbDig contain the parsed representation of + * the number. + * Failure: E_INVALIDARG, if any parameter is invalid. + * DISP_E_TYPEMISMATCH, if the string is not a number or is formatted + * incorrectly. + * DISP_E_OVERFLOW, if rgbDig is too small to hold the number. + * + * NOTES + * pNumprs must have the following fields set: + * cDig: Set to the size of rgbDig. + * dwInFlags: Set to the allowable syntax of the number using NUMPRS_ flags + * from "oleauto.h". + * + * FIXME + * - I am unsure if this function should parse non-arabic (e.g. Thai) + * numerals, so this has not been implemented. + */ +HRESULT WINAPI VarParseNumFromStr(OLECHAR *lpszStr, LCID lcid, ULONG dwFlags, + NUMPARSE *pNumprs, BYTE *rgbDig) +{ + VARIANT_NUMBER_CHARS chars; + BYTE rgbTmp[1024]; + DWORD dwState = B_EXPONENT_START|B_INEXACT_ZEROS; + int iMaxDigits = sizeof(rgbTmp) / sizeof(BYTE); + int cchUsed = 0; + + TRACE("(%s,%ld,0x%08lx,%p,%p)\n", debugstr_w(lpszStr), lcid, dwFlags, pNumprs, rgbDig); + + if (!pNumprs || !rgbDig) + return E_INVALIDARG; + + if (pNumprs->cDig < iMaxDigits) + iMaxDigits = pNumprs->cDig; + + pNumprs->cDig = 0; + pNumprs->dwOutFlags = 0; + pNumprs->cchUsed = 0; + pNumprs->nBaseShift = 0; + pNumprs->nPwr10 = 0; + + if (!lpszStr) + return DISP_E_TYPEMISMATCH; + + VARIANT_GetLocalisedNumberChars(&chars, lcid, dwFlags); + + /* First consume all the leading symbols and space from the string */ + while (1) + { + if (pNumprs->dwInFlags & NUMPRS_LEADING_WHITE && isspaceW(*lpszStr)) + { + pNumprs->dwOutFlags |= NUMPRS_LEADING_WHITE; + do + { + cchUsed++; + lpszStr++; + } while (isspaceW(*lpszStr)); + } + else if (pNumprs->dwInFlags & NUMPRS_LEADING_PLUS && + *lpszStr == chars.cPositiveSymbol && + !(pNumprs->dwOutFlags & NUMPRS_LEADING_PLUS)) + { + pNumprs->dwOutFlags |= NUMPRS_LEADING_PLUS; + cchUsed++; + lpszStr++; + } + else if (pNumprs->dwInFlags & NUMPRS_LEADING_MINUS && + *lpszStr == chars.cNegativeSymbol && + !(pNumprs->dwOutFlags & NUMPRS_LEADING_MINUS)) + { + pNumprs->dwOutFlags |= (NUMPRS_LEADING_MINUS|NUMPRS_NEG); + cchUsed++; + lpszStr++; + } + else if (pNumprs->dwInFlags & NUMPRS_CURRENCY && + !(pNumprs->dwOutFlags & NUMPRS_CURRENCY) && + *lpszStr == chars.cCurrencyLocal && + (!chars.cCurrencyLocal2 || lpszStr[1] == chars.cCurrencyLocal2)) + { + pNumprs->dwOutFlags |= NUMPRS_CURRENCY; + cchUsed++; + lpszStr++; + /* Only accept currency characters */ + chars.cDecimalPoint = chars.cCurrencyDecimalPoint; + chars.cDigitSeperator = chars.cCurrencyDigitSeperator; + } + else if (pNumprs->dwInFlags & NUMPRS_PARENS && *lpszStr == '(' && + !(pNumprs->dwOutFlags & NUMPRS_PARENS)) + { + pNumprs->dwOutFlags |= NUMPRS_PARENS; + cchUsed++; + lpszStr++; + } + else + break; + } + + if (!(pNumprs->dwOutFlags & NUMPRS_CURRENCY)) + { + /* Only accept non-currency characters */ + chars.cCurrencyDecimalPoint = chars.cDecimalPoint; + chars.cCurrencyDigitSeperator = chars.cDigitSeperator; + } + + if ((*lpszStr == '&' && (*(lpszStr+1) == 'H' || *(lpszStr+1) == 'h')) && + pNumprs->dwInFlags & NUMPRS_HEX_OCT) + { + dwState |= B_PROCESSING_HEX; + pNumprs->dwOutFlags |= NUMPRS_HEX_OCT; + cchUsed=cchUsed+2; + lpszStr=lpszStr+2; + } + else if ((*lpszStr == '&' && (*(lpszStr+1) == 'O' || *(lpszStr+1) == 'o')) && + pNumprs->dwInFlags & NUMPRS_HEX_OCT) + { + dwState |= B_PROCESSING_OCT; + pNumprs->dwOutFlags |= NUMPRS_HEX_OCT; + cchUsed=cchUsed+2; + lpszStr=lpszStr+2; + } + + /* Strip Leading zeros */ + while (*lpszStr == '0') + { + dwState |= B_LEADING_ZERO; + cchUsed++; + lpszStr++; + } + + while (*lpszStr) + { + if (isdigitW(*lpszStr)) + { + if (dwState & B_PROCESSING_EXPONENT) + { + int exponentSize = 0; + if (dwState & B_EXPONENT_START) + { + if (!isdigitW(*lpszStr)) + break; /* No exponent digits - invalid */ + while (*lpszStr == '0') + { + /* Skip leading zero's in the exponent */ + cchUsed++; + lpszStr++; + } + } + + while (isdigitW(*lpszStr)) + { + exponentSize *= 10; + exponentSize += *lpszStr - '0'; + cchUsed++; + lpszStr++; + } + if (dwState & B_NEGATIVE_EXPONENT) + exponentSize = -exponentSize; + /* Add the exponent into the powers of 10 */ + pNumprs->nPwr10 += exponentSize; + dwState &= ~(B_PROCESSING_EXPONENT|B_EXPONENT_START); + lpszStr--; /* back up to allow processing of next char */ + } + else + { + if ((pNumprs->cDig >= iMaxDigits) && !(dwState & B_PROCESSING_HEX) + && !(dwState & B_PROCESSING_OCT)) + { + pNumprs->dwOutFlags |= NUMPRS_INEXACT; + + if (*lpszStr != '0') + dwState &= ~B_INEXACT_ZEROS; /* Inexact number with non-trailing zeros */ + + /* This digit can't be represented, but count it in nPwr10 */ + if (pNumprs->dwOutFlags & NUMPRS_DECIMAL) + pNumprs->nPwr10--; + else + pNumprs->nPwr10++; + } + else + { + if ((dwState & B_PROCESSING_OCT) && ((*lpszStr == '8') || (*lpszStr == '9'))) { + return DISP_E_TYPEMISMATCH; + } + + if (pNumprs->dwOutFlags & NUMPRS_DECIMAL) + pNumprs->nPwr10--; /* Count decimal points in nPwr10 */ + + rgbTmp[pNumprs->cDig] = *lpszStr - '0'; + } + pNumprs->cDig++; + cchUsed++; + } + } + else if (*lpszStr == chars.cDigitSeperator && pNumprs->dwInFlags & NUMPRS_THOUSANDS) + { + pNumprs->dwOutFlags |= NUMPRS_THOUSANDS; + cchUsed++; + } + else if (*lpszStr == chars.cDecimalPoint && + pNumprs->dwInFlags & NUMPRS_DECIMAL && + !(pNumprs->dwOutFlags & (NUMPRS_DECIMAL|NUMPRS_EXPONENT))) + { + pNumprs->dwOutFlags |= NUMPRS_DECIMAL; + cchUsed++; + + /* If we have no digits so far, skip leading zeros */ + if (!pNumprs->cDig) + { + while (lpszStr[1] == '0') + { + dwState |= B_LEADING_ZERO; + cchUsed++; + lpszStr++; + pNumprs->nPwr10--; + } + } + } + else if ((*lpszStr == 'e' || *lpszStr == 'E') && + pNumprs->dwInFlags & NUMPRS_EXPONENT && + !(pNumprs->dwOutFlags & NUMPRS_EXPONENT)) + { + dwState |= B_PROCESSING_EXPONENT; + pNumprs->dwOutFlags |= NUMPRS_EXPONENT; + cchUsed++; + } + else if (dwState & B_PROCESSING_EXPONENT && *lpszStr == chars.cPositiveSymbol) + { + cchUsed++; /* Ignore positive exponent */ + } + else if (dwState & B_PROCESSING_EXPONENT && *lpszStr == chars.cNegativeSymbol) + { + dwState |= B_NEGATIVE_EXPONENT; + cchUsed++; + } + else if (((*lpszStr >= 'a' && *lpszStr <= 'f') || + (*lpszStr >= 'A' && *lpszStr <= 'F')) && + dwState & B_PROCESSING_HEX) + { + if (pNumprs->cDig >= iMaxDigits) + { + return DISP_E_OVERFLOW; + } + else + { + if (*lpszStr >= 'a') + rgbTmp[pNumprs->cDig] = *lpszStr - 'a' + 10; + else + rgbTmp[pNumprs->cDig] = *lpszStr - 'A' + 10; + } + pNumprs->cDig++; + cchUsed++; + } + else + break; /* Stop at an unrecognised character */ + + lpszStr++; + } + + if (!pNumprs->cDig && dwState & B_LEADING_ZERO) + { + /* Ensure a 0 on its own gets stored */ + pNumprs->cDig = 1; + rgbTmp[0] = 0; + } + + if (pNumprs->dwOutFlags & NUMPRS_EXPONENT && dwState & B_PROCESSING_EXPONENT) + { + pNumprs->cchUsed = cchUsed; + return DISP_E_TYPEMISMATCH; /* Failed to completely parse the exponent */ + } + + if (pNumprs->dwOutFlags & NUMPRS_INEXACT) + { + if (dwState & B_INEXACT_ZEROS) + pNumprs->dwOutFlags &= ~NUMPRS_INEXACT; /* All zeros doesn't set NUMPRS_INEXACT */ + } else if(pNumprs->dwInFlags & NUMPRS_HEX_OCT) + { + /* copy all of the digits into the output digit buffer */ + /* this is exactly what windows does although it also returns */ + /* cDig of X and writes X+Y where Y>=0 number of digits to rgbDig */ + memcpy(rgbDig, rgbTmp, pNumprs->cDig * sizeof(BYTE)); + + if (dwState & B_PROCESSING_HEX) { + /* hex numbers have always the same format */ + pNumprs->nPwr10=0; + pNumprs->nBaseShift=4; + } else { + if (dwState & B_PROCESSING_OCT) { + /* oct numbers have always the same format */ + pNumprs->nPwr10=0; + pNumprs->nBaseShift=3; + } else { + while (pNumprs->cDig > 1 && !rgbTmp[pNumprs->cDig - 1]) + { + pNumprs->nPwr10++; + pNumprs->cDig--; + } + } + } + } else + { + /* Remove trailing zeros from the last (whole number or decimal) part */ + while (pNumprs->cDig > 1 && !rgbTmp[pNumprs->cDig - 1]) + { + pNumprs->nPwr10++; + pNumprs->cDig--; + } + } + + if (pNumprs->cDig <= iMaxDigits) + pNumprs->dwOutFlags &= ~NUMPRS_INEXACT; /* Ignore stripped zeros for NUMPRS_INEXACT */ + else + pNumprs->cDig = iMaxDigits; /* Only return iMaxDigits worth of digits */ + + /* Copy the digits we processed into rgbDig */ + memcpy(rgbDig, rgbTmp, pNumprs->cDig * sizeof(BYTE)); + + /* Consume any trailing symbols and space */ + while (1) + { + if ((pNumprs->dwInFlags & NUMPRS_TRAILING_WHITE) && isspaceW(*lpszStr)) + { + pNumprs->dwOutFlags |= NUMPRS_TRAILING_WHITE; + do + { + cchUsed++; + lpszStr++; + } while (isspaceW(*lpszStr)); + } + else if (pNumprs->dwInFlags & NUMPRS_TRAILING_PLUS && + !(pNumprs->dwOutFlags & NUMPRS_LEADING_PLUS) && + *lpszStr == chars.cPositiveSymbol) + { + pNumprs->dwOutFlags |= NUMPRS_TRAILING_PLUS; + cchUsed++; + lpszStr++; + } + else if (pNumprs->dwInFlags & NUMPRS_TRAILING_MINUS && + !(pNumprs->dwOutFlags & NUMPRS_LEADING_MINUS) && + *lpszStr == chars.cNegativeSymbol) + { + pNumprs->dwOutFlags |= (NUMPRS_TRAILING_MINUS|NUMPRS_NEG); + cchUsed++; + lpszStr++; + } + else if (pNumprs->dwInFlags & NUMPRS_PARENS && *lpszStr == ')' && + pNumprs->dwOutFlags & NUMPRS_PARENS) + { + cchUsed++; + lpszStr++; + pNumprs->dwOutFlags |= NUMPRS_NEG; + } + else + break; + } + + if (pNumprs->dwOutFlags & NUMPRS_PARENS && !(pNumprs->dwOutFlags & NUMPRS_NEG)) + { + pNumprs->cchUsed = cchUsed; + return DISP_E_TYPEMISMATCH; /* Opening parenthesis not matched */ + } + + if (pNumprs->dwInFlags & NUMPRS_USE_ALL && *lpszStr != '\0') + return DISP_E_TYPEMISMATCH; /* Not all chars were consumed */ + + if (!pNumprs->cDig) + return DISP_E_TYPEMISMATCH; /* No Number found */ + + pNumprs->cchUsed = cchUsed; + return S_OK; +} + +/* VTBIT flags indicating an integer value */ +#define INTEGER_VTBITS (VTBIT_I1|VTBIT_UI1|VTBIT_I2|VTBIT_UI2|VTBIT_I4|VTBIT_UI4|VTBIT_I8|VTBIT_UI8) +/* VTBIT flags indicating a real number value */ +#define REAL_VTBITS (VTBIT_R4|VTBIT_R8|VTBIT_CY) + +/********************************************************************** + * VarNumFromParseNum [OLEAUT32.47] + * + * Convert a NUMPARSE structure into a numeric Variant type. + * + * PARAMS + * pNumprs [I] Source for parsed number. cDig must be set to the size of rgbDig + * rgbDig [I] Source for the numbers digits + * dwVtBits [I] VTBIT_ flags from "oleauto.h" indicating the acceptable dest types + * pVarDst [O] Destination for the converted Variant value. + * + * RETURNS + * Success: S_OK. pVarDst contains the converted value. + * Failure: E_INVALIDARG, if any parameter is invalid. + * DISP_E_OVERFLOW, if the number is too big for the types set in dwVtBits. + * + * NOTES + * - The smallest favoured type present in dwVtBits that can represent the + * number in pNumprs without losing precision is used. + * - Signed types are preferrred over unsigned types of the same size. + * - Preferred types in order are: integer, float, double, currency then decimal. + * - Rounding (dropping of decimal points) occurs without error. See VarI8FromR8() + * for details of the rounding method. + * - pVarDst is not cleared before the result is stored in it. + */ +HRESULT WINAPI VarNumFromParseNum(NUMPARSE *pNumprs, BYTE *rgbDig, + ULONG dwVtBits, VARIANT *pVarDst) +{ + /* Scale factors and limits for double arithmetic */ + static const double dblMultipliers[11] = { + 1.0, 10.0, 100.0, 1000.0, 10000.0, 100000.0, + 1000000.0, 10000000.0, 100000000.0, 1000000000.0, 10000000000.0 + }; + static const double dblMinimums[11] = { + R8_MIN, R8_MIN*10.0, R8_MIN*100.0, R8_MIN*1000.0, R8_MIN*10000.0, + R8_MIN*100000.0, R8_MIN*1000000.0, R8_MIN*10000000.0, + R8_MIN*100000000.0, R8_MIN*1000000000.0, R8_MIN*10000000000.0 + }; + static const double dblMaximums[11] = { + R8_MAX, R8_MAX/10.0, R8_MAX/100.0, R8_MAX/1000.0, R8_MAX/10000.0, + R8_MAX/100000.0, R8_MAX/1000000.0, R8_MAX/10000000.0, + R8_MAX/100000000.0, R8_MAX/1000000000.0, R8_MAX/10000000000.0 + }; + + int wholeNumberDigits, fractionalDigits, divisor10 = 0, multiplier10 = 0; + + TRACE("(%p,%p,0x%lx,%p)\n", pNumprs, rgbDig, dwVtBits, pVarDst); + + if (pNumprs->nBaseShift) + { + /* nBaseShift indicates a hex or octal number */ + ULONG64 ul64 = 0; + LONG64 l64; + int i; + + /* Convert the hex or octal number string into a UI64 */ + for (i = 0; i < pNumprs->cDig; i++) + { + if (ul64 > ((UI8_MAX>>pNumprs->nBaseShift) - rgbDig[i])) + { + TRACE("Overflow multiplying digits\n"); + return DISP_E_OVERFLOW; + } + ul64 = (ul64<nBaseShift) + rgbDig[i]; + } + + /* also make a negative representation */ + l64=-ul64; + + /* Try signed and unsigned types in size order */ + if (dwVtBits & VTBIT_I1 && ((ul64 <= I1_MAX)||(l64 >= I1_MIN))) + { + V_VT(pVarDst) = VT_I1; + if (ul64 <= I1_MAX) + V_I1(pVarDst) = ul64; + else + V_I1(pVarDst) = l64; + return S_OK; + } + else if (dwVtBits & VTBIT_UI1 && ul64 <= UI1_MAX) + { + V_VT(pVarDst) = VT_UI1; + V_UI1(pVarDst) = ul64; + return S_OK; + } + else if (dwVtBits & VTBIT_I2 && ((ul64 <= I2_MAX)||(l64 >= I2_MIN))) + { + V_VT(pVarDst) = VT_I2; + if (ul64 <= I2_MAX) + V_I2(pVarDst) = ul64; + else + V_I2(pVarDst) = l64; + return S_OK; + } + else if (dwVtBits & VTBIT_UI2 && ul64 <= UI2_MAX) + { + V_VT(pVarDst) = VT_UI2; + V_UI2(pVarDst) = ul64; + return S_OK; + } + else if (dwVtBits & VTBIT_I4 && ((ul64 <= I4_MAX)||(l64 >= I4_MIN))) + { + V_VT(pVarDst) = VT_I4; + if (ul64 <= I4_MAX) + V_I4(pVarDst) = ul64; + else + V_I4(pVarDst) = l64; + return S_OK; + } + else if (dwVtBits & VTBIT_UI4 && ul64 <= UI4_MAX) + { + V_VT(pVarDst) = VT_UI4; + V_UI4(pVarDst) = ul64; + return S_OK; + } + else if (dwVtBits & VTBIT_I8 && ((ul64 <= I4_MAX)||(l64>=I4_MIN))) + { + V_VT(pVarDst) = VT_I8; + V_I8(pVarDst) = ul64; + return S_OK; + } + else if (dwVtBits & VTBIT_UI8) + { + V_VT(pVarDst) = VT_UI8; + V_UI8(pVarDst) = ul64; + return S_OK; + } + else if ((dwVtBits & REAL_VTBITS) == VTBIT_DECIMAL) + { + V_VT(pVarDst) = VT_DECIMAL; + DEC_SIGNSCALE(&V_DECIMAL(pVarDst)) = SIGNSCALE(DECIMAL_POS,0); + DEC_HI32(&V_DECIMAL(pVarDst)) = 0; + DEC_LO64(&V_DECIMAL(pVarDst)) = ul64; + return S_OK; + } + else if (dwVtBits & VTBIT_R4 && ((ul64 <= I4_MAX)||(l64 >= I4_MIN))) + { + V_VT(pVarDst) = VT_R4; + if (ul64 <= I4_MAX) + V_R4(pVarDst) = ul64; + else + V_R4(pVarDst) = l64; + return S_OK; + } + else if (dwVtBits & VTBIT_R8 && ((ul64 <= I4_MAX)||(l64 >= I4_MIN))) + { + V_VT(pVarDst) = VT_R8; + if (ul64 <= I4_MAX) + V_R8(pVarDst) = ul64; + else + V_R8(pVarDst) = l64; + return S_OK; + } + + TRACE("Overflow: possible return types: 0x%lx, value: %s\n", dwVtBits, wine_dbgstr_longlong(ul64)); + return DISP_E_OVERFLOW; + } + + /* Count the number of relevant fractional and whole digits stored, + * And compute the divisor/multiplier to scale the number by. + */ + if (pNumprs->nPwr10 < 0) + { + if (-pNumprs->nPwr10 >= pNumprs->cDig) + { + /* A real number < +/- 1.0 e.g. 0.1024 or 0.01024 */ + wholeNumberDigits = 0; + fractionalDigits = pNumprs->cDig; + divisor10 = -pNumprs->nPwr10; + } + else + { + /* An exactly represented real number e.g. 1.024 */ + wholeNumberDigits = pNumprs->cDig + pNumprs->nPwr10; + fractionalDigits = pNumprs->cDig - wholeNumberDigits; + divisor10 = pNumprs->cDig - wholeNumberDigits; + } + } + else if (pNumprs->nPwr10 == 0) + { + /* An exactly represented whole number e.g. 1024 */ + wholeNumberDigits = pNumprs->cDig; + fractionalDigits = 0; + } + else /* pNumprs->nPwr10 > 0 */ + { + /* A whole number followed by nPwr10 0's e.g. 102400 */ + wholeNumberDigits = pNumprs->cDig; + fractionalDigits = 0; + multiplier10 = pNumprs->nPwr10; + } + + TRACE("cDig %d; nPwr10 %d, whole %d, frac %d ", pNumprs->cDig, + pNumprs->nPwr10, wholeNumberDigits, fractionalDigits); + TRACE("mult %d; div %d\n", multiplier10, divisor10); + + if (dwVtBits & (INTEGER_VTBITS|VTBIT_DECIMAL) && + (!fractionalDigits || !(dwVtBits & (REAL_VTBITS|VTBIT_CY|VTBIT_DECIMAL)))) + { + /* We have one or more integer output choices, and either: + * 1) An integer input value, or + * 2) A real number input value but no floating output choices. + * Alternately, we have a DECIMAL output available and an integer input. + * + * So, place the integer value into pVarDst, using the smallest type + * possible and preferring signed over unsigned types. + */ + BOOL bOverflow = FALSE, bNegative; + ULONG64 ul64 = 0; + int i; + + /* Convert the integer part of the number into a UI8 */ + for (i = 0; i < wholeNumberDigits; i++) + { + if (ul64 > (UI8_MAX / 10 - rgbDig[i])) + { + TRACE("Overflow multiplying digits\n"); + bOverflow = TRUE; + break; + } + ul64 = ul64 * 10 + rgbDig[i]; + } + + /* Account for the scale of the number */ + if (!bOverflow && multiplier10) + { + for (i = 0; i < multiplier10; i++) + { + if (ul64 > (UI8_MAX / 10)) + { + TRACE("Overflow scaling number\n"); + bOverflow = TRUE; + break; + } + ul64 = ul64 * 10; + } + } + + /* If we have any fractional digits, round the value. + * Note we don't have to do this if divisor10 is < 1, + * because this means the fractional part must be < 0.5 + */ + if (!bOverflow && fractionalDigits && divisor10 > 0) + { + const BYTE* fracDig = rgbDig + wholeNumberDigits; + BOOL bAdjust = FALSE; + + TRACE("first decimal value is %d\n", *fracDig); + + if (*fracDig > 5) + bAdjust = TRUE; /* > 0.5 */ + else if (*fracDig == 5) + { + for (i = 1; i < fractionalDigits; i++) + { + if (fracDig[i]) + { + bAdjust = TRUE; /* > 0.5 */ + break; + } + } + /* If exactly 0.5, round only odd values */ + if (i == fractionalDigits && (ul64 & 1)) + bAdjust = TRUE; + } + + if (bAdjust) + { + if (ul64 == UI8_MAX) + { + TRACE("Overflow after rounding\n"); + bOverflow = TRUE; + } + ul64++; + } + } + + /* Zero is not a negative number */ + bNegative = pNumprs->dwOutFlags & NUMPRS_NEG && ul64 ? TRUE : FALSE; + + TRACE("Integer value is %lld, bNeg %d\n", ul64, bNegative); + + /* For negative integers, try the signed types in size order */ + if (!bOverflow && bNegative) + { + if (dwVtBits & (VTBIT_I1|VTBIT_I2|VTBIT_I4|VTBIT_I8)) + { + if (dwVtBits & VTBIT_I1 && ul64 <= -I1_MIN) + { + V_VT(pVarDst) = VT_I1; + V_I1(pVarDst) = -ul64; + return S_OK; + } + else if (dwVtBits & VTBIT_I2 && ul64 <= -I2_MIN) + { + V_VT(pVarDst) = VT_I2; + V_I2(pVarDst) = -ul64; + return S_OK; + } + else if (dwVtBits & VTBIT_I4 && ul64 <= -((LONGLONG)I4_MIN)) + { + V_VT(pVarDst) = VT_I4; + V_I4(pVarDst) = -ul64; + return S_OK; + } + else if (dwVtBits & VTBIT_I8 && ul64 <= (ULONGLONG)I8_MAX + 1) + { + V_VT(pVarDst) = VT_I8; + V_I8(pVarDst) = -ul64; + return S_OK; + } + else if ((dwVtBits & REAL_VTBITS) == VTBIT_DECIMAL) + { + /* Decimal is only output choice left - fast path */ + V_VT(pVarDst) = VT_DECIMAL; + DEC_SIGNSCALE(&V_DECIMAL(pVarDst)) = SIGNSCALE(DECIMAL_NEG,0); + DEC_HI32(&V_DECIMAL(pVarDst)) = 0; + DEC_LO64(&V_DECIMAL(pVarDst)) = -ul64; + return S_OK; + } + } + } + else if (!bOverflow) + { + /* For positive integers, try signed then unsigned types in size order */ + if (dwVtBits & VTBIT_I1 && ul64 <= I1_MAX) + { + V_VT(pVarDst) = VT_I1; + V_I1(pVarDst) = ul64; + return S_OK; + } + else if (dwVtBits & VTBIT_UI1 && ul64 <= UI1_MAX) + { + V_VT(pVarDst) = VT_UI1; + V_UI1(pVarDst) = ul64; + return S_OK; + } + else if (dwVtBits & VTBIT_I2 && ul64 <= I2_MAX) + { + V_VT(pVarDst) = VT_I2; + V_I2(pVarDst) = ul64; + return S_OK; + } + else if (dwVtBits & VTBIT_UI2 && ul64 <= UI2_MAX) + { + V_VT(pVarDst) = VT_UI2; + V_UI2(pVarDst) = ul64; + return S_OK; + } + else if (dwVtBits & VTBIT_I4 && ul64 <= I4_MAX) + { + V_VT(pVarDst) = VT_I4; + V_I4(pVarDst) = ul64; + return S_OK; + } + else if (dwVtBits & VTBIT_UI4 && ul64 <= UI4_MAX) + { + V_VT(pVarDst) = VT_UI4; + V_UI4(pVarDst) = ul64; + return S_OK; + } + else if (dwVtBits & VTBIT_I8 && ul64 <= I8_MAX) + { + V_VT(pVarDst) = VT_I8; + V_I8(pVarDst) = ul64; + return S_OK; + } + else if (dwVtBits & VTBIT_UI8) + { + V_VT(pVarDst) = VT_UI8; + V_UI8(pVarDst) = ul64; + return S_OK; + } + else if ((dwVtBits & REAL_VTBITS) == VTBIT_DECIMAL) + { + /* Decimal is only output choice left - fast path */ + V_VT(pVarDst) = VT_DECIMAL; + DEC_SIGNSCALE(&V_DECIMAL(pVarDst)) = SIGNSCALE(DECIMAL_POS,0); + DEC_HI32(&V_DECIMAL(pVarDst)) = 0; + DEC_LO64(&V_DECIMAL(pVarDst)) = ul64; + return S_OK; + } + } + } + + if (dwVtBits & REAL_VTBITS) + { + /* Try to put the number into a float or real */ + BOOL bOverflow = FALSE, bNegative = pNumprs->dwOutFlags & NUMPRS_NEG; + double whole = 0.0; + int i; + + /* Convert the number into a double */ + for (i = 0; i < pNumprs->cDig; i++) + whole = whole * 10.0 + rgbDig[i]; + + TRACE("Whole double value is %16.16g\n", whole); + + /* Account for the scale */ + while (multiplier10 > 10) + { + if (whole > dblMaximums[10]) + { + dwVtBits &= ~(VTBIT_R4|VTBIT_R8|VTBIT_CY); + bOverflow = TRUE; + break; + } + whole = whole * dblMultipliers[10]; + multiplier10 -= 10; + } + if (multiplier10) + { + if (whole > dblMaximums[multiplier10]) + { + dwVtBits &= ~(VTBIT_R4|VTBIT_R8|VTBIT_CY); + bOverflow = TRUE; + } + else + whole = whole * dblMultipliers[multiplier10]; + } + + TRACE("Scaled double value is %16.16g\n", whole); + + while (divisor10 > 10) + { + if (whole < dblMinimums[10] && whole != 0) + { + dwVtBits &= ~(VTBIT_R4|VTBIT_R8|VTBIT_CY); /* Underflow */ + bOverflow = TRUE; + break; + } + whole = whole / dblMultipliers[10]; + divisor10 -= 10; + } + if (divisor10) + { + if (whole < dblMinimums[divisor10] && whole != 0) + { + dwVtBits &= ~(VTBIT_R4|VTBIT_R8|VTBIT_CY); /* Underflow */ + bOverflow = TRUE; + } + else + whole = whole / dblMultipliers[divisor10]; + } + if (!bOverflow) + TRACE("Final double value is %16.16g\n", whole); + + if (dwVtBits & VTBIT_R4 && + ((whole <= R4_MAX && whole >= R4_MIN) || whole == 0.0)) + { + TRACE("Set R4 to final value\n"); + V_VT(pVarDst) = VT_R4; /* Fits into a float */ + V_R4(pVarDst) = pNumprs->dwOutFlags & NUMPRS_NEG ? -whole : whole; + return S_OK; + } + + if (dwVtBits & VTBIT_R8) + { + TRACE("Set R8 to final value\n"); + V_VT(pVarDst) = VT_R8; /* Fits into a double */ + V_R8(pVarDst) = pNumprs->dwOutFlags & NUMPRS_NEG ? -whole : whole; + return S_OK; + } + + if (dwVtBits & VTBIT_CY) + { + if (SUCCEEDED(VarCyFromR8(bNegative ? -whole : whole, &V_CY(pVarDst)))) + { + V_VT(pVarDst) = VT_CY; /* Fits into a currency */ + TRACE("Set CY to final value\n"); + return S_OK; + } + TRACE("Value Overflows CY\n"); + } + } + + if (dwVtBits & VTBIT_DECIMAL) + { + int i; + ULONG carry; + ULONG64 tmp; + DECIMAL* pDec = &V_DECIMAL(pVarDst); + + DECIMAL_SETZERO(*pDec); + DEC_LO32(pDec) = 0; + + if (pNumprs->dwOutFlags & NUMPRS_NEG) + DEC_SIGN(pDec) = DECIMAL_NEG; + else + DEC_SIGN(pDec) = DECIMAL_POS; + + /* Factor the significant digits */ + for (i = 0; i < pNumprs->cDig; i++) + { + tmp = (ULONG64)DEC_LO32(pDec) * 10 + rgbDig[i]; + carry = (ULONG)(tmp >> 32); + DEC_LO32(pDec) = (ULONG)(tmp & UI4_MAX); + tmp = (ULONG64)DEC_MID32(pDec) * 10 + carry; + carry = (ULONG)(tmp >> 32); + DEC_MID32(pDec) = (ULONG)(tmp & UI4_MAX); + tmp = (ULONG64)DEC_HI32(pDec) * 10 + carry; + DEC_HI32(pDec) = (ULONG)(tmp & UI4_MAX); + + if (tmp >> 32 & UI4_MAX) + { +VarNumFromParseNum_DecOverflow: + TRACE("Overflow\n"); + DEC_LO32(pDec) = DEC_MID32(pDec) = DEC_HI32(pDec) = UI4_MAX; + return DISP_E_OVERFLOW; + } + } + + /* Account for the scale of the number */ + while (multiplier10 > 0) + { + tmp = (ULONG64)DEC_LO32(pDec) * 10; + carry = (ULONG)(tmp >> 32); + DEC_LO32(pDec) = (ULONG)(tmp & UI4_MAX); + tmp = (ULONG64)DEC_MID32(pDec) * 10 + carry; + carry = (ULONG)(tmp >> 32); + DEC_MID32(pDec) = (ULONG)(tmp & UI4_MAX); + tmp = (ULONG64)DEC_HI32(pDec) * 10 + carry; + DEC_HI32(pDec) = (ULONG)(tmp & UI4_MAX); + + if (tmp >> 32 & UI4_MAX) + goto VarNumFromParseNum_DecOverflow; + multiplier10--; + } + DEC_SCALE(pDec) = divisor10; + + V_VT(pVarDst) = VT_DECIMAL; + return S_OK; + } + return DISP_E_OVERFLOW; /* No more output choices */ +} + +/********************************************************************** + * VarCat [OLEAUT32.318] + */ +HRESULT WINAPI VarCat(LPVARIANT left, LPVARIANT right, LPVARIANT out) +{ + TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left), + debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), out); + + /* Should we VariantClear out? */ + /* Can we handle array, vector, by ref etc. */ + if ((V_VT(left)&VT_TYPEMASK) == VT_NULL && + (V_VT(right)&VT_TYPEMASK) == VT_NULL) + { + V_VT(out) = VT_NULL; + return S_OK; + } + + if (V_VT(left) == VT_BSTR && V_VT(right) == VT_BSTR) + { + V_VT(out) = VT_BSTR; + VarBstrCat (V_BSTR(left), V_BSTR(right), &V_BSTR(out)); + return S_OK; + } + if (V_VT(left) == VT_BSTR) { + VARIANT bstrvar; + HRESULT hres; + + V_VT(out) = VT_BSTR; + hres = VariantChangeTypeEx(&bstrvar,right,0,0,VT_BSTR); + if (hres) { + FIXME("Failed to convert right side from vt %d to VT_BSTR?\n",V_VT(right)); + return hres; + } + VarBstrCat (V_BSTR(left), V_BSTR(&bstrvar), &V_BSTR(out)); + return S_OK; + } + if (V_VT(right) == VT_BSTR) { + VARIANT bstrvar; + HRESULT hres; + + V_VT(out) = VT_BSTR; + hres = VariantChangeTypeEx(&bstrvar,left,0,0,VT_BSTR); + if (hres) { + FIXME("Failed to convert right side from vt %d to VT_BSTR?\n",V_VT(right)); + return hres; + } + VarBstrCat (V_BSTR(&bstrvar), V_BSTR(right), &V_BSTR(out)); + return S_OK; + } + FIXME ("types %d / %d not supported\n",V_VT(left)&VT_TYPEMASK, V_VT(right)&VT_TYPEMASK); + return S_OK; +} + +/********************************************************************** + * VarCmp [OLEAUT32.176] + * + * flags can be: + * NORM_IGNORECASE, NORM_IGNORENONSPACE, NORM_IGNORESYMBOLS + * NORM_IGNOREWIDTH, NORM_IGNOREKANATYPE, NORM_IGNOREKASHIDA + * + */ +HRESULT WINAPI VarCmp(LPVARIANT left, LPVARIANT right, LCID lcid, DWORD flags) +{ + BOOL lOk = TRUE; + BOOL rOk = TRUE; + LONGLONG lVal = -1; + LONGLONG rVal = -1; + VARIANT rv,lv; + DWORD xmask; + HRESULT rc; + + TRACE("(%p->(%s%s),%p->(%s%s),0x%08lx,0x%08lx)\n", left, debugstr_VT(left), + debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), lcid, flags); + + VariantInit(&lv);VariantInit(&rv); + V_VT(right) &= ~0x8000; /* hack since we sometime get this flag. */ + V_VT(left) &= ~0x8000; /* hack since we sometime get this flag. */ + + /* If either are null, then return VARCMP_NULL */ + if ((V_VT(left)&VT_TYPEMASK) == VT_NULL || + (V_VT(right)&VT_TYPEMASK) == VT_NULL) + return VARCMP_NULL; + + /* Strings - use VarBstrCmp */ + if ((V_VT(left)&VT_TYPEMASK) == VT_BSTR && + (V_VT(right)&VT_TYPEMASK) == VT_BSTR) { + return VarBstrCmp(V_BSTR(left), V_BSTR(right), lcid, flags); + } + + xmask = (1<<(V_VT(left)&VT_TYPEMASK))|(1<<(V_VT(right)&VT_TYPEMASK)); + if (xmask & (1< V_R8(&rv)) return VARCMP_GT; + return E_FAIL; /* can't get here */ + } + if (xmask & (1< V_R4(&rv)) return VARCMP_GT; + return E_FAIL; /* can't get here */ + } + + /* Integers - Ideally like to use VarDecCmp, but no Dec support yet + Use LONGLONG to maximize ranges */ + lOk = TRUE; + switch (V_VT(left)&VT_TYPEMASK) { + case VT_I1 : lVal = V_UNION(left,cVal); break; + case VT_I2 : lVal = V_UNION(left,iVal); break; + case VT_I4 : lVal = V_UNION(left,lVal); break; + case VT_INT : lVal = V_UNION(left,lVal); break; + case VT_UI1 : lVal = V_UNION(left,bVal); break; + case VT_UI2 : lVal = V_UNION(left,uiVal); break; + case VT_UI4 : lVal = V_UNION(left,ulVal); break; + case VT_UINT : lVal = V_UNION(left,ulVal); break; + case VT_BOOL : lVal = V_UNION(left,boolVal); break; + default: lOk = FALSE; + } + + rOk = TRUE; + switch (V_VT(right)&VT_TYPEMASK) { + case VT_I1 : rVal = V_UNION(right,cVal); break; + case VT_I2 : rVal = V_UNION(right,iVal); break; + case VT_I4 : rVal = V_UNION(right,lVal); break; + case VT_INT : rVal = V_UNION(right,lVal); break; + case VT_UI1 : rVal = V_UNION(right,bVal); break; + case VT_UI2 : rVal = V_UNION(right,uiVal); break; + case VT_UI4 : rVal = V_UNION(right,ulVal); break; + case VT_UINT : rVal = V_UNION(right,ulVal); break; + case VT_BOOL : rVal = V_UNION(right,boolVal); break; + default: rOk = FALSE; + } + + if (lOk && rOk) { + if (lVal < rVal) { + return VARCMP_LT; + } else if (lVal > rVal) { + return VARCMP_GT; + } else { + return VARCMP_EQ; + } + } + + /* Strings - use VarBstrCmp */ + if ((V_VT(left)&VT_TYPEMASK) == VT_DATE && + (V_VT(right)&VT_TYPEMASK) == VT_DATE) { + + if (floor(V_UNION(left,date)) == floor(V_UNION(right,date))) { + /* Due to floating point rounding errors, calculate varDate in whole numbers) */ + double wholePart = 0.0; + double leftR; + double rightR; + + /* Get the fraction * 24*60*60 to make it into whole seconds */ + wholePart = (double) floor( V_UNION(left,date) ); + if (wholePart == 0) wholePart = 1; + leftR = floor(fmod( V_UNION(left,date), wholePart ) * (24*60*60)); + + wholePart = (double) floor( V_UNION(right,date) ); + if (wholePart == 0) wholePart = 1; + rightR = floor(fmod( V_UNION(right,date), wholePart ) * (24*60*60)); + + if (leftR < rightR) { + return VARCMP_LT; + } else if (leftR > rightR) { + return VARCMP_GT; + } else { + return VARCMP_EQ; + } + + } else if (V_UNION(left,date) < V_UNION(right,date)) { + return VARCMP_LT; + } else if (V_UNION(left,date) > V_UNION(right,date)) { + return VARCMP_GT; + } + } + FIXME("VarCmp partial implementation, doesn't support vt 0x%x / 0x%x\n",V_VT(left), V_VT(right)); + return E_FAIL; +} + +/********************************************************************** + * VarAnd [OLEAUT32.142] + * + */ +HRESULT WINAPI VarAnd(LPVARIANT left, LPVARIANT right, LPVARIANT result) +{ + HRESULT rc = E_FAIL; + + TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left), + debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), result); + + if ((V_VT(left)&VT_TYPEMASK) == VT_BOOL && + (V_VT(right)&VT_TYPEMASK) == VT_BOOL) { + + V_VT(result) = VT_BOOL; + if (V_BOOL(left) && V_BOOL(right)) { + V_BOOL(result) = VARIANT_TRUE; + } else { + V_BOOL(result) = VARIANT_FALSE; + } + rc = S_OK; + + } else { + /* Integers */ + BOOL lOk = TRUE; + BOOL rOk = TRUE; + LONGLONG lVal = -1; + LONGLONG rVal = -1; + LONGLONG res = -1; + int resT = 0; /* Testing has shown I2 & I2 == I2, all else + becomes I4, even unsigned ints (incl. UI2) */ + + lOk = TRUE; + switch (V_VT(left)&VT_TYPEMASK) { + case VT_I1 : lVal = V_UNION(left,cVal); resT=VT_I4; break; + case VT_I2 : lVal = V_UNION(left,iVal); resT=VT_I2; break; + case VT_I4 : lVal = V_UNION(left,lVal); resT=VT_I4; break; + case VT_INT : lVal = V_UNION(left,lVal); resT=VT_I4; break; + case VT_UI1 : lVal = V_UNION(left,bVal); resT=VT_I4; break; + case VT_UI2 : lVal = V_UNION(left,uiVal); resT=VT_I4; break; + case VT_UI4 : lVal = V_UNION(left,ulVal); resT=VT_I4; break; + case VT_UINT : lVal = V_UNION(left,ulVal); resT=VT_I4; break; + case VT_BOOL : rVal = V_UNION(left,boolVal); resT=VT_I4; break; + default: lOk = FALSE; + } + + rOk = TRUE; + switch (V_VT(right)&VT_TYPEMASK) { + case VT_I1 : rVal = V_UNION(right,cVal); resT=VT_I4; break; + case VT_I2 : rVal = V_UNION(right,iVal); resT=max(VT_I2, resT); break; + case VT_I4 : rVal = V_UNION(right,lVal); resT=VT_I4; break; + case VT_INT : rVal = V_UNION(right,lVal); resT=VT_I4; break; + case VT_UI1 : rVal = V_UNION(right,bVal); resT=VT_I4; break; + case VT_UI2 : rVal = V_UNION(right,uiVal); resT=VT_I4; break; + case VT_UI4 : rVal = V_UNION(right,ulVal); resT=VT_I4; break; + case VT_UINT : rVal = V_UNION(right,ulVal); resT=VT_I4; break; + case VT_BOOL : rVal = V_UNION(right,boolVal); resT=VT_I4; break; + default: rOk = FALSE; + } + + if (lOk && rOk) { + res = (lVal & rVal); + V_VT(result) = resT; + switch (resT) { + case VT_I2 : V_UNION(result,iVal) = res; break; + case VT_I4 : V_UNION(result,lVal) = res; break; + default: + FIXME("Unexpected result variant type %x\n", resT); + V_UNION(result,lVal) = res; + } + rc = S_OK; + + } else { + FIXME("VarAnd stub\n"); + } + } + + TRACE("returning 0x%8lx (%s%s),%ld\n", rc, debugstr_VT(result), + debugstr_VF(result), V_VT(result) == VT_I4 ? V_I4(result) : V_I2(result)); + return rc; +} + +/********************************************************************** + * VarAdd [OLEAUT32.141] + * FIXME: From MSDN: If ... Then + * Both expressions are of the string type Concatenated. + * One expression is a string type and the other a character Addition. + * One expression is numeric and the other is a string Addition. + * Both expressions are numeric Addition. + * Either expression is NULL NULL is returned. + * Both expressions are empty Integer subtype is returned. + * + */ +HRESULT WINAPI VarAdd(LPVARIANT left, LPVARIANT right, LPVARIANT result) +{ + HRESULT rc = E_FAIL; + + TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left), + debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), result); + + if ((V_VT(left)&VT_TYPEMASK) == VT_EMPTY) + return VariantCopy(result,right); + + if ((V_VT(right)&VT_TYPEMASK) == VT_EMPTY) + return VariantCopy(result,left); + + /* check if we add doubles */ + if (((V_VT(left)&VT_TYPEMASK) == VT_R8) || ((V_VT(right)&VT_TYPEMASK) == VT_R8)) { + BOOL lOk = TRUE; + BOOL rOk = TRUE; + double lVal = -1; + double rVal = -1; + double res = -1; + + lOk = TRUE; + switch (V_VT(left)&VT_TYPEMASK) { + case VT_I1 : lVal = V_UNION(left,cVal); break; + case VT_I2 : lVal = V_UNION(left,iVal); break; + case VT_I4 : lVal = V_UNION(left,lVal); break; + case VT_INT : lVal = V_UNION(left,lVal); break; + case VT_UI1 : lVal = V_UNION(left,bVal); break; + case VT_UI2 : lVal = V_UNION(left,uiVal); break; + case VT_UI4 : lVal = V_UNION(left,ulVal); break; + case VT_UINT : lVal = V_UNION(left,ulVal); break; + case VT_R4 : lVal = V_UNION(left,fltVal); break; + case VT_R8 : lVal = V_UNION(left,dblVal); break; + case VT_NULL : lVal = 0.0; break; + default: lOk = FALSE; + } + + rOk = TRUE; + switch (V_VT(right)&VT_TYPEMASK) { + case VT_I1 : rVal = V_UNION(right,cVal); break; + case VT_I2 : rVal = V_UNION(right,iVal); break; + case VT_I4 : rVal = V_UNION(right,lVal); break; + case VT_INT : rVal = V_UNION(right,lVal); break; + case VT_UI1 : rVal = V_UNION(right,bVal); break; + case VT_UI2 : rVal = V_UNION(right,uiVal); break; + case VT_UI4 : rVal = V_UNION(right,ulVal); break; + case VT_UINT : rVal = V_UNION(right,ulVal); break; + case VT_R4 : rVal = V_UNION(right,fltVal);break; + case VT_R8 : rVal = V_UNION(right,dblVal);break; + case VT_NULL : rVal = 0.0; break; + default: rOk = FALSE; + } + + if (lOk && rOk) { + res = (lVal + rVal); + V_VT(result) = VT_R8; + V_UNION(result,dblVal) = res; + rc = S_OK; + } else { + FIXME("Unhandled type pair %d / %d in double addition.\n", + (V_VT(left)&VT_TYPEMASK), + (V_VT(right)&VT_TYPEMASK) + ); + } + return rc; + } + + /* now check if we add floats. VT_R8 can no longer happen here! */ + if (((V_VT(left)&VT_TYPEMASK) == VT_R4) || ((V_VT(right)&VT_TYPEMASK) == VT_R4)) { + BOOL lOk = TRUE; + BOOL rOk = TRUE; + float lVal = -1; + float rVal = -1; + float res = -1; + + lOk = TRUE; + switch (V_VT(left)&VT_TYPEMASK) { + case VT_I1 : lVal = V_UNION(left,cVal); break; + case VT_I2 : lVal = V_UNION(left,iVal); break; + case VT_I4 : lVal = V_UNION(left,lVal); break; + case VT_INT : lVal = V_UNION(left,lVal); break; + case VT_UI1 : lVal = V_UNION(left,bVal); break; + case VT_UI2 : lVal = V_UNION(left,uiVal); break; + case VT_UI4 : lVal = V_UNION(left,ulVal); break; + case VT_UINT : lVal = V_UNION(left,ulVal); break; + case VT_R4 : lVal = V_UNION(left,fltVal); break; + case VT_NULL : lVal = 0.0; break; + default: lOk = FALSE; + } + + rOk = TRUE; + switch (V_VT(right)&VT_TYPEMASK) { + case VT_I1 : rVal = V_UNION(right,cVal); break; + case VT_I2 : rVal = V_UNION(right,iVal); break; + case VT_I4 : rVal = V_UNION(right,lVal); break; + case VT_INT : rVal = V_UNION(right,lVal); break; + case VT_UI1 : rVal = V_UNION(right,bVal); break; + case VT_UI2 : rVal = V_UNION(right,uiVal); break; + case VT_UI4 : rVal = V_UNION(right,ulVal); break; + case VT_UINT : rVal = V_UNION(right,ulVal); break; + case VT_R4 : rVal = V_UNION(right,fltVal);break; + case VT_NULL : rVal = 0.0; break; + default: rOk = FALSE; + } + + if (lOk && rOk) { + res = (lVal + rVal); + V_VT(result) = VT_R4; + V_UNION(result,fltVal) = res; + rc = S_OK; + } else { + FIXME("Unhandled type pair %d / %d in float addition.\n", + (V_VT(left)&VT_TYPEMASK), + (V_VT(right)&VT_TYPEMASK) + ); + } + return rc; + } + + /* Handle strings as concat */ + if ((V_VT(left)&VT_TYPEMASK) == VT_BSTR && + (V_VT(right)&VT_TYPEMASK) == VT_BSTR) { + V_VT(result) = VT_BSTR; + return VarBstrCat(V_BSTR(left), V_BSTR(right), &V_BSTR(result)); + } else { + + /* Integers */ + BOOL lOk = TRUE; + BOOL rOk = TRUE; + LONGLONG lVal = -1; + LONGLONG rVal = -1; + LONGLONG res = -1; + int resT = 0; /* Testing has shown I2 + I2 == I2, all else + becomes I4 */ + + lOk = TRUE; + switch (V_VT(left)&VT_TYPEMASK) { + case VT_I1 : lVal = V_UNION(left,cVal); resT=VT_I4; break; + case VT_I2 : lVal = V_UNION(left,iVal); resT=VT_I2; break; + case VT_I4 : lVal = V_UNION(left,lVal); resT=VT_I4; break; + case VT_INT : lVal = V_UNION(left,lVal); resT=VT_I4; break; + case VT_UI1 : lVal = V_UNION(left,bVal); resT=VT_I4; break; + case VT_UI2 : lVal = V_UNION(left,uiVal); resT=VT_I4; break; + case VT_UI4 : lVal = V_UNION(left,ulVal); resT=VT_I4; break; + case VT_UINT : lVal = V_UNION(left,ulVal); resT=VT_I4; break; + case VT_NULL : lVal = 0; resT = VT_I4; break; + default: lOk = FALSE; + } + + rOk = TRUE; + switch (V_VT(right)&VT_TYPEMASK) { + case VT_I1 : rVal = V_UNION(right,cVal); resT=VT_I4; break; + case VT_I2 : rVal = V_UNION(right,iVal); resT=max(VT_I2, resT); break; + case VT_I4 : rVal = V_UNION(right,lVal); resT=VT_I4; break; + case VT_INT : rVal = V_UNION(right,lVal); resT=VT_I4; break; + case VT_UI1 : rVal = V_UNION(right,bVal); resT=VT_I4; break; + case VT_UI2 : rVal = V_UNION(right,uiVal); resT=VT_I4; break; + case VT_UI4 : rVal = V_UNION(right,ulVal); resT=VT_I4; break; + case VT_UINT : rVal = V_UNION(right,ulVal); resT=VT_I4; break; + case VT_NULL : rVal = 0; resT=VT_I4; break; + default: rOk = FALSE; + } + + if (lOk && rOk) { + res = (lVal + rVal); + V_VT(result) = resT; + switch (resT) { + case VT_I2 : V_UNION(result,iVal) = res; break; + case VT_I4 : V_UNION(result,lVal) = res; break; + default: + FIXME("Unexpected result variant type %x\n", resT); + V_UNION(result,lVal) = res; + } + rc = S_OK; + + } else { + FIXME("unimplemented part (0x%x + 0x%x)\n",V_VT(left), V_VT(right)); + } + } + + TRACE("returning 0x%8lx (%s%s),%ld\n", rc, debugstr_VT(result), + debugstr_VF(result), V_VT(result) == VT_I4 ? V_I4(result) : V_I2(result)); + return rc; +} + +/********************************************************************** + * VarMul [OLEAUT32.156] + * + */ +HRESULT WINAPI VarMul(LPVARIANT left, LPVARIANT right, LPVARIANT result) +{ + HRESULT rc = E_FAIL; + VARTYPE lvt,rvt,resvt; + VARIANT lv,rv; + BOOL found; + + TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left), + debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), result); + + VariantInit(&lv);VariantInit(&rv); + lvt = V_VT(left)&VT_TYPEMASK; + rvt = V_VT(right)&VT_TYPEMASK; + found = FALSE;resvt=VT_VOID; + if (((1<(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left), + debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), result); + + VariantInit(&lv);VariantInit(&rv); + lvt = V_VT(left)&VT_TYPEMASK; + rvt = V_VT(right)&VT_TYPEMASK; + found = FALSE;resvt = VT_VOID; + if (((1<(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left), + debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), result); + + VariantInit(&lv);VariantInit(&rv); + lvt = V_VT(left)&VT_TYPEMASK; + rvt = V_VT(right)&VT_TYPEMASK; + found = FALSE;resvt = VT_VOID; + if (((1<(%s%s),%p->(%s%s),%p)\n", pVarLeft, debugstr_VT(pVarLeft), + debugstr_VF(pVarLeft), pVarRight, debugstr_VT(pVarRight), + debugstr_VF(pVarRight), pVarOut); + + if (V_EXTRA_TYPE(pVarLeft) || V_EXTRA_TYPE(pVarRight) || + V_VT(pVarLeft) == VT_UNKNOWN || V_VT(pVarRight) == VT_UNKNOWN || + V_VT(pVarLeft) == VT_DISPATCH || V_VT(pVarRight) == VT_DISPATCH || + V_VT(pVarLeft) == VT_RECORD || V_VT(pVarRight) == VT_RECORD) + return DISP_E_BADVARTYPE; + + V_VT(&varLeft) = V_VT(&varRight) = V_VT(&varStr) = VT_EMPTY; + + if (V_VT(pVarLeft) == VT_NULL || V_VT(pVarRight) == VT_NULL) + { + /* NULL OR Zero is NULL, NULL OR value is value */ + if (V_VT(pVarLeft) == VT_NULL) + pVarLeft = pVarRight; /* point to the non-NULL var */ + + V_VT(pVarOut) = VT_NULL; + V_I4(pVarOut) = 0; + + switch (V_VT(pVarLeft)) + { + case VT_DATE: case VT_R8: + if (V_R8(pVarLeft)) + goto VarOr_AsEmpty; + return S_OK; + case VT_BOOL: + if (V_BOOL(pVarLeft)) + *pVarOut = *pVarLeft; + return S_OK; + case VT_I2: case VT_UI2: + if (V_I2(pVarLeft)) + goto VarOr_AsEmpty; + return S_OK; + case VT_I1: + if (V_I1(pVarLeft)) + goto VarOr_AsEmpty; + return S_OK; + case VT_UI1: + if (V_UI1(pVarLeft)) + *pVarOut = *pVarLeft; + return S_OK; + case VT_R4: + if (V_R4(pVarLeft)) + goto VarOr_AsEmpty; + return S_OK; + case VT_I4: case VT_UI4: case VT_INT: case VT_UINT: + if (V_I4(pVarLeft)) + goto VarOr_AsEmpty; + return S_OK; + case VT_CY: + if (V_CY(pVarLeft).int64) + goto VarOr_AsEmpty; + return S_OK; + case VT_I8: case VT_UI8: + if (V_I8(pVarLeft)) + goto VarOr_AsEmpty; + return S_OK; + case VT_DECIMAL: + if (DEC_HI32(&V_DECIMAL(pVarLeft)) || DEC_LO64(&V_DECIMAL(pVarLeft))) + goto VarOr_AsEmpty; + return S_OK; + case VT_BSTR: + { + VARIANT_BOOL b; + + if (!V_BSTR(pVarLeft)) + return DISP_E_BADVARTYPE; + + hRet = VarBoolFromStr(V_BSTR(pVarLeft), LOCALE_USER_DEFAULT, VAR_LOCALBOOL, &b); + if (SUCCEEDED(hRet) && b) + { + V_VT(pVarOut) = VT_BOOL; + V_BOOL(pVarOut) = b; + } + return hRet; + } + case VT_NULL: case VT_EMPTY: + V_VT(pVarOut) = VT_NULL; + return S_OK; + default: + return DISP_E_BADVARTYPE; + } + } + + if (V_VT(pVarLeft) == VT_EMPTY || V_VT(pVarRight) == VT_EMPTY) + { + if (V_VT(pVarLeft) == VT_EMPTY) + pVarLeft = pVarRight; /* point to the non-EMPTY var */ + +VarOr_AsEmpty: + /* Since one argument is empty (0), OR'ing it with the other simply + * gives the others value (as 0|x => x). So just convert the other + * argument to the required result type. + */ + switch (V_VT(pVarLeft)) + { + case VT_BSTR: + if (!V_BSTR(pVarLeft)) + return DISP_E_BADVARTYPE; + + hRet = VariantCopy(&varStr, pVarLeft); + if (FAILED(hRet)) + goto VarOr_Exit; + pVarLeft = &varStr; + hRet = VariantChangeType(pVarLeft, pVarLeft, 0, VT_BOOL); + if (FAILED(hRet)) + goto VarOr_Exit; + /* Fall Through ... */ + case VT_EMPTY: case VT_UI1: case VT_BOOL: case VT_I2: + V_VT(pVarOut) = VT_I2; + break; + case VT_DATE: case VT_CY: case VT_DECIMAL: case VT_R4: case VT_R8: + case VT_I1: case VT_UI2: case VT_I4: case VT_UI4: + case VT_INT: case VT_UINT: case VT_UI8: + V_VT(pVarOut) = VT_I4; + break; + case VT_I8: + V_VT(pVarOut) = VT_I8; + break; + default: + return DISP_E_BADVARTYPE; + } + hRet = VariantCopy(&varLeft, pVarLeft); + if (FAILED(hRet)) + goto VarOr_Exit; + pVarLeft = &varLeft; + hRet = VariantChangeType(pVarOut, pVarLeft, 0, V_VT(pVarOut)); + goto VarOr_Exit; + } + + if (V_VT(pVarLeft) == VT_BOOL && V_VT(pVarRight) == VT_BOOL) + { + V_VT(pVarOut) = VT_BOOL; + V_BOOL(pVarOut) = V_BOOL(pVarLeft) | V_BOOL(pVarRight); + return S_OK; + } + + if (V_VT(pVarLeft) == VT_UI1 && V_VT(pVarRight) == VT_UI1) + { + V_VT(pVarOut) = VT_UI1; + V_UI1(pVarOut) = V_UI1(pVarLeft) | V_UI1(pVarRight); + return S_OK; + } + + if (V_VT(pVarLeft) == VT_BSTR) + { + hRet = VariantCopy(&varStr, pVarLeft); + if (FAILED(hRet)) + goto VarOr_Exit; + pVarLeft = &varStr; + hRet = VariantChangeType(pVarLeft, pVarLeft, 0, VT_BOOL); + if (FAILED(hRet)) + goto VarOr_Exit; + } + + if (V_VT(pVarLeft) == VT_BOOL && + (V_VT(pVarRight) == VT_BOOL || V_VT(pVarRight) == VT_BSTR)) + { + vt = VT_BOOL; + } + else if ((V_VT(pVarLeft) == VT_BOOL || V_VT(pVarLeft) == VT_UI1 || + V_VT(pVarLeft) == VT_I2 || V_VT(pVarLeft) == VT_BSTR) && + (V_VT(pVarRight) == VT_BOOL || V_VT(pVarRight) == VT_UI1 || + V_VT(pVarRight) == VT_I2 || V_VT(pVarRight) == VT_BSTR)) + { + vt = VT_I2; + } + else if (V_VT(pVarLeft) == VT_I8 || V_VT(pVarRight) == VT_I8) + { + if (V_VT(pVarLeft) == VT_INT || V_VT(pVarRight) == VT_INT) + return DISP_E_TYPEMISMATCH; + vt = VT_I8; + } + + hRet = VariantCopy(&varLeft, pVarLeft); + if (FAILED(hRet)) + goto VarOr_Exit; + + hRet = VariantCopy(&varRight, pVarRight); + if (FAILED(hRet)) + goto VarOr_Exit; + + if (vt == VT_I4 && V_VT(&varLeft) == VT_UI4) + V_VT(&varLeft) = VT_I4; /* Don't overflow */ + else + { + double d; + + if (V_VT(&varLeft) == VT_BSTR && + FAILED(VarR8FromStr(V_BSTR(&varLeft), LOCALE_USER_DEFAULT, 0, &d))) + hRet = VariantChangeType(&varLeft, &varLeft, VARIANT_LOCALBOOL, VT_BOOL); + if (SUCCEEDED(hRet) && V_VT(&varLeft) != vt) + hRet = VariantChangeType(&varLeft, &varLeft, 0, vt); + if (FAILED(hRet)) + goto VarOr_Exit; + } + + if (vt == VT_I4 && V_VT(&varRight) == VT_UI4) + V_VT(&varRight) = VT_I4; /* Don't overflow */ + else + { + double d; + + if (V_VT(&varRight) == VT_BSTR && + FAILED(VarR8FromStr(V_BSTR(&varRight), LOCALE_USER_DEFAULT, 0, &d))) + hRet = VariantChangeType(&varRight, &varRight, VARIANT_LOCALBOOL, VT_BOOL); + if (SUCCEEDED(hRet) && V_VT(&varRight) != vt) + hRet = VariantChangeType(&varRight, &varRight, 0, vt); + if (FAILED(hRet)) + goto VarOr_Exit; + } + + V_VT(pVarOut) = vt; + if (vt == VT_I8) + { + V_I8(pVarOut) = V_I8(&varLeft) | V_I8(&varRight); + } + else if (vt == VT_I4) + { + V_I4(pVarOut) = V_I4(&varLeft) | V_I4(&varRight); + } + else + { + V_I2(pVarOut) = V_I2(&varLeft) | V_I2(&varRight); + } + +VarOr_Exit: + VariantClear(&varStr); + VariantClear(&varLeft); + VariantClear(&varRight); + return hRet; +} + +/********************************************************************** + * VarAbs [OLEAUT32.168] + * + * Convert a variant to its absolute value. + * + * PARAMS + * pVarIn [I] Source variant + * pVarOut [O] Destination for converted value + * + * RETURNS + * Success: S_OK. pVarOut contains the absolute value of pVarIn. + * Failure: An HRESULT error code indicating the error. + * + * NOTES + * - This function does not process by-reference variants. + * - The type of the value stored in pVarOut depends on the type of pVarIn, + * according to the following table: + *| Input Type Output Type + *| ---------- ----------- + *| VT_BOOL VT_I2 + *| VT_BSTR VT_R8 + *| (All others) Unchanged + */ +HRESULT WINAPI VarAbs(LPVARIANT pVarIn, LPVARIANT pVarOut) +{ + VARIANT varIn; + HRESULT hRet = S_OK; + + TRACE("(%p->(%s%s),%p)\n", pVarIn, debugstr_VT(pVarIn), + debugstr_VF(pVarIn), pVarOut); + + if (V_ISARRAY(pVarIn) || V_VT(pVarIn) == VT_UNKNOWN || + V_VT(pVarIn) == VT_DISPATCH || V_VT(pVarIn) == VT_RECORD || + V_VT(pVarIn) == VT_ERROR) + return DISP_E_TYPEMISMATCH; + + *pVarOut = *pVarIn; /* Shallow copy the value, and invert it if needed */ + +#define ABS_CASE(typ,min) \ + case VT_##typ: if (V_##typ(pVarIn) == min) hRet = DISP_E_OVERFLOW; \ + else if (V_##typ(pVarIn) < 0) V_##typ(pVarOut) = -V_##typ(pVarIn); \ + break + + switch (V_VT(pVarIn)) + { + ABS_CASE(I1,I1_MIN); + case VT_BOOL: + V_VT(pVarOut) = VT_I2; + /* BOOL->I2, Fall through ... */ + ABS_CASE(I2,I2_MIN); + case VT_INT: + ABS_CASE(I4,I4_MIN); + ABS_CASE(I8,I8_MIN); + ABS_CASE(R4,R4_MIN); + case VT_BSTR: + hRet = VarR8FromStr(V_BSTR(pVarIn), LOCALE_USER_DEFAULT, 0, &V_R8(&varIn)); + if (FAILED(hRet)) + break; + V_VT(pVarOut) = VT_R8; + pVarIn = &varIn; + /* Fall through ... */ + case VT_DATE: + ABS_CASE(R8,R8_MIN); + case VT_CY: + hRet = VarCyAbs(V_CY(pVarIn), & V_CY(pVarOut)); + break; + case VT_DECIMAL: + DEC_SIGN(&V_DECIMAL(pVarOut)) &= ~DECIMAL_NEG; + break; + case VT_UI1: + case VT_UI2: + case VT_UINT: + case VT_UI4: + case VT_UI8: + /* No-Op */ + break; + case VT_EMPTY: + V_VT(pVarOut) = VT_I2; + case VT_NULL: + V_I2(pVarOut) = 0; + break; + default: + hRet = DISP_E_BADVARTYPE; + } + + return hRet; +} + +/********************************************************************** + * VarFix [OLEAUT32.169] + * + * Truncate a variants value to a whole number. + * + * PARAMS + * pVarIn [I] Source variant + * pVarOut [O] Destination for converted value + * + * RETURNS + * Success: S_OK. pVarOut contains the converted value. + * Failure: An HRESULT error code indicating the error. + * + * NOTES + * - The type of the value stored in pVarOut depends on the type of pVarIn, + * according to the following table: + *| Input Type Output Type + *| ---------- ----------- + *| VT_BOOL VT_I2 + *| VT_EMPTY VT_I2 + *| VT_BSTR VT_R8 + *| All Others Unchanged + * - The difference between this function and VarInt() is that VarInt() rounds + * negative numbers away from 0, while this function rounds them towards zero. + */ +HRESULT WINAPI VarFix(LPVARIANT pVarIn, LPVARIANT pVarOut) +{ + HRESULT hRet = S_OK; + + TRACE("(%p->(%s%s),%p)\n", pVarIn, debugstr_VT(pVarIn), + debugstr_VF(pVarIn), pVarOut); + + V_VT(pVarOut) = V_VT(pVarIn); + + switch (V_VT(pVarIn)) + { + case VT_UI1: + V_UI1(pVarOut) = V_UI1(pVarIn); + break; + case VT_BOOL: + V_VT(pVarOut) = VT_I2; + /* Fall through */ + case VT_I2: + V_I2(pVarOut) = V_I2(pVarIn); + break; + case VT_I4: + V_I4(pVarOut) = V_I4(pVarIn); + break; + case VT_I8: + V_I8(pVarOut) = V_I8(pVarIn); + break; + case VT_R4: + if (V_R4(pVarIn) < 0.0f) + V_R4(pVarOut) = (float)ceil(V_R4(pVarIn)); + else + V_R4(pVarOut) = (float)floor(V_R4(pVarIn)); + break; + case VT_BSTR: + V_VT(pVarOut) = VT_R8; + hRet = VarR8FromStr(V_BSTR(pVarIn), LOCALE_USER_DEFAULT, 0, &V_R8(pVarOut)); + pVarIn = pVarOut; + /* Fall through */ + case VT_DATE: + case VT_R8: + if (V_R8(pVarIn) < 0.0) + V_R8(pVarOut) = ceil(V_R8(pVarIn)); + else + V_R8(pVarOut) = floor(V_R8(pVarIn)); + break; + case VT_CY: + hRet = VarCyFix(V_CY(pVarIn), &V_CY(pVarOut)); + break; + case VT_DECIMAL: + hRet = VarDecFix(&V_DECIMAL(pVarIn), &V_DECIMAL(pVarOut)); + break; + case VT_EMPTY: + V_VT(pVarOut) = VT_I2; + V_I2(pVarOut) = 0; + break; + case VT_NULL: + /* No-Op */ + break; + default: + if (V_TYPE(pVarIn) == VT_CLSID || /* VT_CLSID is a special case */ + FAILED(VARIANT_ValidateType(V_VT(pVarIn)))) + hRet = DISP_E_BADVARTYPE; + else + hRet = DISP_E_TYPEMISMATCH; + } + if (FAILED(hRet)) + V_VT(pVarOut) = VT_EMPTY; + + return hRet; +} + +/********************************************************************** + * VarInt [OLEAUT32.172] + * + * Truncate a variants value to a whole number. + * + * PARAMS + * pVarIn [I] Source variant + * pVarOut [O] Destination for converted value + * + * RETURNS + * Success: S_OK. pVarOut contains the converted value. + * Failure: An HRESULT error code indicating the error. + * + * NOTES + * - The type of the value stored in pVarOut depends on the type of pVarIn, + * according to the following table: + *| Input Type Output Type + *| ---------- ----------- + *| VT_BOOL VT_I2 + *| VT_EMPTY VT_I2 + *| VT_BSTR VT_R8 + *| All Others Unchanged + * - The difference between this function and VarFix() is that VarFix() rounds + * negative numbers towards 0, while this function rounds them away from zero. + */ +HRESULT WINAPI VarInt(LPVARIANT pVarIn, LPVARIANT pVarOut) +{ + HRESULT hRet = S_OK; + + TRACE("(%p->(%s%s),%p)\n", pVarIn, debugstr_VT(pVarIn), + debugstr_VF(pVarIn), pVarOut); + + V_VT(pVarOut) = V_VT(pVarIn); + + switch (V_VT(pVarIn)) + { + case VT_R4: + V_R4(pVarOut) = (float)floor(V_R4(pVarIn)); + break; + case VT_BSTR: + V_VT(pVarOut) = VT_R8; + hRet = VarR8FromStr(V_BSTR(pVarIn), LOCALE_USER_DEFAULT, 0, &V_R8(pVarOut)); + pVarIn = pVarOut; + /* Fall through */ + case VT_DATE: + case VT_R8: + V_R8(pVarOut) = floor(V_R8(pVarIn)); + break; + case VT_CY: + hRet = VarCyInt(V_CY(pVarIn), &V_CY(pVarOut)); + break; + case VT_DECIMAL: + hRet = VarDecInt(&V_DECIMAL(pVarIn), &V_DECIMAL(pVarOut)); + break; + default: + return VarFix(pVarIn, pVarOut); + } + + return hRet; +} + +/********************************************************************** + * VarXor [OLEAUT32.167] + * + * Perform a logical exclusive-or (XOR) operation on two variants. + * + * PARAMS + * pVarLeft [I] First variant + * pVarRight [I] Variant to XOR with pVarLeft + * pVarOut [O] Destination for XOR result + * + * RETURNS + * Success: S_OK. pVarOut contains the result of the operation with its type + * taken from the table below). + * Failure: An HRESULT error code indicating the error. + * + * NOTES + * - Neither pVarLeft or pVarRight are modified by this function. + * - This function does not process by-reference variants. + * - Input types of VT_BSTR may be numeric strings or boolean text. + * - The type of result stored in pVarOut depends on the types of pVarLeft + * and pVarRight, and will be one of VT_UI1, VT_I2, VT_I4, VT_I8, VT_BOOL, + * or VT_NULL if the function succeeds. + * - Type promotion is inconsistent and as a result certain combinations of + * values will return DISP_E_OVERFLOW even when they could be represented. + * This matches the behaviour of native oleaut32. + */ +HRESULT WINAPI VarXor(LPVARIANT pVarLeft, LPVARIANT pVarRight, LPVARIANT pVarOut) +{ + VARTYPE vt; + VARIANT varLeft, varRight; + double d; + HRESULT hRet; + + TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", pVarLeft, debugstr_VT(pVarLeft), + debugstr_VF(pVarLeft), pVarRight, debugstr_VT(pVarRight), + debugstr_VF(pVarRight), pVarOut); + + if (V_EXTRA_TYPE(pVarLeft) || V_EXTRA_TYPE(pVarRight) || + V_VT(pVarLeft) > VT_UINT || V_VT(pVarRight) > VT_UINT || + V_VT(pVarLeft) == VT_VARIANT || V_VT(pVarRight) == VT_VARIANT || + V_VT(pVarLeft) == VT_UNKNOWN || V_VT(pVarRight) == VT_UNKNOWN || + V_VT(pVarLeft) == (VARTYPE)15 || V_VT(pVarRight) == (VARTYPE)15 || + V_VT(pVarLeft) == VT_ERROR || V_VT(pVarRight) == VT_ERROR) + return DISP_E_BADVARTYPE; + + if (V_VT(pVarLeft) == VT_NULL || V_VT(pVarRight) == VT_NULL) + { + /* NULL XOR anything valid is NULL */ + V_VT(pVarOut) = VT_NULL; + return S_OK; + } + + /* Copy our inputs so we don't disturb anything */ + V_VT(&varLeft) = V_VT(&varRight) = VT_EMPTY; + + hRet = VariantCopy(&varLeft, pVarLeft); + if (FAILED(hRet)) + goto VarXor_Exit; + + hRet = VariantCopy(&varRight, pVarRight); + if (FAILED(hRet)) + goto VarXor_Exit; + + /* Try any strings first as numbers, then as VT_BOOL */ + if (V_VT(&varLeft) == VT_BSTR) + { + hRet = VarR8FromStr(V_BSTR(&varLeft), LOCALE_USER_DEFAULT, 0, &d); + hRet = VariantChangeType(&varLeft, &varLeft, VARIANT_LOCALBOOL, + FAILED(hRet) ? VT_BOOL : VT_I4); + if (FAILED(hRet)) + goto VarXor_Exit; + } + + if (V_VT(&varRight) == VT_BSTR) + { + hRet = VarR8FromStr(V_BSTR(&varRight), LOCALE_USER_DEFAULT, 0, &d); + hRet = VariantChangeType(&varRight, &varRight, VARIANT_LOCALBOOL, + FAILED(hRet) ? VT_BOOL : VT_I4); + if (FAILED(hRet)) + goto VarXor_Exit; + } + + /* Determine the result type */ + if (V_VT(&varLeft) == VT_I8 || V_VT(&varRight) == VT_I8) + { + if (V_VT(pVarLeft) == VT_INT || V_VT(pVarRight) == VT_INT) + return DISP_E_TYPEMISMATCH; + vt = VT_I8; + } + else + { + switch ((V_VT(&varLeft) << 16) | V_VT(&varRight)) + { + case (VT_BOOL << 16) | VT_BOOL: + vt = VT_BOOL; + break; + case (VT_UI1 << 16) | VT_UI1: + vt = VT_UI1; + break; + case (VT_EMPTY << 16) | VT_EMPTY: + case (VT_EMPTY << 16) | VT_UI1: + case (VT_EMPTY << 16) | VT_I2: + case (VT_EMPTY << 16) | VT_BOOL: + case (VT_UI1 << 16) | VT_EMPTY: + case (VT_UI1 << 16) | VT_I2: + case (VT_UI1 << 16) | VT_BOOL: + case (VT_I2 << 16) | VT_EMPTY: + case (VT_I2 << 16) | VT_UI1: + case (VT_I2 << 16) | VT_I2: + case (VT_I2 << 16) | VT_BOOL: + case (VT_BOOL << 16) | VT_EMPTY: + case (VT_BOOL << 16) | VT_UI1: + case (VT_BOOL << 16) | VT_I2: + vt = VT_I2; + break; + default: + vt = VT_I4; + break; + } + } + + /* VT_UI4 does not overflow */ + if (vt != VT_I8) + { + if (V_VT(&varLeft) == VT_UI4) + V_VT(&varLeft) = VT_I4; + if (V_VT(&varRight) == VT_UI4) + V_VT(&varRight) = VT_I4; + } + + /* Convert our input copies to the result type */ + if (V_VT(&varLeft) != vt) + hRet = VariantChangeType(&varLeft, &varLeft, 0, vt); + if (FAILED(hRet)) + goto VarXor_Exit; + + if (V_VT(&varRight) != vt) + hRet = VariantChangeType(&varRight, &varRight, 0, vt); + if (FAILED(hRet)) + goto VarXor_Exit; + + V_VT(pVarOut) = vt; + + /* Calculate the result */ + switch (vt) + { + case VT_I8: + V_I8(pVarOut) = V_I8(&varLeft) ^ V_I8(&varRight); + break; + case VT_I4: + V_I4(pVarOut) = V_I4(&varLeft) ^ V_I4(&varRight); + break; + case VT_BOOL: + case VT_I2: + V_I2(pVarOut) = V_I2(&varLeft) ^ V_I2(&varRight); + break; + case VT_UI1: + V_UI1(pVarOut) = V_UI1(&varLeft) ^ V_UI1(&varRight); + break; + } + +VarXor_Exit: + VariantClear(&varLeft); + VariantClear(&varRight); + return hRet; +} + +/********************************************************************** + * VarEqv [OLEAUT32.172] + * + * Determine if two variants contain the same value. + * + * PARAMS + * pVarLeft [I] First variant to compare + * pVarRight [I] Variant to compare to pVarLeft + * pVarOut [O] Destination for comparison result + * + * RETURNS + * Success: S_OK. pVarOut contains the result of the comparison (VARIANT_TRUE + * if equivalent or non-zero otherwise. + * Failure: An HRESULT error code indicating the error. + * + * NOTES + * - This function simply calls VarXor() on pVarLeft and pVarRight and inverts + * the result. + */ +HRESULT WINAPI VarEqv(LPVARIANT pVarLeft, LPVARIANT pVarRight, LPVARIANT pVarOut) +{ + HRESULT hRet; + + TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", pVarLeft, debugstr_VT(pVarLeft), + debugstr_VF(pVarLeft), pVarRight, debugstr_VT(pVarRight), + debugstr_VF(pVarRight), pVarOut); + + hRet = VarXor(pVarLeft, pVarRight, pVarOut); + if (SUCCEEDED(hRet)) + { + if (V_VT(pVarOut) == VT_I8) + V_I8(pVarOut) = ~V_I8(pVarOut); + else + V_UI4(pVarOut) = ~V_UI4(pVarOut); + } + return hRet; +} + +/********************************************************************** + * VarNeg [OLEAUT32.173] + * + * Negate the value of a variant. + * + * PARAMS + * pVarIn [I] Source variant + * pVarOut [O] Destination for converted value + * + * RETURNS + * Success: S_OK. pVarOut contains the converted value. + * Failure: An HRESULT error code indicating the error. + * + * NOTES + * - The type of the value stored in pVarOut depends on the type of pVarIn, + * according to the following table: + *| Input Type Output Type + *| ---------- ----------- + *| VT_EMPTY VT_I2 + *| VT_UI1 VT_I2 + *| VT_BOOL VT_I2 + *| VT_BSTR VT_R8 + *| All Others Unchanged (unless promoted) + * - Where the negated value of a variant does not fit in its base type, the type + * is promoted according to the following table: + *| Input Type Promoted To + *| ---------- ----------- + *| VT_I2 VT_I4 + *| VT_I4 VT_R8 + *| VT_I8 VT_R8 + * - The native version of this function returns DISP_E_BADVARTYPE for valid + * variant types that cannot be negated, and returns DISP_E_TYPEMISMATCH + * for types which are not valid. Since this is in contravention of the + * meaning of those error codes and unlikely to be relied on by applications, + * this implementation returns errors consistent with the other high level + * variant math functions. + */ +HRESULT WINAPI VarNeg(LPVARIANT pVarIn, LPVARIANT pVarOut) +{ + HRESULT hRet = S_OK; + + TRACE("(%p->(%s%s),%p)\n", pVarIn, debugstr_VT(pVarIn), + debugstr_VF(pVarIn), pVarOut); + + V_VT(pVarOut) = V_VT(pVarIn); + + switch (V_VT(pVarIn)) + { + case VT_UI1: + V_VT(pVarOut) = VT_I2; + V_I2(pVarOut) = -V_UI1(pVarIn); + break; + case VT_BOOL: + V_VT(pVarOut) = VT_I2; + /* Fall through */ + case VT_I2: + if (V_I2(pVarIn) == I2_MIN) + { + V_VT(pVarOut) = VT_I4; + V_I4(pVarOut) = -(int)V_I2(pVarIn); + } + else + V_I2(pVarOut) = -V_I2(pVarIn); + break; + case VT_I4: + if (V_I4(pVarIn) == I4_MIN) + { + V_VT(pVarOut) = VT_R8; + V_R8(pVarOut) = -(double)V_I4(pVarIn); + } + else + V_I4(pVarOut) = -V_I4(pVarIn); + break; + case VT_I8: + if (V_I8(pVarIn) == I8_MIN) + { + V_VT(pVarOut) = VT_R8; + hRet = VarR8FromI8(V_I8(pVarIn), &V_R8(pVarOut)); + V_R8(pVarOut) *= -1.0; + } + else + V_I8(pVarOut) = -V_I8(pVarIn); + break; + case VT_R4: + V_R4(pVarOut) = -V_R4(pVarIn); + break; + case VT_DATE: + case VT_R8: + V_R8(pVarOut) = -V_R8(pVarIn); + break; + case VT_CY: + hRet = VarCyNeg(V_CY(pVarIn), &V_CY(pVarOut)); + break; + case VT_DECIMAL: + hRet = VarDecNeg(&V_DECIMAL(pVarIn), &V_DECIMAL(pVarOut)); + break; + case VT_BSTR: + V_VT(pVarOut) = VT_R8; + hRet = VarR8FromStr(V_BSTR(pVarIn), LOCALE_USER_DEFAULT, 0, &V_R8(pVarOut)); + V_R8(pVarOut) = -V_R8(pVarOut); + break; + case VT_EMPTY: + V_VT(pVarOut) = VT_I2; + V_I2(pVarOut) = 0; + break; + case VT_NULL: + /* No-Op */ + break; + default: + if (V_TYPE(pVarIn) == VT_CLSID || /* VT_CLSID is a special case */ + FAILED(VARIANT_ValidateType(V_VT(pVarIn)))) + hRet = DISP_E_BADVARTYPE; + else + hRet = DISP_E_TYPEMISMATCH; + } + if (FAILED(hRet)) + V_VT(pVarOut) = VT_EMPTY; + + return hRet; +} + +/********************************************************************** + * VarNot [OLEAUT32.174] + * + * Perform a not operation on a variant. + * + * PARAMS + * pVarIn [I] Source variant + * pVarOut [O] Destination for converted value + * + * RETURNS + * Success: S_OK. pVarOut contains the converted value. + * Failure: An HRESULT error code indicating the error. + * + * NOTES + * - Strictly speaking, this function performs a bitwise ones compliment + * on the variants value (after possibly converting to VT_I4, see below). + * This only behaves like a boolean not operation if the value in + * pVarIn is either VARIANT_TRUE or VARIANT_FALSE and the type is signed. + * - To perform a genuine not operation, convert the variant to a VT_BOOL + * before calling this function. + * - This function does not process by-reference variants. + * - The type of the value stored in pVarOut depends on the type of pVarIn, + * according to the following table: + *| Input Type Output Type + *| ---------- ----------- + *| VT_EMPTY VT_I2 + *| VT_R4 VT_I4 + *| VT_R8 VT_I4 + *| VT_BSTR VT_I4 + *| VT_DECIMAL VT_I4 + *| VT_CY VT_I4 + *| (All others) Unchanged + */ +HRESULT WINAPI VarNot(LPVARIANT pVarIn, LPVARIANT pVarOut) +{ + VARIANT varIn; + HRESULT hRet = S_OK; + + TRACE("(%p->(%s%s),%p)\n", pVarIn, debugstr_VT(pVarIn), + debugstr_VF(pVarIn), pVarOut); + + V_VT(pVarOut) = V_VT(pVarIn); + + switch (V_VT(pVarIn)) + { + case VT_I1: + V_I4(pVarOut) = ~V_I1(pVarIn); + V_VT(pVarOut) = VT_I4; + break; + case VT_UI1: V_UI1(pVarOut) = ~V_UI1(pVarIn); break; + case VT_BOOL: + case VT_I2: V_I2(pVarOut) = ~V_I2(pVarIn); break; + case VT_UI2: + V_I4(pVarOut) = ~V_UI2(pVarIn); + V_VT(pVarOut) = VT_I4; + break; + case VT_DECIMAL: + hRet = VarI4FromDec(&V_DECIMAL(pVarIn), &V_I4(&varIn)); + if (FAILED(hRet)) + break; + pVarIn = &varIn; + /* Fall through ... */ + case VT_INT: + V_VT(pVarOut) = VT_I4; + /* Fall through ... */ + case VT_I4: V_I4(pVarOut) = ~V_I4(pVarIn); break; + case VT_UINT: + case VT_UI4: + V_I4(pVarOut) = ~V_UI4(pVarIn); + V_VT(pVarOut) = VT_I4; + break; + case VT_I8: V_I8(pVarOut) = ~V_I8(pVarIn); break; + case VT_UI8: + V_I4(pVarOut) = ~V_UI8(pVarIn); + V_VT(pVarOut) = VT_I4; + break; + case VT_R4: + hRet = VarI4FromR4(V_R4(pVarIn), &V_I4(pVarOut)); + V_I4(pVarOut) = ~V_I4(pVarOut); + V_VT(pVarOut) = VT_I4; + break; + case VT_BSTR: + hRet = VarR8FromStr(V_BSTR(pVarIn), LOCALE_USER_DEFAULT, 0, &V_R8(&varIn)); + if (FAILED(hRet)) + break; + pVarIn = &varIn; + /* Fall through ... */ + case VT_DATE: + case VT_R8: + hRet = VarI4FromR8(V_R8(pVarIn), &V_I4(pVarOut)); + V_I4(pVarOut) = ~V_I4(pVarOut); + V_VT(pVarOut) = VT_I4; + break; + case VT_CY: + hRet = VarI4FromCy(V_CY(pVarIn), &V_I4(pVarOut)); + V_I4(pVarOut) = ~V_I4(pVarOut); + V_VT(pVarOut) = VT_I4; + break; + case VT_EMPTY: + V_I2(pVarOut) = ~0; + V_VT(pVarOut) = VT_I2; + break; + case VT_NULL: + /* No-Op */ + break; + default: + if (V_TYPE(pVarIn) == VT_CLSID || /* VT_CLSID is a special case */ + FAILED(VARIANT_ValidateType(V_VT(pVarIn)))) + hRet = DISP_E_BADVARTYPE; + else + hRet = DISP_E_TYPEMISMATCH; + } + if (FAILED(hRet)) + V_VT(pVarOut) = VT_EMPTY; + + return hRet; +} + +/********************************************************************** + * VarRound [OLEAUT32.175] + * + * Perform a round operation on a variant. + * + * PARAMS + * pVarIn [I] Source variant + * deci [I] Number of decimals to round to + * pVarOut [O] Destination for converted value + * + * RETURNS + * Success: S_OK. pVarOut contains the converted value. + * Failure: An HRESULT error code indicating the error. + * + * NOTES + * - Floating point values are rounded to the desired number of decimals. + * - Some integer types are just copied to the return variable. + * - Some other integer types are not handled and fail. + */ +HRESULT WINAPI VarRound(LPVARIANT pVarIn, int deci, LPVARIANT pVarOut) +{ + VARIANT varIn; + HRESULT hRet = S_OK; + float factor; + + TRACE("(%p->(%s%s),%d)\n", pVarIn, debugstr_VT(pVarIn), debugstr_VF(pVarIn), deci); + + switch (V_VT(pVarIn)) + { + /* cases that fail on windows */ + case VT_I1: + case VT_I8: + case VT_UI2: + case VT_UI4: + hRet = DISP_E_BADVARTYPE; + break; + + /* cases just copying in to out */ + case VT_UI1: + V_VT(pVarOut) = V_VT(pVarIn); + V_UI1(pVarOut) = V_UI1(pVarIn); + break; + case VT_I2: + V_VT(pVarOut) = V_VT(pVarIn); + V_I2(pVarOut) = V_I2(pVarIn); + break; + case VT_I4: + V_VT(pVarOut) = V_VT(pVarIn); + V_I4(pVarOut) = V_I4(pVarIn); + break; + case VT_NULL: + V_VT(pVarOut) = V_VT(pVarIn); + /* value unchanged */ + break; + + /* cases that change type */ + case VT_EMPTY: + V_VT(pVarOut) = VT_I2; + V_I2(pVarOut) = 0; + break; + case VT_BOOL: + V_VT(pVarOut) = VT_I2; + V_I2(pVarOut) = V_BOOL(pVarIn); + break; + case VT_BSTR: + hRet = VarR8FromStr(V_BSTR(pVarIn), LOCALE_USER_DEFAULT, 0, &V_R8(&varIn)); + if (FAILED(hRet)) + break; + V_VT(&varIn)=VT_R8; + pVarIn = &varIn; + /* Fall through ... */ + + /* cases we need to do math */ + case VT_R8: + if (V_R8(pVarIn)>0) { + V_R8(pVarOut)=floor(V_R8(pVarIn)*pow(10, deci)+0.5)/pow(10, deci); + } else { + V_R8(pVarOut)=ceil(V_R8(pVarIn)*pow(10, deci)-0.5)/pow(10, deci); + } + V_VT(pVarOut) = V_VT(pVarIn); + break; + case VT_R4: + if (V_R4(pVarIn)>0) { + V_R4(pVarOut)=floor(V_R4(pVarIn)*pow(10, deci)+0.5)/pow(10, deci); + } else { + V_R4(pVarOut)=ceil(V_R4(pVarIn)*pow(10, deci)-0.5)/pow(10, deci); + } + V_VT(pVarOut) = V_VT(pVarIn); + break; + case VT_DATE: + if (V_DATE(pVarIn)>0) { + V_DATE(pVarOut)=floor(V_DATE(pVarIn)*pow(10, deci)+0.5)/pow(10, deci); + } else { + V_DATE(pVarOut)=ceil(V_DATE(pVarIn)*pow(10, deci)-0.5)/pow(10, deci); + } + V_VT(pVarOut) = V_VT(pVarIn); + break; + case VT_CY: + if (deci>3) + factor=1; + else + factor=pow(10, 4-deci); + + if (V_CY(pVarIn).int64>0) { + V_CY(pVarOut).int64=floor(V_CY(pVarIn).int64/factor)*factor; + } else { + V_CY(pVarOut).int64=ceil(V_CY(pVarIn).int64/factor)*factor; + } + V_VT(pVarOut) = V_VT(pVarIn); + break; + + /* cases we don't know yet */ + default: + FIXME("unimplemented part, V_VT(pVarIn) == 0x%X, deci == %d\n", + V_VT(pVarIn) & VT_TYPEMASK, deci); + hRet = DISP_E_BADVARTYPE; + } + + if (FAILED(hRet)) + V_VT(pVarOut) = VT_EMPTY; + + TRACE("returning 0x%08lx (%s%s),%f\n", hRet, debugstr_VT(pVarOut), + debugstr_VF(pVarOut), (V_VT(pVarOut) == VT_R4) ? V_R4(pVarOut) : + (V_VT(pVarOut) == VT_R8) ? V_R8(pVarOut) : 0); + + return hRet; +} + + +/********************************************************************** + * VarMod [OLEAUT32.154] + * + * Perform the modulus operation of the right hand variant on the left + * + * PARAMS + * left [I] Left hand variant + * right [I] Right hand variant + * result [O] Destination for converted value + * + * RETURNS + * Success: S_OK. result contains the remainder. + * Failure: An HRESULT error code indicating the error. + * + * NOTE: + * If an error occurs the type of result will be modified but the value will not be. + * Doesn't support arrays or any special flags yet. + */ +HRESULT WINAPI VarMod(LPVARIANT left, LPVARIANT right, LPVARIANT result) +{ + BOOL lOk = TRUE; + BOOL rOk = TRUE; + HRESULT rc = E_FAIL; + int resT = 0; + VARIANT lv,rv; + + VariantInit(&lv); + VariantInit(&rv); + + TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left), + debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), result); + + /* check for invalid inputs */ + lOk = TRUE; + switch (V_VT(left) & VT_TYPEMASK) { + case VT_BOOL : + case VT_I1 : + case VT_I2 : + case VT_I4 : + case VT_I8 : + case VT_INT : + case VT_UI1 : + case VT_UI2 : + case VT_UI4 : + case VT_UI8 : + case VT_UINT : + case VT_R4 : + case VT_R8 : + case VT_CY : + case VT_EMPTY: + case VT_DATE : + case VT_BSTR : + break; + case VT_VARIANT: + case VT_UNKNOWN: + V_VT(result) = VT_EMPTY; + return DISP_E_TYPEMISMATCH; + case VT_DECIMAL: + V_VT(result) = VT_EMPTY; + return E_INVALIDARG; + case VT_ERROR: + return DISP_E_TYPEMISMATCH; + case VT_RECORD: + V_VT(result) = VT_EMPTY; + return DISP_E_TYPEMISMATCH; + case VT_NULL: + break; + default: + V_VT(result) = VT_EMPTY; + return DISP_E_BADVARTYPE; + } + + + rOk = TRUE; + switch (V_VT(right) & VT_TYPEMASK) { + case VT_BOOL : + case VT_I1 : + case VT_I2 : + case VT_I4 : + case VT_I8 : + if((V_VT(left) == VT_INT) && (V_VT(right) == VT_I8)) + { + V_VT(result) = VT_EMPTY; + return DISP_E_TYPEMISMATCH; + } + case VT_INT : + if((V_VT(right) == VT_INT) && (V_VT(left) == VT_I8)) + { + V_VT(result) = VT_EMPTY; + return DISP_E_TYPEMISMATCH; + } + case VT_UI1 : + case VT_UI2 : + case VT_UI4 : + case VT_UI8 : + case VT_UINT : + case VT_R4 : + case VT_R8 : + case VT_CY : + if(V_VT(left) == VT_EMPTY) + { + V_VT(result) = VT_I4; + return S_OK; + } + case VT_EMPTY: + case VT_DATE : + case VT_BSTR: + if(V_VT(left) == VT_NULL) + { + V_VT(result) = VT_NULL; + return S_OK; + } + break; + + case VT_VOID: + V_VT(result) = VT_EMPTY; + return DISP_E_BADVARTYPE; + case VT_NULL: + if(V_VT(left) == VT_VOID) + { + V_VT(result) = VT_EMPTY; + return DISP_E_BADVARTYPE; + } else if((V_VT(left) == VT_NULL) || (V_VT(left) == VT_EMPTY) || (V_VT(left) == VT_ERROR) || + lOk) + { + V_VT(result) = VT_NULL; + return S_OK; + } else + { + V_VT(result) = VT_NULL; + return DISP_E_BADVARTYPE; + } + case VT_VARIANT: + case VT_UNKNOWN: + V_VT(result) = VT_EMPTY; + return DISP_E_TYPEMISMATCH; + case VT_DECIMAL: + if(V_VT(left) == VT_ERROR) + { + V_VT(result) = VT_EMPTY; + return DISP_E_TYPEMISMATCH; + } else + { + V_VT(result) = VT_EMPTY; + return E_INVALIDARG; + } + case VT_ERROR: + return DISP_E_TYPEMISMATCH; + case VT_RECORD: + if((V_VT(left) == 15) || ((V_VT(left) >= 24) && (V_VT(left) <= 35)) || !lOk) + { + V_VT(result) = VT_EMPTY; + return DISP_E_BADVARTYPE; + } else + { + V_VT(result) = VT_EMPTY; + return DISP_E_TYPEMISMATCH; + } + default: + V_VT(result) = VT_EMPTY; + return DISP_E_BADVARTYPE; + } + + /* determine the result type */ + if((V_VT(left) == VT_I8) || (V_VT(right) == VT_I8)) resT = VT_I8; + else if((V_VT(left) == VT_UI1) && (V_VT(right) == VT_BOOL)) resT = VT_I2; + else if((V_VT(left) == VT_UI1) && (V_VT(right) == VT_UI1)) resT = VT_UI1; + else if((V_VT(left) == VT_UI1) && (V_VT(right) == VT_I2)) resT = VT_I2; + else if((V_VT(left) == VT_I2) && (V_VT(right) == VT_BOOL)) resT = VT_I2; + else if((V_VT(left) == VT_I2) && (V_VT(right) == VT_UI1)) resT = VT_I2; + else if((V_VT(left) == VT_I2) && (V_VT(right) == VT_I2)) resT = VT_I2; + else if((V_VT(left) == VT_BOOL) && (V_VT(right) == VT_BOOL)) resT = VT_I2; + else if((V_VT(left) == VT_BOOL) && (V_VT(right) == VT_UI1)) resT = VT_I2; + else if((V_VT(left) == VT_BOOL) && (V_VT(right) == VT_I2)) resT = VT_I2; + else resT = VT_I4; /* most outputs are I4 */ + + /* convert to I8 for the modulo */ + rc = VariantChangeType(&lv, left, 0, VT_I8); + if(FAILED(rc)) + { + FIXME("Could not convert left type %d to %d? rc == 0x%lX\n", V_VT(left), VT_I8, rc); + return rc; + } + + rc = VariantChangeType(&rv, right, 0, VT_I8); + if(FAILED(rc)) + { + FIXME("Could not convert right type %d to %d? rc == 0x%lX\n", V_VT(right), VT_I8, rc); + return rc; + } + + /* if right is zero set VT_EMPTY and return divide by zero */ + if(V_I8(&rv) == 0) + { + V_VT(result) = VT_EMPTY; + return DISP_E_DIVBYZERO; + } + + /* perform the modulo operation */ + V_VT(result) = VT_I8; + V_I8(result) = V_I8(&lv) % V_I8(&rv); + + TRACE("V_I8(left) == %ld, V_I8(right) == %ld, V_I8(result) == %ld\n", (long)V_I8(&lv), (long)V_I8(&rv), (long)V_I8(result)); + + /* convert left and right to the destination type */ + rc = VariantChangeType(result, result, 0, resT); + if(FAILED(rc)) + { + FIXME("Could not convert 0x%x to %d?\n", V_VT(result), resT); + return rc; + } + + return S_OK; +} + +/********************************************************************** + * VarPow [OLEAUT32.158] + * + */ +HRESULT WINAPI VarPow(LPVARIANT left, LPVARIANT right, LPVARIANT result) +{ + HRESULT hr; + VARIANT dl,dr; + + TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left), debugstr_VF(left), + right, debugstr_VT(right), debugstr_VF(right), result); + + hr = VariantChangeType(&dl,left,0,VT_R8); + if (!SUCCEEDED(hr)) { + ERR("Could not change passed left argument to VT_R8, handle it differently.\n"); + return E_FAIL; + } + hr = VariantChangeType(&dr,right,0,VT_R8); + if (!SUCCEEDED(hr)) { + ERR("Could not change passed right argument to VT_R8, handle it differently.\n"); + return E_FAIL; + } + V_VT(result) = VT_R8; + V_R8(result) = pow(V_R8(&dl),V_R8(&dr)); + return S_OK; +} diff --git a/reactos/lib/oleaut32/variant.h b/reactos/lib/oleaut32/variant.h new file mode 100644 index 00000000000..a0a4fbe1d2e --- /dev/null +++ b/reactos/lib/oleaut32/variant.h @@ -0,0 +1,435 @@ +/* + * Variant Inlines + * + * Copyright 2003 Jon Griffiths + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#define NONAMELESSUNION +#define NONAMELESSSTRUCT +#include "windef.h" +#include "winerror.h" +#include "objbase.h" +#include "oleauto.h" +#include + +/* Get just the type from a variant pointer */ +#define V_TYPE(v) (V_VT((v)) & VT_TYPEMASK) + +/* Flags set in V_VT, other than the actual type value */ +#define VT_EXTRA_TYPE (VT_VECTOR|VT_ARRAY|VT_BYREF|VT_RESERVED) + +/* Get the extra flags from a variant pointer */ +#define V_EXTRA_TYPE(v) (V_VT((v)) & VT_EXTRA_TYPE) + +extern const char* wine_vtypes[]; +#define debugstr_vt(v) (((v)&VT_TYPEMASK) <= VT_CLSID ? wine_vtypes[((v)&VT_TYPEMASK)] : \ + ((v)&VT_TYPEMASK) == VT_BSTR_BLOB ? "VT_BSTR_BLOB": "Invalid") +#define debugstr_VT(v) (!(v) ? "(null)" : debugstr_vt(V_TYPE((v)))) + +extern const char* wine_vflags[]; +#define debugstr_vf(v) (wine_vflags[((v)&VT_EXTRA_TYPE)>>12]) +#define debugstr_VF(v) (!(v) ? "(null)" : debugstr_vf(V_EXTRA_TYPE(v))) + +/* Size constraints */ +#define I1_MAX 0x7f +#define I1_MIN ((-I1_MAX)-1) +#define UI1_MAX 0xff +#define UI1_MIN 0 +#define I2_MAX 0x7fff +#define I2_MIN ((-I2_MAX)-1) +#define UI2_MAX 0xffff +#define UI2_MIN 0 +#define I4_MAX 0x7fffffff +#define I4_MIN ((-I4_MAX)-1) +#define UI4_MAX 0xffffffff +#define UI4_MIN 0 +#define I8_MAX (((LONGLONG)I4_MAX << 32) | UI4_MAX) +#define I8_MIN ((-I8_MAX)-1) +#define UI8_MAX (((ULONGLONG)UI4_MAX << 32) | UI4_MAX) +#define UI8_MIN 0 +#define DATE_MAX 2958465 +#define DATE_MIN -657434 +#define R4_MAX 3.402823567797336e38 +#define R4_MIN 1.40129846432481707e-45 +#define R8_MAX 1.79769313486231470e+308 +#define R8_MIN 4.94065645841246544e-324 + +/* Value of sign for a positive decimal number */ +#define DECIMAL_POS 0 + +/* Native headers don't change the union ordering for DECIMAL sign/scale (duh). + * This means that the signscale member is only useful for setting both members to 0. + * SIGNSCALE creates endian-correct values so that we can properly set both at once + * to values other than 0. + */ +#ifdef WORDS_BIGENDIAN +#define SIGNSCALE(sign,scale) (((scale) << 8) | sign) +#else +#define SIGNSCALE(sign,scale) (((sign) << 8) | scale) +#endif + +/* Macros for getting at a DECIMAL's parts */ +#define DEC_SIGN(d) ((d)->sign) +#define DEC_SCALE(d) ((d)->scale) +#define DEC_SIGNSCALE(d) ((d)->signscale) +#define DEC_HI32(d) ((d)->Hi32) +#define DEC_MID32(d) ((d)->Mid32) +#define DEC_LO32(d) ((d)->Lo32) +#define DEC_LO64(d) ((d)->Lo64) + +#define DEC_MAX_SCALE 28 /* Maximum scale for a decimal */ + +/* Inline return type */ +#define RETTYP inline static HRESULT + +/* Simple compiler cast from one type to another */ +#define SIMPLE(dest, src, func) RETTYP _##func(src in, dest* out) { \ + *out = in; return S_OK; } + +/* Compiler cast where input cannot be negative */ +#define NEGTST(dest, src, func) RETTYP _##func(src in, dest* out) { \ + if (in < (src)0) return DISP_E_OVERFLOW; *out = in; return S_OK; } + +/* Compiler cast where input cannot be > some number */ +#define POSTST(dest, src, func, tst) RETTYP _##func(src in, dest* out) { \ + if (in > (dest)tst) return DISP_E_OVERFLOW; *out = in; return S_OK; } + +/* Compiler cast where input cannot be < some number or >= some other number */ +#define BOTHTST(dest, src, func, lo, hi) RETTYP _##func(src in, dest* out) { \ + if (in < (dest)lo || in > hi) return DISP_E_OVERFLOW; *out = in; return S_OK; } + +/* Conversions from IDispatch use the same code */ +HRESULT VARIANT_FromDisp(IDispatch*,LCID,void*,VARTYPE); +/* As do conversions from BSTR to numeric types */ +HRESULT VARIANT_NumberFromBstr(OLECHAR*,LCID,ULONG,void*,VARTYPE); + +#define CY_MULTIPLIER 10000 /* 4 dp of precision */ +#define CY_MULTIPLIER_F 10000.0 +#define CY_HALF (CY_MULTIPLIER/2) /* 0.5 */ +#define CY_HALF_F (CY_MULTIPLIER_F/2.0) + +/* I1 */ +POSTST(signed char, BYTE, VarI1FromUI1, I1_MAX); +BOTHTST(signed char, SHORT, VarI1FromI2, I1_MIN, I1_MAX); +BOTHTST(signed char, LONG, VarI1FromI4, I1_MIN, I1_MAX); +#define _VarI1FromR4(flt,out) VarI1FromR8((double)flt,out) +#define _VarI1FromR8 VarI1FromR8 +#define _VarI1FromCy VarI1FromCy +#define _VarI1FromDate(dt,out) VarI1FromR8((double)dt,out) +#define _VarI1FromStr(str,lcid,flags,out) VARIANT_NumberFromBstr(str,lcid,flags,(BYTE*)out,VT_I1) +#define _VarI1FromDisp(disp,lcid,out) VARIANT_FromDisp(disp, lcid, (BYTE*)out, VT_I1) +SIMPLE(signed char, VARIANT_BOOL, VarI1FromBool); +POSTST(signed char, USHORT, VarI1FromUI2, I1_MAX); +POSTST(signed char, ULONG, VarI1FromUI4, I1_MAX); +#define _VarI1FromDec VarI1FromDec +BOTHTST(signed char, LONG64, VarI1FromI8, I1_MIN, I1_MAX); +POSTST(signed char, ULONG64, VarI1FromUI8, I1_MAX); + +/* UI1 */ +BOTHTST(BYTE, SHORT, VarUI1FromI2, UI1_MIN, UI1_MAX); +#define _VarUI1FromR4(flt,out) VarUI1FromR8((double)flt,out) +#define _VarUI1FromR8 VarUI1FromR8 +#define _VarUI1FromCy VarUI1FromCy +#define _VarUI1FromDate(dt,out) VarUI1FromR8((double)dt,out) +#define _VarUI1FromStr(str,lcid,flags,out) VARIANT_NumberFromBstr(str,lcid,flags,(BYTE*)out,VT_UI1) +#define _VarUI1FromDisp(disp,lcid,out) VARIANT_FromDisp(disp, lcid, out, VT_UI1) +SIMPLE(BYTE, VARIANT_BOOL, VarUI1FromBool); +NEGTST(BYTE, signed char, VarUI1FromI1); +POSTST(BYTE, USHORT, VarUI1FromUI2, UI1_MAX); +BOTHTST(BYTE, LONG, VarUI1FromI4, UI1_MIN, UI1_MAX); +POSTST(BYTE, ULONG, VarUI1FromUI4, UI1_MAX); +#define _VarUI1FromDec VarUI1FromDec +BOTHTST(BYTE, LONG64, VarUI1FromI8, UI1_MIN, UI1_MAX); +POSTST(BYTE, ULONG64, VarUI1FromUI8, UI1_MAX); + +/* I2 */ +SIMPLE(SHORT, BYTE, VarI2FromUI1); +BOTHTST(SHORT, LONG, VarI2FromI4, I2_MIN, I2_MAX); +#define _VarI2FromR4(flt,out) VarI2FromR8((double)flt,out) +#define _VarI2FromR8 VarI2FromR8 +#define _VarI2FromCy VarI2FromCy +#define _VarI2FromDate(dt,out) VarI2FromR8((double)dt,out) +#define _VarI2FromStr(str,lcid,flags,out) VARIANT_NumberFromBstr(str,lcid,flags,(BYTE*)out,VT_I2) +#define _VarI2FromDisp(disp,lcid,out) VARIANT_FromDisp(disp, lcid, (BYTE*)out, VT_I2) +SIMPLE(SHORT, VARIANT_BOOL, VarI2FromBool); +SIMPLE(SHORT, signed char, VarI2FromI1); +POSTST(SHORT, USHORT, VarI2FromUI2, I2_MAX); +POSTST(SHORT, ULONG, VarI2FromUI4, I2_MAX); +#define _VarI2FromDec VarI2FromDec +BOTHTST(SHORT, LONG64, VarI2FromI8, I2_MIN, I2_MAX); +POSTST(SHORT, ULONG64, VarI2FromUI8, I2_MAX); + +/* UI2 */ +SIMPLE(USHORT, BYTE, VarUI2FromUI1); +NEGTST(USHORT, SHORT, VarUI2FromI2); +BOTHTST(USHORT, LONG, VarUI2FromI4, UI2_MIN, UI2_MAX); +#define _VarUI2FromR4(flt,out) VarUI2FromR8((double)flt,out) +#define _VarUI2FromR8 VarUI2FromR8 +#define _VarUI2FromCy VarUI2FromCy +#define _VarUI2FromDate(dt,out) VarUI2FromR8((double)dt,out) +#define _VarUI2FromStr(str,lcid,flags,out) VARIANT_NumberFromBstr(str,lcid,flags,(BYTE*)out,VT_UI2) +#define _VarUI2FromDisp(disp,lcid,out) VARIANT_FromDisp(disp, lcid, out, VT_UI2) +SIMPLE(USHORT, VARIANT_BOOL, VarUI2FromBool); +NEGTST(USHORT, signed char, VarUI2FromI1); +POSTST(USHORT, ULONG, VarUI2FromUI4, UI2_MAX); +#define _VarUI2FromDec VarUI2FromDec +BOTHTST(USHORT, LONG64, VarUI2FromI8, UI2_MIN, UI2_MAX); +POSTST(USHORT, ULONG64, VarUI2FromUI8, UI2_MAX); + +/* I4 */ +SIMPLE(LONG, BYTE, VarI4FromUI1); +SIMPLE(LONG, SHORT, VarI4FromI2); +#define _VarI4FromR4(flt,out) VarI4FromR8((double)flt,out) +#define _VarI4FromR8 VarI4FromR8 +#define _VarI4FromCy VarI4FromCy +#define _VarI4FromDate(dt,out) VarI4FromR8((double)dt,out) +#define _VarI4FromStr(str,lcid,flags,out) VARIANT_NumberFromBstr(str,lcid,flags,(BYTE*)out,VT_I4) +#define _VarI4FromDisp(disp,lcid,out) VARIANT_FromDisp(disp, lcid, (BYTE*)out, VT_I4) +SIMPLE(LONG, VARIANT_BOOL, VarI4FromBool); +SIMPLE(LONG, signed char, VarI4FromI1); +SIMPLE(LONG, USHORT, VarI4FromUI2); +POSTST(LONG, ULONG, VarI4FromUI4, I4_MAX); +#define _VarI4FromDec VarI4FromDec +BOTHTST(LONG, LONG64, VarI4FromI8, I4_MIN, I4_MAX); +POSTST(LONG, ULONG64, VarI4FromUI8, I4_MAX); + +/* UI4 */ +SIMPLE(ULONG, BYTE, VarUI4FromUI1); +NEGTST(ULONG, SHORT, VarUI4FromI2); +NEGTST(ULONG, LONG, VarUI4FromI4); +#define _VarUI4FromR4(flt,out) VarUI4FromR8((double)flt,out) +#define _VarUI4FromR8 VarUI4FromR8 +#define _VarUI4FromCy VarUI4FromCy +#define _VarUI4FromDate(dt,out) VarUI4FromR8((double)dt,out) +#define _VarUI4FromStr(str,lcid,flags,out) VARIANT_NumberFromBstr(str,lcid,flags,(BYTE*)out,VT_UI4) +#define _VarUI4FromDisp(disp,lcid,out) VARIANT_FromDisp(disp, lcid, out, VT_UI4) +SIMPLE(ULONG, VARIANT_BOOL, VarUI4FromBool); +NEGTST(ULONG, signed char, VarUI4FromI1); +SIMPLE(ULONG, USHORT, VarUI4FromUI2); +#define _VarUI4FromDec VarUI4FromDec +BOTHTST(ULONG, LONG64, VarUI4FromI8, UI4_MIN, UI4_MAX); +POSTST(ULONG, ULONG64, VarUI4FromUI8, UI4_MAX); + +/* I8 */ +SIMPLE(LONG64, BYTE, VarI8FromUI1); +SIMPLE(LONG64, SHORT, VarI8FromI2); +#define _VarI8FromR4 VarI8FromR8 +#define _VarI8FromR8 VarI8FromR8 +#define _VarI8FromCy VarI8FromCy +#define _VarI8FromDate(dt,out) VarI8FromR8((double)dt,out) +#define _VarI8FromStr(str,lcid,flags,out) VARIANT_NumberFromBstr(str,lcid,flags,(BYTE*)out,VT_I8) +#define _VarI8FromDisp(disp,lcid,out) VARIANT_FromDisp(disp, lcid, out, VT_I8) +#define _VarI8FromBool _VarI8FromI2 +SIMPLE(LONG64, signed char, VarI8FromI1); +SIMPLE(LONG64, USHORT, VarI8FromUI2); +SIMPLE(LONG64, LONG, VarI8FromI4); +SIMPLE(LONG64, ULONG, VarI8FromUI4); +#define _VarI8FromDec VarI8FromDec +POSTST(LONG64, ULONG64, VarI8FromUI8, I8_MAX); + +/* UI8 */ +SIMPLE(ULONG64, BYTE, VarUI8FromUI1); +NEGTST(ULONG64, SHORT, VarUI8FromI2); +#define _VarUI8FromR4 VarUI8FromR8 +#define _VarUI8FromR8 VarUI8FromR8 +#define _VarUI8FromCy VarUI8FromCy +#define _VarUI8FromDate(dt,out) VarUI8FromR8((double)dt,out) +#define _VarUI8FromStr(str,lcid,flags,out) VARIANT_NumberFromBstr(str,lcid,flags,(BYTE*)out,VT_UI8) +#define _VarUI8FromDisp(disp,lcid,out) VARIANT_FromDisp(disp, lcid, out, VT_UI8) +#define _VarUI8FromBool _VarI8FromI2 +NEGTST(ULONG64, signed char, VarUI8FromI1); +SIMPLE(ULONG64, USHORT, VarUI8FromUI2); +NEGTST(ULONG64, LONG, VarUI8FromI4); +SIMPLE(ULONG64, ULONG, VarUI8FromUI4); +#define _VarUI8FromDec VarUI8FromDec +NEGTST(ULONG64, LONG64, VarUI8FromI8); + +/* R4 (float) */ +SIMPLE(float, BYTE, VarR4FromUI1); +SIMPLE(float, SHORT, VarR4FromI2); +RETTYP _VarR4FromR8(double i, float* o) { + double d = i < 0.0 ? -i : i; + if (d > R4_MAX) return DISP_E_OVERFLOW; + *o = i; + return S_OK; +} +RETTYP _VarR4FromCy(CY i, float* o) { *o = (double)i.int64 / CY_MULTIPLIER_F; return S_OK; } +#define _VarR4FromDate(dt,out) _VarR4FromR8((double)dt,out) +#define _VarR4FromStr(str,lcid,flags,out) VARIANT_NumberFromBstr(str,lcid,flags,(BYTE*)out,VT_R4) +#define _VarR4FromDisp(disp,lcid,out) VARIANT_FromDisp(disp, lcid, out, VT_R4) +#define _VarR4FromBool _VarR4FromI2 +SIMPLE(float, signed char, VarR4FromI1); +SIMPLE(float, USHORT, VarR4FromUI2); +SIMPLE(float, LONG, VarR4FromI4); +SIMPLE(float, ULONG, VarR4FromUI4); +#define _VarR4FromDec VarR4FromDec +SIMPLE(float, LONG64, VarR4FromI8); +SIMPLE(float, ULONG64, VarR4FromUI8); + +/* R8 (double) */ +SIMPLE(double, BYTE, VarR8FromUI1); +SIMPLE(double, SHORT, VarR8FromI2); +SIMPLE(double, float, VarR8FromR4); +RETTYP _VarR8FromCy(CY i, double* o) { *o = (double)i.int64 / CY_MULTIPLIER_F; return S_OK; } +SIMPLE(double, DATE, VarR8FromDate); +#define _VarR8FromStr(str,lcid,flags,out) VARIANT_NumberFromBstr(str,lcid,flags,(BYTE*)out,VT_R8) +#define _VarR8FromDisp(disp,lcid,out) VARIANT_FromDisp(disp, lcid, out, VT_R8) +#define _VarR8FromBool _VarR8FromI2 +SIMPLE(double, signed char, VarR8FromI1); +SIMPLE(double, USHORT, VarR8FromUI2); +SIMPLE(double, LONG, VarR8FromI4); +SIMPLE(double, ULONG, VarR8FromUI4); +#define _VarR8FromDec VarR8FromDec +SIMPLE(double, LONG64, VarR8FromI8); +SIMPLE(double, ULONG64, VarR8FromUI8); + +/* BOOL */ +#define BOOLFUNC(src, func) RETTYP _##func(src in, VARIANT_BOOL* out) { \ + *out = in ? VARIANT_TRUE : VARIANT_FALSE; return S_OK; } + +BOOLFUNC(signed char,VarBoolFromI1); +BOOLFUNC(BYTE,VarBoolFromUI1); +BOOLFUNC(SHORT,VarBoolFromI2); +BOOLFUNC(USHORT,VarBoolFromUI2); +BOOLFUNC(LONG,VarBoolFromI4); +BOOLFUNC(ULONG,VarBoolFromUI4); +BOOLFUNC(LONG64,VarBoolFromI8); +BOOLFUNC(ULONG64,VarBoolFromUI8); +#define _VarBoolFromR4(flt,out) _VarBoolFromR8((double)flt,out) +BOOLFUNC(double,VarBoolFromR8); +#define _VarBoolFromCy(i,o) _VarBoolFromI8(i.int64,o) +#define _VarBoolFromDate(dt,out) _VarBoolFromR8((double)dt,out) +#define _VarBoolFromStr VarBoolFromStr +#define _VarBoolFromDisp(disp,lcid,out) VARIANT_FromDisp(disp, lcid, (BYTE*)out, VT_BOOL) +#define _VarBoolFromDec VarBoolFromDec + +/* Internal flags for low level conversion functions */ +#define VAR_BOOLONOFF 0x0400 /* Convert bool to "On"/"Off" */ +#define VAR_BOOLYESNO 0x0800 /* Convert bool to "Yes"/"No" */ +#define VAR_NEGATIVE 0x1000 /* Number is negative */ + +/* DECIMAL */ +#define _VarDecFromUI1 VarDecFromUI4 +#define _VarDecFromI2 VarDecFromI4 +#define _VarDecFromR4 VarDecFromR4 +#define _VarDecFromR8 VarDecFromR8 +#define _VarDecFromCy VarDecFromCy +#define _VarDecFromDate(dt,out) VarDecFromR8((double)dt,out) +#define _VarDecFromStr(str,lcid,flags,out) VARIANT_NumberFromBstr(str,lcid,flags,(BYTE*)out,VT_DECIMAL) +#define _VarDecFromDisp(disp,lcid,out) VARIANT_FromDisp(disp, lcid, out, VT_DECIMAL) +#define _VarDecFromBool VarDecFromBool +#define _VarDecFromI1 VarDecFromI4 +#define _VarDecFromUI2 VarDecFromUI4 +#define _VarDecFromI4 VarDecFromI4 +#define _VarDecFromUI4 VarDecFromUI4 +#define _VarDecFromI8 VarDecFromI8 +#define _VarDecFromUI8 VarDecFromUI8 + +/* CY (Currency) */ +#define _VarCyFromUI1 VarCyFromR8 +#define _VarCyFromI2 VarCyFromR8 +#define _VarCyFromR4 VarCyFromR8 +#define _VarCyFromR8 VarCyFromR8 +#define _VarCyFromDate VarCyFromR8 +#define _VarCyFromStr(str,lcid,flags,out) VARIANT_NumberFromBstr(str,lcid,flags,(BYTE*)out,VT_CY) +#define _VarCyFromDisp(disp,lcid,out) VARIANT_FromDisp(disp, lcid, out, VT_CY) +#define _VarCyFromBool VarCyFromR8 +#define _VarCyFromI1 VarCyFromR8 +#define _VarCyFromUI2 VarCyFromR8 +#define _VarCyFromI4 VarCyFromR8 +#define _VarCyFromUI4 VarCyFromR8 +#define _VarCyFromDec VarCyFromDec +RETTYP _VarCyFromI8(LONG64 i, CY* o) { + if (i <= (I8_MIN/CY_MULTIPLIER) || i >= (I8_MAX/CY_MULTIPLIER)) return DISP_E_OVERFLOW; + o->int64 = i * CY_MULTIPLIER; + return S_OK; +} +#define _VarCyFromUI8 VarCyFromR8 + +/* DATE */ +#define _VarDateFromUI1 _VarR8FromUI1 +#define _VarDateFromI2 _VarR8FromI2 +#define _VarDateFromR4 _VarDateFromR8 +RETTYP _VarDateFromR8(double i, DATE* o) { + if (i <= (DATE_MIN - 1.0) || i >= (DATE_MAX + 1.0)) return DISP_E_OVERFLOW; + *o = (DATE)i; + return S_OK; +} +#define _VarDateFromCy _VarR8FromCy +#define _VarDateFromStr VarDateFromStr +#define _VarDateFromDisp(disp,lcid,out) VARIANT_FromDisp(disp, lcid, out, VT_DATE) +#define _VarDateFromBool _VarR8FromBool +#define _VarDateFromI1 _VarR8FromI1 +#define _VarDateFromUI2 _VarR8FromUI2 +#define _VarDateFromI4 _VarDateFromR8 +#define _VarDateFromUI4 _VarDateFromR8 +#define _VarDateFromDec _VarR8FromDec +RETTYP _VarDateFromI8(LONG64 i, DATE* o) { + if (i < DATE_MIN || i > DATE_MAX) return DISP_E_OVERFLOW; + *o = (DATE)i; + return S_OK; +} +RETTYP _VarDateFromUI8(ULONG64 i, DATE* o) { + if (i > DATE_MAX) return DISP_E_OVERFLOW; + *o = (DATE)i; + return S_OK; +} + +/* BSTR */ +#define _VarBstrFromUI1 VarBstrFromUI4 +#define _VarBstrFromI2 VarBstrFromI4 +#define _VarBstrFromR4 VarBstrFromR8 +#define _VarBstrFromR8 VarBstrFromR8 +#define _VarBstrFromCy VarBstrFromCy +#define _VarBstrFromDate VarBstrFromDate +#define _VarBstrFromDisp(disp,lcid,out) VARIANT_FromDisp(disp, lcid, out, VT_BSTR) +#define _VarBstrFromBool VarBstrFromBool +#define _VarBstrFromI1 VarBstrFromI4 +#define _VarBstrFromUI2 VarBstrFromUI4 +#define _VarBstrFromI4 VarBstrFromI4 +#define _VarBstrFromUI4 VarBstrFromUI4 +#define _VarBstrFromDec VarBstrFromDec +#define _VarBstrFromI8 VarBstrFromI8 +#define _VarBstrFromUI8 VarBstrFromUI8 + +/* Macro to inline conversion from a float or double to any integer type, + * rounding according to the 'dutch' convention. + */ +#define OLEAUT32_DutchRound(typ, value, res) do { \ + double whole = (double)value < 0 ? ceil((double)value) : floor((double)value); \ + double fract = (double)value - whole; \ + if (fract > 0.5) res = (typ)whole + (typ)1; \ + else if (fract == 0.5) { typ is_odd = (typ)whole & 1; res = whole + is_odd; } \ + else if (fract >= 0.0) res = (typ)whole; \ + else if (fract == -0.5) { typ is_odd = (typ)whole & 1; res = whole - is_odd; } \ + else if (fract > -0.5) res = (typ)whole; \ + else res = (typ)whole - (typ)1; \ +} while(0); + +/* The localised characters that make up a valid number */ +typedef struct tagVARIANT_NUMBER_CHARS +{ + WCHAR cNegativeSymbol; + WCHAR cPositiveSymbol; + WCHAR cDecimalPoint; + WCHAR cDigitSeperator; + WCHAR cCurrencyLocal; + WCHAR cCurrencyLocal2; + WCHAR cCurrencyDecimalPoint; + WCHAR cCurrencyDigitSeperator; +} VARIANT_NUMBER_CHARS; + +void VARIANT_GetLocalisedNumberChars(VARIANT_NUMBER_CHARS*,LCID,DWORD); diff --git a/reactos/lib/oleaut32/vartype.c b/reactos/lib/oleaut32/vartype.c new file mode 100644 index 00000000000..8c03a5ae9e5 --- /dev/null +++ b/reactos/lib/oleaut32/vartype.c @@ -0,0 +1,6556 @@ +/* + * Low level variant functions + * + * Copyright 2003 Jon Griffiths + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define COBJMACROS +#define NONAMELESSUNION +#define NONAMELESSSTRUCT + +#include "wine/debug.h" +#include "wine/unicode.h" +#include "winbase.h" +#include "winuser.h" +#include "winnt.h" +#include "variant.h" +#include "resource.h" + +WINE_DEFAULT_DEBUG_CHANNEL(variant); + +extern HMODULE OLEAUT32_hModule; + +static const WCHAR szFloatFormatW[] = { '%','.','7','G','\0' }; +static const WCHAR szDoubleFormatW[] = { '%','.','1','5','G','\0' }; + +/* Copy data from one variant to another. */ +static inline void VARIANT_CopyData(const VARIANT *srcVar, VARTYPE vt, void *pOut) +{ + switch (vt) + { + case VT_I1: + case VT_UI1: memcpy(pOut, &V_UI1(srcVar), sizeof(BYTE)); break; + case VT_BOOL: + case VT_I2: + case VT_UI2: memcpy(pOut, &V_UI2(srcVar), sizeof(SHORT)); break; + case VT_R4: + case VT_INT: + case VT_I4: + case VT_UINT: + case VT_UI4: memcpy(pOut, &V_UI4(srcVar), sizeof (LONG)); break; + case VT_R8: + case VT_DATE: + case VT_CY: + case VT_I8: + case VT_UI8: memcpy(pOut, &V_UI8(srcVar), sizeof (LONG64)); break; + case VT_INT_PTR: memcpy(pOut, &V_INT_PTR(srcVar), sizeof (INT_PTR)); break; + case VT_DECIMAL: memcpy(pOut, &V_DECIMAL(srcVar), sizeof (DECIMAL)); break; + default: + FIXME("VT_ type %d unhandled, please report!\n", vt); + } +} + + +/* Coerce VT_BSTR to a numeric type */ +HRESULT VARIANT_NumberFromBstr(OLECHAR* pStrIn, LCID lcid, ULONG ulFlags, + void* pOut, VARTYPE vt) +{ + VARIANTARG dstVar; + HRESULT hRet; + NUMPARSE np; + BYTE rgb[1024]; + + /* Use VarParseNumFromStr/VarNumFromParseNum as MSDN indicates */ + np.cDig = sizeof(rgb) / sizeof(BYTE); + np.dwInFlags = NUMPRS_STD; + + hRet = VarParseNumFromStr(pStrIn, lcid, ulFlags, &np, rgb); + + if (SUCCEEDED(hRet)) + { + /* 1 << vt gives us the VTBIT constant for the destination number type */ + hRet = VarNumFromParseNum(&np, rgb, 1 << vt, &dstVar); + if (SUCCEEDED(hRet)) + VARIANT_CopyData(&dstVar, vt, pOut); + } + return hRet; +} + +/* Coerce VT_DISPATCH to another type */ +HRESULT VARIANT_FromDisp(IDispatch* pdispIn, LCID lcid, void* pOut, VARTYPE vt) +{ + static const DISPPARAMS emptyParams = { NULL, NULL, 0, 0 }; + VARIANTARG srcVar, dstVar; + HRESULT hRet; + + if (!pdispIn) + return DISP_E_BADVARTYPE; + + /* Get the default 'value' property from the IDispatch */ + hRet = IDispatch_Invoke(pdispIn, DISPID_VALUE, &IID_NULL, lcid, DISPATCH_PROPERTYGET, + (DISPPARAMS*)&emptyParams, &srcVar, NULL, NULL); + + if (SUCCEEDED(hRet)) + { + /* Convert the property to the requested type */ + V_VT(&dstVar) = VT_EMPTY; + hRet = VariantChangeTypeEx(&dstVar, &srcVar, lcid, 0, vt); + VariantClear(&srcVar); + + if (SUCCEEDED(hRet)) + { + VARIANT_CopyData(&dstVar, vt, pOut); + VariantClear(&srcVar); + } + } + else + hRet = DISP_E_TYPEMISMATCH; + return hRet; +} + +/* I1 + */ + +/************************************************************************ + * VarI1FromUI1 (OLEAUT32.244) + * + * Convert a VT_UI1 to a VT_I1. + * + * PARAMS + * bIn [I] Source + * pcOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarI1FromUI1(BYTE bIn, signed char* pcOut) +{ + return _VarI1FromUI1(bIn, pcOut); +} + +/************************************************************************ + * VarI1FromI2 (OLEAUT32.245) + * + * Convert a VT_I2 to a VT_I1. + * + * PARAMS + * sIn [I] Source + * pcOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarI1FromI2(SHORT sIn, signed char* pcOut) +{ + return _VarI1FromI2(sIn, pcOut); +} + +/************************************************************************ + * VarI1FromI4 (OLEAUT32.246) + * + * Convert a VT_I4 to a VT_I1. + * + * PARAMS + * iIn [I] Source + * pcOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarI1FromI4(LONG iIn, signed char* pcOut) +{ + return _VarI1FromI4(iIn, pcOut); +} + +/************************************************************************ + * VarI1FromR4 (OLEAUT32.247) + * + * Convert a VT_R4 to a VT_I1. + * + * PARAMS + * fltIn [I] Source + * pcOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarI1FromR4(FLOAT fltIn, signed char* pcOut) +{ + return _VarI1FromR4(fltIn, pcOut); +} + +/************************************************************************ + * VarI1FromR8 (OLEAUT32.248) + * + * Convert a VT_R8 to a VT_I1. + * + * PARAMS + * dblIn [I] Source + * pcOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * + * NOTES + * See VarI8FromR8() for details concerning rounding. + */ +HRESULT WINAPI VarI1FromR8(double dblIn, signed char* pcOut) +{ + if (dblIn < (double)I1_MIN || dblIn > (double)I1_MAX) + return DISP_E_OVERFLOW; + OLEAUT32_DutchRound(CHAR, dblIn, *pcOut); + return S_OK; +} + +/************************************************************************ + * VarI1FromDate (OLEAUT32.249) + * + * Convert a VT_DATE to a VT_I1. + * + * PARAMS + * dateIn [I] Source + * pcOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarI1FromDate(DATE dateIn, signed char* pcOut) +{ + return _VarI1FromDate(dateIn, pcOut); +} + +/************************************************************************ + * VarI1FromCy (OLEAUT32.250) + * + * Convert a VT_CY to a VT_I1. + * + * PARAMS + * cyIn [I] Source + * pcOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarI1FromCy(CY cyIn, signed char* pcOut) +{ + LONG i = I1_MAX + 1; + + _VarI4FromCy(cyIn, &i); + return _VarI1FromI4(i, pcOut); +} + +/************************************************************************ + * VarI1FromStr (OLEAUT32.251) + * + * Convert a VT_BSTR to a VT_I1. + * + * PARAMS + * strIn [I] Source + * lcid [I] LCID for the conversion + * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h") + * pcOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarI1FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, signed char* pcOut) +{ + return _VarI1FromStr(strIn, lcid, dwFlags, pcOut); +} + +/************************************************************************ + * VarI1FromDisp (OLEAUT32.252) + * + * Convert a VT_DISPATCH to a VT_I1. + * + * PARAMS + * pdispIn [I] Source + * lcid [I] LCID for conversion + * pcOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarI1FromDisp(IDispatch* pdispIn, LCID lcid, signed char* pcOut) +{ + return _VarI1FromDisp(pdispIn, lcid, pcOut); +} + +/************************************************************************ + * VarI1FromBool (OLEAUT32.253) + * + * Convert a VT_BOOL to a VT_I1. + * + * PARAMS + * boolIn [I] Source + * pcOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarI1FromBool(VARIANT_BOOL boolIn, signed char* pcOut) +{ + return _VarI1FromBool(boolIn, pcOut); +} + +/************************************************************************ + * VarI1FromUI2 (OLEAUT32.254) + * + * Convert a VT_UI2 to a VT_I1. + * + * PARAMS + * usIn [I] Source + * pcOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarI1FromUI2(USHORT usIn, signed char* pcOut) +{ + return _VarI1FromUI2(usIn, pcOut); +} + +/************************************************************************ + * VarI1FromUI4 (OLEAUT32.255) + * + * Convert a VT_UI4 to a VT_I1. + * + * PARAMS + * ulIn [I] Source + * pcOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarI1FromUI4(ULONG ulIn, signed char* pcOut) +{ + return _VarI1FromUI4(ulIn, pcOut); +} + +/************************************************************************ + * VarI1FromDec (OLEAUT32.256) + * + * Convert a VT_DECIMAL to a VT_I1. + * + * PARAMS + * pDecIn [I] Source + * pcOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarI1FromDec(DECIMAL *pdecIn, signed char* pcOut) +{ + LONG64 i64; + HRESULT hRet; + + hRet = _VarI8FromDec(pdecIn, &i64); + + if (SUCCEEDED(hRet)) + hRet = _VarI1FromI8(i64, pcOut); + return hRet; +} + +/************************************************************************ + * VarI1FromI8 (OLEAUT32.376) + * + * Convert a VT_I8 to a VT_I1. + * + * PARAMS + * llIn [I] Source + * pcOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarI1FromI8(LONG64 llIn, signed char* pcOut) +{ + return _VarI1FromI8(llIn, pcOut); +} + +/************************************************************************ + * VarI1FromUI8 (OLEAUT32.377) + * + * Convert a VT_UI8 to a VT_I1. + * + * PARAMS + * ullIn [I] Source + * pcOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarI1FromUI8(ULONG64 ullIn, signed char* pcOut) +{ + return _VarI1FromUI8(ullIn, pcOut); +} + +/* UI1 + */ + +/************************************************************************ + * VarUI1FromI2 (OLEAUT32.130) + * + * Convert a VT_I2 to a VT_UI1. + * + * PARAMS + * sIn [I] Source + * pbOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarUI1FromI2(SHORT sIn, BYTE* pbOut) +{ + return _VarUI1FromI2(sIn, pbOut); +} + +/************************************************************************ + * VarUI1FromI4 (OLEAUT32.131) + * + * Convert a VT_I4 to a VT_UI1. + * + * PARAMS + * iIn [I] Source + * pbOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarUI1FromI4(LONG iIn, BYTE* pbOut) +{ + return _VarUI1FromI4(iIn, pbOut); +} + +/************************************************************************ + * VarUI1FromR4 (OLEAUT32.132) + * + * Convert a VT_R4 to a VT_UI1. + * + * PARAMS + * fltIn [I] Source + * pbOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarUI1FromR4(FLOAT fltIn, BYTE* pbOut) +{ + return _VarUI1FromR4(fltIn, pbOut); +} + +/************************************************************************ + * VarUI1FromR8 (OLEAUT32.133) + * + * Convert a VT_R8 to a VT_UI1. + * + * PARAMS + * dblIn [I] Source + * pbOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * + * NOTES + * See VarI8FromR8() for details concerning rounding. + */ +HRESULT WINAPI VarUI1FromR8(double dblIn, BYTE* pbOut) +{ + if (dblIn < -0.5 || dblIn > (double)UI1_MAX) + return DISP_E_OVERFLOW; + OLEAUT32_DutchRound(BYTE, dblIn, *pbOut); + return S_OK; +} + +/************************************************************************ + * VarUI1FromCy (OLEAUT32.134) + * + * Convert a VT_CY to a VT_UI1. + * + * PARAMS + * cyIn [I] Source + * pbOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * + * NOTES + * Negative values >= -5000 will be converted to 0. + */ +HRESULT WINAPI VarUI1FromCy(CY cyIn, BYTE* pbOut) +{ + ULONG i = UI1_MAX + 1; + + _VarUI4FromCy(cyIn, &i); + return _VarUI1FromUI4(i, pbOut); +} + +/************************************************************************ + * VarUI1FromDate (OLEAUT32.135) + * + * Convert a VT_DATE to a VT_UI1. + * + * PARAMS + * dateIn [I] Source + * pbOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarUI1FromDate(DATE dateIn, BYTE* pbOut) +{ + return _VarUI1FromDate(dateIn, pbOut); +} + +/************************************************************************ + * VarUI1FromStr (OLEAUT32.136) + * + * Convert a VT_BSTR to a VT_UI1. + * + * PARAMS + * strIn [I] Source + * lcid [I] LCID for the conversion + * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h") + * pbOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarUI1FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, BYTE* pbOut) +{ + return _VarUI1FromStr(strIn, lcid, dwFlags, pbOut); +} + +/************************************************************************ + * VarUI1FromDisp (OLEAUT32.137) + * + * Convert a VT_DISPATCH to a VT_UI1. + * + * PARAMS + * pdispIn [I] Source + * lcid [I] LCID for conversion + * pbOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarUI1FromDisp(IDispatch* pdispIn, LCID lcid, BYTE* pbOut) +{ + return _VarUI1FromDisp(pdispIn, lcid, pbOut); +} + +/************************************************************************ + * VarUI1FromBool (OLEAUT32.138) + * + * Convert a VT_BOOL to a VT_UI1. + * + * PARAMS + * boolIn [I] Source + * pbOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarUI1FromBool(VARIANT_BOOL boolIn, BYTE* pbOut) +{ + return _VarUI1FromBool(boolIn, pbOut); +} + +/************************************************************************ + * VarUI1FromI1 (OLEAUT32.237) + * + * Convert a VT_I1 to a VT_UI1. + * + * PARAMS + * cIn [I] Source + * pbOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarUI1FromI1(signed char cIn, BYTE* pbOut) +{ + return _VarUI1FromI1(cIn, pbOut); +} + +/************************************************************************ + * VarUI1FromUI2 (OLEAUT32.238) + * + * Convert a VT_UI2 to a VT_UI1. + * + * PARAMS + * usIn [I] Source + * pbOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarUI1FromUI2(USHORT usIn, BYTE* pbOut) +{ + return _VarUI1FromUI2(usIn, pbOut); +} + +/************************************************************************ + * VarUI1FromUI4 (OLEAUT32.239) + * + * Convert a VT_UI4 to a VT_UI1. + * + * PARAMS + * ulIn [I] Source + * pbOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarUI1FromUI4(ULONG ulIn, BYTE* pbOut) +{ + return _VarUI1FromUI4(ulIn, pbOut); +} + +/************************************************************************ + * VarUI1FromDec (OLEAUT32.240) + * + * Convert a VT_DECIMAL to a VT_UI1. + * + * PARAMS + * pDecIn [I] Source + * pbOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarUI1FromDec(DECIMAL *pdecIn, BYTE* pbOut) +{ + LONG64 i64; + HRESULT hRet; + + hRet = _VarI8FromDec(pdecIn, &i64); + + if (SUCCEEDED(hRet)) + hRet = _VarUI1FromI8(i64, pbOut); + return hRet; +} + +/************************************************************************ + * VarUI1FromI8 (OLEAUT32.372) + * + * Convert a VT_I8 to a VT_UI1. + * + * PARAMS + * llIn [I] Source + * pbOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarUI1FromI8(LONG64 llIn, BYTE* pbOut) +{ + return _VarUI1FromI8(llIn, pbOut); +} + +/************************************************************************ + * VarUI1FromUI8 (OLEAUT32.373) + * + * Convert a VT_UI8 to a VT_UI1. + * + * PARAMS + * ullIn [I] Source + * pbOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarUI1FromUI8(ULONG64 ullIn, BYTE* pbOut) +{ + return _VarUI1FromUI8(ullIn, pbOut); +} + + +/* I2 + */ + +/************************************************************************ + * VarI2FromUI1 (OLEAUT32.48) + * + * Convert a VT_UI2 to a VT_I2. + * + * PARAMS + * bIn [I] Source + * psOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarI2FromUI1(BYTE bIn, SHORT* psOut) +{ + return _VarI2FromUI1(bIn, psOut); +} + +/************************************************************************ + * VarI2FromI4 (OLEAUT32.49) + * + * Convert a VT_I4 to a VT_I2. + * + * PARAMS + * iIn [I] Source + * psOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarI2FromI4(LONG iIn, SHORT* psOut) +{ + return _VarI2FromI4(iIn, psOut); +} + +/************************************************************************ + * VarI2FromR4 (OLEAUT32.50) + * + * Convert a VT_R4 to a VT_I2. + * + * PARAMS + * fltIn [I] Source + * psOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarI2FromR4(FLOAT fltIn, SHORT* psOut) +{ + return _VarI2FromR4(fltIn, psOut); +} + +/************************************************************************ + * VarI2FromR8 (OLEAUT32.51) + * + * Convert a VT_R8 to a VT_I2. + * + * PARAMS + * dblIn [I] Source + * psOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + * + * NOTES + * See VarI8FromR8() for details concerning rounding. + */ +HRESULT WINAPI VarI2FromR8(double dblIn, SHORT* psOut) +{ + if (dblIn < (double)I2_MIN || dblIn > (double)I2_MAX) + return DISP_E_OVERFLOW; + OLEAUT32_DutchRound(SHORT, dblIn, *psOut); + return S_OK; +} + +/************************************************************************ + * VarI2FromCy (OLEAUT32.52) + * + * Convert a VT_CY to a VT_I2. + * + * PARAMS + * cyIn [I] Source + * psOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarI2FromCy(CY cyIn, SHORT* psOut) +{ + LONG i = I2_MAX + 1; + + _VarI4FromCy(cyIn, &i); + return _VarI2FromI4(i, psOut); +} + +/************************************************************************ + * VarI2FromDate (OLEAUT32.53) + * + * Convert a VT_DATE to a VT_I2. + * + * PARAMS + * dateIn [I] Source + * psOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarI2FromDate(DATE dateIn, SHORT* psOut) +{ + return _VarI2FromDate(dateIn, psOut); +} + +/************************************************************************ + * VarI2FromStr (OLEAUT32.54) + * + * Convert a VT_BSTR to a VT_I2. + * + * PARAMS + * strIn [I] Source + * lcid [I] LCID for the conversion + * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h") + * psOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if any parameter is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarI2FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, SHORT* psOut) +{ + return _VarI2FromStr(strIn, lcid, dwFlags, psOut); +} + +/************************************************************************ + * VarI2FromDisp (OLEAUT32.55) + * + * Convert a VT_DISPATCH to a VT_I2. + * + * PARAMS + * pdispIn [I] Source + * lcid [I] LCID for conversion + * psOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if pdispIn is invalid, + * DISP_E_OVERFLOW, if the value will not fit in the destination, + * DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarI2FromDisp(IDispatch* pdispIn, LCID lcid, SHORT* psOut) +{ + return _VarI2FromDisp(pdispIn, lcid, psOut); +} + +/************************************************************************ + * VarI2FromBool (OLEAUT32.56) + * + * Convert a VT_BOOL to a VT_I2. + * + * PARAMS + * boolIn [I] Source + * psOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarI2FromBool(VARIANT_BOOL boolIn, SHORT* psOut) +{ + return _VarI2FromBool(boolIn, psOut); +} + +/************************************************************************ + * VarI2FromI1 (OLEAUT32.205) + * + * Convert a VT_I1 to a VT_I2. + * + * PARAMS + * cIn [I] Source + * psOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarI2FromI1(signed char cIn, SHORT* psOut) +{ + return _VarI2FromI1(cIn, psOut); +} + +/************************************************************************ + * VarI2FromUI2 (OLEAUT32.206) + * + * Convert a VT_UI2 to a VT_I2. + * + * PARAMS + * usIn [I] Source + * psOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarI2FromUI2(USHORT usIn, SHORT* psOut) +{ + return _VarI2FromUI2(usIn, psOut); +} + +/************************************************************************ + * VarI2FromUI4 (OLEAUT32.207) + * + * Convert a VT_UI4 to a VT_I2. + * + * PARAMS + * ulIn [I] Source + * psOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarI2FromUI4(ULONG ulIn, SHORT* psOut) +{ + return _VarI2FromUI4(ulIn, psOut); +} + +/************************************************************************ + * VarI2FromDec (OLEAUT32.208) + * + * Convert a VT_DECIMAL to a VT_I2. + * + * PARAMS + * pDecIn [I] Source + * psOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarI2FromDec(DECIMAL *pdecIn, SHORT* psOut) +{ + LONG64 i64; + HRESULT hRet; + + hRet = _VarI8FromDec(pdecIn, &i64); + + if (SUCCEEDED(hRet)) + hRet = _VarI2FromI8(i64, psOut); + return hRet; +} + +/************************************************************************ + * VarI2FromI8 (OLEAUT32.346) + * + * Convert a VT_I8 to a VT_I2. + * + * PARAMS + * llIn [I] Source + * psOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarI2FromI8(LONG64 llIn, SHORT* psOut) +{ + return _VarI2FromI8(llIn, psOut); +} + +/************************************************************************ + * VarI2FromUI8 (OLEAUT32.347) + * + * Convert a VT_UI8 to a VT_I2. + * + * PARAMS + * ullIn [I] Source + * psOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarI2FromUI8(ULONG64 ullIn, SHORT* psOut) +{ + return _VarI2FromUI8(ullIn, psOut); +} + +/* UI2 + */ + +/************************************************************************ + * VarUI2FromUI1 (OLEAUT32.257) + * + * Convert a VT_UI1 to a VT_UI2. + * + * PARAMS + * bIn [I] Source + * pusOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarUI2FromUI1(BYTE bIn, USHORT* pusOut) +{ + return _VarUI2FromUI1(bIn, pusOut); +} + +/************************************************************************ + * VarUI2FromI2 (OLEAUT32.258) + * + * Convert a VT_I2 to a VT_UI2. + * + * PARAMS + * sIn [I] Source + * pusOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarUI2FromI2(SHORT sIn, USHORT* pusOut) +{ + return _VarUI2FromI2(sIn, pusOut); +} + +/************************************************************************ + * VarUI2FromI4 (OLEAUT32.259) + * + * Convert a VT_I4 to a VT_UI2. + * + * PARAMS + * iIn [I] Source + * pusOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarUI2FromI4(LONG iIn, USHORT* pusOut) +{ + return _VarUI2FromI4(iIn, pusOut); +} + +/************************************************************************ + * VarUI2FromR4 (OLEAUT32.260) + * + * Convert a VT_R4 to a VT_UI2. + * + * PARAMS + * fltIn [I] Source + * pusOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarUI2FromR4(FLOAT fltIn, USHORT* pusOut) +{ + return _VarUI2FromR4(fltIn, pusOut); +} + +/************************************************************************ + * VarUI2FromR8 (OLEAUT32.261) + * + * Convert a VT_R8 to a VT_UI2. + * + * PARAMS + * dblIn [I] Source + * pusOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + * + * NOTES + * See VarI8FromR8() for details concerning rounding. + */ +HRESULT WINAPI VarUI2FromR8(double dblIn, USHORT* pusOut) +{ + if (dblIn < -0.5 || dblIn > (double)UI2_MAX) + return DISP_E_OVERFLOW; + OLEAUT32_DutchRound(USHORT, dblIn, *pusOut); + return S_OK; +} + +/************************************************************************ + * VarUI2FromDate (OLEAUT32.262) + * + * Convert a VT_DATE to a VT_UI2. + * + * PARAMS + * dateIn [I] Source + * pusOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarUI2FromDate(DATE dateIn, USHORT* pusOut) +{ + return _VarUI2FromDate(dateIn, pusOut); +} + +/************************************************************************ + * VarUI2FromCy (OLEAUT32.263) + * + * Convert a VT_CY to a VT_UI2. + * + * PARAMS + * cyIn [I] Source + * pusOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + * + * NOTES + * Negative values >= -5000 will be converted to 0. + */ +HRESULT WINAPI VarUI2FromCy(CY cyIn, USHORT* pusOut) +{ + ULONG i = UI2_MAX + 1; + + _VarUI4FromCy(cyIn, &i); + return _VarUI2FromUI4(i, pusOut); +} + +/************************************************************************ + * VarUI2FromStr (OLEAUT32.264) + * + * Convert a VT_BSTR to a VT_UI2. + * + * PARAMS + * strIn [I] Source + * lcid [I] LCID for the conversion + * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h") + * pusOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + * DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarUI2FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, USHORT* pusOut) +{ + return _VarUI2FromStr(strIn, lcid, dwFlags, pusOut); +} + +/************************************************************************ + * VarUI2FromDisp (OLEAUT32.265) + * + * Convert a VT_DISPATCH to a VT_UI2. + * + * PARAMS + * pdispIn [I] Source + * lcid [I] LCID for conversion + * pusOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarUI2FromDisp(IDispatch* pdispIn, LCID lcid, USHORT* pusOut) +{ + return _VarUI2FromDisp(pdispIn, lcid, pusOut); +} + +/************************************************************************ + * VarUI2FromBool (OLEAUT32.266) + * + * Convert a VT_BOOL to a VT_UI2. + * + * PARAMS + * boolIn [I] Source + * pusOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarUI2FromBool(VARIANT_BOOL boolIn, USHORT* pusOut) +{ + return _VarUI2FromBool(boolIn, pusOut); +} + +/************************************************************************ + * VarUI2FromI1 (OLEAUT32.267) + * + * Convert a VT_I1 to a VT_UI2. + * + * PARAMS + * cIn [I] Source + * pusOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarUI2FromI1(signed char cIn, USHORT* pusOut) +{ + return _VarUI2FromI1(cIn, pusOut); +} + +/************************************************************************ + * VarUI2FromUI4 (OLEAUT32.268) + * + * Convert a VT_UI4 to a VT_UI2. + * + * PARAMS + * ulIn [I] Source + * pusOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarUI2FromUI4(ULONG ulIn, USHORT* pusOut) +{ + return _VarUI2FromUI4(ulIn, pusOut); +} + +/************************************************************************ + * VarUI2FromDec (OLEAUT32.269) + * + * Convert a VT_DECIMAL to a VT_UI2. + * + * PARAMS + * pDecIn [I] Source + * pusOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarUI2FromDec(DECIMAL *pdecIn, USHORT* pusOut) +{ + LONG64 i64; + HRESULT hRet; + + hRet = _VarI8FromDec(pdecIn, &i64); + + if (SUCCEEDED(hRet)) + hRet = _VarUI2FromI8(i64, pusOut); + return hRet; +} + +/************************************************************************ + * VarUI2FromI8 (OLEAUT32.378) + * + * Convert a VT_I8 to a VT_UI2. + * + * PARAMS + * llIn [I] Source + * pusOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarUI2FromI8(LONG64 llIn, USHORT* pusOut) +{ + return _VarUI2FromI8(llIn, pusOut); +} + +/************************************************************************ + * VarUI2FromUI8 (OLEAUT32.379) + * + * Convert a VT_UI8 to a VT_UI2. + * + * PARAMS + * ullIn [I] Source + * pusOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarUI2FromUI8(ULONG64 ullIn, USHORT* pusOut) +{ + return _VarUI2FromUI8(ullIn, pusOut); +} + +/* I4 + */ + +/************************************************************************ + * VarI4FromUI1 (OLEAUT32.58) + * + * Convert a VT_UI1 to a VT_I4. + * + * PARAMS + * bIn [I] Source + * piOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarI4FromUI1(BYTE bIn, LONG *piOut) +{ + return _VarI4FromUI1(bIn, piOut); +} + +/************************************************************************ + * VarI4FromI2 (OLEAUT32.59) + * + * Convert a VT_I2 to a VT_I4. + * + * PARAMS + * sIn [I] Source + * piOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarI4FromI2(SHORT sIn, LONG *piOut) +{ + return _VarI4FromI2(sIn, piOut); +} + +/************************************************************************ + * VarI4FromR4 (OLEAUT32.60) + * + * Convert a VT_R4 to a VT_I4. + * + * PARAMS + * fltIn [I] Source + * piOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarI4FromR4(FLOAT fltIn, LONG *piOut) +{ + return _VarI4FromR4(fltIn, piOut); +} + +/************************************************************************ + * VarI4FromR8 (OLEAUT32.61) + * + * Convert a VT_R8 to a VT_I4. + * + * PARAMS + * dblIn [I] Source + * piOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + * + * NOTES + * See VarI8FromR8() for details concerning rounding. + */ +HRESULT WINAPI VarI4FromR8(double dblIn, LONG *piOut) +{ + if (dblIn < (double)I4_MIN || dblIn > (double)I4_MAX) + return DISP_E_OVERFLOW; + OLEAUT32_DutchRound(LONG, dblIn, *piOut); + return S_OK; +} + +/************************************************************************ + * VarI4FromCy (OLEAUT32.62) + * + * Convert a VT_CY to a VT_I4. + * + * PARAMS + * cyIn [I] Source + * piOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarI4FromCy(CY cyIn, LONG *piOut) +{ + double d = cyIn.int64 / CY_MULTIPLIER_F; + return _VarI4FromR8(d, piOut); +} + +/************************************************************************ + * VarI4FromDate (OLEAUT32.63) + * + * Convert a VT_DATE to a VT_I4. + * + * PARAMS + * dateIn [I] Source + * piOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarI4FromDate(DATE dateIn, LONG *piOut) +{ + return _VarI4FromDate(dateIn, piOut); +} + +/************************************************************************ + * VarI4FromStr (OLEAUT32.64) + * + * Convert a VT_BSTR to a VT_I4. + * + * PARAMS + * strIn [I] Source + * lcid [I] LCID for the conversion + * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h") + * piOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if any parameter is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * DISP_E_TYPEMISMATCH, if strIn cannot be converted + */ +HRESULT WINAPI VarI4FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, LONG *piOut) +{ + return _VarI4FromStr(strIn, lcid, dwFlags, piOut); +} + +/************************************************************************ + * VarI4FromDisp (OLEAUT32.65) + * + * Convert a VT_DISPATCH to a VT_I4. + * + * PARAMS + * pdispIn [I] Source + * lcid [I] LCID for conversion + * piOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarI4FromDisp(IDispatch* pdispIn, LCID lcid, LONG *piOut) +{ + return _VarI4FromDisp(pdispIn, lcid, piOut); +} + +/************************************************************************ + * VarI4FromBool (OLEAUT32.66) + * + * Convert a VT_BOOL to a VT_I4. + * + * PARAMS + * boolIn [I] Source + * piOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarI4FromBool(VARIANT_BOOL boolIn, LONG *piOut) +{ + return _VarI4FromBool(boolIn, piOut); +} + +/************************************************************************ + * VarI4FromI1 (OLEAUT32.209) + * + * Convert a VT_I4 to a VT_I4. + * + * PARAMS + * cIn [I] Source + * piOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarI4FromI1(signed char cIn, LONG *piOut) +{ + return _VarI4FromI1(cIn, piOut); +} + +/************************************************************************ + * VarI4FromUI2 (OLEAUT32.210) + * + * Convert a VT_UI2 to a VT_I4. + * + * PARAMS + * usIn [I] Source + * piOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarI4FromUI2(USHORT usIn, LONG *piOut) +{ + return _VarI4FromUI2(usIn, piOut); +} + +/************************************************************************ + * VarI4FromUI4 (OLEAUT32.211) + * + * Convert a VT_UI4 to a VT_I4. + * + * PARAMS + * ulIn [I] Source + * piOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarI4FromUI4(ULONG ulIn, LONG *piOut) +{ + return _VarI4FromUI4(ulIn, piOut); +} + +/************************************************************************ + * VarI4FromDec (OLEAUT32.212) + * + * Convert a VT_DECIMAL to a VT_I4. + * + * PARAMS + * pDecIn [I] Source + * piOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if pdecIn is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarI4FromDec(DECIMAL *pdecIn, LONG *piOut) +{ + LONG64 i64; + HRESULT hRet; + + hRet = _VarI8FromDec(pdecIn, &i64); + + if (SUCCEEDED(hRet)) + hRet = _VarI4FromI8(i64, piOut); + return hRet; +} + +/************************************************************************ + * VarI4FromI8 (OLEAUT32.348) + * + * Convert a VT_I8 to a VT_I4. + * + * PARAMS + * llIn [I] Source + * piOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarI4FromI8(LONG64 llIn, LONG *piOut) +{ + return _VarI4FromI8(llIn, piOut); +} + +/************************************************************************ + * VarI4FromUI8 (OLEAUT32.349) + * + * Convert a VT_UI8 to a VT_I4. + * + * PARAMS + * ullIn [I] Source + * piOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarI4FromUI8(ULONG64 ullIn, LONG *piOut) +{ + return _VarI4FromUI8(ullIn, piOut); +} + +/* UI4 + */ + +/************************************************************************ + * VarUI4FromUI1 (OLEAUT32.270) + * + * Convert a VT_UI1 to a VT_UI4. + * + * PARAMS + * bIn [I] Source + * pulOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarUI4FromUI1(BYTE bIn, ULONG *pulOut) +{ + return _VarUI4FromUI1(bIn, pulOut); +} + +/************************************************************************ + * VarUI4FromI2 (OLEAUT32.271) + * + * Convert a VT_I2 to a VT_UI4. + * + * PARAMS + * sIn [I] Source + * pulOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarUI4FromI2(SHORT sIn, ULONG *pulOut) +{ + return _VarUI4FromI2(sIn, pulOut); +} + +/************************************************************************ + * VarUI4FromI4 (OLEAUT32.272) + * + * Convert a VT_I4 to a VT_UI4. + * + * PARAMS + * iIn [I] Source + * pulOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarUI4FromI4(LONG iIn, ULONG *pulOut) +{ + return _VarUI4FromI4(iIn, pulOut); +} + +/************************************************************************ + * VarUI4FromR4 (OLEAUT32.273) + * + * Convert a VT_R4 to a VT_UI4. + * + * PARAMS + * fltIn [I] Source + * pulOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarUI4FromR4(FLOAT fltIn, ULONG *pulOut) +{ + return _VarUI4FromR4(fltIn, pulOut); +} + +/************************************************************************ + * VarUI4FromR8 (OLEAUT32.274) + * + * Convert a VT_R8 to a VT_UI4. + * + * PARAMS + * dblIn [I] Source + * pulOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + * + * NOTES + * See VarI8FromR8() for details concerning rounding. + */ +HRESULT WINAPI VarUI4FromR8(double dblIn, ULONG *pulOut) +{ + if (dblIn < -0.5 || dblIn > (double)UI4_MAX) + return DISP_E_OVERFLOW; + OLEAUT32_DutchRound(ULONG, dblIn, *pulOut); + return S_OK; +} + +/************************************************************************ + * VarUI4FromDate (OLEAUT32.275) + * + * Convert a VT_DATE to a VT_UI4. + * + * PARAMS + * dateIn [I] Source + * pulOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarUI4FromDate(DATE dateIn, ULONG *pulOut) +{ + return _VarUI4FromDate(dateIn, pulOut); +} + +/************************************************************************ + * VarUI4FromCy (OLEAUT32.276) + * + * Convert a VT_CY to a VT_UI4. + * + * PARAMS + * cyIn [I] Source + * pulOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarUI4FromCy(CY cyIn, ULONG *pulOut) +{ + double d = cyIn.int64 / CY_MULTIPLIER_F; + return _VarUI4FromR8(d, pulOut); +} + +/************************************************************************ + * VarUI4FromStr (OLEAUT32.277) + * + * Convert a VT_BSTR to a VT_UI4. + * + * PARAMS + * strIn [I] Source + * lcid [I] LCID for the conversion + * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h") + * pulOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if any parameter is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * DISP_E_TYPEMISMATCH, if strIn cannot be converted + */ +HRESULT WINAPI VarUI4FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, ULONG *pulOut) +{ + return _VarUI4FromStr(strIn, lcid, dwFlags, pulOut); +} + +/************************************************************************ + * VarUI4FromDisp (OLEAUT32.278) + * + * Convert a VT_DISPATCH to a VT_UI4. + * + * PARAMS + * pdispIn [I] Source + * lcid [I] LCID for conversion + * pulOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarUI4FromDisp(IDispatch* pdispIn, LCID lcid, ULONG *pulOut) +{ + return _VarUI4FromDisp(pdispIn, lcid, pulOut); +} + +/************************************************************************ + * VarUI4FromBool (OLEAUT32.279) + * + * Convert a VT_BOOL to a VT_UI4. + * + * PARAMS + * boolIn [I] Source + * pulOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarUI4FromBool(VARIANT_BOOL boolIn, ULONG *pulOut) +{ + return _VarUI4FromBool(boolIn, pulOut); +} + +/************************************************************************ + * VarUI4FromI1 (OLEAUT32.280) + * + * Convert a VT_I1 to a VT_UI4. + * + * PARAMS + * cIn [I] Source + * pulOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarUI4FromI1(signed char cIn, ULONG *pulOut) +{ + return _VarUI4FromI1(cIn, pulOut); +} + +/************************************************************************ + * VarUI4FromUI2 (OLEAUT32.281) + * + * Convert a VT_UI2 to a VT_UI4. + * + * PARAMS + * usIn [I] Source + * pulOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarUI4FromUI2(USHORT usIn, ULONG *pulOut) +{ + return _VarUI4FromUI2(usIn, pulOut); +} + +/************************************************************************ + * VarUI4FromDec (OLEAUT32.282) + * + * Convert a VT_DECIMAL to a VT_UI4. + * + * PARAMS + * pDecIn [I] Source + * pulOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if pdecIn is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarUI4FromDec(DECIMAL *pdecIn, ULONG *pulOut) +{ + LONG64 i64; + HRESULT hRet; + + hRet = _VarI8FromDec(pdecIn, &i64); + + if (SUCCEEDED(hRet)) + hRet = _VarUI4FromI8(i64, pulOut); + return hRet; +} + +/************************************************************************ + * VarUI4FromI8 (OLEAUT32.425) + * + * Convert a VT_I8 to a VT_UI4. + * + * PARAMS + * llIn [I] Source + * pulOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarUI4FromI8(LONG64 llIn, ULONG *pulOut) +{ + return _VarUI4FromI8(llIn, pulOut); +} + +/************************************************************************ + * VarUI4FromUI8 (OLEAUT32.426) + * + * Convert a VT_UI8 to a VT_UI4. + * + * PARAMS + * ullIn [I] Source + * pulOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarUI4FromUI8(ULONG64 ullIn, ULONG *pulOut) +{ + return _VarUI4FromUI8(ullIn, pulOut); +} + +/* I8 + */ + +/************************************************************************ + * VarI8FromUI1 (OLEAUT32.333) + * + * Convert a VT_UI1 to a VT_I8. + * + * PARAMS + * bIn [I] Source + * pi64Out [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarI8FromUI1(BYTE bIn, LONG64* pi64Out) +{ + return _VarI8FromUI1(bIn, pi64Out); +} + + +/************************************************************************ + * VarI8FromI2 (OLEAUT32.334) + * + * Convert a VT_I2 to a VT_I8. + * + * PARAMS + * sIn [I] Source + * pi64Out [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarI8FromI2(SHORT sIn, LONG64* pi64Out) +{ + return _VarI8FromI2(sIn, pi64Out); +} + +/************************************************************************ + * VarI8FromR4 (OLEAUT32.335) + * + * Convert a VT_R4 to a VT_I8. + * + * PARAMS + * fltIn [I] Source + * pi64Out [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarI8FromR4(FLOAT fltIn, LONG64* pi64Out) +{ + return _VarI8FromR4(fltIn, pi64Out); +} + +/************************************************************************ + * VarI8FromR8 (OLEAUT32.336) + * + * Convert a VT_R8 to a VT_I8. + * + * PARAMS + * dblIn [I] Source + * pi64Out [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * + * NOTES + * Only values that fit into 63 bits are accepted. Due to rounding issues, + * very high or low values will not be accurately converted. + * + * Numbers are rounded using Dutch rounding, as follows: + * + *| Fractional Part Sign Direction Example + *| --------------- ---- --------- ------- + *| < 0.5 + Down 0.4 -> 0.0 + *| < 0.5 - Up -0.4 -> 0.0 + *| > 0.5 + Up 0.6 -> 1.0 + *| < 0.5 - Up -0.6 -> -1.0 + *| = 0.5 + Up/Down Down if even, Up if odd + *| = 0.5 - Up/Down Up if even, Down if odd + * + * This system is often used in supermarkets. + */ +HRESULT WINAPI VarI8FromR8(double dblIn, LONG64* pi64Out) +{ + if ( dblIn < -4611686018427387904.0 || dblIn >= 4611686018427387904.0) + return DISP_E_OVERFLOW; + OLEAUT32_DutchRound(LONG64, dblIn, *pi64Out); + return S_OK; +} + +/************************************************************************ + * VarI8FromCy (OLEAUT32.337) + * + * Convert a VT_CY to a VT_I8. + * + * PARAMS + * cyIn [I] Source + * pi64Out [O] Destination + * + * RETURNS + * S_OK. + * + * NOTES + * All negative numbers are rounded down by 1, including those that are + * evenly divisible by 10000 (this is a Win32 bug that Wine mimics). + * Positive numbers are rounded using Dutch rounding: See VarI8FromR8() + * for details. + */ +HRESULT WINAPI VarI8FromCy(CY cyIn, LONG64* pi64Out) +{ + *pi64Out = cyIn.int64 / CY_MULTIPLIER; + + if (cyIn.int64 < 0) + (*pi64Out)--; /* Mimic Win32 bug */ + else + { + cyIn.int64 -= *pi64Out * CY_MULTIPLIER; /* cyIn.s.Lo now holds fractional remainder */ + + if (cyIn.s.Lo > CY_HALF || (cyIn.s.Lo == CY_HALF && (*pi64Out & 0x1))) + (*pi64Out)++; + } + return S_OK; +} + +/************************************************************************ + * VarI8FromDate (OLEAUT32.338) + * + * Convert a VT_DATE to a VT_I8. + * + * PARAMS + * dateIn [I] Source + * pi64Out [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarI8FromDate(DATE dateIn, LONG64* pi64Out) +{ + return _VarI8FromDate(dateIn, pi64Out); +} + +/************************************************************************ + * VarI8FromStr (OLEAUT32.339) + * + * Convert a VT_BSTR to a VT_I8. + * + * PARAMS + * strIn [I] Source + * lcid [I] LCID for the conversion + * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h") + * pi64Out [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarI8FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, LONG64* pi64Out) +{ + return _VarI8FromStr(strIn, lcid, dwFlags, pi64Out); +} + +/************************************************************************ + * VarI8FromDisp (OLEAUT32.340) + * + * Convert a VT_DISPATCH to a VT_I8. + * + * PARAMS + * pdispIn [I] Source + * lcid [I] LCID for conversion + * pi64Out [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarI8FromDisp(IDispatch* pdispIn, LCID lcid, LONG64* pi64Out) +{ + return _VarI8FromDisp(pdispIn, lcid, pi64Out); +} + +/************************************************************************ + * VarI8FromBool (OLEAUT32.341) + * + * Convert a VT_BOOL to a VT_I8. + * + * PARAMS + * boolIn [I] Source + * pi64Out [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarI8FromBool(VARIANT_BOOL boolIn, LONG64* pi64Out) +{ + return _VarI8FromBool(boolIn, pi64Out); +} + +/************************************************************************ + * VarI8FromI1 (OLEAUT32.342) + * + * Convert a VT_I1 to a VT_I8. + * + * PARAMS + * cIn [I] Source + * pi64Out [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarI8FromI1(signed char cIn, LONG64* pi64Out) +{ + return _VarI8FromI1(cIn, pi64Out); +} + +/************************************************************************ + * VarI8FromUI2 (OLEAUT32.343) + * + * Convert a VT_UI2 to a VT_I8. + * + * PARAMS + * usIn [I] Source + * pi64Out [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarI8FromUI2(USHORT usIn, LONG64* pi64Out) +{ + return _VarI8FromUI2(usIn, pi64Out); +} + +/************************************************************************ + * VarI8FromUI4 (OLEAUT32.344) + * + * Convert a VT_UI4 to a VT_I8. + * + * PARAMS + * ulIn [I] Source + * pi64Out [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarI8FromUI4(ULONG ulIn, LONG64* pi64Out) +{ + return _VarI8FromUI4(ulIn, pi64Out); +} + +/************************************************************************ + * VarI8FromDec (OLEAUT32.345) + * + * Convert a VT_DECIMAL to a VT_I8. + * + * PARAMS + * pDecIn [I] Source + * pi64Out [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarI8FromDec(DECIMAL *pdecIn, LONG64* pi64Out) +{ + if (!DEC_SCALE(pdecIn)) + { + /* This decimal is just a 96 bit integer */ + if (DEC_SIGN(pdecIn) & ~DECIMAL_NEG) + return E_INVALIDARG; + + if (DEC_HI32(pdecIn) || DEC_MID32(pdecIn) & 0x80000000) + return DISP_E_OVERFLOW; + + if (DEC_SIGN(pdecIn)) + *pi64Out = -DEC_LO64(pdecIn); + else + *pi64Out = DEC_LO64(pdecIn); + return S_OK; + } + else + { + /* Decimal contains a floating point number */ + HRESULT hRet; + double dbl; + + hRet = _VarR8FromDec(pdecIn, &dbl); + if (SUCCEEDED(hRet)) + hRet = VarI8FromR8(dbl, pi64Out); + return hRet; + } +} + +/************************************************************************ + * VarI8FromUI8 (OLEAUT32.427) + * + * Convert a VT_UI8 to a VT_I8. + * + * PARAMS + * ullIn [I] Source + * pi64Out [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarI8FromUI8(ULONG64 ullIn, LONG64* pi64Out) +{ + return _VarI8FromUI8(ullIn, pi64Out); +} + +/* UI8 + */ + +/************************************************************************ + * VarUI8FromI8 (OLEAUT32.428) + * + * Convert a VT_I8 to a VT_UI8. + * + * PARAMS + * ulIn [I] Source + * pui64Out [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarUI8FromI8(LONG64 llIn, ULONG64* pui64Out) +{ + return _VarUI8FromI8(llIn, pui64Out); +} + +/************************************************************************ + * VarUI8FromUI1 (OLEAUT32.429) + * + * Convert a VT_UI1 to a VT_UI8. + * + * PARAMS + * bIn [I] Source + * pui64Out [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarUI8FromUI1(BYTE bIn, ULONG64* pui64Out) +{ + return _VarUI8FromUI1(bIn, pui64Out); +} + +/************************************************************************ + * VarUI8FromI2 (OLEAUT32.430) + * + * Convert a VT_I2 to a VT_UI8. + * + * PARAMS + * sIn [I] Source + * pui64Out [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarUI8FromI2(SHORT sIn, ULONG64* pui64Out) +{ + return _VarUI8FromI2(sIn, pui64Out); +} + +/************************************************************************ + * VarUI8FromR4 (OLEAUT32.431) + * + * Convert a VT_R4 to a VT_UI8. + * + * PARAMS + * fltIn [I] Source + * pui64Out [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarUI8FromR4(FLOAT fltIn, ULONG64* pui64Out) +{ + return _VarUI8FromR4(fltIn, pui64Out); +} + +/************************************************************************ + * VarUI8FromR8 (OLEAUT32.432) + * + * Convert a VT_R8 to a VT_UI8. + * + * PARAMS + * dblIn [I] Source + * pui64Out [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * + * NOTES + * See VarI8FromR8() for details concerning rounding. + */ +HRESULT WINAPI VarUI8FromR8(double dblIn, ULONG64* pui64Out) +{ + if (dblIn < -0.5 || dblIn > 1.844674407370955e19) + return DISP_E_OVERFLOW; + OLEAUT32_DutchRound(ULONG64, dblIn, *pui64Out); + return S_OK; +} + +/************************************************************************ + * VarUI8FromCy (OLEAUT32.433) + * + * Convert a VT_CY to a VT_UI8. + * + * PARAMS + * cyIn [I] Source + * pui64Out [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * + * NOTES + * Negative values >= -5000 will be converted to 0. + */ +HRESULT WINAPI VarUI8FromCy(CY cyIn, ULONG64* pui64Out) +{ + if (cyIn.int64 < 0) + { + if (cyIn.int64 < -CY_HALF) + return DISP_E_OVERFLOW; + *pui64Out = 0; + } + else + { + *pui64Out = cyIn.int64 / CY_MULTIPLIER; + + cyIn.int64 -= *pui64Out * CY_MULTIPLIER; /* cyIn.s.Lo now holds fractional remainder */ + + if (cyIn.s.Lo > CY_HALF || (cyIn.s.Lo == CY_HALF && (*pui64Out & 0x1))) + (*pui64Out)++; + } + return S_OK; +} + +/************************************************************************ + * VarUI8FromDate (OLEAUT32.434) + * + * Convert a VT_DATE to a VT_UI8. + * + * PARAMS + * dateIn [I] Source + * pui64Out [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarUI8FromDate(DATE dateIn, ULONG64* pui64Out) +{ + return _VarUI8FromDate(dateIn, pui64Out); +} + +/************************************************************************ + * VarUI8FromStr (OLEAUT32.435) + * + * Convert a VT_BSTR to a VT_UI8. + * + * PARAMS + * strIn [I] Source + * lcid [I] LCID for the conversion + * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h") + * pui64Out [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarUI8FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, ULONG64* pui64Out) +{ + return _VarUI8FromStr(strIn, lcid, dwFlags, pui64Out); +} + +/************************************************************************ + * VarUI8FromDisp (OLEAUT32.436) + * + * Convert a VT_DISPATCH to a VT_UI8. + * + * PARAMS + * pdispIn [I] Source + * lcid [I] LCID for conversion + * pui64Out [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarUI8FromDisp(IDispatch* pdispIn, LCID lcid, ULONG64* pui64Out) +{ + return _VarUI8FromDisp(pdispIn, lcid, pui64Out); +} + +/************************************************************************ + * VarUI8FromBool (OLEAUT32.437) + * + * Convert a VT_BOOL to a VT_UI8. + * + * PARAMS + * boolIn [I] Source + * pui64Out [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarUI8FromBool(VARIANT_BOOL boolIn, ULONG64* pui64Out) +{ + return _VarUI8FromBool(boolIn, pui64Out); +} +/************************************************************************ + * VarUI8FromI1 (OLEAUT32.438) + * + * Convert a VT_I1 to a VT_UI8. + * + * PARAMS + * cIn [I] Source + * pui64Out [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarUI8FromI1(signed char cIn, ULONG64* pui64Out) +{ + return _VarUI8FromI1(cIn, pui64Out); +} + +/************************************************************************ + * VarUI8FromUI2 (OLEAUT32.439) + * + * Convert a VT_UI2 to a VT_UI8. + * + * PARAMS + * usIn [I] Source + * pui64Out [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarUI8FromUI2(USHORT usIn, ULONG64* pui64Out) +{ + return _VarUI8FromUI2(usIn, pui64Out); +} + +/************************************************************************ + * VarUI8FromUI4 (OLEAUT32.440) + * + * Convert a VT_UI4 to a VT_UI8. + * + * PARAMS + * ulIn [I] Source + * pui64Out [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarUI8FromUI4(ULONG ulIn, ULONG64* pui64Out) +{ + return _VarUI8FromUI4(ulIn, pui64Out); +} + +/************************************************************************ + * VarUI8FromDec (OLEAUT32.441) + * + * Convert a VT_DECIMAL to a VT_UI8. + * + * PARAMS + * pDecIn [I] Source + * pui64Out [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * + * NOTES + * Under native Win32, if the source value has a scale of 0, its sign is + * ignored, i.e. this function takes the absolute value rather than fail + * with DISP_E_OVERFLOW. This bug has been fixed in Wine's implementation + * (use VarAbs() on pDecIn first if you really want this behaviour). + */ +HRESULT WINAPI VarUI8FromDec(DECIMAL *pdecIn, ULONG64* pui64Out) +{ + if (!DEC_SCALE(pdecIn)) + { + /* This decimal is just a 96 bit integer */ + if (DEC_SIGN(pdecIn) & ~DECIMAL_NEG) + return E_INVALIDARG; + + if (DEC_HI32(pdecIn)) + return DISP_E_OVERFLOW; + + if (DEC_SIGN(pdecIn)) + { + WARN("Sign would be ignored under Win32!\n"); + return DISP_E_OVERFLOW; + } + + *pui64Out = DEC_LO64(pdecIn); + return S_OK; + } + else + { + /* Decimal contains a floating point number */ + HRESULT hRet; + double dbl; + + hRet = _VarR8FromDec(pdecIn, &dbl); + if (SUCCEEDED(hRet)) + hRet = VarUI8FromR8(dbl, pui64Out); + return hRet; + } +} + +/* R4 + */ + +/************************************************************************ + * VarR4FromUI1 (OLEAUT32.68) + * + * Convert a VT_UI1 to a VT_R4. + * + * PARAMS + * bIn [I] Source + * pFltOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarR4FromUI1(BYTE bIn, float *pFltOut) +{ + return _VarR4FromUI1(bIn, pFltOut); +} + +/************************************************************************ + * VarR4FromI2 (OLEAUT32.69) + * + * Convert a VT_I2 to a VT_R4. + * + * PARAMS + * sIn [I] Source + * pFltOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarR4FromI2(SHORT sIn, float *pFltOut) +{ + return _VarR4FromI2(sIn, pFltOut); +} + +/************************************************************************ + * VarR4FromI4 (OLEAUT32.70) + * + * Convert a VT_I4 to a VT_R4. + * + * PARAMS + * sIn [I] Source + * pFltOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarR4FromI4(LONG lIn, float *pFltOut) +{ + return _VarR4FromI4(lIn, pFltOut); +} + +/************************************************************************ + * VarR4FromR8 (OLEAUT32.71) + * + * Convert a VT_R8 to a VT_R4. + * + * PARAMS + * dblIn [I] Source + * pFltOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination. + */ +HRESULT WINAPI VarR4FromR8(double dblIn, float *pFltOut) +{ + return _VarR4FromR8(dblIn, pFltOut); +} + +/************************************************************************ + * VarR4FromCy (OLEAUT32.72) + * + * Convert a VT_CY to a VT_R4. + * + * PARAMS + * cyIn [I] Source + * pFltOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarR4FromCy(CY cyIn, float *pFltOut) +{ + return _VarR4FromCy(cyIn, pFltOut); +} + +/************************************************************************ + * VarR4FromDate (OLEAUT32.73) + * + * Convert a VT_DATE to a VT_R4. + * + * PARAMS + * dateIn [I] Source + * pFltOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination. + */ +HRESULT WINAPI VarR4FromDate(DATE dateIn, float *pFltOut) +{ + return _VarR4FromDate(dateIn, pFltOut); +} + +/************************************************************************ + * VarR4FromStr (OLEAUT32.74) + * + * Convert a VT_BSTR to a VT_R4. + * + * PARAMS + * strIn [I] Source + * lcid [I] LCID for the conversion + * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h") + * pFltOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if strIn or pFltOut is invalid. + * DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarR4FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, float *pFltOut) +{ + return _VarR4FromStr(strIn, lcid, dwFlags, pFltOut); +} + +/************************************************************************ + * VarR4FromDisp (OLEAUT32.75) + * + * Convert a VT_DISPATCH to a VT_R4. + * + * PARAMS + * pdispIn [I] Source + * lcid [I] LCID for conversion + * pFltOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarR4FromDisp(IDispatch* pdispIn, LCID lcid, float *pFltOut) +{ + return _VarR4FromDisp(pdispIn, lcid, pFltOut); +} + +/************************************************************************ + * VarR4FromBool (OLEAUT32.76) + * + * Convert a VT_BOOL to a VT_R4. + * + * PARAMS + * boolIn [I] Source + * pFltOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarR4FromBool(VARIANT_BOOL boolIn, float *pFltOut) +{ + return _VarR4FromBool(boolIn, pFltOut); +} + +/************************************************************************ + * VarR4FromI1 (OLEAUT32.213) + * + * Convert a VT_I1 to a VT_R4. + * + * PARAMS + * cIn [I] Source + * pFltOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarR4FromI1(signed char cIn, float *pFltOut) +{ + return _VarR4FromI1(cIn, pFltOut); +} + +/************************************************************************ + * VarR4FromUI2 (OLEAUT32.214) + * + * Convert a VT_UI2 to a VT_R4. + * + * PARAMS + * usIn [I] Source + * pFltOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarR4FromUI2(USHORT usIn, float *pFltOut) +{ + return _VarR4FromUI2(usIn, pFltOut); +} + +/************************************************************************ + * VarR4FromUI4 (OLEAUT32.215) + * + * Convert a VT_UI4 to a VT_R4. + * + * PARAMS + * ulIn [I] Source + * pFltOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarR4FromUI4(ULONG ulIn, float *pFltOut) +{ + return _VarR4FromUI4(ulIn, pFltOut); +} + +/************************************************************************ + * VarR4FromDec (OLEAUT32.216) + * + * Convert a VT_DECIMAL to a VT_R4. + * + * PARAMS + * pDecIn [I] Source + * pFltOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid. + */ +HRESULT WINAPI VarR4FromDec(DECIMAL* pDecIn, float *pFltOut) +{ + BYTE scale = DEC_SCALE(pDecIn); + int divisor = 1; + double highPart; + + if (scale > DEC_MAX_SCALE || DEC_SIGN(pDecIn) & ~DECIMAL_NEG) + return E_INVALIDARG; + + while (scale--) + divisor *= 10; + + if (DEC_SIGN(pDecIn)) + divisor = -divisor; + + if (DEC_HI32(pDecIn)) + { + highPart = (double)DEC_HI32(pDecIn) / (double)divisor; + highPart *= 1.0e64; + } + else + highPart = 0.0; + + *pFltOut = (double)DEC_LO64(pDecIn) / (double)divisor + highPart; + return S_OK; +} + +/************************************************************************ + * VarR4FromI8 (OLEAUT32.360) + * + * Convert a VT_I8 to a VT_R4. + * + * PARAMS + * ullIn [I] Source + * pFltOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarR4FromI8(LONG64 llIn, float *pFltOut) +{ + return _VarR4FromI8(llIn, pFltOut); +} + +/************************************************************************ + * VarR4FromUI8 (OLEAUT32.361) + * + * Convert a VT_UI8 to a VT_R4. + * + * PARAMS + * ullIn [I] Source + * pFltOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarR4FromUI8(ULONG64 ullIn, float *pFltOut) +{ + return _VarR4FromUI8(ullIn, pFltOut); +} + +/************************************************************************ + * VarR4CmpR8 (OLEAUT32.316) + * + * Compare a VT_R4 to a VT_R8. + * + * PARAMS + * fltLeft [I] Source + * dblRight [I] Value to compare + * + * RETURNS + * VARCMP_LT, VARCMP_EQ or VARCMP_GT indicating that fltLeft is less than, + * equal to or greater than dblRight respectively. + */ +HRESULT WINAPI VarR4CmpR8(float fltLeft, double dblRight) +{ + if (fltLeft < dblRight) + return VARCMP_LT; + else if (fltLeft > dblRight) + return VARCMP_GT; + return VARCMP_EQ; +} + +/* R8 + */ + +/************************************************************************ + * VarR8FromUI1 (OLEAUT32.78) + * + * Convert a VT_UI1 to a VT_R8. + * + * PARAMS + * bIn [I] Source + * pDblOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarR8FromUI1(BYTE bIn, double *pDblOut) +{ + return _VarR8FromUI1(bIn, pDblOut); +} + +/************************************************************************ + * VarR8FromI2 (OLEAUT32.79) + * + * Convert a VT_I2 to a VT_R8. + * + * PARAMS + * sIn [I] Source + * pDblOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarR8FromI2(SHORT sIn, double *pDblOut) +{ + return _VarR8FromI2(sIn, pDblOut); +} + +/************************************************************************ + * VarR8FromI4 (OLEAUT32.80) + * + * Convert a VT_I4 to a VT_R8. + * + * PARAMS + * sIn [I] Source + * pDblOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarR8FromI4(LONG lIn, double *pDblOut) +{ + return _VarR8FromI4(lIn, pDblOut); +} + +/************************************************************************ + * VarR8FromR4 (OLEAUT32.81) + * + * Convert a VT_R4 to a VT_R8. + * + * PARAMS + * fltIn [I] Source + * pDblOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarR8FromR4(FLOAT fltIn, double *pDblOut) +{ + return _VarR8FromR4(fltIn, pDblOut); +} + +/************************************************************************ + * VarR8FromCy (OLEAUT32.82) + * + * Convert a VT_CY to a VT_R8. + * + * PARAMS + * cyIn [I] Source + * pDblOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarR8FromCy(CY cyIn, double *pDblOut) +{ + return _VarR8FromCy(cyIn, pDblOut); +} + +/************************************************************************ + * VarR8FromDate (OLEAUT32.83) + * + * Convert a VT_DATE to a VT_R8. + * + * PARAMS + * dateIn [I] Source + * pDblOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarR8FromDate(DATE dateIn, double *pDblOut) +{ + return _VarR8FromDate(dateIn, pDblOut); +} + +/************************************************************************ + * VarR8FromStr (OLEAUT32.84) + * + * Convert a VT_BSTR to a VT_R8. + * + * PARAMS + * strIn [I] Source + * lcid [I] LCID for the conversion + * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h") + * pDblOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if strIn or pDblOut is invalid. + * DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarR8FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, double *pDblOut) +{ + return _VarR8FromStr(strIn, lcid, dwFlags, pDblOut); +} + +/************************************************************************ + * VarR8FromDisp (OLEAUT32.85) + * + * Convert a VT_DISPATCH to a VT_R8. + * + * PARAMS + * pdispIn [I] Source + * lcid [I] LCID for conversion + * pDblOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarR8FromDisp(IDispatch* pdispIn, LCID lcid, double *pDblOut) +{ + return _VarR8FromDisp(pdispIn, lcid, pDblOut); +} + +/************************************************************************ + * VarR8FromBool (OLEAUT32.86) + * + * Convert a VT_BOOL to a VT_R8. + * + * PARAMS + * boolIn [I] Source + * pDblOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarR8FromBool(VARIANT_BOOL boolIn, double *pDblOut) +{ + return _VarR8FromBool(boolIn, pDblOut); +} + +/************************************************************************ + * VarR8FromI1 (OLEAUT32.217) + * + * Convert a VT_I1 to a VT_R8. + * + * PARAMS + * cIn [I] Source + * pDblOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarR8FromI1(signed char cIn, double *pDblOut) +{ + return _VarR8FromI1(cIn, pDblOut); +} + +/************************************************************************ + * VarR8FromUI2 (OLEAUT32.218) + * + * Convert a VT_UI2 to a VT_R8. + * + * PARAMS + * usIn [I] Source + * pDblOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarR8FromUI2(USHORT usIn, double *pDblOut) +{ + return _VarR8FromUI2(usIn, pDblOut); +} + +/************************************************************************ + * VarR8FromUI4 (OLEAUT32.219) + * + * Convert a VT_UI4 to a VT_R8. + * + * PARAMS + * ulIn [I] Source + * pDblOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarR8FromUI4(ULONG ulIn, double *pDblOut) +{ + return _VarR8FromUI4(ulIn, pDblOut); +} + +/************************************************************************ + * VarR8FromDec (OLEAUT32.220) + * + * Convert a VT_DECIMAL to a VT_R8. + * + * PARAMS + * pDecIn [I] Source + * pDblOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid. + */ +HRESULT WINAPI VarR8FromDec(DECIMAL* pDecIn, double *pDblOut) +{ + BYTE scale = DEC_SCALE(pDecIn); + double divisor = 1.0, highPart; + + if (scale > DEC_MAX_SCALE || DEC_SIGN(pDecIn) & ~DECIMAL_NEG) + return E_INVALIDARG; + + while (scale--) + divisor *= 10; + + if (DEC_SIGN(pDecIn)) + divisor = -divisor; + + if (DEC_HI32(pDecIn)) + { + highPart = (double)DEC_HI32(pDecIn) / divisor; + highPart *= 1.0e64; + } + else + highPart = 0.0; + + *pDblOut = (double)DEC_LO64(pDecIn) / divisor + highPart; + return S_OK; +} + +/************************************************************************ + * VarR8FromI8 (OLEAUT32.362) + * + * Convert a VT_I8 to a VT_R8. + * + * PARAMS + * ullIn [I] Source + * pDblOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarR8FromI8(LONG64 llIn, double *pDblOut) +{ + return _VarR8FromI8(llIn, pDblOut); +} + +/************************************************************************ + * VarR8FromUI8 (OLEAUT32.363) + * + * Convert a VT_UI8 to a VT_R8. + * + * PARAMS + * ullIn [I] Source + * pDblOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarR8FromUI8(ULONG64 ullIn, double *pDblOut) +{ + return _VarR8FromUI8(ullIn, pDblOut); +} + +/************************************************************************ + * VarR8Pow (OLEAUT32.315) + * + * Raise a VT_R8 to a power. + * + * PARAMS + * dblLeft [I] Source + * dblPow [I] Power to raise dblLeft by + * pDblOut [O] Destination + * + * RETURNS + * S_OK. pDblOut contains dblLeft to the power of dblRight. + */ +HRESULT WINAPI VarR8Pow(double dblLeft, double dblPow, double *pDblOut) +{ + *pDblOut = pow(dblLeft, dblPow); + return S_OK; +} + +/************************************************************************ + * VarR8Round (OLEAUT32.317) + * + * Round a VT_R8 to a given number of decimal points. + * + * PARAMS + * dblIn [I] Source + * nDig [I] Number of decimal points to round to + * pDblOut [O] Destination for rounded number + * + * RETURNS + * Success: S_OK. pDblOut is rounded to nDig digits. + * Failure: E_INVALIDARG, if cDecimals is less than 0. + * + * NOTES + * The native version of this function rounds using the internal + * binary representation of the number. Wine uses the dutch rounding + * convention, so therefore small differences can occur in the value returned. + * MSDN says that you should use your own rounding function if you want + * rounding to be predictable in your application. + */ +HRESULT WINAPI VarR8Round(double dblIn, int nDig, double *pDblOut) +{ + double scale, whole, fract; + + if (nDig < 0) + return E_INVALIDARG; + + scale = pow(10.0, nDig); + + dblIn *= scale; + whole = dblIn < 0 ? ceil(dblIn) : floor(dblIn); + fract = dblIn - whole; + + if (fract > 0.5) + dblIn = whole + 1.0; + else if (fract == 0.5) + dblIn = whole + fmod(whole, 2.0); + else if (fract >= 0.0) + dblIn = whole; + else if (fract == -0.5) + dblIn = whole - fmod(whole, 2.0); + else if (fract > -0.5) + dblIn = whole; + else + dblIn = whole - 1.0; + + *pDblOut = dblIn / scale; + return S_OK; +} + +/* CY + */ + +/* Powers of 10 from 0..4 D.P. */ +static const int CY_Divisors[5] = { CY_MULTIPLIER/10000, CY_MULTIPLIER/1000, + CY_MULTIPLIER/100, CY_MULTIPLIER/10, CY_MULTIPLIER }; + +/************************************************************************ + * VarCyFromUI1 (OLEAUT32.98) + * + * Convert a VT_UI1 to a VT_CY. + * + * PARAMS + * bIn [I] Source + * pCyOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarCyFromUI1(BYTE bIn, CY* pCyOut) +{ + return _VarCyFromUI1(bIn, pCyOut); +} + +/************************************************************************ + * VarCyFromI2 (OLEAUT32.99) + * + * Convert a VT_I2 to a VT_CY. + * + * PARAMS + * sIn [I] Source + * pCyOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarCyFromI2(SHORT sIn, CY* pCyOut) +{ + return _VarCyFromI2(sIn, pCyOut); +} + +/************************************************************************ + * VarCyFromI4 (OLEAUT32.100) + * + * Convert a VT_I4 to a VT_CY. + * + * PARAMS + * sIn [I] Source + * pCyOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarCyFromI4(LONG lIn, CY* pCyOut) +{ + return _VarCyFromI4(lIn, pCyOut); +} + +/************************************************************************ + * VarCyFromR4 (OLEAUT32.101) + * + * Convert a VT_R4 to a VT_CY. + * + * PARAMS + * fltIn [I] Source + * pCyOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarCyFromR4(FLOAT fltIn, CY* pCyOut) +{ + return _VarCyFromR4(fltIn, pCyOut); +} + +/************************************************************************ + * VarCyFromR8 (OLEAUT32.102) + * + * Convert a VT_R8 to a VT_CY. + * + * PARAMS + * dblIn [I] Source + * pCyOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarCyFromR8(double dblIn, CY* pCyOut) +{ +#if defined(__GNUC__) && defined(__i386__) + /* This code gives identical results to Win32 on Intel. + * Here we use fp exceptions to catch overflows when storing the value. + */ + static const unsigned short r8_fpcontrol = 0x137f; + static const double r8_multiplier = CY_MULTIPLIER_F; + unsigned short old_fpcontrol, result_fpstatus; + + /* Clear exceptions, save the old fp state and load the new state */ + __asm__ __volatile__( "fnclex" ); + __asm__ __volatile__( "fstcw %0" : "=m" (old_fpcontrol) : ); + __asm__ __volatile__( "fldcw %0" : : "m" (r8_fpcontrol) ); + /* Perform the conversion. */ + __asm__ __volatile__( "fldl %0" : : "m" (dblIn) ); + __asm__ __volatile__( "fmull %0" : : "m" (r8_multiplier) ); + __asm__ __volatile__( "fistpll %0" : : "m" (*pCyOut) ); + /* Save the resulting fp state, load the old state and clear exceptions */ + __asm__ __volatile__( "fstsw %0" : "=m" (result_fpstatus) : ); + __asm__ __volatile__( "fnclex" ); + __asm__ __volatile__( "fldcw %0" : : "m" (old_fpcontrol) ); + + if (result_fpstatus & 0x9) /* Overflow | Invalid */ + return DISP_E_OVERFLOW; + return S_OK; +#else + /* This version produces slightly different results for boundary cases */ + if (dblIn < -922337203685477.5807 || dblIn >= 922337203685477.5807) + return DISP_E_OVERFLOW; + dblIn *= CY_MULTIPLIER_F; + OLEAUT32_DutchRound(LONG64, dblIn, pCyOut->int64); +#endif + return S_OK; +} + +/************************************************************************ + * VarCyFromDate (OLEAUT32.103) + * + * Convert a VT_DATE to a VT_CY. + * + * PARAMS + * dateIn [I] Source + * pCyOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarCyFromDate(DATE dateIn, CY* pCyOut) +{ + return _VarCyFromDate(dateIn, pCyOut); +} + +/************************************************************************ + * VarCyFromStr (OLEAUT32.104) + * + * Convert a VT_BSTR to a VT_CY. + * + * PARAMS + * strIn [I] Source + * lcid [I] LCID for the conversion + * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h") + * pCyOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarCyFromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, CY* pCyOut) +{ + return _VarCyFromStr(strIn, lcid, dwFlags, pCyOut); +} + +/************************************************************************ + * VarCyFromDisp (OLEAUT32.105) + * + * Convert a VT_DISPATCH to a VT_CY. + * + * PARAMS + * pdispIn [I] Source + * lcid [I] LCID for conversion + * pCyOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarCyFromDisp(IDispatch* pdispIn, LCID lcid, CY* pCyOut) +{ + return _VarCyFromDisp(pdispIn, lcid, pCyOut); +} + +/************************************************************************ + * VarCyFromBool (OLEAUT32.106) + * + * Convert a VT_BOOL to a VT_CY. + * + * PARAMS + * boolIn [I] Source + * pCyOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * DISP_E_TYPEMISMATCH, if the type cannot be converted + * + * NOTES + * While the sign of the boolean is stored in the currency, the value is + * converted to either 0 or 1. + */ +HRESULT WINAPI VarCyFromBool(VARIANT_BOOL boolIn, CY* pCyOut) +{ + return _VarCyFromBool(boolIn, pCyOut); +} + +/************************************************************************ + * VarCyFromI1 (OLEAUT32.225) + * + * Convert a VT_I1 to a VT_CY. + * + * PARAMS + * cIn [I] Source + * pCyOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarCyFromI1(signed char cIn, CY* pCyOut) +{ + return _VarCyFromI1(cIn, pCyOut); +} + +/************************************************************************ + * VarCyFromUI2 (OLEAUT32.226) + * + * Convert a VT_UI2 to a VT_CY. + * + * PARAMS + * usIn [I] Source + * pCyOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarCyFromUI2(USHORT usIn, CY* pCyOut) +{ + return _VarCyFromUI2(usIn, pCyOut); +} + +/************************************************************************ + * VarCyFromUI4 (OLEAUT32.227) + * + * Convert a VT_UI4 to a VT_CY. + * + * PARAMS + * ulIn [I] Source + * pCyOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarCyFromUI4(ULONG ulIn, CY* pCyOut) +{ + return _VarCyFromUI4(ulIn, pCyOut); +} + +/************************************************************************ + * VarCyFromDec (OLEAUT32.228) + * + * Convert a VT_DECIMAL to a VT_CY. + * + * PARAMS + * pdecIn [I] Source + * pCyOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarCyFromDec(DECIMAL* pdecIn, CY* pCyOut) +{ + DECIMAL rounded; + HRESULT hRet; + + hRet = VarDecRound(pdecIn, 4, &rounded); + + if (SUCCEEDED(hRet)) + { + double d; + + if (DEC_HI32(&rounded)) + return DISP_E_OVERFLOW; + + /* Note: Without the casts this promotes to int64 which loses precision */ + d = (double)DEC_LO64(&rounded) / (double)CY_Divisors[DEC_SCALE(&rounded)]; + if (DEC_SIGN(&rounded)) + d = -d; + return _VarCyFromR8(d, pCyOut); + } + return hRet; +} + +/************************************************************************ + * VarCyFromI8 (OLEAUT32.366) + * + * Convert a VT_I8 to a VT_CY. + * + * PARAMS + * ullIn [I] Source + * pCyOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarCyFromI8(LONG64 llIn, CY* pCyOut) +{ + return _VarCyFromI8(llIn, pCyOut); +} + +/************************************************************************ + * VarCyFromUI8 (OLEAUT32.375) + * + * Convert a VT_UI8 to a VT_CY. + * + * PARAMS + * ullIn [I] Source + * pCyOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarCyFromUI8(ULONG64 ullIn, CY* pCyOut) +{ + return _VarCyFromUI8(ullIn, pCyOut); +} + +/************************************************************************ + * VarCyAdd (OLEAUT32.299) + * + * Add one CY to another. + * + * PARAMS + * cyLeft [I] Source + * cyRight [I] Value to add + * pCyOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarCyAdd(const CY cyLeft, const CY cyRight, CY* pCyOut) +{ + double l,r; + _VarR8FromCy(cyLeft, &l); + _VarR8FromCy(cyRight, &r); + l = l + r; + return _VarCyFromR8(l, pCyOut); +} + +/************************************************************************ + * VarCyMul (OLEAUT32.303) + * + * Multiply one CY by another. + * + * PARAMS + * cyLeft [I] Source + * cyRight [I] Value to multiply by + * pCyOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarCyMul(const CY cyLeft, const CY cyRight, CY* pCyOut) +{ + double l,r; + _VarR8FromCy(cyLeft, &l); + _VarR8FromCy(cyRight, &r); + l = l * r; + return _VarCyFromR8(l, pCyOut); +} + +/************************************************************************ + * VarCyMulI4 (OLEAUT32.304) + * + * Multiply one CY by a VT_I4. + * + * PARAMS + * cyLeft [I] Source + * lRight [I] Value to multiply by + * pCyOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarCyMulI4(const CY cyLeft, LONG lRight, CY* pCyOut) +{ + double d; + + _VarR8FromCy(cyLeft, &d); + d = d * lRight; + return _VarCyFromR8(d, pCyOut); +} + +/************************************************************************ + * VarCySub (OLEAUT32.305) + * + * Subtract one CY from another. + * + * PARAMS + * cyLeft [I] Source + * cyRight [I] Value to subtract + * pCyOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarCySub(const CY cyLeft, const CY cyRight, CY* pCyOut) +{ + double l,r; + _VarR8FromCy(cyLeft, &l); + _VarR8FromCy(cyRight, &r); + l = l - r; + return _VarCyFromR8(l, pCyOut); +} + +/************************************************************************ + * VarCyAbs (OLEAUT32.306) + * + * Convert a VT_CY into its absolute value. + * + * PARAMS + * cyIn [I] Source + * pCyOut [O] Destination + * + * RETURNS + * Success: S_OK. pCyOut contains the absolute value. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarCyAbs(const CY cyIn, CY* pCyOut) +{ + if (cyIn.s.Hi == (int)0x80000000 && !cyIn.s.Lo) + return DISP_E_OVERFLOW; + + pCyOut->int64 = cyIn.int64 < 0 ? -cyIn.int64 : cyIn.int64; + return S_OK; +} + +/************************************************************************ + * VarCyFix (OLEAUT32.307) + * + * Return the integer part of a VT_CY. + * + * PARAMS + * cyIn [I] Source + * pCyOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + * + * NOTES + * - The difference between this function and VarCyInt() is that VarCyInt() rounds + * negative numbers away from 0, while this function rounds them towards zero. + */ +HRESULT WINAPI VarCyFix(const CY cyIn, CY* pCyOut) +{ + pCyOut->int64 = cyIn.int64 / CY_MULTIPLIER; + pCyOut->int64 *= CY_MULTIPLIER; + return S_OK; +} + +/************************************************************************ + * VarCyInt (OLEAUT32.308) + * + * Return the integer part of a VT_CY. + * + * PARAMS + * cyIn [I] Source + * pCyOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + * + * NOTES + * - The difference between this function and VarCyFix() is that VarCyFix() rounds + * negative numbers towards 0, while this function rounds them away from zero. + */ +HRESULT WINAPI VarCyInt(const CY cyIn, CY* pCyOut) +{ + pCyOut->int64 = cyIn.int64 / CY_MULTIPLIER; + pCyOut->int64 *= CY_MULTIPLIER; + + if (cyIn.int64 < 0 && cyIn.int64 % CY_MULTIPLIER != 0) + { + pCyOut->int64 -= CY_MULTIPLIER; + } + return S_OK; +} + +/************************************************************************ + * VarCyNeg (OLEAUT32.309) + * + * Change the sign of a VT_CY. + * + * PARAMS + * cyIn [I] Source + * pCyOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarCyNeg(const CY cyIn, CY* pCyOut) +{ + if (cyIn.s.Hi == (int)0x80000000 && !cyIn.s.Lo) + return DISP_E_OVERFLOW; + + pCyOut->int64 = -cyIn.int64; + return S_OK; +} + +/************************************************************************ + * VarCyRound (OLEAUT32.310) + * + * Change the precision of a VT_CY. + * + * PARAMS + * cyIn [I] Source + * cDecimals [I] New number of decimals to keep + * pCyOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if cDecimals is less than 0. + */ +HRESULT WINAPI VarCyRound(const CY cyIn, int cDecimals, CY* pCyOut) +{ + if (cDecimals < 0) + return E_INVALIDARG; + + if (cDecimals > 3) + { + /* Rounding to more precision than we have */ + *pCyOut = cyIn; + return S_OK; + } + else + { + double d, div = CY_Divisors[cDecimals]; + + _VarR8FromCy(cyIn, &d); + d = d * div; + OLEAUT32_DutchRound(LONGLONG, d, pCyOut->int64) + d = (double)pCyOut->int64 / div * CY_MULTIPLIER_F; + OLEAUT32_DutchRound(LONGLONG, d, pCyOut->int64) + return S_OK; + } +} + +/************************************************************************ + * VarCyCmp (OLEAUT32.311) + * + * Compare two VT_CY values. + * + * PARAMS + * cyLeft [I] Source + * cyRight [I] Value to compare + * + * RETURNS + * Success: VARCMP_LT, VARCMP_EQ or VARCMP_GT indicating that the value to + * compare is less, equal or greater than source respectively. + * Failure: DISP_E_OVERFLOW, if overflow occurs during the comparison + */ +HRESULT WINAPI VarCyCmp(const CY cyLeft, const CY cyRight) +{ + HRESULT hRet; + CY result; + + /* Subtract right from left, and compare the result to 0 */ + hRet = VarCySub(cyLeft, cyRight, &result); + + if (SUCCEEDED(hRet)) + { + if (result.int64 < 0) + hRet = (HRESULT)VARCMP_LT; + else if (result.int64 > 0) + hRet = (HRESULT)VARCMP_GT; + else + hRet = (HRESULT)VARCMP_EQ; + } + return hRet; +} + +/************************************************************************ + * VarCyCmpR8 (OLEAUT32.312) + * + * Compare a VT_CY to a double + * + * PARAMS + * cyLeft [I] Currency Source + * dblRight [I] double to compare to cyLeft + * + * RETURNS + * Success: VARCMP_LT, VARCMP_EQ or VARCMP_GT indicating that dblRight is + * less than, equal to or greater than cyLeft respectively. + * Failure: DISP_E_OVERFLOW, if overflow occurs during the comparison + */ +HRESULT WINAPI VarCyCmpR8(const CY cyLeft, double dblRight) +{ + HRESULT hRet; + CY cyRight; + + hRet = _VarCyFromR8(dblRight, &cyRight); + + if (SUCCEEDED(hRet)) + hRet = VarCyCmp(cyLeft, cyRight); + + return hRet; +} + +/************************************************************************ + * VarCyMulI8 (OLEAUT32.329) + * + * Multiply a VT_CY by a VT_I8. + * + * PARAMS + * cyLeft [I] Source + * llRight [I] Value to multiply by + * pCyOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarCyMulI8(const CY cyLeft, LONG64 llRight, CY* pCyOut) +{ + double d; + + _VarR8FromCy(cyLeft, &d); + d = d * (double)llRight; + return _VarCyFromR8(d, pCyOut); +} + +/* DECIMAL + */ + +/************************************************************************ + * VarDecFromUI1 (OLEAUT32.190) + * + * Convert a VT_UI1 to a DECIMAL. + * + * PARAMS + * bIn [I] Source + * pDecOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarDecFromUI1(BYTE bIn, DECIMAL* pDecOut) +{ + return _VarDecFromUI1(bIn, pDecOut); +} + +/************************************************************************ + * VarDecFromI2 (OLEAUT32.191) + * + * Convert a VT_I2 to a DECIMAL. + * + * PARAMS + * sIn [I] Source + * pDecOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarDecFromI2(SHORT sIn, DECIMAL* pDecOut) +{ + return _VarDecFromI2(sIn, pDecOut); +} + +/************************************************************************ + * VarDecFromI4 (OLEAUT32.192) + * + * Convert a VT_I4 to a DECIMAL. + * + * PARAMS + * sIn [I] Source + * pDecOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarDecFromI4(LONG lIn, DECIMAL* pDecOut) +{ + DEC_HI32(pDecOut) = 0; + DEC_MID32(pDecOut) = 0; + + if (lIn < 0) + { + DEC_SIGNSCALE(pDecOut) = SIGNSCALE(DECIMAL_NEG,0); + DEC_LO32(pDecOut) = -lIn; + } + else + { + DEC_SIGNSCALE(pDecOut) = SIGNSCALE(DECIMAL_POS,0); + DEC_LO32(pDecOut) = lIn; + } + return S_OK; +} + +/************************************************************************ + * VarDecFromR4 (OLEAUT32.193) + * + * Convert a VT_R4 to a DECIMAL. + * + * PARAMS + * fltIn [I] Source + * pDecOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarDecFromR4(FLOAT fltIn, DECIMAL* pDecOut) +{ + WCHAR buff[256]; + + sprintfW( buff, szFloatFormatW, fltIn ); + return _VarDecFromStr(buff, LOCALE_SYSTEM_DEFAULT, 0, pDecOut); +} + +/************************************************************************ + * VarDecFromR8 (OLEAUT32.194) + * + * Convert a VT_R8 to a DECIMAL. + * + * PARAMS + * dblIn [I] Source + * pDecOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarDecFromR8(double dblIn, DECIMAL* pDecOut) +{ + WCHAR buff[256]; + + sprintfW( buff, szDoubleFormatW, dblIn ); + return _VarDecFromStr(buff, LOCALE_USER_DEFAULT, 0, pDecOut); +} + +/************************************************************************ + * VarDecFromDate (OLEAUT32.195) + * + * Convert a VT_DATE to a DECIMAL. + * + * PARAMS + * dateIn [I] Source + * pDecOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarDecFromDate(DATE dateIn, DECIMAL* pDecOut) +{ + return _VarDecFromDate(dateIn, pDecOut); +} + +/************************************************************************ + * VarDecFromCy (OLEAUT32.196) + * + * Convert a VT_CY to a DECIMAL. + * + * PARAMS + * cyIn [I] Source + * pDecOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarDecFromCy(CY cyIn, DECIMAL* pDecOut) +{ + DEC_HI32(pDecOut) = 0; + + /* Note: This assumes 2s complement integer representation */ + if (cyIn.s.Hi & 0x80000000) + { + DEC_SIGNSCALE(pDecOut) = SIGNSCALE(DECIMAL_NEG,4); + DEC_LO64(pDecOut) = -cyIn.int64; + } + else + { + DEC_SIGNSCALE(pDecOut) = SIGNSCALE(DECIMAL_POS,4); + DEC_MID32(pDecOut) = cyIn.s.Hi; + DEC_LO32(pDecOut) = cyIn.s.Lo; + } + return S_OK; +} + +/************************************************************************ + * VarDecFromStr (OLEAUT32.197) + * + * Convert a VT_BSTR to a DECIMAL. + * + * PARAMS + * strIn [I] Source + * lcid [I] LCID for the conversion + * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h") + * pDecOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarDecFromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, DECIMAL* pDecOut) +{ + return _VarDecFromStr(strIn, lcid, dwFlags, pDecOut); +} + +/************************************************************************ + * VarDecFromDisp (OLEAUT32.198) + * + * Convert a VT_DISPATCH to a DECIMAL. + * + * PARAMS + * pdispIn [I] Source + * lcid [I] LCID for conversion + * pDecOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarDecFromDisp(IDispatch* pdispIn, LCID lcid, DECIMAL* pDecOut) +{ + return _VarDecFromDisp(pdispIn, lcid, pDecOut); +} + +/************************************************************************ + * VarDecFromBool (OLEAUT32.199) + * + * Convert a VT_BOOL to a DECIMAL. + * + * PARAMS + * bIn [I] Source + * pDecOut [O] Destination + * + * RETURNS + * S_OK. + * + * NOTES + * The value is converted to either 0 (if bIn is FALSE) or -1 (TRUE). + */ +HRESULT WINAPI VarDecFromBool(VARIANT_BOOL bIn, DECIMAL* pDecOut) +{ + DEC_HI32(pDecOut) = 0; + DEC_MID32(pDecOut) = 0; + if (bIn) + { + DEC_SIGNSCALE(pDecOut) = SIGNSCALE(DECIMAL_NEG,0); + DEC_LO32(pDecOut) = 1; + } + else + { + DEC_SIGNSCALE(pDecOut) = SIGNSCALE(DECIMAL_POS,0); + DEC_LO32(pDecOut) = 0; + } + return S_OK; +} + +/************************************************************************ + * VarDecFromI1 (OLEAUT32.241) + * + * Convert a VT_I1 to a DECIMAL. + * + * PARAMS + * cIn [I] Source + * pDecOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarDecFromI1(signed char cIn, DECIMAL* pDecOut) +{ + return _VarDecFromI1(cIn, pDecOut); +} + +/************************************************************************ + * VarDecFromUI2 (OLEAUT32.242) + * + * Convert a VT_UI2 to a DECIMAL. + * + * PARAMS + * usIn [I] Source + * pDecOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarDecFromUI2(USHORT usIn, DECIMAL* pDecOut) +{ + return _VarDecFromUI2(usIn, pDecOut); +} + +/************************************************************************ + * VarDecFromUI4 (OLEAUT32.243) + * + * Convert a VT_UI4 to a DECIMAL. + * + * PARAMS + * ulIn [I] Source + * pDecOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarDecFromUI4(ULONG ulIn, DECIMAL* pDecOut) +{ + DEC_SIGNSCALE(pDecOut) = SIGNSCALE(DECIMAL_POS,0); + DEC_HI32(pDecOut) = 0; + DEC_MID32(pDecOut) = 0; + DEC_LO32(pDecOut) = ulIn; + return S_OK; +} + +/************************************************************************ + * VarDecFromI8 (OLEAUT32.374) + * + * Convert a VT_I8 to a DECIMAL. + * + * PARAMS + * llIn [I] Source + * pDecOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarDecFromI8(LONG64 llIn, DECIMAL* pDecOut) +{ + PULARGE_INTEGER pLi = (PULARGE_INTEGER)&llIn; + + DEC_HI32(pDecOut) = 0; + + /* Note: This assumes 2s complement integer representation */ + if (pLi->u.HighPart & 0x80000000) + { + DEC_SIGNSCALE(pDecOut) = SIGNSCALE(DECIMAL_NEG,0); + DEC_LO64(pDecOut) = -pLi->QuadPart; + } + else + { + DEC_SIGNSCALE(pDecOut) = SIGNSCALE(DECIMAL_POS,0); + DEC_MID32(pDecOut) = pLi->u.HighPart; + DEC_LO32(pDecOut) = pLi->u.LowPart; + } + return S_OK; +} + +/************************************************************************ + * VarDecFromUI8 (OLEAUT32.375) + * + * Convert a VT_UI8 to a DECIMAL. + * + * PARAMS + * ullIn [I] Source + * pDecOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarDecFromUI8(ULONG64 ullIn, DECIMAL* pDecOut) +{ + DEC_SIGNSCALE(pDecOut) = SIGNSCALE(DECIMAL_POS,0); + DEC_HI32(pDecOut) = 0; + DEC_LO64(pDecOut) = ullIn; + return S_OK; +} + +/* Make two DECIMALS the same scale; used by math functions below */ +static HRESULT VARIANT_DecScale(const DECIMAL** ppDecLeft, + const DECIMAL** ppDecRight, + DECIMAL* pDecOut) +{ + static DECIMAL scaleFactor; + DECIMAL decTemp; + int scaleAmount, i; + HRESULT hRet = S_OK; + + if (DEC_SIGN(*ppDecLeft) & ~DECIMAL_NEG || DEC_SIGN(*ppDecRight) & ~DECIMAL_NEG) + return E_INVALIDARG; + + DEC_LO32(&scaleFactor) = 10; + + i = scaleAmount = DEC_SCALE(*ppDecLeft) - DEC_SCALE(*ppDecRight); + + if (!scaleAmount) + return S_OK; /* Same scale */ + + if (scaleAmount > 0) + { + decTemp = *(*ppDecRight); /* Left is bigger - scale the right hand side */ + *ppDecRight = pDecOut; + } + else + { + decTemp = *(*ppDecLeft); /* Right is bigger - scale the left hand side */ + *ppDecLeft = pDecOut; + i = scaleAmount = -scaleAmount; + } + + if (DEC_SCALE(&decTemp) + scaleAmount > DEC_MAX_SCALE) + return DISP_E_OVERFLOW; /* Can't scale up */ + + /* Multiply up the value to be scaled by the correct amount */ + while (SUCCEEDED(hRet) && i--) + { + /* Note we are multiplying by a value with a scale of 0, so we don't recurse */ + hRet = VarDecMul(&decTemp, &scaleFactor, pDecOut); + decTemp = *pDecOut; + } + DEC_SCALE(pDecOut) += scaleAmount; /* Set the new scale */ + return hRet; +} + +/* Add two unsigned 32 bit values with overflow */ +static ULONG VARIANT_Add(ULONG ulLeft, ULONG ulRight, ULONG* pulHigh) +{ + ULARGE_INTEGER ul64; + + ul64.QuadPart = (ULONG64)ulLeft + (ULONG64)ulRight + (ULONG64)*pulHigh; + *pulHigh = ul64.u.HighPart; + return ul64.u.LowPart; +} + +/* Subtract two unsigned 32 bit values with underflow */ +static ULONG VARIANT_Sub(ULONG ulLeft, ULONG ulRight, ULONG* pulHigh) +{ + int invert = 0; + ULARGE_INTEGER ul64; + + ul64.QuadPart = (LONG64)ulLeft - (ULONG64)ulRight; + if (ulLeft < ulRight) + invert = 1; + + if (ul64.QuadPart > (ULONG64)*pulHigh) + ul64.QuadPart -= (ULONG64)*pulHigh; + else + { + ul64.QuadPart -= (ULONG64)*pulHigh; + invert = 1; + } + if (invert) + ul64.u.HighPart = -ul64.u.HighPart ; + + *pulHigh = ul64.u.HighPart; + return ul64.u.LowPart; +} + +/* Multiply two unsigned 32 bit values with overflow */ +static ULONG VARIANT_Mul(ULONG ulLeft, ULONG ulRight, ULONG* pulHigh) +{ + ULARGE_INTEGER ul64; + + ul64.QuadPart = (ULONG64)ulLeft * (ULONG64)ulRight + (ULONG64)*pulHigh; + *pulHigh = ul64.u.HighPart; + return ul64.u.LowPart; +} + +/* Compare two decimals that have the same scale */ +static inline int VARIANT_DecCmp(const DECIMAL *pDecLeft, const DECIMAL *pDecRight) +{ + if ( DEC_HI32(pDecLeft) < DEC_HI32(pDecRight) || + (DEC_HI32(pDecLeft) <= DEC_HI32(pDecRight) && DEC_LO64(pDecLeft) < DEC_LO64(pDecRight))) + return -1; + else if (DEC_HI32(pDecLeft) == DEC_HI32(pDecRight) && DEC_LO64(pDecLeft) == DEC_LO64(pDecRight)) + return 0; + return 1; +} + +/************************************************************************ + * VarDecAdd (OLEAUT32.177) + * + * Add one DECIMAL to another. + * + * PARAMS + * pDecLeft [I] Source + * pDecRight [I] Value to add + * pDecOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarDecAdd(const DECIMAL* pDecLeft, const DECIMAL* pDecRight, DECIMAL* pDecOut) +{ + HRESULT hRet; + DECIMAL scaled; + + hRet = VARIANT_DecScale(&pDecLeft, &pDecRight, &scaled); + + if (SUCCEEDED(hRet)) + { + /* Our decimals now have the same scale, we can add them as 96 bit integers */ + ULONG overflow = 0; + BYTE sign = DECIMAL_POS; + + /* Correct for the sign of the result */ + if (DEC_SIGN(pDecLeft) && DEC_SIGN(pDecRight)) + { + /* -x + -y : Negative */ + sign = DECIMAL_NEG; + goto VarDecAdd_AsPositive; + } + else if (DEC_SIGN(pDecLeft) && !DEC_SIGN(pDecRight)) + { + int cmp = VARIANT_DecCmp(pDecLeft, pDecRight); + + /* -x + y : Negative if x > y */ + if (cmp > 0) + { + sign = DECIMAL_NEG; +VarDecAdd_AsNegative: + DEC_LO32(pDecOut) = VARIANT_Sub(DEC_LO32(pDecLeft), DEC_LO32(pDecRight), &overflow); + DEC_MID32(pDecOut) = VARIANT_Sub(DEC_MID32(pDecLeft), DEC_MID32(pDecRight), &overflow); + DEC_HI32(pDecOut) = VARIANT_Sub(DEC_HI32(pDecLeft), DEC_HI32(pDecRight), &overflow); + } + else + { +VarDecAdd_AsInvertedNegative: + DEC_LO32(pDecOut) = VARIANT_Sub(DEC_LO32(pDecRight), DEC_LO32(pDecLeft), &overflow); + DEC_MID32(pDecOut) = VARIANT_Sub(DEC_MID32(pDecRight), DEC_MID32(pDecLeft), &overflow); + DEC_HI32(pDecOut) = VARIANT_Sub(DEC_HI32(pDecRight), DEC_HI32(pDecLeft), &overflow); + } + } + else if (!DEC_SIGN(pDecLeft) && DEC_SIGN(pDecRight)) + { + int cmp = VARIANT_DecCmp(pDecLeft, pDecRight); + + /* x + -y : Negative if x <= y */ + if (cmp <= 0) + { + sign = DECIMAL_NEG; + goto VarDecAdd_AsInvertedNegative; + } + goto VarDecAdd_AsNegative; + } + else + { + /* x + y : Positive */ +VarDecAdd_AsPositive: + DEC_LO32(pDecOut) = VARIANT_Add(DEC_LO32(pDecLeft), DEC_LO32(pDecRight), &overflow); + DEC_MID32(pDecOut) = VARIANT_Add(DEC_MID32(pDecLeft), DEC_MID32(pDecRight), &overflow); + DEC_HI32(pDecOut) = VARIANT_Add(DEC_HI32(pDecLeft), DEC_HI32(pDecRight), &overflow); + } + + if (overflow) + return DISP_E_OVERFLOW; /* overflowed */ + + DEC_SCALE(pDecOut) = DEC_SCALE(pDecLeft); + DEC_SIGN(pDecOut) = sign; + } + return hRet; +} + +/************************************************************************ + * VarDecDiv (OLEAUT32.178) + * + * Divide one DECIMAL by another. + * + * PARAMS + * pDecLeft [I] Source + * pDecRight [I] Value to divide by + * pDecOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarDecDiv(const DECIMAL* pDecLeft, const DECIMAL* pDecRight, DECIMAL* pDecOut) +{ + FIXME("(%p,%p,%p)-stub!\n",pDecLeft,pDecRight,pDecOut); + return DISP_E_OVERFLOW; +} + +/************************************************************************ + * VarDecMul (OLEAUT32.179) + * + * Multiply one DECIMAL by another. + * + * PARAMS + * pDecLeft [I] Source + * pDecRight [I] Value to multiply by + * pDecOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarDecMul(const DECIMAL* pDecLeft, const DECIMAL* pDecRight, DECIMAL* pDecOut) +{ + /* FIXME: This only allows multiplying by a fixed integer <= 0xffffffff */ + + if (!DEC_SCALE(pDecLeft) || !DEC_SCALE(pDecRight)) + { + /* At least one term is an integer */ + const DECIMAL* pDecInteger = DEC_SCALE(pDecLeft) ? pDecRight : pDecLeft; + const DECIMAL* pDecOperand = DEC_SCALE(pDecLeft) ? pDecLeft : pDecRight; + HRESULT hRet = S_OK; + unsigned int multiplier = DEC_LO32(pDecInteger); + ULONG overflow = 0; + + if (DEC_HI32(pDecInteger) || DEC_MID32(pDecInteger)) + { + FIXME("(%p,%p,%p) semi-stub!\n",pDecLeft,pDecRight,pDecOut); + return DISP_E_OVERFLOW; + } + + DEC_LO32(pDecOut) = VARIANT_Mul(DEC_LO32(pDecOperand), multiplier, &overflow); + DEC_MID32(pDecOut) = VARIANT_Mul(DEC_MID32(pDecOperand), multiplier, &overflow); + DEC_HI32(pDecOut) = VARIANT_Mul(DEC_HI32(pDecOperand), multiplier, &overflow); + + if (overflow) + hRet = DISP_E_OVERFLOW; + else + { + BYTE sign = DECIMAL_POS; + + if (DEC_SIGN(pDecLeft) != DEC_SIGN(pDecRight)) + sign = DECIMAL_NEG; /* pos * neg => negative */ + DEC_SIGN(pDecOut) = sign; + DEC_SCALE(pDecOut) = DEC_SCALE(pDecOperand); + } + return hRet; + } + FIXME("(%p,%p,%p) semi-stub!\n",pDecLeft,pDecRight,pDecOut); + return DISP_E_OVERFLOW; +} + +/************************************************************************ + * VarDecSub (OLEAUT32.181) + * + * Subtract one DECIMAL from another. + * + * PARAMS + * pDecLeft [I] Source + * pDecRight [I] DECIMAL to subtract from pDecLeft + * pDecOut [O] Destination + * + * RETURNS + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarDecSub(const DECIMAL* pDecLeft, const DECIMAL* pDecRight, DECIMAL* pDecOut) +{ + DECIMAL decRight; + + /* Implement as addition of the negative */ + VarDecNeg(pDecRight, &decRight); + return VarDecAdd(pDecLeft, &decRight, pDecOut); +} + +/************************************************************************ + * VarDecAbs (OLEAUT32.182) + * + * Convert a DECIMAL into its absolute value. + * + * PARAMS + * pDecIn [I] Source + * pDecOut [O] Destination + * + * RETURNS + * S_OK. This function does not fail. + */ +HRESULT WINAPI VarDecAbs(const DECIMAL* pDecIn, DECIMAL* pDecOut) +{ + *pDecOut = *pDecIn; + DEC_SIGN(pDecOut) &= ~DECIMAL_NEG; + return S_OK; +} + +/************************************************************************ + * VarDecFix (OLEAUT32.187) + * + * Return the integer portion of a DECIMAL. + * + * PARAMS + * pDecIn [I] Source + * pDecOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + * + * NOTES + * - The difference between this function and VarDecInt() is that VarDecInt() rounds + * negative numbers away from 0, while this function rounds them towards zero. + */ +HRESULT WINAPI VarDecFix(const DECIMAL* pDecIn, DECIMAL* pDecOut) +{ + if (DEC_SIGN(pDecIn) & ~DECIMAL_NEG) + return E_INVALIDARG; + + if (!DEC_SCALE(pDecIn)) + { + *pDecOut = *pDecIn; /* Already an integer */ + return S_OK; + } + + FIXME("semi-stub!\n"); + return DISP_E_OVERFLOW; +} + +/************************************************************************ + * VarDecInt (OLEAUT32.188) + * + * Return the integer portion of a DECIMAL. + * + * PARAMS + * pDecIn [I] Source + * pDecOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + * + * NOTES + * - The difference between this function and VarDecFix() is that VarDecFix() rounds + * negative numbers towards 0, while this function rounds them away from zero. + */ +HRESULT WINAPI VarDecInt(const DECIMAL* pDecIn, DECIMAL* pDecOut) +{ + if (DEC_SIGN(pDecIn) & ~DECIMAL_NEG) + return E_INVALIDARG; + + if (!(DEC_SIGN(pDecIn) & DECIMAL_NEG) || !DEC_SCALE(pDecIn)) + return VarDecFix(pDecIn, pDecOut); /* The same, if +ve or no fractionals */ + + FIXME("semi-stub!\n"); + return DISP_E_OVERFLOW; +} + +/************************************************************************ + * VarDecNeg (OLEAUT32.189) + * + * Change the sign of a DECIMAL. + * + * PARAMS + * pDecIn [I] Source + * pDecOut [O] Destination + * + * RETURNS + * S_OK. This function does not fail. + */ +HRESULT WINAPI VarDecNeg(const DECIMAL* pDecIn, DECIMAL* pDecOut) +{ + *pDecOut = *pDecIn; + DEC_SIGN(pDecOut) ^= DECIMAL_NEG; + return S_OK; +} + +/************************************************************************ + * VarDecRound (OLEAUT32.203) + * + * Change the precision of a DECIMAL. + * + * PARAMS + * pDecIn [I] Source + * cDecimals [I] New number of decimals to keep + * pDecOut [O] Destination + * + * RETURNS + * Success: S_OK. pDecOut contains the rounded value. + * Failure: E_INVALIDARG if any argument is invalid. + */ +HRESULT WINAPI VarDecRound(const DECIMAL* pDecIn, int cDecimals, DECIMAL* pDecOut) +{ + if (cDecimals < 0 || (DEC_SIGN(pDecIn) & ~DECIMAL_NEG) || DEC_SCALE(pDecIn) > DEC_MAX_SCALE) + return E_INVALIDARG; + + if (cDecimals >= DEC_SCALE(pDecIn)) + { + *pDecOut = *pDecIn; /* More precision than we have */ + return S_OK; + } + + FIXME("semi-stub!\n"); + + return DISP_E_OVERFLOW; +} + +/************************************************************************ + * VarDecCmp (OLEAUT32.204) + * + * Compare two DECIMAL values. + * + * PARAMS + * pDecLeft [I] Source + * pDecRight [I] Value to compare + * + * RETURNS + * Success: VARCMP_LT, VARCMP_EQ or VARCMP_GT indicating that pDecLeft + * is less than, equal to or greater than pDecRight respectively. + * Failure: DISP_E_OVERFLOW, if overflow occurs during the comparison + */ +HRESULT WINAPI VarDecCmp(const DECIMAL* pDecLeft, const DECIMAL* pDecRight) +{ + HRESULT hRet; + DECIMAL result; + + /* Subtract right from left, and compare the result to 0 */ + hRet = VarDecSub(pDecLeft, pDecRight, &result); + + if (SUCCEEDED(hRet)) + { + int non_zero = DEC_HI32(&result) | DEC_MID32(&result) | DEC_LO32(&result); + + if ((DEC_SIGN(&result) & DECIMAL_NEG) && non_zero) + hRet = (HRESULT)VARCMP_LT; + else if (non_zero) + hRet = (HRESULT)VARCMP_GT; + else + hRet = (HRESULT)VARCMP_EQ; + } + return hRet; +} + +/************************************************************************ + * VarDecCmpR8 (OLEAUT32.298) + * + * Compare a DECIMAL to a double + * + * PARAMS + * pDecLeft [I] DECIMAL Source + * dblRight [I] double to compare to pDecLeft + * + * RETURNS + * Success: VARCMP_LT, VARCMP_EQ or VARCMP_GT indicating that dblRight + * is less than, equal to or greater than pDecLeft respectively. + * Failure: DISP_E_OVERFLOW, if overflow occurs during the comparison + */ +HRESULT WINAPI VarDecCmpR8(const DECIMAL* pDecLeft, double dblRight) +{ + HRESULT hRet; + DECIMAL decRight; + + hRet = VarDecFromR8(dblRight, &decRight); + + if (SUCCEEDED(hRet)) + hRet = VarDecCmp(pDecLeft, &decRight); + + return hRet; +} + +/* BOOL + */ + +/************************************************************************ + * VarBoolFromUI1 (OLEAUT32.118) + * + * Convert a VT_UI1 to a VT_BOOL. + * + * PARAMS + * bIn [I] Source + * pBoolOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarBoolFromUI1(BYTE bIn, VARIANT_BOOL *pBoolOut) +{ + return _VarBoolFromUI1(bIn, pBoolOut); +} + +/************************************************************************ + * VarBoolFromI2 (OLEAUT32.119) + * + * Convert a VT_I2 to a VT_BOOL. + * + * PARAMS + * sIn [I] Source + * pBoolOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarBoolFromI2(SHORT sIn, VARIANT_BOOL *pBoolOut) +{ + return _VarBoolFromI2(sIn, pBoolOut); +} + +/************************************************************************ + * VarBoolFromI4 (OLEAUT32.120) + * + * Convert a VT_I4 to a VT_BOOL. + * + * PARAMS + * sIn [I] Source + * pBoolOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarBoolFromI4(LONG lIn, VARIANT_BOOL *pBoolOut) +{ + return _VarBoolFromI4(lIn, pBoolOut); +} + +/************************************************************************ + * VarBoolFromR4 (OLEAUT32.121) + * + * Convert a VT_R4 to a VT_BOOL. + * + * PARAMS + * fltIn [I] Source + * pBoolOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarBoolFromR4(FLOAT fltIn, VARIANT_BOOL *pBoolOut) +{ + return _VarBoolFromR4(fltIn, pBoolOut); +} + +/************************************************************************ + * VarBoolFromR8 (OLEAUT32.122) + * + * Convert a VT_R8 to a VT_BOOL. + * + * PARAMS + * dblIn [I] Source + * pBoolOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarBoolFromR8(double dblIn, VARIANT_BOOL *pBoolOut) +{ + return _VarBoolFromR8(dblIn, pBoolOut); +} + +/************************************************************************ + * VarBoolFromDate (OLEAUT32.123) + * + * Convert a VT_DATE to a VT_BOOL. + * + * PARAMS + * dateIn [I] Source + * pBoolOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarBoolFromDate(DATE dateIn, VARIANT_BOOL *pBoolOut) +{ + return _VarBoolFromDate(dateIn, pBoolOut); +} + +/************************************************************************ + * VarBoolFromCy (OLEAUT32.124) + * + * Convert a VT_CY to a VT_BOOL. + * + * PARAMS + * cyIn [I] Source + * pBoolOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarBoolFromCy(CY cyIn, VARIANT_BOOL *pBoolOut) +{ + return _VarBoolFromCy(cyIn, pBoolOut); +} + +static BOOL VARIANT_GetLocalisedText(LANGID langId, DWORD dwId, WCHAR *lpszDest) +{ + HRSRC hrsrc; + + hrsrc = FindResourceExW( OLEAUT32_hModule, (LPWSTR)RT_STRING, + (LPCWSTR)((dwId >> 4) + 1), langId ); + if (hrsrc) + { + HGLOBAL hmem = LoadResource( OLEAUT32_hModule, hrsrc ); + + if (hmem) + { + const WCHAR *p; + unsigned int i; + + p = LockResource( hmem ); + for (i = 0; i < (dwId & 0x0f); i++) p += *p + 1; + + memcpy( lpszDest, p + 1, *p * sizeof(WCHAR) ); + lpszDest[*p] = '\0'; + TRACE("got %s for LANGID %08x\n", debugstr_w(lpszDest), langId); + return TRUE; + } + } + return FALSE; +} + +/************************************************************************ + * VarBoolFromStr (OLEAUT32.125) + * + * Convert a VT_BSTR to a VT_BOOL. + * + * PARAMS + * strIn [I] Source + * lcid [I] LCID for the conversion + * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h") + * pBoolOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if pBoolOut is invalid. + * DISP_E_TYPEMISMATCH, if the type cannot be converted + * + * NOTES + * - strIn will be recognised if it contains "#TRUE#" or "#FALSE#". Additionally, + * it may contain (in any case mapping) the text "true" or "false". + * - If dwFlags includes VAR_LOCALBOOL, then the text may also match the + * localised text of "True" or "False" in the language specified by lcid. + * - If none of these matches occur, the string is treated as a numeric string + * and the boolean pBoolOut will be set according to whether the number is zero + * or not. The dwFlags parameter is passed to VarR8FromStr() for this conversion. + * - If the text is not numeric and does not match any of the above, then + * DISP_E_TYPEMISMATCH is returned. + */ +HRESULT WINAPI VarBoolFromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, VARIANT_BOOL *pBoolOut) +{ + /* Any VB/VBA programmers out there should recognise these strings... */ + static const WCHAR szFalse[] = { '#','F','A','L','S','E','#','\0' }; + static const WCHAR szTrue[] = { '#','T','R','U','E','#','\0' }; + WCHAR szBuff[64]; + LANGID langId = MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT); + HRESULT hRes = S_OK; + + if (!strIn || !pBoolOut) + return DISP_E_TYPEMISMATCH; + + /* Check if we should be comparing against localised text */ + if (dwFlags & VAR_LOCALBOOL) + { + /* Convert our LCID into a usable value */ + lcid = ConvertDefaultLocale(lcid); + + langId = LANGIDFROMLCID(lcid); + + if (PRIMARYLANGID(langId) == LANG_NEUTRAL) + langId = MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT); + + /* Note: Native oleaut32 always copies strIn and maps halfwidth characters. + * I don't think this is needed unless any of the localised text strings + * contain characters that can be so mapped. In the event that this is + * true for a given language (possibly some Asian languages), then strIn + * should be mapped here _only_ if langId is an Id for which this can occur. + */ + } + + /* Note that if we are not comparing against localised strings, langId + * will have its default value of LANG_ENGLISH. This allows us to mimic + * the native behaviour of always checking against English strings even + * after we've checked for localised ones. + */ +VarBoolFromStr_CheckLocalised: + if (VARIANT_GetLocalisedText(langId, IDS_TRUE, szBuff)) + { + /* Compare against localised strings, ignoring case */ + if (!strcmpiW(strIn, szBuff)) + { + *pBoolOut = VARIANT_TRUE; /* Matched localised 'true' text */ + return hRes; + } + VARIANT_GetLocalisedText(langId, IDS_FALSE, szBuff); + if (!strcmpiW(strIn, szBuff)) + { + *pBoolOut = VARIANT_FALSE; /* Matched localised 'false' text */ + return hRes; + } + } + + if (langId != MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT)) + { + /* We have checked the localised text, now check English */ + langId = MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT); + goto VarBoolFromStr_CheckLocalised; + } + + /* All checks against localised text have failed, try #TRUE#/#FALSE# */ + if (!strcmpW(strIn, szFalse)) + *pBoolOut = VARIANT_FALSE; + else if (!strcmpW(strIn, szTrue)) + *pBoolOut = VARIANT_TRUE; + else + { + double d; + + /* If this string is a number, convert it as one */ + hRes = _VarR8FromStr(strIn, lcid, dwFlags, &d); + if (SUCCEEDED(hRes)) + hRes = _VarBoolFromR8(d, pBoolOut); + } + return hRes; +} + +/************************************************************************ + * VarBoolFromDisp (OLEAUT32.126) + * + * Convert a VT_DISPATCH to a VT_BOOL. + * + * PARAMS + * pdispIn [I] Source + * lcid [I] LCID for conversion + * pBoolOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarBoolFromDisp(IDispatch* pdispIn, LCID lcid, VARIANT_BOOL *pBoolOut) +{ + return _VarBoolFromDisp(pdispIn, lcid, pBoolOut); +} + +/************************************************************************ + * VarBoolFromI1 (OLEAUT32.233) + * + * Convert a VT_I1 to a VT_BOOL. + * + * PARAMS + * cIn [I] Source + * pBoolOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarBoolFromI1(signed char cIn, VARIANT_BOOL *pBoolOut) +{ + return _VarBoolFromI1(cIn, pBoolOut); +} + +/************************************************************************ + * VarBoolFromUI2 (OLEAUT32.234) + * + * Convert a VT_UI2 to a VT_BOOL. + * + * PARAMS + * usIn [I] Source + * pBoolOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarBoolFromUI2(USHORT usIn, VARIANT_BOOL *pBoolOut) +{ + return _VarBoolFromUI2(usIn, pBoolOut); +} + +/************************************************************************ + * VarBoolFromUI4 (OLEAUT32.235) + * + * Convert a VT_UI4 to a VT_BOOL. + * + * PARAMS + * ulIn [I] Source + * pBoolOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarBoolFromUI4(ULONG ulIn, VARIANT_BOOL *pBoolOut) +{ + return _VarBoolFromUI4(ulIn, pBoolOut); +} + +/************************************************************************ + * VarBoolFromDec (OLEAUT32.236) + * + * Convert a VT_DECIMAL to a VT_BOOL. + * + * PARAMS + * pDecIn [I] Source + * pBoolOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if pDecIn is invalid. + */ +HRESULT WINAPI VarBoolFromDec(DECIMAL* pDecIn, VARIANT_BOOL *pBoolOut) +{ + if (DEC_SCALE(pDecIn) > DEC_MAX_SCALE || (DEC_SIGN(pDecIn) & ~DECIMAL_NEG)) + return E_INVALIDARG; + + if (DEC_HI32(pDecIn) || DEC_MID32(pDecIn) || DEC_LO32(pDecIn)) + *pBoolOut = VARIANT_TRUE; + else + *pBoolOut = VARIANT_FALSE; + return S_OK; +} + +/************************************************************************ + * VarBoolFromI8 (OLEAUT32.370) + * + * Convert a VT_I8 to a VT_BOOL. + * + * PARAMS + * ullIn [I] Source + * pBoolOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarBoolFromI8(LONG64 llIn, VARIANT_BOOL *pBoolOut) +{ + return _VarBoolFromI8(llIn, pBoolOut); +} + +/************************************************************************ + * VarBoolFromUI8 (OLEAUT32.371) + * + * Convert a VT_UI8 to a VT_BOOL. + * + * PARAMS + * ullIn [I] Source + * pBoolOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarBoolFromUI8(ULONG64 ullIn, VARIANT_BOOL *pBoolOut) +{ + return _VarBoolFromUI8(ullIn, pBoolOut); +} + +/* BSTR + */ + +/* Write a number from a UI8 and sign */ +static WCHAR *VARIANT_WriteNumber(ULONG64 ulVal, WCHAR* szOut) +{ + do + { + WCHAR ulNextDigit = ulVal % 10; + + *szOut-- = '0' + ulNextDigit; + ulVal = (ulVal - ulNextDigit) / 10; + } while (ulVal); + + szOut++; + return szOut; +} + +/* Create a (possibly localised) BSTR from a UI8 and sign */ +static BSTR VARIANT_MakeBstr(LCID lcid, DWORD dwFlags, WCHAR *szOut) +{ + WCHAR szConverted[256]; + + if (dwFlags & VAR_NEGATIVE) + *--szOut = '-'; + + if (dwFlags & LOCALE_USE_NLS) + { + /* Format the number for the locale */ + szConverted[0] = '\0'; + GetNumberFormatW(lcid, + dwFlags & LOCALE_NOUSEROVERRIDE, + szOut, NULL, szConverted, sizeof(szConverted)/sizeof(WCHAR)); + szOut = szConverted; + } + return SysAllocStringByteLen((LPCSTR)szOut, strlenW(szOut) * sizeof(WCHAR)); +} + +/* Create a (possibly localised) BSTR from a UI8 and sign */ +static HRESULT VARIANT_BstrFromUInt(ULONG64 ulVal, LCID lcid, DWORD dwFlags, BSTR *pbstrOut) +{ + WCHAR szBuff[64], *szOut = szBuff + sizeof(szBuff)/sizeof(WCHAR) - 1; + + if (!pbstrOut) + return E_INVALIDARG; + + /* Create the basic number string */ + *szOut-- = '\0'; + szOut = VARIANT_WriteNumber(ulVal, szOut); + + *pbstrOut = VARIANT_MakeBstr(lcid, dwFlags, szOut); + TRACE("returning %s\n", debugstr_w(*pbstrOut)); + return *pbstrOut ? S_OK : E_OUTOFMEMORY; +} + +/****************************************************************************** + * VarBstrFromUI1 (OLEAUT32.108) + * + * Convert a VT_UI1 to a VT_BSTR. + * + * PARAMS + * bIn [I] Source + * lcid [I] LCID for the conversion + * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h") + * pbstrOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if pbstrOut is invalid. + * E_OUTOFMEMORY, if memory allocation fails. + */ +HRESULT WINAPI VarBstrFromUI1(BYTE bIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut) +{ + return VARIANT_BstrFromUInt(bIn, lcid, dwFlags, pbstrOut); +} + +/****************************************************************************** + * VarBstrFromI2 (OLEAUT32.109) + * + * Convert a VT_I2 to a VT_BSTR. + * + * PARAMS + * sIn [I] Source + * lcid [I] LCID for the conversion + * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h") + * pbstrOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if pbstrOut is invalid. + * E_OUTOFMEMORY, if memory allocation fails. + */ +HRESULT WINAPI VarBstrFromI2(short sIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut) +{ + ULONG64 ul64 = sIn; + + if (sIn < 0) + { + ul64 = -sIn; + dwFlags |= VAR_NEGATIVE; + } + return VARIANT_BstrFromUInt(ul64, lcid, dwFlags, pbstrOut); +} + +/****************************************************************************** + * VarBstrFromI4 (OLEAUT32.110) + * + * Convert a VT_I4 to a VT_BSTR. + * + * PARAMS + * lIn [I] Source + * lcid [I] LCID for the conversion + * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h") + * pbstrOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if pbstrOut is invalid. + * E_OUTOFMEMORY, if memory allocation fails. + */ +HRESULT WINAPI VarBstrFromI4(LONG lIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut) +{ + ULONG64 ul64 = lIn; + + if (lIn < 0) + { + ul64 = (ULONG)-lIn; + dwFlags |= VAR_NEGATIVE; + } + return VARIANT_BstrFromUInt(ul64, lcid, dwFlags, pbstrOut); +} + +static HRESULT VARIANT_BstrFromReal(DOUBLE dblIn, LCID lcid, ULONG dwFlags, + BSTR* pbstrOut, LPCWSTR lpszFormat) +{ + WCHAR buff[256]; + + if (!pbstrOut) + return E_INVALIDARG; + + sprintfW( buff, lpszFormat, dblIn ); + TRACE("created string %s\n", debugstr_w(buff)); + if (dwFlags & LOCALE_USE_NLS) + { + WCHAR numbuff[256]; + + /* Format the number for the locale */ + numbuff[0] = '\0'; + GetNumberFormatW(lcid, dwFlags & LOCALE_NOUSEROVERRIDE, + buff, NULL, numbuff, sizeof(numbuff) / sizeof(WCHAR)); + TRACE("created NLS string %s\n", debugstr_w(numbuff)); + *pbstrOut = SysAllocString(numbuff); + } + else + *pbstrOut = SysAllocString(buff); + return *pbstrOut ? S_OK : E_OUTOFMEMORY; +} + +/****************************************************************************** + * VarBstrFromR4 (OLEAUT32.111) + * + * Convert a VT_R4 to a VT_BSTR. + * + * PARAMS + * fltIn [I] Source + * lcid [I] LCID for the conversion + * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h") + * pbstrOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if pbstrOut is invalid. + * E_OUTOFMEMORY, if memory allocation fails. + */ +HRESULT WINAPI VarBstrFromR4(FLOAT fltIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut) +{ + return VARIANT_BstrFromReal(fltIn, lcid, dwFlags, pbstrOut, szFloatFormatW); +} + +/****************************************************************************** + * VarBstrFromR8 (OLEAUT32.112) + * + * Convert a VT_R8 to a VT_BSTR. + * + * PARAMS + * dblIn [I] Source + * lcid [I] LCID for the conversion + * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h") + * pbstrOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if pbstrOut is invalid. + * E_OUTOFMEMORY, if memory allocation fails. + */ +HRESULT WINAPI VarBstrFromR8(double dblIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut) +{ + return VARIANT_BstrFromReal(dblIn, lcid, dwFlags, pbstrOut, szDoubleFormatW); +} + +/****************************************************************************** + * VarBstrFromCy [OLEAUT32.113] + * + * Convert a VT_CY to a VT_BSTR. + * + * PARAMS + * cyIn [I] Source + * lcid [I] LCID for the conversion + * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h") + * pbstrOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if pbstrOut is invalid. + * E_OUTOFMEMORY, if memory allocation fails. + */ +HRESULT WINAPI VarBstrFromCy(CY cyIn, LCID lcid, ULONG dwFlags, BSTR *pbstrOut) +{ + WCHAR buff[256]; + double dblVal; + + if (!pbstrOut) + return E_INVALIDARG; + + VarR8FromCy(cyIn, &dblVal); + sprintfW(buff, szDoubleFormatW, dblVal); + + if (dwFlags & LOCALE_USE_NLS) + { + WCHAR cybuff[256]; + + /* Format the currency for the locale */ + cybuff[0] = '\0'; + GetCurrencyFormatW(lcid, dwFlags & LOCALE_NOUSEROVERRIDE, + buff, NULL, cybuff, sizeof(cybuff) / sizeof(WCHAR)); + *pbstrOut = SysAllocString(cybuff); + } + else + *pbstrOut = SysAllocString(buff); + + return *pbstrOut ? S_OK : E_OUTOFMEMORY; +} + +/****************************************************************************** + * VarBstrFromDate [OLEAUT32.114] + * + * Convert a VT_DATE to a VT_BSTR. + * + * PARAMS + * dateIn [I] Source + * lcid [I] LCID for the conversion + * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h") + * pbstrOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if pbstrOut or dateIn is invalid. + * E_OUTOFMEMORY, if memory allocation fails. + */ +HRESULT WINAPI VarBstrFromDate(DATE dateIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut) +{ + SYSTEMTIME st; + DWORD dwFormatFlags = dwFlags & LOCALE_NOUSEROVERRIDE; + WCHAR date[128], *time; + + TRACE("(%g,0x%08lx,0x%08lx,%p)\n", dateIn, lcid, dwFlags, pbstrOut); + + if (!pbstrOut || !VariantTimeToSystemTime(dateIn, &st)) + return E_INVALIDARG; + + *pbstrOut = NULL; + + if (dwFlags & VAR_CALENDAR_THAI) + st.wYear += 553; /* Use the Thai buddhist calendar year */ + else if (dwFlags & (VAR_CALENDAR_HIJRI|VAR_CALENDAR_GREGORIAN)) + FIXME("VAR_CALENDAR_HIJRI/VAR_CALENDAR_GREGORIAN not handled\n"); + + if (dwFlags & LOCALE_USE_NLS) + dwFlags &= ~(VAR_TIMEVALUEONLY|VAR_DATEVALUEONLY); + else + { + double whole = dateIn < 0 ? ceil(dateIn) : floor(dateIn); + double partial = dateIn - whole; + + if (whole == 0.0) + dwFlags |= VAR_TIMEVALUEONLY; + else if (partial < 1e-12) + dwFlags |= VAR_DATEVALUEONLY; + } + + if (dwFlags & VAR_TIMEVALUEONLY) + date[0] = '\0'; + else + if (!GetDateFormatW(lcid, dwFormatFlags|DATE_SHORTDATE, &st, NULL, date, + sizeof(date)/sizeof(WCHAR))) + return E_INVALIDARG; + + if (!(dwFlags & VAR_DATEVALUEONLY)) + { + time = date + strlenW(date); + if (time != date) + *time++ = ' '; + if (!GetTimeFormatW(lcid, dwFormatFlags, &st, NULL, time, + sizeof(date)/sizeof(WCHAR)-(time-date))) + return E_INVALIDARG; + } + + *pbstrOut = SysAllocString(date); + if (*pbstrOut) + TRACE("returning %s\n", debugstr_w(*pbstrOut)); + return *pbstrOut ? S_OK : E_OUTOFMEMORY; +} + +/****************************************************************************** + * VarBstrFromBool (OLEAUT32.116) + * + * Convert a VT_BOOL to a VT_BSTR. + * + * PARAMS + * boolIn [I] Source + * lcid [I] LCID for the conversion + * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h") + * pbstrOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if pbstrOut is invalid. + * E_OUTOFMEMORY, if memory allocation fails. + * + * NOTES + * If dwFlags includes VARIANT_LOCALBOOL, this function converts to the + * localised text of "True" or "False". To convert a bool into a + * numeric string of "0" or "-1", use VariantChangeTypeTypeEx(). + */ +HRESULT WINAPI VarBstrFromBool(VARIANT_BOOL boolIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut) +{ + WCHAR szBuff[64]; + DWORD dwResId = IDS_TRUE; + LANGID langId; + + TRACE("%d,0x%08lx,0x%08lx,%p\n", boolIn, lcid, dwFlags, pbstrOut); + + if (!pbstrOut) + return E_INVALIDARG; + + /* VAR_BOOLONOFF and VAR_BOOLYESNO are internal flags used + * for variant formatting */ + switch (dwFlags & (VAR_LOCALBOOL|VAR_BOOLONOFF|VAR_BOOLYESNO)) + { + case VAR_BOOLONOFF: + dwResId = IDS_ON; + break; + case VAR_BOOLYESNO: + dwResId = IDS_YES; + break; + case VAR_LOCALBOOL: + break; + default: + lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT),SORT_DEFAULT); + } + + lcid = ConvertDefaultLocale(lcid); + langId = LANGIDFROMLCID(lcid); + if (PRIMARYLANGID(langId) == LANG_NEUTRAL) + langId = MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT); + + if (boolIn == VARIANT_FALSE) + dwResId++; /* Use negative form */ + +VarBstrFromBool_GetLocalised: + if (VARIANT_GetLocalisedText(langId, dwResId, szBuff)) + { + *pbstrOut = SysAllocString(szBuff); + return *pbstrOut ? S_OK : E_OUTOFMEMORY; + } + + if (langId != MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT)) + { + langId = MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT); + goto VarBstrFromBool_GetLocalised; + } + + /* Should never get here */ + WARN("Failed to load bool text!\n"); + return E_OUTOFMEMORY; +} + +/****************************************************************************** + * VarBstrFromI1 (OLEAUT32.229) + * + * Convert a VT_I1 to a VT_BSTR. + * + * PARAMS + * cIn [I] Source + * lcid [I] LCID for the conversion + * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h") + * pbstrOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if pbstrOut is invalid. + * E_OUTOFMEMORY, if memory allocation fails. + */ +HRESULT WINAPI VarBstrFromI1(signed char cIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut) +{ + ULONG64 ul64 = cIn; + + if (cIn < 0) + { + ul64 = -cIn; + dwFlags |= VAR_NEGATIVE; + } + return VARIANT_BstrFromUInt(ul64, lcid, dwFlags, pbstrOut); +} + +/****************************************************************************** + * VarBstrFromUI2 (OLEAUT32.230) + * + * Convert a VT_UI2 to a VT_BSTR. + * + * PARAMS + * usIn [I] Source + * lcid [I] LCID for the conversion + * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h") + * pbstrOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if pbstrOut is invalid. + * E_OUTOFMEMORY, if memory allocation fails. + */ +HRESULT WINAPI VarBstrFromUI2(USHORT usIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut) +{ + return VARIANT_BstrFromUInt(usIn, lcid, dwFlags, pbstrOut); +} + +/****************************************************************************** + * VarBstrFromUI4 (OLEAUT32.231) + * + * Convert a VT_UI4 to a VT_BSTR. + * + * PARAMS + * ulIn [I] Source + * lcid [I] LCID for the conversion + * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h") + * pbstrOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if pbstrOut is invalid. + * E_OUTOFMEMORY, if memory allocation fails. + */ +HRESULT WINAPI VarBstrFromUI4(ULONG ulIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut) +{ + return VARIANT_BstrFromUInt(ulIn, lcid, dwFlags, pbstrOut); +} + +/****************************************************************************** + * VarBstrFromDec (OLEAUT32.232) + * + * Convert a VT_DECIMAL to a VT_BSTR. + * + * PARAMS + * pDecIn [I] Source + * lcid [I] LCID for the conversion + * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h") + * pbstrOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if pbstrOut is invalid. + * E_OUTOFMEMORY, if memory allocation fails. + */ +HRESULT WINAPI VarBstrFromDec(DECIMAL* pDecIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut) +{ + if (!pbstrOut) + return E_INVALIDARG; + + if (!DEC_SCALE(pDecIn) && !DEC_HI32(pDecIn)) + { + WCHAR szBuff[256], *szOut = szBuff + sizeof(szBuff)/sizeof(WCHAR) - 1; + + /* Create the basic number string */ + *szOut-- = '\0'; + szOut = VARIANT_WriteNumber(DEC_LO64(pDecIn), szOut); + if (DEC_SIGN(pDecIn)) + dwFlags |= VAR_NEGATIVE; + + *pbstrOut = VARIANT_MakeBstr(lcid, dwFlags, szOut); + TRACE("returning %s\n", debugstr_w(*pbstrOut)); + return *pbstrOut ? S_OK : E_OUTOFMEMORY; + } + FIXME("semi-stub\n"); + return E_INVALIDARG; +} + +/************************************************************************ + * VarBstrFromI8 (OLEAUT32.370) + * + * Convert a VT_I8 to a VT_BSTR. + * + * PARAMS + * llIn [I] Source + * lcid [I] LCID for the conversion + * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h") + * pbstrOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if pbstrOut is invalid. + * E_OUTOFMEMORY, if memory allocation fails. + */ +HRESULT WINAPI VarBstrFromI8(LONG64 llIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut) +{ + ULONG64 ul64 = llIn; + + if (llIn < 0) + { + ul64 = -llIn; + dwFlags |= VAR_NEGATIVE; + } + return VARIANT_BstrFromUInt(ul64, lcid, dwFlags, pbstrOut); +} + +/************************************************************************ + * VarBstrFromUI8 (OLEAUT32.371) + * + * Convert a VT_UI8 to a VT_BSTR. + * + * PARAMS + * ullIn [I] Source + * lcid [I] LCID for the conversion + * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h") + * pbstrOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if pbstrOut is invalid. + * E_OUTOFMEMORY, if memory allocation fails. + */ +HRESULT WINAPI VarBstrFromUI8(ULONG64 ullIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut) +{ + return VARIANT_BstrFromUInt(ullIn, lcid, dwFlags, pbstrOut); +} + +/********************************************************************** + * VarBstrCat (OLEAUT32.313) + * + * Concatenate two BSTR values. + * + * PARAMS + * pbstrLeft [I] Source + * pbstrRight [I] Value to concatenate + * pbstrOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if pbstrOut is invalid. + * E_OUTOFMEMORY, if memory allocation fails. + */ +HRESULT WINAPI VarBstrCat(BSTR pbstrLeft, BSTR pbstrRight, BSTR *pbstrOut) +{ + unsigned int len; + + if (!pbstrOut) + return E_INVALIDARG; + + len = pbstrLeft ? strlenW(pbstrLeft) : 0; + if (pbstrRight) + len += strlenW(pbstrRight); + + *pbstrOut = SysAllocStringLen(NULL, len); + if (!*pbstrOut) + return E_OUTOFMEMORY; + + (*pbstrOut)[0] = '\0'; + + if (pbstrLeft) + strcpyW(*pbstrOut, pbstrLeft); + + if (pbstrRight) + strcatW(*pbstrOut, pbstrRight); + + return S_OK; +} + +/********************************************************************** + * VarBstrCmp (OLEAUT32.314) + * + * Compare two BSTR values. + * + * PARAMS + * pbstrLeft [I] Source + * pbstrRight [I] Value to compare + * lcid [I] LCID for the comparison + * dwFlags [I] Flags to pass directly to CompareStringW(). + * + * RETURNS + * VARCMP_LT, VARCMP_EQ or VARCMP_GT indicating that pbstrLeft is less + * than, equal to or greater than pbstrRight respectively. + * VARCMP_NULL is returned if either string is NULL, unless both are NULL + * in which case VARCMP_EQ is returned. + */ +HRESULT WINAPI VarBstrCmp(BSTR pbstrLeft, BSTR pbstrRight, LCID lcid, DWORD dwFlags) +{ + if (!pbstrLeft) + { + if (!pbstrRight || !*pbstrRight) + return VARCMP_EQ; + return VARCMP_NULL; + } + else if (!pbstrRight) + { + if (!*pbstrLeft) + return VARCMP_EQ; + return VARCMP_NULL; + } + + return CompareStringW(lcid, dwFlags, pbstrLeft, -1, pbstrRight, -1) - 1; +} + +/* + * DATE + */ + +/****************************************************************************** + * VarDateFromUI1 (OLEAUT32.88) + * + * Convert a VT_UI1 to a VT_DATE. + * + * PARAMS + * bIn [I] Source + * pdateOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarDateFromUI1(BYTE bIn, DATE* pdateOut) +{ + return _VarDateFromUI1(bIn, pdateOut); +} + +/****************************************************************************** + * VarDateFromI2 (OLEAUT32.89) + * + * Convert a VT_I2 to a VT_DATE. + * + * PARAMS + * sIn [I] Source + * pdateOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarDateFromI2(short sIn, DATE* pdateOut) +{ + return _VarDateFromI2(sIn, pdateOut); +} + +/****************************************************************************** + * VarDateFromI4 (OLEAUT32.90) + * + * Convert a VT_I4 to a VT_DATE. + * + * PARAMS + * lIn [I] Source + * pdateOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarDateFromI4(LONG lIn, DATE* pdateOut) +{ + return _VarDateFromI4(lIn, pdateOut); +} + +/****************************************************************************** + * VarDateFromR4 (OLEAUT32.91) + * + * Convert a VT_R4 to a VT_DATE. + * + * PARAMS + * fltIn [I] Source + * pdateOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarDateFromR4(FLOAT fltIn, DATE* pdateOut) +{ + return _VarDateFromR4(fltIn, pdateOut); +} + +/****************************************************************************** + * VarDateFromR8 (OLEAUT32.92) + * + * Convert a VT_R8 to a VT_DATE. + * + * PARAMS + * dblIn [I] Source + * pdateOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarDateFromR8(double dblIn, DATE* pdateOut) +{ + return _VarDateFromR8(dblIn, pdateOut); +} + +/********************************************************************** + * VarDateFromDisp (OLEAUT32.95) + * + * Convert a VT_DISPATCH to a VT_DATE. + * + * PARAMS + * pdispIn [I] Source + * lcid [I] LCID for conversion + * pdateOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: E_INVALIDARG, if the source value is invalid + * DISP_E_OVERFLOW, if the value will not fit in the destination + * DISP_E_TYPEMISMATCH, if the type cannot be converted + */ +HRESULT WINAPI VarDateFromDisp(IDispatch* pdispIn, LCID lcid, DATE* pdateOut) +{ + return _VarDateFromDisp(pdispIn, lcid, pdateOut); +} + +/****************************************************************************** + * VarDateFromBool (OLEAUT32.96) + * + * Convert a VT_BOOL to a VT_DATE. + * + * PARAMS + * boolIn [I] Source + * pdateOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarDateFromBool(VARIANT_BOOL boolIn, DATE* pdateOut) +{ + return _VarDateFromBool(boolIn, pdateOut); +} + +/********************************************************************** + * VarDateFromCy (OLEAUT32.93) + * + * Convert a VT_CY to a VT_DATE. + * + * PARAMS + * lIn [I] Source + * pdateOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarDateFromCy(CY cyIn, DATE* pdateOut) +{ + return _VarDateFromCy(cyIn, pdateOut); +} + +/* Date string parsing */ +#define DP_TIMESEP 0x01 /* Time separator ( _must_ remain 0x1, used as a bitmask) */ +#define DP_DATESEP 0x02 /* Date separator */ +#define DP_MONTH 0x04 /* Month name */ +#define DP_AM 0x08 /* AM */ +#define DP_PM 0x10 /* PM */ + +typedef struct tagDATEPARSE +{ + DWORD dwCount; /* Number of fields found so far (maximum 6) */ + DWORD dwParseFlags; /* Global parse flags (DP_ Flags above) */ + DWORD dwFlags[6]; /* Flags for each field */ + DWORD dwValues[6]; /* Value of each field */ +} DATEPARSE; + +#define TIMEFLAG(i) ((dp.dwFlags[i] & DP_TIMESEP) << i) + +#define IsLeapYear(y) (((y % 4) == 0) && (((y % 100) != 0) || ((y % 400) == 0))) + +/* Determine if a day is valid in a given month of a given year */ +static BOOL VARIANT_IsValidMonthDay(DWORD day, DWORD month, DWORD year) +{ + static const BYTE days[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + + if (day && month && month < 13) + { + if (day <= days[month] || (month == 2 && day == 29 && IsLeapYear(year))) + return TRUE; + } + return FALSE; +} + +/* Possible orders for 3 numbers making up a date */ +#define ORDER_MDY 0x01 +#define ORDER_YMD 0x02 +#define ORDER_YDM 0x04 +#define ORDER_DMY 0x08 +#define ORDER_MYD 0x10 /* Synthetic order, used only for funky 2 digit dates */ + +/* Determine a date for a particular locale, from 3 numbers */ +static inline HRESULT VARIANT_MakeDate(DATEPARSE *dp, DWORD iDate, + DWORD offset, SYSTEMTIME *st) +{ + DWORD dwAllOrders, dwTry, dwCount = 0, v1, v2, v3; + + if (!dp->dwCount) + { + v1 = 30; /* Default to (Variant) 0 date part */ + v2 = 12; + v3 = 1899; + goto VARIANT_MakeDate_OK; + } + + v1 = dp->dwValues[offset + 0]; + v2 = dp->dwValues[offset + 1]; + if (dp->dwCount == 2) + { + SYSTEMTIME current; + GetSystemTime(¤t); + v3 = current.wYear; + } + else + v3 = dp->dwValues[offset + 2]; + + TRACE("(%ld,%ld,%ld,%ld,%ld)\n", v1, v2, v3, iDate, offset); + + /* If one number must be a month (Because a month name was given), then only + * consider orders with the month in that position. + * If we took the current year as 'v3', then only allow a year in that position. + */ + if (dp->dwFlags[offset + 0] & DP_MONTH) + { + dwAllOrders = ORDER_MDY; + } + else if (dp->dwFlags[offset + 1] & DP_MONTH) + { + dwAllOrders = ORDER_DMY; + if (dp->dwCount > 2) + dwAllOrders |= ORDER_YMD; + } + else if (dp->dwCount > 2 && dp->dwFlags[offset + 2] & DP_MONTH) + { + dwAllOrders = ORDER_YDM; + } + else + { + dwAllOrders = ORDER_MDY|ORDER_DMY; + if (dp->dwCount > 2) + dwAllOrders |= (ORDER_YMD|ORDER_YDM); + } + +VARIANT_MakeDate_Start: + TRACE("dwAllOrders is 0x%08lx\n", dwAllOrders); + + while (dwAllOrders) + { + DWORD dwTemp; + + if (dwCount == 0) + { + /* First: Try the order given by iDate */ + switch (iDate) + { + case 0: dwTry = dwAllOrders & ORDER_MDY; break; + case 1: dwTry = dwAllOrders & ORDER_DMY; break; + default: dwTry = dwAllOrders & ORDER_YMD; break; + } + } + else if (dwCount == 1) + { + /* Second: Try all the orders compatible with iDate */ + switch (iDate) + { + case 0: dwTry = dwAllOrders & ~(ORDER_DMY|ORDER_YDM); break; + case 1: dwTry = dwAllOrders & ~(ORDER_MDY|ORDER_YMD|ORDER_MYD); break; + default: dwTry = dwAllOrders & ~(ORDER_DMY|ORDER_YDM); break; + } + } + else + { + /* Finally: Try any remaining orders */ + dwTry = dwAllOrders; + } + + TRACE("Attempt %ld, dwTry is 0x%08lx\n", dwCount, dwTry); + + dwCount++; + if (!dwTry) + continue; + +#define DATE_SWAP(x,y) do { dwTemp = x; x = y; y = dwTemp; } while (0) + + if (dwTry & ORDER_MDY) + { + if (VARIANT_IsValidMonthDay(v2,v1,v3)) + { + DATE_SWAP(v1,v2); + goto VARIANT_MakeDate_OK; + } + dwAllOrders &= ~ORDER_MDY; + } + if (dwTry & ORDER_YMD) + { + if (VARIANT_IsValidMonthDay(v3,v2,v1)) + { + DATE_SWAP(v1,v3); + goto VARIANT_MakeDate_OK; + } + dwAllOrders &= ~ORDER_YMD; + } + if (dwTry & ORDER_YDM) + { + if (VARIANT_IsValidMonthDay(v2,v3,v1)) + { + DATE_SWAP(v1,v2); + DATE_SWAP(v2,v3); + goto VARIANT_MakeDate_OK; + } + dwAllOrders &= ~ORDER_YDM; + } + if (dwTry & ORDER_DMY) + { + if (VARIANT_IsValidMonthDay(v1,v2,v3)) + goto VARIANT_MakeDate_OK; + dwAllOrders &= ~ORDER_DMY; + } + if (dwTry & ORDER_MYD) + { + /* Only occurs if we are trying a 2 year date as M/Y not D/M */ + if (VARIANT_IsValidMonthDay(v3,v1,v2)) + { + DATE_SWAP(v1,v3); + DATE_SWAP(v2,v3); + goto VARIANT_MakeDate_OK; + } + dwAllOrders &= ~ORDER_MYD; + } + } + + if (dp->dwCount == 2) + { + /* We couldn't make a date as D/M or M/D, so try M/Y or Y/M */ + v3 = 1; /* 1st of the month */ + dwAllOrders = ORDER_YMD|ORDER_MYD; + dp->dwCount = 0; /* Don't return to this code path again */ + dwCount = 0; + goto VARIANT_MakeDate_Start; + } + + /* No valid dates were able to be constructed */ + return DISP_E_TYPEMISMATCH; + +VARIANT_MakeDate_OK: + + /* Check that the time part is ok */ + if (st->wHour > 23 || st->wMinute > 59 || st->wSecond > 59) + return DISP_E_TYPEMISMATCH; + + TRACE("Time %d %d %d\n", st->wHour, st->wMinute, st->wSecond); + if (st->wHour < 12 && (dp->dwParseFlags & DP_PM)) + st->wHour += 12; + else if (st->wHour == 12 && (dp->dwParseFlags & DP_AM)) + st->wHour = 0; + TRACE("Time %d %d %d\n", st->wHour, st->wMinute, st->wSecond); + + st->wDay = v1; + st->wMonth = v2; + /* FIXME: For 2 digit dates, I'm not sure if 30 is hard coded or not. It may + * be retrieved from: + * HKCU\Control Panel\International\Calendars\TwoDigitYearMax + * But Wine doesn't have/use that key as at the time of writing. + */ + st->wYear = v3 < 30 ? 2000 + v3 : v3 < 100 ? 1900 + v3 : v3; + TRACE("Returning date %ld/%ld/%d\n", v1, v2, st->wYear); + return S_OK; +} + +/****************************************************************************** + * VarDateFromStr [OLEAUT32.94] + * + * Convert a VT_BSTR to at VT_DATE. + * + * PARAMS + * strIn [I] String to convert + * lcid [I] Locale identifier for the conversion + * dwFlags [I] Flags affecting the conversion (VAR_ flags from "oleauto.h") + * pdateOut [O] Destination for the converted value + * + * RETURNS + * Success: S_OK. pdateOut contains the converted value. + * FAILURE: An HRESULT error code indicating the prolem. + * + * NOTES + * Any date format that can be created using the date formats from lcid + * (Either from kernel Nls functions, variant conversion or formatting) is a + * valid input to this function. In addition, a few more esoteric formats are + * also supported for compatibility with the native version. The date is + * interpreted according to the date settings in the control panel, unless + * the date is invalid in that format, in which the most compatible format + * that produces a valid date will be used. + */ +HRESULT WINAPI VarDateFromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, DATE* pdateOut) +{ + static const USHORT ParseDateTokens[] = + { + LOCALE_SMONTHNAME1, LOCALE_SMONTHNAME2, LOCALE_SMONTHNAME3, LOCALE_SMONTHNAME4, + LOCALE_SMONTHNAME5, LOCALE_SMONTHNAME6, LOCALE_SMONTHNAME7, LOCALE_SMONTHNAME8, + LOCALE_SMONTHNAME9, LOCALE_SMONTHNAME10, LOCALE_SMONTHNAME11, LOCALE_SMONTHNAME12, + LOCALE_SMONTHNAME13, + LOCALE_SABBREVMONTHNAME1, LOCALE_SABBREVMONTHNAME2, LOCALE_SABBREVMONTHNAME3, + LOCALE_SABBREVMONTHNAME4, LOCALE_SABBREVMONTHNAME5, LOCALE_SABBREVMONTHNAME6, + LOCALE_SABBREVMONTHNAME7, LOCALE_SABBREVMONTHNAME8, LOCALE_SABBREVMONTHNAME9, + LOCALE_SABBREVMONTHNAME10, LOCALE_SABBREVMONTHNAME11, LOCALE_SABBREVMONTHNAME12, + LOCALE_SABBREVMONTHNAME13, + LOCALE_SDAYNAME1, LOCALE_SDAYNAME2, LOCALE_SDAYNAME3, LOCALE_SDAYNAME4, + LOCALE_SDAYNAME5, LOCALE_SDAYNAME6, LOCALE_SDAYNAME7, + LOCALE_SABBREVDAYNAME1, LOCALE_SABBREVDAYNAME2, LOCALE_SABBREVDAYNAME3, + LOCALE_SABBREVDAYNAME4, LOCALE_SABBREVDAYNAME5, LOCALE_SABBREVDAYNAME6, + LOCALE_SABBREVDAYNAME7, + LOCALE_S1159, LOCALE_S2359 + }; + static const BYTE ParseDateMonths[] = + { + 1,2,3,4,5,6,7,8,9,10,11,12,13, + 1,2,3,4,5,6,7,8,9,10,11,12,13 + }; + size_t i; + BSTR tokens[sizeof(ParseDateTokens)/sizeof(ParseDateTokens[0])]; + DATEPARSE dp; + DWORD dwDateSeps = 0, iDate = 0; + HRESULT hRet = S_OK; + + if ((dwFlags & (VAR_TIMEVALUEONLY|VAR_DATEVALUEONLY)) == + (VAR_TIMEVALUEONLY|VAR_DATEVALUEONLY)) + return E_INVALIDARG; + + if (!strIn) + return DISP_E_TYPEMISMATCH; + + *pdateOut = 0.0; + + TRACE("(%s,0x%08lx,0x%08lx,%p)\n", debugstr_w(strIn), lcid, dwFlags, pdateOut); + + memset(&dp, 0, sizeof(dp)); + + GetLocaleInfoW(lcid, LOCALE_IDATE|LOCALE_RETURN_NUMBER|(dwFlags & LOCALE_NOUSEROVERRIDE), + (LPWSTR)&iDate, sizeof(iDate)/sizeof(WCHAR)); + TRACE("iDate is %ld\n", iDate); + + /* Get the month/day/am/pm tokens for this locale */ + for (i = 0; i < sizeof(tokens)/sizeof(tokens[0]); i++) + { + WCHAR buff[128]; + LCTYPE lctype = ParseDateTokens[i] | (dwFlags & LOCALE_NOUSEROVERRIDE); + + /* FIXME: Alternate calendars - should use GetCalendarInfo() and/or + * GetAltMonthNames(). We should really cache these strings too. + */ + buff[0] = '\0'; + GetLocaleInfoW(lcid, lctype, buff, sizeof(buff)/sizeof(WCHAR)); + tokens[i] = SysAllocString(buff); + TRACE("token %d is %s\n", i, debugstr_w(tokens[i])); + } + + /* Parse the string into our structure */ + while (*strIn) + { + if (dp.dwCount > 6) + break; + + if (isdigitW(*strIn)) + { + dp.dwValues[dp.dwCount] = strtoulW(strIn, &strIn, 10); + dp.dwCount++; + strIn--; + } + else if (isalpha(*strIn)) + { + BOOL bFound = FALSE; + + for (i = 0; i < sizeof(tokens)/sizeof(tokens[0]); i++) + { + DWORD dwLen = strlenW(tokens[i]); + if (dwLen && !strncmpiW(strIn, tokens[i], dwLen)) + { + if (i <= 25) + { + dp.dwValues[dp.dwCount] = ParseDateMonths[i]; + dp.dwFlags[dp.dwCount] |= (DP_MONTH|DP_DATESEP); + dp.dwCount++; + } + else if (i > 39) + { + if (!dp.dwCount || dp.dwParseFlags & (DP_AM|DP_PM)) + hRet = DISP_E_TYPEMISMATCH; + else + { + dp.dwFlags[dp.dwCount - 1] |= (i == 40 ? DP_AM : DP_PM); + dp.dwParseFlags |= (i == 40 ? DP_AM : DP_PM); + } + } + strIn += (dwLen - 1); + bFound = TRUE; + break; + } + } + + if (!bFound) + { + if ((*strIn == 'a' || *strIn == 'A' || *strIn == 'p' || *strIn == 'P') && + (dp.dwCount && !(dp.dwParseFlags & (DP_AM|DP_PM)))) + { + /* Special case - 'a' and 'p' are recognised as short for am/pm */ + if (*strIn == 'a' || *strIn == 'A') + { + dp.dwFlags[dp.dwCount - 1] |= DP_AM; + dp.dwParseFlags |= DP_AM; + } + else + { + dp.dwFlags[dp.dwCount - 1] |= DP_PM; + dp.dwParseFlags |= DP_PM; + } + strIn++; + } + else + { + TRACE("No matching token for %s\n", debugstr_w(strIn)); + hRet = DISP_E_TYPEMISMATCH; + break; + } + } + } + else if (*strIn == ':' || *strIn == '.') + { + if (!dp.dwCount || !strIn[1]) + hRet = DISP_E_TYPEMISMATCH; + else + dp.dwFlags[dp.dwCount - 1] |= DP_TIMESEP; + } + else if (*strIn == '-' || *strIn == '/') + { + dwDateSeps++; + if (dwDateSeps > 2 || !dp.dwCount || !strIn[1]) + hRet = DISP_E_TYPEMISMATCH; + else + dp.dwFlags[dp.dwCount - 1] |= DP_DATESEP; + } + else if (*strIn == ',' || isspaceW(*strIn)) + { + if (*strIn == ',' && !strIn[1]) + hRet = DISP_E_TYPEMISMATCH; + } + else + { + hRet = DISP_E_TYPEMISMATCH; + } + strIn++; + } + + if (!dp.dwCount || dp.dwCount > 6 || + (dp.dwCount == 1 && !(dp.dwParseFlags & (DP_AM|DP_PM)))) + hRet = DISP_E_TYPEMISMATCH; + + if (SUCCEEDED(hRet)) + { + SYSTEMTIME st; + DWORD dwOffset = 0; /* Start of date fields in dp.dwValues */ + + st.wDayOfWeek = st.wHour = st.wMinute = st.wSecond = st.wMilliseconds = 0; + + /* Figure out which numbers correspond to which fields. + * + * This switch statement works based on the fact that native interprets any + * fields that are not joined with a time separator ('.' or ':') as date + * fields. Thus we construct a value from 0-32 where each set bit indicates + * a time field. This encapsulates the hundreds of permutations of 2-6 fields. + * For valid permutations, we set dwOffset to point to the first date field + * and shorten dp.dwCount by the number of time fields found. The real + * magic here occurs in VARIANT_MakeDate() above, where we determine what + * each date number must represent in the context of iDate. + */ + TRACE("0x%08lx\n", TIMEFLAG(0)|TIMEFLAG(1)|TIMEFLAG(2)|TIMEFLAG(3)|TIMEFLAG(4)); + + switch (TIMEFLAG(0)|TIMEFLAG(1)|TIMEFLAG(2)|TIMEFLAG(3)|TIMEFLAG(4)) + { + case 0x1: /* TT TTDD TTDDD */ + if (dp.dwCount > 3 && + ((dp.dwFlags[2] & (DP_AM|DP_PM)) || (dp.dwFlags[3] & (DP_AM|DP_PM)) || + (dp.dwFlags[4] & (DP_AM|DP_PM)))) + hRet = DISP_E_TYPEMISMATCH; + else if (dp.dwCount != 2 && dp.dwCount != 4 && dp.dwCount != 5) + hRet = DISP_E_TYPEMISMATCH; + st.wHour = dp.dwValues[0]; + st.wMinute = dp.dwValues[1]; + dp.dwCount -= 2; + dwOffset = 2; + break; + + case 0x3: /* TTT TTTDD TTTDDD */ + if (dp.dwCount > 4 && + ((dp.dwFlags[3] & (DP_AM|DP_PM)) || (dp.dwFlags[4] & (DP_AM|DP_PM)) || + (dp.dwFlags[5] & (DP_AM|DP_PM)))) + hRet = DISP_E_TYPEMISMATCH; + else if (dp.dwCount != 3 && dp.dwCount != 5 && dp.dwCount != 6) + hRet = DISP_E_TYPEMISMATCH; + st.wHour = dp.dwValues[0]; + st.wMinute = dp.dwValues[1]; + st.wSecond = dp.dwValues[2]; + dwOffset = 3; + dp.dwCount -= 3; + break; + + case 0x4: /* DDTT */ + if (dp.dwCount != 4 || + (dp.dwFlags[0] & (DP_AM|DP_PM)) || (dp.dwFlags[1] & (DP_AM|DP_PM))) + hRet = DISP_E_TYPEMISMATCH; + + st.wHour = dp.dwValues[2]; + st.wMinute = dp.dwValues[3]; + dp.dwCount -= 2; + break; + + case 0x0: /* T DD DDD TDDD TDDD */ + if (dp.dwCount == 1 && (dp.dwParseFlags & (DP_AM|DP_PM))) + { + st.wHour = dp.dwValues[0]; /* T */ + dp.dwCount = 0; + break; + } + else if (dp.dwCount > 4 || (dp.dwCount < 3 && dp.dwParseFlags & (DP_AM|DP_PM))) + { + hRet = DISP_E_TYPEMISMATCH; + } + else if (dp.dwCount == 3) + { + if (dp.dwFlags[0] & (DP_AM|DP_PM)) /* TDD */ + { + dp.dwCount = 2; + st.wHour = dp.dwValues[0]; + dwOffset = 1; + break; + } + if (dp.dwFlags[2] & (DP_AM|DP_PM)) /* DDT */ + { + dp.dwCount = 2; + st.wHour = dp.dwValues[2]; + break; + } + else if (dp.dwParseFlags & (DP_AM|DP_PM)) + hRet = DISP_E_TYPEMISMATCH; + } + else if (dp.dwCount == 4) + { + dp.dwCount = 3; + if (dp.dwFlags[0] & (DP_AM|DP_PM)) /* TDDD */ + { + st.wHour = dp.dwValues[0]; + dwOffset = 1; + } + else if (dp.dwFlags[3] & (DP_AM|DP_PM)) /* DDDT */ + { + st.wHour = dp.dwValues[3]; + } + else + hRet = DISP_E_TYPEMISMATCH; + break; + } + /* .. fall through .. */ + + case 0x8: /* DDDTT */ + if ((dp.dwCount == 2 && (dp.dwParseFlags & (DP_AM|DP_PM))) || + (dp.dwCount == 5 && ((dp.dwFlags[0] & (DP_AM|DP_PM)) || + (dp.dwFlags[1] & (DP_AM|DP_PM)) || (dp.dwFlags[2] & (DP_AM|DP_PM)))) || + dp.dwCount == 4 || dp.dwCount == 6) + hRet = DISP_E_TYPEMISMATCH; + st.wHour = dp.dwValues[3]; + st.wMinute = dp.dwValues[4]; + if (dp.dwCount == 5) + dp.dwCount -= 2; + break; + + case 0xC: /* DDTTT */ + if (dp.dwCount != 5 || + (dp.dwFlags[0] & (DP_AM|DP_PM)) || (dp.dwFlags[1] & (DP_AM|DP_PM))) + hRet = DISP_E_TYPEMISMATCH; + st.wHour = dp.dwValues[2]; + st.wMinute = dp.dwValues[3]; + st.wSecond = dp.dwValues[4]; + dp.dwCount -= 3; + break; + + case 0x18: /* DDDTTT */ + if ((dp.dwFlags[0] & (DP_AM|DP_PM)) || (dp.dwFlags[1] & (DP_AM|DP_PM)) || + (dp.dwFlags[2] & (DP_AM|DP_PM))) + hRet = DISP_E_TYPEMISMATCH; + st.wHour = dp.dwValues[3]; + st.wMinute = dp.dwValues[4]; + st.wSecond = dp.dwValues[5]; + dp.dwCount -= 3; + break; + + default: + hRet = DISP_E_TYPEMISMATCH; + break; + } + + if (SUCCEEDED(hRet)) + { + hRet = VARIANT_MakeDate(&dp, iDate, dwOffset, &st); + + if (dwFlags & VAR_TIMEVALUEONLY) + { + st.wYear = 1899; + st.wMonth = 12; + st.wDay = 30; + } + else if (dwFlags & VAR_DATEVALUEONLY) + st.wHour = st.wMinute = st.wSecond = 0; + + /* Finally, convert the value to a VT_DATE */ + if (SUCCEEDED(hRet)) + hRet = SystemTimeToVariantTime(&st, pdateOut) ? S_OK : DISP_E_TYPEMISMATCH; + } + } + + for (i = 0; i < sizeof(tokens)/sizeof(tokens[0]); i++) + SysFreeString(tokens[i]); + return hRet; +} + +/****************************************************************************** + * VarDateFromI1 (OLEAUT32.221) + * + * Convert a VT_I1 to a VT_DATE. + * + * PARAMS + * cIn [I] Source + * pdateOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarDateFromI1(signed char cIn, DATE* pdateOut) +{ + return _VarDateFromI1(cIn, pdateOut); +} + +/****************************************************************************** + * VarDateFromUI2 (OLEAUT32.222) + * + * Convert a VT_UI2 to a VT_DATE. + * + * PARAMS + * uiIn [I] Source + * pdateOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarDateFromUI2(USHORT uiIn, DATE* pdateOut) +{ + return _VarDateFromUI2(uiIn, pdateOut); +} + +/****************************************************************************** + * VarDateFromUI4 (OLEAUT32.223) + * + * Convert a VT_UI4 to a VT_DATE. + * + * PARAMS + * ulIn [I] Source + * pdateOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarDateFromUI4(ULONG ulIn, DATE* pdateOut) +{ + return _VarDateFromUI4(ulIn, pdateOut); +} + +/********************************************************************** + * VarDateFromDec (OLEAUT32.224) + * + * Convert a VT_DECIMAL to a VT_DATE. + * + * PARAMS + * pdecIn [I] Source + * pdateOut [O] Destination + * + * RETURNS + * S_OK. + */ +HRESULT WINAPI VarDateFromDec(DECIMAL *pdecIn, DATE* pdateOut) +{ + return _VarDateFromDec(pdecIn, pdateOut); +} + +/****************************************************************************** + * VarDateFromI8 (OLEAUT32.364) + * + * Convert a VT_I8 to a VT_DATE. + * + * PARAMS + * llIn [I] Source + * pdateOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarDateFromI8(LONG64 llIn, DATE* pdateOut) +{ + return _VarDateFromI8(llIn, pdateOut); +} + +/****************************************************************************** + * VarDateFromUI8 (OLEAUT32.365) + * + * Convert a VT_UI8 to a VT_DATE. + * + * PARAMS + * ullIn [I] Source + * pdateOut [O] Destination + * + * RETURNS + * Success: S_OK. + * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination + */ +HRESULT WINAPI VarDateFromUI8(ULONG64 ullIn, DATE* pdateOut) +{ + return _VarDateFromUI8(ullIn, pdateOut); +} diff --git a/reactos/lib/oleaut32/version.rc b/reactos/lib/oleaut32/version.rc new file mode 100644 index 00000000000..7b26ef7a6f4 --- /dev/null +++ b/reactos/lib/oleaut32/version.rc @@ -0,0 +1,23 @@ +/* + * Copyright 2001 Dmitry Timoshkov + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define WINE_OLESELFREGISTER +#define WINE_FILEDESCRIPTION_STR "Wine OLE dll" +#define WINE_FILENAME_STR "oleaut32.dll" + +#include "wine/wine_common_ver.rc"