From: Amine Khaldi Date: Tue, 29 Jan 2019 12:18:42 +0000 (+0100) Subject: [OLEAUT32] Sync with Wine Staging 4.0. CORE-15682 X-Git-Tag: 0.4.13-dev~537 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=5db885cae7050f46999387ffd88ea6b8a1d512be [OLEAUT32] Sync with Wine Staging 4.0. CORE-15682 --- diff --git a/dll/win32/oleaut32/CMakeLists.txt b/dll/win32/oleaut32/CMakeLists.txt index 26c2149a2af..1eae81ee810 100644 --- a/dll/win32/oleaut32/CMakeLists.txt +++ b/dll/win32/oleaut32/CMakeLists.txt @@ -25,7 +25,6 @@ list(APPEND SOURCE olepropframe.c recinfo.c safearray.c - tmarshal.c typelib.c usrmarshal.c varformat.c diff --git a/dll/win32/oleaut32/msvc.S b/dll/win32/oleaut32/msvc.S index ddb3fa8d6e6..0d088d3e8c8 100644 --- a/dll/win32/oleaut32/msvc.S +++ b/dll/win32/oleaut32/msvc.S @@ -49,6 +49,11 @@ cm1: pop esi pop ebp ret + +PUBLIC _call_double_method +_call_double_method: + jmp _call_method + #endif END diff --git a/dll/win32/oleaut32/oleaut.c b/dll/win32/oleaut32/oleaut.c index ee3ff27336d..8c5d68fee29 100644 --- a/dll/win32/oleaut32/oleaut.c +++ b/dll/win32/oleaut32/oleaut.c @@ -21,6 +21,7 @@ #include "config.h" #include +#include #include #include @@ -122,9 +123,7 @@ static inline bstr_t *bstr_from_str(BSTR str) static inline bstr_cache_entry_t *get_cache_entry_from_idx(unsigned cache_idx) { - return bstr_cache_enabled && cache_idx < sizeof(bstr_cache)/sizeof(*bstr_cache) - ? bstr_cache + cache_idx - : NULL; + return bstr_cache_enabled && cache_idx < ARRAY_SIZE(bstr_cache) ? bstr_cache + cache_idx : NULL; } static inline bstr_cache_entry_t *get_cache_entry(size_t size) @@ -272,7 +271,7 @@ static inline IMalloc *get_malloc(void) * See BSTR. * str may be NULL, in which case this function does nothing. */ -void WINAPI SysFreeString(BSTR str) +void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str) { bstr_cache_entry_t *cache_entry; bstr_t *bstr; @@ -304,7 +303,7 @@ void WINAPI SysFreeString(BSTR str) } } - if(cache_entry->cnt < sizeof(cache_entry->buf)/sizeof(*cache_entry->buf)) { + if(cache_entry->cnt < ARRAY_SIZE(cache_entry->buf)) { cache_entry->buf[(cache_entry->head+cache_entry->cnt) % BUCKET_BUFFER_SIZE] = bstr; cache_entry->cnt++; @@ -429,7 +428,7 @@ int WINAPI SysReAllocStringLen(BSTR* old, const OLECHAR* str, unsigned int len) * without checking for a terminating NUL. * See BSTR. */ -BSTR WINAPI SysAllocStringByteLen(LPCSTR str, UINT len) +BSTR WINAPI DECLSPEC_HOTPATCH SysAllocStringByteLen(LPCSTR str, UINT len) { bstr_t *bstr; @@ -768,6 +767,230 @@ extern BOOL WINAPI OLEAUTPS_DllMain(HINSTANCE, DWORD, LPVOID) DECLSPEC_HIDDEN; extern HRESULT WINAPI OLEAUTPS_DllRegisterServer(void) DECLSPEC_HIDDEN; extern HRESULT WINAPI OLEAUTPS_DllUnregisterServer(void) DECLSPEC_HIDDEN; +extern HRESULT WINAPI CreateProxyFromTypeInfo(ITypeInfo *typeinfo, + IUnknown *outer, REFIID iid, IRpcProxyBuffer **proxy, void **obj); +extern HRESULT WINAPI CreateStubFromTypeInfo(ITypeInfo *typeinfo, REFIID iid, + IUnknown *server, IRpcStubBuffer **stub); + +struct ifacepsredirect_data +{ + ULONG size; + DWORD mask; + GUID iid; + ULONG nummethods; + GUID tlbid; + GUID base; + ULONG name_len; + ULONG name_offset; +}; + +struct tlibredirect_data +{ + ULONG size; + DWORD res; + ULONG name_len; + ULONG name_offset; + LANGID langid; + WORD flags; + ULONG help_len; + ULONG help_offset; + WORD major_version; + WORD minor_version; +}; + +static BOOL actctx_get_typelib_module(REFIID iid, WCHAR *module, DWORD len) +{ + struct ifacepsredirect_data *iface; + struct tlibredirect_data *tlib; + ACTCTX_SECTION_KEYED_DATA data; + WCHAR *ptrW; + + data.cbSize = sizeof(data); + if (!FindActCtxSectionGuid(0, NULL, ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION, + iid, &data)) + return FALSE; + + iface = (struct ifacepsredirect_data *)data.lpData; + if (!FindActCtxSectionGuid(0, NULL, ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION, + &iface->tlbid, &data)) + return FALSE; + + tlib = (struct tlibredirect_data *)data.lpData; + ptrW = (WCHAR *)((BYTE *)data.lpSectionBase + tlib->name_offset); + + if (tlib->name_len/sizeof(WCHAR) >= len) + { + ERR("need larger module buffer, %u\n", tlib->name_len); + return FALSE; + } + + memcpy(module, ptrW, tlib->name_len); + module[tlib->name_len/sizeof(WCHAR)] = 0; + return TRUE; +} + +static HRESULT reg_get_typelib_module(REFIID iid, WCHAR *module, DWORD len) +{ + REGSAM opposite = (sizeof(void*) == 8) ? KEY_WOW64_32KEY : KEY_WOW64_64KEY; + char tlguid[200], typelibkey[300], interfacekey[300], ver[100], tlfn[260]; + DWORD tlguidlen, verlen, type; + LONG tlfnlen, err; + BOOL is_wow64; + HKEY ikey; + + sprintf( interfacekey, "Interface\\{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\Typelib", + iid->Data1, iid->Data2, iid->Data3, + iid->Data4[0], iid->Data4[1], iid->Data4[2], iid->Data4[3], + iid->Data4[4], iid->Data4[5], iid->Data4[6], iid->Data4[7] + ); + + err = RegOpenKeyExA(HKEY_CLASSES_ROOT,interfacekey,0,KEY_READ,&ikey); + if (err && (opposite == KEY_WOW64_32KEY || (IsWow64Process(GetCurrentProcess(), &is_wow64) + && is_wow64))) + err = RegOpenKeyExA(HKEY_CLASSES_ROOT,interfacekey,0,KEY_READ|opposite,&ikey); + + if (err) + { + ERR("No %s key found.\n", interfacekey); + return E_FAIL; + } + + tlguidlen = sizeof(tlguid); + if (RegQueryValueExA(ikey, NULL, NULL, &type, (BYTE *)tlguid, &tlguidlen)) + { + ERR("Getting typelib guid failed.\n"); + RegCloseKey(ikey); + return E_FAIL; + } + + verlen = sizeof(ver); + if (RegQueryValueExA(ikey, "Version", NULL, &type, (BYTE *)ver, &verlen)) + { + ERR("Could not get version value?\n"); + RegCloseKey(ikey); + return E_FAIL; + } + + RegCloseKey(ikey); + + sprintf(typelibkey, "Typelib\\%s\\%s\\0\\win%u", tlguid, ver, sizeof(void *) == 8 ? 64 : 32); + tlfnlen = sizeof(tlfn); + if (RegQueryValueA(HKEY_CLASSES_ROOT, typelibkey, tlfn, &tlfnlen)) + { +#ifdef _WIN64 + sprintf(typelibkey, "Typelib\\%s\\%s\\0\\win32", tlguid, ver); + tlfnlen = sizeof(tlfn); + if (RegQueryValueA(HKEY_CLASSES_ROOT, typelibkey, tlfn, &tlfnlen)) + { +#endif + ERR("Could not get typelib fn?\n"); + return E_FAIL; +#ifdef _WIN64 + } +#endif + } + MultiByteToWideChar(CP_ACP, 0, tlfn, -1, module, len); + return S_OK; +} + +static HRESULT get_typeinfo_for_iid(REFIID iid, ITypeInfo **typeinfo) +{ + WCHAR module[MAX_PATH]; + ITypeLib *typelib; + HRESULT hr; + + *typeinfo = NULL; + + module[0] = 0; + if (!actctx_get_typelib_module(iid, module, ARRAY_SIZE(module))) + { + hr = reg_get_typelib_module(iid, module, ARRAY_SIZE(module)); + if (FAILED(hr)) + return hr; + } + + hr = LoadTypeLib(module, &typelib); + if (hr != S_OK) { + ERR("Failed to load typelib for %s, but it should be there.\n", debugstr_guid(iid)); + return hr; + } + + hr = ITypeLib_GetTypeInfoOfGuid(typelib, iid, typeinfo); + ITypeLib_Release(typelib); + if (hr != S_OK) + ERR("typelib does not contain info for %s\n", debugstr_guid(iid)); + + return hr; +} + +static HRESULT WINAPI typelib_ps_QueryInterface(IPSFactoryBuffer *iface, REFIID iid, void **out) +{ + if (IsEqualIID(iid, &IID_IPSFactoryBuffer) || IsEqualIID(iid, &IID_IUnknown)) + { + *out = iface; + return S_OK; + } + + FIXME("No interface for %s.\n", debugstr_guid(iid)); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI typelib_ps_AddRef(IPSFactoryBuffer *iface) +{ + return 2; +} + +static ULONG WINAPI typelib_ps_Release(IPSFactoryBuffer *iface) +{ + return 1; +} + +static HRESULT WINAPI typelib_ps_CreateProxy(IPSFactoryBuffer *iface, + IUnknown *outer, REFIID iid, IRpcProxyBuffer **proxy, void **out) +{ + ITypeInfo *typeinfo; + HRESULT hr; + + hr = get_typeinfo_for_iid(iid, &typeinfo); + if (FAILED(hr)) return hr; + + hr = CreateProxyFromTypeInfo(typeinfo, outer, iid, proxy, out); + if (FAILED(hr)) + ERR("Failed to create proxy, hr %#x.\n", hr); + + ITypeInfo_Release(typeinfo); + return hr; +} + +static HRESULT WINAPI typelib_ps_CreateStub(IPSFactoryBuffer *iface, REFIID iid, + IUnknown *server, IRpcStubBuffer **stub) +{ + ITypeInfo *typeinfo; + HRESULT hr; + + hr = get_typeinfo_for_iid(iid, &typeinfo); + if (FAILED(hr)) return hr; + + hr = CreateStubFromTypeInfo(typeinfo, iid, server, stub); + if (FAILED(hr)) + ERR("Failed to create stub, hr %#x.\n", hr); + + ITypeInfo_Release(typeinfo); + return hr; +} + +static const IPSFactoryBufferVtbl typelib_ps_vtbl = +{ + typelib_ps_QueryInterface, + typelib_ps_AddRef, + typelib_ps_Release, + typelib_ps_CreateProxy, + typelib_ps_CreateStub, +}; + +static IPSFactoryBuffer typelib_ps = { &typelib_ps_vtbl }; + extern void _get_STDFONT_CF(LPVOID *); extern void _get_STDPIC_CF(LPVOID *); @@ -793,40 +1016,42 @@ static ULONG WINAPI PSDispatchFacBuf_Release(IPSFactoryBuffer *iface) return 1; } -static HRESULT WINAPI PSDispatchFacBuf_CreateProxy(IPSFactoryBuffer *iface, IUnknown *pUnkOuter, REFIID riid, IRpcProxyBuffer **ppProxy, void **ppv) +static HRESULT WINAPI PSDispatchFacBuf_CreateProxy(IPSFactoryBuffer *iface, + IUnknown *outer, REFIID iid, IRpcProxyBuffer **proxy, void **obj) { - IPSFactoryBuffer *pPSFB; + IPSFactoryBuffer *factory; HRESULT hr; - if (IsEqualIID(riid, &IID_IDispatch)) - hr = OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer, &IID_IPSFactoryBuffer, (void **)&pPSFB); - else - hr = TMARSHAL_DllGetClassObject(&CLSID_PSOAInterface, &IID_IPSFactoryBuffer, (void **)&pPSFB); - - if (FAILED(hr)) return hr; - - hr = IPSFactoryBuffer_CreateProxy(pPSFB, pUnkOuter, riid, ppProxy, ppv); + if (IsEqualIID(iid, &IID_IDispatch)) + { + hr = OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer, &IID_IPSFactoryBuffer, (void **)&factory); + if (FAILED(hr)) return hr; - IPSFactoryBuffer_Release(pPSFB); - return hr; + hr = IPSFactoryBuffer_CreateProxy(factory, outer, iid, proxy, obj); + IPSFactoryBuffer_Release(factory); + return hr; + } + else + return IPSFactoryBuffer_CreateProxy(&typelib_ps, outer, iid, proxy, obj); } -static HRESULT WINAPI PSDispatchFacBuf_CreateStub(IPSFactoryBuffer *iface, REFIID riid, IUnknown *pUnkOuter, IRpcStubBuffer **ppStub) +static HRESULT WINAPI PSDispatchFacBuf_CreateStub(IPSFactoryBuffer *iface, + REFIID iid, IUnknown *server, IRpcStubBuffer **stub) { - IPSFactoryBuffer *pPSFB; + IPSFactoryBuffer *factory; HRESULT hr; - if (IsEqualIID(riid, &IID_IDispatch)) - hr = OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer, &IID_IPSFactoryBuffer, (void **)&pPSFB); - else - hr = TMARSHAL_DllGetClassObject(&CLSID_PSOAInterface, &IID_IPSFactoryBuffer, (void **)&pPSFB); - - if (FAILED(hr)) return hr; - - hr = IPSFactoryBuffer_CreateStub(pPSFB, riid, pUnkOuter, ppStub); + if (IsEqualIID(iid, &IID_IDispatch)) + { + hr = OLEAUTPS_DllGetClassObject(&CLSID_PSFactoryBuffer, &IID_IPSFactoryBuffer, (void **)&factory); + if (FAILED(hr)) return hr; - IPSFactoryBuffer_Release(pPSFB); - return hr; + hr = IPSFactoryBuffer_CreateStub(factory, iid, server, stub); + IPSFactoryBuffer_Release(factory); + return hr; + } + else + return IPSFactoryBuffer_CreateStub(&typelib_ps, iid, server, stub); } static const IPSFactoryBufferVtbl PSDispatchFacBuf_Vtbl = @@ -866,11 +1091,10 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv) IPSFactoryBuffer_AddRef((IPSFactoryBuffer *)*ppv); return S_OK; } - if (IsEqualGUID(rclsid,&CLSID_PSOAInterface)) { - if (S_OK==TMARSHAL_DllGetClassObject(rclsid,iid,ppv)) - return S_OK; - /*FALLTHROUGH*/ - } + + if (IsEqualGUID(rclsid, &CLSID_PSOAInterface)) + return IPSFactoryBuffer_QueryInterface(&typelib_ps, iid, ppv); + if (IsEqualCLSID(rclsid, &CLSID_PSTypeComp) || IsEqualCLSID(rclsid, &CLSID_PSTypeInfo) || IsEqualCLSID(rclsid, &CLSID_PSTypeLib) || diff --git a/dll/win32/oleaut32/olefont.c b/dll/win32/oleaut32/olefont.c index c20093c7023..9628dc091e9 100644 --- a/dll/win32/oleaut32/olefont.c +++ b/dll/win32/oleaut32/olefont.c @@ -591,7 +591,7 @@ static void realize_font(OLEFontImpl *This) if(This->gdiFont) { old_font = SelectObject(hdc, This->gdiFont); - GetTextFaceW(hdc, sizeof(text_face) / sizeof(text_face[0]), text_face); + GetTextFaceW(hdc, ARRAY_SIZE(text_face), text_face); SelectObject(hdc, old_font); dec_int_ref(This->gdiFont); This->gdiFont = 0; @@ -645,7 +645,7 @@ static void realize_font(OLEFontImpl *This) /* Fixup the name and charset properties so that they match the selected font */ old_font = SelectObject(get_dc(), This->gdiFont); - GetTextFaceW(hdc, sizeof(text_face) / sizeof(text_face[0]), text_face); + GetTextFaceW(hdc, ARRAY_SIZE(text_face), text_face); if(lstrcmpiW(text_face, This->description.lpstrName)) { HeapFree(GetProcessHeap(), 0, This->description.lpstrName); diff --git a/dll/win32/oleaut32/olepicture.c b/dll/win32/oleaut32/olepicture.c index 96304e06446..702fcde86de 100644 --- a/dll/win32/oleaut32/olepicture.c +++ b/dll/win32/oleaut32/olepicture.c @@ -287,9 +287,10 @@ static void OLEPictureImpl_SetEMF(OLEPictureImpl *This) * The caller of this method must release the object when it's * done with it. */ -static OLEPictureImpl* OLEPictureImpl_Construct(LPPICTDESC pictDesc, BOOL fOwn) +static HRESULT OLEPictureImpl_Construct(LPPICTDESC pictDesc, BOOL fOwn, OLEPictureImpl **pict) { - OLEPictureImpl* newObject = 0; + OLEPictureImpl *newObject; + HRESULT hr; if (pictDesc) TRACE("(%p) type = %d\n", pictDesc, pictDesc->picType); @@ -298,9 +299,8 @@ static OLEPictureImpl* OLEPictureImpl_Construct(LPPICTDESC pictDesc, BOOL fOwn) * Allocate space for the object. */ newObject = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(OLEPictureImpl)); - - if (newObject==0) - return newObject; + if (!newObject) + return E_OUTOFMEMORY; /* * Initialize the virtual function table. @@ -311,12 +311,12 @@ static OLEPictureImpl* OLEPictureImpl_Construct(LPPICTDESC pictDesc, BOOL fOwn) newObject->IConnectionPointContainer_iface.lpVtbl = &OLEPictureImpl_IConnectionPointContainer_VTable; newObject->pCP = NULL; - CreateConnectionPoint((IUnknown*)&newObject->IPicture_iface, &IID_IPropertyNotifySink, + hr = CreateConnectionPoint((IUnknown*)&newObject->IPicture_iface, &IID_IPropertyNotifySink, &newObject->pCP); - if (!newObject->pCP) + if (hr != S_OK) { HeapFree(GetProcessHeap(), 0, newObject); - return NULL; + return hr; } /* @@ -365,16 +365,17 @@ static OLEPictureImpl* OLEPictureImpl_Construct(LPPICTDESC pictDesc, BOOL fOwn) break; default: - FIXME("Unsupported type %d\n", pictDesc->picType); - newObject->himetricWidth = newObject->himetricHeight = 0; - break; + WARN("Unsupported type %d\n", pictDesc->picType); + IPicture_Release(&newObject->IPicture_iface); + return E_UNEXPECTED; } } else { newObject->desc.picType = PICTYPE_UNINITIALIZED; } TRACE("returning %p\n", newObject); - return newObject; + *pict = newObject; + return S_OK; } /************************************************************************ @@ -565,37 +566,19 @@ static HRESULT WINAPI OLEPictureImpl_get_Handle(IPicture *iface, static HRESULT WINAPI OLEPictureImpl_get_hPal(IPicture *iface, OLE_HANDLE *phandle) { - OLEPictureImpl *This = impl_from_IPicture(iface); - HRESULT hres; - TRACE("(%p)->(%p)\n", This, phandle); + OLEPictureImpl *This = impl_from_IPicture(iface); - if (!phandle) - return E_POINTER; + TRACE("(%p)->(%p)\n", This, phandle); - switch (This->desc.picType) { - case (UINT)PICTYPE_UNINITIALIZED: - case PICTYPE_NONE: - *phandle = 0; - hres = S_FALSE; - break; - case PICTYPE_BITMAP: - *phandle = HandleToUlong(This->desc.u.bmp.hpal); - hres = S_OK; - break; - case PICTYPE_METAFILE: - hres = E_FAIL; - break; - case PICTYPE_ICON: - case PICTYPE_ENHMETAFILE: - default: - FIXME("unimplemented for type %d. Returning 0 palette.\n", - This->desc.picType); - *phandle = 0; - hres = S_OK; - } + if (!phandle) return E_POINTER; - TRACE("returning 0x%08x, palette handle %08x\n", hres, *phandle); - return hres; + if (This->desc.picType == PICTYPE_BITMAP) + { + *phandle = HandleToUlong(This->desc.u.bmp.hpal); + return S_OK; + } + + return E_FAIL; } /************************************************************************ @@ -638,6 +621,48 @@ static HRESULT WINAPI OLEPictureImpl_get_Height(IPicture *iface, return S_OK; } +static void render_masked_bitmap(OLEPictureImpl *This, HDC hdc, + LONG x, LONG y, LONG cx, LONG cy, OLE_XPOS_HIMETRIC xSrc, OLE_YPOS_HIMETRIC ySrc, + OLE_XSIZE_HIMETRIC cxSrc, OLE_YSIZE_HIMETRIC cySrc, HBITMAP hbmMask, HBITMAP hbmXor) +{ + HDC hdcBmp; + + /* Set a mapping mode that maps bitmap pixels into HIMETRIC units. + * NB y-axis gets flipped + */ + + hdcBmp = CreateCompatibleDC(0); + SetMapMode(hdcBmp, MM_ANISOTROPIC); + SetWindowOrgEx(hdcBmp, 0, 0, NULL); + SetWindowExtEx(hdcBmp, This->himetricWidth, This->himetricHeight, NULL); + SetViewportOrgEx(hdcBmp, 0, This->origHeight, NULL); + SetViewportExtEx(hdcBmp, This->origWidth, -This->origHeight, NULL); + + if (hbmMask) + { + SetBkColor(hdc, RGB(255, 255, 255)); + SetTextColor(hdc, RGB(0, 0, 0)); + + SelectObject(hdcBmp, hbmMask); + StretchBlt(hdc, x, y, cx, cy, hdcBmp, xSrc, ySrc, cxSrc, cySrc, SRCAND); + + if (hbmXor) + { + SelectObject(hdcBmp, hbmXor); + StretchBlt(hdc, x, y, cx, cy, hdcBmp, xSrc, ySrc, cxSrc, cySrc, SRCPAINT); + } + else StretchBlt(hdc, x, y, cx, cy, hdcBmp, xSrc, ySrc - This->himetricHeight, + cxSrc, cySrc, SRCPAINT); + } + else + { + SelectObject(hdcBmp, hbmXor); + StretchBlt(hdc, x, y, cx, cy, hdcBmp, xSrc, ySrc, cxSrc, cySrc, SRCCOPY); + } + + DeleteDC(hdcBmp); +} + /************************************************************************ * OLEPictureImpl_Render */ @@ -671,52 +696,37 @@ static HRESULT WINAPI OLEPictureImpl_Render(IPicture *iface, HDC hdc, /* nothing to do */ return S_OK; case PICTYPE_BITMAP: - { - HBITMAP hbmpOld; - HDC hdcBmp; - - /* Set a mapping mode that maps bitmap pixels into HIMETRIC units. - NB y-axis gets flipped */ - - hdcBmp = CreateCompatibleDC(0); - SetMapMode(hdcBmp, MM_ANISOTROPIC); - SetWindowOrgEx(hdcBmp, 0, 0, NULL); - SetWindowExtEx(hdcBmp, This->himetricWidth, This->himetricHeight, NULL); - SetViewportOrgEx(hdcBmp, 0, This->origHeight, NULL); - SetViewportExtEx(hdcBmp, This->origWidth, -This->origHeight, NULL); - - if (This->hbmMask) { - HDC hdcMask = CreateCompatibleDC(0); - HBITMAP hOldbm = SelectObject(hdcMask, This->hbmMask); - - hbmpOld = SelectObject(hdcBmp, This->hbmXor); - - SetMapMode(hdcMask, MM_ANISOTROPIC); - SetWindowOrgEx(hdcMask, 0, 0, NULL); - SetWindowExtEx(hdcMask, This->himetricWidth, This->himetricHeight, NULL); - SetViewportOrgEx(hdcMask, 0, This->origHeight, NULL); - SetViewportExtEx(hdcMask, This->origWidth, -This->origHeight, NULL); - - SetBkColor(hdc, RGB(255, 255, 255)); - SetTextColor(hdc, RGB(0, 0, 0)); - StretchBlt(hdc, x, y, cx, cy, hdcMask, xSrc, ySrc, cxSrc, cySrc, SRCAND); - StretchBlt(hdc, x, y, cx, cy, hdcBmp, xSrc, ySrc, cxSrc, cySrc, SRCPAINT); - - SelectObject(hdcMask, hOldbm); - DeleteDC(hdcMask); - } else { - hbmpOld = SelectObject(hdcBmp, This->desc.u.bmp.hbitmap); - StretchBlt(hdc, x, y, cx, cy, hdcBmp, xSrc, ySrc, cxSrc, cySrc, SRCCOPY); - } + { + HBITMAP hbmMask, hbmXor; - SelectObject(hdcBmp, hbmpOld); - DeleteDC(hdcBmp); + if (This->hbmMask) + { + hbmMask = This->hbmMask; + hbmXor = This->hbmXor; } + else + { + hbmMask = 0; + hbmXor = This->desc.u.bmp.hbitmap; + } + + render_masked_bitmap(This, hdc, x, y, cx, cy, xSrc, ySrc, cxSrc, cySrc, hbmMask, hbmXor); break; + } + case PICTYPE_ICON: - FIXME("Not quite correct implementation of rendering icons...\n"); - DrawIconEx(hdc, x, y, This->desc.u.icon.hicon, cx, cy, 0, NULL, DI_NORMAL); + { + ICONINFO info; + + if (!GetIconInfo(This->desc.u.icon.hicon, &info)) + return E_FAIL; + + render_masked_bitmap(This, hdc, x, y, cx, cy, xSrc, ySrc, cxSrc, cySrc, info.hbmMask, info.hbmColor); + + DeleteObject(info.hbmMask); + if (info.hbmColor) DeleteObject(info.hbmColor); break; + } case PICTYPE_METAFILE: { @@ -767,10 +777,18 @@ static HRESULT WINAPI OLEPictureImpl_Render(IPicture *iface, HDC hdc, static HRESULT WINAPI OLEPictureImpl_set_hPal(IPicture *iface, OLE_HANDLE hpal) { - OLEPictureImpl *This = impl_from_IPicture(iface); - FIXME("(%p)->(%08x): stub\n", This, hpal); - OLEPicture_SendNotify(This,DISPID_PICT_HPAL); - return E_NOTIMPL; + OLEPictureImpl *This = impl_from_IPicture(iface); + + TRACE("(%p)->(%08x)\n", This, hpal); + + if (This->desc.picType == PICTYPE_BITMAP) + { + This->desc.u.bmp.hpal = ULongToHandle(hpal); + OLEPicture_SendNotify(This,DISPID_PICT_HPAL); + return S_OK; + } + + return E_FAIL; } /************************************************************************ @@ -2310,10 +2328,8 @@ HRESULT WINAPI OleCreatePictureIndirect(LPPICTDESC lpPictDesc, REFIID riid, *ppvObj = NULL; - newPict = OLEPictureImpl_Construct(lpPictDesc, Own); - - if (newPict == NULL) - return E_OUTOFMEMORY; + hr = OLEPictureImpl_Construct(lpPictDesc, Own, &newPict); + if (hr != S_OK) return hr; /* * Make sure it supports the interface required by the caller. @@ -2509,7 +2525,7 @@ HRESULT WINAPI OleLoadPicturePath( LPOLESTR szURLorPath, LPUNKNOWN punkCaller, if (strncmpW(szURLorPath, file, 5) == 0) { DWORD size; hRes = CoInternetParseUrl(szURLorPath, PARSE_PATH_FROM_URL, 0, path_buf, - sizeof(path_buf)/sizeof(WCHAR), &size, 0); + ARRAY_SIZE(path_buf), &size, 0); if (FAILED(hRes)) return hRes; diff --git a/dll/win32/oleaut32/safearray.c b/dll/win32/oleaut32/safearray.c index 01dbfc34178..64a5ab94d5d 100644 --- a/dll/win32/oleaut32/safearray.c +++ b/dll/win32/oleaut32/safearray.c @@ -289,7 +289,7 @@ static HRESULT SAFEARRAY_DestroyData(SAFEARRAY *psa, ULONG ulStartCell) ULONG ulCellCount = SAFEARRAY_GetCellCount(psa); if (ulStartCell > ulCellCount) { - FIXME("unexpted ulcellcount %d, start %d\n",ulCellCount,ulStartCell); + FIXME("unexpected ulCellCount %d, start %d\n",ulCellCount,ulStartCell); return E_UNEXPECTED; } diff --git a/dll/win32/oleaut32/tmarshal.c b/dll/win32/oleaut32/tmarshal.c deleted file mode 100644 index 7530f66c9b7..00000000000 --- a/dll/win32/oleaut32/tmarshal.c +++ /dev/null @@ -1,2480 +0,0 @@ -/* - * TYPELIB Marshaler - * - * Copyright 2002,2005 Marcus Meissner - * - * The olerelay debug channel allows you to see calls marshalled by - * the typelib marshaller. It is not a generic COM relaying system. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" -#include "wine/port.h" - -#include -#include -#include -#include -#include -#include - -#define COBJMACROS -#define NONAMELESSUNION - -#include "winerror.h" -#include "windef.h" -#include "winbase.h" -#include "winnls.h" -#include "winreg.h" -#include "winuser.h" - -#include "ole2.h" -#include "propidl.h" /* for LPSAFEARRAY_User* functions */ -#include "typelib.h" -#include "variant.h" -#include "wine/debug.h" -#include "wine/exception.h" - -static const WCHAR IDispatchW[] = { 'I','D','i','s','p','a','t','c','h',0}; - -WINE_DEFAULT_DEBUG_CHANNEL(ole); -WINE_DECLARE_DEBUG_CHANNEL(olerelay); - -static HRESULT TMarshalDispatchChannel_Create( - IRpcChannelBuffer *pDelegateChannel, REFIID tmarshal_riid, - IRpcChannelBuffer **ppChannel); - -typedef struct _marshal_state { - LPBYTE base; - int size; - int curoff; -} marshal_state; - -/* used in the olerelay code to avoid having the L"" stuff added by debugstr_w */ -static char *relaystr(WCHAR *in) { - char *tmp = (char *)debugstr_w(in); - tmp += 2; - tmp[strlen(tmp)-1] = '\0'; - return tmp; -} - -static HRESULT -xbuf_resize(marshal_state *buf, DWORD newsize) -{ - if(buf->size >= newsize) - return S_FALSE; - - if(buf->base) - { - newsize = max(newsize, buf->size * 2); - buf->base = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, buf->base, newsize); - if(!buf->base) - return E_OUTOFMEMORY; - } - else - { - newsize = max(newsize, 256); - buf->base = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, newsize); - if(!buf->base) - return E_OUTOFMEMORY; - } - buf->size = newsize; - return S_OK; -} - -static HRESULT -xbuf_add(marshal_state *buf, const BYTE *stuff, DWORD size) -{ - HRESULT hr; - - if(buf->size - buf->curoff < size) - { - hr = xbuf_resize(buf, buf->size + size); - if(FAILED(hr)) return hr; - } - memcpy(buf->base+buf->curoff,stuff,size); - buf->curoff += size; - return S_OK; -} - -static HRESULT -xbuf_get(marshal_state *buf, LPBYTE stuff, DWORD size) { - if (buf->size < buf->curoff+size) return E_FAIL; - memcpy(stuff,buf->base+buf->curoff,size); - buf->curoff += size; - return S_OK; -} - -static HRESULT -xbuf_skip(marshal_state *buf, DWORD size) { - if (buf->size < buf->curoff+size) return E_FAIL; - buf->curoff += size; - return S_OK; -} - -static HRESULT -_unmarshal_interface(marshal_state *buf, REFIID riid, LPUNKNOWN *pUnk) { - IStream *pStm; - ULARGE_INTEGER newpos; - LARGE_INTEGER seekto; - ULONG res; - HRESULT hres; - DWORD xsize; - - TRACE("...%s...\n",debugstr_guid(riid)); - - *pUnk = NULL; - hres = xbuf_get(buf,(LPBYTE)&xsize,sizeof(xsize)); - if (hres) { - ERR("xbuf_get failed\n"); - return hres; - } - - if (xsize == 0) return S_OK; - - hres = CreateStreamOnHGlobal(0,TRUE,&pStm); - if (hres) { - ERR("Stream create failed %x\n",hres); - return hres; - } - - hres = IStream_Write(pStm,buf->base+buf->curoff,xsize,&res); - if (hres) { - ERR("stream write %x\n",hres); - IStream_Release(pStm); - return hres; - } - - memset(&seekto,0,sizeof(seekto)); - hres = IStream_Seek(pStm,seekto,SEEK_SET,&newpos); - if (hres) { - ERR("Failed Seek %x\n",hres); - IStream_Release(pStm); - return hres; - } - - hres = CoUnmarshalInterface(pStm,riid,(LPVOID*)pUnk); - if (hres) { - ERR("Unmarshalling interface %s failed with %x\n",debugstr_guid(riid),hres); - IStream_Release(pStm); - return hres; - } - - IStream_Release(pStm); - return xbuf_skip(buf,xsize); -} - -static HRESULT -_marshal_interface(marshal_state *buf, REFIID riid, LPUNKNOWN pUnk) { - LPBYTE tempbuf = NULL; - IStream *pStm = NULL; - STATSTG ststg; - ULARGE_INTEGER newpos; - LARGE_INTEGER seekto; - ULONG res; - DWORD xsize; - HRESULT hres; - - if (!pUnk) { - /* this is valid, if for instance we serialize - * a VT_DISPATCH with NULL ptr which apparently - * can happen. S_OK to make sure we continue - * serializing. - */ - WARN("pUnk is NULL\n"); - xsize = 0; - return xbuf_add(buf,(LPBYTE)&xsize,sizeof(xsize)); - } - - TRACE("...%s...\n",debugstr_guid(riid)); - - hres = CreateStreamOnHGlobal(0,TRUE,&pStm); - if (hres) { - ERR("Stream create failed %x\n",hres); - goto fail; - } - - hres = CoMarshalInterface(pStm,riid,pUnk,0,NULL,0); - if (hres) { - ERR("Marshalling interface %s failed with %x\n", debugstr_guid(riid), hres); - goto fail; - } - - hres = IStream_Stat(pStm,&ststg,STATFLAG_NONAME); - if (hres) { - ERR("Stream stat failed\n"); - goto fail; - } - - tempbuf = HeapAlloc(GetProcessHeap(), 0, ststg.cbSize.u.LowPart); - memset(&seekto,0,sizeof(seekto)); - hres = IStream_Seek(pStm,seekto,SEEK_SET,&newpos); - if (hres) { - ERR("Failed Seek %x\n",hres); - goto fail; - } - - hres = IStream_Read(pStm,tempbuf,ststg.cbSize.u.LowPart,&res); - if (hres) { - ERR("Failed Read %x\n",hres); - goto fail; - } - - xsize = ststg.cbSize.u.LowPart; - xbuf_add(buf,(LPBYTE)&xsize,sizeof(xsize)); - hres = xbuf_add(buf,tempbuf,ststg.cbSize.u.LowPart); - - HeapFree(GetProcessHeap(),0,tempbuf); - IStream_Release(pStm); - - return hres; - -fail: - xsize = 0; - xbuf_add(buf,(LPBYTE)&xsize,sizeof(xsize)); - if (pStm) IStream_Release(pStm); - HeapFree(GetProcessHeap(), 0, tempbuf); - return hres; -} - -/********************* OLE Proxy/Stub Factory ********************************/ -static HRESULT WINAPI -PSFacBuf_QueryInterface(LPPSFACTORYBUFFER iface, REFIID iid, LPVOID *ppv) { - if (IsEqualIID(iid,&IID_IPSFactoryBuffer)||IsEqualIID(iid,&IID_IUnknown)) { - *ppv = iface; - /* No ref counting, static class */ - return S_OK; - } - FIXME("(%s) unknown IID?\n",debugstr_guid(iid)); - return E_NOINTERFACE; -} - -static ULONG WINAPI PSFacBuf_AddRef(LPPSFACTORYBUFFER iface) { return 2; } -static ULONG WINAPI PSFacBuf_Release(LPPSFACTORYBUFFER iface) { return 1; } - -struct ifacepsredirect_data -{ - ULONG size; - DWORD mask; - GUID iid; - ULONG nummethods; - GUID tlbid; - GUID base; - ULONG name_len; - ULONG name_offset; -}; - -struct tlibredirect_data -{ - ULONG size; - DWORD res; - ULONG name_len; - ULONG name_offset; - LANGID langid; - WORD flags; - ULONG help_len; - ULONG help_offset; - WORD major_version; - WORD minor_version; -}; - -static BOOL actctx_get_typelib_module(REFIID riid, WCHAR *module, DWORD len) -{ - struct ifacepsredirect_data *iface; - struct tlibredirect_data *tlib; - ACTCTX_SECTION_KEYED_DATA data; - WCHAR *ptrW; - - data.cbSize = sizeof(data); - if (!FindActCtxSectionGuid(0, NULL, ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION, - riid, &data)) - return FALSE; - - iface = (struct ifacepsredirect_data*)data.lpData; - if (!FindActCtxSectionGuid(0, NULL, ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION, - &iface->tlbid, &data)) - return FALSE; - - tlib = (struct tlibredirect_data*)data.lpData; - ptrW = (WCHAR*)((BYTE*)data.lpSectionBase + tlib->name_offset); - - if (tlib->name_len/sizeof(WCHAR) >= len) { - ERR("need larger module buffer, %u\n", tlib->name_len); - return FALSE; - } - - memcpy(module, ptrW, tlib->name_len); - module[tlib->name_len/sizeof(WCHAR)] = 0; - return TRUE; -} - -static HRESULT reg_get_typelib_module(REFIID riid, WCHAR *module, DWORD len) -{ - HKEY ikey; - REGSAM opposite = (sizeof(void*) == 8) ? KEY_WOW64_32KEY : KEY_WOW64_64KEY; - BOOL is_wow64; - char tlguid[200],typelibkey[300],interfacekey[300],ver[100]; - char tlfn[260]; - DWORD tlguidlen, verlen, type; - LONG tlfnlen, err; - - sprintf( interfacekey, "Interface\\{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\Typelib", - riid->Data1, riid->Data2, riid->Data3, - riid->Data4[0], riid->Data4[1], riid->Data4[2], riid->Data4[3], - riid->Data4[4], riid->Data4[5], riid->Data4[6], riid->Data4[7] - ); - - err = RegOpenKeyExA(HKEY_CLASSES_ROOT,interfacekey,0,KEY_READ,&ikey); - if (err && (opposite == KEY_WOW64_32KEY || (IsWow64Process(GetCurrentProcess(), &is_wow64) - && is_wow64))) { - err = RegOpenKeyExA(HKEY_CLASSES_ROOT,interfacekey,0,KEY_READ|opposite,&ikey); - } - if (err) { - ERR("No %s key found.\n",interfacekey); - return E_FAIL; - } - tlguidlen = sizeof(tlguid); - if (RegQueryValueExA(ikey,NULL,NULL,&type,(LPBYTE)tlguid,&tlguidlen)) { - ERR("Getting typelib guid failed.\n"); - RegCloseKey(ikey); - return E_FAIL; - } - verlen = sizeof(ver); - if (RegQueryValueExA(ikey,"Version",NULL,&type,(LPBYTE)ver,&verlen)) { - ERR("Could not get version value?\n"); - RegCloseKey(ikey); - return E_FAIL; - } - RegCloseKey(ikey); - sprintf(typelibkey,"Typelib\\%s\\%s\\0\\win%u",tlguid,ver,(sizeof(void*) == 8) ? 64 : 32); - tlfnlen = sizeof(tlfn); - if (RegQueryValueA(HKEY_CLASSES_ROOT,typelibkey,tlfn,&tlfnlen)) { -#ifdef _WIN64 - sprintf(typelibkey,"Typelib\\%s\\%s\\0\\win32",tlguid,ver); - tlfnlen = sizeof(tlfn); - if (RegQueryValueA(HKEY_CLASSES_ROOT,typelibkey,tlfn,&tlfnlen)) { -#endif - ERR("Could not get typelib fn?\n"); - return E_FAIL; -#ifdef _WIN64 - } -#endif - } - MultiByteToWideChar(CP_ACP, 0, tlfn, -1, module, len); - return S_OK; -} - -static HRESULT -_get_typeinfo_for_iid(REFIID riid, ITypeInfo **typeinfo) -{ - OLECHAR moduleW[260]; - ITypeLib *typelib; - HRESULT hres; - - *typeinfo = NULL; - - moduleW[0] = 0; - if (!actctx_get_typelib_module(riid, moduleW, sizeof(moduleW)/sizeof(moduleW[0]))) { - hres = reg_get_typelib_module(riid, moduleW, sizeof(moduleW)/sizeof(moduleW[0])); - if (FAILED(hres)) - return hres; - } - - hres = LoadTypeLib(moduleW, &typelib); - if (hres != S_OK) { - ERR("Failed to load typelib for %s, but it should be there.\n",debugstr_guid(riid)); - return hres; - } - - hres = ITypeLib_GetTypeInfoOfGuid(typelib, riid, typeinfo); - ITypeLib_Release(typelib); - if (hres != S_OK) - ERR("typelib does not contain info for %s\n", debugstr_guid(riid)); - - return hres; -} - -/* - * Determine the number of functions including all inherited functions - * and well as the size of the vtbl. - * Note for non-dual dispinterfaces we simply return the size of IDispatch. - */ -static HRESULT num_of_funcs(ITypeInfo *tinfo, unsigned int *num, - unsigned int *vtbl_size) -{ - HRESULT hr; - TYPEATTR *attr; - ITypeInfo *tinfo2; - UINT inherited_funcs = 0, i; - - *num = 0; - if(vtbl_size) *vtbl_size = 0; - - hr = ITypeInfo_GetTypeAttr(tinfo, &attr); - if (hr) - { - ERR("GetTypeAttr failed with %x\n", hr); - return hr; - } - - if(attr->typekind == TKIND_DISPATCH) - { - if(attr->wTypeFlags & TYPEFLAG_FDUAL) - { - HREFTYPE href; - - ITypeInfo_ReleaseTypeAttr(tinfo, attr); - hr = ITypeInfo_GetRefTypeOfImplType(tinfo, -1, &href); - if(FAILED(hr)) - { - ERR("Unable to get interface href from dual dispinterface\n"); - return hr; - } - hr = ITypeInfo_GetRefTypeInfo(tinfo, href, &tinfo2); - if(FAILED(hr)) - { - ERR("Unable to get interface from dual dispinterface\n"); - return hr; - } - hr = num_of_funcs(tinfo2, num, vtbl_size); - ITypeInfo_Release(tinfo2); - return hr; - } - else /* non-dual dispinterface */ - { - /* These will be the size of IDispatchVtbl */ - *num = attr->cbSizeVft / sizeof(void *); - if(vtbl_size) *vtbl_size = attr->cbSizeVft; - ITypeInfo_ReleaseTypeAttr(tinfo, attr); - return hr; - } - } - - for (i = 0; i < attr->cImplTypes; i++) - { - HREFTYPE href; - ITypeInfo *pSubTypeInfo; - UINT sub_funcs; - - hr = ITypeInfo_GetRefTypeOfImplType(tinfo, i, &href); - if (FAILED(hr)) goto end; - hr = ITypeInfo_GetRefTypeInfo(tinfo, href, &pSubTypeInfo); - if (FAILED(hr)) goto end; - - hr = num_of_funcs(pSubTypeInfo, &sub_funcs, NULL); - ITypeInfo_Release(pSubTypeInfo); - - if(FAILED(hr)) goto end; - inherited_funcs += sub_funcs; - } - - *num = inherited_funcs + attr->cFuncs; - if(vtbl_size) *vtbl_size = attr->cbSizeVft; - - end: - ITypeInfo_ReleaseTypeAttr(tinfo, attr); - return hr; -} - -#ifdef __i386__ - -#include "pshpack1.h" -typedef struct _TMAsmProxy { - DWORD lealeax; - BYTE pushleax; - BYTE pushlval; - DWORD nr; - BYTE lcall; - DWORD xcall; - BYTE lret; - WORD bytestopop; - WORD nop; -} TMAsmProxy; -#include "poppack.h" - -#elif defined(__x86_64__) - -#include "pshpack1.h" -typedef struct _TMAsmProxy { - BYTE pushq_rbp; - BYTE movq_rsp_rbp[3]; - DWORD subq_0x20_rsp; - DWORD movq_rcx_0x10rbp; - DWORD movq_rdx_0x18rbp; - DWORD movq_r8_0x20rbp; - DWORD movq_r9_0x28rbp; - BYTE movq_rcx[3]; - DWORD nr; - DWORD leaq_0x10rbp_rdx; - WORD movq_rax; - void *xcall; - WORD callq_rax; - BYTE movq_rbp_rsp[3]; - BYTE popq_rbp; - BYTE ret; - DWORD nop; -} TMAsmProxy; -#include "poppack.h" - -#else /* __i386__ */ -#ifdef _MSC_VER -#pragma message("You need to implement stubless proxies for your architecture") -#else -# warning You need to implement stubless proxies for your architecture -#endif -typedef struct _TMAsmProxy { - char a; -} TMAsmProxy; -#endif - -typedef struct _TMProxyImpl { - LPVOID *lpvtbl; - IRpcProxyBuffer IRpcProxyBuffer_iface; - LONG ref; - - TMAsmProxy *asmstubs; - ITypeInfo* tinfo; - IRpcChannelBuffer* chanbuf; - IID iid; - CRITICAL_SECTION crit; - IUnknown *outerunknown; - IDispatch *dispatch; - IRpcProxyBuffer *dispatch_proxy; -} TMProxyImpl; - -static inline TMProxyImpl *impl_from_IRpcProxyBuffer( IRpcProxyBuffer *iface ) -{ - return CONTAINING_RECORD(iface, TMProxyImpl, IRpcProxyBuffer_iface); -} - -static HRESULT WINAPI -TMProxyImpl_QueryInterface(LPRPCPROXYBUFFER iface, REFIID riid, LPVOID *ppv) -{ - TRACE("()\n"); - if (IsEqualIID(riid,&IID_IUnknown)||IsEqualIID(riid,&IID_IRpcProxyBuffer)) { - *ppv = iface; - IRpcProxyBuffer_AddRef(iface); - return S_OK; - } - FIXME("no interface for %s\n",debugstr_guid(riid)); - return E_NOINTERFACE; -} - -static ULONG WINAPI -TMProxyImpl_AddRef(LPRPCPROXYBUFFER iface) -{ - TMProxyImpl *This = impl_from_IRpcProxyBuffer( iface ); - ULONG refCount = InterlockedIncrement(&This->ref); - - TRACE("(%p)->(ref before=%u)\n",This, refCount - 1); - - return refCount; -} - -static ULONG WINAPI -TMProxyImpl_Release(LPRPCPROXYBUFFER iface) -{ - TMProxyImpl *This = impl_from_IRpcProxyBuffer( iface ); - ULONG refCount = InterlockedDecrement(&This->ref); - - TRACE("(%p)->(ref before=%u)\n",This, refCount + 1); - - if (!refCount) - { - if (This->dispatch_proxy) IRpcProxyBuffer_Release(This->dispatch_proxy); - This->crit.DebugInfo->Spare[0] = 0; - DeleteCriticalSection(&This->crit); - if (This->chanbuf) IRpcChannelBuffer_Release(This->chanbuf); - VirtualFree(This->asmstubs, 0, MEM_RELEASE); - HeapFree(GetProcessHeap(), 0, This->lpvtbl); - ITypeInfo_Release(This->tinfo); - CoTaskMemFree(This); - } - return refCount; -} - -static HRESULT WINAPI -TMProxyImpl_Connect( - LPRPCPROXYBUFFER iface,IRpcChannelBuffer* pRpcChannelBuffer) -{ - TMProxyImpl *This = impl_from_IRpcProxyBuffer( iface ); - - TRACE("(%p)\n", pRpcChannelBuffer); - - EnterCriticalSection(&This->crit); - - IRpcChannelBuffer_AddRef(pRpcChannelBuffer); - This->chanbuf = pRpcChannelBuffer; - - LeaveCriticalSection(&This->crit); - - if (This->dispatch_proxy) - { - IRpcChannelBuffer *pDelegateChannel; - HRESULT hr = TMarshalDispatchChannel_Create(pRpcChannelBuffer, &This->iid, &pDelegateChannel); - if (FAILED(hr)) - return hr; - hr = IRpcProxyBuffer_Connect(This->dispatch_proxy, pDelegateChannel); - IRpcChannelBuffer_Release(pDelegateChannel); - return hr; - } - - return S_OK; -} - -static void WINAPI -TMProxyImpl_Disconnect(LPRPCPROXYBUFFER iface) -{ - TMProxyImpl *This = impl_from_IRpcProxyBuffer( iface ); - - TRACE("()\n"); - - EnterCriticalSection(&This->crit); - - IRpcChannelBuffer_Release(This->chanbuf); - This->chanbuf = NULL; - - LeaveCriticalSection(&This->crit); - - if (This->dispatch_proxy) - IRpcProxyBuffer_Disconnect(This->dispatch_proxy); -} - - -static const IRpcProxyBufferVtbl tmproxyvtable = { - TMProxyImpl_QueryInterface, - TMProxyImpl_AddRef, - TMProxyImpl_Release, - TMProxyImpl_Connect, - TMProxyImpl_Disconnect -}; - -/* how much space do we use on stack in DWORD_PTR steps. */ -static int -_argsize(TYPEDESC *tdesc, ITypeInfo *tinfo) { - DWORD ret; - switch (tdesc->vt) { - case VT_I8: - case VT_UI8: - ret = 8; - break; - case VT_R8: - ret = sizeof(double); - break; - case VT_CY: - ret = sizeof(CY); - break; - case VT_DATE: - ret = sizeof(DATE); - break; - case VT_DECIMAL: - ret = sizeof(DECIMAL); - break; - case VT_VARIANT: - ret = sizeof(VARIANT); - break; - case VT_USERDEFINED: - { - ITypeInfo *tinfo2; - TYPEATTR *tattr; - HRESULT hres; - - hres = ITypeInfo_GetRefTypeInfo(tinfo,tdesc->u.hreftype,&tinfo2); - if (FAILED(hres)) - return 0; /* should fail critically in serialize_param */ - ITypeInfo_GetTypeAttr(tinfo2,&tattr); - ret = tattr->cbSizeInstance; - ITypeInfo_ReleaseTypeAttr(tinfo2, tattr); - ITypeInfo_Release(tinfo2); - break; - } - default: - ret = sizeof(DWORD_PTR); - break; - } - - return (ret + sizeof(DWORD_PTR) - 1) / sizeof(DWORD_PTR); -} - -/* how much space do we use on the heap (in bytes) */ -static int -_xsize(const TYPEDESC *td, ITypeInfo *tinfo) { - switch (td->vt) { - case VT_DATE: - return sizeof(DATE); - case VT_CY: - return sizeof(CY); - case VT_VARIANT: - return sizeof(VARIANT); - case VT_CARRAY: { - int i, arrsize = 1; - const ARRAYDESC *adesc = td->u.lpadesc; - - for (i=0;icDims;i++) - arrsize *= adesc->rgbounds[i].cElements; - return arrsize*_xsize(&adesc->tdescElem, tinfo); - } - case VT_UI8: - case VT_I8: - case VT_R8: - return 8; - case VT_UI2: - case VT_I2: - case VT_BOOL: - return 2; - case VT_UI1: - case VT_I1: - return 1; - case VT_USERDEFINED: - { - ITypeInfo *tinfo2; - TYPEATTR *tattr; - HRESULT hres; - DWORD ret; - - hres = ITypeInfo_GetRefTypeInfo(tinfo,td->u.hreftype,&tinfo2); - if (FAILED(hres)) - return 0; - ITypeInfo_GetTypeAttr(tinfo2,&tattr); - ret = tattr->cbSizeInstance; - ITypeInfo_ReleaseTypeAttr(tinfo2, tattr); - ITypeInfo_Release(tinfo2); - return ret; - } - default: - return sizeof(DWORD_PTR); - } -} - -/* Whether we pass this type by reference or by value */ -static BOOL -_passbyref(const TYPEDESC *td, ITypeInfo *tinfo) { - return (td->vt == VT_USERDEFINED || - td->vt == VT_VARIANT || - td->vt == VT_PTR); -} - -static HRESULT -serialize_param( - ITypeInfo *tinfo, - BOOL writeit, - BOOL debugout, - BOOL dealloc, - TYPEDESC *tdesc, - DWORD_PTR *arg, - marshal_state *buf) -{ - HRESULT hres = S_OK; - VARTYPE vartype; - - TRACE("(tdesc.vt %s)\n",debugstr_vt(tdesc->vt)); - - vartype = tdesc->vt; - if ((vartype & 0xf000) == VT_ARRAY) - vartype = VT_SAFEARRAY; - - switch (vartype) { - case VT_DATE: - case VT_I8: - case VT_UI8: - case VT_R8: - case VT_CY: - hres = S_OK; - if (debugout) TRACE_(olerelay)("%s\n", wine_dbgstr_longlong(*(ULONGLONG *)arg)); - if (writeit) - hres = xbuf_add(buf,(LPBYTE)arg,8); - return hres; - case VT_ERROR: - case VT_INT: - case VT_UINT: - case VT_I4: - case VT_R4: - case VT_UI4: - hres = S_OK; - if (debugout) TRACE_(olerelay)("%x\n", *(DWORD *)arg); - if (writeit) - hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD)); - return hres; - case VT_I2: - case VT_UI2: - case VT_BOOL: - hres = S_OK; - if (debugout) TRACE_(olerelay)("%04x\n", *(WORD *)arg); - if (writeit) - hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD)); - return hres; - case VT_I1: - case VT_UI1: - hres = S_OK; - if (debugout) TRACE_(olerelay)("%02x\n", *(BYTE *)arg); - if (writeit) - hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD)); - return hres; - case VT_VARIANT: { - if (debugout) TRACE_(olerelay)("%s", debugstr_variant((VARIANT *)arg)); - if (writeit) - { - ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION); - ULONG size = VARIANT_UserSize(&flags, buf->curoff, (VARIANT *)arg); - xbuf_resize(buf, size); - VARIANT_UserMarshal(&flags, buf->base + buf->curoff, (VARIANT *)arg); - buf->curoff = size; - } - if (dealloc) - { - ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION); - VARIANT_UserFree(&flags, (VARIANT *)arg); - } - return S_OK; - } - case VT_BSTR: { - if (writeit && debugout) { - if (*arg) - TRACE_(olerelay)("%s",relaystr((WCHAR*)*arg)); - else - TRACE_(olerelay)(""); - } - if (writeit) - { - ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION); - ULONG size = BSTR_UserSize(&flags, buf->curoff, (BSTR *)arg); - xbuf_resize(buf, size); - BSTR_UserMarshal(&flags, buf->base + buf->curoff, (BSTR *)arg); - buf->curoff = size; - } - if (dealloc) - { - ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION); - BSTR_UserFree(&flags, (BSTR *)arg); - } - return S_OK; - } - case VT_PTR: { - DWORD cookie; - BOOL derefhere = TRUE; - - if (tdesc->u.lptdesc->vt == VT_USERDEFINED) { - ITypeInfo *tinfo2; - TYPEATTR *tattr; - - hres = ITypeInfo_GetRefTypeInfo(tinfo,tdesc->u.lptdesc->u.hreftype,&tinfo2); - if (hres) { - ERR("Could not get typeinfo of hreftype %x for VT_USERDEFINED.\n",tdesc->u.lptdesc->u.hreftype); - return hres; - } - ITypeInfo_GetTypeAttr(tinfo2,&tattr); - switch (tattr->typekind) { - case TKIND_ALIAS: - if (tattr->tdescAlias.vt == VT_USERDEFINED) - { - DWORD href = tattr->tdescAlias.u.hreftype; - ITypeInfo_ReleaseTypeAttr(tinfo, tattr); - ITypeInfo_Release(tinfo2); - hres = ITypeInfo_GetRefTypeInfo(tinfo,href,&tinfo2); - if (hres) { - ERR("Could not get typeinfo of hreftype %x for VT_USERDEFINED.\n",tdesc->u.lptdesc->u.hreftype); - return hres; - } - ITypeInfo_GetTypeAttr(tinfo2,&tattr); - derefhere = (tattr->typekind != TKIND_DISPATCH && - tattr->typekind != TKIND_INTERFACE && - tattr->typekind != TKIND_COCLASS); - } - break; - case TKIND_ENUM: /* confirmed */ - case TKIND_RECORD: /* FIXME: mostly untested */ - break; - case TKIND_DISPATCH: /* will be done in VT_USERDEFINED case */ - case TKIND_INTERFACE: /* will be done in VT_USERDEFINED case */ - case TKIND_COCLASS: /* will be done in VT_USERDEFINED case */ - derefhere=FALSE; - break; - default: - FIXME("unhandled switch cases tattr->typekind %d\n", tattr->typekind); - derefhere=FALSE; - break; - } - ITypeInfo_ReleaseTypeAttr(tinfo, tattr); - ITypeInfo_Release(tinfo2); - } - - if (debugout) TRACE_(olerelay)("*"); - /* Write always, so the other side knows when it gets a NULL pointer. - */ - cookie = *arg ? 0x42424242 : 0; - hres = xbuf_add(buf,(LPBYTE)&cookie,sizeof(cookie)); - if (hres) - return hres; - if (!*arg) { - if (debugout) TRACE_(olerelay)("NULL"); - return S_OK; - } - hres = serialize_param(tinfo,writeit,debugout,dealloc,tdesc->u.lptdesc,(DWORD_PTR *)*arg,buf); - if (derefhere && dealloc) HeapFree(GetProcessHeap(),0,(LPVOID)*arg); - return hres; - } - case VT_UNKNOWN: - if (debugout) TRACE_(olerelay)("unk(0x%lx)", *arg); - if (writeit) - hres = _marshal_interface(buf,&IID_IUnknown,(LPUNKNOWN)*arg); - if (dealloc && *(IUnknown **)arg) - IUnknown_Release((LPUNKNOWN)*arg); - return hres; - case VT_DISPATCH: - if (debugout) TRACE_(olerelay)("idisp(0x%lx)", *arg); - if (writeit) - hres = _marshal_interface(buf,&IID_IDispatch,(LPUNKNOWN)*arg); - if (dealloc && *(IUnknown **)arg) - IUnknown_Release((LPUNKNOWN)*arg); - return hres; - case VT_VOID: - if (debugout) TRACE_(olerelay)(""); - return S_OK; - case VT_USERDEFINED: { - ITypeInfo *tinfo2; - TYPEATTR *tattr; - - hres = ITypeInfo_GetRefTypeInfo(tinfo,tdesc->u.hreftype,&tinfo2); - if (hres) { - ERR("Could not get typeinfo of hreftype %x for VT_USERDEFINED.\n",tdesc->u.hreftype); - return hres; - } - ITypeInfo_GetTypeAttr(tinfo2,&tattr); - switch (tattr->typekind) { - case TKIND_DISPATCH: - case TKIND_INTERFACE: - if (writeit) - hres=_marshal_interface(buf,&(tattr->guid),(LPUNKNOWN)arg); - if (dealloc) - IUnknown_Release((LPUNKNOWN)arg); - break; - case TKIND_COCLASS: { - GUID iid = tattr->guid; - unsigned int i; - int type_flags; - - for(i = 0; i < tattr->cImplTypes; i++) { - if(SUCCEEDED(ITypeInfo_GetImplTypeFlags(tinfo2, i, &type_flags)) && - type_flags == (IMPLTYPEFLAG_FSOURCE|IMPLTYPEFLAG_FDEFAULT)) { - ITypeInfo *tinfo3; - TYPEATTR *tattr2; - HREFTYPE href; - if(FAILED(ITypeInfo_GetRefTypeOfImplType(tinfo2, i, &href))) - break; - if(FAILED(ITypeInfo_GetRefTypeInfo(tinfo2, href, &tinfo3))) - break; - if(SUCCEEDED(ITypeInfo_GetTypeAttr(tinfo3, &tattr2))) { - iid = tattr2->guid; - ITypeInfo_ReleaseTypeAttr(tinfo3, tattr2); - } - ITypeInfo_Release(tinfo3); - break; - } - } - - if(writeit) - hres=_marshal_interface(buf, &iid, (LPUNKNOWN)arg); - if(dealloc) - IUnknown_Release((LPUNKNOWN)arg); - break; - } - case TKIND_RECORD: { - int i; - if (debugout) TRACE_(olerelay)("{"); - for (i=0;icVars;i++) { - VARDESC *vdesc; - ELEMDESC *elem2; - TYPEDESC *tdesc2; - - hres = ITypeInfo_GetVarDesc(tinfo2, i, &vdesc); - if (hres) { - ERR("Could not get vardesc of %d\n",i); - return hres; - } - elem2 = &vdesc->elemdescVar; - tdesc2 = &elem2->tdesc; - hres = serialize_param( - tinfo2, - writeit, - debugout, - dealloc, - tdesc2, - (DWORD_PTR *)(((LPBYTE)arg)+vdesc->u.oInst), - buf - ); - ITypeInfo_ReleaseVarDesc(tinfo2, vdesc); - if (hres!=S_OK) - return hres; - if (debugout && (i<(tattr->cVars-1))) - TRACE_(olerelay)(","); - } - if (debugout) TRACE_(olerelay)("}"); - break; - } - case TKIND_ALIAS: - hres = serialize_param(tinfo2,writeit,debugout,dealloc,&tattr->tdescAlias,arg,buf); - break; - case TKIND_ENUM: - hres = S_OK; - if (debugout) TRACE_(olerelay)("%x", *(DWORD *)arg); - if (writeit) - hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD)); - break; - default: - FIXME("Unhandled typekind %d\n",tattr->typekind); - hres = E_FAIL; - break; - } - ITypeInfo_ReleaseTypeAttr(tinfo2, tattr); - ITypeInfo_Release(tinfo2); - return hres; - } - case VT_CARRAY: { - ARRAYDESC *adesc = tdesc->u.lpadesc; - int i, arrsize = 1; - - if (debugout) TRACE_(olerelay)("carr"); - for (i=0;icDims;i++) { - if (debugout) TRACE_(olerelay)("[%d]",adesc->rgbounds[i].cElements); - arrsize *= adesc->rgbounds[i].cElements; - } - if (debugout) TRACE_(olerelay)("(vt %s)",debugstr_vt(adesc->tdescElem.vt)); - if (debugout) TRACE_(olerelay)("["); - for (i=0;itdescElem, tinfo) ? (LPBYTE) *arg : (LPBYTE) arg; - hres = serialize_param(tinfo, writeit, debugout, dealloc, &adesc->tdescElem, (DWORD_PTR *)((LPBYTE)base+i*_xsize(&adesc->tdescElem, tinfo)), buf); - if (hres) - return hres; - if (debugout && (icuroff, (LPSAFEARRAY *)arg); - xbuf_resize(buf, size); - LPSAFEARRAY_UserMarshal(&flags, buf->base + buf->curoff, (LPSAFEARRAY *)arg); - buf->curoff = size; - } - if (dealloc) - { - ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION); - LPSAFEARRAY_UserFree(&flags, (LPSAFEARRAY *)arg); - } - return S_OK; - } - default: - ERR("Unhandled marshal type %d.\n",tdesc->vt); - return S_OK; - } -} - -static HRESULT -deserialize_param( - ITypeInfo *tinfo, - BOOL readit, - BOOL debugout, - BOOL alloc, - TYPEDESC *tdesc, - DWORD_PTR *arg, - marshal_state *buf) -{ - HRESULT hres = S_OK; - VARTYPE vartype; - - TRACE("vt %s at %p\n",debugstr_vt(tdesc->vt),arg); - - vartype = tdesc->vt; - if ((vartype & 0xf000) == VT_ARRAY) - vartype = VT_SAFEARRAY; - - while (1) { - switch (vartype) { - case VT_VARIANT: { - if (readit) - { - ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION); - unsigned char *buffer; - buffer = VARIANT_UserUnmarshal(&flags, buf->base + buf->curoff, (VARIANT *)arg); - buf->curoff = buffer - buf->base; - } - return S_OK; - } - case VT_DATE: - case VT_I8: - case VT_UI8: - case VT_R8: - case VT_CY: - if (readit) { - hres = xbuf_get(buf,(LPBYTE)arg,8); - if (hres) ERR("Failed to read integer 8 byte\n"); - } - if (debugout) TRACE_(olerelay)("%s", wine_dbgstr_longlong(*(ULONGLONG *)arg)); - return hres; - case VT_ERROR: - case VT_I4: - case VT_INT: - case VT_UINT: - case VT_R4: - case VT_UI4: - if (readit) { - hres = xbuf_get(buf,(LPBYTE)arg,sizeof(DWORD)); - if (hres) ERR("Failed to read integer 4 byte\n"); - } - if (debugout) TRACE_(olerelay)("%x", *(DWORD *)arg); - return hres; - case VT_I2: - case VT_UI2: - case VT_BOOL: - if (readit) { - DWORD x; - hres = xbuf_get(buf,(LPBYTE)&x,sizeof(DWORD)); - if (hres) ERR("Failed to read integer 4 byte\n"); - else memcpy(arg,&x,2); - } - if (debugout) TRACE_(olerelay)("%04x", *(WORD *)arg); - return hres; - case VT_I1: - case VT_UI1: - if (readit) { - DWORD x; - hres = xbuf_get(buf,(LPBYTE)&x,sizeof(DWORD)); - if (hres) ERR("Failed to read integer 4 byte\n"); - else memcpy(arg,&x,1); - } - if (debugout) TRACE_(olerelay)("%02x", *(BYTE *)arg); - return hres; - case VT_BSTR: { - if (readit) - { - ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION); - unsigned char *buffer; - buffer = BSTR_UserUnmarshal(&flags, buf->base + buf->curoff, (BSTR *)arg); - buf->curoff = buffer - buf->base; - if (debugout) TRACE_(olerelay)("%s",debugstr_w(*(BSTR *)arg)); - } - return S_OK; - } - case VT_PTR: { - DWORD cookie; - BOOL derefhere = TRUE; - - if (tdesc->u.lptdesc->vt == VT_USERDEFINED) { - ITypeInfo *tinfo2; - TYPEATTR *tattr; - - hres = ITypeInfo_GetRefTypeInfo(tinfo,tdesc->u.lptdesc->u.hreftype,&tinfo2); - if (hres) { - ERR("Could not get typeinfo of hreftype %x for VT_USERDEFINED.\n",tdesc->u.lptdesc->u.hreftype); - return hres; - } - ITypeInfo_GetTypeAttr(tinfo2,&tattr); - switch (tattr->typekind) { - case TKIND_ALIAS: - if (tattr->tdescAlias.vt == VT_USERDEFINED) - { - DWORD href = tattr->tdescAlias.u.hreftype; - ITypeInfo_ReleaseTypeAttr(tinfo, tattr); - ITypeInfo_Release(tinfo2); - hres = ITypeInfo_GetRefTypeInfo(tinfo,href,&tinfo2); - if (hres) { - ERR("Could not get typeinfo of hreftype %x for VT_USERDEFINED.\n",tdesc->u.lptdesc->u.hreftype); - return hres; - } - ITypeInfo_GetTypeAttr(tinfo2,&tattr); - derefhere = (tattr->typekind != TKIND_DISPATCH && - tattr->typekind != TKIND_INTERFACE && - tattr->typekind != TKIND_COCLASS); - } - break; - case TKIND_ENUM: /* confirmed */ - case TKIND_RECORD: /* FIXME: mostly untested */ - break; - case TKIND_DISPATCH: /* will be done in VT_USERDEFINED case */ - case TKIND_INTERFACE: /* will be done in VT_USERDEFINED case */ - case TKIND_COCLASS: /* will be done in VT_USERDEFINED case */ - derefhere=FALSE; - break; - default: - FIXME("unhandled switch cases tattr->typekind %d\n", tattr->typekind); - derefhere=FALSE; - break; - } - ITypeInfo_ReleaseTypeAttr(tinfo2, tattr); - ITypeInfo_Release(tinfo2); - } - /* read it in all cases, we need to know if we have - * NULL pointer or not. - */ - hres = xbuf_get(buf,(LPBYTE)&cookie,sizeof(cookie)); - if (hres) { - ERR("Failed to load pointer cookie.\n"); - return hres; - } - if (cookie != 0x42424242) { - /* we read a NULL ptr from the remote side */ - if (debugout) TRACE_(olerelay)("NULL"); - *arg = 0; - return S_OK; - } - if (debugout) TRACE_(olerelay)("*"); - if (alloc) { - /* Allocate space for the referenced struct */ - if (derefhere) - *arg=(DWORD_PTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,_xsize(tdesc->u.lptdesc, tinfo)); - } - if (derefhere) - return deserialize_param(tinfo, readit, debugout, alloc, tdesc->u.lptdesc, (DWORD_PTR *)*arg, buf); - else - return deserialize_param(tinfo, readit, debugout, alloc, tdesc->u.lptdesc, arg, buf); - } - case VT_UNKNOWN: - /* FIXME: UNKNOWN is unknown ..., but allocate 4 byte for it */ - if (alloc) - *arg=(DWORD_PTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DWORD_PTR)); - hres = S_OK; - if (readit) - hres = _unmarshal_interface(buf,&IID_IUnknown,(LPUNKNOWN*)arg); - if (debugout) - TRACE_(olerelay)("unk(%p)",arg); - return hres; - case VT_DISPATCH: - hres = S_OK; - if (readit) - hres = _unmarshal_interface(buf,&IID_IDispatch,(LPUNKNOWN*)arg); - if (debugout) - TRACE_(olerelay)("idisp(%p)",arg); - return hres; - case VT_VOID: - if (debugout) TRACE_(olerelay)(""); - return S_OK; - case VT_USERDEFINED: { - ITypeInfo *tinfo2; - TYPEATTR *tattr; - - hres = ITypeInfo_GetRefTypeInfo(tinfo,tdesc->u.hreftype,&tinfo2); - if (hres) { - ERR("Could not get typeinfo of hreftype %x for VT_USERDEFINED.\n",tdesc->u.hreftype); - return hres; - } - hres = ITypeInfo_GetTypeAttr(tinfo2,&tattr); - if (hres) { - ERR("Could not get typeattr in VT_USERDEFINED.\n"); - } else { - switch (tattr->typekind) { - case TKIND_DISPATCH: - case TKIND_INTERFACE: - if (readit) - hres = _unmarshal_interface(buf,&(tattr->guid),(LPUNKNOWN*)arg); - break; - case TKIND_COCLASS: { - GUID iid = tattr->guid; - unsigned int i; - int type_flags; - - for(i = 0; i < tattr->cImplTypes; i++) { - if(SUCCEEDED(ITypeInfo_GetImplTypeFlags(tinfo2, i, &type_flags)) && - type_flags == (IMPLTYPEFLAG_FSOURCE|IMPLTYPEFLAG_FDEFAULT)) { - ITypeInfo *tinfo3; - TYPEATTR *tattr2; - HREFTYPE href; - if(FAILED(ITypeInfo_GetRefTypeOfImplType(tinfo2, i, &href))) - break; - if(FAILED(ITypeInfo_GetRefTypeInfo(tinfo2, href, &tinfo3))) - break; - if(SUCCEEDED(ITypeInfo_GetTypeAttr(tinfo3, &tattr2))) { - iid = tattr2->guid; - ITypeInfo_ReleaseTypeAttr(tinfo3, tattr2); - } - ITypeInfo_Release(tinfo3); - break; - } - } - - if(readit) - hres = _unmarshal_interface(buf, &iid, (LPUNKNOWN*)arg); - break; - } - case TKIND_RECORD: { - int i; - - if (debugout) TRACE_(olerelay)("{"); - for (i=0;icVars;i++) { - VARDESC *vdesc; - - hres = ITypeInfo_GetVarDesc(tinfo2, i, &vdesc); - if (hres) { - ERR("Could not get vardesc of %d\n",i); - ITypeInfo_ReleaseTypeAttr(tinfo2, tattr); - ITypeInfo_Release(tinfo2); - return hres; - } - hres = deserialize_param( - tinfo2, - readit, - debugout, - alloc, - &vdesc->elemdescVar.tdesc, - (DWORD_PTR *)(((LPBYTE)arg)+vdesc->u.oInst), - buf - ); - ITypeInfo_ReleaseVarDesc(tinfo2, vdesc); - if (debugout && (icVars-1)) TRACE_(olerelay)(","); - } - if (debugout) TRACE_(olerelay)("}"); - break; - } - case TKIND_ALIAS: - hres = deserialize_param(tinfo2,readit,debugout,alloc,&tattr->tdescAlias,arg,buf); - break; - 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)("%x", *(DWORD *)arg); - break; - default: - ERR("Unhandled typekind %d\n",tattr->typekind); - hres = E_FAIL; - break; - } - ITypeInfo_ReleaseTypeAttr(tinfo2, tattr); - } - if (hres) - ERR("failed to stuballoc in TKIND_RECORD.\n"); - ITypeInfo_Release(tinfo2); - return hres; - } - case VT_CARRAY: { - /* arg is pointing to the start of the array. */ - LPBYTE base = (LPBYTE) arg; - ARRAYDESC *adesc = tdesc->u.lpadesc; - int arrsize,i; - arrsize = 1; - if (adesc->cDims > 1) FIXME("cDims > 1 in VT_CARRAY. Does it work?\n"); - for (i=0;icDims;i++) - arrsize *= adesc->rgbounds[i].cElements; - if (_passbyref(&adesc->tdescElem, tinfo)) - { - base = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,_xsize(tdesc->u.lptdesc, tinfo) * arrsize); - *arg = (DWORD_PTR)base; - } - for (i=0;itdescElem, - (DWORD_PTR *)(base + i*_xsize(&adesc->tdescElem, tinfo)), - buf - ); - return S_OK; - } - case VT_SAFEARRAY: { - if (readit) - { - ULONG flags = MAKELONG(MSHCTX_DIFFERENTMACHINE, NDR_LOCAL_DATA_REPRESENTATION); - unsigned char *buffer; - buffer = LPSAFEARRAY_UserUnmarshal(&flags, buf->base + buf->curoff, (LPSAFEARRAY *)arg); - buf->curoff = buffer - buf->base; - } - return S_OK; - } - default: - ERR("No handler for VT type %d!\n",tdesc->vt); - return S_OK; - } - } -} - -/* Retrieves a function's funcdesc, searching back into inherited interfaces. */ -static HRESULT get_funcdesc(ITypeInfo *tinfo, int iMethod, ITypeInfo **tactual, const FUNCDESC **fdesc, - BSTR *iname, BSTR *fname, UINT *num) -{ - HRESULT hr; - UINT i, impl_types; - UINT inherited_funcs = 0; - TYPEATTR *attr; - - if (fname) *fname = NULL; - if (iname) *iname = NULL; - if (num) *num = 0; - *tactual = NULL; - - hr = ITypeInfo_GetTypeAttr(tinfo, &attr); - if (FAILED(hr)) - { - ERR("GetTypeAttr failed with %x\n",hr); - return hr; - } - - if(attr->typekind == TKIND_DISPATCH) - { - if(attr->wTypeFlags & TYPEFLAG_FDUAL) - { - HREFTYPE href; - ITypeInfo *tinfo2; - - hr = ITypeInfo_GetRefTypeOfImplType(tinfo, -1, &href); - if(FAILED(hr)) - { - ERR("Cannot get interface href from dual dispinterface\n"); - ITypeInfo_ReleaseTypeAttr(tinfo, attr); - return hr; - } - hr = ITypeInfo_GetRefTypeInfo(tinfo, href, &tinfo2); - if(FAILED(hr)) - { - ERR("Cannot get interface from dual dispinterface\n"); - ITypeInfo_ReleaseTypeAttr(tinfo, attr); - return hr; - } - hr = get_funcdesc(tinfo2, iMethod, tactual, fdesc, iname, fname, num); - ITypeInfo_Release(tinfo2); - ITypeInfo_ReleaseTypeAttr(tinfo, attr); - return hr; - } - ERR("Shouldn't be called with a non-dual dispinterface\n"); - return E_FAIL; - } - - impl_types = attr->cImplTypes; - ITypeInfo_ReleaseTypeAttr(tinfo, attr); - - for (i = 0; i < impl_types; i++) - { - HREFTYPE href; - ITypeInfo *pSubTypeInfo; - UINT sub_funcs; - - hr = ITypeInfo_GetRefTypeOfImplType(tinfo, i, &href); - if (FAILED(hr)) return hr; - hr = ITypeInfo_GetRefTypeInfo(tinfo, href, &pSubTypeInfo); - if (FAILED(hr)) return hr; - - hr = get_funcdesc(pSubTypeInfo, iMethod, tactual, fdesc, iname, fname, &sub_funcs); - inherited_funcs += sub_funcs; - ITypeInfo_Release(pSubTypeInfo); - if(SUCCEEDED(hr)) return hr; - } - if(iMethod < inherited_funcs) - { - ERR("shouldn't be here\n"); - return E_INVALIDARG; - } - - for(i = inherited_funcs; i <= iMethod; i++) - { - hr = ITypeInfoImpl_GetInternalFuncDesc(tinfo, i - inherited_funcs, fdesc); - if(FAILED(hr)) - { - if(num) *num = i; - return hr; - } - } - - /* found it. We don't care about num so zero it */ - if(num) *num = 0; - *tactual = tinfo; - ITypeInfo_AddRef(*tactual); - if (fname) ITypeInfo_GetDocumentation(tinfo,(*fdesc)->memid,fname,NULL,NULL,NULL); - if (iname) ITypeInfo_GetDocumentation(tinfo,-1,iname,NULL,NULL,NULL); - return S_OK; -} - -static inline BOOL is_in_elem(const ELEMDESC *elem) -{ - return (elem->u.paramdesc.wParamFlags & PARAMFLAG_FIN || !elem->u.paramdesc.wParamFlags); -} - -static inline BOOL is_out_elem(const ELEMDESC *elem) -{ - return (elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT || !elem->u.paramdesc.wParamFlags); -} - -static DWORD WINAPI xCall(int method, void **args) -{ - TMProxyImpl *tpinfo = args[0]; - DWORD_PTR *xargs; - const FUNCDESC *fdesc; - HRESULT hres; - int i; - marshal_state buf; - RPCOLEMESSAGE msg; - ULONG status; - BSTR fname,iname; - BSTR names[10]; - UINT nrofnames; - DWORD remoteresult = 0; - ITypeInfo *tinfo; - IRpcChannelBuffer *chanbuf; - - EnterCriticalSection(&tpinfo->crit); - - hres = get_funcdesc(tpinfo->tinfo,method,&tinfo,&fdesc,&iname,&fname,NULL); - if (hres) { - ERR("Did not find typeinfo/funcdesc entry for method %d!\n",method); - LeaveCriticalSection(&tpinfo->crit); - return E_FAIL; - } - - if (!tpinfo->chanbuf) - { - WARN("Tried to use disconnected proxy\n"); - ITypeInfo_Release(tinfo); - LeaveCriticalSection(&tpinfo->crit); - return RPC_E_DISCONNECTED; - } - chanbuf = tpinfo->chanbuf; - IRpcChannelBuffer_AddRef(chanbuf); - - LeaveCriticalSection(&tpinfo->crit); - - if (TRACE_ON(olerelay)) { - TRACE_(olerelay)("->"); - if (iname) - TRACE_(olerelay)("%s:",relaystr(iname)); - if (fname) - TRACE_(olerelay)("%s(%d)",relaystr(fname),method); - else - TRACE_(olerelay)("%d",method); - TRACE_(olerelay)("("); - } - - SysFreeString(iname); - SysFreeString(fname); - - memset(&buf,0,sizeof(buf)); - - /* normal typelib driven serializing */ - - /* Need them for hack below */ - memset(names,0,sizeof(names)); - if (ITypeInfo_GetNames(tinfo,fdesc->memid,names,sizeof(names)/sizeof(names[0]),&nrofnames)) - nrofnames = 0; - if (nrofnames > sizeof(names)/sizeof(names[0])) - ERR("Need more names!\n"); - - xargs = (DWORD_PTR *)(args + 1); - for (i=0;icParams;i++) { - ELEMDESC *elem = fdesc->lprgelemdescParam+i; - if (TRACE_ON(olerelay)) { - if (i) TRACE_(olerelay)(","); - if (i+1tdesc.u.lptdesc, tinfo ) ); - } - } - - hres = serialize_param( - tinfo, - is_in_elem(elem), - TRACE_ON(olerelay), - FALSE, - &elem->tdesc, - xargs, - &buf - ); - - if (hres) { - ERR("Failed to serialize param, hres %x\n",hres); - break; - } - xargs+=_argsize(&elem->tdesc, tinfo); - } - TRACE_(olerelay)(")"); - - memset(&msg,0,sizeof(msg)); - msg.cbBuffer = buf.curoff; - msg.iMethod = method; - hres = IRpcChannelBuffer_GetBuffer(chanbuf,&msg,&(tpinfo->iid)); - if (hres) { - ERR("RpcChannelBuffer GetBuffer failed, %x\n",hres); - goto exit; - } - memcpy(msg.Buffer,buf.base,buf.curoff); - TRACE_(olerelay)("\n"); - hres = IRpcChannelBuffer_SendReceive(chanbuf,&msg,&status); - if (hres) { - ERR("RpcChannelBuffer SendReceive failed, %x\n",hres); - goto exit; - } - - TRACE_(olerelay)(" status = %08x (",status); - if (buf.base) - buf.base = HeapReAlloc(GetProcessHeap(),0,buf.base,msg.cbBuffer); - else - buf.base = HeapAlloc(GetProcessHeap(),0,msg.cbBuffer); - buf.size = msg.cbBuffer; - memcpy(buf.base,msg.Buffer,buf.size); - buf.curoff = 0; - - /* generic deserializer using typelib description */ - xargs = (DWORD_PTR *)(args + 1); - status = S_OK; - for (i=0;icParams;i++) { - ELEMDESC *elem = fdesc->lprgelemdescParam+i; - - if (i) TRACE_(olerelay)(","); - if (i+1tdesc), - xargs, - &buf - ); - if (hres) { - ERR("Failed to unmarshall param, hres %x\n",hres); - status = hres; - break; - } - xargs += _argsize(&elem->tdesc, tinfo); - } - - hres = xbuf_get(&buf, (LPBYTE)&remoteresult, sizeof(DWORD)); - if (hres != S_OK) - goto exit; - TRACE_(olerelay)(") = %08x\n", remoteresult); - - hres = remoteresult; - -exit: - IRpcChannelBuffer_FreeBuffer(chanbuf,&msg); - for (i = 0; i < nrofnames; i++) - SysFreeString(names[i]); - HeapFree(GetProcessHeap(),0,buf.base); - IRpcChannelBuffer_Release(chanbuf); - ITypeInfo_Release(tinfo); - TRACE("-- 0x%08x\n", hres); - return hres; -} - -static HRESULT WINAPI ProxyIUnknown_QueryInterface(IUnknown *iface, REFIID riid, void **ppv) -{ - TMProxyImpl *proxy = (TMProxyImpl *)iface; - - TRACE("(%s, %p)\n", debugstr_guid(riid), ppv); - - if (proxy->outerunknown) - return IUnknown_QueryInterface(proxy->outerunknown, riid, ppv); - - FIXME("No interface\n"); - return E_NOINTERFACE; -} - -static ULONG WINAPI ProxyIUnknown_AddRef(IUnknown *iface) -{ - TMProxyImpl *proxy = (TMProxyImpl *)iface; - - TRACE("\n"); - - if (proxy->outerunknown) - return IUnknown_AddRef(proxy->outerunknown); - - return 2; /* FIXME */ -} - -static ULONG WINAPI ProxyIUnknown_Release(IUnknown *iface) -{ - TMProxyImpl *proxy = (TMProxyImpl *)iface; - - TRACE("\n"); - - if (proxy->outerunknown) - return IUnknown_Release(proxy->outerunknown); - - return 1; /* FIXME */ -} - -static HRESULT WINAPI ProxyIDispatch_GetTypeInfoCount(LPDISPATCH iface, UINT * pctinfo) -{ - TMProxyImpl *This = (TMProxyImpl *)iface; - - TRACE("(%p)\n", pctinfo); - - return IDispatch_GetTypeInfoCount(This->dispatch, pctinfo); -} - -static HRESULT WINAPI ProxyIDispatch_GetTypeInfo(LPDISPATCH iface, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo) -{ - TMProxyImpl *This = (TMProxyImpl *)iface; - - TRACE("(%d, %x, %p)\n", iTInfo, lcid, ppTInfo); - - return IDispatch_GetTypeInfo(This->dispatch, iTInfo, lcid, ppTInfo); -} - -static HRESULT WINAPI ProxyIDispatch_GetIDsOfNames(LPDISPATCH iface, REFIID riid, LPOLESTR * rgszNames, UINT cNames, LCID lcid, DISPID * rgDispId) -{ - TMProxyImpl *This = (TMProxyImpl *)iface; - - TRACE("(%s, %p, %d, 0x%x, %p)\n", debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId); - - return IDispatch_GetIDsOfNames(This->dispatch, riid, rgszNames, - cNames, lcid, rgDispId); -} - -static HRESULT WINAPI ProxyIDispatch_Invoke(LPDISPATCH iface, DISPID dispIdMember, REFIID riid, LCID lcid, - WORD wFlags, DISPPARAMS * pDispParams, VARIANT * pVarResult, - EXCEPINFO * pExcepInfo, UINT * puArgErr) -{ - TMProxyImpl *This = (TMProxyImpl *)iface; - - TRACE("(%d, %s, 0x%x, 0x%x, %p, %p, %p, %p)\n", dispIdMember, - debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult, - pExcepInfo, puArgErr); - - return IDispatch_Invoke(This->dispatch, dispIdMember, riid, lcid, - wFlags, pDispParams, pVarResult, pExcepInfo, - puArgErr); -} - -typedef struct -{ - IRpcChannelBuffer IRpcChannelBuffer_iface; - LONG refs; - /* the IDispatch-derived interface we are handling */ - IID tmarshal_iid; - IRpcChannelBuffer *pDelegateChannel; -} TMarshalDispatchChannel; - -static inline TMarshalDispatchChannel *impl_from_IRpcChannelBuffer(IRpcChannelBuffer *iface) -{ - return CONTAINING_RECORD(iface, TMarshalDispatchChannel, IRpcChannelBuffer_iface); -} - -static HRESULT WINAPI TMarshalDispatchChannel_QueryInterface(IRpcChannelBuffer *iface, REFIID riid, LPVOID *ppv) -{ - *ppv = NULL; - if (IsEqualIID(riid,&IID_IRpcChannelBuffer) || IsEqualIID(riid,&IID_IUnknown)) - { - *ppv = iface; - IRpcChannelBuffer_AddRef(iface); - return S_OK; - } - return E_NOINTERFACE; -} - -static ULONG WINAPI TMarshalDispatchChannel_AddRef(LPRPCCHANNELBUFFER iface) -{ - TMarshalDispatchChannel *This = impl_from_IRpcChannelBuffer(iface); - return InterlockedIncrement(&This->refs); -} - -static ULONG WINAPI TMarshalDispatchChannel_Release(LPRPCCHANNELBUFFER iface) -{ - TMarshalDispatchChannel *This = impl_from_IRpcChannelBuffer(iface); - ULONG ref; - - ref = InterlockedDecrement(&This->refs); - if (ref) - return ref; - - IRpcChannelBuffer_Release(This->pDelegateChannel); - HeapFree(GetProcessHeap(), 0, This); - return 0; -} - -static HRESULT WINAPI TMarshalDispatchChannel_GetBuffer(LPRPCCHANNELBUFFER iface, RPCOLEMESSAGE* olemsg, REFIID riid) -{ - TMarshalDispatchChannel *This = impl_from_IRpcChannelBuffer(iface); - TRACE("(%p, %s)\n", olemsg, debugstr_guid(riid)); - /* Note: we are pretending to invoke a method on the interface identified - * by tmarshal_iid so that we can re-use the IDispatch proxy/stub code - * without the RPC runtime getting confused by not exporting an IDispatch interface */ - return IRpcChannelBuffer_GetBuffer(This->pDelegateChannel, olemsg, &This->tmarshal_iid); -} - -static HRESULT WINAPI TMarshalDispatchChannel_SendReceive(LPRPCCHANNELBUFFER iface, RPCOLEMESSAGE *olemsg, ULONG *pstatus) -{ - TMarshalDispatchChannel *This = impl_from_IRpcChannelBuffer(iface); - TRACE("(%p, %p)\n", olemsg, pstatus); - return IRpcChannelBuffer_SendReceive(This->pDelegateChannel, olemsg, pstatus); -} - -static HRESULT WINAPI TMarshalDispatchChannel_FreeBuffer(LPRPCCHANNELBUFFER iface, RPCOLEMESSAGE* olemsg) -{ - TMarshalDispatchChannel *This = impl_from_IRpcChannelBuffer(iface); - TRACE("(%p)\n", olemsg); - return IRpcChannelBuffer_FreeBuffer(This->pDelegateChannel, olemsg); -} - -static HRESULT WINAPI TMarshalDispatchChannel_GetDestCtx(LPRPCCHANNELBUFFER iface, DWORD* pdwDestContext, void** ppvDestContext) -{ - TMarshalDispatchChannel *This = impl_from_IRpcChannelBuffer(iface); - TRACE("(%p,%p)\n", pdwDestContext, ppvDestContext); - return IRpcChannelBuffer_GetDestCtx(This->pDelegateChannel, pdwDestContext, ppvDestContext); -} - -static HRESULT WINAPI TMarshalDispatchChannel_IsConnected(LPRPCCHANNELBUFFER iface) -{ - TMarshalDispatchChannel *This = impl_from_IRpcChannelBuffer(iface); - TRACE("()\n"); - return IRpcChannelBuffer_IsConnected(This->pDelegateChannel); -} - -static const IRpcChannelBufferVtbl TMarshalDispatchChannelVtbl = -{ - TMarshalDispatchChannel_QueryInterface, - TMarshalDispatchChannel_AddRef, - TMarshalDispatchChannel_Release, - TMarshalDispatchChannel_GetBuffer, - TMarshalDispatchChannel_SendReceive, - TMarshalDispatchChannel_FreeBuffer, - TMarshalDispatchChannel_GetDestCtx, - TMarshalDispatchChannel_IsConnected -}; - -static HRESULT TMarshalDispatchChannel_Create( - IRpcChannelBuffer *pDelegateChannel, REFIID tmarshal_riid, - IRpcChannelBuffer **ppChannel) -{ - TMarshalDispatchChannel *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This)); - if (!This) - return E_OUTOFMEMORY; - - This->IRpcChannelBuffer_iface.lpVtbl = &TMarshalDispatchChannelVtbl; - This->refs = 1; - IRpcChannelBuffer_AddRef(pDelegateChannel); - This->pDelegateChannel = pDelegateChannel; - This->tmarshal_iid = *tmarshal_riid; - - *ppChannel = &This->IRpcChannelBuffer_iface; - return S_OK; -} - - -static inline HRESULT get_facbuf_for_iid(REFIID riid, IPSFactoryBuffer **facbuf) -{ - HRESULT hr; - CLSID clsid; - - if ((hr = CoGetPSClsid(riid, &clsid))) - return hr; - return CoGetClassObject(&clsid, CLSCTX_INPROC_SERVER, NULL, - &IID_IPSFactoryBuffer, (LPVOID*)facbuf); -} - -static HRESULT init_proxy_entry_point(TMProxyImpl *proxy, unsigned int num) -{ - int j; - /* nrofargs including This */ - int nrofargs = 1; - ITypeInfo *tinfo2; - TMAsmProxy *xasm = proxy->asmstubs + num; - HRESULT hres; - const FUNCDESC *fdesc; - - hres = get_funcdesc(proxy->tinfo, num, &tinfo2, &fdesc, NULL, NULL, NULL); - if (hres) { - ERR("GetFuncDesc %x should not fail here.\n",hres); - return hres; - } - ITypeInfo_Release(tinfo2); - /* some args take more than 4 byte on the stack */ - for (j=0;jcParams;j++) - nrofargs += _argsize(&fdesc->lprgelemdescParam[j].tdesc, proxy->tinfo); - -#ifdef __i386__ - if (fdesc->callconv != CC_STDCALL) { - ERR("calling convention is not stdcall????\n"); - return E_FAIL; - } -/* leal 4(%esp),%eax - * pushl %eax - * pushl - * call xCall - * lret - */ - xasm->lealeax = 0x0424448d; - xasm->pushleax = 0x50; - xasm->pushlval = 0x68; - xasm->nr = num; - xasm->lcall = 0xe8; - xasm->xcall = (char *)xCall - (char *)&xasm->lret; - xasm->lret = 0xc2; - xasm->bytestopop = nrofargs * 4; - xasm->nop = 0x9090; - proxy->lpvtbl[fdesc->oVft / sizeof(void *)] = xasm; - -#elif defined(__x86_64__) - - xasm->pushq_rbp = 0x55; /* pushq %rbp */ - xasm->movq_rsp_rbp[0] = 0x48; /* movq %rsp,%rbp */ - xasm->movq_rsp_rbp[1] = 0x89; - xasm->movq_rsp_rbp[2] = 0xe5; - xasm->subq_0x20_rsp = 0x20ec8348; /* subq 0x20,%rsp */ - xasm->movq_rcx_0x10rbp = 0x104d8948; /* movq %rcx,0x10(%rbp) */ - xasm->movq_rdx_0x18rbp = 0x18558948; /* movq %rdx,0x18(%rbp) */ - xasm->movq_r8_0x20rbp = 0x2045894c; /* movq %r8,0x20(%rbp) */ - xasm->movq_r9_0x28rbp = 0x284d894c; /* movq %r9,0x28(%rbp) */ - xasm->movq_rcx[0] = 0x48; /* movq ,%rcx */ - xasm->movq_rcx[1] = 0xc7; - xasm->movq_rcx[2] = 0xc1; - xasm->nr = num; - xasm->leaq_0x10rbp_rdx = 0x10558d48; /* leaq 0x10(%rbp),%rdx */ - xasm->movq_rax = 0xb848; /* movq ,%rax */ - xasm->xcall = xCall; - xasm->callq_rax = 0xd0ff; /* callq *%rax */ - xasm->movq_rbp_rsp[0] = 0x48; /* movq %rbp,%rsp */ - xasm->movq_rbp_rsp[1] = 0x89; - xasm->movq_rbp_rsp[2] = 0xec; - xasm->popq_rbp = 0x5d; /* popq %rbp */ - xasm->ret = 0xc3; /* ret */ - xasm->nop = 0x90909090; /* nop */ - proxy->lpvtbl[fdesc->oVft / sizeof(void *)] = xasm; - -#else - FIXME("not implemented on non i386\n"); - return E_FAIL; -#endif - return S_OK; -} - -static HRESULT WINAPI -PSFacBuf_CreateProxy( - LPPSFACTORYBUFFER iface, IUnknown* pUnkOuter, REFIID riid, - IRpcProxyBuffer **ppProxy, LPVOID *ppv) -{ - HRESULT hres; - ITypeInfo *tinfo; - unsigned int i, nroffuncs, vtbl_size; - TMProxyImpl *proxy; - TYPEATTR *typeattr; - BOOL defer_to_dispatch = FALSE; - - TRACE("(...%s...)\n",debugstr_guid(riid)); - hres = _get_typeinfo_for_iid(riid,&tinfo); - if (hres) { - ERR("No typeinfo for %s?\n",debugstr_guid(riid)); - return hres; - } - - hres = num_of_funcs(tinfo, &nroffuncs, &vtbl_size); - TRACE("Got %d funcs, vtbl size %d\n", nroffuncs, vtbl_size); - - if (FAILED(hres)) { - ERR("Cannot get number of functions for typeinfo %s\n",debugstr_guid(riid)); - ITypeInfo_Release(tinfo); - return hres; - } - - proxy = CoTaskMemAlloc(sizeof(TMProxyImpl)); - if (!proxy) return E_OUTOFMEMORY; - - proxy->dispatch = NULL; - proxy->dispatch_proxy = NULL; - proxy->outerunknown = pUnkOuter; - proxy->asmstubs = VirtualAlloc(NULL, sizeof(TMAsmProxy) * nroffuncs, MEM_COMMIT, PAGE_EXECUTE_READWRITE); - if (!proxy->asmstubs) { - ERR("Could not commit pages for proxy thunks\n"); - CoTaskMemFree(proxy); - return E_OUTOFMEMORY; - } - proxy->IRpcProxyBuffer_iface.lpVtbl = &tmproxyvtable; - /* one reference for the proxy */ - proxy->ref = 1; - proxy->tinfo = tinfo; - proxy->iid = *riid; - proxy->chanbuf = 0; - - InitializeCriticalSection(&proxy->crit); - proxy->crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": TMProxyImpl.crit"); - - proxy->lpvtbl = HeapAlloc(GetProcessHeap(), 0, vtbl_size); - - /* if we derive from IDispatch then defer to its proxy for its methods */ - hres = ITypeInfo_GetTypeAttr(tinfo, &typeattr); - if (hres == S_OK) - { - if (typeattr->wTypeFlags & TYPEFLAG_FDISPATCHABLE) - { - IPSFactoryBuffer *factory_buffer; - hres = get_facbuf_for_iid(&IID_IDispatch, &factory_buffer); - if (hres == S_OK) - { - hres = IPSFactoryBuffer_CreateProxy(factory_buffer, NULL, - &IID_IDispatch, &proxy->dispatch_proxy, - (void **)&proxy->dispatch); - IPSFactoryBuffer_Release(factory_buffer); - } - if ((hres == S_OK) && (nroffuncs < 7)) - { - ERR("nroffuncs calculated incorrectly (%d)\n", nroffuncs); - hres = E_UNEXPECTED; - } - if (hres == S_OK) - { - defer_to_dispatch = TRUE; - } - } - ITypeInfo_ReleaseTypeAttr(tinfo, typeattr); - } - - for (i=0;ilpvtbl[i] = ProxyIUnknown_QueryInterface; - break; - case 1: - proxy->lpvtbl[i] = ProxyIUnknown_AddRef; - break; - case 2: - proxy->lpvtbl[i] = ProxyIUnknown_Release; - break; - case 3: - if(!defer_to_dispatch) hres = init_proxy_entry_point(proxy, i); - else proxy->lpvtbl[3] = ProxyIDispatch_GetTypeInfoCount; - break; - case 4: - if(!defer_to_dispatch) hres = init_proxy_entry_point(proxy, i); - else proxy->lpvtbl[4] = ProxyIDispatch_GetTypeInfo; - break; - case 5: - if(!defer_to_dispatch) hres = init_proxy_entry_point(proxy, i); - else proxy->lpvtbl[5] = ProxyIDispatch_GetIDsOfNames; - break; - case 6: - if(!defer_to_dispatch) hres = init_proxy_entry_point(proxy, i); - else proxy->lpvtbl[6] = ProxyIDispatch_Invoke; - break; - default: - hres = init_proxy_entry_point(proxy, i); - } - } - - if (hres == S_OK) - { - *ppv = proxy; - *ppProxy = &proxy->IRpcProxyBuffer_iface; - IUnknown_AddRef((IUnknown *)*ppv); - return S_OK; - } - else - TMProxyImpl_Release(&proxy->IRpcProxyBuffer_iface); - return hres; -} - -typedef struct _TMStubImpl { - IRpcStubBuffer IRpcStubBuffer_iface; - LONG ref; - - LPUNKNOWN pUnk; - ITypeInfo *tinfo; - IID iid; - IRpcStubBuffer *dispatch_stub; - BOOL dispatch_derivative; -} TMStubImpl; - -static inline TMStubImpl *impl_from_IRpcStubBuffer(IRpcStubBuffer *iface) -{ - return CONTAINING_RECORD(iface, TMStubImpl, IRpcStubBuffer_iface); -} - -static HRESULT WINAPI -TMStubImpl_QueryInterface(LPRPCSTUBBUFFER iface, REFIID riid, LPVOID *ppv) -{ - if (IsEqualIID(riid,&IID_IRpcStubBuffer)||IsEqualIID(riid,&IID_IUnknown)){ - *ppv = iface; - IRpcStubBuffer_AddRef(iface); - return S_OK; - } - FIXME("%s, not supported IID.\n",debugstr_guid(riid)); - return E_NOINTERFACE; -} - -static ULONG WINAPI -TMStubImpl_AddRef(LPRPCSTUBBUFFER iface) -{ - TMStubImpl *This = impl_from_IRpcStubBuffer(iface); - ULONG refCount = InterlockedIncrement(&This->ref); - - TRACE("(%p)->(ref before=%u)\n", This, refCount - 1); - - return refCount; -} - -static ULONG WINAPI -TMStubImpl_Release(LPRPCSTUBBUFFER iface) -{ - TMStubImpl *This = impl_from_IRpcStubBuffer(iface); - ULONG refCount = InterlockedDecrement(&This->ref); - - TRACE("(%p)->(ref before=%u)\n", This, refCount + 1); - - if (!refCount) - { - IRpcStubBuffer_Disconnect(iface); - ITypeInfo_Release(This->tinfo); - if (This->dispatch_stub) - IRpcStubBuffer_Release(This->dispatch_stub); - CoTaskMemFree(This); - } - return refCount; -} - -static HRESULT WINAPI -TMStubImpl_Connect(LPRPCSTUBBUFFER iface, LPUNKNOWN pUnkServer) -{ - TMStubImpl *This = impl_from_IRpcStubBuffer(iface); - - TRACE("(%p)->(%p)\n", This, pUnkServer); - - IUnknown_AddRef(pUnkServer); - This->pUnk = pUnkServer; - - if (This->dispatch_stub) - IRpcStubBuffer_Connect(This->dispatch_stub, pUnkServer); - - return S_OK; -} - -static void WINAPI -TMStubImpl_Disconnect(LPRPCSTUBBUFFER iface) -{ - TMStubImpl *This = impl_from_IRpcStubBuffer(iface); - - TRACE("(%p)->()\n", This); - - if (This->pUnk) - { - IUnknown_Release(This->pUnk); - This->pUnk = NULL; - } - - if (This->dispatch_stub) - IRpcStubBuffer_Disconnect(This->dispatch_stub); -} - -static HRESULT WINAPI -TMStubImpl_Invoke( - LPRPCSTUBBUFFER iface, RPCOLEMESSAGE* xmsg,IRpcChannelBuffer*rpcchanbuf) -{ -#if defined(__i386__) || defined(__x86_64__) - int i; - const FUNCDESC *fdesc; - TMStubImpl *This = impl_from_IRpcStubBuffer(iface); - HRESULT hres; - DWORD_PTR *args = NULL, *xargs; - DWORD res, nrofargs; - marshal_state buf; - UINT nrofnames = 0; - BSTR names[10]; - BSTR iname = NULL; - ITypeInfo *tinfo = NULL; - - TRACE("...\n"); - - if (xmsg->iMethod < 3) { - ERR("IUnknown methods cannot be marshaled by the typelib marshaler\n"); - return E_UNEXPECTED; - } - - if (This->dispatch_derivative && xmsg->iMethod < sizeof(IDispatchVtbl)/sizeof(void *)) - { - if (!This->dispatch_stub) - { - IPSFactoryBuffer *factory_buffer; - hres = get_facbuf_for_iid(&IID_IDispatch, &factory_buffer); - if (hres == S_OK) - { - hres = IPSFactoryBuffer_CreateStub(factory_buffer, &IID_IDispatch, - This->pUnk, &This->dispatch_stub); - IPSFactoryBuffer_Release(factory_buffer); - } - if (hres != S_OK) - return hres; - } - return IRpcStubBuffer_Invoke(This->dispatch_stub, xmsg, rpcchanbuf); - } - - memset(&buf,0,sizeof(buf)); - buf.size = xmsg->cbBuffer; - buf.base = HeapAlloc(GetProcessHeap(), 0, xmsg->cbBuffer); - memcpy(buf.base, xmsg->Buffer, xmsg->cbBuffer); - buf.curoff = 0; - - hres = get_funcdesc(This->tinfo,xmsg->iMethod,&tinfo,&fdesc,&iname,NULL,NULL); - if (hres) { - ERR("GetFuncDesc on method %d failed with %x\n",xmsg->iMethod,hres); - return hres; - } - - if (iname && !lstrcmpW(iname, IDispatchW)) - { - ERR("IDispatch cannot be marshaled by the typelib marshaler\n"); - hres = E_UNEXPECTED; - SysFreeString (iname); - goto exit; - } - - SysFreeString (iname); - - /* Need them for hack below */ - memset(names,0,sizeof(names)); - ITypeInfo_GetNames(tinfo,fdesc->memid,names,sizeof(names)/sizeof(names[0]),&nrofnames); - if (nrofnames > sizeof(names)/sizeof(names[0])) { - ERR("Need more names!\n"); - } - - /*dump_FUNCDESC(fdesc);*/ - nrofargs = 0; - for (i=0;icParams;i++) - nrofargs += _argsize(&fdesc->lprgelemdescParam[i].tdesc, tinfo); - args = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (nrofargs+1)*sizeof(DWORD_PTR)); - if (!args) - { - hres = E_OUTOFMEMORY; - goto exit; - } - - /* Allocate all stuff used by call. */ - xargs = args+1; - for (i=0;icParams;i++) { - ELEMDESC *elem = fdesc->lprgelemdescParam+i; - - hres = deserialize_param( - tinfo, - is_in_elem(elem), - FALSE, - TRUE, - &(elem->tdesc), - xargs, - &buf - ); - xargs += _argsize(&elem->tdesc, tinfo); - if (hres) { - ERR("Failed to deserialize param %s, hres %x\n",relaystr(names[i+1]),hres); - break; - } - } - - args[0] = (DWORD_PTR)This->pUnk; - - __TRY - { - res = _invoke( - (*((FARPROC**)args[0]))[fdesc->oVft / sizeof(DWORD_PTR)], - fdesc->callconv, - (xargs-args), - args - ); - } - __EXCEPT_ALL - { - DWORD dwExceptionCode = GetExceptionCode(); - ERR("invoke call failed with exception 0x%08x (%d)\n", dwExceptionCode, dwExceptionCode); - if (FAILED(dwExceptionCode)) - hres = dwExceptionCode; - else - hres = HRESULT_FROM_WIN32(dwExceptionCode); - } - __ENDTRY - - if (hres != S_OK) - goto exit; - - buf.curoff = 0; - - xargs = args+1; - for (i=0;icParams;i++) { - ELEMDESC *elem = fdesc->lprgelemdescParam+i; - hres = serialize_param( - tinfo, - is_out_elem(elem), - FALSE, - TRUE, - &elem->tdesc, - xargs, - &buf - ); - xargs += _argsize(&elem->tdesc, tinfo); - if (hres) { - ERR("Failed to stuballoc param, hres %x\n",hres); - break; - } - } - - hres = xbuf_add (&buf, (LPBYTE)&res, sizeof(DWORD)); - - if (hres != S_OK) - goto exit; - - xmsg->cbBuffer = buf.curoff; - hres = IRpcChannelBuffer_GetBuffer(rpcchanbuf, xmsg, &This->iid); - if (hres != S_OK) - ERR("IRpcChannelBuffer_GetBuffer failed with error 0x%08x\n", hres); - - if (hres == S_OK) - memcpy(xmsg->Buffer, buf.base, buf.curoff); - -exit: - for (i = 0; i < nrofnames; i++) - SysFreeString(names[i]); - - ITypeInfo_Release(tinfo); - HeapFree(GetProcessHeap(), 0, args); - - HeapFree(GetProcessHeap(), 0, buf.base); - - TRACE("returning\n"); - return hres; -#else - FIXME( "not implemented on non-i386\n" ); - return E_FAIL; -#endif -} - -static LPRPCSTUBBUFFER WINAPI -TMStubImpl_IsIIDSupported(LPRPCSTUBBUFFER iface, REFIID riid) { - FIXME("Huh (%s)?\n",debugstr_guid(riid)); - return NULL; -} - -static ULONG WINAPI -TMStubImpl_CountRefs(LPRPCSTUBBUFFER iface) { - TMStubImpl *This = impl_from_IRpcStubBuffer(iface); - - FIXME("()\n"); - return This->ref; /*FIXME? */ -} - -static HRESULT WINAPI -TMStubImpl_DebugServerQueryInterface(LPRPCSTUBBUFFER iface, LPVOID *ppv) { - return E_NOTIMPL; -} - -static void WINAPI -TMStubImpl_DebugServerRelease(LPRPCSTUBBUFFER iface, LPVOID ppv) { - return; -} - -static const IRpcStubBufferVtbl tmstubvtbl = { - TMStubImpl_QueryInterface, - TMStubImpl_AddRef, - TMStubImpl_Release, - TMStubImpl_Connect, - TMStubImpl_Disconnect, - TMStubImpl_Invoke, - TMStubImpl_IsIIDSupported, - TMStubImpl_CountRefs, - TMStubImpl_DebugServerQueryInterface, - TMStubImpl_DebugServerRelease -}; - -static HRESULT WINAPI -PSFacBuf_CreateStub( - LPPSFACTORYBUFFER iface, REFIID riid,IUnknown *pUnkServer, - IRpcStubBuffer** ppStub -) { - HRESULT hres; - ITypeInfo *tinfo; - TMStubImpl *stub; - TYPEATTR *typeattr; - IUnknown *obj; - - TRACE("(%s,%p,%p)\n",debugstr_guid(riid),pUnkServer,ppStub); - - hres = _get_typeinfo_for_iid(riid,&tinfo); - if (hres) { - ERR("No typeinfo for %s?\n",debugstr_guid(riid)); - return hres; - } - - /* FIXME: This is not exactly right. We should probably call QI later. */ - hres = IUnknown_QueryInterface(pUnkServer, riid, (void**)&obj); - if (FAILED(hres)) { - WARN("Could not get %s iface: %08x\n", debugstr_guid(riid), hres); - obj = pUnkServer; - IUnknown_AddRef(obj); - } - - stub = CoTaskMemAlloc(sizeof(TMStubImpl)); - if (!stub) { - IUnknown_Release(obj); - return E_OUTOFMEMORY; - } - stub->IRpcStubBuffer_iface.lpVtbl = &tmstubvtbl; - stub->ref = 1; - stub->tinfo = tinfo; - stub->dispatch_stub = NULL; - stub->dispatch_derivative = FALSE; - stub->iid = *riid; - hres = IRpcStubBuffer_Connect(&stub->IRpcStubBuffer_iface, obj); - *ppStub = &stub->IRpcStubBuffer_iface; - TRACE("IRpcStubBuffer: %p\n", stub); - if (hres) - ERR("Connect to pUnkServer failed?\n"); - - /* if we derive from IDispatch then defer to its stub for some of its methods */ - hres = ITypeInfo_GetTypeAttr(tinfo, &typeattr); - if (hres == S_OK) - { - if (typeattr->wTypeFlags & TYPEFLAG_FDISPATCHABLE) - stub->dispatch_derivative = TRUE; - ITypeInfo_ReleaseTypeAttr(tinfo, typeattr); - } - - IUnknown_Release(obj); - return hres; -} - -static const IPSFactoryBufferVtbl psfacbufvtbl = { - PSFacBuf_QueryInterface, - PSFacBuf_AddRef, - PSFacBuf_Release, - PSFacBuf_CreateProxy, - PSFacBuf_CreateStub -}; - -static IPSFactoryBuffer psfac = { &psfacbufvtbl }; - -/*********************************************************************** - * TMARSHAL_DllGetClassObject - */ -HRESULT TMARSHAL_DllGetClassObject(REFCLSID rclsid, REFIID iid, void **ppv) -{ - return IPSFactoryBuffer_QueryInterface(&psfac, iid, ppv); -} diff --git a/dll/win32/oleaut32/typelib.c b/dll/win32/oleaut32/typelib.c index 4a609d70503..6ed9ce9eb73 100644 --- a/dll/win32/oleaut32/typelib.c +++ b/dll/win32/oleaut32/typelib.c @@ -328,7 +328,7 @@ static HRESULT query_typelib_path( REFGUID guid, WORD wMaj, WORD wMin, return TYPE_E_LIBNOTREGISTERED; nameW = (WCHAR*)((BYTE*)data.lpSectionBase + tlib->name_offset); - len = SearchPathW( NULL, nameW, NULL, sizeof(Path)/sizeof(WCHAR), Path, NULL ); + len = SearchPathW( NULL, nameW, NULL, ARRAY_SIZE( Path ), Path, NULL ); if (!len) return TYPE_E_LIBNOTREGISTERED; TRACE_(typelib)("got path from context %s\n", debugstr_w(Path)); @@ -979,11 +979,11 @@ enddeleteloop: /* check if there is anything besides the FLAGS/HELPDIR keys. If there is, we don't delete them */ - tmpLength = sizeof(subKeyName)/sizeof(WCHAR); + tmpLength = ARRAY_SIZE(subKeyName); deleteOtherStuff = TRUE; i = 0; while(RegEnumKeyExW(key, i++, subKeyName, &tmpLength, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) { - tmpLength = sizeof(subKeyName)/sizeof(WCHAR); + tmpLength = ARRAY_SIZE(subKeyName); /* if its not FLAGS or HELPDIR, then we must keep the rest of the key */ if (!strcmpW(subKeyName, FLAGSW)) continue; @@ -2685,7 +2685,7 @@ static ITypeInfoImpl * MSFT_DoTypeInfo( ptiRet->typeattr.wMajorVerNum = LOWORD(tiBase.version); ptiRet->typeattr.wMinorVerNum = HIWORD(tiBase.version); ptiRet->typeattr.cImplTypes = tiBase.cImplTypes; - ptiRet->typeattr.cbSizeVft = tiBase.cbSizeVft; /* FIXME: this is only the non inherited part */ + ptiRet->typeattr.cbSizeVft = tiBase.cbSizeVft; if (ptiRet->typeattr.typekind == TKIND_ALIAS) { TYPEDESC tmp; MSFT_GetTdesc(pcx, tiBase.datatype1, &tmp); @@ -6405,6 +6405,7 @@ static HRESULT WINAPI ITypeInfo_fnGetIDsOfNames( ITypeInfo2 *iface, #ifdef __i386__ extern LONGLONG call_method( void *func, int nb_args, const DWORD *args, int *stack_offset ); +extern double call_double_method( void *func, int nb_args, const DWORD *args, int *stack_offset ); __ASM_GLOBAL_FUNC( call_method, "pushl %ebp\n\t" __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") @@ -6439,45 +6440,13 @@ __ASM_GLOBAL_FUNC( call_method, __ASM_CFI(".cfi_def_cfa %esp,4\n\t") __ASM_CFI(".cfi_same_value %ebp\n\t") "ret" ) - -/* same function but returning floating point */ -static double (* const call_double_method)(void*,int,const DWORD*,int*) = (void *)call_method; - -/* ITypeInfo::Invoke - * - * Invokes a method, or accesses a property of an object, that implements the - * interface described by the type description. - */ -DWORD _invoke(FARPROC func, CALLCONV callconv, int nrargs, DWORD_PTR *args) -{ - DWORD res; - int stack_offset; - - if (TRACE_ON(ole)) { - int i; - TRACE("Calling %p(",func); - for (i=0;i 30) TRACE("..."); - TRACE(")\n"); - } - - switch (callconv) { - case CC_STDCALL: - case CC_CDECL: - res = call_method(func, nrargs, (DWORD *)args, &stack_offset); - break; - default: - FIXME("unsupported calling convention %d\n",callconv); - res = -1; - break; - } - TRACE("returns %08x\n",res); - return res; -} +__ASM_GLOBAL_FUNC( call_double_method, + "jmp " __ASM_NAME("call_method") ) #elif defined(__x86_64__) extern DWORD_PTR CDECL call_method( void *func, int nb_args, const DWORD_PTR *args ); +extern double CDECL call_double_method( void *func, int nb_args, const DWORD_PTR *args ); __ASM_GLOBAL_FUNC( call_method, "pushq %rbp\n\t" __ASM_CFI(".cfi_adjust_cfa_offset 8\n\t") @@ -6517,41 +6486,14 @@ __ASM_GLOBAL_FUNC( call_method, __ASM_CFI(".cfi_adjust_cfa_offset -8\n\t") __ASM_CFI(".cfi_same_value %rbp\n\t") "ret") - -/* same function but returning floating point */ -static double (CDECL * const call_double_method)(void*,int,const DWORD_PTR*) = (void *)call_method; - -DWORD _invoke(FARPROC func, CALLCONV callconv, int nrargs, DWORD_PTR *args) -{ - DWORD res; - - if (TRACE_ON(ole)) - { - int i; - TRACE("Calling %p(", func); - for (i=0; i 30) TRACE("..."); - TRACE(")\n"); - } - - switch (callconv) { - case CC_STDCALL: - case CC_CDECL: - res = call_method(func, nrargs, args); - break; - default: - FIXME("unsupported calling convention %d\n", callconv); - res = -1; - break; - } - - TRACE("returns %08x\n", res); - return res; -} +__ASM_GLOBAL_FUNC( call_double_method, + "jmp " __ASM_NAME("call_method") ) #elif defined(__arm__) extern LONGLONG CDECL call_method( void *func, int nb_stk_args, const DWORD *stk_args, const DWORD *reg_args ); +extern float CDECL call_float_method( void *func, int nb_stk_args, const DWORD *stk_args, const DWORD *reg_args ); +extern double CDECL call_double_method( void *func, int nb_stk_args, const DWORD *stk_args, const DWORD *reg_args ); __ASM_GLOBAL_FUNC( call_method, /* r0 = *func * r1 = nb_stk_args @@ -6582,12 +6524,12 @@ __ASM_GLOBAL_FUNC( call_method, "mov sp, fp\n\t" /* Clean the stack using fp */ "pop {fp, pc}\n\t" /* Restore fp and return */ ) +__ASM_GLOBAL_FUNC( call_float_method, + "b " __ASM_NAME("call_method") ) +__ASM_GLOBAL_FUNC( call_double_method, + "b " __ASM_NAME("call_method") ) -/* same function but returning single/double floating point */ -static float (CDECL * const call_float_method)(void *, int, const DWORD *, const DWORD *) = (void *)call_method; -static double (CDECL * const call_double_method)(void *, int, const DWORD *, const DWORD *) = (void *)call_method; - -#endif /* __x86_64__ */ +#endif /* __arm__ */ static HRESULT userdefined_to_variantvt(ITypeInfo *tinfo, const TYPEDESC *tdesc, VARTYPE *vt) { @@ -6728,6 +6670,7 @@ static HRESULT get_iface_guid(ITypeInfo *tinfo, HREFTYPE href, GUID *guid) ITypeInfo *tinfo2; TYPEATTR *tattr; HRESULT hres; + int flags, i; hres = ITypeInfo_GetRefTypeInfo(tinfo, href, &tinfo2); if(FAILED(hres)) @@ -6749,20 +6692,21 @@ static HRESULT get_iface_guid(ITypeInfo *tinfo, HREFTYPE href, GUID *guid) *guid = tattr->guid; break; - case TKIND_COCLASS: { - unsigned int i; - int type_flags; + case TKIND_COCLASS: + for (i = 0; i < tattr->cImplTypes; i++) + { + ITypeInfo_GetImplTypeFlags(tinfo2, i, &flags); + if (flags & IMPLTYPEFLAG_FDEFAULT) + break; + } - for(i = 0; i < tattr->cImplTypes; i++) - if(SUCCEEDED(ITypeInfo_GetImplTypeFlags(tinfo2, i, &type_flags)) && - type_flags == (IMPLTYPEFLAG_FSOURCE|IMPLTYPEFLAG_FDEFAULT)) break; + if (i == tattr->cImplTypes) + i = 0; - if(i < tattr->cImplTypes) { - hres = ITypeInfo_GetRefTypeOfImplType(tinfo2, i, &href); - if(SUCCEEDED(hres)) hres = get_iface_guid(tinfo2, href, guid); - } else hres = E_UNEXPECTED; + hres = ITypeInfo_GetRefTypeOfImplType(tinfo2, i, &href); + if (SUCCEEDED(hres)) + hres = get_iface_guid(tinfo2, href, guid); break; - } default: ERR("Unexpected typekind %d\n", tattr->typekind); @@ -6818,7 +6762,7 @@ DispCallFunc( VARTYPE* prgvt, VARIANTARG** prgpvarg, VARIANT* pvargResult) { #ifdef __i386__ - int argspos, stack_offset; + int argspos = 0, stack_offset; void *func; UINT i; DWORD *args; @@ -6836,8 +6780,6 @@ DispCallFunc( /* maximum size for an argument is sizeof(VARIANT) */ args = heap_alloc(sizeof(VARIANT) * cActuals + sizeof(DWORD) * 2 ); - /* start at 1 in case we need to pass a pointer to the return value as arg 0 */ - argspos = 1; if (pvInstance) { const FARPROC *vtable = *(FARPROC **)pvInstance; @@ -6846,6 +6788,20 @@ DispCallFunc( } else func = (void *)oVft; + switch (vtReturn) + { + case VT_DECIMAL: + case VT_VARIANT: + args[argspos++] = (DWORD)pvargResult; /* arg 0 is a pointer to the result */ + break; + case VT_HRESULT: + WARN("invalid return type %u\n", vtReturn); + heap_free( args ); + return E_INVALIDARG; + default: + break; + } + for (i = 0; i < cActuals; i++) { VARIANT *arg = prgpvarg[i]; @@ -6880,40 +6836,24 @@ DispCallFunc( switch (vtReturn) { case VT_EMPTY: - call_method( func, argspos - 1, args + 1, &stack_offset ); + case VT_DECIMAL: + case VT_VARIANT: + call_method( func, argspos, args, &stack_offset ); break; case VT_R4: - V_R4(pvargResult) = call_double_method( func, argspos - 1, args + 1, &stack_offset ); + V_R4(pvargResult) = call_double_method( func, argspos, args, &stack_offset ); break; case VT_R8: case VT_DATE: - V_R8(pvargResult) = call_double_method( func, argspos - 1, args + 1, &stack_offset ); - break; - case VT_DECIMAL: - case VT_VARIANT: - if (pvInstance) - { - args[0] = (DWORD)pvInstance; /* arg 0 is a pointer to the instance */ - args[1] = (DWORD)pvargResult; /* arg 1 is a pointer to the result */ - call_method( func, argspos, args, &stack_offset ); - } - else - { - args[0] = (DWORD)pvargResult; /* arg 0 is a pointer to the result */ - call_method( func, argspos, args, &stack_offset ); - } + V_R8(pvargResult) = call_double_method( func, argspos, args, &stack_offset ); break; case VT_I8: case VT_UI8: case VT_CY: - V_UI8(pvargResult) = call_method( func, argspos - 1, args + 1, &stack_offset ); + V_UI8(pvargResult) = call_method( func, argspos, args, &stack_offset ); break; - case VT_HRESULT: - WARN("invalid return type %u\n", vtReturn); - heap_free( args ); - return E_INVALIDARG; default: - V_UI4(pvargResult) = call_method( func, argspos - 1, args + 1, &stack_offset ); + V_UI4(pvargResult) = call_method( func, argspos, args, &stack_offset ); break; } heap_free( args ); @@ -6927,7 +6867,7 @@ DispCallFunc( return S_OK; #elif defined(__x86_64__) - int argspos; + int argspos = 0; UINT i; DWORD_PTR *args; void *func; @@ -6945,8 +6885,6 @@ DispCallFunc( /* maximum size for an argument is sizeof(DWORD_PTR) */ args = heap_alloc( sizeof(DWORD_PTR) * (cActuals + 2) ); - /* start at 1 in case we need to pass a pointer to the return value as arg 0 */ - argspos = 1; if (pvInstance) { const FARPROC *vtable = *(FARPROC **)pvInstance; @@ -6955,6 +6893,20 @@ DispCallFunc( } else func = (void *)oVft; + switch (vtReturn) + { + case VT_DECIMAL: + case VT_VARIANT: + args[argspos++] = (DWORD_PTR)pvargResult; /* arg 0 is a pointer to the result */ + break; + case VT_HRESULT: + WARN("invalid return type %u\n", vtReturn); + heap_free( args ); + return E_INVALIDARG; + default: + break; + } + for (i = 0; i < cActuals; i++) { VARIANT *arg = prgpvarg[i]; @@ -6978,32 +6930,18 @@ DispCallFunc( switch (vtReturn) { case VT_R4: - V_R4(pvargResult) = call_double_method( func, argspos - 1, args + 1 ); + V_R4(pvargResult) = call_double_method( func, argspos, args ); break; case VT_R8: case VT_DATE: - V_R8(pvargResult) = call_double_method( func, argspos - 1, args + 1 ); + V_R8(pvargResult) = call_double_method( func, argspos, args ); break; case VT_DECIMAL: case VT_VARIANT: - if (pvInstance) - { - args[0] = (DWORD_PTR)pvInstance; /* arg 0 is a pointer to the instance */ - args[1] = (DWORD_PTR)pvargResult; /* arg 1 is a pointer to the result */ - call_method( func, argspos, args ); - } - else - { - args[0] = (DWORD_PTR)pvargResult; /* arg 0 is a pointer to the result */ - call_method( func, argspos, args ); - } + call_method( func, argspos, args ); break; - case VT_HRESULT: - WARN("invalid return type %u\n", vtReturn); - heap_free( args ); - return E_INVALIDARG; default: - V_UI8(pvargResult) = call_method( func, argspos - 1, args + 1 ); + V_UI8(pvargResult) = call_method( func, argspos, args ); break; } heap_free( args ); @@ -7043,6 +6981,14 @@ DispCallFunc( argspos = 0; rcount = 0; + if (pvInstance) + { + const FARPROC *vtable = *(FARPROC **)pvInstance; + func = vtable[oVft/sizeof(void *)]; + regs.r[rcount++] = (DWORD)pvInstance; /* the This pointer is always the first parameter */ + } + else func = (void *)oVft; + /* Determine if we need to pass a pointer for the return value as arg 0. If so, do that */ /* first as it will need to be in the 'r' registers: */ switch (vtReturn) @@ -7058,14 +7004,6 @@ DispCallFunc( break; } - if (pvInstance) - { - const FARPROC *vtable = *(FARPROC **)pvInstance; - func = vtable[oVft/sizeof(void *)]; - regs.r[rcount++] = (DWORD)pvInstance; /* the This pointer is always the first parameter */ - } - else func = (void *)oVft; - /* maximum size for an argument is sizeof(VARIANT). Also allow for return pointer and stack alignment. */ args = heap_alloc( sizeof(VARIANT) * cActuals + sizeof(DWORD) * 4 ); @@ -7912,7 +7850,7 @@ static BOOL CALLBACK search_res_tlb(HMODULE hModule, LPCWSTR lpszType, LPWSTR lp if (!(len = GetModuleFileNameW(hModule, szPath, MAX_PATH))) return TRUE; - if (snprintfW(szPath + len, sizeof(szPath)/sizeof(WCHAR) - len, formatW, LOWORD(lpszName)) < 0) + if (snprintfW(szPath + len, ARRAY_SIZE(szPath) - len, formatW, LOWORD(lpszName)) < 0) return TRUE; ret = LoadTypeLibEx(szPath, REGKIND_NONE, &pTLib); diff --git a/dll/win32/oleaut32/typelib.h b/dll/win32/oleaut32/typelib.h index bfea174bc01..4ab8055bd2a 100644 --- a/dll/win32/oleaut32/typelib.h +++ b/dll/win32/oleaut32/typelib.h @@ -142,11 +142,11 @@ typedef struct tagMSFT_TypeInfoBase { INT helpcontext; /* */ INT oCustData; /* offset in customer data table */ #ifdef WORDS_BIGENDIAN - INT16 cbSizeVft; /* virtual table size, not including inherits */ + INT16 cbSizeVft; /* virtual table size, including inherits */ INT16 cImplTypes; /* nr of implemented interfaces */ #else INT16 cImplTypes; /* nr of implemented interfaces */ - INT16 cbSizeVft; /* virtual table size, not including inherits */ + INT16 cbSizeVft; /* virtual table size, including inherits */ #endif /*050*/ INT size; /* size in bytes, at least for structures */ /* FIXME: name of this field */ @@ -155,10 +155,8 @@ typedef struct tagMSFT_TypeInfoBase { /* if coclass: offset in reftable */ /* if interface: reference to inherited if */ /* if module: offset to dllname in name table */ - INT datatype2; /* if 0x8000, entry above is valid */ - /* actually dunno */ - /* else it is zero? */ - /* if interface: inheritance level | no of inherited funcs */ + INT datatype2; /* for interfaces: hiword is num of inherited funcs */ + /* loword is num of inherited interfaces */ INT res18; /* always? 0 */ /*060*/ INT res19; /* always? -1 */ } MSFT_TypeInfoBase; @@ -281,9 +279,10 @@ typedef struct { to the typeinfo itself or to a member of the typeinfo */ INT next_hash; /* offset to next name in the hash bucket */ - INT namelen; /* only lower 8 bits are valid, - lower-middle 8 bits are unknown (flags?), - upper 16 bits are hash code */ + INT namelen; /* only lower 8 bits are valid */ + /* 0x1000 if name is only used once as a variable name */ + /* 0x2000 if name is a variable in an enumeration */ + /* 0x3800 if name is typeinfo name */ } MSFT_NameIntro; /* the custom data table directory has entries like this */ typedef struct { @@ -596,12 +595,6 @@ WORD typeofarray #include "poppack.h" -HRESULT ITypeInfoImpl_GetInternalFuncDesc( ITypeInfo *iface, UINT index, const FUNCDESC **ppFuncDesc ) DECLSPEC_HIDDEN; - -extern DWORD _invoke(FARPROC func, CALLCONV callconv, int nrargs, DWORD_PTR *args) DECLSPEC_HIDDEN; - -HRESULT TMARSHAL_DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv) DECLSPEC_HIDDEN; - /* The OLE Automation ProxyStub Interface Class (aka Typelib Marshaler) */ DEFINE_OLEGUID( CLSID_PSDispatch, 0x00020420, 0x0000, 0x0000 ); DEFINE_OLEGUID( CLSID_PSEnumVariant, 0x00020421, 0x0000, 0x0000 ); diff --git a/dll/win32/oleaut32/usrmarshal.c b/dll/win32/oleaut32/usrmarshal.c index da524c85ebb..163b48f6f46 100644 --- a/dll/win32/oleaut32/usrmarshal.c +++ b/dll/win32/oleaut32/usrmarshal.c @@ -227,6 +227,9 @@ unsigned int get_type_size(ULONG *pFlags, VARTYPE vt) case VT_INT: case VT_UINT: return sizeof(INT); + case VT_I8: + case VT_UI8: + return sizeof(LONGLONG); case VT_R4: return sizeof(FLOAT); case VT_R8: @@ -644,7 +647,8 @@ void WINAPI VARIANT_UserFree(ULONG *pFlags, VARIANT *pvar) break; case VT_UNKNOWN | VT_BYREF: case VT_DISPATCH | VT_BYREF: - IUnknown_Release(*V_UNKNOWNREF(pvar)); + if (*V_UNKNOWNREF(pvar)) + IUnknown_Release(*V_UNKNOWNREF(pvar)); break; } } diff --git a/dll/win32/oleaut32/varformat.c b/dll/win32/oleaut32/varformat.c index 696763e7ed7..470ea4e01b7 100644 --- a/dll/win32/oleaut32/varformat.c +++ b/dll/win32/oleaut32/varformat.c @@ -449,8 +449,7 @@ static inline const BYTE *VARIANT_GetNamedFormat(LPCWSTR lpszFormat) LPCNAMED_FORMAT fmt; key.name = lpszFormat; - fmt = bsearch(&key, VARIANT_NamedFormats, - sizeof(VARIANT_NamedFormats)/sizeof(NAMED_FORMAT), + fmt = bsearch(&key, VARIANT_NamedFormats, ARRAY_SIZE(VARIANT_NamedFormats), sizeof(NAMED_FORMAT), FormatCompareFn); return fmt ? fmt->format : NULL; } @@ -764,7 +763,7 @@ HRESULT WINAPI VarTokenizeFormatString(LPOLESTR lpszFormat, LPBYTE rgbTok, TRACE("time sep\n"); } else if ((*pFormat == 'a' || *pFormat == 'A') && - !strncmpiW(pFormat, szAMPM, sizeof(szAMPM)/sizeof(WCHAR))) + !strncmpiW(pFormat, szAMPM, ARRAY_SIZE(szAMPM))) { /* Date formats: System AM/PM designation * Other formats: Literal @@ -772,8 +771,8 @@ HRESULT WINAPI VarTokenizeFormatString(LPOLESTR lpszFormat, LPBYTE rgbTok, */ header->type = FMT_TYPE_DATE; NEED_SPACE(sizeof(BYTE)); - pFormat += sizeof(szAMPM)/sizeof(WCHAR); - if (!strncmpW(pFormat, szampm, sizeof(szampm)/sizeof(WCHAR))) + pFormat += ARRAY_SIZE(szAMPM); + if (!strncmpW(pFormat, szampm, ARRAY_SIZE(szampm))) *pOut++ = FMT_DATE_AMPM_SYS2; else *pOut++ = FMT_DATE_AMPM_SYS1; @@ -811,8 +810,7 @@ HRESULT WINAPI VarTokenizeFormatString(LPOLESTR lpszFormat, LPBYTE rgbTok, *pLastHours = *pLastHours + 2; TRACE("A/P\n"); } - else if (*pFormat == 'a' && - !strncmpW(pFormat, szamSlashpm, sizeof(szamSlashpm)/sizeof(WCHAR))) + else if (*pFormat == 'a' && !strncmpW(pFormat, szamSlashpm, ARRAY_SIZE(szamSlashpm))) { /* Date formats: lowercase AM or PM designation * Other formats: Literal @@ -820,14 +818,13 @@ HRESULT WINAPI VarTokenizeFormatString(LPOLESTR lpszFormat, LPBYTE rgbTok, */ header->type = FMT_TYPE_DATE; NEED_SPACE(sizeof(BYTE)); - pFormat += sizeof(szamSlashpm)/sizeof(WCHAR); + pFormat += ARRAY_SIZE(szamSlashpm); *pOut++ = FMT_DATE_AMPM_LOWER; if (pLastHours) *pLastHours = *pLastHours + 2; TRACE("AM/PM\n"); } - else if (*pFormat == 'A' && - !strncmpW(pFormat, szAMSlashPM, sizeof(szAMSlashPM)/sizeof(WCHAR))) + else if (*pFormat == 'A' && !strncmpW(pFormat, szAMSlashPM, ARRAY_SIZE(szAMSlashPM))) { /* Date formats: Uppercase AM or PM designation * Other formats: Literal @@ -835,7 +832,7 @@ HRESULT WINAPI VarTokenizeFormatString(LPOLESTR lpszFormat, LPBYTE rgbTok, */ header->type = FMT_TYPE_DATE; NEED_SPACE(sizeof(BYTE)); - pFormat += sizeof(szAMSlashPM)/sizeof(WCHAR); + pFormat += ARRAY_SIZE(szAMSlashPM); *pOut++ = FMT_DATE_AMPM_UPPER; TRACE("AM/PM\n"); } @@ -847,7 +844,7 @@ HRESULT WINAPI VarTokenizeFormatString(LPOLESTR lpszFormat, LPBYTE rgbTok, */ header->type = FMT_TYPE_DATE; NEED_SPACE(sizeof(BYTE)); - pFormat += sizeof(szAMSlashPM)/sizeof(WCHAR); + pFormat += ARRAY_SIZE(szAMSlashPM); *pOut++ = FMT_DATE_GENERAL; TRACE("gen date\n"); } @@ -989,14 +986,14 @@ HRESULT WINAPI VarTokenizeFormatString(LPOLESTR lpszFormat, LPBYTE rgbTok, fmt_state &= ~FMT_STATE_OPEN_COPY; } else if ((*pFormat == 't' || *pFormat == 'T') && - !strncmpiW(pFormat, szTTTTT, sizeof(szTTTTT)/sizeof(WCHAR))) + !strncmpiW(pFormat, szTTTTT, ARRAY_SIZE(szTTTTT))) { /* Date formats: System time specifier * Other formats: Literal * Types the format if found */ header->type = FMT_TYPE_DATE; - pFormat += sizeof(szTTTTT)/sizeof(WCHAR); + pFormat += ARRAY_SIZE(szTTTTT); NEED_SPACE(sizeof(BYTE)); *pOut++ = FMT_DATE_TIME_SYS; fmt_state &= ~FMT_STATE_OPEN_COPY; @@ -1316,8 +1313,7 @@ static HRESULT VARIANT_FormatNumber(LPVARIANT pVarIn, LPOLESTR lpszFormat, if (numHeader->flags & FMT_FLAG_THOUSANDS) { - if (!GetLocaleInfoW(lcid, LOCALE_STHOUSAND, thousandSeparator, - sizeof(thousandSeparator)/sizeof(WCHAR))) + if (!GetLocaleInfoW(lcid, LOCALE_STHOUSAND, thousandSeparator, ARRAY_SIZE(thousandSeparator))) { thousandSeparator[0] = ','; thousandSeparator[1] = 0; @@ -1555,8 +1551,7 @@ VARIANT_FormatNumber_Bool: } if (localeValue) { - if (GetLocaleInfoW(lcid, localeValue, pBuff, - sizeof(buff)/sizeof(WCHAR)-(pBuff-buff))) + if (GetLocaleInfoW(lcid, localeValue, pBuff, ARRAY_SIZE(buff)-(pBuff-buff))) { TRACE("added %s\n", debugstr_w(pBuff)); while (*pBuff) @@ -1875,8 +1870,7 @@ static HRESULT VARIANT_FormatDate(LPVARIANT pVarIn, LPOLESTR lpszFormat, if (localeValue) { *pBuff = '\0'; - if (GetLocaleInfoW(lcid, localeValue, pBuff, - sizeof(buff)/sizeof(WCHAR)-(pBuff-buff))) + if (GetLocaleInfoW(lcid, localeValue, pBuff, ARRAY_SIZE(buff)-(pBuff-buff))) { TRACE("added %s\n", debugstr_w(pBuff)); while (*pBuff) @@ -1892,9 +1886,8 @@ static HRESULT VARIANT_FormatDate(LPVARIANT pVarIn, LPOLESTR lpszFormat, { WCHAR fmt_buff[80]; - if (!GetLocaleInfoW(lcid, dwFmt, fmt_buff, sizeof(fmt_buff)/sizeof(WCHAR)) || - !get_date_format(lcid, 0, &udate.st, fmt_buff, pBuff, - sizeof(buff)/sizeof(WCHAR)-(pBuff-buff))) + if (!GetLocaleInfoW(lcid, dwFmt, fmt_buff, ARRAY_SIZE(fmt_buff)) || + !get_date_format(lcid, 0, &udate.st, fmt_buff, pBuff, ARRAY_SIZE(buff)-(pBuff-buff))) { hRes = E_INVALIDARG; goto VARIANT_FormatDate_Exit; @@ -2293,8 +2286,7 @@ HRESULT WINAPI VarFormatNumber(LPVARIANT pVarIn, INT nDigits, INT nLeading, INT { WCHAR grouping[16]; grouping[2] = '\0'; - GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, grouping, - sizeof(grouping)/sizeof(WCHAR)); + GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, grouping, ARRAY_SIZE(grouping)); numfmt.Grouping = grouping[2] == '2' ? 32 : grouping[0] - '0'; } else if (nGrouping == -1) @@ -2310,14 +2302,11 @@ HRESULT WINAPI VarFormatNumber(LPVARIANT pVarIn, INT nDigits, INT nLeading, INT numfmt.NegativeOrder = 1; /* 1 = "-xxx" */ numfmt.lpDecimalSep = decimal; - GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, decimal, - sizeof(decimal)/sizeof(WCHAR)); + GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, decimal, ARRAY_SIZE(decimal)); numfmt.lpThousandSep = thousands; - GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, thousands, - sizeof(thousands)/sizeof(WCHAR)); + GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, thousands, ARRAY_SIZE(thousands)); - if (GetNumberFormatW(LOCALE_USER_DEFAULT, 0, V_BSTR(&vStr), &numfmt, - buff, sizeof(buff)/sizeof(WCHAR))) + if (GetNumberFormatW(LOCALE_USER_DEFAULT, 0, V_BSTR(&vStr), &numfmt, buff, ARRAY_SIZE(buff))) { *pbstrOut = SysAllocString(buff); if (!*pbstrOut) @@ -2473,8 +2462,7 @@ HRESULT WINAPI VarFormatCurrency(LPVARIANT pVarIn, INT nDigits, INT nLeading, { WCHAR grouping[16]; grouping[2] = '\0'; - GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, grouping, - sizeof(grouping)/sizeof(WCHAR)); + GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, grouping, ARRAY_SIZE(grouping)); numfmt.Grouping = grouping[2] == '2' ? 32 : grouping[0] - '0'; } else if (nGrouping == -1) @@ -2492,18 +2480,14 @@ HRESULT WINAPI VarFormatCurrency(LPVARIANT pVarIn, INT nDigits, INT nLeading, GETLOCALENUMBER(LOCALE_ICURRENCY, PositiveOrder); numfmt.lpDecimalSep = decimal; - GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, decimal, - sizeof(decimal)/sizeof(WCHAR)); + GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, decimal, ARRAY_SIZE(decimal)); numfmt.lpThousandSep = thousands; - GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, thousands, - sizeof(thousands)/sizeof(WCHAR)); + GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, thousands, ARRAY_SIZE(thousands)); numfmt.lpCurrencySymbol = currency; - GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, currency, - sizeof(currency)/sizeof(WCHAR)); + GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, currency, ARRAY_SIZE(currency)); /* use NLS as per VarFormatNumber() */ - if (GetCurrencyFormatW(LOCALE_USER_DEFAULT, 0, V_BSTR(&vStr), &numfmt, - buff, sizeof(buff)/sizeof(WCHAR))) + if (GetCurrencyFormatW(LOCALE_USER_DEFAULT, 0, V_BSTR(&vStr), &numfmt, buff, ARRAY_SIZE(buff))) { *pbstrOut = SysAllocString(buff); if (!*pbstrOut) diff --git a/dll/win32/oleaut32/variant.c b/dll/win32/oleaut32/variant.c index b9cf4b0a002..fcbef5317fd 100644 --- a/dll/win32/oleaut32/variant.c +++ b/dll/win32/oleaut32/variant.c @@ -648,7 +648,7 @@ HRESULT VARIANT_ClearInd(VARIANTARG *pVarg) * Success: S_OK. Any previous value in pVarg is freed and its type is set to VT_EMPTY. * Failure: DISP_E_BADVARTYPE, if the variant is not a valid variant type. */ -HRESULT WINAPI VariantClear(VARIANTARG* pVarg) +HRESULT WINAPI DECLSPEC_HOTPATCH VariantClear(VARIANTARG* pVarg) { HRESULT hres; @@ -962,8 +962,8 @@ VariantCopyInd_Return: * The LCID used for the conversion is LOCALE_USER_DEFAULT. * See VariantChangeTypeEx. */ -HRESULT WINAPI VariantChangeType(VARIANTARG* pvargDest, VARIANTARG* pvargSrc, - USHORT wFlags, VARTYPE vt) +HRESULT WINAPI DECLSPEC_HOTPATCH VariantChangeType(VARIANTARG* pvargDest, VARIANTARG* pvargSrc, + USHORT wFlags, VARTYPE vt) { return VariantChangeTypeEx( pvargDest, pvargSrc, LOCALE_USER_DEFAULT, wFlags, vt ); } @@ -1549,7 +1549,7 @@ static void VARIANT_GetLocalisedNumberChars(VARIANT_NUMBER_CHARS *lpChars, LCID /* Local currency symbols are often 2 characters */ lpChars->cCurrencyLocal2 = '\0'; - switch(GetLocaleInfoW(lcid, lctype|LOCALE_SCURRENCY, buff, sizeof(buff)/sizeof(WCHAR))) + switch(GetLocaleInfoW(lcid, lctype|LOCALE_SCURRENCY, buff, ARRAY_SIZE(buff))) { case 3: lpChars->cCurrencyLocal2 = buff[1]; /* Fall through */ case 2: lpChars->cCurrencyLocal = buff[0]; @@ -1610,7 +1610,7 @@ HRESULT WINAPI VarParseNumFromStr(OLECHAR *lpszStr, LCID lcid, ULONG dwFlags, VARIANT_NUMBER_CHARS chars; BYTE rgbTmp[1024]; DWORD dwState = B_EXPONENT_START|B_INEXACT_ZEROS; - int iMaxDigits = sizeof(rgbTmp) / sizeof(BYTE); + int iMaxDigits = ARRAY_SIZE(rgbTmp); int cchUsed = 0; TRACE("(%s,%d,0x%08x,%p,%p)\n", debugstr_w(lpszStr), lcid, dwFlags, pNumprs, rgbDig); @@ -5134,7 +5134,21 @@ HRESULT WINAPI VarRound(LPVARIANT pVarIn, int deci, LPVARIANT pVarOut) } V_VT(pVarOut) = V_VT(pVarIn); break; + case VT_DECIMAL: + { + double dbl; + VarR8FromDec(&V_DECIMAL(pVarIn), &dbl); + + if (dbl>0.0f) + dbl = floor(dbl*pow(10,deci)+0.5); + else + dbl = ceil(dbl*pow(10,deci)-0.5); + + V_VT(pVarOut)=VT_DECIMAL; + VarDecFromR8(dbl, &V_DECIMAL(pVarOut)); + break; + } /* cases we don't know yet */ default: FIXME("unimplemented part, V_VT(pVarIn) == 0x%X, deci == %d\n", diff --git a/dll/win32/oleaut32/vartype.c b/dll/win32/oleaut32/vartype.c index 9e271be5a23..067d515e34c 100644 --- a/dll/win32/oleaut32/vartype.c +++ b/dll/win32/oleaut32/vartype.c @@ -95,7 +95,7 @@ static HRESULT VARIANT_NumberFromBstr(OLECHAR* pStrIn, LCID lcid, ULONG ulFlags, BYTE rgb[1024]; /* Use VarParseNumFromStr/VarNumFromParseNum as MSDN indicates */ - np.cDig = sizeof(rgb) / sizeof(BYTE); + np.cDig = ARRAY_SIZE(rgb); np.dwInFlags = NUMPRS_STD; hRet = VarParseNumFromStr(pStrIn, lcid, ulFlags, &np, rgb); @@ -3781,7 +3781,7 @@ HRESULT WINAPI VarCyFromUI8(ULONG64 ullIn, CY* pCyOut) * Success: S_OK. * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination */ -HRESULT WINAPI VarCyAdd(const CY cyLeft, const CY cyRight, CY* pCyOut) +HRESULT WINAPI VarCyAdd(CY cyLeft, CY cyRight, CY* pCyOut) { double l,r; _VarR8FromCy(cyLeft, &l); @@ -3804,7 +3804,7 @@ HRESULT WINAPI VarCyAdd(const CY cyLeft, const CY cyRight, CY* pCyOut) * Success: S_OK. * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination */ -HRESULT WINAPI VarCyMul(const CY cyLeft, CY cyRight, CY* pCyOut) +HRESULT WINAPI VarCyMul(CY cyLeft, CY cyRight, CY* pCyOut) { double l,r; _VarR8FromCy(cyLeft, &l); @@ -3827,7 +3827,7 @@ HRESULT WINAPI VarCyMul(const CY cyLeft, CY cyRight, CY* pCyOut) * Success: S_OK. * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination */ -HRESULT WINAPI VarCyMulI4(const CY cyLeft, LONG lRight, CY* pCyOut) +HRESULT WINAPI VarCyMulI4(CY cyLeft, LONG lRight, CY* pCyOut) { double d; @@ -3850,7 +3850,7 @@ HRESULT WINAPI VarCyMulI4(const CY cyLeft, LONG lRight, CY* pCyOut) * Success: S_OK. * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination */ -HRESULT WINAPI VarCySub(const CY cyLeft, const CY cyRight, CY* pCyOut) +HRESULT WINAPI VarCySub(CY cyLeft, CY cyRight, CY* pCyOut) { double l,r; _VarR8FromCy(cyLeft, &l); @@ -3872,7 +3872,7 @@ HRESULT WINAPI VarCySub(const CY cyLeft, const CY cyRight, CY* pCyOut) * Success: S_OK. pCyOut contains the absolute value. * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination */ -HRESULT WINAPI VarCyAbs(const CY cyIn, CY* pCyOut) +HRESULT WINAPI VarCyAbs(CY cyIn, CY* pCyOut) { if (cyIn.s.Hi == (int)0x80000000 && !cyIn.s.Lo) return DISP_E_OVERFLOW; @@ -3898,7 +3898,7 @@ HRESULT WINAPI VarCyAbs(const CY cyIn, CY* pCyOut) * - The difference between this function and VarCyInt() is that VarCyInt() rounds * negative numbers away from 0, while this function rounds them towards zero. */ -HRESULT WINAPI VarCyFix(const CY cyIn, CY* pCyOut) +HRESULT WINAPI VarCyFix(CY cyIn, CY* pCyOut) { pCyOut->int64 = cyIn.int64 / CY_MULTIPLIER; pCyOut->int64 *= CY_MULTIPLIER; @@ -3922,7 +3922,7 @@ HRESULT WINAPI VarCyFix(const CY cyIn, CY* pCyOut) * - The difference between this function and VarCyFix() is that VarCyFix() rounds * negative numbers towards 0, while this function rounds them away from zero. */ -HRESULT WINAPI VarCyInt(const CY cyIn, CY* pCyOut) +HRESULT WINAPI VarCyInt(CY cyIn, CY* pCyOut) { pCyOut->int64 = cyIn.int64 / CY_MULTIPLIER; pCyOut->int64 *= CY_MULTIPLIER; @@ -3947,7 +3947,7 @@ HRESULT WINAPI VarCyInt(const CY cyIn, CY* pCyOut) * Success: S_OK. * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination */ -HRESULT WINAPI VarCyNeg(const CY cyIn, CY* pCyOut) +HRESULT WINAPI VarCyNeg(CY cyIn, CY* pCyOut) { if (cyIn.s.Hi == (int)0x80000000 && !cyIn.s.Lo) return DISP_E_OVERFLOW; @@ -3970,7 +3970,7 @@ HRESULT WINAPI VarCyNeg(const CY cyIn, CY* pCyOut) * Success: S_OK. * Failure: E_INVALIDARG, if cDecimals is less than 0. */ -HRESULT WINAPI VarCyRound(const CY cyIn, int cDecimals, CY* pCyOut) +HRESULT WINAPI VarCyRound(CY cyIn, int cDecimals, CY* pCyOut) { if (cDecimals < 0) return E_INVALIDARG; @@ -4008,7 +4008,7 @@ HRESULT WINAPI VarCyRound(const CY cyIn, int cDecimals, CY* pCyOut) * compare is less, equal or greater than source respectively. * Failure: DISP_E_OVERFLOW, if overflow occurs during the comparison */ -HRESULT WINAPI VarCyCmp(const CY cyLeft, const CY cyRight) +HRESULT WINAPI VarCyCmp(CY cyLeft, CY cyRight) { HRESULT hRet; CY result; @@ -4042,7 +4042,7 @@ HRESULT WINAPI VarCyCmp(const CY cyLeft, const CY cyRight) * less than, equal to or greater than cyLeft respectively. * Failure: DISP_E_OVERFLOW, if overflow occurs during the comparison */ -HRESULT WINAPI VarCyCmpR8(const CY cyLeft, double dblRight) +HRESULT WINAPI VarCyCmpR8(CY cyLeft, double dblRight) { HRESULT hRet; CY cyRight; @@ -4069,7 +4069,7 @@ HRESULT WINAPI VarCyCmpR8(const CY cyLeft, double dblRight) * Success: S_OK. * Failure: DISP_E_OVERFLOW, if the value will not fit in the destination */ -HRESULT WINAPI VarCyMulI8(const CY cyLeft, LONG64 llRight, CY* pCyOut) +HRESULT WINAPI VarCyMulI8(CY cyLeft, LONG64 llRight, CY* pCyOut) { double d; @@ -4496,15 +4496,15 @@ static HRESULT VARIANT_DecScale(const DECIMAL** ppDecLeft, di.scale -= i; remainder = 0; - while (i-- > 0 && !VARIANT_int_iszero(di.bitsnum, sizeof(di.bitsnum)/sizeof(DWORD))) + while (i-- > 0 && !VARIANT_int_iszero(di.bitsnum, ARRAY_SIZE(di.bitsnum))) { - remainder = VARIANT_int_divbychar(di.bitsnum, sizeof(di.bitsnum)/sizeof(DWORD), 10); + remainder = VARIANT_int_divbychar(di.bitsnum, ARRAY_SIZE(di.bitsnum), 10); if (remainder > 0) WARN("losing significant digits (remainder %u)...\n", remainder); } /* round up the result - native oleaut32 does this */ if (remainder >= 5) { - for (remainder = 1, i = 0; i < sizeof(di.bitsnum)/sizeof(DWORD) && remainder; i++) { + for (remainder = 1, i = 0; i < ARRAY_SIZE(di.bitsnum) && remainder; i++) { ULONGLONG digit = di.bitsnum[i] + 1; remainder = (digit > 0xFFFFFFFF) ? 1 : 0; di.bitsnum[i] = digit & 0xFFFFFFFF; @@ -4743,7 +4743,7 @@ static int VARIANT_DI_mul(const VARIANT_DI * a, const VARIANT_DI * b, VARIANT_DI memset(running, 0, sizeof(running)); /* count number of leading zero-bytes in operand A */ - for (mulstart = sizeof(a->bitsnum)/sizeof(DWORD) - 1; mulstart >= 0 && !a->bitsnum[mulstart]; mulstart--); + for (mulstart = ARRAY_SIZE(a->bitsnum) - 1; mulstart >= 0 && !a->bitsnum[mulstart]; mulstart--); if (mulstart < 0) { /* result is 0, because operand A is 0 */ result->scale = 0; @@ -4757,7 +4757,7 @@ static int VARIANT_DI_mul(const VARIANT_DI * a, const VARIANT_DI * b, VARIANT_DI ULONG iOverflowMul; int iB; - for (iOverflowMul = 0, iB = 0; iB < sizeof(b->bitsnum)/sizeof(DWORD); iB++) { + for (iOverflowMul = 0, iB = 0; iB < ARRAY_SIZE(b->bitsnum); iB++) { ULONG iRV; int iR; @@ -4789,11 +4789,10 @@ static int VARIANT_DI_mul(const VARIANT_DI * a, const VARIANT_DI * b, VARIANT_DI This operation *will* lose significant digits of the result because all the factors of 10 were consumed by the previous operation. */ - while (result->scale > 0 && !VARIANT_int_iszero( - running + sizeof(result->bitsnum) / sizeof(DWORD), - (sizeof(running) - sizeof(result->bitsnum)) / sizeof(DWORD))) { - - remainder = VARIANT_int_divbychar(running, sizeof(running) / sizeof(DWORD), 10); + while (result->scale > 0 && !VARIANT_int_iszero(running + ARRAY_SIZE(result->bitsnum), + ARRAY_SIZE(running) - ARRAY_SIZE(result->bitsnum))) { + + remainder = VARIANT_int_divbychar(running, ARRAY_SIZE(running), 10); if (remainder > 0) WARN("losing significant digits (remainder %u)...\n", remainder); result->scale--; } @@ -4801,7 +4800,7 @@ static int VARIANT_DI_mul(const VARIANT_DI * a, const VARIANT_DI * b, VARIANT_DI /* round up the result - native oleaut32 does this */ if (remainder >= 5) { unsigned int i; - for (remainder = 1, i = 0; i < sizeof(running)/sizeof(DWORD) && remainder; i++) { + for (remainder = 1, i = 0; i < ARRAY_SIZE(running) && remainder; i++) { ULONGLONG digit = running[i] + 1; remainder = (digit > 0xFFFFFFFF) ? 1 : 0; running[i] = digit & 0xFFFFFFFF; @@ -4811,9 +4810,8 @@ static int VARIANT_DI_mul(const VARIANT_DI * a, const VARIANT_DI * b, VARIANT_DI /* Signal overflow if scale == 0 and 256-bit result still overflows, and copy result bits into result structure */ - r_overflow = !VARIANT_int_iszero( - running + sizeof(result->bitsnum)/sizeof(DWORD), - (sizeof(running) - sizeof(result->bitsnum))/sizeof(DWORD)); + r_overflow = !VARIANT_int_iszero(running + ARRAY_SIZE(result->bitsnum), + ARRAY_SIZE(running) - ARRAY_SIZE(result->bitsnum)); memcpy(result->bitsnum, running, sizeof(result->bitsnum)); } return r_overflow; @@ -4831,7 +4829,7 @@ static BOOL VARIANT_DI_tostringW(const VARIANT_DI * a, WCHAR * s, unsigned int n unsigned int i; /* place negative sign */ - if (!VARIANT_int_iszero(a->bitsnum, sizeof(a->bitsnum) / sizeof(DWORD)) && a->sign) { + if (!VARIANT_int_iszero(a->bitsnum, ARRAY_SIZE(a->bitsnum)) && a->sign) { if (n > 0) { *s++ = '-'; n--; @@ -4849,8 +4847,8 @@ static BOOL VARIANT_DI_tostringW(const VARIANT_DI * a, WCHAR * s, unsigned int n i = 0; memcpy(quotient, a->bitsnum, sizeof(a->bitsnum)); - while (!overflow && !VARIANT_int_iszero(quotient, sizeof(quotient) / sizeof(DWORD))) { - remainder = VARIANT_int_divbychar(quotient, sizeof(quotient) / sizeof(DWORD), 10); + while (!overflow && !VARIANT_int_iszero(quotient, ARRAY_SIZE(quotient))) { + remainder = VARIANT_int_divbychar(quotient, ARRAY_SIZE(quotient), 10); if (i + 2 > n) { overflow = TRUE; } else { @@ -4859,7 +4857,7 @@ static BOOL VARIANT_DI_tostringW(const VARIANT_DI * a, WCHAR * s, unsigned int n } } - if (!overflow && !VARIANT_int_iszero(a->bitsnum, sizeof(a->bitsnum) / sizeof(DWORD))) { + if (!overflow && !VARIANT_int_iszero(a->bitsnum, ARRAY_SIZE(a->bitsnum))) { /* reverse order of digits */ WCHAR * x = s; WCHAR * y = s + i - 1; @@ -5175,10 +5173,10 @@ static HRESULT VARIANT_DI_div(const VARIANT_DI * dividend, const VARIANT_DI * di { HRESULT r_overflow = S_OK; - if (VARIANT_int_iszero(divisor->bitsnum, sizeof(divisor->bitsnum)/sizeof(DWORD))) { + if (VARIANT_int_iszero(divisor->bitsnum, ARRAY_SIZE(divisor->bitsnum))) { /* division by 0 */ r_overflow = DISP_E_DIVBYZERO; - } else if (VARIANT_int_iszero(dividend->bitsnum, sizeof(dividend->bitsnum)/sizeof(DWORD))) { + } else if (VARIANT_int_iszero(dividend->bitsnum, ARRAY_SIZE(dividend->bitsnum))) { VARIANT_DI_clear(quotient); } else { int quotientscale, remainderscale, tempquotientscale; @@ -5208,17 +5206,14 @@ static HRESULT VARIANT_DI_div(const VARIANT_DI * dividend, const VARIANT_DI * di memset(remainderplusquotient, 0, sizeof(remainderplusquotient)); memcpy(remainderplusquotient, dividend->bitsnum, sizeof(dividend->bitsnum)); do { - VARIANT_int_div( - remainderplusquotient, 4, - divisor->bitsnum, sizeof(divisor->bitsnum)/sizeof(DWORD)); - underflow = VARIANT_int_addlossy( - quotient->bitsnum, "ientscale, sizeof(quotient->bitsnum) / sizeof(DWORD), - remainderplusquotient, &tempquotientscale, 4); + VARIANT_int_div(remainderplusquotient, 4, divisor->bitsnum, ARRAY_SIZE(divisor->bitsnum)); + underflow = VARIANT_int_addlossy( quotient->bitsnum, "ientscale, + ARRAY_SIZE(quotient->bitsnum), remainderplusquotient, &tempquotientscale, 4); if (round_remainder) { if(remainderplusquotient[4] >= 5){ unsigned int i; unsigned char remainder = 1; - for (i = 0; i < sizeof(quotient->bitsnum) / sizeof(DWORD) && remainder; i++) { + for (i = 0; i < ARRAY_SIZE(quotient->bitsnum) && remainder; i++) { ULONGLONG digit = quotient->bitsnum[i] + 1; remainder = (digit > 0xFFFFFFFF) ? 1 : 0; quotient->bitsnum[i] = digit & 0xFFFFFFFF; @@ -5239,9 +5234,9 @@ static HRESULT VARIANT_DI_div(const VARIANT_DI * dividend, const VARIANT_DI * di while (r_overflow == S_OK && quotientscale < 0) { memset(remainderplusquotient, 0, sizeof(remainderplusquotient)); memcpy(remainderplusquotient, quotient->bitsnum, sizeof(quotient->bitsnum)); - VARIANT_int_mulbychar(remainderplusquotient, sizeof(remainderplusquotient)/sizeof(DWORD), 10); - if (VARIANT_int_iszero(remainderplusquotient + sizeof(quotient->bitsnum)/sizeof(DWORD), - (sizeof(remainderplusquotient) - sizeof(quotient->bitsnum))/sizeof(DWORD))) { + VARIANT_int_mulbychar(remainderplusquotient, ARRAY_SIZE(remainderplusquotient), 10); + if (VARIANT_int_iszero(remainderplusquotient + ARRAY_SIZE(quotient->bitsnum), + ARRAY_SIZE(remainderplusquotient) - ARRAY_SIZE(quotient->bitsnum))) { quotientscale++; memcpy(quotient->bitsnum, remainderplusquotient, sizeof(quotient->bitsnum)); } else r_overflow = DISP_E_OVERFLOW; @@ -5562,9 +5557,9 @@ static HRESULT VARIANT_do_division(const DECIMAL *pDecLeft, const DECIMAL *pDecR WARN("result scale is %u, scaling (with loss of significant digits)...\n", di_result.scale); while (di_result.scale > DEC_MAX_SCALE && - !VARIANT_int_iszero(di_result.bitsnum, sizeof(di_result.bitsnum) / sizeof(DWORD))) + !VARIANT_int_iszero(di_result.bitsnum, ARRAY_SIZE(di_result.bitsnum))) { - remainder = VARIANT_int_divbychar(di_result.bitsnum, sizeof(di_result.bitsnum) / sizeof(DWORD), 10); + remainder = VARIANT_int_divbychar(di_result.bitsnum, ARRAY_SIZE(di_result.bitsnum), 10); di_result.scale--; } if (di_result.scale > DEC_MAX_SCALE) @@ -5576,7 +5571,7 @@ static HRESULT VARIANT_do_division(const DECIMAL *pDecLeft, const DECIMAL *pDecR else if (remainder >= 5) /* round up result - native oleaut32 does this */ { unsigned int i; - for (remainder = 1, i = 0; i < sizeof(di_result.bitsnum) / sizeof(DWORD) && remainder; i++) { + for (remainder = 1, i = 0; i < ARRAY_SIZE(di_result.bitsnum) && remainder; i++) { ULONGLONG digit = di_result.bitsnum[i] + 1; remainder = (digit > 0xFFFFFFFF) ? 1 : 0; di_result.bitsnum[i] = digit & 0xFFFFFFFF; @@ -5648,9 +5643,9 @@ HRESULT WINAPI VarDecMul(const DECIMAL* pDecLeft, const DECIMAL* pDecRight, DECI WARN("result scale is %u, scaling (with loss of significant digits)...\n", di_result.scale); while (di_result.scale > DEC_MAX_SCALE && - !VARIANT_int_iszero(di_result.bitsnum, sizeof(di_result.bitsnum)/sizeof(DWORD))) + !VARIANT_int_iszero(di_result.bitsnum, ARRAY_SIZE(di_result.bitsnum))) { - VARIANT_int_divbychar(di_result.bitsnum, sizeof(di_result.bitsnum)/sizeof(DWORD), 10); + VARIANT_int_divbychar(di_result.bitsnum, ARRAY_SIZE(di_result.bitsnum), 10); di_result.scale--; } if (di_result.scale > DEC_MAX_SCALE) @@ -6357,9 +6352,8 @@ static BSTR VARIANT_MakeBstr(LCID lcid, DWORD dwFlags, WCHAR *szOut) { /* Format the number for the locale */ szConverted[0] = '\0'; - GetNumberFormatW(lcid, - dwFlags & LOCALE_NOUSEROVERRIDE, - szOut, NULL, szConverted, sizeof(szConverted)/sizeof(WCHAR)); + GetNumberFormatW(lcid, dwFlags & LOCALE_NOUSEROVERRIDE, + szOut, NULL, szConverted, ARRAY_SIZE(szConverted)); szOut = szConverted; } return SysAllocStringByteLen((LPCSTR)szOut, strlenW(szOut) * sizeof(WCHAR)); @@ -6368,7 +6362,7 @@ static BSTR VARIANT_MakeBstr(LCID lcid, DWORD dwFlags, WCHAR *szOut) /* Create a (possibly localised) BSTR from a UI8 and sign */ static HRESULT VARIANT_BstrFromUInt(ULONG64 ulVal, LCID lcid, DWORD dwFlags, BSTR *pbstrOut) { - WCHAR szBuff[64], *szOut = szBuff + sizeof(szBuff)/sizeof(WCHAR) - 1; + WCHAR szBuff[64], *szOut = szBuff + ARRAY_SIZE(szBuff) - 1; if (!pbstrOut) return E_INVALIDARG; @@ -6453,7 +6447,7 @@ HRESULT WINAPI VarBstrFromI4(LONG lIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut) if (lIn < 0) { - ul64 = (ULONG)-lIn; + ul64 = -(LONG64)lIn; dwFlags |= VAR_NEGATIVE; } return VARIANT_BstrFromUInt(ul64, lcid, dwFlags, pbstrOut); @@ -6472,7 +6466,7 @@ static BSTR VARIANT_BstrReplaceDecimal(const WCHAR * buff, LCID lcid, ULONG dwFl appropriate NUMBERFMTW structure to do the job via GetNumberFormatW(). */ GetLocaleInfoW(lcid, LOCALE_SDECIMAL | (dwFlags & LOCALE_NOUSEROVERRIDE), - lpDecimalSep, sizeof(lpDecimalSep) / sizeof(WCHAR)); + lpDecimalSep, ARRAY_SIZE(lpDecimalSep)); if (lpDecimalSep[0] == '.' && lpDecimalSep[1] == '\0') { /* locale is compatible with English - return original string */ @@ -6497,7 +6491,7 @@ static BSTR VARIANT_BstrReplaceDecimal(const WCHAR * buff, LCID lcid, ULONG dwFl if (p) minFormat.NumDigits = strlenW(p + 1); numbuff[0] = '\0'; - if (!GetNumberFormatW(lcid, 0, buff, &minFormat, numbuff, sizeof(numbuff) / sizeof(WCHAR))) + if (!GetNumberFormatW(lcid, 0, buff, &minFormat, numbuff, ARRAY_SIZE(numbuff))) { WARN("GetNumberFormatW() failed, returning raw number string instead\n"); bstrOut = SysAllocString(buff); @@ -6528,7 +6522,7 @@ static HRESULT VARIANT_BstrFromReal(DOUBLE dblIn, LCID lcid, ULONG dwFlags, */ if (buff[0] == '-') { - const WCHAR szAccept[] = {'0', '.', '\0'}; + static const WCHAR szAccept[] = {'0', '.', '\0'}; if (strlenW(buff + 1) == strspnW(buff + 1, szAccept)) { buff[0] = '0'; buff[1] = '\0'; } } @@ -6541,7 +6535,7 @@ static HRESULT VARIANT_BstrFromReal(DOUBLE dblIn, LCID lcid, ULONG dwFlags, /* Format the number for the locale */ numbuff[0] = '\0'; GetNumberFormatW(lcid, dwFlags & LOCALE_NOUSEROVERRIDE, - buff, NULL, numbuff, sizeof(numbuff) / sizeof(WCHAR)); + buff, NULL, numbuff, ARRAY_SIZE(numbuff)); TRACE("created NLS string %s\n", debugstr_w(numbuff)); *pbstrOut = SysAllocString(numbuff); } @@ -6632,7 +6626,7 @@ HRESULT WINAPI VarBstrFromCy(CY cyIn, LCID lcid, ULONG dwFlags, BSTR *pbstrOut) VARIANT_int_add(decVal.bitsnum, 3, &one, 1); } decVal.bitsnum[2] = 0; - VARIANT_DI_tostringW(&decVal, buff, sizeof(buff)/sizeof(buff[0])); + VARIANT_DI_tostringW(&decVal, buff, ARRAY_SIZE(buff)); if (dwFlags & LOCALE_USE_NLS) { @@ -6641,7 +6635,7 @@ HRESULT WINAPI VarBstrFromCy(CY cyIn, LCID lcid, ULONG dwFlags, BSTR *pbstrOut) /* Format the currency for the locale */ cybuff[0] = '\0'; GetCurrencyFormatW(lcid, dwFlags & LOCALE_NOUSEROVERRIDE, - buff, NULL, cybuff, sizeof(cybuff) / sizeof(WCHAR)); + buff, NULL, cybuff, ARRAY_SIZE(cybuff)); *pbstrOut = SysAllocString(cybuff); } else @@ -6814,8 +6808,8 @@ HRESULT WINAPI VarBstrFromDate(DATE dateIn, LCID lcid, ULONG dwFlags, BSTR* pbst if (dwFlags & VAR_TIMEVALUEONLY) date[0] = '\0'; else - if (!GetLocaleInfoW(lcid, LOCALE_SSHORTDATE, fmt_buff, sizeof(fmt_buff)/sizeof(WCHAR)) || - !get_date_format(lcid, dwFlags, &st, fmt_buff, date, sizeof(date)/sizeof(WCHAR))) + if (!GetLocaleInfoW(lcid, LOCALE_SSHORTDATE, fmt_buff, ARRAY_SIZE(fmt_buff)) || + !get_date_format(lcid, dwFlags, &st, fmt_buff, date, ARRAY_SIZE(date))) return E_INVALIDARG; if (!(dwFlags & VAR_DATEVALUEONLY)) @@ -6823,8 +6817,7 @@ HRESULT WINAPI VarBstrFromDate(DATE dateIn, LCID lcid, ULONG dwFlags, BSTR* pbst time = date + strlenW(date); if (time != date) *time++ = ' '; - if (!GetTimeFormatW(lcid, dwFormatFlags, &st, NULL, time, - sizeof(date)/sizeof(WCHAR)-(time-date))) + if (!GetTimeFormatW(lcid, dwFormatFlags, &st, NULL, time, ARRAY_SIZE(date)-(time-date))) return E_INVALIDARG; } @@ -7012,7 +7005,7 @@ HRESULT WINAPI VarBstrFromDec(DECIMAL* pDecIn, LCID lcid, ULONG dwFlags, BSTR* p /* Format the number for the locale */ numbuff[0] = '\0'; GetNumberFormatW(lcid, dwFlags & LOCALE_NOUSEROVERRIDE, - buff, NULL, numbuff, sizeof(numbuff) / sizeof(WCHAR)); + buff, NULL, numbuff, ARRAY_SIZE(numbuff)); TRACE("created NLS string %s\n", debugstr_w(numbuff)); *pbstrOut = SysAllocString(numbuff); } @@ -7625,7 +7618,7 @@ HRESULT WINAPI VarDateFromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, DATE* pd 1,2,3,4,5,6,7,8,9,10,11,12,13 }; unsigned int i; - BSTR tokens[sizeof(ParseDateTokens)/sizeof(ParseDateTokens[0])]; + BSTR tokens[ARRAY_SIZE(ParseDateTokens)]; DATEPARSE dp; DWORD dwDateSeps = 0, iDate = 0; HRESULT hRet = S_OK; @@ -7648,7 +7641,7 @@ HRESULT WINAPI VarDateFromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, DATE* pd TRACE("iDate is %d\n", iDate); /* Get the month/day/am/pm tokens for this locale */ - for (i = 0; i < sizeof(tokens)/sizeof(tokens[0]); i++) + for (i = 0; i < ARRAY_SIZE(tokens); i++) { WCHAR buff[128]; LCTYPE lctype = ParseDateTokens[i] | (dwFlags & LOCALE_NOUSEROVERRIDE); @@ -7657,7 +7650,7 @@ HRESULT WINAPI VarDateFromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, DATE* pd * GetAltMonthNames(). We should really cache these strings too. */ buff[0] = '\0'; - GetLocaleInfoW(lcid, lctype, buff, sizeof(buff)/sizeof(WCHAR)); + GetLocaleInfoW(lcid, lctype, buff, ARRAY_SIZE(buff)); tokens[i] = SysAllocString(buff); TRACE("token %d is %s\n", i, debugstr_w(tokens[i])); } @@ -7680,7 +7673,7 @@ HRESULT WINAPI VarDateFromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, DATE* pd { BOOL bFound = FALSE; - for (i = 0; i < sizeof(tokens)/sizeof(tokens[0]); i++) + for (i = 0; i < ARRAY_SIZE(tokens); i++) { DWORD dwLen = strlenW(tokens[i]); if (dwLen && !strncmpiW(strIn, tokens[i], dwLen)) @@ -7940,7 +7933,7 @@ HRESULT WINAPI VarDateFromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, DATE* pd } } - for (i = 0; i < sizeof(tokens)/sizeof(tokens[0]); i++) + for (i = 0; i < ARRAY_SIZE(tokens); i++) SysFreeString(tokens[i]); return hRet; } diff --git a/media/doc/README.WINE b/media/doc/README.WINE index f31f2105ac4..27033f2a312 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -141,7 +141,7 @@ reactos/dll/win32/odbc32 # Synced to WineStaging-4.0. Depends on po reactos/dll/win32/odbccp32 # Synced to WineStaging-4.0 reactos/dll/win32/ole32 # Synced to WineStaging-4.0 reactos/dll/win32/oleacc # Synced to WineStaging-4.0 -reactos/dll/win32/oleaut32 # Synced to WineStaging-3.3 +reactos/dll/win32/oleaut32 # Synced to WineStaging-4.0 reactos/dll/win32/olecli32 # Synced to WineStaging-3.3 reactos/dll/win32/oledlg # Synced to WineStaging-3.3 reactos/dll/win32/olepro32 # Synced to WineStaging-3.3 diff --git a/sdk/include/psdk/oleauto.h b/sdk/include/psdk/oleauto.h index ac3a92b67d6..82211297277 100644 --- a/sdk/include/psdk/oleauto.h +++ b/sdk/include/psdk/oleauto.h @@ -676,18 +676,18 @@ HRESULT WINAPI VarDecNeg(_In_ const DECIMAL*, _Out_ DECIMAL*); HRESULT WINAPI VarDecRound(_In_ const DECIMAL*, int, _Out_ DECIMAL*); HRESULT WINAPI VarDecSub(_In_ const DECIMAL*, _In_ const DECIMAL*, _Out_ DECIMAL*); -HRESULT WINAPI VarCyAbs(_In_ const CY, _Out_ CY*); -HRESULT WINAPI VarCyAdd(_In_ const CY, _In_ const CY, _Out_ CY*); -HRESULT WINAPI VarCyCmp(_In_ const CY, _In_ const CY); -HRESULT WINAPI VarCyCmpR8(_In_ const CY, _In_ DOUBLE); -HRESULT WINAPI VarCyFix(_In_ const CY, _Out_ CY*); -HRESULT WINAPI VarCyInt(_In_ const CY, _Out_ CY*); -HRESULT WINAPI VarCyMul(_In_ const CY, _In_ CY, _Out_ CY*); -HRESULT WINAPI VarCyMulI4(_In_ const CY, _In_ LONG, _Out_ CY*); -HRESULT WINAPI VarCyMulI8(_In_ const CY, _In_ LONG64, _Out_ CY*); -HRESULT WINAPI VarCyNeg(_In_ const CY, _Out_ CY*); -HRESULT WINAPI VarCyRound(_In_ const CY, _In_ INT, _Out_ CY*); -HRESULT WINAPI VarCySub(_In_ const CY, _In_ const CY, _Out_ CY*); +HRESULT WINAPI VarCyAbs(_In_ CY, _Out_ CY*); +HRESULT WINAPI VarCyAdd(_In_ CY, _In_ CY, _Out_ CY*); +HRESULT WINAPI VarCyCmp(_In_ CY, _In_ CY); +HRESULT WINAPI VarCyCmpR8(_In_ CY, _In_ DOUBLE); +HRESULT WINAPI VarCyFix(_In_ CY, _Out_ CY*); +HRESULT WINAPI VarCyInt(_In_ CY, _Out_ CY*); +HRESULT WINAPI VarCyMul(_In_ CY, _In_ CY, _Out_ CY*); +HRESULT WINAPI VarCyMulI4(_In_ CY, _In_ LONG, _Out_ CY*); +HRESULT WINAPI VarCyMulI8(_In_ CY, _In_ LONG64, _Out_ CY*); +HRESULT WINAPI VarCyNeg(_In_ CY, _Out_ CY*); +HRESULT WINAPI VarCyRound(_In_ CY, _In_ INT, _Out_ CY*); +HRESULT WINAPI VarCySub(_In_ CY, _In_ CY, _Out_ CY*); HRESULT WINAPI VarAdd(_In_ LPVARIANT, _In_ LPVARIANT, _Out_ LPVARIANT); HRESULT WINAPI VarAnd(_In_ LPVARIANT, _In_ LPVARIANT, _Out_ LPVARIANT);