diff --git a/dll/win32/oleacc/main.c b/dll/win32/oleacc/main.c index 57b02a0e136..cd2864feab0 100644 --- a/dll/win32/oleacc/main.c +++ b/dll/win32/oleacc/main.c @@ -340,10 +340,116 @@ LRESULT WINAPI LresultFromObject( REFIID riid, WPARAM wParam, LPUNKNOWN pAcc ) return atom; } -HRESULT WINAPI AccessibleObjectFromPoint( POINT ptScreen, IAccessible** ppacc, VARIANT* pvarChild ) +static void variant_init_i4( VARIANT *v, int val ) { - FIXME("{%d,%d} %p %p: stub\n", ptScreen.x, ptScreen.y, ppacc, pvarChild ); - return E_NOTIMPL; + V_VT(v) = VT_I4; + V_I4(v) = val; +} + +HRESULT WINAPI AccessibleObjectFromEvent( HWND hwnd, DWORD object_id, DWORD child_id, + IAccessible **acc_out, VARIANT *child_id_out ) +{ + VARIANT child_id_variant; + IAccessible *acc = NULL; + IDispatch *child = NULL; + HRESULT hr; + + TRACE("%p %ld %ld %p %p\n", hwnd, object_id, child_id, acc_out, child_id_out); + + if (!acc_out) + return E_INVALIDARG; + *acc_out = NULL; + VariantInit(child_id_out); + + hr = AccessibleObjectFromWindow(hwnd, object_id, &IID_IAccessible, (void **)&acc); + if (FAILED(hr)) + return hr; + + variant_init_i4(&child_id_variant, child_id); + hr = IAccessible_get_accChild(acc, child_id_variant, &child); + if (FAILED(hr)) + TRACE("get_accChild failed with %#lx!\n", hr); + + if (SUCCEEDED(hr) && child) + { + IAccessible_Release(acc); + hr = IDispatch_QueryInterface(child, &IID_IAccessible, (void **)&acc); + IDispatch_Release(child); + if (FAILED(hr)) + return hr; + + variant_init_i4(&child_id_variant, CHILDID_SELF); + } + + *acc_out = acc; + *child_id_out = child_id_variant; + + return S_OK; +} + +HRESULT WINAPI AccessibleObjectFromPoint( POINT point, IAccessible** acc, VARIANT* child_id ) +{ + IAccessible *cur; + HRESULT hr; + VARIANT v; + HWND hwnd; + + TRACE("{%ld,%ld} %p %p\n", point.x, point.y, acc, child_id); + + if (!acc || !child_id) + return E_INVALIDARG; + + *acc = NULL; + V_VT(child_id) = VT_EMPTY; + + hwnd = WindowFromPoint(point); + if (!hwnd) + return E_FAIL; + hwnd = GetAncestor(hwnd, GA_ROOT); + + hr = AccessibleObjectFromWindow(hwnd, OBJID_WINDOW, &IID_IAccessible, (void **)&cur); + if (FAILED(hr)) + return hr; + if (!cur) + return E_FAIL; + + V_VT(&v) = VT_EMPTY; + while (1) + { + hr = IAccessible_accHitTest(cur, point.x, point.y, &v); + if (FAILED(hr)) + { + IAccessible_Release(cur); + return hr; + } + + if (V_VT(&v) == VT_I4) + { + *acc = cur; + variant_init_i4(child_id, V_I4(&v)); + return S_OK; + } + else if (V_VT(&v) == VT_DISPATCH) + { + IAccessible_Release(cur); + + hr = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IAccessible, (void**)&cur); + VariantClear(&v); + if (FAILED(hr)) + return hr; + if (!cur) + return E_FAIL; + } + else + { + VariantClear(&v); + IAccessible_Release(cur); + FIXME("unhandled variant type: %d\n", V_VT(&v)); + return E_NOTIMPL; + } + } + + return S_OK; } HRESULT WINAPI AccessibleObjectFromWindow( HWND hwnd, DWORD dwObjectID, diff --git a/dll/win32/oleacc/oleacc.spec b/dll/win32/oleacc/oleacc.spec index 4cff0b8effc..9ad6e915965 100644 --- a/dll/win32/oleacc/oleacc.spec +++ b/dll/win32/oleacc/oleacc.spec @@ -1,5 +1,5 @@ @ stdcall AccessibleChildren(ptr long long ptr ptr) -@ stub AccessibleObjectFromEvent +@ stdcall AccessibleObjectFromEvent(ptr long long ptr ptr) @ stdcall AccessibleObjectFromPoint(int64 ptr ptr) @ stdcall AccessibleObjectFromWindow(ptr long ptr ptr) @ stdcall CreateStdAccessibleObject(ptr long ptr ptr) diff --git a/dll/win32/oleacc/window.c b/dll/win32/oleacc/window.c index 5957d49ef1f..1bd57743b2c 100644 --- a/dll/win32/oleacc/window.c +++ b/dll/win32/oleacc/window.c @@ -31,6 +31,7 @@ typedef struct { IEnumVARIANT IEnumVARIANT_iface; LONG ref; + HWND hwnd; } Window; static inline Window* impl_from_Window(IAccessible *iface) @@ -244,14 +245,43 @@ static HRESULT WINAPI Window_accNavigate(IAccessible *iface, return E_NOTIMPL; } -static HRESULT WINAPI Window_accHitTest(IAccessible *iface, - LONG xLeft, LONG yTop, VARIANT *pvarID) + +static HRESULT WINAPI Window_accHitTest(IAccessible *iface, LONG x, LONG y, VARIANT *v) { Window *This = impl_from_Window(iface); - FIXME("(%p)->(%d %d %p)\n", This, xLeft, yTop, pvarID); + IDispatch *disp; + POINT pt; + HRESULT hr; + RECT rect; + + TRACE("(%p)->(%ld %ld %p)\n", This, x, y, v); + + V_VT(v) = VT_EMPTY; + if (!GetClientRect(This->hwnd, &rect)) + return E_FAIL; + if (!ClientToScreen(This->hwnd, (POINT*)&rect) || + !ClientToScreen(This->hwnd, &((POINT*)&rect)[1])) + return E_FAIL; + pt.x = x; + pt.y = y; + if (PtInRect(&rect, pt)) + { + hr = AccessibleObjectFromWindow(This->hwnd, OBJID_CLIENT, &IID_IDispatch, (void**)&disp); + if (FAILED(hr)) + return hr; + if (!disp) + return E_FAIL; + + V_VT(v) = VT_DISPATCH; + V_DISPATCH(v) = disp; + return S_OK; + } + + FIXME("non-client area not handled yet\n"); return E_NOTIMPL; } + static HRESULT WINAPI Window_accDoDefaultAction(IAccessible *iface, VARIANT varID) { Window *This = impl_from_Window(iface); @@ -330,8 +360,9 @@ static ULONG WINAPI Window_OleWindow_Release(IOleWindow *iface) static HRESULT WINAPI Window_OleWindow_GetWindow(IOleWindow *iface, HWND *phwnd) { Window *This = impl_from_Window_OleWindow(iface); - FIXME("(%p)->(%p)\n", This, phwnd); - return E_NOTIMPL; + TRACE("(%p)->(%p)\n", This, phwnd); + *phwnd = This->hwnd; + return S_OK; } static HRESULT WINAPI Window_OleWindow_ContextSensitiveHelp(IOleWindow *iface, BOOL fEnterMode) @@ -426,6 +457,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->hwnd = hwnd; window->ref = 1; hres = IAccessible_QueryInterface(&window->IAccessible_iface, iid, obj); diff --git a/dll/win32/rpcrt4/rpcrt4.spec b/dll/win32/rpcrt4/rpcrt4.spec index 7b946ca37ff..f103cc5868d 100644 --- a/dll/win32/rpcrt4/rpcrt4.spec +++ b/dll/win32/rpcrt4/rpcrt4.spec @@ -525,3 +525,4 @@ @ stub tree_into_ndr @ stub tree_peek_ndr @ stub tree_size_ndr +@ stdcall RpcServerRegisterIf3(ptr ptr ptr long long long ptr ptr) diff --git a/drivers/filesystems/npfs/fsctrl.c b/drivers/filesystems/npfs/fsctrl.c index 7f4f1d75cfb..24421c2e0b4 100644 --- a/drivers/filesystems/npfs/fsctrl.c +++ b/drivers/filesystems/npfs/fsctrl.c @@ -842,6 +842,12 @@ NpCommonFileSystemControl(IN PDEVICE_OBJECT DeviceObject, Status = NpSetClientProcess(DeviceObject, Irp); break; + case FSCTL_PIPE_GET_CONNECTION_ATTRIBUTE: + + NpAcquireExclusiveVcb(); + Status = NpGetConnectionAttribute(DeviceObject, Irp); + break; + default: return STATUS_NOT_SUPPORTED; } @@ -875,4 +881,52 @@ NpFsdFileSystemControl(IN PDEVICE_OBJECT DeviceObject, return Status; } + +NTSTATUS +NTAPI +NpGetConnectionAttribute(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION IoStackLocation; + NODE_TYPE_CODE NodeTypeCode; + PNP_CCB Ccb; + ULONG Length; + ULONG* pid; + PAGED_CODE(); + + /* Get the current stack location */ + IoStackLocation = IoGetCurrentIrpStackLocation(Irp); + + /* Decode the file object and check the node type */ + NodeTypeCode = NpDecodeFileObject(IoStackLocation->FileObject, 0, &Ccb, 0); + if (NodeTypeCode != NPFS_NTC_CCB) + { + return STATUS_PIPE_DISCONNECTED; + } + + /* Get the length of the query buffer */ + Length = IoStackLocation->Parameters.QueryFile.Length; + if (Length < sizeof(ULONG)) + { + return STATUS_INVALID_PARAMETER; + } + + /* Lock the Ccb */ + ExAcquireResourceExclusiveLite(&Ccb->NonPagedCcb->Lock, TRUE); + + Irp->IoStatus.Information = sizeof(ULONG); + pid = (ULONG*)(Irp->AssociatedIrp.SystemBuffer); + if (Ccb->ClientSession != NULL){ + PNP_CLIENT_PROCESS ClientSession = Ccb->ClientSession; + *pid = (ULONG)PsGetProcessId(ClientSession->Process); + } + else + *pid = (ULONG)PsGetProcessId(Ccb->Process); + + /* Unlock the Ccb */ + ExReleaseResourceLite(&Ccb->NonPagedCcb->Lock); + + return STATUS_SUCCESS; +} + /* EOF */ diff --git a/drivers/filesystems/npfs/npfs.h b/drivers/filesystems/npfs/npfs.h index 5d36d0cf3bf..b7d15b4419b 100644 --- a/drivers/filesystems/npfs/npfs.h +++ b/drivers/filesystems/npfs/npfs.h @@ -692,4 +692,9 @@ NTAPI NpFsdQueryVolumeInformation(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); +NTSTATUS +NTAPI +NpGetConnectionAttribute(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + #endif /* _NPFS_PCH_ */ diff --git a/sdk/include/ndk/iotypes.h b/sdk/include/ndk/iotypes.h index 5610099f884..3b854ecddd9 100644 --- a/sdk/include/ndk/iotypes.h +++ b/sdk/include/ndk/iotypes.h @@ -1205,6 +1205,8 @@ typedef VOID CTL_CODE(FILE_DEVICE_NAMED_PIPE, 8, METHOD_BUFFERED, FILE_ANY_ACCESS) #define FSCTL_PIPE_QUERY_CLIENT_PROCESS \ CTL_CODE(FILE_DEVICE_NAMED_PIPE, 9, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define FSCTL_PIPE_GET_CONNECTION_ATTRIBUTE \ + CTL_CODE(FILE_DEVICE_NAMED_PIPE, 12, METHOD_BUFFERED, FILE_ANY_ACCESS) #define FSCTL_PIPE_INTERNAL_READ \ CTL_CODE(FILE_DEVICE_NAMED_PIPE, 2045, METHOD_BUFFERED, FILE_READ_DATA) #define FSCTL_PIPE_INTERNAL_WRITE \ diff --git a/win32ss/user/ntuser/focus.c b/win32ss/user/ntuser/focus.c index 8f38ac37592..47fe55db6d6 100644 --- a/win32ss/user/ntuser/focus.c +++ b/win32ss/user/ntuser/focus.c @@ -1123,7 +1123,7 @@ co_IntSetActiveWindow( // Set state flag to prevent recursions. Wnd->state |= WNDS_BEINGACTIVATED; - IntNotifyWinEvent(EVENT_SYSTEM_FOREGROUND, Wnd, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI); + //IntNotifyWinEvent(EVENT_SYSTEM_FOREGROUND, Wnd, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI); // Clear out activate EVENT messages. FindRemoveEventMsg(pti, POSTEVENT_SAW, POSTEVENT_DAW); diff --git a/win32ss/user/user32/windows/hook.c b/win32ss/user/user32/windows/hook.c index a9e9647eddf..9c9ca097f10 100644 --- a/win32ss/user/user32/windows/hook.c +++ b/win32ss/user/user32/windows/hook.c @@ -834,15 +834,16 @@ User32CallEventProcFromKernel(PVOID Arguments, ULONG ArgumentLength) } } - Proc(Common->hook, - Common->event, - Common->hwnd, - Common->idObject, - Common->idChild, - Common->dwEventThread, - Common->dwmsEventTime); - - if (Loaded) FreeLibrary(mod); + if (Loaded){ + Proc(Common->hook, + Common->event, + Common->hwnd, + Common->idObject, + Common->idChild, + Common->dwEventThread, + Common->dwmsEventTime); + FreeLibrary(mod); + } return ZwCallbackReturn(NULL, 0, STATUS_SUCCESS); }