mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
Sync to Wine-20050310:
Jacek Caban <jack@itma.pwr.wroc.pl> - Implemented GetRecordInfoFromTypeInfo and GetRecordInfoFromGuid. - Beginnig implementation of IRecordInfo. - More implementation of IRecordInfo. Maxime Bellenge <maxime.bellenge@laposte.net> - Implements OleLoadPicturePath. Jon Griffiths <jon_p_griffiths@yahoo.com> - Use variant macros instead of accessing the union directly. - Documentation spelling fixes. Alex Villacis Lasso <a_villacis@palosanto.com> - Implement OleFontImpl_QueryTextMetrics. - Change SUBLANG_DEFAULT to SUBLANG_NEUTRAL for LANG_SPANISH in all resources, so that Spanish locales other than Spain also use Spanish resources. Marcelo Duarte <wine-devel@bol.com.br> - Update the resources for Portuguese. Francois Gouget <fgouget@free.fr> - Assorted spelling fixes. Vincent Beron <vberon@mecano.gme.usherb.ca> - Add a stub for OleLoadPicturePath(). Huw Davies <huw@codeweavers.com> - The typelib cache should take the typelib resource index into account. Mike Hearn <mh@codeweavers.com> - Allow loading of builtin typelibs. Marcus Meissner <marcus@jet.franken.de> - Check for overflows with ClrUsed. svn path=/trunk/; revision=14085
This commit is contained in:
parent
9bc71c43a2
commit
f9279fd739
16 changed files with 923 additions and 191 deletions
|
@ -5,7 +5,7 @@ SRCDIR = @srcdir@
|
|||
VPATH = @srcdir@
|
||||
MODULE = oleaut32.dll
|
||||
IMPORTS = ole32 rpcrt4 user32 gdi32 advapi32 kernel32 ntdll
|
||||
DELAYIMPORTS = comctl32
|
||||
DELAYIMPORTS = comctl32 urlmon
|
||||
EXTRALIBS = $(LIBUNICODE) -luuid
|
||||
|
||||
C_SRCS = \
|
||||
|
@ -16,6 +16,7 @@ C_SRCS = \
|
|||
oleaut.c \
|
||||
olefont.c \
|
||||
olepicture.c \
|
||||
recinfo.c \
|
||||
regsvr.c \
|
||||
safearray.c \
|
||||
stubs.c \
|
||||
|
|
|
@ -6,7 +6,7 @@ TARGET_OBJECTS = @C_SRCS@
|
|||
|
||||
TARGET_CFLAGS = @EXTRADEFS@ -D__REACTOS__
|
||||
|
||||
TARGET_SDKLIBS = @IMPORTS@ winmm.a wine.a wine_uuid.a ntdll.a
|
||||
TARGET_SDKLIBS = @IMPORTS@ urlmon.a winmm.a wine.a wine_uuid.a ntdll.a
|
||||
|
||||
TARGET_BASE = $(TARGET_BASE_LIB_OLEAUT32)
|
||||
|
||||
|
|
|
@ -571,28 +571,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]
|
||||
*
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
|
||||
/*
|
||||
* FIXME:
|
||||
* Finnish, Greek, Hebrew, Japanese, Korean, Portuguese,
|
||||
* Finnish, Greek, Hebrew, Japanese, Korean,
|
||||
* Turkish, Slovenian (at least) are localised in XP Home.
|
||||
* I expect Chinese etc are localised in Asian Editions also.
|
||||
*/
|
||||
|
|
|
@ -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()
|
||||
|
@ -396,7 +396,7 @@
|
|||
421 stdcall OleTranslateColor(long long long)
|
||||
422 stub OleLoadPictureFile
|
||||
423 stub OleSavePictureFile
|
||||
424 stub OleLoadPicturePath
|
||||
424 stdcall OleLoadPicturePath(wstr ptr long long ptr ptr)
|
||||
425 stdcall VarUI4FromI8(long long ptr)
|
||||
426 stdcall VarUI4FromUI8(long long ptr)
|
||||
427 stdcall VarI8FromUI8(long long ptr)
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
LANGUAGE LANG_SPANISH, SUBLANG_DEFAULT
|
||||
LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
{
|
||||
|
|
|
@ -1068,8 +1068,16 @@ static HRESULT WINAPI OLEFontImpl_QueryTextMetrics(
|
|||
IFont* iface,
|
||||
TEXTMETRICOLE* ptm)
|
||||
{
|
||||
FIXME("(%p, %p), stub!\n",iface,ptm);
|
||||
return E_NOTIMPL;
|
||||
HDC hdcRef;
|
||||
HFONT hOldFont, hNewFont;
|
||||
|
||||
hdcRef = GetDC(0);
|
||||
OLEFontImpl_get_hFont(iface, &hNewFont);
|
||||
hOldFont = SelectObject(hdcRef, hNewFont);
|
||||
GetTextMetricsW(hdcRef, ptm);
|
||||
SelectObject(hdcRef, hOldFont);
|
||||
ReleaseDC(0, hdcRef);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
|
|
|
@ -71,7 +71,9 @@
|
|||
#include "olectl.h"
|
||||
#include "oleauto.h"
|
||||
#include "connpt.h"
|
||||
#include "urlmon.h"
|
||||
#include "wine/debug.h"
|
||||
#include "wine/unicode.h"
|
||||
|
||||
#include "wine/wingdi16.h"
|
||||
#include "cursoricon.h"
|
||||
|
@ -106,7 +108,7 @@ typedef struct OLEPictureImpl {
|
|||
IPersistStreamVtbl *lpvtbl3;
|
||||
IConnectionPointContainerVtbl *lpvtbl4;
|
||||
|
||||
/* Object referenece count */
|
||||
/* Object reference count */
|
||||
DWORD ref;
|
||||
|
||||
/* We own the object and must destroy it ourselves */
|
||||
|
@ -705,7 +707,7 @@ static HRESULT WINAPI OLEPictureImpl_get_Attributes(IPicture *iface,
|
|||
TRACE("(%p)->(%p).\n", This, pdwAttr);
|
||||
*pdwAttr = 0;
|
||||
switch (This->desc.picType) {
|
||||
case PICTYPE_BITMAP: break; /* not 'truely' scalable, see MSDN. */
|
||||
case PICTYPE_BITMAP: break; /* not 'truly' 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;
|
||||
|
@ -1514,9 +1516,15 @@ static int serializeBMP(HBITMAP hBitmap, void ** ppBuffer, unsigned int * pLengt
|
|||
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;
|
||||
if (pInfoBitmap->bmiHeader.biClrUsed != 0) {
|
||||
iNumPaletteEntries = pInfoBitmap->bmiHeader.biClrUsed;
|
||||
if (iNumPaletteEntries > 256) iNumPaletteEntries = 256;
|
||||
} else {
|
||||
if (pInfoBitmap->bmiHeader.biBitCount <= 8)
|
||||
iNumPaletteEntries = 1 << pInfoBitmap->bmiHeader.biBitCount;
|
||||
else
|
||||
iNumPaletteEntries = 0;
|
||||
}
|
||||
*pLength =
|
||||
sizeof(BITMAPFILEHEADER) +
|
||||
sizeof(BITMAPINFOHEADER) +
|
||||
|
@ -1624,6 +1632,7 @@ static int serializeIcon(HICON hIcon, void ** ppBuffer, unsigned int * pLength)
|
|||
|| (pInfoBitmap->bmiHeader.biBitCount == 24)
|
||||
|| (pInfoBitmap->bmiHeader.biBitCount == 32 && pInfoBitmap->bmiHeader.biCompression == BI_RGB)) {
|
||||
iNumEntriesPalette = pInfoBitmap->bmiHeader.biClrUsed;
|
||||
if (iNumEntriesPalette > 256) iNumEntriesPalette = 256;
|
||||
} else if ((pInfoBitmap->bmiHeader.biBitCount == 16 || pInfoBitmap->bmiHeader.biBitCount == 32)
|
||||
&& pInfoBitmap->bmiHeader.biCompression == BI_BITFIELDS) {
|
||||
iNumEntriesPalette = 3;
|
||||
|
@ -1820,7 +1829,7 @@ static HRESULT WINAPI OLEPictureImpl_Invoke(
|
|||
|
||||
VariantInit(pVarResult);
|
||||
V_VT(pVarResult) = VT_BOOL;
|
||||
V_UNION(pVarResult,boolVal) = FALSE;
|
||||
V_BOOL(pVarResult) = FALSE;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -1984,6 +1993,113 @@ HRESULT WINAPI OleLoadPictureEx( LPSTREAM lpstream, LONG lSize, BOOL fRunmode,
|
|||
return hr;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* OleLoadPicturePath (OLEAUT32.424)
|
||||
*/
|
||||
HRESULT WINAPI OleLoadPicturePath( LPOLESTR szURLorPath, LPUNKNOWN punkCaller,
|
||||
DWORD dwReserved, OLE_COLOR clrReserved, REFIID riid,
|
||||
LPVOID *ppvRet )
|
||||
{
|
||||
static const WCHAR file[] = { 'f','i','l','e',':','/','/',0 };
|
||||
IPicture *ipicture;
|
||||
HANDLE hFile;
|
||||
DWORD dwFileSize;
|
||||
HGLOBAL hGlobal = NULL;
|
||||
DWORD dwBytesRead = 0;
|
||||
IStream *stream;
|
||||
BOOL bRead;
|
||||
IPersistStream *pStream;
|
||||
HRESULT hRes;
|
||||
|
||||
TRACE("(%s,%p,%ld,%08lx,%s,%p): stub\n",
|
||||
debugstr_w(szURLorPath), punkCaller, dwReserved, clrReserved,
|
||||
debugstr_guid(riid), ppvRet);
|
||||
|
||||
if (!ppvRet) return E_POINTER;
|
||||
|
||||
if (strncmpW(szURLorPath, file, 7) == 0) {
|
||||
szURLorPath += 7;
|
||||
|
||||
hFile = CreateFileW(szURLorPath, GENERIC_READ, 0, NULL, OPEN_EXISTING,
|
||||
0, NULL);
|
||||
if (hFile == INVALID_HANDLE_VALUE)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
dwFileSize = GetFileSize(hFile, NULL);
|
||||
if (dwFileSize != INVALID_FILE_SIZE )
|
||||
{
|
||||
hGlobal = GlobalAlloc(GMEM_FIXED,dwFileSize);
|
||||
if ( hGlobal)
|
||||
{
|
||||
bRead = ReadFile(hFile, hGlobal, dwFileSize, &dwBytesRead, NULL);
|
||||
if (!bRead)
|
||||
{
|
||||
GlobalFree(hGlobal);
|
||||
hGlobal = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
CloseHandle(hFile);
|
||||
|
||||
if (!hGlobal)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
hRes = CreateStreamOnHGlobal(hGlobal, TRUE, &stream);
|
||||
if (FAILED(hRes))
|
||||
{
|
||||
GlobalFree(hGlobal);
|
||||
return hRes;
|
||||
}
|
||||
} else {
|
||||
IMoniker *pmnk;
|
||||
IBindCtx *pbc;
|
||||
|
||||
hRes = CreateBindCtx(0, &pbc);
|
||||
if (SUCCEEDED(hRes))
|
||||
{
|
||||
hRes = CreateURLMoniker(NULL, szURLorPath, &pmnk);
|
||||
if (SUCCEEDED(hRes))
|
||||
{
|
||||
hRes = IMoniker_BindToStorage(pmnk, pbc, NULL, &IID_IStream, (LPVOID*)&stream);
|
||||
IMoniker_Release(pmnk);
|
||||
}
|
||||
IBindCtx_Release(pbc);
|
||||
}
|
||||
if (FAILED(hRes))
|
||||
return hRes;
|
||||
}
|
||||
|
||||
hRes = CoCreateInstance(&CLSID_StdPicture, punkCaller, CLSCTX_INPROC_SERVER,
|
||||
&IID_IPicture, (LPVOID*)&ipicture);
|
||||
if (hRes != S_OK) {
|
||||
IStream_Release(stream);
|
||||
return hRes;
|
||||
}
|
||||
|
||||
hRes = IPicture_QueryInterface(ipicture, &IID_IPersistStream, (LPVOID*)&pStream);
|
||||
if (hRes) {
|
||||
IStream_Release(stream);
|
||||
IPicture_Release(ipicture);
|
||||
return hRes;
|
||||
}
|
||||
|
||||
hRes = IPersistStream_Load(pStream, stream);
|
||||
IPersistStream_Release(pStream);
|
||||
IStream_Release(stream);
|
||||
|
||||
if (hRes) {
|
||||
IPicture_Release(ipicture);
|
||||
return hRes;
|
||||
}
|
||||
|
||||
hRes = IPicture_QueryInterface(ipicture,riid,ppvRet);
|
||||
if (hRes)
|
||||
FIXME("Failed to get interface %s from IPicture.\n",debugstr_guid(riid));
|
||||
|
||||
IPicture_Release(ipicture);
|
||||
return hRes;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* StdPic ClassFactory
|
||||
*/
|
||||
|
@ -2017,12 +2133,8 @@ static ULONG WINAPI SPCF_Release(LPCLASSFACTORY iface) {
|
|||
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);
|
||||
/* Creates an uninitialized picture */
|
||||
return OleCreatePictureIndirect(NULL,riid,TRUE,ppobj);
|
||||
|
||||
}
|
||||
|
||||
|
|
621
reactos/lib/oleaut32/recinfo.c
Normal file
621
reactos/lib/oleaut32/recinfo.c
Normal file
|
@ -0,0 +1,621 @@
|
|||
/*
|
||||
* 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/unicode.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
|
||||
typedef struct {
|
||||
enum VARENUM vt;
|
||||
VARKIND varkind;
|
||||
ULONG offset;
|
||||
BSTR name;
|
||||
} fieldstr;
|
||||
|
||||
typedef struct {
|
||||
IRecordInfoVtbl *lpVtbl;
|
||||
ULONG ref;
|
||||
|
||||
GUID guid;
|
||||
UINT lib_index;
|
||||
WORD n_vars;
|
||||
ULONG size;
|
||||
BSTR name;
|
||||
fieldstr *fields;
|
||||
ITypeInfo *pTypeInfo;
|
||||
} IRecordInfoImpl;
|
||||
|
||||
static HRESULT copy_to_variant(void *src, VARIANT *pvar, enum VARENUM vt)
|
||||
{
|
||||
TRACE("%p %p %d\n", src, pvar, vt);
|
||||
|
||||
#define CASE_COPY(x) \
|
||||
case VT_ ## x: \
|
||||
V_ ## x(pvar) = *(typeof(V_ ## x(pvar))*)src; \
|
||||
break
|
||||
|
||||
switch(vt) {
|
||||
CASE_COPY(I2);
|
||||
CASE_COPY(I4);
|
||||
CASE_COPY(R4);
|
||||
CASE_COPY(R8);
|
||||
CASE_COPY(CY);
|
||||
CASE_COPY(DATE);
|
||||
CASE_COPY(BSTR);
|
||||
CASE_COPY(ERROR);
|
||||
CASE_COPY(BOOL);
|
||||
CASE_COPY(DECIMAL);
|
||||
CASE_COPY(I1);
|
||||
CASE_COPY(UI1);
|
||||
CASE_COPY(UI2);
|
||||
CASE_COPY(UI4);
|
||||
CASE_COPY(I8);
|
||||
CASE_COPY(UI8);
|
||||
CASE_COPY(INT);
|
||||
CASE_COPY(UINT);
|
||||
CASE_COPY(INT_PTR);
|
||||
CASE_COPY(UINT_PTR);
|
||||
default:
|
||||
FIXME("Not supported type: %d\n", vt);
|
||||
return E_NOTIMPL;
|
||||
};
|
||||
#undef CASE_COPY
|
||||
|
||||
V_VT(pvar) = vt;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT copy_from_variant(VARIANT *src, void *dest, enum VARENUM vt)
|
||||
{
|
||||
VARIANT var;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%p(%d) %p %d)\n", src, V_VT(src), dest, vt);
|
||||
|
||||
hres = VariantChangeType(&var, src, 0, vt);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
#define CASE_COPY(x) \
|
||||
case VT_ ## x: \
|
||||
*(typeof(V_ ## x(&var))*)dest = V_ ## x(&var); \
|
||||
break
|
||||
|
||||
switch(vt) {
|
||||
CASE_COPY(I2);
|
||||
CASE_COPY(I4);
|
||||
CASE_COPY(R4);
|
||||
CASE_COPY(R8);
|
||||
CASE_COPY(CY);
|
||||
CASE_COPY(DATE);
|
||||
CASE_COPY(BSTR);
|
||||
CASE_COPY(ERROR);
|
||||
CASE_COPY(BOOL);
|
||||
CASE_COPY(DECIMAL);
|
||||
CASE_COPY(I1);
|
||||
CASE_COPY(UI1);
|
||||
CASE_COPY(UI2);
|
||||
CASE_COPY(UI4);
|
||||
CASE_COPY(I8);
|
||||
CASE_COPY(UI8);
|
||||
CASE_COPY(INT);
|
||||
CASE_COPY(UINT);
|
||||
CASE_COPY(INT_PTR);
|
||||
CASE_COPY(UINT_PTR);
|
||||
default:
|
||||
FIXME("Not supported type: %d\n", V_VT(&var));
|
||||
return E_NOTIMPL;
|
||||
};
|
||||
#undef CASE_COPY
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
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->n_vars; i++)
|
||||
SysFreeString(This->fields[i].name);
|
||||
HeapFree(GetProcessHeap(), 0, This->name);
|
||||
HeapFree(GetProcessHeap(), 0, This->fields);
|
||||
ITypeInfo_Release(This->pTypeInfo);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IRecordInfoImpl_RecordInit(IRecordInfo *iface, PVOID pvNew)
|
||||
{
|
||||
IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
|
||||
TRACE("(%p)->(%p)\n", This, pvNew);
|
||||
|
||||
if(!pvNew)
|
||||
return E_INVALIDARG;
|
||||
|
||||
memset(pvNew, 0, This->size);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IRecordInfoImpl_RecordClear(IRecordInfo *iface, PVOID pvExisting)
|
||||
{
|
||||
IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
|
||||
int i;
|
||||
PVOID var;
|
||||
|
||||
TRACE("(%p)->(%p)\n", This, pvExisting);
|
||||
|
||||
if(!pvExisting)
|
||||
return E_INVALIDARG;
|
||||
|
||||
for(i=0; i<This->n_vars; i++) {
|
||||
if(This->fields[i].varkind != VAR_PERINSTANCE) {
|
||||
ERR("varkind != VAR_PERINSTANCE\n");
|
||||
continue;
|
||||
}
|
||||
var = ((PBYTE)pvExisting)+This->fields[i].offset;
|
||||
switch(This->fields[i].vt) {
|
||||
case VT_BSTR:
|
||||
/* NOTE: Windows implementatino reads DWORD (len) before string,
|
||||
* but it seems to do nothing with this */
|
||||
*(BSTR*)var = NULL;
|
||||
break;
|
||||
case VT_I2:
|
||||
case VT_I4:
|
||||
case VT_R8:
|
||||
case VT_CY:
|
||||
case VT_DATE:
|
||||
case VT_ERROR:
|
||||
case VT_BOOL:
|
||||
case VT_DECIMAL:
|
||||
case VT_I1:
|
||||
case VT_UI1:
|
||||
case VT_UI2:
|
||||
case VT_UI4:
|
||||
case VT_I8:
|
||||
case VT_UI8:
|
||||
case VT_INT:
|
||||
case VT_UINT:
|
||||
break;
|
||||
case VT_INT_PTR:
|
||||
case VT_UINT_PTR:
|
||||
*(void**)var = NULL;
|
||||
break;
|
||||
default:
|
||||
FIXME("Not supported vt = %d\n", This->fields[i].vt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IRecordInfoImpl_RecordCopy(IRecordInfo *iface, PVOID pvExisting,
|
||||
PVOID pvNew)
|
||||
{
|
||||
IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
|
||||
|
||||
TRACE("(%p)->(%p %p)\n", This, pvExisting, pvNew);
|
||||
|
||||
if(!pvExisting || !pvNew)
|
||||
return E_INVALIDARG;
|
||||
|
||||
memcpy(pvExisting, pvNew, This->size);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
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->size;
|
||||
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;
|
||||
int i;
|
||||
|
||||
TRACE("(%p)->(%p %s %p)\n", This, pvData, debugstr_w(szFieldName), pvarField);
|
||||
|
||||
if(!pvData || !szFieldName || !pvarField)
|
||||
return E_INVALIDARG;
|
||||
|
||||
for(i=0; i<This->n_vars; i++)
|
||||
if(!strcmpW(This->fields[i].name, szFieldName))
|
||||
break;
|
||||
if(i == This->n_vars)
|
||||
return TYPE_E_FIELDNOTFOUND;
|
||||
|
||||
VariantClear(pvarField);
|
||||
return copy_to_variant(((PBYTE)pvData)+This->fields[i].offset, pvarField,
|
||||
This->fields[i].vt);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IRecordInfoImpl_GetFieldNoCopy(IRecordInfo *iface, PVOID pvData,
|
||||
LPCOLESTR szFieldName, VARIANT *pvarField, PVOID *ppvDataCArray)
|
||||
{
|
||||
IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
|
||||
int i;
|
||||
|
||||
TRACE("(%p)->(%p %s %p %p)\n", This, pvData, debugstr_w(szFieldName), pvarField, ppvDataCArray);
|
||||
|
||||
if(!pvData || !szFieldName || !pvarField)
|
||||
return E_INVALIDARG;
|
||||
|
||||
for(i=0; i<This->n_vars; i++)
|
||||
if(!strcmpW(This->fields[i].name, szFieldName))
|
||||
break;
|
||||
if(i == This->n_vars)
|
||||
return TYPE_E_FIELDNOTFOUND;
|
||||
|
||||
VariantClear(pvarField);
|
||||
V_VT(pvarField) = VT_BYREF|This->fields[i].vt;
|
||||
V_BYREF(pvarField) = ((PBYTE)pvData)+This->fields[i].offset;
|
||||
*ppvDataCArray = NULL;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IRecordInfoImpl_PutField(IRecordInfo *iface, ULONG wFlags, PVOID pvData,
|
||||
LPCOLESTR szFieldName, VARIANT *pvarField)
|
||||
{
|
||||
IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
|
||||
int i;
|
||||
|
||||
TRACE("(%p)->(%08lx %p %s %p)\n", This, wFlags, pvData, debugstr_w(szFieldName),
|
||||
pvarField);
|
||||
|
||||
if(!pvData || !szFieldName || !pvarField
|
||||
|| (wFlags != INVOKE_PROPERTYPUTREF && wFlags != INVOKE_PROPERTYPUT))
|
||||
return E_INVALIDARG;
|
||||
|
||||
if(wFlags == INVOKE_PROPERTYPUTREF) {
|
||||
FIXME("wFlag == INVOKE_PROPERTYPUTREF not supported\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
for(i=0; i<This->n_vars; i++)
|
||||
if(!strcmpW(This->fields[i].name, szFieldName))
|
||||
break;
|
||||
if(i == This->n_vars)
|
||||
return TYPE_E_FIELDNOTFOUND;
|
||||
|
||||
return copy_from_variant(pvarField, ((PBYTE)pvData)+This->fields[i].offset,
|
||||
This->fields[i].vt);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IRecordInfoImpl_PutFieldNoCopy(IRecordInfo *iface, ULONG wFlags,
|
||||
PVOID pvData, LPCOLESTR szFieldName, VARIANT *pvarField)
|
||||
{
|
||||
IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
|
||||
int i;
|
||||
|
||||
FIXME("(%p)->(%08lx %p %s %p) stub\n", This, wFlags, pvData, debugstr_w(szFieldName), pvarField);
|
||||
|
||||
if(!pvData || !szFieldName || !pvarField
|
||||
|| (wFlags != INVOKE_PROPERTYPUTREF && wFlags != INVOKE_PROPERTYPUT))
|
||||
return E_INVALIDARG;
|
||||
|
||||
for(i=0; i<This->n_vars; i++)
|
||||
if(!strcmpW(This->fields[i].name, szFieldName))
|
||||
break;
|
||||
if(i == This->n_vars)
|
||||
return TYPE_E_FIELDNOTFOUND;
|
||||
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IRecordInfoImpl_GetFieldNames(IRecordInfo *iface, ULONG *pcNames,
|
||||
BSTR *rgBstrNames)
|
||||
{
|
||||
IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
|
||||
ULONG n = This->n_vars;
|
||||
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->fields[i].name);
|
||||
}
|
||||
|
||||
*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;
|
||||
|
||||
TRACE("(%p)\n", This);
|
||||
|
||||
return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->size);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IRecordInfoImpl_RecordCreateCopy(IRecordInfo *iface, PVOID pvSource,
|
||||
PVOID *ppvDest)
|
||||
{
|
||||
IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
|
||||
|
||||
TRACE("(%p)->(%p %p)\n", This, pvSource, ppvDest);
|
||||
|
||||
if(!pvSource || !ppvDest)
|
||||
return E_INVALIDARG;
|
||||
|
||||
*ppvDest = IRecordInfo_RecordCreate(iface);
|
||||
return IRecordInfo_RecordCopy(iface, pvSource, *ppvDest);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IRecordInfoImpl_RecordDestroy(IRecordInfo *iface, PVOID pvRecord)
|
||||
{
|
||||
IRecordInfoImpl *This = (IRecordInfoImpl*)iface;
|
||||
|
||||
TRACE("(%p)->(%p)\n", This, pvRecord);
|
||||
|
||||
if(!HeapFree(GetProcessHeap(), 0, pvRecord))
|
||||
return E_INVALIDARG;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
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;
|
||||
ret->n_vars = typeattr->cVars;
|
||||
ret->size = typeattr->cbSizeInstance;
|
||||
ITypeInfo_ReleaseTypeAttr(pTypeInfo, typeattr);
|
||||
|
||||
memcpy(&ret->guid, &guid, sizeof(GUID));
|
||||
|
||||
/* 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->fields = HeapAlloc(GetProcessHeap(), 0, ret->n_vars*sizeof(VARDESC));
|
||||
for(i = 0; i<ret->n_vars; i++) {
|
||||
VARDESC *vardesc;
|
||||
hres = ITypeInfo_GetVarDesc(pTypeInfo, i, &vardesc);
|
||||
if(FAILED(hres)) {
|
||||
WARN("GetVarDesc failed\n");
|
||||
continue;
|
||||
}
|
||||
ret->fields[i].vt = vardesc->elemdescVar.tdesc.vt;
|
||||
ret->fields[i].varkind = vardesc->varkind;
|
||||
ret->fields[i].offset = vardesc->u.oInst;
|
||||
hres = ITypeInfo_GetDocumentation(pTypeInfo, vardesc->memid, &ret->fields[i].name,
|
||||
NULL, NULL, NULL);
|
||||
if(FAILED(hres))
|
||||
WARN("GetDocumentation failed: %08lx\n", hres);
|
||||
ITypeInfo_ReleaseVarDesc(pTypeInfo, vardesc);
|
||||
}
|
||||
|
||||
*ppRecInfo = (IRecordInfo*)ret;
|
||||
|
||||
return S_OK;
|
||||
}
|
|
@ -315,6 +315,9 @@ HRESULT WINAPI LoadTypeLibEx(
|
|||
|
||||
TRACE("(%s,%d,%p)\n",debugstr_w(szFile), regkind, pptLib);
|
||||
|
||||
/* by default try and load using LoadLibrary (for builtin stdole32.tlb) */
|
||||
memcpy(szPath, szFile, (strlenW(szFile)+1)*sizeof(WCHAR));
|
||||
|
||||
*pptLib = NULL;
|
||||
if(!SearchPathW(NULL,szFile,NULL,sizeof(szPath)/sizeof(WCHAR),szPath,
|
||||
NULL)) {
|
||||
|
@ -331,9 +334,6 @@ HRESULT WINAPI LoadTypeLibEx(
|
|||
return TYPE_E_CANTLOADLIBRARY;
|
||||
if (GetFileAttributesW(szFileCopy) & FILE_ATTRIBUTE_DIRECTORY)
|
||||
return TYPE_E_CANTLOADLIBRARY;
|
||||
} else {
|
||||
TRACE("Wanted to load %s as typelib, but file was not found.\n",debugstr_w(szFile));
|
||||
return TYPE_E_CANTLOADLIBRARY;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -848,9 +848,10 @@ typedef struct tagITypeLibImpl
|
|||
libary. Only used while read MSFT
|
||||
typelibs */
|
||||
|
||||
/* typelibs are cached, keyed by path, so store the linked list info within them */
|
||||
/* typelibs are cached, keyed by path and index, so store the linked list info within them */
|
||||
struct tagITypeLibImpl *next, *prev;
|
||||
WCHAR *path;
|
||||
INT index;
|
||||
} ITypeLibImpl;
|
||||
|
||||
static struct ITypeLib2Vtbl tlbvt;
|
||||
|
@ -865,7 +866,7 @@ static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength);
|
|||
|
||||
/*======================= ITypeInfo implementation =======================*/
|
||||
|
||||
/* data for refernced types */
|
||||
/* data for referenced types */
|
||||
typedef struct tagTLBRefType
|
||||
{
|
||||
INT index; /* Type index for internal ref or for external ref
|
||||
|
@ -1497,7 +1498,7 @@ static void MSFT_ReadValue( VARIANT * pVar, int offset, TLBContext *pcx )
|
|||
|
||||
if(offset <0) { /* data are packed in here */
|
||||
V_VT(pVar) = (offset & 0x7c000000 )>> 26;
|
||||
V_UNION(pVar, iVal) = offset & 0x3ffffff;
|
||||
V_I2(pVar) = offset & 0x3ffffff;
|
||||
return;
|
||||
}
|
||||
MSFT_ReadLEWords(&(V_VT(pVar)), sizeof(VARTYPE), pcx,
|
||||
|
@ -1537,7 +1538,7 @@ static void MSFT_ReadValue( VARIANT * pVar, int offset, TLBContext *pcx )
|
|||
} 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);
|
||||
V_BSTR(pVar)=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];
|
||||
|
@ -1570,7 +1571,7 @@ static void MSFT_ReadValue( VARIANT * pVar, int offset, TLBContext *pcx )
|
|||
}
|
||||
|
||||
if(size>0) /* (big|small) endian correct? */
|
||||
MSFT_Read(&(V_UNION(pVar, iVal)), size, pcx, DO_NOT_SEEK );
|
||||
MSFT_Read(&(V_I2(pVar)), size, pcx, DO_NOT_SEEK );
|
||||
return;
|
||||
}
|
||||
/*
|
||||
|
@ -1924,7 +1925,7 @@ static void MSFT_DoVars(TLBContext *pcx, ITypeInfoImpl *pTI, int cFuncs,
|
|||
recoffset += reclength;
|
||||
}
|
||||
}
|
||||
/* fill in data for a hreftype (offset). When the refernced type is contained
|
||||
/* fill in data for a hreftype (offset). When the referenced 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
|
||||
* */
|
||||
|
@ -2169,7 +2170,7 @@ int TLB_ReadTypeLib(LPCWSTR pszFileName, INT index, ITypeLib2 **ppTypeLib)
|
|||
EnterCriticalSection(&cache_section);
|
||||
for (entry = tlb_cache_first; entry != NULL; entry = entry->next)
|
||||
{
|
||||
if (!strcmpiW(entry->path, pszFileName))
|
||||
if (!strcmpiW(entry->path, pszFileName) && entry->index == index)
|
||||
{
|
||||
TRACE("cache hit\n");
|
||||
*ppTypeLib = (ITypeLib2*)entry;
|
||||
|
@ -2209,8 +2210,13 @@ int TLB_ReadTypeLib(LPCWSTR pszFileName, INT index, ITypeLib2 **ppTypeLib)
|
|||
}
|
||||
CloseHandle(hFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE("not found, trying to load %s as library\n", debugstr_w(pszFileName));
|
||||
}
|
||||
|
||||
if( (WORD)dwSignature == IMAGE_DOS_SIGNATURE )
|
||||
/* if the file is a DLL or not found, try loading it with LoadLibrary */
|
||||
if (((WORD)dwSignature == IMAGE_DOS_SIGNATURE) || (dwSignature == 0))
|
||||
{
|
||||
/* find the typelibrary resource*/
|
||||
HINSTANCE hinstDLL = LoadLibraryExW(pszFileName, 0, DONT_RESOLVE_DLL_REFERENCES|
|
||||
|
@ -2258,6 +2264,7 @@ int TLB_ReadTypeLib(LPCWSTR pszFileName, INT index, ITypeLib2 **ppTypeLib)
|
|||
impl->path = HeapAlloc(GetProcessHeap(), 0, (strlenW(pszFileName)+1) * sizeof(WCHAR));
|
||||
lstrcpyW(impl->path, pszFileName);
|
||||
/* We should really canonicalise the path here. */
|
||||
impl->index = index;
|
||||
|
||||
/* FIXME: check if it has added already in the meantime */
|
||||
EnterCriticalSection(&cache_section);
|
||||
|
@ -3074,7 +3081,7 @@ static SLTG_TypeInfoTail *SLTG_ProcessEnum(char *pBlk, ITypeInfoImpl *pTI,
|
|||
return (SLTG_TypeInfoTail*)(pFirstItem + pMemHeader->cbExtra);
|
||||
}
|
||||
|
||||
/* Because SLTG_OtherTypeInfo is such a painfull struct, we make a more
|
||||
/* Because SLTG_OtherTypeInfo is such a painful struct, we make a more
|
||||
managable copy of it into this */
|
||||
typedef struct {
|
||||
WORD small_no;
|
||||
|
@ -4109,8 +4116,8 @@ static ULONG WINAPI ITypeInfo_fnRelease(ITypeInfo2 *iface)
|
|||
TRACE("(%p)->(%lu)\n",This, ref);
|
||||
|
||||
if (ref) {
|
||||
/* We don't release ITypeLib when ref=0 becouse
|
||||
it means that funtion is called by ITypeLi2_Release */
|
||||
/* We don't release ITypeLib when ref=0 because
|
||||
it means that function is called by ITypeLib2_Release */
|
||||
ITypeLib2_Release((ITypeLib2*)This->pTypeLib);
|
||||
} else {
|
||||
FIXME("destroy child objects\n");
|
||||
|
@ -4518,12 +4525,12 @@ _copy_arg( ITypeInfo2 *tinfo, TYPEDESC *tdesc,
|
|||
}
|
||||
|
||||
if (V_VT(arg) == vt) {
|
||||
memcpy(argpos, &V_UNION(arg,lVal), arglen);
|
||||
memcpy(argpos, &V_I4(arg), arglen);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (V_ISARRAY(arg) && (vt == VT_SAFEARRAY)) {
|
||||
memcpy(argpos, &V_UNION(arg,parray), sizeof(SAFEARRAY*));
|
||||
memcpy(argpos, &V_ARRAY(arg), sizeof(SAFEARRAY*));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -4533,13 +4540,13 @@ _copy_arg( ITypeInfo2 *tinfo, TYPEDESC *tdesc,
|
|||
}
|
||||
/* 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);
|
||||
memcpy(argpos,(void*)V_I4(arg), 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);
|
||||
memcpy(argpos,&V_I4(arg), arglen);
|
||||
return S_OK;
|
||||
}
|
||||
if ((vt == VT_PTR) && tdesc)
|
||||
|
@ -4555,7 +4562,7 @@ _copy_arg( ITypeInfo2 *tinfo, TYPEDESC *tdesc,
|
|||
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);
|
||||
memcpy(argpos, &V_I4(arg), 4);
|
||||
return S_OK;
|
||||
}
|
||||
hres = ITypeInfo_GetTypeAttr(tinfo2,&tattr);
|
||||
|
@ -4569,11 +4576,11 @@ _copy_arg( ITypeInfo2 *tinfo, TYPEDESC *tdesc,
|
|||
case TKIND_ENUM:
|
||||
switch ( V_VT( arg ) ) {
|
||||
case VT_I2:
|
||||
*argpos = V_UNION(arg,iVal);
|
||||
*argpos = V_I2(arg);
|
||||
hres = S_OK;
|
||||
break;
|
||||
case VT_I4:
|
||||
memcpy(argpos, &V_UNION(arg,lVal), 4);
|
||||
memcpy(argpos, &V_I4(arg), 4);
|
||||
hres = S_OK;
|
||||
break;
|
||||
default:
|
||||
|
@ -4592,15 +4599,15 @@ _copy_arg( ITypeInfo2 *tinfo, TYPEDESC *tdesc,
|
|||
if (V_VT(arg) == VT_DISPATCH) {
|
||||
IDispatch *disp;
|
||||
if (IsEqualIID(&IID_IDispatch,&(tattr->guid))) {
|
||||
memcpy(argpos, &V_UNION(arg,pdispVal), 4);
|
||||
memcpy(argpos, &V_DISPATCH(arg), 4);
|
||||
hres = S_OK;
|
||||
break;
|
||||
}
|
||||
hres=IUnknown_QueryInterface(V_UNION(arg,pdispVal),
|
||||
hres=IUnknown_QueryInterface(V_DISPATCH(arg),
|
||||
&IID_IDispatch,(LPVOID*)&disp);
|
||||
if (SUCCEEDED(hres)) {
|
||||
memcpy(argpos,&disp,4);
|
||||
IUnknown_Release(V_UNION(arg,pdispVal));
|
||||
IUnknown_Release(V_DISPATCH(arg));
|
||||
hres = S_OK;
|
||||
break;
|
||||
}
|
||||
|
@ -4610,7 +4617,7 @@ _copy_arg( ITypeInfo2 *tinfo, TYPEDESC *tdesc,
|
|||
break;
|
||||
}
|
||||
if (V_VT(arg) == VT_UNKNOWN) {
|
||||
memcpy(argpos, &V_UNION(arg,punkVal), 4);
|
||||
memcpy(argpos, &V_UNKNOWN(arg), 4);
|
||||
hres = S_OK;
|
||||
break;
|
||||
}
|
||||
|
@ -4621,7 +4628,7 @@ _copy_arg( ITypeInfo2 *tinfo, TYPEDESC *tdesc,
|
|||
|
||||
case TKIND_DISPATCH:
|
||||
if (V_VT(arg) == VT_DISPATCH) {
|
||||
memcpy(argpos, &V_UNION(arg,pdispVal), 4);
|
||||
memcpy(argpos, &V_DISPATCH(arg), 4);
|
||||
hres = S_OK;
|
||||
}
|
||||
else {
|
||||
|
@ -4646,7 +4653,7 @@ _copy_arg( ITypeInfo2 *tinfo, TYPEDESC *tdesc,
|
|||
oldvt = V_VT(arg);
|
||||
VariantInit(&va);
|
||||
if (VariantChangeType(&va,arg,0,vt)==S_OK) {
|
||||
memcpy(argpos,&V_UNION(&va,lVal), arglen);
|
||||
memcpy(argpos,&V_I4(&va), arglen);
|
||||
FIXME("Should not use VariantChangeType here."
|
||||
" (conversion from 0x%x -> 0x%x) %08lx\n",
|
||||
V_VT(arg), vt, *argpos
|
||||
|
@ -4768,7 +4775,7 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
|
|||
if(i < func_desc->cParams - func_desc->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))) {
|
||||
|| ((V_ISBYREF(arg)) && !V_BYREF(arg))) {
|
||||
/* FIXME: Documentation says that we do this when parameter is left unspecified.
|
||||
How to determine it? */
|
||||
|
||||
|
@ -4834,7 +4841,7 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
|
|||
continue;
|
||||
|
||||
VariantInit(pVarResult);
|
||||
memcpy(&V_UNION(pVarResult,intVal),&args2[args2pos],arglen*sizeof(DWORD));
|
||||
memcpy(&V_INT(pVarResult),&args2[args2pos],arglen*sizeof(DWORD));
|
||||
|
||||
if (tdesc->vt == VT_PTR)
|
||||
tdesc = tdesc->u.lptdesc;
|
||||
|
|
|
@ -140,7 +140,7 @@ 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. */
|
||||
char filename[0]; /* preceded by two bytes of encoded (length << 2) + flags in the low two bits. */
|
||||
} MSFT_ImpFile;
|
||||
|
||||
typedef struct tagICreateTypeLib2Impl
|
||||
|
@ -2055,7 +2055,7 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetFuncCustData(
|
|||
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. */
|
||||
UINT indexParam, /* [I] The index of the parameter 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. */
|
||||
{
|
||||
|
|
|
@ -190,7 +190,7 @@ static unsigned wire_extra(unsigned long *pFlags, VARIANT *pvar)
|
|||
ULONG size;
|
||||
HRESULT hr;
|
||||
|
||||
if (V_VT(pvar) & VT_ARRAY) {
|
||||
if (V_ISARRAY(pvar)) {
|
||||
FIXME("wire-size safearray\n");
|
||||
return 0;
|
||||
}
|
||||
|
@ -527,7 +527,7 @@ HRESULT CALLBACK IDispatch_Invoke_Proxy(
|
|||
/* count by-ref args */
|
||||
for (cVarRef=0,u=0; u<pDispParams->cArgs; u++) {
|
||||
VARIANTARG* arg = &pDispParams->rgvarg[u];
|
||||
if (V_VT(arg) & VT_BYREF) {
|
||||
if (V_ISBYREF(arg)) {
|
||||
cVarRef++;
|
||||
}
|
||||
}
|
||||
|
@ -537,7 +537,7 @@ HRESULT CALLBACK IDispatch_Invoke_Proxy(
|
|||
/* make list of by-ref args */
|
||||
for (cVarRef=0,u=0; u<pDispParams->cArgs; u++) {
|
||||
VARIANTARG* arg = &pDispParams->rgvarg[u];
|
||||
if (V_VT(arg) & VT_BYREF) {
|
||||
if (V_ISBYREF(arg)) {
|
||||
rgVarRefIdx[cVarRef] = u;
|
||||
VariantInit(&rgVarRef[cVarRef]);
|
||||
cVarRef++;
|
||||
|
|
|
@ -94,7 +94,7 @@ static const WCHAR szPercentZeroStar_d[] = { '%','0','*','d','\0' };
|
|||
* 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
|
||||
* also be specified by preceding 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
|
||||
|
@ -885,7 +885,7 @@ HRESULT WINAPI VarTokenizeFormatString(LPOLESTR lpszFormat, LPBYTE rgbTok,
|
|||
TRACE("h\n");
|
||||
}
|
||||
fmt_state &= ~FMT_STATE_OPEN_COPY;
|
||||
/* Note that now we have seen an hours token, the next occurence of
|
||||
/* Note that now we have seen an hours token, the next occurrence of
|
||||
* 'mm' indicates minutes, not months.
|
||||
*/
|
||||
fmt_state |= FMT_STATE_SEEN_HOURS;
|
||||
|
|
|
@ -984,7 +984,7 @@ HRESULT WINAPI VariantChangeTypeEx(VARIANTARG* pvargDest, VARIANTARG* pvargSrc,
|
|||
{
|
||||
VARIANTARG vTmp, vSrcDeref;
|
||||
|
||||
if(V_VT(pvargSrc)&VT_BYREF && !V_BYREF(pvargSrc))
|
||||
if(V_ISBYREF(pvargSrc) && !V_BYREF(pvargSrc))
|
||||
res = DISP_E_TYPEMISMATCH;
|
||||
else
|
||||
{
|
||||
|
@ -2531,7 +2531,7 @@ HRESULT WINAPI VarCmp(LPVARIANT left, LPVARIANT right, LCID lcid, DWORD flags)
|
|||
}
|
||||
|
||||
xmask = (1<<(V_VT(left)&VT_TYPEMASK))|(1<<(V_VT(right)&VT_TYPEMASK));
|
||||
if (xmask & (1<<VT_R8)) {
|
||||
if (xmask & VTBIT_R8) {
|
||||
rc = VariantChangeType(&lv,left,0,VT_R8);
|
||||
if (FAILED(rc)) return rc;
|
||||
rc = VariantChangeType(&rv,right,0,VT_R8);
|
||||
|
@ -2542,7 +2542,7 @@ HRESULT WINAPI VarCmp(LPVARIANT left, LPVARIANT right, LCID lcid, DWORD flags)
|
|||
if (V_R8(&lv) > V_R8(&rv)) return VARCMP_GT;
|
||||
return E_FAIL; /* can't get here */
|
||||
}
|
||||
if (xmask & (1<<VT_R4)) {
|
||||
if (xmask & VTBIT_R4) {
|
||||
rc = VariantChangeType(&lv,left,0,VT_R4);
|
||||
if (FAILED(rc)) return rc;
|
||||
rc = VariantChangeType(&rv,right,0,VT_R4);
|
||||
|
@ -2558,29 +2558,29 @@ HRESULT WINAPI VarCmp(LPVARIANT left, LPVARIANT right, LCID lcid, DWORD flags)
|
|||
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;
|
||||
case VT_I1 : lVal = V_I1(left); break;
|
||||
case VT_I2 : lVal = V_I2(left); break;
|
||||
case VT_I4 :
|
||||
case VT_INT : lVal = V_I4(left); break;
|
||||
case VT_UI1 : lVal = V_UI1(left); break;
|
||||
case VT_UI2 : lVal = V_UI2(left); break;
|
||||
case VT_UI4 :
|
||||
case VT_UINT : lVal = V_UI4(left); break;
|
||||
case VT_BOOL : lVal = V_BOOL(left); 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;
|
||||
case VT_I1 : rVal = V_I1(right); break;
|
||||
case VT_I2 : rVal = V_I2(right); break;
|
||||
case VT_I4 :
|
||||
case VT_INT : rVal = V_I4(right); break;
|
||||
case VT_UI1 : rVal = V_UI1(right); break;
|
||||
case VT_UI2 : rVal = V_UI2(right); break;
|
||||
case VT_UI4 :
|
||||
case VT_UINT : rVal = V_UI4(right); break;
|
||||
case VT_BOOL : rVal = V_BOOL(right); break;
|
||||
default: rOk = FALSE;
|
||||
}
|
||||
|
||||
|
@ -2598,20 +2598,20 @@ HRESULT WINAPI VarCmp(LPVARIANT left, LPVARIANT right, LCID lcid, DWORD flags)
|
|||
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))) {
|
||||
if (floor(V_DATE(left)) == floor(V_DATE(right))) {
|
||||
/* 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) );
|
||||
wholePart = (double) floor( V_DATE(left) );
|
||||
if (wholePart == 0) wholePart = 1;
|
||||
leftR = floor(fmod( V_UNION(left,date), wholePart ) * (24*60*60));
|
||||
leftR = floor(fmod( V_DATE(left), wholePart ) * (24*60*60));
|
||||
|
||||
wholePart = (double) floor( V_UNION(right,date) );
|
||||
wholePart = (double) floor( V_DATE(right) );
|
||||
if (wholePart == 0) wholePart = 1;
|
||||
rightR = floor(fmod( V_UNION(right,date), wholePart ) * (24*60*60));
|
||||
rightR = floor(fmod( V_DATE(right), wholePart ) * (24*60*60));
|
||||
|
||||
if (leftR < rightR) {
|
||||
return VARCMP_LT;
|
||||
|
@ -2621,9 +2621,9 @@ HRESULT WINAPI VarCmp(LPVARIANT left, LPVARIANT right, LCID lcid, DWORD flags)
|
|||
return VARCMP_EQ;
|
||||
}
|
||||
|
||||
} else if (V_UNION(left,date) < V_UNION(right,date)) {
|
||||
} else if (V_DATE(left) < V_DATE(right)) {
|
||||
return VARCMP_LT;
|
||||
} else if (V_UNION(left,date) > V_UNION(right,date)) {
|
||||
} else if (V_DATE(left) > V_DATE(right)) {
|
||||
return VARCMP_GT;
|
||||
}
|
||||
}
|
||||
|
@ -2665,29 +2665,29 @@ HRESULT WINAPI VarAnd(LPVARIANT left, LPVARIANT right, LPVARIANT result)
|
|||
|
||||
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;
|
||||
case VT_I1 : lVal = V_I1(left); resT=VT_I4; break;
|
||||
case VT_I2 : lVal = V_I2(left); resT=VT_I2; break;
|
||||
case VT_I4 :
|
||||
case VT_INT : lVal = V_I4(left); resT=VT_I4; break;
|
||||
case VT_UI1 : lVal = V_UI1(left); resT=VT_I4; break;
|
||||
case VT_UI2 : lVal = V_UI2(left); resT=VT_I4; break;
|
||||
case VT_UI4 :
|
||||
case VT_UINT : lVal = V_UI4(left); resT=VT_I4; break;
|
||||
case VT_BOOL : rVal = V_BOOL(left); 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;
|
||||
case VT_I1 : rVal = V_I1(right); resT=VT_I4; break;
|
||||
case VT_I2 : rVal = V_I2(right); resT=max(VT_I2, resT); break;
|
||||
case VT_I4 :
|
||||
case VT_INT : rVal = V_I4(right); resT=VT_I4; break;
|
||||
case VT_UI1 : rVal = V_UI1(right); resT=VT_I4; break;
|
||||
case VT_UI2 : rVal = V_UI2(right); resT=VT_I4; break;
|
||||
case VT_UI4 :
|
||||
case VT_UINT : rVal = V_UI4(right); resT=VT_I4; break;
|
||||
case VT_BOOL : rVal = V_BOOL(right); resT=VT_I4; break;
|
||||
default: rOk = FALSE;
|
||||
}
|
||||
|
||||
|
@ -2695,11 +2695,11 @@ HRESULT WINAPI VarAnd(LPVARIANT left, LPVARIANT right, LPVARIANT result)
|
|||
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;
|
||||
case VT_I2 : V_I2(result) = res; break;
|
||||
case VT_I4 : V_I4(result) = res; break;
|
||||
default:
|
||||
FIXME("Unexpected result variant type %x\n", resT);
|
||||
V_UNION(result,lVal) = res;
|
||||
V_I4(result) = res;
|
||||
}
|
||||
rc = S_OK;
|
||||
|
||||
|
@ -2747,32 +2747,32 @@ HRESULT WINAPI VarAdd(LPVARIANT left, LPVARIANT right, LPVARIANT result)
|
|||
|
||||
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_I1 : lVal = V_I1(left); break;
|
||||
case VT_I2 : lVal = V_I2(left); break;
|
||||
case VT_I4 :
|
||||
case VT_INT : lVal = V_I4(left); break;
|
||||
case VT_UI1 : lVal = V_UI1(left); break;
|
||||
case VT_UI2 : lVal = V_UI2(left); break;
|
||||
case VT_UI4 :
|
||||
case VT_UINT : lVal = V_UI4(left); break;
|
||||
case VT_R4 : lVal = V_R4(left); break;
|
||||
case VT_R8 : lVal = V_R8(left); 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_I1 : rVal = V_I1(right); break;
|
||||
case VT_I2 : rVal = V_I2(right); break;
|
||||
case VT_I4 :
|
||||
case VT_INT : rVal = V_I4(right); break;
|
||||
case VT_UI1 : rVal = V_UI1(right); break;
|
||||
case VT_UI2 : rVal = V_UI2(right); break;
|
||||
case VT_UI4 :
|
||||
case VT_UINT : rVal = V_UI4(right); break;
|
||||
case VT_R4 : rVal = V_R4(right);break;
|
||||
case VT_R8 : rVal = V_R8(right);break;
|
||||
case VT_NULL : rVal = 0.0; break;
|
||||
default: rOk = FALSE;
|
||||
}
|
||||
|
@ -2780,7 +2780,7 @@ HRESULT WINAPI VarAdd(LPVARIANT left, LPVARIANT right, LPVARIANT result)
|
|||
if (lOk && rOk) {
|
||||
res = (lVal + rVal);
|
||||
V_VT(result) = VT_R8;
|
||||
V_UNION(result,dblVal) = res;
|
||||
V_R8(result) = res;
|
||||
rc = S_OK;
|
||||
} else {
|
||||
FIXME("Unhandled type pair %d / %d in double addition.\n",
|
||||
|
@ -2801,30 +2801,30 @@ HRESULT WINAPI VarAdd(LPVARIANT left, LPVARIANT right, LPVARIANT result)
|
|||
|
||||
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_I1 : lVal = V_I1(left); break;
|
||||
case VT_I2 : lVal = V_I2(left); break;
|
||||
case VT_I4 :
|
||||
case VT_INT : lVal = V_I4(left); break;
|
||||
case VT_UI1 : lVal = V_UI1(left); break;
|
||||
case VT_UI2 : lVal = V_UI2(left); break;
|
||||
case VT_UI4 :
|
||||
case VT_UINT : lVal = V_UI4(left); break;
|
||||
case VT_R4 : lVal = V_R4(left); 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_I1 : rVal = V_I1(right); break;
|
||||
case VT_I2 : rVal = V_I2(right); break;
|
||||
case VT_I4 :
|
||||
case VT_INT : rVal = V_I4(right); break;
|
||||
case VT_UI1 : rVal = V_UI1(right); break;
|
||||
case VT_UI2 : rVal = V_UI2(right); break;
|
||||
case VT_UI4 :
|
||||
case VT_UINT : rVal = V_UI4(right); break;
|
||||
case VT_R4 : rVal = V_R4(right);break;
|
||||
case VT_NULL : rVal = 0.0; break;
|
||||
default: rOk = FALSE;
|
||||
}
|
||||
|
@ -2832,7 +2832,7 @@ HRESULT WINAPI VarAdd(LPVARIANT left, LPVARIANT right, LPVARIANT result)
|
|||
if (lOk && rOk) {
|
||||
res = (lVal + rVal);
|
||||
V_VT(result) = VT_R4;
|
||||
V_UNION(result,fltVal) = res;
|
||||
V_R4(result) = res;
|
||||
rc = S_OK;
|
||||
} else {
|
||||
FIXME("Unhandled type pair %d / %d in float addition.\n",
|
||||
|
@ -2861,28 +2861,28 @@ HRESULT WINAPI VarAdd(LPVARIANT left, LPVARIANT right, LPVARIANT result)
|
|||
|
||||
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_I1 : lVal = V_I1(left); resT=VT_I4; break;
|
||||
case VT_I2 : lVal = V_I2(left); resT=VT_I2; break;
|
||||
case VT_I4 :
|
||||
case VT_INT : lVal = V_I4(left); resT=VT_I4; break;
|
||||
case VT_UI1 : lVal = V_UI1(left); resT=VT_I4; break;
|
||||
case VT_UI2 : lVal = V_UI2(left); resT=VT_I4; break;
|
||||
case VT_UI4 :
|
||||
case VT_UINT : lVal = V_UI4(left); 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_I1 : rVal = V_I1(right); resT=VT_I4; break;
|
||||
case VT_I2 : rVal = V_I2(right); resT=max(VT_I2, resT); break;
|
||||
case VT_I4 :
|
||||
case VT_INT : rVal = V_I4(right); resT=VT_I4; break;
|
||||
case VT_UI1 : rVal = V_UI1(right); resT=VT_I4; break;
|
||||
case VT_UI2 : rVal = V_UI2(right); resT=VT_I4; break;
|
||||
case VT_UI4 :
|
||||
case VT_UINT : rVal = V_UI4(right); resT=VT_I4; break;
|
||||
case VT_NULL : rVal = 0; resT=VT_I4; break;
|
||||
default: rOk = FALSE;
|
||||
}
|
||||
|
@ -2891,11 +2891,11 @@ HRESULT WINAPI VarAdd(LPVARIANT left, LPVARIANT right, LPVARIANT result)
|
|||
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;
|
||||
case VT_I2 : V_I2(result) = res; break;
|
||||
case VT_I4 : V_I4(result) = res; break;
|
||||
default:
|
||||
FIXME("Unexpected result variant type %x\n", resT);
|
||||
V_UNION(result,lVal) = res;
|
||||
V_I4(result) = res;
|
||||
}
|
||||
rc = S_OK;
|
||||
|
||||
|
@ -2927,11 +2927,11 @@ HRESULT WINAPI VarMul(LPVARIANT left, LPVARIANT right, LPVARIANT result)
|
|||
lvt = V_VT(left)&VT_TYPEMASK;
|
||||
rvt = V_VT(right)&VT_TYPEMASK;
|
||||
found = FALSE;resvt=VT_VOID;
|
||||
if (((1<<lvt) | (1<<rvt)) & ((1<<VT_R4)|(1<<VT_R8))) {
|
||||
if (((1<<lvt) | (1<<rvt)) & (VTBIT_R4|VTBIT_R8)) {
|
||||
found = TRUE;
|
||||
resvt = VT_R8;
|
||||
}
|
||||
if (!found && (((1<<lvt) | (1<<rvt)) & ((1<<VT_I1)|(1<<VT_I2)|(1<<VT_UI1)|(1<<VT_UI2)|(1<<VT_I4)|(1<<VT_UI4)|(1<<VT_INT)|(1<<VT_UINT)))) {
|
||||
if (!found && (((1<<lvt) | (1<<rvt)) & (VTBIT_I1|VTBIT_I2|VTBIT_UI1|VTBIT_UI2|VTBIT_I4|VTBIT_UI4|(1<<VT_INT)|(1<<VT_UINT)))) {
|
||||
found = TRUE;
|
||||
resvt = VT_I4;
|
||||
}
|
||||
|
@ -2984,11 +2984,11 @@ HRESULT WINAPI VarDiv(LPVARIANT left, LPVARIANT right, LPVARIANT result)
|
|||
lvt = V_VT(left)&VT_TYPEMASK;
|
||||
rvt = V_VT(right)&VT_TYPEMASK;
|
||||
found = FALSE;resvt = VT_VOID;
|
||||
if (((1<<lvt) | (1<<rvt)) & ((1<<VT_R4)|(1<<VT_R8))) {
|
||||
if (((1<<lvt) | (1<<rvt)) & (VTBIT_R4|VTBIT_R8)) {
|
||||
found = TRUE;
|
||||
resvt = VT_R8;
|
||||
}
|
||||
if (!found && (((1<<lvt) | (1<<rvt)) & ((1<<VT_I1)|(1<<VT_I2)|(1<<VT_UI1)|(1<<VT_UI2)|(1<<VT_I4)|(1<<VT_UI4)|(1<<VT_INT)|(1<<VT_UINT)))) {
|
||||
if (!found && (((1<<lvt) | (1<<rvt)) & (VTBIT_I1|VTBIT_I2|VTBIT_UI1|VTBIT_UI2|VTBIT_I4|VTBIT_UI4|(1<<VT_INT)|(1<<VT_UINT)))) {
|
||||
found = TRUE;
|
||||
resvt = VT_I4;
|
||||
}
|
||||
|
@ -3045,7 +3045,7 @@ HRESULT WINAPI VarSub(LPVARIANT left, LPVARIANT right, LPVARIANT result)
|
|||
found = TRUE;
|
||||
resvt = VT_R8;
|
||||
}
|
||||
if (!found && (((1<<lvt) | (1<<rvt)) & ((1<<VT_I1)|(1<<VT_I2)|(1<<VT_UI1)|(1<<VT_UI2)|(1<<VT_I4)|(1<<VT_UI4)|(1<<VT_INT)|(1<<VT_UINT)))) {
|
||||
if (!found && (((1<<lvt) | (1<<rvt)) & (VTBIT_I1|VTBIT_I2|VTBIT_UI1|VTBIT_UI2|VTBIT_I4|VTBIT_UI4|(1<<VT_INT)|(1<<VT_UINT)))) {
|
||||
found = TRUE;
|
||||
resvt = VT_I4;
|
||||
}
|
||||
|
|
|
@ -50,6 +50,8 @@
|
|||
#define V_ISARRAY(X) (V_VT(X)&VT_ARRAY)
|
||||
#define V_ISVECTOR(X) (V_VT(X)&VT_VECTOR)
|
||||
#define V_NONE(X) V_I2(X)
|
||||
#define V_INT(A) V_UNION(A,intVal)
|
||||
#define V_UINT(A) V_UNION(A,uintVal)
|
||||
#define V_UI1(X) V_UNION(X,bVal)
|
||||
#define V_UI1REF(X) V_UNION(X,pbVal)
|
||||
#define V_I2(X) V_UNION(X,iVal)
|
||||
|
@ -354,6 +356,8 @@ WINOLEAUTAPI VectorFromBstr (BSTR, SAFEARRAY **);
|
|||
WINOLEAUTAPI BstrFromVector (SAFEARRAY *, BSTR *);
|
||||
WINOLEAUTAPI VarParseNumFromStr(OLECHAR*,LCID,ULONG,NUMPARSE*,BYTE*);
|
||||
WINOLEAUTAPI VarNumFromParseNum(NUMPARSE*,BYTE*,ULONG,VARIANT*);
|
||||
WINOLEAUTAPI GetRecordInfoFromTypeInfo(ITypeInfo*,IRecordInfo**);
|
||||
WINOLEAUTAPI GetRecordInfoFromGuids(REFGUID,ULONG,ULONG,LCID,REFGUID,IRecordInfo**);
|
||||
|
||||
WINOLEAUTAPI VarAdd(LPVARIANT, LPVARIANT, LPVARIANT);
|
||||
WINOLEAUTAPI VarSub(LPVARIANT, LPVARIANT, LPVARIANT);
|
||||
|
|
|
@ -2106,6 +2106,7 @@
|
|||
#define DISP_E_NOTACOLLECTION ((HRESULT)0x80020011L)
|
||||
#define DISP_E_DIVBYZERO ((HRESULT)0x80020012L)
|
||||
#define TYPE_E_BUFFERTOOSMALL ((HRESULT)0x80028016L)
|
||||
#define TYPE_E_FIELDNOTFOUND ((HRESULT)0x80028017L)
|
||||
#define TYPE_E_INVDATAREAD ((HRESULT)0x80028018L)
|
||||
#define TYPE_E_UNSUPFORMAT ((HRESULT)0x80028019L)
|
||||
#define TYPE_E_REGISTRYACCESS ((HRESULT)0x8002801CL)
|
||||
|
|
Loading…
Reference in a new issue