#define strcmpiW(s1,s2) _wcsicmp((const wchar_t *)(s1),(const wchar_t *)(s2))
#define strncmpiW(s1,s2,n) _wcsnicmp((const wchar_t *)(s1),(const wchar_t *)(s2),(n))
#define strtoulW(s1,s2,b) wcstoul((const wchar_t *)(s1),(wchar_t **)(s2),(b))
+#define strspnW(str, accept) wcsspn((const wchar_t *)(str), (const wchar_t *)(accept))
#define tolowerW(n) towlower((n))
#define toupperW(n) towupper((n))
#define islowerW(n) iswlower((n))
IUnknown *Obj;
/* Reference count */
- DWORD ref;
+ LONG ref;
/* IID of sink interface */
IID iid;
const IEnumConnectionsVtbl *lpvtbl;
- DWORD ref;
+ LONG ref;
/* IUnknown of ConnectionPoint, used for ref counting */
IUnknown *pUnk;
const IDispatchVtbl *lpVtbl;
void * pvThis;
ITypeInfo * pTypeInfo;
- ULONG ref;
+ LONG ref;
} StdDispatch;
/******************************************************************************
/* The OLE Automation ProxyStub Interface Class (aka Typelib Marshaler) */
extern const GUID CLSID_PSOAInterface;
-/* IDispatch marshaler */
extern const GUID CLSID_PSDispatch;
+extern const GUID CLSID_PSEnumVariant;
+extern const GUID CLSID_PSTypeInfo;
+extern const GUID CLSID_PSTypeLib;
+extern const GUID CLSID_PSTypeComp;
static BOOL BSTR_bCache = TRUE; /* Cache allocations to minimise alloc calls? */
/***********************************************************************
* RegisterActiveObject (OLEAUT32.33)
+ *
+ * Registers an object in the global item table.
+ *
+ * PARAMS
+ * punk [I] Object to register.
+ * rcid [I] CLSID of the object.
+ * dwFlags [I] Flags.
+ * pdwRegister [O] Address to store cookie of object registration in.
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: HRESULT code.
*/
HRESULT WINAPI RegisterActiveObject(
LPUNKNOWN punk,REFCLSID rcid,DWORD dwFlags,LPDWORD pdwRegister
/***********************************************************************
* RevokeActiveObject (OLEAUT32.34)
+ *
+ * Revokes an object from the global item table.
+ *
+ * PARAMS
+ * xregister [I] Registration cookie.
+ * reserved [I] Reserved. Set to NULL.
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: HRESULT code.
*/
HRESULT WINAPI RevokeActiveObject(DWORD xregister,LPVOID reserved)
{
/***********************************************************************
* GetActiveObject (OLEAUT32.35)
+ *
+ * Gets an object from the global item table.
+ *
+ * PARAMS
+ * rcid [I] CLSID of the object.
+ * preserved [I] Reserved. Set to NULL.
+ * ppunk [O] Address to store object into.
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: HRESULT code.
*/
HRESULT WINAPI GetActiveObject(REFCLSID rcid,LPVOID preserved,LPUNKNOWN *ppunk)
{
/***********************************************************************
* DllGetClassObject (OLEAUT32.1)
*/
-HRESULT WINAPI OLEAUT32_DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
+HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
{
*ppv = NULL;
if (IsEqualGUID(rclsid,&CLSID_StdFont)) {
return S_OK;
}
}
- if (IsEqualGUID(rclsid,&CLSID_PSDispatch)) {
- return OLEAUTPS_DllGetClassObject(rclsid,iid,ppv);
+ if (IsEqualCLSID(rclsid, &CLSID_PSDispatch) ||
+ IsEqualCLSID(rclsid, &CLSID_PSTypeInfo) ||
+ IsEqualCLSID(rclsid, &CLSID_PSTypeLib) ||
+ IsEqualCLSID(rclsid, &CLSID_PSEnumVariant)) {
+ return OLEAUTPS_DllGetClassObject(&CLSID_PSDispatch, iid, ppv);
}
if (IsEqualGUID(rclsid,&CLSID_PSOAInterface)) {
if (S_OK==TypeLibFac_DllGetClassObject(rclsid,iid,ppv))
* RETURNS
* Always returns S_FALSE. This dll cannot be unloaded.
*/
-HRESULT WINAPI OLEAUT32_DllCanUnloadNow(void)
+HRESULT WINAPI DllCanUnloadNow(void)
{
return S_FALSE;
}
-1 stdcall -private DllGetClassObject(ptr ptr ptr) OLEAUT32_DllGetClassObject\r
+1 stdcall -private DllGetClassObject(ptr ptr ptr)\r
2 stdcall SysAllocString(wstr)\r
3 stdcall SysReAllocString(ptr wstr)\r
4 stdcall SysAllocStringLen(wstr long)\r
317 stdcall VarR8Round(double long ptr)\r
318 stdcall VarCat(ptr ptr ptr)\r
319 stdcall VarDateFromUdateEx(ptr long long ptr)\r
-320 stdcall -private DllRegisterServer() OLEAUT32_DllRegisterServer\r
-321 stdcall -private DllUnregisterServer() OLEAUT32_DllUnregisterServer\r
+320 stdcall -private DllRegisterServer()\r
+321 stdcall -private DllUnregisterServer()\r
322 stdcall GetRecordInfoFromGuids(ptr long long long ptr ptr)\r
323 stdcall GetRecordInfoFromTypeInfo(ptr ptr)\r
325 stub SetVarConversionLocaleSetting\r
399 stub UserMSG_free_local\r
401 stdcall OleLoadPictureEx(ptr long long long long long long ptr)\r
402 stub OleLoadPictureFileEx\r
-410 stdcall -private DllCanUnloadNow() OLEAUT32_DllCanUnloadNow\r
+410 stdcall -private DllCanUnloadNow()\r
411 stdcall SafeArrayCreateVector(long long long)\r
412 stdcall SafeArrayCopyData(ptr ptr)\r
413 stdcall VectorFromBstr(ptr ptr)\r
/*
* Reference count for that instance of the class.
*/
- ULONG ref;
+ LONG ref;
/*
* This structure contains the description of the class.
{
/* IUnknown fields */
const IClassFactoryVtbl *lpVtbl;
- DWORD ref;
+ LONG ref;
} IClassFactoryImpl;
static HRESULT WINAPI
#include "wine/unicode.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*/
WINE_DEFAULT_DEBUG_CHANNEL(ole);
+#include "pshpack1.h"
+
+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 "poppack.h"
+
/*************************************************************************
* Declaration of implementation class
*/
const IConnectionPointContainerVtbl *lpvtbl4;
/* Object reference count */
- DWORD ref;
+ LONG ref;
/* We own the object and must destroy it ourselves */
BOOL fOwn;
);
/* */
padding = (gif->SWidth+3) & ~3;
- bmi = HeapAlloc(GetProcessHeap(),0,sizeof(BITMAPINFOHEADER)+(1<<gif->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;
+ bmi = HeapAlloc(GetProcessHeap(),0,sizeof(BITMAPINFOHEADER)+(cm->ColorCount)*sizeof(RGBQUAD));
+ bytes= HeapAlloc(GetProcessHeap(),0,padding*gif->SHeight);
/* look for the transparent color extension */
for (i = 0; i < si->ExtensionBlockCount; ++i) {
}
}
- for (i=0;i<(1<<gif->SColorResolution);i++) {
+ for (i = 0; i < cm->ColorCount; 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;
bmi->bmiHeader.biSizeImage = padding*gif->SHeight;
bmi->bmiHeader.biXPelsPerMeter = 0;
bmi->bmiHeader.biYPelsPerMeter = 0;
- bmi->bmiHeader.biClrUsed = 1 << gif->SColorResolution;
+ bmi->bmiHeader.biClrUsed = cm->ColorCount;
bmi->bmiHeader.biClrImportant = 0;
hdcref = GetDC(0);
{
/* IUnknown fields */
const IClassFactoryVtbl *lpVtbl;
- DWORD ref;
+ LONG ref;
} IClassFactoryImpl;
static HRESULT WINAPI
typedef struct {
const IRecordInfoVtbl *lpVtbl;
- ULONG ref;
+ LONG ref;
GUID guid;
UINT lib_index;
extern GUID const CLSID_PSDispatch;
-static GUID const CLSID_PSEnumVariant = {
+GUID const CLSID_PSEnumVariant = {
0x00020421, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} };
-static GUID const CLSID_PSTypeInfo = {
+GUID const CLSID_PSTypeInfo = {
0x00020422, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} };
-static GUID const CLSID_PSTypeLib = {
+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 = {
+GUID const CLSID_PSTypeComp = {
0x00020425, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} };
+extern GUID const CLSID_PSOAInterface;
+
static GUID const CLSID_OldFont = {
0x46763EE0, 0xCAB2, 0x11CE, {0x8C,0x20,0x00,0xAA,0x00,0x51,0xE5,0xD4} };
/***********************************************************************
* DllRegisterServer (OLEAUT32.320)
*/
-HRESULT WINAPI OLEAUT32_DllRegisterServer()
+HRESULT WINAPI DllRegisterServer(void)
{
HRESULT hr;
/***********************************************************************
* DllUnregisterServer (OLEAUT32.321)
*/
-HRESULT WINAPI OLEAUT32_DllUnregisterServer()
+HRESULT WINAPI DllUnregisterServer(void)
{
HRESULT hr;
char tlguid[200],typelibkey[300],interfacekey[300],ver[100];
char tlfn[260];
OLECHAR tlfnW[260];
- DWORD tlguidlen, verlen, type, tlfnlen;
+ DWORD tlguidlen, verlen, type;
+ LONG tlfnlen;
ITypeLib *tl;
sprintf( interfacekey, "Interface\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\Typelib",
}
type = (1<<REG_SZ);
tlguidlen = sizeof(tlguid);
- if (RegQueryValueExA(ikey,NULL,NULL,&type,tlguid,&tlguidlen)) {
+ if (RegQueryValueExA(ikey,NULL,NULL,&type,(LPBYTE)tlguid,&tlguidlen)) {
ERR("Getting typelib guid failed.\n");
RegCloseKey(ikey);
return E_FAIL;
}
type = (1<<REG_SZ);
verlen = sizeof(ver);
- if (RegQueryValueExA(ikey,"Version",NULL,&type,ver,&verlen)) {
+ if (RegQueryValueExA(ikey,"Version",NULL,&type,(LPBYTE)ver,&verlen)) {
ERR("Could not get version value?\n");
RegCloseKey(ikey);
return E_FAIL;
typedef struct _TMProxyImpl {
LPVOID *lpvtbl;
const IRpcProxyBufferVtbl *lpvtbl2;
- ULONG ref;
+ LONG ref;
TMAsmProxy *asmstubs;
ITypeInfo* tinfo;
if (writeit) {
/* ptr to ptr to magic widestring, basically */
BSTR *bstr = (BSTR *) *arg;
+ DWORD len;
if (!*bstr) {
/* -1 means "null string" which is equivalent to empty string */
- DWORD fakelen = -1;
- xbuf_add(buf, (LPBYTE)&fakelen,4);
+ len = -1;
+ hres = xbuf_add(buf, (LPBYTE)&len,sizeof(DWORD));
+ if (hres) return hres;
} else {
- /* BSTRs store the length behind the first character */
- DWORD *len = ((DWORD *)(*bstr))-1;
- hres = xbuf_add(buf, (LPBYTE) len, *len + 4);
- if (hres) return hres;
+ len = *((DWORD*)*bstr-1)/sizeof(WCHAR);
+ hres = xbuf_add(buf,(LPBYTE)&len,sizeof(DWORD));
+ if (hres) return hres;
+ hres = xbuf_add(buf,(LPBYTE)*bstr,len * sizeof(WCHAR));
+ if (hres) return hres;
}
}
TRACE_(olerelay)("<bstr NULL>");
}
if (writeit) {
- if (!*arg) {
- DWORD fakelen = -1;
- hres = xbuf_add(buf,(LPBYTE)&fakelen,4);
- if (hres)
- return hres;
+ BSTR bstr = (BSTR)*arg;
+ DWORD len;
+ if (!bstr) {
+ len = -1;
+ hres = xbuf_add(buf,(LPBYTE)&len,sizeof(DWORD));
+ if (hres) return hres;
} else {
- DWORD *bstr = ((DWORD*)(*arg))-1;
-
- hres = xbuf_add(buf,(LPBYTE)bstr,bstr[0]+4);
- if (hres)
- return hres;
+ len = *((DWORD*)bstr-1)/sizeof(WCHAR);
+ hres = xbuf_add(buf,(LPBYTE)&len,sizeof(DWORD));
+ if (hres) return hres;
+ hres = xbuf_add(buf,(LPBYTE)bstr,len * sizeof(WCHAR));
+ if (hres) return hres;
}
}
if (debugout) TRACE_(olerelay)("}");
break;
}
+ case TKIND_ALIAS:
+ return serialize_param(tinfo2,writeit,debugout,dealloc,&tattr->tdescAlias,arg,buf);
+ case TKIND_ENUM:
+ hres = S_OK;
+ if (debugout) TRACE_(olerelay)("%lx",*arg);
+ if (writeit)
+ hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD));
+ return hres;
default:
FIXME("Unhandled typekind %d\n",tattr->typekind);
hres = E_FAIL;
**bstr = NULL;
if (debugout) TRACE_(olerelay)("<bstr NULL>");
} else {
- str = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,len+sizeof(WCHAR));
- hres = xbuf_get(buf,(LPBYTE)str,len);
+ str = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(len+1)*sizeof(WCHAR));
+ hres = xbuf_get(buf,(LPBYTE)str,len*sizeof(WCHAR));
if (hres) {
ERR("Failed to read BSTR.\n");
return hres;
*arg = 0;
if (debugout) TRACE_(olerelay)("<bstr NULL>");
} else {
- str = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,len+sizeof(WCHAR));
- hres = xbuf_get(buf,(LPBYTE)str,len);
+ str = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(len+1)*sizeof(WCHAR));
+ hres = xbuf_get(buf,(LPBYTE)str,len*sizeof(WCHAR));
if (hres) {
ERR("Failed to read BSTR.\n");
return hres;
if (debugout) TRACE_(olerelay)("}");
break;
}
+ case TKIND_ALIAS:
+ return deserialize_param(tinfo2,readit,debugout,alloc,&tattr->tdescAlias,arg,buf);
+ case TKIND_ENUM:
+ if (readit) {
+ hres = xbuf_get(buf,(LPBYTE)arg,sizeof(DWORD));
+ if (hres) ERR("Failed to read enum (4 byte)\n");
+ }
+ if (debugout) TRACE_(olerelay)("%lx",*arg);
+ return hres;
default:
ERR("Unhandled typekind %d\n",tattr->typekind);
hres = E_FAIL;
typedef struct _TMStubImpl {
const IRpcStubBufferVtbl *lpvtbl;
- ULONG ref;
+ LONG ref;
LPUNKNOWN pUnk;
ITypeInfo *tinfo;
if (!refCount)
{
IRpcStubBuffer_Disconnect(iface);
+ ITypeInfo_Release(This->tinfo);
CoTaskMemFree(This);
}
return refCount;
TRACE("(%p)->()\n", This);
- IUnknown_Release(This->pUnk);
- This->pUnk = NULL;
- return;
+ if (This->pUnk)
+ {
+ IUnknown_Release(This->pUnk);
+ This->pUnk = NULL;
+ }
}
static HRESULT WINAPI
/* The OLE Automation ProxyStub Interface Class (aka Typelib Marshaler) */
const GUID CLSID_PSOAInterface = { 0x00020424, 0, 0, { 0xC0, 0, 0, 0, 0, 0, 0, 0x46 } };
+static HRESULT typedescvt_to_variantvt(ITypeInfo *tinfo, TYPEDESC *tdesc, VARTYPE *vt);
+
/****************************************************************************
* FromLExxx
*
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|TYPEFLAG_FDUAL))
{
- 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,
{
const ITypeLib2Vtbl *lpVtbl;
const ITypeCompVtbl *lpVtblTypeComp;
- ULONG ref;
+ LONG ref;
TLIBATTR LibAttr; /* guid,lcid,syskind,version,flags */
/* strings can be stored in tlb as multibyte strings BUT they are *always*
{
const ITypeInfo2Vtbl *lpVtbl;
const ITypeCompVtbl *lpVtblTypeComp;
- ULONG ref;
+ LONG ref;
TYPEATTR TypeAttr ; /* _lots_ of type information. */
ITypeLibImpl * pTypeLib; /* back pointer to typelib */
int index; /* index in this typelib; */
}
}
-void dump_ELEMDESC(ELEMDESC *edesc) {
+static 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) {
+static void dump_FUNCDESC(FUNCDESC *funcdesc) {
int i;
MESSAGE("memid is %08lx\n",funcdesc->memid);
for (i=0;i<funcdesc->cParams;i++) {
dump_ELEMDESC(&funcdesc->elemdescFunc);
}
-void dump_IDLDESC(IDLDESC *idl) {
- MESSAGE("\t\twIdlflags: %d\n",idl->wIDLFlags);
-}
-
static const char * typekind_desc[] =
{
"TKIND_ENUM",
"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;
dump_TLBImplType(pty->impltypelist);
}
-void dump_VARDESC(VARDESC *v)
+static void dump_VARDESC(VARDESC *v)
{
MESSAGE("memid %ld\n",v->memid);
MESSAGE("lpstrSchema %s\n",debugstr_w(v->lpstrSchema));
* Functions for reading MSFT typelibs (those created by CreateTypeLib2)
*/
/* read function */
-DWORD MSFT_Read(void *buffer, DWORD count, TLBContext *pcx, long where )
+static 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);
TRACE_(typelib)("%s\n", debugstr_guid(pGuid));
}
-BSTR MSFT_ReadName( TLBContext *pcx, int offset)
+static BSTR MSFT_ReadName( TLBContext *pcx, int offset)
{
char * name;
MSFT_NameIntro niName;
return bstrName;
}
-BSTR MSFT_ReadString( TLBContext *pcx, int offset)
+static BSTR MSFT_ReadString( TLBContext *pcx, int offset)
{
char * string;
INT16 length;
if(pImpLib){
(*ppRefType)->reference=offset;
(*ppRefType)->pImpTLInfo = pImpLib;
- MSFT_ReadGuid(&(*ppRefType)->guid, impinfo.oGuid, pcx);
- (*ppRefType)->index = TLB_REF_USE_GUID;
+ if(impinfo.flags & MSFT_IMPINFO_OFFSET_IS_GUID) {
+ MSFT_ReadGuid(&(*ppRefType)->guid, impinfo.oGuid, pcx);
+ (*ppRefType)->index = TLB_REF_USE_GUID;
+ } else
+ (*ppRefType)->index = impinfo.oGuid;
}else{
ERR("Cannot find a reference\n");
(*ppRefType)->reference=-1;
/*
* process a typeinfo record
*/
-ITypeInfoImpl * MSFT_DoTypeInfo(
+static ITypeInfoImpl * MSFT_DoTypeInfo(
TLBContext *pcx,
int count,
ITypeLibImpl * pLibInfo)
memcpy(argpos, &V_I4(arg), 4);
hres = S_OK;
break;
+ case VT_BYREF|VT_I4:
+ memcpy(argpos, V_I4REF(arg), 4);
+ hres = S_OK;
+ break;
default:
FIXME("vt 0x%x -> TKIND_ENUM unhandled.\n",V_VT(arg));
hres = E_FAIL;
return E_FAIL;
}
+static HRESULT userdefined_to_variantvt(ITypeInfo *tinfo, TYPEDESC *tdesc, VARTYPE *vt)
+{
+ HRESULT hr = S_OK;
+ ITypeInfo *tinfo2 = NULL;
+ TYPEATTR *tattr = NULL;
+
+ hr = ITypeInfo_GetRefTypeInfo(tinfo, tdesc->u.hreftype, &tinfo2);
+ if (hr)
+ {
+ ERR("Could not get typeinfo of hreftype %lx for VT_USERDEFINED, "
+ "hr = 0x%08lx\n",
+ tdesc->u.hreftype, hr);
+ return hr;
+ }
+ hr = ITypeInfo_GetTypeAttr(tinfo2, &tattr);
+ if (hr)
+ {
+ ERR("ITypeInfo_GetTypeAttr failed, hr = 0x%08lx\n", hr);
+ ITypeInfo_Release(tinfo2);
+ return hr;
+ }
+
+ switch (tattr->typekind)
+ {
+ case TKIND_ENUM:
+ *vt |= VT_INT;
+ break;
+
+ case TKIND_ALIAS:
+ tdesc = &tattr->tdescAlias;
+ hr = typedescvt_to_variantvt(tinfo2, &tattr->tdescAlias, vt);
+ break;
+
+ case TKIND_INTERFACE:
+ if (IsEqualIID(&IID_IDispatch, &tattr->guid))
+ *vt |= VT_DISPATCH;
+ else
+ *vt |= VT_UNKNOWN;
+ break;
+
+ case TKIND_DISPATCH:
+ *vt |= VT_DISPATCH;
+ break;
+
+ case TKIND_RECORD:
+ FIXME("TKIND_RECORD unhandled.\n");
+ hr = E_NOTIMPL;
+ break;
+
+ case TKIND_UNION:
+ FIXME("TKIND_RECORD unhandled.\n");
+ hr = E_NOTIMPL;
+ break;
+
+ default:
+ FIXME("TKIND %d unhandled.\n",tattr->typekind);
+ hr = E_NOTIMPL;
+ break;
+ }
+ ITypeInfo_ReleaseTypeAttr(tinfo2, tattr);
+ ITypeInfo_Release(tinfo2);
+ return hr;
+}
+
+static HRESULT typedescvt_to_variantvt(ITypeInfo *tinfo, TYPEDESC *tdesc, VARTYPE *vt)
+{
+ HRESULT hr = S_OK;
+
+ /* enforce only one level of pointer indirection */
+ if (!(*vt & VT_BYREF) && (tdesc->vt == VT_PTR))
+ {
+ tdesc = tdesc->u.lptdesc;
+
+ /* munch VT_PTR -> VT_USERDEFINED(interface) into VT_UNKNOWN or
+ * VT_DISPATCH and VT_PTR -> VT_PTR -> VT_USERDEFINED(interface) into
+ * VT_BYREF|VT_DISPATCH or VT_BYREF|VT_UNKNOWN */
+ if ((tdesc->vt == VT_USERDEFINED) ||
+ ((tdesc->vt == VT_PTR) && (tdesc->u.lptdesc->vt == VT_USERDEFINED)))
+ {
+ VARTYPE vt_userdefined = 0;
+ TYPEDESC *tdesc_userdefined = tdesc;
+ if (tdesc->vt == VT_PTR)
+ {
+ vt_userdefined = VT_BYREF;
+ tdesc_userdefined = tdesc->u.lptdesc;
+ }
+ hr = userdefined_to_variantvt(tinfo, tdesc_userdefined, &vt_userdefined);
+ if ((hr == S_OK) &&
+ (((vt_userdefined & VT_TYPEMASK) == VT_UNKNOWN) ||
+ ((vt_userdefined & VT_TYPEMASK) == VT_DISPATCH)))
+ {
+ *vt |= vt_userdefined;
+ return S_OK;
+ }
+ }
+ *vt = VT_BYREF;
+ }
+
+ switch (tdesc->vt)
+ {
+ case VT_HRESULT:
+ *vt |= VT_ERROR;
+ break;
+ case VT_USERDEFINED:
+ hr = userdefined_to_variantvt(tinfo, tdesc, vt);
+ break;
+ case VT_PTR:
+ ERR("cannot convert VT_PTR into variant VT\n");
+ hr = E_FAIL;
+ break;
+ default:
+ *vt |= tdesc->vt;
+ break;
+ }
+ return hr;
+}
+
/***********************************************************************
* DispCallFunc (OLEAUT32.@)
*/
hres = ITypeInfo2_GetFuncDesc(iface, func_index, &func_desc);
if(FAILED(hres)) return hres;
+ if (TRACE_ON(ole))
+ {
+ TRACE("invoking:\n");
+ dump_FUNCDESC(func_desc);
+ }
switch (func_desc->funckind) {
case FUNC_PUREVIRTUAL:
args
);
- if (pVarResult && (dwFlags & (DISPATCH_PROPERTYGET))) {
- args2pos = 0;
- for (i = 0; i < func_desc->cParams - pDispParams->cArgs; i++) {
- ELEMDESC *elemdesc = &(func_desc->lprgelemdescParam[i+pDispParams->cArgs]);
- TYPEDESC *tdesc = &(elemdesc->tdesc);
- int arglen = _argsize(tdesc->vt);
- 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;
-
- if (tdesc->vt == VT_PTR) {
- tdesc = tdesc->u.lptdesc;
- arglen = _argsize(tdesc->vt);
- }
-
- VariantInit(pVarResult);
- memcpy(&V_INT(pVarResult),&args2[args2pos],arglen*sizeof(DWORD));
-
- if (tdesc->vt == VT_USERDEFINED) {
- ITypeInfo *tinfo2;
- TYPEATTR *tattr;
-
- hres = ITypeInfo_GetRefTypeInfo(iface,tdesc->u.hreftype,&tinfo2);
- if (FAILED(hres)) {
- FIXME("Could not get typeinfo of hreftype %lx for VT_USERDEFINED, while coercing. Copying 4 byte.\n",tdesc->u.hreftype);
- goto func_fail;
- }
- ITypeInfo_GetTypeAttr(tinfo2,&tattr);
- switch (tattr->typekind) {
- case TKIND_ENUM:
- /* force the return type to be VT_I4 */
- tdesc = &i4_tdesc;
+ if (pVarResult) {
+ for (i = 0; i < func_desc->cParams; i++) {
+ USHORT wParamFlags = func_desc->lprgelemdescParam[i].u.paramdesc.wParamFlags;
+ if (wParamFlags & PARAMFLAG_FRETVAL) {
+ ELEMDESC *elemdesc = &func_desc->lprgelemdescParam[i];
+ TYPEDESC *tdesc = &elemdesc->tdesc;
+ VARIANTARG varresult;
+ V_VT(&varresult) = 0;
+ hres = typedescvt_to_variantvt((ITypeInfo *)iface, tdesc, &V_VT(&varresult));
+ if (hres)
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);
+ /* FIXME: this is really messy - we should keep the
+ * args in VARIANTARGs rather than a DWORD array */
+ memcpy(&V_UI4(&varresult), &args[i+1], sizeof(DWORD));
+ if (TRACE_ON(ole))
+ {
+ TRACE("varresult: ");
+ dump_Variant(&varresult);
+ }
+ hres = VariantCopyInd(pVarResult, &varresult);
+ break;
}
- 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;
}
}
+
+ if ((func_desc->elemdescFunc.tdesc.vt == VT_HRESULT) && FAILED(res)) {
+ WARN("invoked function failed with error 0x%08lx\n", res);
+ hres = DISP_E_EXCEPTION;
+ if (pExcepInfo) pExcepInfo->scode = res;
+ }
func_fail:
HeapFree(GetProcessHeap(), 0, rgvarg);
HeapFree(GetProcessHeap(),0,args2);
/* else it is zero? */
INT res18; /* always? 0 */
/*060*/ INT res19; /* always? -1 */
- } MSFT_TypeInfoBase;
+} MSFT_TypeInfoBase;
/* layout of an entry with information on imported types */
typedef struct tagMSFT_ImpInfo {
- INT res0; /* bits 0 - 15: count */
+ INT flags; /* bits 0 - 15: count */
/* bit 16: if set oGuid is an offset to Guid */
/* if clear oGuid is a typeinfo index in the specified typelib */
/* bits 24 - 31: TKIND of reference */
INT oImpFile; /* offset in the Import File table */
INT oGuid; /* offset in Guid table or typeinfo index (see bit 16 of res0) */
- } MSFT_ImpInfo;
+} MSFT_ImpInfo;
+
+#define MSFT_IMPINFO_OFFSET_IS_GUID 0x00010000
/* function description data */
typedef struct {
{
char xguid[80];
char typelibkey[100],pathname[260];
- DWORD plen;
+ LONG plen;
TRACE("\n");
const ICreateTypeLib2Vtbl *lpVtbl;
const ITypeLib2Vtbl *lpVtblTypeLib2;
- ULONG ref;
+ LONG ref;
WCHAR *filename;
const ICreateTypeInfo2Vtbl *lpVtbl;
const ITypeInfo2Vtbl *lpVtblTypeInfo2;
- ULONG ref;
+ LONG ref;
ICreateTypeLib2Impl *typelib;
MSFT_TypeInfoBase *typeinfo;
guidoffset = ctl2_alloc_guid(This->typelib, &foo);
if (guidoffset == -1) return E_OUTOFMEMORY;
- impinfo.res0 = 0x03010000;
+ impinfo.flags = TKIND_INTERFACE << 24 | MSFT_IMPINFO_OFFSET_IS_GUID;
impinfo.oImpFile = fileoffset;
impinfo.oGuid = guidoffset;
ctl2_alloc_importinfo(This->typelib, &impinfo);
{
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),
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);
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_UI1: V_I1(pd) = V_UI1(ps); return S_OK;
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_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_UI2: V_I2(pd) = V_UI2(ps); return S_OK;
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_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_UI4: V_I4(pd) = V_UI4(ps); return S_OK;
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));
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_I1: V_UI1(pd) = V_I1(ps); return S_OK;
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_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_I2: V_UI2(pd) = V_I2(ps); return S_OK;
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_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_I4: V_UI4(pd) = V_I4(ps); return S_OK;
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_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_I8: V_UI8(pd) = V_I8(ps); return S_OK;
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_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_UI8: V_I8(pd) = V_UI8(ps); return S_OK;
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));
/**********************************************************************
* VarCat [OLEAUT32.318]
+ *
+ * Concatenates one variant onto another.
+ *
+ * PARAMS
+ * left [I] First variant
+ * right [I] Second variant
+ * result [O] Result variant
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: An HRESULT error code indicating the error.
*/
HRESULT WINAPI VarCat(LPVARIANT left, LPVARIANT right, LPVARIANT out)
{
/**********************************************************************
* VarAnd [OLEAUT32.142]
*
+ * Computes the logical AND of two variants.
+ *
+ * PARAMS
+ * left [I] First variant
+ * right [I] Second variant
+ * result [O] Result variant
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: An HRESULT error code indicating the error.
*/
HRESULT WINAPI VarAnd(LPVARIANT left, LPVARIANT right, LPVARIANT result)
{
/**********************************************************************
* VarDiv [OLEAUT32.143]
*
+ * Divides one variant with another.
+ *
+ * PARAMS
+ * left [I] First variant
+ * right [I] Second variant
+ * result [O] Result variant
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: An HRESULT error code indicating the error.
*/
HRESULT WINAPI VarDiv(LPVARIANT left, LPVARIANT right, LPVARIANT result)
{
/**********************************************************************
* VarSub [OLEAUT32.159]
*
+ * Subtract two variants.
+ *
+ * PARAMS
+ * left [I] First variant
+ * right [I] Second variant
+ * result [O] Result variant
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: An HRESULT error code indicating the error.
*/
HRESULT WINAPI VarSub(LPVARIANT left, LPVARIANT right, LPVARIANT result)
{
/**********************************************************************
* VarPow [OLEAUT32.158]
*
+ * Computes the power of one variant to another variant.
+ *
+ * PARAMS
+ * left [I] First variant
+ * right [I] Second variant
+ * result [O] Result variant
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: An HRESULT error code indicating the error.
*/
HRESULT WINAPI VarPow(LPVARIANT left, LPVARIANT right, LPVARIANT result)
{
return E_INVALIDARG;
sprintfW( buff, lpszFormat, dblIn );
+
+ /* Negative zeroes are disallowed (some applications depend on this).
+ If buff starts with a minus, and then nothing follows but zeroes
+ and/or a period, it is a negative zero and is replaced with a
+ canonical zero. This duplicates native oleaut32 behavior.
+ */
+ if (buff[0] == '-')
+ {
+ const WCHAR szAccept[] = {'0', '.', '\0'};
+ if (strlenW(buff + 1) == strspnW(buff + 1, szAccept))
+ { buff[0] = '0'; buff[1] = '\0'; }
+ }
+
TRACE("created string %s\n", debugstr_w(buff));
if (dwFlags & LOCALE_USE_NLS)
{