From b17a4d83bd6b40d358b11b04946aac7b60283cc9 Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Mon, 20 Jul 2015 21:52:13 +0000 Subject: [PATCH] [OLEACC] Sync with Wine Staging 1.7.47. CORE-9924 svn path=/trunk/; revision=68483 --- reactos/dll/win32/oleacc/CMakeLists.txt | 23 ++- reactos/dll/win32/oleacc/client.c | 135 +++++++++++++++++- reactos/dll/win32/oleacc/guid.c | 15 ++ reactos/dll/win32/oleacc/main.c | 82 ++++++++++- reactos/dll/win32/oleacc/oleacc.rc | 3 +- reactos/dll/win32/oleacc/oleacc.spec | 2 +- reactos/dll/win32/oleacc/oleacc_classes.idl | 8 ++ reactos/dll/win32/oleacc/oleacc_classes_r.rgs | 38 +++++ ...leacc_classes.rgs => oleacc_classes_t.rgs} | 6 + reactos/dll/win32/oleacc/oleacc_private.h | 3 +- reactos/dll/win32/oleacc/propservice.c | 10 +- reactos/dll/win32/oleacc/window.c | 66 +++++++++ reactos/media/doc/README.WINE | 2 +- 13 files changed, 368 insertions(+), 25 deletions(-) create mode 100644 reactos/dll/win32/oleacc/guid.c create mode 100644 reactos/dll/win32/oleacc/oleacc_classes_r.rgs rename reactos/dll/win32/oleacc/{oleacc_classes.rgs => oleacc_classes_t.rgs} (54%) diff --git a/reactos/dll/win32/oleacc/CMakeLists.txt b/reactos/dll/win32/oleacc/CMakeLists.txt index a2c10078b9d..d6790ff1e91 100644 --- a/reactos/dll/win32/oleacc/CMakeLists.txt +++ b/reactos/dll/win32/oleacc/CMakeLists.txt @@ -1,5 +1,10 @@ -add_definitions(-D__WINESRC__) +add_definitions( + -D__WINESRC__ + -DENTRY_PREFIX=OLEACC_ + -DPROXY_DELEGATION + -DWINE_REGISTER_DLL) + include_directories(${REACTOS_SOURCE_DIR}/include/reactos/wine) spec2def(oleacc.dll oleacc.spec ADD_IMPORTLIB) @@ -8,25 +13,31 @@ list(APPEND SOURCE main.c propservice.c window.c - oleacc_private.h) + oleacc_private.h + ${CMAKE_CURRENT_BINARY_DIR}/proxy.dlldata.c) +add_idl_headers(oleacc_idlheader oleacc_classes.idl) add_typelib(oleacc_classes.idl) +add_rpcproxy_files(oleacc_classes.idl) list(APPEND oleacc_rc_deps - ${CMAKE_CURRENT_SOURCE_DIR}/oleacc_classes.rgs + ${CMAKE_CURRENT_SOURCE_DIR}/oleacc_classes_r.rgs + ${CMAKE_CURRENT_SOURCE_DIR}/oleacc_classes_t.rgs ${CMAKE_CURRENT_BINARY_DIR}/oleacc_classes.tlb) set_source_files_properties(oleacc.rc PROPERTIES OBJECT_DEPENDS "${oleacc_rc_deps}") add_library(oleacc SHARED ${SOURCE} + guid.c oleacc.rc + ${CMAKE_CURRENT_BINARY_DIR}/oleacc_classes_p.c ${CMAKE_CURRENT_BINARY_DIR}/oleacc_stubs.c ${CMAKE_CURRENT_BINARY_DIR}/oleacc.def) -add_dependencies(oleacc stdole2) +add_dependencies(oleacc oleacc_idlheader stdole2) set_module_type(oleacc win32dll) -target_link_libraries(oleacc uuid wine) -add_importlibs(oleacc oleaut32 ole32 user32 msvcrt kernel32 ntdll) +target_link_libraries(oleacc uuid wine ${PSEH_LIB}) +add_importlibs(oleacc oleaut32 ole32 user32 rpcrt4 msvcrt kernel32 ntdll) add_pch(oleacc oleacc_private.h SOURCE) add_cd_file(TARGET oleacc DESTINATION reactos/system32 FOR all) diff --git a/reactos/dll/win32/oleacc/client.c b/reactos/dll/win32/oleacc/client.c index 0629feb4434..b4b8d6525ce 100644 --- a/reactos/dll/win32/oleacc/client.c +++ b/reactos/dll/win32/oleacc/client.c @@ -21,10 +21,12 @@ typedef struct { IAccessible IAccessible_iface; IOleWindow IOleWindow_iface; + IEnumVARIANT IEnumVARIANT_iface; LONG ref; HWND hwnd; + HWND enum_pos; } Client; static inline Client* impl_from_Client(IAccessible *iface) @@ -44,6 +46,8 @@ static HRESULT WINAPI Client_QueryInterface(IAccessible *iface, REFIID riid, voi *ppv = iface; }else if(IsEqualIID(riid, &IID_IOleWindow)) { *ppv = &This->IOleWindow_iface; + }else if(IsEqualIID(riid, &IID_IEnumVARIANT)) { + *ppv = &This->IEnumVARIANT_iface; }else { WARN("no interface: %s\n", debugstr_guid(riid)); *ppv = NULL; @@ -137,8 +141,11 @@ static HRESULT WINAPI Client_get_accChild(IAccessible *iface, VARIANT varChildID, IDispatch **ppdispChild) { Client *This = impl_from_Client(iface); - FIXME("(%p)->(%s %p)\n", This, debugstr_variant(&varChildID), ppdispChild); - return E_NOTIMPL; + + TRACE("(%p)->(%s %p)\n", This, debugstr_variant(&varChildID), ppdispChild); + + *ppdispChild = NULL; + return E_INVALIDARG; } static HRESULT WINAPI Client_get_accName(IAccessible *iface, VARIANT varID, BSTR *pszName) @@ -486,6 +493,128 @@ static const IOleWindowVtbl ClientOleWindowVtbl = { Client_OleWindow_ContextSensitiveHelp }; +static inline Client* impl_from_Client_EnumVARIANT(IEnumVARIANT *iface) +{ + return CONTAINING_RECORD(iface, Client, IEnumVARIANT_iface); +} + +static HRESULT WINAPI Client_EnumVARIANT_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **ppv) +{ + Client *This = impl_from_Client_EnumVARIANT(iface); + return IAccessible_QueryInterface(&This->IAccessible_iface, riid, ppv); +} + +static ULONG WINAPI Client_EnumVARIANT_AddRef(IEnumVARIANT *iface) +{ + Client *This = impl_from_Client_EnumVARIANT(iface); + return IAccessible_AddRef(&This->IAccessible_iface); +} + +static ULONG WINAPI Client_EnumVARIANT_Release(IEnumVARIANT *iface) +{ + Client *This = impl_from_Client_EnumVARIANT(iface); + return IAccessible_Release(&This->IAccessible_iface); +} + +static HRESULT WINAPI Client_EnumVARIANT_Next(IEnumVARIANT *iface, + ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched) +{ + Client *This = impl_from_Client_EnumVARIANT(iface); + HWND cur = This->enum_pos, next; + ULONG fetched = 0; + HRESULT hr; + + TRACE("(%p)->(%u %p %p)\n", This, celt, rgVar, pCeltFetched); + + if(!celt) { + if(pCeltFetched) + *pCeltFetched = 0; + return S_OK; + } + + if(!This->enum_pos) + next = GetWindow(This->hwnd, GW_CHILD); + else + next = GetWindow(This->enum_pos, GW_HWNDNEXT); + + while(next) { + cur = next; + + V_VT(rgVar+fetched) = VT_DISPATCH; + hr = AccessibleObjectFromWindow(cur, OBJID_WINDOW, + &IID_IDispatch, (void**)&V_DISPATCH(rgVar+fetched)); + if(FAILED(hr)) { + V_VT(rgVar+fetched) = VT_EMPTY; + while(fetched > 0) { + VariantClear(rgVar+fetched-1); + fetched--; + } + if(pCeltFetched) + *pCeltFetched = 0; + return hr; + } + fetched++; + if(fetched == celt) + break; + + next = GetWindow(cur, GW_HWNDNEXT); + } + + This->enum_pos = cur; + if(pCeltFetched) + *pCeltFetched = fetched; + return celt == fetched ? S_OK : S_FALSE; +} + +static HRESULT WINAPI Client_EnumVARIANT_Skip(IEnumVARIANT *iface, ULONG celt) +{ + Client *This = impl_from_Client_EnumVARIANT(iface); + HWND next; + + TRACE("(%p)->(%u)\n", This, celt); + + while(celt) { + if(!This->enum_pos) + next = GetWindow(This->hwnd, GW_CHILD); + else + next = GetWindow(This->enum_pos, GW_HWNDNEXT); + if(!next) + return S_FALSE; + + This->enum_pos = next; + celt--; + } + + return S_OK; +} + +static HRESULT WINAPI Client_EnumVARIANT_Reset(IEnumVARIANT *iface) +{ + Client *This = impl_from_Client_EnumVARIANT(iface); + + TRACE("(%p)\n", This); + + This->enum_pos = 0; + return S_OK; +} + +static HRESULT WINAPI Client_EnumVARIANT_Clone(IEnumVARIANT *iface, IEnumVARIANT **ppEnum) +{ + Client *This = impl_from_Client_EnumVARIANT(iface); + FIXME("(%p)->(%p)\n", This, ppEnum); + return E_NOTIMPL; +} + +static const IEnumVARIANTVtbl ClientEnumVARIANTVtbl = { + Client_EnumVARIANT_QueryInterface, + Client_EnumVARIANT_AddRef, + Client_EnumVARIANT_Release, + Client_EnumVARIANT_Next, + Client_EnumVARIANT_Skip, + Client_EnumVARIANT_Reset, + Client_EnumVARIANT_Clone +}; + HRESULT create_client_object(HWND hwnd, const IID *iid, void **obj) { Client *client; @@ -500,8 +629,10 @@ HRESULT create_client_object(HWND hwnd, const IID *iid, void **obj) client->IAccessible_iface.lpVtbl = &ClientVtbl; client->IOleWindow_iface.lpVtbl = &ClientOleWindowVtbl; + client->IEnumVARIANT_iface.lpVtbl = &ClientEnumVARIANTVtbl; client->ref = 1; client->hwnd = hwnd; + client->enum_pos = 0; hres = IAccessible_QueryInterface(&client->IAccessible_iface, iid, obj); IAccessible_Release(&client->IAccessible_iface); diff --git a/reactos/dll/win32/oleacc/guid.c b/reactos/dll/win32/oleacc/guid.c new file mode 100644 index 00000000000..ad13c284d61 --- /dev/null +++ b/reactos/dll/win32/oleacc/guid.c @@ -0,0 +1,15 @@ +/* DO NOT USE THE PRECOMPILED HEADER FOR THIS FILE! */ + +#include + +#define WIN32_NO_STATUS +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H + +#include +#include +#include +#include +#include + +/* NO CODE HERE, THIS IS JUST REQUIRED FOR THE GUID DEFINITIONS */ diff --git a/reactos/dll/win32/oleacc/main.c b/reactos/dll/win32/oleacc/main.c index adadd66fe95..ca6c65d86f2 100644 --- a/reactos/dll/win32/oleacc/main.c +++ b/reactos/dll/win32/oleacc/main.c @@ -40,6 +40,11 @@ static const WCHAR richedit20wW[] = {'R','i','c','h','E','d','i','t','2','0','W' typedef HRESULT (WINAPI *accessible_create)(HWND, const IID*, void**); +extern HRESULT WINAPI OLEACC_DllGetClassObject(REFCLSID, REFIID, void**) DECLSPEC_HIDDEN; +extern BOOL WINAPI OLEACC_DllMain(HINSTANCE, DWORD, void*) DECLSPEC_HIDDEN; +extern HRESULT WINAPI OLEACC_DllRegisterServer(void) DECLSPEC_HIDDEN; +extern HRESULT WINAPI OLEACC_DllUnregisterServer(void) DECLSPEC_HIDDEN; + static struct { const WCHAR *name; DWORD idx; @@ -397,25 +402,45 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, DisableThreadLibraryCalls(hinstDLL); break; } - return TRUE; + + return OLEACC_DllMain(hinstDLL, fdwReason, lpvReserved); } HRESULT WINAPI DllRegisterServer(void) { - TRACE("()\n"); - return __wine_register_resources(oleacc_handle); + return OLEACC_DllRegisterServer(); } HRESULT WINAPI DllUnregisterServer(void) { - TRACE("()\n"); - return __wine_unregister_resources(oleacc_handle); + return OLEACC_DllUnregisterServer(); +} + +HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, void **ppv) +{ + if(IsEqualGUID(&CLSID_CAccPropServices, rclsid)) { + TRACE("(CLSID_CAccPropServices %s %p)\n", debugstr_guid(iid), ppv); + return get_accpropservices_factory(iid, ppv); + } + + if(IsEqualGUID(&CLSID_PSFactoryBuffer, rclsid)) { + TRACE("(CLSID_PSFactoryBuffer %s %p)\n", debugstr_guid(iid), ppv); + return OLEACC_DllGetClassObject(rclsid, iid, ppv); + } + + FIXME("%s %s %p: stub\n", debugstr_guid(rclsid), debugstr_guid(iid), ppv); + return E_NOTIMPL; } void WINAPI GetOleaccVersionInfo(DWORD* pVersion, DWORD* pBuild) { +#ifdef __REACTOS__ *pVersion = MAKELONG(2,4); /* Windows XP version of oleacc: 4.2.5406.0 */ *pBuild = MAKELONG(0,5406); +#else + *pVersion = MAKELONG(0,7); /* Windows 7 version of oleacc: 7.0.0.0 */ + *pBuild = MAKELONG(0,0); +#endif } HANDLE WINAPI GetProcessHandleFromHwnd(HWND hwnd) @@ -559,3 +584,50 @@ UINT WINAPI GetStateTextA(DWORD state_bit, CHAR *state_str, UINT state_str_len) return LoadStringA(oleacc_handle, state_id, tmp, sizeof(tmp)); } } + +HRESULT WINAPI AccessibleChildren(IAccessible *container, + LONG start, LONG count, VARIANT *children, LONG *children_cnt) +{ + IEnumVARIANT *ev; + LONG i, child_no; + HRESULT hr; + + TRACE("%p %d %d %p %p\n", container, start, count, children, children_cnt); + + if(!container || !children || !children_cnt) + return E_INVALIDARG; + + for(i=0; i #include #include -#include +#include #include WINE_DEFAULT_DEBUG_CHANNEL(oleacc); HRESULT create_client_object(HWND, const IID*, void**) DECLSPEC_HIDDEN; HRESULT create_window_object(HWND, const IID*, void**) DECLSPEC_HIDDEN; +HRESULT get_accpropservices_factory(REFIID, void**) DECLSPEC_HIDDEN; int convert_child_id(VARIANT *v) DECLSPEC_HIDDEN; diff --git a/reactos/dll/win32/oleacc/propservice.c b/reactos/dll/win32/oleacc/propservice.c index 58a113dde34..bd99831777d 100644 --- a/reactos/dll/win32/oleacc/propservice.c +++ b/reactos/dll/win32/oleacc/propservice.c @@ -236,13 +236,7 @@ static const IClassFactoryVtbl CAccPropServicesFactoryVtbl = { static IClassFactory CAccPropServicesFactory = { &CAccPropServicesFactoryVtbl }; -HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, void **ppv) +HRESULT get_accpropservices_factory(REFIID riid, void **ppv) { - if(IsEqualGUID(&CLSID_CAccPropServices, rclsid)) { - TRACE("(CLSID_CAccPropServices %s %p)\n", debugstr_guid(iid), ppv); - return IClassFactory_QueryInterface(&CAccPropServicesFactory, iid, ppv); - } - - FIXME("%s %s %p: stub\n", debugstr_guid(rclsid), debugstr_guid(iid), ppv); - return E_NOTIMPL; + return IClassFactory_QueryInterface(&CAccPropServicesFactory, riid, ppv); } diff --git a/reactos/dll/win32/oleacc/window.c b/reactos/dll/win32/oleacc/window.c index a659adaad8e..a7efe713f02 100644 --- a/reactos/dll/win32/oleacc/window.c +++ b/reactos/dll/win32/oleacc/window.c @@ -21,6 +21,7 @@ typedef struct { IAccessible IAccessible_iface; IOleWindow IOleWindow_iface; + IEnumVARIANT IEnumVARIANT_iface; LONG ref; } Window; @@ -42,6 +43,8 @@ static HRESULT WINAPI Window_QueryInterface(IAccessible *iface, REFIID riid, voi *ppv = iface; }else if(IsEqualIID(riid, &IID_IOleWindow)) { *ppv = &This->IOleWindow_iface; + }else if(IsEqualIID(riid, &IID_IEnumVARIANT)) { + *ppv = &This->IEnumVARIANT_iface; }else { WARN("no interface: %s\n", debugstr_guid(riid)); *ppv = NULL; @@ -339,6 +342,68 @@ static const IOleWindowVtbl WindowOleWindowVtbl = { Window_OleWindow_ContextSensitiveHelp }; +static inline Window* impl_from_Window_EnumVARIANT(IEnumVARIANT *iface) +{ + return CONTAINING_RECORD(iface, Window, IEnumVARIANT_iface); +} + +static HRESULT WINAPI Window_EnumVARIANT_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **ppv) +{ + Window *This = impl_from_Window_EnumVARIANT(iface); + return IAccessible_QueryInterface(&This->IAccessible_iface, riid, ppv); +} + +static ULONG WINAPI Window_EnumVARIANT_AddRef(IEnumVARIANT *iface) +{ + Window *This = impl_from_Window_EnumVARIANT(iface); + return IAccessible_AddRef(&This->IAccessible_iface); +} + +static ULONG WINAPI Window_EnumVARIANT_Release(IEnumVARIANT *iface) +{ + Window *This = impl_from_Window_EnumVARIANT(iface); + return IAccessible_Release(&This->IAccessible_iface); +} + +static HRESULT WINAPI Window_EnumVARIANT_Next(IEnumVARIANT *iface, + ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched) +{ + Window *This = impl_from_Window_EnumVARIANT(iface); + FIXME("(%p)->(%u %p %p)\n", This, celt, rgVar, pCeltFetched); + return E_NOTIMPL; +} + +static HRESULT WINAPI Window_EnumVARIANT_Skip(IEnumVARIANT *iface, ULONG celt) +{ + Window *This = impl_from_Window_EnumVARIANT(iface); + FIXME("(%p)->(%u)\n", This, celt); + return E_NOTIMPL; +} + +static HRESULT WINAPI Window_EnumVARIANT_Reset(IEnumVARIANT *iface) +{ + Window *This = impl_from_Window_EnumVARIANT(iface); + FIXME("(%p)\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI Window_EnumVARIANT_Clone(IEnumVARIANT *iface, IEnumVARIANT **ppEnum) +{ + Window *This = impl_from_Window_EnumVARIANT(iface); + FIXME("(%p)->(%p)\n", This, ppEnum); + return E_NOTIMPL; +} + +static const IEnumVARIANTVtbl WindowEnumVARIANTVtbl = { + Window_EnumVARIANT_QueryInterface, + Window_EnumVARIANT_AddRef, + Window_EnumVARIANT_Release, + Window_EnumVARIANT_Next, + Window_EnumVARIANT_Skip, + Window_EnumVARIANT_Reset, + Window_EnumVARIANT_Clone +}; + HRESULT create_window_object(HWND hwnd, const IID *iid, void **obj) { Window *window; @@ -353,6 +418,7 @@ HRESULT create_window_object(HWND hwnd, const IID *iid, void **obj) window->IAccessible_iface.lpVtbl = &WindowVtbl; window->IOleWindow_iface.lpVtbl = &WindowOleWindowVtbl; + window->IEnumVARIANT_iface.lpVtbl = &WindowEnumVARIANTVtbl; window->ref = 1; hres = IAccessible_QueryInterface(&window->IAccessible_iface, iid, obj); diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index a5bfdcfe837..d95cecd1a87 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -146,7 +146,7 @@ reactos/dll/win32/objsel # Synced to WineStaging-1.7.37 reactos/dll/win32/odbc32 # Synced to WineStaging-1.7.37. Depends on port of Linux ODBC. reactos/dll/win32/odbccp32 # Synced to WineStaging-1.7.47 reactos/dll/win32/ole32 # Synced to WineStaging-1.7.47 -reactos/dll/win32/oleacc # Synced to WineStaging-1.7.37 +reactos/dll/win32/oleacc # Synced to WineStaging-1.7.47 reactos/dll/win32/oleaut32 # Synced to WineStaging-1.7.37 reactos/dll/win32/olecli32 # Synced to WineStaging-1.7.37 reactos/dll/win32/oledlg # Synced to WineStaging-1.7.37