Begining implementation of IRecordInfo
Jacek Caban
jack at itma.pwr.wroc.pl
Thu Mar 3 12:06:57 CST 2005
Patch includes implementation of GetRecordInfoFromTypeInfo and
GetRecordInfoFromGuids and some functions of IRecordInfo
interface. I've wrote a test for this, but it needs a tlb file with
typedef struct {...}.
This test uses it's own tlb file, but it can be changed to use any other
file -
in Wine there is none that could be used. Is it ok to generate tlb file
in test (I think it may cause problems with cross-compiling)?
Changelog:
- Implemented GetRecordInfoFromTypeInfo and GetRecordInfoFromGuid
- Beginig implementation of IRecordInfo
-------------- next part --------------
Index: dlls/oleaut32/oleaut32.spec
===================================================================
RCS file: /home/wine/wine/dlls/oleaut32/oleaut32.spec,v
retrieving revision 1.71
diff -u -p -r1.71 oleaut32.spec
--- dlls/oleaut32/oleaut32.spec 21 Feb 2005 18:36:06 -0000 1.71
+++ dlls/oleaut32/oleaut32.spec 3 Mar 2005 17:48:04 -0000
@@ -315,7 +315,7 @@
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)
+323 stdcall GetRecordInfoFromTypeInfo(ptr ptr)
325 stub SetVarConversionLocaleSetting
326 stub GetVarConversionLocaleSetting
327 stdcall SetOaNoCache()
Index: dlls/oleaut32/oleaut.c
===================================================================
RCS file: /home/wine/wine/dlls/oleaut32/oleaut.c,v
retrieving revision 1.45
diff -u -p -r1.45 oleaut.c
--- dlls/oleaut32/oleaut.c 8 Feb 2005 12:56:50 -0000 1.45
+++ dlls/oleaut32/oleaut.c 3 Mar 2005 17:48:04 -0000
@@ -572,28 +572,6 @@ ULONG WINAPI OaBuildVersion()
}
/******************************************************************************
- * 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.
Index: dlls/oleaut32/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/oleaut32/Makefile.in,v
retrieving revision 1.57
diff -u -p -r1.57 Makefile.in
--- dlls/oleaut32/Makefile.in 27 Oct 2004 00:47:53 -0000 1.57
+++ dlls/oleaut32/Makefile.in 3 Mar 2005 17:48:04 -0000
@@ -16,6 +16,7 @@ C_SRCS = \
oleaut.c \
olefont.c \
olepicture.c \
+ recinfo.c \
regsvr.c \
safearray.c \
stubs.c \
--- /dev/null 1970-01-01 01:00:00.000000000 +0100
+++ dlls/oleaut32/recinfo.c 2005-03-03 18:44:55.447602192 +0100
@@ -0,0 +1,378 @@
+/*
+ * Copyright 2005 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
+ */
+
+#include <stdarg.h>
+
+#define COBJMACROS
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+
+#include "windef.h"
+#include "winbase.h"
+#include "objbase.h"
+#include "oaidl.h"
+#include "oleauto.h"
+
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(ole);
+
+typedef struct {
+ IRecordInfoVtbl *lpVtbl;
+ ULONG ref;
+
+ GUID guid;
+ TYPEATTR typeattr;
+ UINT lib_index;
+ BSTR name;
+ BSTR *field_names;
+ ITypeInfo *pTypeInfo;
+} IRecordInfoImpl;
+
+static HRESULT WINAPI IRecordInfoImpl_QueryInterface(IRecordInfo *iface, REFIID riid, void **ppvObject)
+{
+ TRACE("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppvObject);
+
+ if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IRecordInfo, riid)) {
+ *ppvObject = iface;
+ IRecordInfo_AddRef(iface);
+ return S_OK;
+ }
+
+ FIXME("Not supported interface: %s\n", debugstr_guid(riid));
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI IRecordInfoImpl_AddRef(IRecordInfo *iface)
+{
+ IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+ ULONG ref = InterlockedIncrement(&This->ref);
+ TRACE("(%p) -> %ld\n", This, ref);
+ return ref;
+}
+
+static ULONG WINAPI IRecordInfoImpl_Release(IRecordInfo *iface)
+{
+ IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+ ULONG ref = InterlockedDecrement(&This->ref);
+
+ TRACE("(%p) -> %ld\n", This, ref);
+ if(!ref) {
+ int i;
+ for(i=0; i<This->typeattr.cVars; i++)
+ HeapFree(GetProcessHeap(), 0, This->field_names[i]);
+ HeapFree(GetProcessHeap(), 0, This->name);
+ ITypeInfo_Release(This->pTypeInfo);
+ HeapFree(GetProcessHeap(), 0, This);
+ }
+ return ref;
+}
+
+static HRESULT WINAPI IRecordInfoImpl_RecordInit(IRecordInfo *iface, PVOID pvNew)
+{
+ IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+ FIXME("(%p)->(%p) stub\n", This, pvNew);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI IRecordInfoImpl_RecordClear(IRecordInfo *iface, PVOID pvExisting)
+{
+ IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+ FIXME("(%p)->(%p) stub\n", This, pvExisting);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI IRecordInfoImpl_RecordCopy(IRecordInfo *iface, PVOID pvExisting, PVOID pvNew)
+{
+ IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+ FIXME("(%p)->(%p %p) stub\n", This, pvExisting, pvNew);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI IRecordInfoImpl_GetGuid(IRecordInfo *iface, GUID *pguid)
+{
+ IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+ TRACE("(%p)->(%p)\n", This, pguid);
+
+ if(!pguid)
+ return E_INVALIDARG;
+
+ memcpy(pguid, &This->guid, sizeof(GUID));
+ return S_OK;
+}
+
+static HRESULT WINAPI IRecordInfoImpl_GetName(IRecordInfo *iface, BSTR *pbstrName)
+{
+ IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+
+ TRACE("(%p)->(%p)\n", This, pbstrName);
+ if(!pbstrName)
+ return E_INVALIDARG;
+
+ *pbstrName = SysAllocString(This->name);
+ return S_OK;
+}
+
+static HRESULT WINAPI IRecordInfoImpl_GetSize(IRecordInfo *iface, ULONG *pcbSize)
+{
+ IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+
+ TRACE("(%p)->(%p)\n", This, pcbSize);
+
+ if(!pcbSize)
+ return E_INVALIDARG;
+
+ *pcbSize = This->typeattr.cbSizeInstance;
+ return S_OK;
+}
+
+static HRESULT WINAPI IRecordInfoImpl_GetTypeInfo(IRecordInfo *iface, ITypeInfo **ppTypeInfo)
+{
+ IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+
+ TRACE("(%p)->(%p)\n", This, ppTypeInfo);
+
+ if(!ppTypeInfo)
+ return E_INVALIDARG;
+
+ ITypeInfo_AddRef(This->pTypeInfo);
+ *ppTypeInfo = This->pTypeInfo;
+
+ return S_OK;
+}
+
+static HRESULT WINAPI IRecordInfoImpl_GetField(IRecordInfo *iface, PVOID pvData,
+ LPCOLESTR szFieldName, VARIANT *pvarField)
+{
+ IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+ FIXME("(%p)->(%p %s %p) stub\n", This, pvData, debugstr_w(szFieldName), pvarField);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI IRecordInfoImpl_GetFieldNoCopy(IRecordInfo *iface, PVOID pvData, LPCOLESTR szFieldName,
+ VARIANT *pvarField, PVOID *ppvDataCArray)
+{
+ IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+ FIXME("(%p)->(%p %s %p %p) stub\n", This, pvData, debugstr_w(szFieldName), pvarField, ppvDataCArray);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI IRecordInfoImpl_PutField(IRecordInfo *iface, ULONG wFlags, PVOID pvData, LPCOLESTR szFieldName,
+ VARIANT *pvarField)
+{
+ IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+ FIXME("(%p)->(%08lx %p %s %p) stub\n", This, wFlags, pvData, debugstr_w(szFieldName), pvarField);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI IRecordInfoImpl_PutFieldNoCopy(IRecordInfo *iface, ULONG wFlags, PVOID pvData, LPCOLESTR szFieldName,
+ VARIANT *pvarField)
+{
+ IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+ FIXME("(%p)->(%08lx %p %s %p) stub\n", This, wFlags, pvData, debugstr_w(szFieldName), pvarField);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI IRecordInfoImpl_GetFieldNames(IRecordInfo *iface, ULONG *pcNames, BSTR *rgBstrNames)
+{
+ IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+ ULONG n = This->typeattr.cVars;
+ int i;
+ TRACE("(%p)->(%p %p)\n", This, pcNames, rgBstrNames);
+
+ if(!pcNames)
+ return E_INVALIDARG;
+
+ if(*pcNames < n)
+ n = *pcNames;
+
+ if(rgBstrNames) {
+ for(i=0; i<n; i++)
+ rgBstrNames[i] = SysAllocString(This->field_names[i]);
+ }
+
+ *pcNames = n;
+ return S_OK;
+}
+
+static BOOL WINAPI IRecordInfoImpl_IsMatchingType(IRecordInfo *iface, IRecordInfo *pRecordInfo)
+{
+ IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+ FIXME("(%p)->(%p) stub\n", This, pRecordInfo);
+ return FALSE;
+}
+
+static PVOID WINAPI IRecordInfoImpl_RecordCreate(IRecordInfo *iface)
+{
+ IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+ FIXME("(%p) stub\n", This);
+ return NULL;
+}
+
+static HRESULT WINAPI IRecordInfoImpl_RecordCreateCopy(IRecordInfo *iface, PVOID pvSource, PVOID *ppvDest)
+{
+ IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+ FIXME("(%p)->(%p %p) stub\n", This, pvSource, ppvDest);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI IRecordInfoImpl_RecordDestroy(IRecordInfo *iface, PVOID pvRecord)
+{
+ IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
+ FIXME("(%p)->(%p) stub\n", This, pvRecord);
+ return E_NOTIMPL;
+}
+
+static IRecordInfoVtbl IRecordInfoImplVtbl = {
+ IRecordInfoImpl_QueryInterface,
+ IRecordInfoImpl_AddRef,
+ IRecordInfoImpl_Release,
+ IRecordInfoImpl_RecordInit,
+ IRecordInfoImpl_RecordClear,
+ IRecordInfoImpl_RecordCopy,
+ IRecordInfoImpl_GetGuid,
+ IRecordInfoImpl_GetName,
+ IRecordInfoImpl_GetSize,
+ IRecordInfoImpl_GetTypeInfo,
+ IRecordInfoImpl_GetField,
+ IRecordInfoImpl_GetFieldNoCopy,
+ IRecordInfoImpl_PutField,
+ IRecordInfoImpl_PutFieldNoCopy,
+ IRecordInfoImpl_GetFieldNames,
+ IRecordInfoImpl_IsMatchingType,
+ IRecordInfoImpl_RecordCreate,
+ IRecordInfoImpl_RecordCreateCopy,
+ IRecordInfoImpl_RecordDestroy
+};
+
+/******************************************************************************
+ * GetRecordInfoFromGuids [OLEAUT32.322]
+ *
+ * RETURNS
+ * Success: S_OK
+ * Failure: E_INVALIDARG, if any argument is invalid.
+ */
+HRESULT WINAPI GetRecordInfoFromGuids(REFGUID rGuidTypeLib, ULONG uVerMajor,
+ ULONG uVerMinor, LCID lcid, REFGUID rGuidTypeInfo, IRecordInfo** ppRecInfo)
+{
+ ITypeInfo *pTypeInfo;
+ ITypeLib *pTypeLib;
+ HRESULT hres;
+
+ TRACE("(%p,%ld,%ld,%ld,%p,%p)\n", rGuidTypeLib, uVerMajor, uVerMinor,
+ lcid, rGuidTypeInfo, ppRecInfo);
+
+ hres = LoadRegTypeLib(rGuidTypeLib, uVerMajor, uVerMinor, lcid, &pTypeLib);
+ if(FAILED(hres)) {
+ WARN("LoadRegTypeLib failed!\n");
+ return hres;
+ }
+
+ hres = ITypeLib_GetTypeInfoOfGuid(pTypeLib, rGuidTypeInfo, &pTypeInfo);
+ ITypeLib_Release(pTypeLib);
+ if(FAILED(hres)) {
+ WARN("GetTypeInfoOfGuid failed!\n");
+ return hres;
+ }
+
+ hres = GetRecordInfoFromTypeInfo(pTypeInfo, ppRecInfo);
+ ITypeInfo_Release(pTypeInfo);
+ return hres;
+}
+
+/******************************************************************************
+ * GetRecordInfoFromTypeInfo [OLEAUT32.332]
+ */
+HRESULT WINAPI GetRecordInfoFromTypeInfo(ITypeInfo* pTI, IRecordInfo** ppRecInfo) {
+ HRESULT hres;
+ TYPEATTR *typeattr;
+ IRecordInfoImpl *ret;
+ ITypeInfo *pTypeInfo;
+ int i;
+ GUID guid;
+
+ TRACE("(%p %p)\n", pTI, ppRecInfo);
+
+ if(!pTI || !ppRecInfo)
+ return E_INVALIDARG;
+
+ hres = ITypeInfo_GetTypeAttr(pTI, &typeattr);
+ if(FAILED(hres) || !typeattr) {
+ WARN("GetTypeAttr failed: %08lx\n", hres);
+ return hres;
+ }
+
+ if(typeattr->typekind == TKIND_ALIAS) {
+ hres = ITypeInfo_GetRefTypeInfo(pTI, typeattr->tdescAlias.u.hreftype, &pTypeInfo);
+ memcpy(&guid, &typeattr->guid, sizeof(GUID));
+ ITypeInfo_ReleaseTypeAttr(pTI, typeattr);
+ if(FAILED(hres)) {
+ WARN("GetRefTypeInfo failed: %08lx\n", hres);
+ return hres;
+ }
+ ITypeInfo_GetTypeAttr(pTypeInfo, &typeattr);
+ }else {
+ pTypeInfo = pTI;
+ ITypeInfo_AddRef(pTypeInfo);
+ memcpy(&guid, &typeattr->guid, sizeof(GUID));
+ }
+
+ if(typeattr->typekind != TKIND_RECORD) {
+ WARN("typekind != TKIND_RECORD\n");
+ ITypeInfo_ReleaseTypeAttr(pTypeInfo, typeattr);
+ ITypeInfo_Release(pTypeInfo);
+ return E_INVALIDARG;
+ }
+
+ ret = HeapAlloc(GetProcessHeap(), 0, sizeof(*ret));
+ ret->lpVtbl = &IRecordInfoImplVtbl;
+ ret->ref = 1;
+ ret->pTypeInfo = pTypeInfo;
+ memcpy(&ret->guid, &guid, sizeof(GUID));
+ memcpy(&ret->typeattr, typeattr, sizeof(TYPEATTR));
+ ITypeInfo_ReleaseTypeAttr(pTypeInfo, typeattr);
+
+ /* NOTE: Windows implementation calls ITypeInfo::GetCantainingTypeLib and
+ * ITypeLib::GetLibAttr, but we currently don't need this.
+ */
+
+ hres = ITypeInfo_GetDocumentation(pTypeInfo, MEMBERID_NIL, &ret->name, NULL, NULL, NULL);
+ if(FAILED(hres)) {
+ WARN("ITypeInfo::GetDocumentation failed\n");
+ ret->name = NULL;
+ }
+
+ ret->field_names = HeapAlloc(GetProcessHeap(), 0, ret->typeattr.cVars*sizeof(BSTR));
+ for(i = 0; i<ret->typeattr.cVars; i++) {
+ VARDESC *vardesc;
+ hres = ITypeInfo_GetVarDesc(pTypeInfo, i, &vardesc);
+ if(FAILED(hres)) {
+ WARN("GetVarDesc failed\n");
+ continue;
+ }
+ hres = ITypeInfo_GetDocumentation(pTypeInfo, vardesc->memid, ret->field_names+i, NULL, NULL, NULL);
+ if(FAILED(hres))
+ WARN("GetDocumentation failed: %08lx\n", hres);
+ ITypeInfo_ReleaseVarDesc(pTypeInfo, vardesc);
+ }
+
+ *ppRecInfo = (IRecordInfo*)ret;
+
+ return S_OK;
+}
+
More information about the wine-patches
mailing list