From 27e1836146a4b879037be8e996fb65cfbe29dace Mon Sep 17 00:00:00 2001 From: Jan Zerebecki Date: Wed, 26 Dec 2007 17:25:24 +0100 Subject: [PATCH] push 2611c5e74b6b3f940a18cbfccd94936eddcba0c6 --- dlls/comdlg32/printdlg.c | 53 +++--- dlls/dbghelp/dwarf.c | 1 + dlls/hlink/extserv.c | 1 + dlls/msi/streams.c | 5 + dlls/msi/table.c | 2 + dlls/ole32/moniker.c | 9 +- dlls/oleaut32/tests/usrmarshal.c | 6 +- dlls/quartz/filtergraph.c | 1 + dlls/rpcrt4/Makefile.in | 1 + dlls/rpcrt4/ndr_contexthandle.c | 339 +++++++++++++++++++++++++++++++++++++++ dlls/rpcrt4/ndr_marshall.c | 334 +++++++++----------------------------- dlls/rpcrt4/rpc_assoc.c | 146 +++++++++++++++++ dlls/rpcrt4/rpc_assoc.h | 14 +- dlls/rpcrt4/tests/server.c | 134 ++++++++++++++++ dlls/rpcrt4/tests/server.idl | 4 +- dlls/user32/spy.c | 30 ++-- dlls/wined3d/directx.c | 9 +- dlls/winex11.drv/wintab.c | 326 +++++++++++++++++++++++++------------ dlls/wintab32/context.c | 89 +++++----- dlls/ws2_32/socket.c | 2 +- include/d3d10.idl | 14 +- include/msinkaut.idl | 4 +- include/oleacc.idl | 10 +- include/wine/irot.idl | 9 +- include/winuser.h | 28 +++- programs/rpcss/irotp.c | 46 ++++-- tools/widl/typegen.c | 51 +++++- 27 files changed, 1168 insertions(+), 500 deletions(-) create mode 100644 dlls/rpcrt4/ndr_contexthandle.c diff --git a/dlls/comdlg32/printdlg.c b/dlls/comdlg32/printdlg.c index dd290d5d35e..6b8ed15aaa1 100644 --- a/dlls/comdlg32/printdlg.c +++ b/dlls/comdlg32/printdlg.c @@ -2684,6 +2684,23 @@ PRINTDLG_PS_ChangePrinterA(HWND hDlg, PageSetupDataA *pda) { return TRUE; } +static void PRINTDLG_PS_SetOrientationW(HWND hDlg, PageSetupDataW* pda) +{ + WCHAR PaperName[64]; + + GetDlgItemTextW(hDlg, cmb2, PaperName, sizeof(PaperName)/sizeof(WCHAR)); + PRINTDLG_PaperSizeW(&pda->pdlg, PaperName, &pda->curdlg.ptPaperSize); + pda->curdlg.ptPaperSize.x = _c_10mm2size((LPPAGESETUPDLGA)pda->dlga, pda->curdlg.ptPaperSize.x); + pda->curdlg.ptPaperSize.y = _c_10mm2size((LPPAGESETUPDLGA)pda->dlga, pda->curdlg.ptPaperSize.y); + + if(IsDlgButtonChecked(hDlg, rad2)) + { + DWORD tmp = pda->curdlg.ptPaperSize.x; + pda->curdlg.ptPaperSize.x = pda->curdlg.ptPaperSize.y; + pda->curdlg.ptPaperSize.y = tmp; + } +} + static BOOL PRINTDLG_PS_ChangePrinterW(HWND hDlg, PageSetupDataW *pda) { DEVNAMES *dn; @@ -2696,8 +2713,18 @@ PRINTDLG_PS_ChangePrinterW(HWND hDlg, PageSetupDataW *pda) { portname = ((WCHAR*)dn)+dn->wOutputOffset; PRINTDLG_SetUpPaperComboBoxW(hDlg,cmb2,devname,portname,dm); PRINTDLG_SetUpPaperComboBoxW(hDlg,cmb3,devname,portname,dm); + + /* Landscape orientation */ + if (dm->u1.s1.dmOrientation == DMORIENT_LANDSCAPE) + CheckRadioButton(hDlg, rad1, rad2, rad2); + else /* this is default if papersize is not set */ + CheckRadioButton(hDlg, rad1, rad2, rad1); + GlobalUnlock(pda->pdlg.hDevNames); GlobalUnlock(pda->pdlg.hDevMode); + + PRINTDLG_PS_SetOrientationW(hDlg, pda); + return TRUE; } @@ -3302,7 +3329,6 @@ PageDlgProcW(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { '_', '_', 'W', 'I', 'N', 'E', '_', 'P', 'A', 'G', 'E', 'S', 'E', 'T', 'U', 'P', 'D', 'L', 'G', 'D', 'A', 'T', 'A', 0 }; PageSetupDataW *pda; - LPDEVMODEW dm; BOOL res = FALSE; if (uMsg==WM_INITDIALOG) { @@ -3332,31 +3358,6 @@ PageDlgProcW(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) PRINTDLG_PS_ChangePrinterW(hDlg,pda); - if(pda->dlga->hDevMode) - { - WCHAR PaperName[64]; - - dm = GlobalLock(pda->dlga->hDevMode); - /* Landscape orientation */ - if (dm->u1.s1.dmOrientation == DMORIENT_LANDSCAPE) - CheckRadioButton(hDlg, rad1, rad2, rad2); - else /* this is default if papersize is not set */ - CheckRadioButton(hDlg, rad1, rad2, rad1); - - GetDlgItemTextW(hDlg, cmb2, PaperName, sizeof(PaperName)/sizeof(WCHAR)); - PRINTDLG_PaperSizeW(&pda->pdlg, PaperName, &pda->curdlg.ptPaperSize); - pda->curdlg.ptPaperSize.x = _c_10mm2size((LPPAGESETUPDLGA)pda->dlga, pda->curdlg.ptPaperSize.x); - pda->curdlg.ptPaperSize.y = _c_10mm2size((LPPAGESETUPDLGA)pda->dlga, pda->curdlg.ptPaperSize.y); - GlobalUnlock(pda->dlga->hDevMode); - - if(IsDlgButtonChecked(hDlg, rad2)) - { - DWORD tmp = pda->curdlg.ptPaperSize.x; - pda->curdlg.ptPaperSize.x = pda->curdlg.ptPaperSize.y; - pda->curdlg.ptPaperSize.y = tmp; - } - } - if (pda->dlga->Flags & PSD_DISABLEORIENTATION) { EnableWindow(GetDlgItem(hDlg,rad1),FALSE); EnableWindow(GetDlgItem(hDlg,rad2),FALSE); diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index 66c761c3626..a03b0490800 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -1329,6 +1329,7 @@ static void dwarf2_parse_variable(dwarf2_subprogram_t* subpgm, case DW_FORM_data2: case DW_FORM_data4: case DW_FORM_udata: + case DW_FORM_addr: v.n1.n2.vt = VT_UI4; v.n1.n2.n3.lVal = value.u.uvalue; break; diff --git a/dlls/hlink/extserv.c b/dlls/hlink/extserv.c index d58d1ddde84..c7a1b779d0f 100644 --- a/dlls/hlink/extserv.c +++ b/dlls/hlink/extserv.c @@ -91,6 +91,7 @@ static ULONG WINAPI ExtServUnk_Release(IUnknown *iface) if(!ref) { heap_free(This->username); heap_free(This->password); + heap_free(This->headers); heap_free(This); } diff --git a/dlls/msi/streams.c b/dlls/msi/streams.c index bb86fd0e84c..9828b7f355c 100644 --- a/dlls/msi/streams.c +++ b/dlls/msi/streams.c @@ -408,17 +408,22 @@ static UINT add_streams_to_table(MSISTREAMSVIEW *sv) /* table streams are not in the _Streams table */ if (*stat.pwcsName == 0x4840) + { + CoTaskMemFree(stat.pwcsName); continue; + } stream = create_stream(sv, stat.pwcsName, TRUE, NULL); if (!stream) { count = -1; + CoTaskMemFree(stat.pwcsName); break; } IStorage_OpenStream(sv->db->storage, stat.pwcsName, 0, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stream->stream); + CoTaskMemFree(stat.pwcsName); if (!add_stream_to_table(sv, stream, count++)) { diff --git a/dlls/msi/table.c b/dlls/msi/table.c index 7824521c413..ca6fa1b911e 100644 --- a/dlls/msi/table.c +++ b/dlls/msi/table.c @@ -265,6 +265,7 @@ void enum_stream_names( IStorage *stg ) decode_streamname( stat.pwcsName, name ); TRACE("stream %2d -> %s %s\n", n, debugstr_w(stat.pwcsName), debugstr_w(name) ); + CoTaskMemFree( stat.pwcsName ); n++; } @@ -2577,6 +2578,7 @@ UINT msi_table_apply_transform( MSIDATABASE *db, IStorage *stg ) break; decode_streamname( stat.pwcsName, name ); + CoTaskMemFree( stat.pwcsName ); if ( name[0] != 0x4840 ) continue; diff --git a/dlls/ole32/moniker.c b/dlls/ole32/moniker.c index 8511a9f72b4..e77c8c417ec 100644 --- a/dlls/ole32/moniker.c +++ b/dlls/ole32/moniker.c @@ -73,6 +73,7 @@ struct rot_entry MonikerComparisonData* moniker_data; /* moniker comparison data that identifies this object */ DWORD cookie; /* cookie identifying this object */ FILETIME last_modified; + IrotContextHandle ctxt_handle; }; /* define the RunningObjectTableImpl structure */ @@ -183,7 +184,8 @@ static inline void rot_entry_delete(struct rot_entry *rot_entry) InterfaceData *moniker = NULL; __TRY { - IrotRevoke(get_irot_handle(), rot_entry->cookie, &object, &moniker); + IrotRevoke(get_irot_handle(), rot_entry->cookie, + &rot_entry->ctxt_handle, &object, &moniker); } __EXCEPT(rpc_filter) { @@ -554,7 +556,10 @@ RunningObjectTableImpl_Register(IRunningObjectTable* iface, DWORD grfFlags, { __TRY { - hr = IrotRegister(get_irot_handle(), rot_entry->moniker_data, rot_entry->object, moniker, &rot_entry->last_modified, grfFlags, &rot_entry->cookie); + hr = IrotRegister(get_irot_handle(), rot_entry->moniker_data, + rot_entry->object, moniker, + &rot_entry->last_modified, grfFlags, + &rot_entry->cookie, &rot_entry->ctxt_handle); } __EXCEPT(rpc_filter) { diff --git a/dlls/oleaut32/tests/usrmarshal.c b/dlls/oleaut32/tests/usrmarshal.c index 20fc2f82244..70f9fd29c62 100644 --- a/dlls/oleaut32/tests/usrmarshal.c +++ b/dlls/oleaut32/tests/usrmarshal.c @@ -1043,7 +1043,6 @@ static void test_marshal_VARIANT(void) lpsa = SafeArrayCreate(VT_R8, 1, &sab); *(DWORD *)lpsa->pvData = 0xcafebabe; *((DWORD *)lpsa->pvData + 1) = 0xdeadbeef; - lpsa->cLocks = 7; VariantInit(&v); V_VT(&v) = VT_UI4 | VT_ARRAY; @@ -1127,7 +1126,6 @@ static void test_marshal_VARIANT(void) VARIANT_UserFree(&umcb.Flags, &v2); } HeapFree(GetProcessHeap(), 0, buffer); - lpsa->cLocks = 0; SafeArrayDestroy(lpsa); /*** VARIANT BYREF ***/ @@ -1216,9 +1214,7 @@ static void test_marshal_VARIANT(void) stubMsg.Buffer = buffer; next = VARIANT_UserUnmarshal(&umcb.Flags, buffer, &v3); ok(V_VT(&v) == V_VT(&v3), "got vt %d expect %d\n", V_VT(&v), V_VT(&v3)); - ok(V_VT(V_VARIANTREF(&v)) == V_VT(V_VARIANTREF(&v3)), "vts differ %x %x\n", - V_VT(V_VARIANTREF(&v)), V_VT(V_VARIANTREF(&v3))); - ok(V_R8(V_VARIANTREF(&v)) == V_R8(V_VARIANTREF(&v3)), "r8s differ\n"); + ok(V_UNKNOWN(&v) == V_UNKNOWN(&v3), "got %p expect %p\n", V_UNKNOWN(&v), V_UNKNOWN(&v3)); VARIANT_UserFree(&umcb.Flags, &v3); ok(heap_unknown->refs == 1, "%d refcounts of IUnknown leaked\n", heap_unknown->refs - 1); IUnknown_Release((IUnknown *)heap_unknown); diff --git a/dlls/quartz/filtergraph.c b/dlls/quartz/filtergraph.c index fc1aa572e08..5b4b7110d71 100644 --- a/dlls/quartz/filtergraph.c +++ b/dlls/quartz/filtergraph.c @@ -289,6 +289,7 @@ static ULONG WINAPI FilterGraphInner_Release(IUnknown * iface) { { IBaseFilter_SetSyncSource(This->ppFiltersInGraph[i], NULL); IBaseFilter_Release(This->ppFiltersInGraph[i]); + CoTaskMemFree(This->pFilterNames[i]); } for (i = 0; i < This->nItfCacheEntries; i++) { diff --git a/dlls/rpcrt4/Makefile.in b/dlls/rpcrt4/Makefile.in index 65ae475c31c..abfea12c2a2 100644 --- a/dlls/rpcrt4/Makefile.in +++ b/dlls/rpcrt4/Makefile.in @@ -14,6 +14,7 @@ C_SRCS = \ cpsf.c \ cstub.c \ ndr_clientserver.c \ + ndr_contexthandle.c \ ndr_fullpointer.c \ ndr_marshall.c \ ndr_ole.c \ diff --git a/dlls/rpcrt4/ndr_contexthandle.c b/dlls/rpcrt4/ndr_contexthandle.c new file mode 100644 index 00000000000..0b3eeb1fcd4 --- /dev/null +++ b/dlls/rpcrt4/ndr_contexthandle.c @@ -0,0 +1,339 @@ +/* + * NDR data marshalling + * + * Copyright 2006 Mike McCormack (for CodeWeavers) + * Copyright 2006-2007 Robert Shearman (for CodeWeavers) + * + * 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 "ndr_misc.h" +#include "rpc_assoc.h" +#include "rpcndr.h" + +#include "wine/rpcfc.h" + +#include "wine/debug.h" +#include "wine/list.h" + +WINE_DEFAULT_DEBUG_CHANNEL(ole); + +#define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e + +typedef struct ndr_context_handle +{ + ULONG attributes; + GUID uuid; +} ndr_context_handle; + +struct context_handle_entry +{ + struct list entry; + DWORD magic; + RPC_BINDING_HANDLE handle; + ndr_context_handle wire_data; +}; + +static struct list context_handle_list = LIST_INIT(context_handle_list); + +static CRITICAL_SECTION ndr_context_cs; +static CRITICAL_SECTION_DEBUG ndr_context_debug = +{ + 0, 0, &ndr_context_cs, + { &ndr_context_debug.ProcessLocksList, &ndr_context_debug.ProcessLocksList }, + 0, 0, { (DWORD_PTR)(__FILE__ ": ndr_context") } +}; +static CRITICAL_SECTION ndr_context_cs = { &ndr_context_debug, -1, 0, 0, 0, 0 }; + +static struct context_handle_entry *get_context_entry(NDR_CCONTEXT CContext) +{ + struct context_handle_entry *che = (struct context_handle_entry*) CContext; + + if (che->magic != NDR_CONTEXT_HANDLE_MAGIC) + return NULL; + return che; +} + +static struct context_handle_entry *context_entry_from_guid(LPCGUID uuid) +{ + struct context_handle_entry *che; + LIST_FOR_EACH_ENTRY(che, &context_handle_list, struct context_handle_entry, entry) + if (IsEqualGUID(&che->wire_data.uuid, uuid)) + return che; + return NULL; +} + +RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext) +{ + struct context_handle_entry *che; + RPC_BINDING_HANDLE handle = NULL; + + TRACE("%p\n", CContext); + + EnterCriticalSection(&ndr_context_cs); + che = get_context_entry(CContext); + if (che) + handle = che->handle; + LeaveCriticalSection(&ndr_context_cs); + + if (!handle) + RpcRaiseException(ERROR_INVALID_HANDLE); + return handle; +} + +void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff) +{ + struct context_handle_entry *che; + + TRACE("%p %p\n", CContext, pBuff); + + if (CContext) + { + EnterCriticalSection(&ndr_context_cs); + che = get_context_entry(CContext); + memcpy(pBuff, &che->wire_data, sizeof (ndr_context_handle)); + LeaveCriticalSection(&ndr_context_cs); + } + else + { + ndr_context_handle *wire_data = (ndr_context_handle *)pBuff; + wire_data->attributes = 0; + wire_data->uuid = GUID_NULL; + } +} + +/*********************************************************************** + * RpcSmDestroyClientContext [RPCRT4.@] + */ +RPC_STATUS WINAPI RpcSmDestroyClientContext(void **ContextHandle) +{ + RPC_STATUS status = RPC_X_SS_CONTEXT_MISMATCH; + struct context_handle_entry *che = NULL; + + TRACE("(%p)\n", ContextHandle); + + EnterCriticalSection(&ndr_context_cs); + che = get_context_entry(*ContextHandle); + *ContextHandle = NULL; + if (che) + { + status = RPC_S_OK; + list_remove(&che->entry); + } + + LeaveCriticalSection(&ndr_context_cs); + + if (che) + { + RpcBindingFree(&che->handle); + HeapFree(GetProcessHeap(), 0, che); + } + + return status; +} + +/*********************************************************************** + * RpcSsDestroyClientContext [RPCRT4.@] + */ +void WINAPI RpcSsDestroyClientContext(void **ContextHandle) +{ + RPC_STATUS status = RpcSmDestroyClientContext(ContextHandle); + if (status != RPC_S_OK) + RpcRaiseException(status); +} + +static UINT ndr_update_context_handle(NDR_CCONTEXT *CContext, + RPC_BINDING_HANDLE hBinding, + const ndr_context_handle *chi) +{ + struct context_handle_entry *che = NULL; + + /* a null UUID means we should free the context handle */ + if (IsEqualGUID(&chi->uuid, &GUID_NULL)) + { + if (*CContext) + { + che = get_context_entry(*CContext); + if (!che) + return ERROR_INVALID_HANDLE; + list_remove(&che->entry); + RpcBindingFree(&che->handle); + HeapFree(GetProcessHeap(), 0, che); + che = NULL; + } + } + /* if there's no existing entry matching the GUID, allocate one */ + else if (!(che = context_entry_from_guid(&chi->uuid))) + { + che = HeapAlloc(GetProcessHeap(), 0, sizeof *che); + if (!che) + return ERROR_NOT_ENOUGH_MEMORY; + che->magic = NDR_CONTEXT_HANDLE_MAGIC; + RpcBindingCopy(hBinding, &che->handle); + list_add_tail(&context_handle_list, &che->entry); + memcpy(&che->wire_data, chi, sizeof *chi); + } + + *CContext = che; + + return ERROR_SUCCESS; +} + +/*********************************************************************** + * NDRCContextUnmarshall [RPCRT4.@] + */ +void WINAPI NDRCContextUnmarshall(NDR_CCONTEXT *CContext, + RPC_BINDING_HANDLE hBinding, + void *pBuff, ULONG DataRepresentation) +{ + UINT r; + + TRACE("*%p=(%p) %p %p %08x\n", + CContext, *CContext, hBinding, pBuff, DataRepresentation); + + EnterCriticalSection(&ndr_context_cs); + r = ndr_update_context_handle(CContext, hBinding, pBuff); + LeaveCriticalSection(&ndr_context_cs); + if (r) + RpcRaiseException(r); +} + +/*********************************************************************** + * NDRSContextMarshall [RPCRT4.@] + */ +void WINAPI NDRSContextMarshall(NDR_SCONTEXT SContext, + void *pBuff, + NDR_RUNDOWN userRunDownIn) +{ + TRACE("(%p %p %p)\n", SContext, pBuff, userRunDownIn); + NDRSContextMarshall2(I_RpcGetCurrentCallHandle(), SContext, pBuff, userRunDownIn, NULL, 0); +} + +/*********************************************************************** + * NDRSContextMarshallEx [RPCRT4.@] + */ +void WINAPI NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding, + NDR_SCONTEXT SContext, + void *pBuff, + NDR_RUNDOWN userRunDownIn) +{ + TRACE("(%p %p %p %p)\n", hBinding, SContext, pBuff, userRunDownIn); + NDRSContextMarshall2(hBinding, SContext, pBuff, userRunDownIn, NULL, 0); +} + +/*********************************************************************** + * NDRSContextMarshall2 [RPCRT4.@] + */ +void WINAPI NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding, + NDR_SCONTEXT SContext, + void *pBuff, + NDR_RUNDOWN userRunDownIn, + void *CtxGuard, ULONG Flags) +{ + RpcBinding *binding = hBinding; + RPC_STATUS status; + ndr_context_handle *ndr = pBuff; + + TRACE("(%p %p %p %p %p %u)\n", + hBinding, SContext, pBuff, userRunDownIn, CtxGuard, Flags); + + if (!binding->server || !binding->Assoc) + RpcRaiseException(ERROR_INVALID_HANDLE); + + if (SContext->userContext) + { + status = RpcServerAssoc_UpdateContextHandle(binding->Assoc, SContext, CtxGuard, userRunDownIn); + if (status != RPC_S_OK) + RpcRaiseException(status); + ndr->attributes = 0; + RpcContextHandle_GetUuid(SContext, &ndr->uuid); + } + else + { + if (!RpcContextHandle_IsGuardCorrect(SContext, CtxGuard)) + RpcRaiseException(ERROR_INVALID_HANDLE); + memset(ndr, 0, sizeof(*ndr)); + /* Note: release the context handle twice in this case to release + * one ref being kept around for the data and one ref for the + * unmarshall/marshall sequence */ + if (!RpcServerAssoc_ReleaseContextHandle(binding->Assoc, SContext, FALSE)) + return; /* this is to cope with the case of the data not being valid + * before and so not having a further reference */ + } + RpcServerAssoc_ReleaseContextHandle(binding->Assoc, SContext, TRUE); +} + +/*********************************************************************** + * NDRSContextUnmarshall [RPCRT4.@] + */ +NDR_SCONTEXT WINAPI NDRSContextUnmarshall(void *pBuff, + ULONG DataRepresentation) +{ + TRACE("(%p %08x)\n", pBuff, DataRepresentation); + return NDRSContextUnmarshall2(I_RpcGetCurrentCallHandle(), pBuff, DataRepresentation, NULL, 0); +} + +/*********************************************************************** + * NDRSContextUnmarshallEx [RPCRT4.@] + */ +NDR_SCONTEXT WINAPI NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding, + void *pBuff, + ULONG DataRepresentation) +{ + TRACE("(%p %p %08x)\n", hBinding, pBuff, DataRepresentation); + return NDRSContextUnmarshall2(hBinding, pBuff, DataRepresentation, NULL, 0); +} + +/*********************************************************************** + * NDRSContextUnmarshall2 [RPCRT4.@] + */ +NDR_SCONTEXT WINAPI NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding, + void *pBuff, + ULONG DataRepresentation, + void *CtxGuard, ULONG Flags) +{ + RpcBinding *binding = hBinding; + NDR_SCONTEXT SContext; + RPC_STATUS status; + + TRACE("(%p %p %08x %p %u)\n", + hBinding, pBuff, DataRepresentation, CtxGuard, Flags); + + if (!binding->server || !binding->Assoc) + RpcRaiseException(ERROR_INVALID_HANDLE); + + if (!pBuff) + status = RpcServerAssoc_AllocateContextHandle(binding->Assoc, CtxGuard, + &SContext); + else + { + const ndr_context_handle *context_ndr = pBuff; + if (context_ndr->attributes) + { + ERR("non-null attributes 0x%x\n", context_ndr->attributes); + status = ERROR_INVALID_HANDLE; + } + else + status = RpcServerAssoc_FindContextHandle(binding->Assoc, + &context_ndr->uuid, + CtxGuard, Flags, + &SContext); + } + + if (status != RPC_S_OK) + RpcRaiseException(status); + + return SContext; +} diff --git a/dlls/rpcrt4/ndr_marshall.c b/dlls/rpcrt4/ndr_marshall.c index 2db0212f9f0..60e057fdbc6 100644 --- a/dlls/rpcrt4/ndr_marshall.c +++ b/dlls/rpcrt4/ndr_marshall.c @@ -45,7 +45,6 @@ #include "wine/rpcfc.h" #include "wine/debug.h" -#include "wine/list.h" WINE_DEFAULT_DEBUG_CHANNEL(ole); @@ -2865,6 +2864,8 @@ unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pS ULONG bufsize, memsize; unsigned char alignment = pFormat[1] + 1; DWORD esize = *(const WORD*)(pFormat+2); + unsigned char *saved_buffer; + ULONG offset; TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); @@ -2882,13 +2883,16 @@ unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pS bufsize = safe_multiply(esize, pStubMsg->ActualCount); memsize = safe_multiply(esize, pStubMsg->MaxCount); + offset = pStubMsg->Offset; if (!*ppMemory || fMustAlloc) *ppMemory = NdrAllocate(pStubMsg, memsize); - pStubMsg->BufferMark = pStubMsg->Buffer; - safe_copy_from_buffer(pStubMsg, *ppMemory + pStubMsg->Offset, bufsize); + saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer; + safe_buffer_increment(pStubMsg, bufsize); - EmbeddedPointerUnmarshall(pStubMsg, *ppMemory, *ppMemory, pFormat, TRUE /* FIXME */); + EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc); + + memcpy(*ppMemory + offset, saved_buffer, bufsize); return NULL; } @@ -4475,6 +4479,8 @@ unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char alignment; DWORD size, elements, esize; ULONG bufsize; + unsigned char *saved_buffer; + ULONG offset; TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); @@ -4513,13 +4519,16 @@ unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, ALIGN_POINTER(pStubMsg->Buffer, alignment); bufsize = safe_multiply(esize, pStubMsg->ActualCount); + offset = pStubMsg->Offset; if (!*ppMemory || fMustAlloc) *ppMemory = NdrAllocate(pStubMsg, size); - pStubMsg->BufferMark = pStubMsg->Buffer; - safe_copy_from_buffer(pStubMsg, *ppMemory + pStubMsg->Offset, bufsize); + saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer; + safe_buffer_increment(pStubMsg, bufsize); - EmbeddedPointerUnmarshall(pStubMsg, *ppMemory, *ppMemory, pFormat, TRUE /* FIXME */); + EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc); + + memcpy(*ppMemory + offset, saved_buffer, bufsize); return NULL; } @@ -6002,13 +6011,44 @@ void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg, NDR_SCONTEXT ContextHandle, NDR_RUNDOWN RundownRoutine ) { - FIXME("(%p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine); + TRACE("(%p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine); + + ALIGN_POINTER(pStubMsg->Buffer, 4); + + if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) + { + ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", + pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } + + NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle, + pStubMsg->Buffer, RundownRoutine, NULL, 0); + pStubMsg->Buffer += cbNDRContext; } NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg) { - FIXME("(%p): stub\n", pStubMsg); - return NULL; + NDR_SCONTEXT ContextHandle; + + TRACE("(%p)\n", pStubMsg); + + ALIGN_POINTER(pStubMsg->Buffer, 4); + + if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) + { + ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", + pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } + + ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, + pStubMsg->Buffer, + pStubMsg->RpcMsg->DataRepresentation, + NULL, 0); + pStubMsg->Buffer += cbNDRContext; + + return ContextHandle; } void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg, @@ -6021,8 +6061,9 @@ void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg, NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat) { - FIXME("(%p, %p): stub\n", pStubMsg, pFormat); - return NULL; + TRACE("(%p, %p)\n", pStubMsg, pFormat); + return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL, + pStubMsg->RpcMsg->DataRepresentation, NULL, 0); } void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg, @@ -6030,260 +6071,45 @@ void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg, NDR_RUNDOWN RundownRoutine, PFORMAT_STRING pFormat) { - FIXME("(%p, %p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine, pFormat); -} - -NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, - PFORMAT_STRING pFormat) -{ - FIXME("(%p, %p): stub\n", pStubMsg, pFormat); - return NULL; -} - -#define NDR_CONTEXT_HANDLE_MAGIC 0x4352444e - -typedef struct ndr_context_handle -{ - DWORD attributes; - GUID uuid; -} ndr_context_handle; - -struct context_handle_entry -{ - struct list entry; - DWORD magic; - RPC_BINDING_HANDLE handle; - ndr_context_handle wire_data; -}; - -static struct list context_handle_list = LIST_INIT(context_handle_list); - -static CRITICAL_SECTION ndr_context_cs; -static CRITICAL_SECTION_DEBUG ndr_context_debug = -{ - 0, 0, &ndr_context_cs, - { &ndr_context_debug.ProcessLocksList, &ndr_context_debug.ProcessLocksList }, - 0, 0, { (DWORD_PTR)(__FILE__ ": ndr_context") } -}; -static CRITICAL_SECTION ndr_context_cs = { &ndr_context_debug, -1, 0, 0, 0, 0 }; - -static struct context_handle_entry *get_context_entry(NDR_CCONTEXT CContext) -{ - struct context_handle_entry *che = (struct context_handle_entry*) CContext; + TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat); - if (che->magic != NDR_CONTEXT_HANDLE_MAGIC) - return NULL; - return che; -} - -static struct context_handle_entry *context_entry_from_guid(LPCGUID uuid) -{ - struct context_handle_entry *che; - LIST_FOR_EACH_ENTRY(che, &context_handle_list, struct context_handle_entry, entry) - if (IsEqualGUID(&che->wire_data.uuid, uuid)) - return che; - return NULL; -} - -RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext) -{ - struct context_handle_entry *che; - RPC_BINDING_HANDLE handle = NULL; - - TRACE("%p\n", CContext); - - EnterCriticalSection(&ndr_context_cs); - che = get_context_entry(CContext); - if (che) - handle = che->handle; - LeaveCriticalSection(&ndr_context_cs); - - if (!handle) - RpcRaiseException(ERROR_INVALID_HANDLE); - return handle; -} - -void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff) -{ - struct context_handle_entry *che; - - TRACE("%p %p\n", CContext, pBuff); - - if (CContext) - { - EnterCriticalSection(&ndr_context_cs); - che = get_context_entry(CContext); - memcpy(pBuff, &che->wire_data, sizeof (ndr_context_handle)); - LeaveCriticalSection(&ndr_context_cs); - } - else - { - ndr_context_handle *wire_data = (ndr_context_handle *)pBuff; - wire_data->attributes = 0; - wire_data->uuid = GUID_NULL; - } -} - -/*********************************************************************** - * RpcSmDestroyClientContext [RPCRT4.@] - */ -RPC_STATUS WINAPI RpcSmDestroyClientContext(void **ContextHandle) -{ - RPC_STATUS status = RPC_X_SS_CONTEXT_MISMATCH; - struct context_handle_entry *che = NULL; - - TRACE("(%p)\n", ContextHandle); - - EnterCriticalSection(&ndr_context_cs); - che = get_context_entry(*ContextHandle); - *ContextHandle = NULL; - if (che) - { - status = RPC_S_OK; - list_remove(&che->entry); - } - - LeaveCriticalSection(&ndr_context_cs); + ALIGN_POINTER(pStubMsg->Buffer, 4); - if (che) + if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) { - RpcBindingFree(&che->handle); - HeapFree(GetProcessHeap(), 0, che); + ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", + pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); + RpcRaiseException(RPC_X_BAD_STUB_DATA); } - return status; + /* FIXME: do something with pFormat */ + NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle, + pStubMsg->Buffer, RundownRoutine, NULL, 0); + pStubMsg->Buffer += cbNDRContext; } -/*********************************************************************** - * RpcSsDestroyClientContext [RPCRT4.@] - */ -void WINAPI RpcSsDestroyClientContext(void **ContextHandle) +NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, + PFORMAT_STRING pFormat) { - RPC_STATUS status = RpcSmDestroyClientContext(ContextHandle); - if (status != RPC_S_OK) - RpcRaiseException(status); -} + NDR_SCONTEXT ContextHandle; -static UINT ndr_update_context_handle(NDR_CCONTEXT *CContext, - RPC_BINDING_HANDLE hBinding, - const ndr_context_handle *chi) -{ - struct context_handle_entry *che = NULL; + TRACE("(%p, %p)\n", pStubMsg, pFormat); - /* a null UUID means we should free the context handle */ - if (IsEqualGUID(&chi->uuid, &GUID_NULL)) - { - if (*CContext) - { - che = get_context_entry(*CContext); - if (!che) - return ERROR_INVALID_HANDLE; - list_remove(&che->entry); - RpcBindingFree(&che->handle); - HeapFree(GetProcessHeap(), 0, che); - che = NULL; - } - } - /* if there's no existing entry matching the GUID, allocate one */ - else if (!(che = context_entry_from_guid(&chi->uuid))) + ALIGN_POINTER(pStubMsg->Buffer, 4); + + if (pStubMsg->Buffer + cbNDRContext > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) { - che = HeapAlloc(GetProcessHeap(), 0, sizeof *che); - if (!che) - return ERROR_NOT_ENOUGH_MEMORY; - che->magic = NDR_CONTEXT_HANDLE_MAGIC; - RpcBindingCopy(hBinding, &che->handle); - list_add_tail(&context_handle_list, &che->entry); - memcpy(&che->wire_data, chi, sizeof *chi); + ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", + pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); + RpcRaiseException(RPC_X_BAD_STUB_DATA); } - *CContext = che; - - return ERROR_SUCCESS; -} - -/*********************************************************************** - * NDRCContextUnmarshall [RPCRT4.@] - */ -void WINAPI NDRCContextUnmarshall(NDR_CCONTEXT *CContext, - RPC_BINDING_HANDLE hBinding, - void *pBuff, ULONG DataRepresentation) -{ - UINT r; - - TRACE("*%p=(%p) %p %p %08x\n", - CContext, *CContext, hBinding, pBuff, DataRepresentation); - - EnterCriticalSection(&ndr_context_cs); - r = ndr_update_context_handle(CContext, hBinding, pBuff); - LeaveCriticalSection(&ndr_context_cs); - if (r) - RpcRaiseException(r); -} - -/*********************************************************************** - * NDRSContextMarshall [RPCRT4.@] - */ -void WINAPI NDRSContextMarshall(NDR_SCONTEXT CContext, - void *pBuff, - NDR_RUNDOWN userRunDownIn) -{ - FIXME("(%p %p %p): stub\n", CContext, pBuff, userRunDownIn); -} - -/*********************************************************************** - * NDRSContextMarshallEx [RPCRT4.@] - */ -void WINAPI NDRSContextMarshallEx(RPC_BINDING_HANDLE hBinding, - NDR_SCONTEXT CContext, - void *pBuff, - NDR_RUNDOWN userRunDownIn) -{ - FIXME("(%p %p %p %p): stub\n", hBinding, CContext, pBuff, userRunDownIn); -} - -/*********************************************************************** - * NDRSContextMarshall2 [RPCRT4.@] - */ -void WINAPI NDRSContextMarshall2(RPC_BINDING_HANDLE hBinding, - NDR_SCONTEXT CContext, - void *pBuff, - NDR_RUNDOWN userRunDownIn, - void *CtxGuard, ULONG Flags) -{ - FIXME("(%p %p %p %p %p %u): stub\n", - hBinding, CContext, pBuff, userRunDownIn, CtxGuard, Flags); -} - -/*********************************************************************** - * NDRSContextUnmarshall [RPCRT4.@] - */ -NDR_SCONTEXT WINAPI NDRSContextUnmarshall(void *pBuff, - ULONG DataRepresentation) -{ - FIXME("(%p %08x): stub\n", pBuff, DataRepresentation); - return NULL; -} - -/*********************************************************************** - * NDRSContextUnmarshallEx [RPCRT4.@] - */ -NDR_SCONTEXT WINAPI NDRSContextUnmarshallEx(RPC_BINDING_HANDLE hBinding, - void *pBuff, - ULONG DataRepresentation) -{ - FIXME("(%p %p %08x): stub\n", hBinding, pBuff, DataRepresentation); - return NULL; -} + /* FIXME: do something with pFormat */ + ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, + pStubMsg->Buffer, + pStubMsg->RpcMsg->DataRepresentation, + NULL, 0); + pStubMsg->Buffer += cbNDRContext; -/*********************************************************************** - * NDRSContextUnmarshall2 [RPCRT4.@] - */ -NDR_SCONTEXT WINAPI NDRSContextUnmarshall2(RPC_BINDING_HANDLE hBinding, - void *pBuff, - ULONG DataRepresentation, - void *CtxGuard, ULONG Flags) -{ - FIXME("(%p %p %08x %p %u): stub\n", - hBinding, pBuff, DataRepresentation, CtxGuard, Flags); - return NULL; + return ContextHandle; } diff --git a/dlls/rpcrt4/rpc_assoc.c b/dlls/rpcrt4/rpc_assoc.c index 7793c48e435..1bffb8564ed 100644 --- a/dlls/rpcrt4/rpc_assoc.c +++ b/dlls/rpcrt4/rpc_assoc.c @@ -24,6 +24,7 @@ #include "rpc.h" #include "rpcndr.h" +#include "winternl.h" #include "wine/unicode.h" #include "wine/debug.h" @@ -48,6 +49,19 @@ static struct list server_assoc_list = LIST_INIT(server_assoc_list); static LONG last_assoc_group_id; +typedef struct _RpcContextHandle +{ + struct list entry; + void *user_context; + NDR_RUNDOWN rundown_routine; + void *ctx_guard; + UUID uuid; + RTL_RWLOCK rw_lock; + unsigned int refs; +} RpcContextHandle; + +static void RpcContextHandle_Destroy(RpcContextHandle *context_handle); + static RPC_STATUS RpcAssoc_Alloc(LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint, LPCWSTR NetworkOptions, RpcAssoc **assoc_out) @@ -58,6 +72,7 @@ static RPC_STATUS RpcAssoc_Alloc(LPCSTR Protseq, LPCSTR NetworkAddr, return RPC_S_OUT_OF_RESOURCES; assoc->refs = 1; list_init(&assoc->free_connection_pool); + list_init(&assoc->context_handle_list); InitializeCriticalSection(&assoc->cs); assoc->Protseq = RPCRT4_strdupA(Protseq); assoc->NetworkAddr = RPCRT4_strdupA(NetworkAddr); @@ -171,6 +186,7 @@ ULONG RpcAssoc_Release(RpcAssoc *assoc) if (!refs) { RpcConnection *Connection, *cursor2; + RpcContextHandle *context_handle, *context_handle_cursor; TRACE("destroying assoc %p\n", assoc); @@ -180,6 +196,9 @@ ULONG RpcAssoc_Release(RpcAssoc *assoc) RPCRT4_DestroyConnection(Connection); } + LIST_FOR_EACH_ENTRY_SAFE(context_handle, context_handle_cursor, &assoc->context_handle_list, RpcContextHandle, entry) + RpcContextHandle_Destroy(context_handle); + HeapFree(GetProcessHeap(), 0, assoc->NetworkOptions); HeapFree(GetProcessHeap(), 0, assoc->Endpoint); HeapFree(GetProcessHeap(), 0, assoc->NetworkAddr); @@ -391,3 +410,130 @@ void RpcAssoc_ReleaseIdleConnection(RpcAssoc *assoc, RpcConnection *Connection) list_add_head(&assoc->free_connection_pool, &Connection->conn_pool_entry); LeaveCriticalSection(&assoc->cs); } + +RPC_STATUS RpcServerAssoc_AllocateContextHandle(RpcAssoc *assoc, void *CtxGuard, + NDR_SCONTEXT *SContext) +{ + RpcContextHandle *context_handle; + + context_handle = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*context_handle)); + if (!context_handle) + return ERROR_OUTOFMEMORY; + + context_handle->ctx_guard = CtxGuard; + RtlInitializeResource(&context_handle->rw_lock); + context_handle->refs = 1; + + /* lock here to mirror unmarshall, so we don't need to special-case the + * freeing of a non-marshalled context handle */ + RtlAcquireResourceExclusive(&context_handle->rw_lock, TRUE); + + EnterCriticalSection(&assoc->cs); + list_add_tail(&assoc->context_handle_list, &context_handle->entry); + LeaveCriticalSection(&assoc->cs); + + *SContext = (NDR_SCONTEXT)context_handle; + return RPC_S_OK; +} + +BOOL RpcContextHandle_IsGuardCorrect(NDR_SCONTEXT SContext, void *CtxGuard) +{ + RpcContextHandle *context_handle = (RpcContextHandle *)SContext; + return context_handle->ctx_guard == CtxGuard; +} + +RPC_STATUS RpcServerAssoc_FindContextHandle(RpcAssoc *assoc, const UUID *uuid, + void *CtxGuard, ULONG Flags, NDR_SCONTEXT *SContext) +{ + RpcContextHandle *context_handle; + + EnterCriticalSection(&assoc->cs); + LIST_FOR_EACH_ENTRY(context_handle, &assoc->context_handle_list, RpcContextHandle, entry) + { + if (RpcContextHandle_IsGuardCorrect((NDR_SCONTEXT)context_handle, CtxGuard) && + !memcmp(&context_handle->uuid, uuid, sizeof(*uuid))) + { + *SContext = (NDR_SCONTEXT)context_handle; + if (context_handle->refs++) + { + LeaveCriticalSection(&assoc->cs); + TRACE("found %p\n", context_handle); + RtlAcquireResourceExclusive(&context_handle->rw_lock, TRUE); + return RPC_S_OK; + } + } + } + LeaveCriticalSection(&assoc->cs); + + ERR("no context handle found for uuid %s, guard %p\n", + debugstr_guid(uuid), CtxGuard); + return ERROR_INVALID_HANDLE; +} + +RPC_STATUS RpcServerAssoc_UpdateContextHandle(RpcAssoc *assoc, + NDR_SCONTEXT SContext, + void *CtxGuard, + NDR_RUNDOWN rundown_routine) +{ + RpcContextHandle *context_handle = (RpcContextHandle *)SContext; + RPC_STATUS status; + + if (!RpcContextHandle_IsGuardCorrect((NDR_SCONTEXT)context_handle, CtxGuard)) + return ERROR_INVALID_HANDLE; + + EnterCriticalSection(&assoc->cs); + if (UuidIsNil(&context_handle->uuid, &status)) + { + /* add a ref for the data being valid */ + context_handle->refs++; + UuidCreate(&context_handle->uuid); + context_handle->rundown_routine = rundown_routine; + TRACE("allocated uuid %s for context handle %p\n", + debugstr_guid(&context_handle->uuid), context_handle); + } + LeaveCriticalSection(&assoc->cs); + + return RPC_S_OK; +} + +void RpcContextHandle_GetUuid(NDR_SCONTEXT SContext, UUID *uuid) +{ + RpcContextHandle *context_handle = (RpcContextHandle *)SContext; + *uuid = context_handle->uuid; +} + +static void RpcContextHandle_Destroy(RpcContextHandle *context_handle) +{ + TRACE("freeing %p\n", context_handle); + + if (context_handle->user_context && context_handle->rundown_routine) + { + TRACE("calling rundown routine %p with user context %p\n", + context_handle->rundown_routine, context_handle->user_context); + context_handle->rundown_routine(context_handle->user_context); + } + + RtlDeleteResource(&context_handle->rw_lock); + + HeapFree(GetProcessHeap(), 0, context_handle); +} + +unsigned int RpcServerAssoc_ReleaseContextHandle(RpcAssoc *assoc, NDR_SCONTEXT SContext, BOOL release_lock) +{ + RpcContextHandle *context_handle = (RpcContextHandle *)SContext; + unsigned int refs; + + if (release_lock) + RtlReleaseResource(&context_handle->rw_lock); + + EnterCriticalSection(&assoc->cs); + refs = --context_handle->refs; + if (!refs) + list_remove(&context_handle->entry); + LeaveCriticalSection(&assoc->cs); + + if (!refs) + RpcContextHandle_Destroy(context_handle); + + return refs; +} diff --git a/dlls/rpcrt4/rpc_assoc.h b/dlls/rpcrt4/rpc_assoc.h index a943324902e..1ce1f135638 100644 --- a/dlls/rpcrt4/rpc_assoc.h +++ b/dlls/rpcrt4/rpc_assoc.h @@ -19,6 +19,7 @@ * */ +#include "rpc_binding.h" #include "wine/list.h" typedef struct _RpcAssoc @@ -35,8 +36,13 @@ typedef struct _RpcAssoc ULONG assoc_group_id; CRITICAL_SECTION cs; - /* connections available to be used */ + + /* client-only */ + /* connections available to be used (protected by cs) */ struct list free_connection_pool; + + /* server-only */ + struct list context_handle_list; /* protected by cs */ } RpcAssoc; RPC_STATUS RPCRT4_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint, LPCWSTR NetworkOptions, RpcAssoc **assoc); @@ -44,3 +50,9 @@ RPC_STATUS RpcAssoc_GetClientConnection(RpcAssoc *assoc, const RPC_SYNTAX_IDENTI void RpcAssoc_ReleaseIdleConnection(RpcAssoc *assoc, RpcConnection *Connection); ULONG RpcAssoc_Release(RpcAssoc *assoc); RPC_STATUS RpcServerAssoc_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint, LPCWSTR NetworkOptions, unsigned long assoc_gid, RpcAssoc **assoc_out); +RPC_STATUS RpcServerAssoc_AllocateContextHandle(RpcAssoc *assoc, void *CtxGuard, NDR_SCONTEXT *SContext); +RPC_STATUS RpcServerAssoc_FindContextHandle(RpcAssoc *assoc, const UUID *uuid, void *CtxGuard, ULONG Flags, NDR_SCONTEXT *SContext); +RPC_STATUS RpcServerAssoc_UpdateContextHandle(RpcAssoc *assoc, NDR_SCONTEXT SContext, void *CtxGuard, NDR_RUNDOWN rundown_routine); +unsigned int RpcServerAssoc_ReleaseContextHandle(RpcAssoc *assoc, NDR_SCONTEXT SContext, BOOL release_lock); +void RpcContextHandle_GetUuid(NDR_SCONTEXT SContext, UUID *uuid); +BOOL RpcContextHandle_IsGuardCorrect(NDR_SCONTEXT SContext, void *CtxGuard); diff --git a/dlls/rpcrt4/tests/server.c b/dlls/rpcrt4/tests/server.c index 9ddde434d0c..425b20b98af 100644 --- a/dlls/rpcrt4/tests/server.c +++ b/dlls/rpcrt4/tests/server.c @@ -504,6 +504,123 @@ s_get_filename(void) } void +s_context_handle_test(void) +{ + NDR_SCONTEXT h; + RPC_BINDING_HANDLE binding; + RPC_STATUS status; + unsigned char buf[20]; + static RPC_SERVER_INTERFACE server_if = + { + sizeof(RPC_SERVER_INTERFACE), + {{0x00000000,0x4114,0x0704,{0x23,0x01,0x00,0x00,0x00,0x00,0x00,0x00}},{1,0}}, + {{0x8a885d04,0x1ceb,0x11c9,{0x9f,0xe8,0x08,0x00,0x2b,0x10,0x48,0x60}},{2,0}}, + NULL, + 0, + 0, + 0, + 0, + 0, + }; + + binding = I_RpcGetCurrentCallHandle(); + ok(binding != NULL, "I_RpcGetCurrentCallHandle returned NULL\n"); + + h = NDRSContextUnmarshall2(binding, NULL, NDR_LOCAL_DATA_REPRESENTATION, NULL, 0); + ok(h != NULL, "NDRSContextUnmarshall2 returned NULL\n"); + + /* marshal a context handle with NULL userContext */ + memset(buf, 0xcc, sizeof(buf)); + NDRSContextMarshall2(binding, h, buf, NULL, NULL, 0); + ok(*(ULONG *)buf == 0, "attributes should have been set to 0 instead of 0x%x\n", *(ULONG *)buf); + ok(UuidIsNil((UUID *)&buf[4], &status), "uuid should have been nil\n"); + + h = NDRSContextUnmarshall2(binding, NULL, NDR_LOCAL_DATA_REPRESENTATION, NULL, 0); + ok(h != NULL, "NDRSContextUnmarshall2 returned NULL\n"); + + /* marshal a context handle with non-NULL userContext */ + memset(buf, 0xcc, sizeof(buf)); + h->userContext = (void *)0xdeadbeef; + NDRSContextMarshall2(binding, h, buf, NULL, NULL, 0); + ok(*(ULONG *)buf == 0, "attributes should have been set to 0 instead of 0x%x\n", *(ULONG *)buf); + ok(!UuidIsNil((UUID *)&buf[4], &status), "uuid should not have been nil\n"); + + h = NDRSContextUnmarshall2(binding, buf, NDR_LOCAL_DATA_REPRESENTATION, NULL, 0); + ok(h != NULL, "NDRSContextUnmarshall2 returned NULL\n"); + ok(h->userContext == (void *)0xdeadbeef, "userContext of interface didn't unmarshal properly: %p\n", h->userContext); + + /* marshal a context handle with an interface specified */ + h = NDRSContextUnmarshall2(binding, NULL, NDR_LOCAL_DATA_REPRESENTATION, &server_if.InterfaceId, 0); + ok(h != NULL, "NDRSContextUnmarshall2 returned NULL\n"); + + memset(buf, 0xcc, sizeof(buf)); + h->userContext = (void *)0xcafebabe; + NDRSContextMarshall2(binding, h, buf, NULL, &server_if.InterfaceId, 0); + ok(*(ULONG *)buf == 0, "attributes should have been set to 0 instead of 0x%x\n", *(ULONG *)buf); + ok(!UuidIsNil((UUID *)&buf[4], &status), "uuid should not have been nil\n"); + + h = NDRSContextUnmarshall2(binding, buf, NDR_LOCAL_DATA_REPRESENTATION, &server_if.InterfaceId, 0); + ok(h != NULL, "NDRSContextUnmarshall2 returned NULL\n"); + ok(h->userContext == (void *)0xcafebabe, "userContext of interface didn't unmarshal properly: %p\n", h->userContext); + + /* test same interface data, but different pointer */ + /* raises ERROR_INVALID_HANDLE exception */ + if (0) + { + RPC_SERVER_INTERFACE server_if_clone = server_if; + + NDRSContextUnmarshall2(binding, buf, NDR_LOCAL_DATA_REPRESENTATION, &server_if_clone.InterfaceId, 0); + } + + /* test different interface data, but different pointer */ + /* raises ERROR_INVALID_HANDLE exception */ + if (0) + { + static RPC_SERVER_INTERFACE server_if2 = + { + sizeof(RPC_SERVER_INTERFACE), + {{0x00000000,0x4114,0x0704,{0x23,0x01,0x00,0x00,0x00,0x00,0x00,0x00}},{1,0}}, + {{0x8a885d04,0x1ceb,0x11c9,{0x9f,0xe8,0x08,0x00,0x2b,0x10,0x48,0x60}},{2,0}}, + NULL, + 0, + 0, + 0, + 0, + 0, + }; + NDRSContextMarshall2(binding, h, buf, NULL, &server_if.InterfaceId, 0); + + NDRSContextUnmarshall2(binding, buf, NDR_LOCAL_DATA_REPRESENTATION, &server_if2.InterfaceId, 0); + } +} + +void +s_get_5numbers(int count, pints_t n[5]) +{ + int i; + for (i = 0; i < count; i++) + { + n[i].pi = midl_user_allocate(sizeof(*n[i].pi)); + *n[i].pi = i; + n[i].ppi = NULL; + n[i].pppi = NULL; + } +} + +void +s_get_numbers(int length, int size, pints_t n[]) +{ + int i; + for (i = 0; i < length; i++) + { + n[i].pi = midl_user_allocate(sizeof(*n[i].pi)); + *n[i].pi = i; + n[i].ppi = NULL; + n[i].pppi = NULL; + } +} + +void s_stop(void) { ok(RPC_S_OK == RpcMgmtStopServerListening(NULL), "RpcMgmtStopServerListening\n"); @@ -938,6 +1055,8 @@ array_tests(void) int n; int ca[5] = {1, -2, 3, -4, 5}; doub_carr_t *dc; + int *pi; + pints_t api[5]; ok(cstr_length(str1, sizeof str1) == strlen(str1), "RPC cstr_length\n"); @@ -1012,6 +1131,20 @@ array_tests(void) free_pyramid_doub_carr(dc); ok(sum_L1_norms(2, vs) == 21, "RPC sum_L1_norms\n"); + + memset(api, 0, sizeof(api)); + pi = HeapAlloc(GetProcessHeap(), 0, sizeof(*pi)); + *pi = -1; + api[0].pi = pi; + get_5numbers(1, api); + ok(api[0].pi == pi, "RPC varying array [out] pointer changed from %p to %p\n", pi, api[0].pi); + ok(*api[0].pi == 0, "pi unmarshalled incorrectly %d\n", *pi); + + api[0].pi = pi; + get_numbers(1, 1, api); + ok(api[0].pi == pi, "RPC conformant varying array [out] pointer changed from %p to %p\n", pi, api[0].pi); + ok(*api[0].pi == 0, "pi unmarshalled incorrectly %d\n", *pi); + HeapFree(GetProcessHeap(), 0, pi); } static void @@ -1021,6 +1154,7 @@ run_tests(void) union_tests(); pointer_tests(); array_tests(); + context_handle_test(); } static void diff --git a/dlls/rpcrt4/tests/server.idl b/dlls/rpcrt4/tests/server.idl index 4ce89d229e9..ec517572dc3 100644 --- a/dlls/rpcrt4/tests/server.idl +++ b/dlls/rpcrt4/tests/server.idl @@ -300,7 +300,9 @@ cpp_quote("#endif") int sum_pcarr2(int n, [size_is(, n)] int **pa); int sum_L1_norms(int n, [size_is(n)] vector_t *vs); + void get_5numbers([in] int count, [out, length_is(count)] pints_t pn[5]); + void get_numbers([in] int length, [in] int size, [out, length_is(length), size_is(size)] pints_t pn[]); str_t get_filename(void); - + void context_handle_test(void); void stop(void); } diff --git a/dlls/user32/spy.c b/dlls/user32/spy.c index c29c6d76fd9..22a4d5c4882 100644 --- a/dlls/user32/spy.c +++ b/dlls/user32/spy.c @@ -260,7 +260,9 @@ static const char * const MessageTypeNames[SPY_MAX_MSGNUM + 1] = "BM_CLICK", /* 0x00f5 */ "BM_GETIMAGE", /* 0x00f6 */ "BM_SETIMAGE", /* 0x00f7 */ - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, + "WM_INPUT_DEVICE_CHANGE", /* 0x00fe */ + "WM_INPUT", /* 0x00ff */ "WM_KEYDOWN", /* 0x0100 */ "WM_KEYUP", /* 0x0101 */ @@ -270,11 +272,11 @@ static const char * const MessageTypeNames[SPY_MAX_MSGNUM + 1] = "WM_SYSKEYUP", /* 0x0105 */ "WM_SYSCHAR", /* 0x0106 */ "WM_SYSDEADCHAR", /* 0x0107 */ - "WM_KEYLAST", /* 0x0108 */ NULL, - "WM_CONVERTREQUEST", - "WM_CONVERTRESULT", - "WM_INTERIM", + "WM_UNICHAR", /* 0x0109 */ + "WM_CONVERTREQUEST", /* 0x010a */ + "WM_CONVERTRESULT", /* 0x010b */ + "WM_INTERIM", /* 0x010c */ "WM_IME_STARTCOMPOSITION", /* 0x010d */ "WM_IME_ENDCOMPOSITION", /* 0x010e */ "WM_IME_COMPOSITION", /* 0x010f */ @@ -450,7 +452,8 @@ static const char * const MessageTypeNames[SPY_MAX_MSGNUM + 1] = "WM_XBUTTONDOWN", /* 0x020B */ "WM_XBUTTONUP", /* 0x020C */ "WM_XBUTTONDBLCLK", /* 0x020D */ - NULL, NULL, + "WM_MOUSEHWHEEL", /* 0x020E */ + NULL, "WM_PARENTNOTIFY", /* 0x0210 */ "WM_ENTERMENULOOP", /* 0x0211 */ @@ -589,17 +592,24 @@ static const char * const MessageTypeNames[SPY_MAX_MSGNUM + 1] = "WM_PALETTEISCHANGING", "WM_PALETTECHANGED", "WM_HOTKEY", /* 0x0312 */ - NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, "WM_PRINT", /* 0x0317 */ "WM_PRINTCLIENT", /* 0x0318 */ "WM_APPCOMMAND", /* 0x0319 */ "WM_THEMECHANGED", /* 0x031A */ - NULL, NULL, NULL, NULL, NULL, + NULL, NULL, + "WM_CLIPBOARDUPDATE", /* 0x031D */ + "WM_DWMCOMPOSITIONCHANGED", /* 0x031E */ + "WM_DWMNCRENDERINGCHANGED", /* 0x031F */ + "WM_DWMCOLORIZATIONCOLORCHANGED", /* 0x0320 */ + "WM_DWMWINDOWMAXIMIZEDCHANGE", /* 0x0321 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + "WM_GETTITLEBARINFOEX", /* 0x033F */ /* 0x0340 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index 9e6bf330063..9536b716572 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -2906,9 +2906,14 @@ static void position_d3dcolor(void *data) { } static void position_float4(void *data) { GLfloat *pos = (float *) data; - float w = 1.0 / pos[3]; - glVertex4f(pos[0] * w, pos[1] * w, pos[2] * w, w); + if (pos[3] < eps && pos[3] > -eps) + glVertex3fv(pos); + else { + float w = 1.0 / pos[3]; + + glVertex4f(pos[0] * w, pos[1] * w, pos[2] * w, w); + } } static void diffuse_d3dcolor(void *data) { diff --git a/dlls/winex11.drv/wintab.c b/dlls/winex11.drv/wintab.c index 5f7beb3ea20..c3ad140ad0b 100644 --- a/dlls/winex11.drv/wintab.c +++ b/dlls/winex11.drv/wintab.c @@ -202,6 +202,24 @@ typedef struct tagWTI_DEVICES_INFO /* a null-terminated string containing the devices Plug and Play ID.*/ } WTI_DEVICES_INFO, *LPWTI_DEVICES_INFO; + +/*********************************************************************** + * WACOM WINTAB EXTENSIONS TO SUPPORT CSR_TYPE + * In Wintab 1.2, a CSR_TYPE feature was added. This adds the + * ability to return a type of cursor on a tablet. + * Unfortunately, we cannot get the cursor type directly from X, + * and it is not specified directly anywhere. So we virtualize + * the type here. (This is unfortunate, the kernel module has + * the exact type, but we have no way of getting that module to + * pass us that type). + */ + +#define CSR_TYPE_PEN 0x822 +#define CSR_TYPE_ERASER 0x82a +#define CSR_TYPE_MOUSE_2D 0x007 +#define CSR_TYPE_MOUSE_4D 0x094 + + typedef struct tagWTPACKET { HCTX pkContext; UINT pkStatus; @@ -286,6 +304,64 @@ static int Tablet_ErrorHandler(Display *dpy, XErrorEvent *event, void* arg) return 1; } +static int find_cursor_by_type(int cursor_type, int exclude) +{ + int i; + for (i = 0; i < gNumCursors; i++) + if (i != exclude) + if (gSysCursor[i].TYPE == cursor_type) + return i; + + return -1; +} + +static void swap_cursors(int a, int b) +{ + WTI_CURSORS_INFO temp; + temp = gSysCursor[a]; + gSysCursor[a] = gSysCursor[b]; + gSysCursor[b] = temp; +} + +/* Adobe Photoshop 7.0 relies on the eraser being cursor #2 or #5, and it assumes the stylus is 1. +** If the X configuration is not set up that way, make it +*/ +static void Tablet_FixupCursors(void) +{ + if (gNumCursors >= 1) + if (gSysCursor[1].TYPE != CSR_TYPE_PEN) + { + int stylus; + stylus = find_cursor_by_type(CSR_TYPE_PEN, 1); + if (stylus >= 0) + { + swap_cursors(1, stylus); + TRACE("Swapped cursor %d with stylus slot (1) for compatibility with older programs\n", stylus); + } + } + + if (gNumCursors >= 2) + if (gSysCursor[2].TYPE != CSR_TYPE_ERASER) + { + int eraser; + eraser = find_cursor_by_type(CSR_TYPE_ERASER, 2); + if (eraser >= 0) + { + swap_cursors(2, eraser); + TRACE("Swapped cursor %d with eraser slot (2) for compatibility with older programs\n", eraser); + } + } +} + +static void trace_axes(XValuatorInfoPtr val) +{ + int i; + XAxisInfoPtr axis; + + for (i = 0, axis = val->axes ; i < val->num_axes; i++, axis++) + TRACE(" Axis %d: [resolution %d|min_value %d|max_value %d]\n", i, axis->resolution, axis->min_value, axis->max_value); +} + void X11DRV_LoadTabletInfo(HWND hwnddefault) { const WCHAR SZ_CONTEXT_NAME[] = {'W','i','n','e',' ','T','a','b','l','e','t',' ','C','o','n','t','e','x','t',0}; @@ -364,7 +440,15 @@ void X11DRV_LoadTabletInfo(HWND hwnddefault) { int class_loop; - TRACE("Trying device %i(%s)\n",loop,devices[loop].name); + TRACE("Device %i: [id %d|name %s|type %s|num_classes %d|use %s]\n", + loop, (int) devices[loop].id, devices[loop].name, + XGetAtomName(data->display, devices[loop].type), + devices[loop].num_classes, + devices[loop].use == IsXKeyboard ? "IsXKeyboard" : + devices[loop].use == IsXPointer ? "IsXPointer" : + devices[loop].use == IsXExtensionDevice ? "IsXExtensionDevice" : + "Unknown" + ); if (devices[loop].use == IsXExtensionDevice) { LPWTI_CURSORS_INFO cursor; @@ -390,8 +474,8 @@ void X11DRV_LoadTabletInfo(HWND hwnddefault) int shft = 0; X11DRV_expect_error(data->display,Tablet_ErrorHandler,NULL); - pXGetDeviceButtonMapping(data->display, opendevice, map, 32); - if (X11DRV_check_error()) + cursor->BUTTONS = pXGetDeviceButtonMapping(data->display, opendevice, map, 32); + if (X11DRV_check_error() || cursor->BUTTONS <= 0) { TRACE("No buttons, Non Tablet Device\n"); pXCloseDevice(data->display, opendevice); @@ -425,9 +509,9 @@ void X11DRV_LoadTabletInfo(HWND hwnddefault) cursor->NPBTNMARKS[1] = 1 ; cursor->CAPABILITIES = CRC_MULTIMODE; if (strcasecmp(target->name,"stylus")==0) - cursor->TYPE = 0x4825; + cursor->TYPE = CSR_TYPE_PEN; if (strcasecmp(target->name,"eraser")==0) - cursor->TYPE = 0xc85a; + cursor->TYPE = CSR_TYPE_ERASER; any = (XAnyClassPtr) (target->inputclassinfo); @@ -436,10 +520,22 @@ void X11DRV_LoadTabletInfo(HWND hwnddefault) { switch (any->class) { + case ValuatorClass: - if (!axis_read_complete) + Val = (XValuatorInfoPtr) any; + TRACE(" ValidatorInput %d: [class %d|length %d|num_axes %d|mode %d|motion_buffer %ld]\n", + class_loop, (int) Val->class, Val->length, Val->num_axes, Val->mode, Val->motion_buffer); + if (TRACE_ON(wintab32)) + trace_axes(Val); + + /* FIXME: This is imperfect; we compute our devices capabilities based upon the + ** first pen type device we find. However, a more correct implementation + ** would require acquiring a wide variety of tablets and running through + ** the various inputs to see what the values are. Odds are that a + ** more 'correct' algorithm would condense to this one anyway. + */ + if (!axis_read_complete && Val->num_axes >= 5 && cursor->TYPE == CSR_TYPE_PEN) { - Val = (XValuatorInfoPtr) any; Axis = (XAxisInfoPtr) ((char *) Val + sizeof (XValuatorInfo)); @@ -510,7 +606,8 @@ void X11DRV_LoadTabletInfo(HWND hwnddefault) int i; Button = (XButtonInfoPtr) any; - cursor->BUTTONS = Button->num_buttons; + TRACE(" ButtonInput %d: [class %d|length %d|num_buttons %d]\n", + class_loop, (int) Button->class, Button->length, Button->num_buttons); cursor->BTNNAMES = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*cchBuf); for (i = 0; i < cursor->BUTTONS; i++) { @@ -536,9 +633,10 @@ void X11DRV_LoadTabletInfo(HWND hwnddefault) } } pXFreeDeviceList(devices); - wine_tsx11_unlock(); gSysDevice.NCSRTYPES = cursor_target+1; gNumCursors = cursor_target+1; + Tablet_FixupCursors(); + wine_tsx11_unlock(); } static int figure_deg(int x, int y) @@ -644,7 +742,7 @@ static void motion_event( HWND hwnd, XEvent *event ) TRACE("Received tablet motion event (%p); device id %d, cursor num %d\n",hwnd, (int) motion->deviceid, curnum); /* Set cursor to inverted if cursor is the eraser */ - gMsgPacket.pkStatus = (cursor->TYPE == 0xc85a ?TPS_INVERT:0); + gMsgPacket.pkStatus = (cursor->TYPE == CSR_TYPE_ERASER ? TPS_INVERT:0); gMsgPacket.pkTime = EVENT_x11_time_to_win32_time(motion->time); gMsgPacket.pkSerialNumber = gSerial++; gMsgPacket.pkCursor = curnum; @@ -673,7 +771,7 @@ static void button_event( HWND hwnd, XEvent *event ) TRACE("Received tablet button %s event\n", (event->type == button_press_type)?"press":"release"); /* Set cursor to inverted if cursor is the eraser */ - gMsgPacket.pkStatus = (cursor->TYPE == 0xc85a ?TPS_INVERT:0); + gMsgPacket.pkStatus = (cursor->TYPE == CSR_TYPE_ERASER ? TPS_INVERT:0); set_button_state(curnum, button->deviceid); gMsgPacket.pkTime = EVENT_x11_time_to_win32_time(button->time); gMsgPacket.pkSerialNumber = gSerial++; @@ -709,7 +807,7 @@ static void proximity_event( HWND hwnd, XEvent *event ) TRACE("Received tablet proximity event\n"); /* Set cursor to inverted if cursor is the eraser */ - gMsgPacket.pkStatus = (cursor->TYPE == 0xc85a ?TPS_INVERT:0); + gMsgPacket.pkStatus = (cursor->TYPE == CSR_TYPE_ERASER ? TPS_INVERT:0); gMsgPacket.pkStatus |= (event->type==proximity_out_type)?TPS_PROXIMITY:0; gMsgPacket.pkTime = EVENT_x11_time_to_win32_time(proximity->time); gMsgPacket.pkSerialNumber = gSerial++; @@ -770,19 +868,19 @@ int X11DRV_AttachEventQueueToTablet(HWND hOwner) if (the_device->num_classes > 0) { DeviceKeyPress(the_device, key_press_type, event_list[event_number]); - if (event_list[event_number]) event_number++; + if (key_press_type) event_number++; DeviceKeyRelease(the_device, key_release_type, event_list[event_number]); - if (event_list[event_number]) event_number++; + if (key_release_type) event_number++; DeviceButtonPress(the_device, button_press_type, event_list[event_number]); - if (event_list[event_number]) event_number++; + if (button_press_type) event_number++; DeviceButtonRelease(the_device, button_release_type, event_list[event_number]); - if (event_list[event_number]) event_number++; + if (button_release_type) event_number++; DeviceMotionNotify(the_device, motion_type, event_list[event_number]); - if (event_list[event_number]) event_number++; + if (motion_type) event_number++; ProximityIn(the_device, proximity_in_type, event_list[event_number]); - if (event_list[event_number]) event_number++; + if (proximity_in_type) event_number++; ProximityOut(the_device, proximity_out_type, event_list[event_number]); - if (event_list[event_number]) event_number++; + if (proximity_out_type) event_number++; if (key_press_type) X11DRV_register_event_handler( key_press_type, key_event ); if (key_release_type) X11DRV_register_event_handler( key_release_type, key_event ); @@ -853,6 +951,7 @@ UINT X11DRV_WTInfoW(UINT wCategory, UINT nIndex, LPVOID lpOutput) switch (nIndex) { WORD version; + UINT num; case IFC_WINTABID: { static const WCHAR driver[] = {'W','i','n','e',' ','W','i','n','t','a','b',' ','1','.','1',0}; @@ -867,6 +966,14 @@ UINT X11DRV_WTInfoW(UINT wCategory, UINT nIndex, LPVOID lpOutput) version = (0x00) | (0x01 << 8); rc = CopyTabletData(lpOutput, &version,sizeof(WORD)); break; + case IFC_NDEVICES: + num = 1; + rc = CopyTabletData(lpOutput, &num,sizeof(num)); + break; + case IFC_NCURSORS: + num = gNumCursors; + rc = CopyTabletData(lpOutput, &num,sizeof(num)); + break; default: FIXME("WTI_INTERFACE unhandled index %i\n",nIndex); rc = 0; @@ -1032,95 +1139,104 @@ UINT X11DRV_WTInfoW(UINT wCategory, UINT nIndex, LPVOID lpOutput) case WTI_CURSORS+7: case WTI_CURSORS+8: case WTI_CURSORS+9: - tgtcursor = &gSysCursor[wCategory - WTI_CURSORS]; - switch (nIndex) + if (wCategory - WTI_CURSORS >= gNumCursors) { - case CSR_NAME: - rc = CopyTabletData(lpOutput, &tgtcursor->NAME, - (strlenW(tgtcursor->NAME)+1) * sizeof(WCHAR)); - break; - case CSR_ACTIVE: - rc = CopyTabletData(lpOutput,&tgtcursor->ACTIVE, - sizeof(BOOL)); - break; - case CSR_PKTDATA: - rc = CopyTabletData(lpOutput,&tgtcursor->PKTDATA, - sizeof(WTPKT)); - break; - case CSR_BUTTONS: - rc = CopyTabletData(lpOutput,&tgtcursor->BUTTONS, - sizeof(BYTE)); - break; - case CSR_BUTTONBITS: - rc = CopyTabletData(lpOutput,&tgtcursor->BUTTONBITS, - sizeof(BYTE)); - break; - case CSR_BTNNAMES: - FIXME("Button Names not returned correctly\n"); - rc = CopyTabletData(lpOutput,&tgtcursor->BTNNAMES, - tgtcursor->cchBTNNAMES*sizeof(WCHAR)); - break; - case CSR_BUTTONMAP: - rc = CopyTabletData(lpOutput,&tgtcursor->BUTTONMAP, - sizeof(BYTE)*32); - break; - case CSR_SYSBTNMAP: - rc = CopyTabletData(lpOutput,&tgtcursor->SYSBTNMAP, - sizeof(BYTE)*32); - break; - case CSR_NPBTNMARKS: - rc = CopyTabletData(lpOutput,&tgtcursor->NPBTNMARKS, - sizeof(UINT)*2); - break; - case CSR_NPBUTTON: - rc = CopyTabletData(lpOutput,&tgtcursor->NPBUTTON, - sizeof(BYTE)); - break; - case CSR_NPRESPONSE: - FIXME("Not returning CSR_NPRESPONSE correctly\n"); - rc = 0; - break; - case CSR_TPBUTTON: - rc = CopyTabletData(lpOutput,&tgtcursor->TPBUTTON, - sizeof(BYTE)); - break; - case CSR_TPBTNMARKS: - rc = CopyTabletData(lpOutput,&tgtcursor->TPBTNMARKS, - sizeof(UINT)*2); - break; - case CSR_TPRESPONSE: - FIXME("Not returning CSR_TPRESPONSE correctly\n"); - rc = 0; - break; - case CSR_PHYSID: + rc = 0; + WARN("Requested cursor information for non existent cursor %d; only %d cursors\n", + wCategory - WTI_CURSORS, gNumCursors); + } + else + { + tgtcursor = &gSysCursor[wCategory - WTI_CURSORS]; + switch (nIndex) { - DWORD id; - id = tgtcursor->PHYSID; - rc = CopyTabletData(lpOutput,&id,sizeof(DWORD)); + case CSR_NAME: + rc = CopyTabletData(lpOutput, &tgtcursor->NAME, + (strlenW(tgtcursor->NAME)+1) * sizeof(WCHAR)); + break; + case CSR_ACTIVE: + rc = CopyTabletData(lpOutput,&tgtcursor->ACTIVE, + sizeof(BOOL)); + break; + case CSR_PKTDATA: + rc = CopyTabletData(lpOutput,&tgtcursor->PKTDATA, + sizeof(WTPKT)); + break; + case CSR_BUTTONS: + rc = CopyTabletData(lpOutput,&tgtcursor->BUTTONS, + sizeof(BYTE)); + break; + case CSR_BUTTONBITS: + rc = CopyTabletData(lpOutput,&tgtcursor->BUTTONBITS, + sizeof(BYTE)); + break; + case CSR_BTNNAMES: + FIXME("Button Names not returned correctly\n"); + rc = CopyTabletData(lpOutput,&tgtcursor->BTNNAMES, + tgtcursor->cchBTNNAMES*sizeof(WCHAR)); + break; + case CSR_BUTTONMAP: + rc = CopyTabletData(lpOutput,&tgtcursor->BUTTONMAP, + sizeof(BYTE)*32); + break; + case CSR_SYSBTNMAP: + rc = CopyTabletData(lpOutput,&tgtcursor->SYSBTNMAP, + sizeof(BYTE)*32); + break; + case CSR_NPBTNMARKS: + rc = CopyTabletData(lpOutput,&tgtcursor->NPBTNMARKS, + sizeof(UINT)*2); + break; + case CSR_NPBUTTON: + rc = CopyTabletData(lpOutput,&tgtcursor->NPBUTTON, + sizeof(BYTE)); + break; + case CSR_NPRESPONSE: + FIXME("Not returning CSR_NPRESPONSE correctly\n"); + rc = 0; + break; + case CSR_TPBUTTON: + rc = CopyTabletData(lpOutput,&tgtcursor->TPBUTTON, + sizeof(BYTE)); + break; + case CSR_TPBTNMARKS: + rc = CopyTabletData(lpOutput,&tgtcursor->TPBTNMARKS, + sizeof(UINT)*2); + break; + case CSR_TPRESPONSE: + FIXME("Not returning CSR_TPRESPONSE correctly\n"); + rc = 0; + break; + case CSR_PHYSID: + { + DWORD id; + id = tgtcursor->PHYSID; + rc = CopyTabletData(lpOutput,&id,sizeof(DWORD)); + } + break; + case CSR_MODE: + rc = CopyTabletData(lpOutput,&tgtcursor->MODE,sizeof(UINT)); + break; + case CSR_MINPKTDATA: + rc = CopyTabletData(lpOutput,&tgtcursor->MINPKTDATA, + sizeof(UINT)); + break; + case CSR_MINBUTTONS: + rc = CopyTabletData(lpOutput,&tgtcursor->MINBUTTONS, + sizeof(UINT)); + break; + case CSR_CAPABILITIES: + rc = CopyTabletData(lpOutput,&tgtcursor->CAPABILITIES, + sizeof(UINT)); + break; + case CSR_TYPE: + rc = CopyTabletData(lpOutput,&tgtcursor->TYPE, + sizeof(UINT)); + break; + default: + FIXME("WTI_CURSORS unhandled index %i\n",nIndex); + rc = 0; } - break; - case CSR_MODE: - rc = CopyTabletData(lpOutput,&tgtcursor->MODE,sizeof(UINT)); - break; - case CSR_MINPKTDATA: - rc = CopyTabletData(lpOutput,&tgtcursor->MINPKTDATA, - sizeof(UINT)); - break; - case CSR_MINBUTTONS: - rc = CopyTabletData(lpOutput,&tgtcursor->MINBUTTONS, - sizeof(UINT)); - break; - case CSR_CAPABILITIES: - rc = CopyTabletData(lpOutput,&tgtcursor->CAPABILITIES, - sizeof(UINT)); - break; - case CSR_TYPE: - rc = CopyTabletData(lpOutput,&tgtcursor->TYPE, - sizeof(UINT)); - break; - default: - FIXME("WTI_CURSORS unhandled index %i\n",nIndex); - rc = 0; } break; case WTI_DEVICES: diff --git a/dlls/wintab32/context.c b/dlls/wintab32/context.c index cb85e08a33b..7974972ba11 100644 --- a/dlls/wintab32/context.c +++ b/dlls/wintab32/context.c @@ -73,73 +73,57 @@ static BOOL is_string_field(UINT wCategory, UINT nIndex) return TRUE; if (is_logcontext_category(wCategory) && nIndex == CTX_NAME) return TRUE; - if (wCategory >= WTI_CURSORS && wCategory <= WTI_CURSORS + 9) + if ((wCategory >= WTI_CURSORS && wCategory <= WTI_CURSORS + 9) && + (nIndex == CSR_NAME || nIndex == CSR_BTNNAMES)) return TRUE; if (wCategory == WTI_DEVICES && (nIndex == DVC_NAME || nIndex == DVC_PNPID)) return TRUE; return FALSE; } -static char* DUMPBITS(int x, char* buf) +static const char* DUMPBITS(int x) { - strcpy(buf,"{"); - if (x&PK_CONTEXT) strcat(buf,"PK_CONTEXT "); - if (x&PK_STATUS) strcat(buf, "PK_STATUS "); - if (x&PK_TIME) strcat(buf, "PK_TIME "); - if (x&PK_CHANGED) strcat(buf, "PK_CHANGED "); - if (x&PK_SERIAL_NUMBER) strcat(buf, "PK_SERIAL_NUMBER "); - if (x&PK_CURSOR) strcat(buf, "PK_CURSOR "); - if (x&PK_BUTTONS) strcat(buf, "PK_BUTTONS "); - if (x&PK_X) strcat(buf, "PK_X "); - if (x&PK_Y) strcat(buf, "PK_Y "); - if (x&PK_Z) strcat(buf, "PK_Z "); - if (x&PK_NORMAL_PRESSURE) strcat(buf, "PK_NORMAL_PRESSURE "); - if (x&PK_TANGENT_PRESSURE) strcat(buf, "PK_TANGENT_PRESSURE "); - if (x&PK_ORIENTATION) strcat(buf, "PK_ORIENTATION "); - if (x&PK_ROTATION) strcat(buf, "PK_ROTATION "); - strcat(buf, "}"); - return buf; + char buf[200]; + buf[0] = 0; + if (x&PK_CONTEXT) strcat(buf,"PK_CONTEXT "); + if (x&PK_STATUS) strcat(buf, "PK_STATUS "); + if (x&PK_TIME) strcat(buf, "PK_TIME "); + if (x&PK_CHANGED) strcat(buf, "PK_CHANGED "); + if (x&PK_SERIAL_NUMBER) strcat(buf, "PK_SERIAL_NUMBER "); + if (x&PK_CURSOR) strcat(buf, "PK_CURSOR "); + if (x&PK_BUTTONS) strcat(buf, "PK_BUTTONS "); + if (x&PK_X) strcat(buf, "PK_X "); + if (x&PK_Y) strcat(buf, "PK_Y "); + if (x&PK_Z) strcat(buf, "PK_Z "); + if (x&PK_NORMAL_PRESSURE) strcat(buf, "PK_NORMAL_PRESSURE "); + if (x&PK_TANGENT_PRESSURE) strcat(buf, "PK_TANGENT_PRESSURE "); + if (x&PK_ORIENTATION) strcat(buf, "PK_ORIENTATION "); + if (x&PK_ROTATION) strcat(buf, "PK_ROTATION "); + return wine_dbg_sprintf("{%s}",buf); } static inline void DUMPPACKET(WTPACKET packet) { TRACE("pkContext: %p pkStatus: 0x%x pkTime : 0x%x pkChanged: 0x%x pkSerialNumber: 0x%x pkCursor : %i pkButtons: %x pkX: %i pkY: %i pkZ: %i pkNormalPressure: %i pkTangentPressure: %i pkOrientation: (%i,%i,%i) pkRotation: (%i,%i,%i)\n", - packet.pkContext, - (UINT)packet.pkStatus, - (UINT)packet.pkTime, - (UINT)packet.pkChanged, - packet.pkSerialNumber, - packet.pkCursor, - (UINT)packet.pkButtons, - packet.pkX, - packet.pkY, - packet.pkZ, - packet.pkNormalPressure, - packet.pkTangentPressure, - packet.pkOrientation.orAzimuth, - packet.pkOrientation.orAltitude, packet.pkOrientation.orTwist, - packet.pkRotation.roPitch, - packet.pkRotation.roRoll, packet.pkRotation.roYaw); + packet.pkContext, packet.pkStatus, packet.pkTime, packet.pkChanged, packet.pkSerialNumber, + packet.pkCursor, packet.pkButtons, packet.pkX, packet.pkY, packet.pkZ, + packet.pkNormalPressure, packet.pkTangentPressure, + packet.pkOrientation.orAzimuth, packet.pkOrientation.orAltitude, packet.pkOrientation.orTwist, + packet.pkRotation.roPitch, packet.pkRotation.roRoll, packet.pkRotation.roYaw); } static inline void DUMPCONTEXT(LOGCONTEXTW lc) { - CHAR mmsg[4000]; - CHAR bits[100]; - CHAR bits1[100]; - CHAR bits2[100]; - - sprintf(mmsg,"%s, %x, %x, %x, %x, %x, %x, %x%s, %x%s, %x%s, %x, %x, %i, %i, %i, %i ,%i, %i, %i, %i, %i,%i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i %i %i", - wine_dbgstr_w(lc.lcName), lc.lcOptions, lc.lcStatus, lc.lcLocks, lc.lcMsgBase, -lc.lcDevice, lc.lcPktRate, (UINT)lc.lcPktData, DUMPBITS(lc.lcPktData,bits), -(UINT)lc.lcPktMode, DUMPBITS(lc.lcPktMode,bits1), (UINT)lc.lcMoveMask, -DUMPBITS(lc.lcMoveMask,bits2), (INT)lc.lcBtnDnMask, (INT)lc.lcBtnUpMask, -(INT)lc.lcInOrgX, (INT)lc.lcInOrgY, (INT)lc.lcInOrgZ, lc.lcInExtX, lc.lcInExtY, -lc.lcInExtZ, lc.lcOutOrgX, lc.lcOutOrgY, lc.lcOutOrgZ, lc.lcOutExtX, -lc.lcOutExtY, lc.lcOutExtZ, lc.lcSensX, lc.lcSensY, lc.lcSensZ, lc.lcSysMode, -lc.lcSysOrgX, lc.lcSysOrgY, lc.lcSysExtX, lc.lcSysExtY, lc.lcSysSensX, -lc.lcSysSensY); - TRACE("context: %s\n",mmsg); + TRACE("context: %s, %x, %x, %x, %x, %x, %x, %x%s, %x%s, %x%s, %x, %x, %i, %i, %i, %i ,%i, %i, %i, %i, %i,%i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i %i %i", + wine_dbgstr_w(lc.lcName), lc.lcOptions, lc.lcStatus, lc.lcLocks, lc.lcMsgBase, + lc.lcDevice, lc.lcPktRate, lc.lcPktData, DUMPBITS(lc.lcPktData), + lc.lcPktMode, DUMPBITS(lc.lcPktMode), lc.lcMoveMask, + DUMPBITS(lc.lcMoveMask), lc.lcBtnDnMask, lc.lcBtnUpMask, + lc.lcInOrgX, lc.lcInOrgY, lc.lcInOrgZ, lc.lcInExtX, lc.lcInExtY, + lc.lcInExtZ, lc.lcOutOrgX, lc.lcOutOrgY, lc.lcOutOrgZ, lc.lcOutExtX, + lc.lcOutExtY, lc.lcOutExtZ, lc.lcSensX, lc.lcSensY, lc.lcSensZ, lc.lcSysMode, + lc.lcSysOrgX, lc.lcSysOrgY, lc.lcSysExtX, lc.lcSysExtY, lc.lcSysSensX, + lc.lcSysSensY); } @@ -305,10 +289,9 @@ static LPVOID TABLET_CopyPacketData(LPOPENCONTEXT context, LPVOID lpPkt, LPWTPACKET wtp) { LPBYTE ptr; - CHAR bits[100]; ptr = lpPkt; - TRACE("Packet Bits %s\n",DUMPBITS(context->context.lcPktData,bits)); + TRACE("Packet Bits %s\n",DUMPBITS(context->context.lcPktData)); if (context->context.lcPktData & PK_CONTEXT) ptr+=CopyTabletData(ptr,&wtp->pkContext,sizeof(HCTX)); diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index f1ea825976c..98eb2f90760 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -2766,7 +2766,7 @@ INT WINAPI WSASendTo( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, if (timeout != -1) { - timeout -= timeout_start - GetTickCount(); + timeout -= GetTickCount() - timeout_start; if (timeout < 0) timeout = 0; } diff --git a/include/d3d10.idl b/include/d3d10.idl index 0a3439e7f50..4e5292f26b7 100644 --- a/include/d3d10.idl +++ b/include/d3d10.idl @@ -20,8 +20,8 @@ import "oaidl.idl"; import "ocidl.idl"; import "dxgi.idl"; -cpp_quote("#ifndef _D3D10_CONSTANTS"); -cpp_quote("#define _D3D10_CONSTANTS"); +cpp_quote("#ifndef _D3D10_CONSTANTS") +cpp_quote("#define _D3D10_CONSTANTS") const float D3D10_DEFAULT_BLEND_FACTOR_ALPHA = 1.0; const float D3D10_DEFAULT_BLEND_FACTOR_BLUE = 1.0; const float D3D10_DEFAULT_BLEND_FACTOR_GREEN = 1.0; @@ -238,7 +238,7 @@ const unsigned int D3D_MINOR_VERSION const unsigned int D3D_SPEC_DATE_DAY = 8; const unsigned int D3D_SPEC_DATE_MONTH = 8; const unsigned int D3D_SPEC_DATE_YEAR = 2006; -cpp_quote("#endif"); +cpp_quote("#endif") const unsigned int D3D10_APPEND_ALIGNED_ELEMENT = 0xffffffff; const unsigned int _FACD3D10 = 0x87; @@ -246,10 +246,10 @@ const unsigned int _FACD3D10DEBUG const unsigned int D3D10_FILTER_TYPE_MASK = 0x3; const unsigned int D3D10_SDK_VERSION = 29; -cpp_quote("#define MAKE_D3D10_HRESULT(code) MAKE_HRESULT( 1, _FACD3D10, code)"); -cpp_quote("#define MAKE_D3D10_STATUS(code) MAKE_HRESULT( 0, _FACD3D10, code)"); -cpp_quote("#define D3D10_ERROR_TOO_MANY_UNIQUE_STATE_OBJECTS MAKE_D3D10_HRESULT(1)"); -cpp_quote("#define D3D10_ERROR_FILE_NOT_FOUND MAKE_D3D10_HRESULT(2)"); +cpp_quote("#define MAKE_D3D10_HRESULT(code) MAKE_HRESULT( 1, _FACD3D10, code)") +cpp_quote("#define MAKE_D3D10_STATUS(code) MAKE_HRESULT( 0, _FACD3D10, code)") +cpp_quote("#define D3D10_ERROR_TOO_MANY_UNIQUE_STATE_OBJECTS MAKE_D3D10_HRESULT(1)") +cpp_quote("#define D3D10_ERROR_FILE_NOT_FOUND MAKE_D3D10_HRESULT(2)") typedef enum D3D10_BLEND { D3D10_BLEND_ZERO = 1, diff --git a/include/msinkaut.idl b/include/msinkaut.idl index 75f7686d97d..1f221749a4c 100644 --- a/include/msinkaut.idl +++ b/include/msinkaut.idl @@ -130,7 +130,7 @@ library MSINKAUTLib [out, retval] IInkDrawingAttributes** DrawingAttributes); }; -cpp_quote("#ifndef _WINGDI_"); +cpp_quote("#ifndef _WINGDI_") /* already defined in wingdi.h but needed for WIDL */ typedef struct tagXFORM { single eM11; @@ -140,7 +140,7 @@ cpp_quote("#ifndef _WINGDI_"); single eDx; single eDy; } XFORM; -cpp_quote("#endif /* _WINGDI_ */"); +cpp_quote("#endif /* _WINGDI_ */") [ odl, diff --git a/include/oleacc.idl b/include/oleacc.idl index e92f9fd83f7..53332857aef 100644 --- a/include/oleacc.idl +++ b/include/oleacc.idl @@ -172,9 +172,9 @@ cpp_quote("HRESULT WINAPI CreateStdAccessibleProxyA(HWND,LPCSTR,LONG,REFIID,void cpp_quote("HRESULT WINAPI CreateStdAccessibleProxyW(HWND,LPCWSTR,LONG,REFIID,void **);") cpp_quote("#define CreateStdAccessibleProxy WINELIB_NAME_AW(CreateStdAccessibleProxy)") -cpp_quote("UINT WINAPI GetRoleTextA(DWORD,LPSTR,UINT);"); -cpp_quote("UINT WINAPI GetRoleTextW(DWORD,LPWSTR,UINT);"); -cpp_quote("#define GetRoleText WINELIB_NAME_AW(GetRoleText)"); -cpp_quote("UINT WINAPI GetStateTextA(DWORD,LPSTR,UINT);"); -cpp_quote("UINT WINAPI GetStateTextW(DWORD,LPWSTR,UINT);"); +cpp_quote("UINT WINAPI GetRoleTextA(DWORD,LPSTR,UINT);") +cpp_quote("UINT WINAPI GetRoleTextW(DWORD,LPWSTR,UINT);") +cpp_quote("#define GetRoleText WINELIB_NAME_AW(GetRoleText)") +cpp_quote("UINT WINAPI GetStateTextA(DWORD,LPSTR,UINT);") +cpp_quote("UINT WINAPI GetStateTextW(DWORD,LPWSTR,UINT);") cpp_quote("#define GetStateText WINELIB_NAME_AW(GetStateText)") diff --git a/include/wine/irot.idl b/include/wine/irot.idl index 12a2c3311ba..f14af136308 100644 --- a/include/wine/irot.idl +++ b/include/wine/irot.idl @@ -18,8 +18,8 @@ import "wtypes.idl"; -cpp_quote("#define IROT_PROTSEQ {'n','c','a','l','r','p','c',0}"); -cpp_quote("#define IROT_ENDPOINT {'i','r','o','t',0}"); +cpp_quote("#define IROT_PROTSEQ {'n','c','a','l','r','p','c',0}") +cpp_quote("#define IROT_ENDPOINT {'i','r','o','t',0}") typedef struct tagMonikerComparisonData { ULONG ulCntData; @@ -51,6 +51,7 @@ interface Irot typedef DWORD IrotCookie; typedef handle_t IrotHandle; + typedef [context_handle] void *IrotContextHandle; HRESULT IrotRegister( [in] IrotHandle h, @@ -59,11 +60,13 @@ interface Irot [in] const InterfaceData *moniker, [in] const FILETIME *time, [in] DWORD grfFlags, - [out] IrotCookie *cookie); + [out] IrotCookie *cookie, + [out] IrotContextHandle *ctxt_handle); HRESULT IrotRevoke( [in] IrotHandle h, [in] IrotCookie cookie, + [in, out] IrotContextHandle *ctxt_handle, [out] PInterfaceData *object, [out] PInterfaceData *moniker); diff --git a/include/winuser.h b/include/winuser.h index ddd81c5b09a..3a6a42c2797 100644 --- a/include/winuser.h +++ b/include/winuser.h @@ -1193,6 +1193,7 @@ WINUSERAPI BOOL WINAPI SetSysColors(INT,const INT*,const COLORREF*); #define WM_NCXBUTTONDBLCLK 0x00ad /* Raw input */ +#define WM_INPUT_DEVICE_CHANGE 0x00fe #define WM_INPUT 0x00ff /* Keyboard messages */ @@ -1204,8 +1205,9 @@ WINUSERAPI BOOL WINAPI SetSysColors(INT,const INT*,const COLORREF*); #define WM_SYSKEYUP 0x0105 #define WM_SYSCHAR 0x0106 #define WM_SYSDEADCHAR 0x0107 +#define WM_UNICHAR 0x0109 #define WM_KEYFIRST WM_KEYDOWN -#define WM_KEYLAST 0x0108 +#define WM_KEYLAST 0x0109 /* Win32 4.0 messages for IME */ #define WM_IME_STARTCOMPOSITION 0x010d @@ -1278,12 +1280,13 @@ WINUSERAPI BOOL WINAPI SetSysColors(INT,const INT*,const COLORREF*); #define WM_XBUTTONDOWN 0x020B #define WM_XBUTTONUP 0x020C #define WM_XBUTTONDBLCLK 0x020D +#define WM_MOUSEHWHEEL 0x020E #define XBUTTON1 0x0001 #define XBUTTON2 0x0002 #define WM_MOUSEFIRST 0x0200 -#define WM_MOUSELAST 0x020D +#define WM_MOUSELAST 0x020E #define WHEEL_DELTA 120 #define WHEEL_PAGESCROLL (UINT_MAX) @@ -1369,6 +1372,11 @@ WINUSERAPI BOOL WINAPI SetSysColors(INT,const INT*,const COLORREF*); #define WM_IME_KEYDOWN 0x0290 #define WM_IME_KEYUP 0x0291 +#define WM_NCMOUSEHOVER 0x02A0 +#define WM_MOUSEHOVER 0x02A1 +#define WM_MOUSELEAVE 0x02A3 +#define WM_NCMOUSELEAVE 0x02A2 + #define WM_WTSSESSION_CHANGE 0x02B1 #define WM_TABLET_FIRST 0x02c0 @@ -1404,6 +1412,14 @@ WINUSERAPI BOOL WINAPI SetSysColors(INT,const INT*,const COLORREF*); #define WM_PRINTCLIENT 0x0318 #define WM_APPCOMMAND 0x0319 #define WM_THEMECHANGED 0x031A +#define WM_CLIPBOARDUPDATE 0x031D + +#define WM_DWMCOMPOSITIONCHANGED 0x031E +#define WM_DWMNCRENDERINGCHANGED 0x031F +#define WM_DWMCOLORIZATIONCOLORCHANGED 0x0320 +#define WM_DWMWINDOWMAXIMIZEDCHANGE 0x0321 + +#define WM_GETTITLEBARINFOEX 0x033F #define WM_HANDHELDFIRST 0x0358 #define WM_HANDHELDLAST 0x035F @@ -1416,6 +1432,8 @@ WINUSERAPI BOOL WINAPI SetSysColors(INT,const INT*,const COLORREF*); #define WM_APP 0x8000 +#define UNICODE_NOCHAR 0xFFFF + /* MsgWaitForMultipleObjectsEx flags */ #define MWMO_WAITALL 0x0001 #define MWMO_ALERTABLE 0x0002 @@ -3799,12 +3817,6 @@ typedef struct tagCOMPAREITEMSTRUCT #define MK_XBUTTON2 0x0040 -#define WM_MOUSEHOVER 0x02A1 -#define WM_MOUSELEAVE 0x02A3 -#define WM_NCMOUSEHOVER 0x02A0 -#define WM_NCMOUSELEAVE 0x02A2 - - #define TME_HOVER 0x00000001 #define TME_LEAVE 0x00000002 #define TME_NONCLIENT 0x00000010 diff --git a/programs/rpcss/irotp.c b/programs/rpcss/irotp.c index fd406259da8..7832ac7286e 100644 --- a/programs/rpcss/irotp.c +++ b/programs/rpcss/irotp.c @@ -41,6 +41,7 @@ struct rot_entry MonikerComparisonData *moniker_data; /* moniker comparison data that identifies this object */ DWORD cookie; /* cookie identifying this object */ FILETIME last_modified; + LONG refs; }; static struct list RunningObjectTable = LIST_INIT(RunningObjectTable); @@ -56,12 +57,15 @@ static CRITICAL_SECTION csRunningObjectTable = { &critsect_debug, -1, 0, 0, 0, 0 static LONG last_cookie = 1; -static inline void rot_entry_delete(struct rot_entry *rot_entry) +static inline void rot_entry_release(struct rot_entry *rot_entry) { - HeapFree(GetProcessHeap(), 0, rot_entry->object); - HeapFree(GetProcessHeap(), 0, rot_entry->moniker); - HeapFree(GetProcessHeap(), 0, rot_entry->moniker_data); - HeapFree(GetProcessHeap(), 0, rot_entry); + if (!InterlockedDecrement(&rot_entry->refs)) + { + HeapFree(GetProcessHeap(), 0, rot_entry->object); + HeapFree(GetProcessHeap(), 0, rot_entry->moniker); + HeapFree(GetProcessHeap(), 0, rot_entry->moniker_data); + HeapFree(GetProcessHeap(), 0, rot_entry); + } } HRESULT IrotRegister( @@ -71,10 +75,11 @@ HRESULT IrotRegister( const InterfaceData *mk, const FILETIME *time, DWORD grfFlags, - IrotCookie *cookie) + IrotCookie *cookie, + IrotContextHandle *ctxt_handle) { struct rot_entry *rot_entry; - const struct rot_entry *existing_rot_entry; + struct rot_entry *existing_rot_entry; HRESULT hr; if (grfFlags & ~(ROTFLAGS_REGISTRATIONKEEPSALIVE|ROTFLAGS_ALLOWANYCLIENT)) @@ -87,10 +92,11 @@ HRESULT IrotRegister( if (!rot_entry) return E_OUTOFMEMORY; + rot_entry->refs = 1; rot_entry->object = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(InterfaceData, abData[obj->ulCntData])); if (!rot_entry->object) { - rot_entry_delete(rot_entry); + rot_entry_release(rot_entry); return E_OUTOFMEMORY; } rot_entry->object->ulCntData = obj->ulCntData; @@ -101,7 +107,7 @@ HRESULT IrotRegister( rot_entry->moniker = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(InterfaceData, abData[mk->ulCntData])); if (!rot_entry->moniker) { - rot_entry_delete(rot_entry); + rot_entry_release(rot_entry); return E_OUTOFMEMORY; } rot_entry->moniker->ulCntData = mk->ulCntData; @@ -110,7 +116,7 @@ HRESULT IrotRegister( rot_entry->moniker_data = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(MonikerComparisonData, abData[data->ulCntData])); if (!rot_entry->moniker_data) { - rot_entry_delete(rot_entry); + rot_entry_release(rot_entry); return E_OUTOFMEMORY; } rot_entry->moniker_data->ulCntData = data->ulCntData; @@ -120,7 +126,7 @@ HRESULT IrotRegister( hr = S_OK; - LIST_FOR_EACH_ENTRY(existing_rot_entry, &RunningObjectTable, const struct rot_entry, entry) + LIST_FOR_EACH_ENTRY(existing_rot_entry, &RunningObjectTable, struct rot_entry, entry) { if ((existing_rot_entry->moniker_data->ulCntData == data->ulCntData) && !memcmp(&data->abData, &existing_rot_entry->moniker_data->abData, data->ulCntData)) @@ -136,11 +142,14 @@ HRESULT IrotRegister( list_add_tail(&RunningObjectTable, &rot_entry->entry); /* gives a registration identifier to the registered object*/ *cookie = rot_entry->cookie = InterlockedIncrement(&last_cookie); + *ctxt_handle = rot_entry; } else { - rot_entry_delete(rot_entry); + rot_entry_release(rot_entry); *cookie = existing_rot_entry->cookie; + InterlockedIncrement(&existing_rot_entry->refs); + *ctxt_handle = existing_rot_entry; } @@ -152,6 +161,7 @@ HRESULT IrotRegister( HRESULT IrotRevoke( IrotHandle h, IrotCookie cookie, + IrotContextHandle *ctxt_handle, PInterfaceData *obj, PInterfaceData *mk) { @@ -185,7 +195,8 @@ HRESULT IrotRevoke( hr = E_OUTOFMEMORY; } - rot_entry_delete(rot_entry); + rot_entry_release(rot_entry); + *ctxt_handle = NULL; return hr; } } @@ -354,6 +365,15 @@ HRESULT IrotEnumRunning( return hr; } +void __RPC_USER IrotContextHandle_rundown(IrotContextHandle ctxt_handle) +{ + struct rot_entry *rot_entry = ctxt_handle; + EnterCriticalSection(&csRunningObjectTable); + list_remove(&rot_entry->entry); + LeaveCriticalSection(&csRunningObjectTable); + rot_entry_release(rot_entry); +} + void * __RPC_USER MIDL_user_allocate(size_t size) { return HeapAlloc(GetProcessHeap(), 0, size); diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c index ea7e3178286..dee5ad8ec03 100644 --- a/tools/widl/typegen.c +++ b/tools/widl/typegen.c @@ -154,6 +154,44 @@ int is_union(unsigned char type) } } +static int type_has_pointers(const type_t *type) +{ + if (is_user_type(type)) + return FALSE; + else if (is_ptr(type)) + return TRUE; + else if (is_array(type)) + return type_has_pointers(type->ref); + else if (is_struct(type->type)) + { + const var_t *field; + if (type->fields) LIST_FOR_EACH_ENTRY( field, type->fields, const var_t, entry ) + { + if (type_has_pointers(field->type)) + return TRUE; + } + } + else if (is_union(type->type)) + { + var_list_t *fields; + const var_t *field; + if (type->type == RPC_FC_ENCAPSULATED_UNION) + { + const var_t *uv = LIST_ENTRY(list_tail(type->fields), const var_t, entry); + fields = uv->type->fields; + } + else + fields = type->fields; + if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry ) + { + if (field->type && type_has_pointers(field->type)) + return TRUE; + } + } + + return FALSE; +} + static unsigned short user_type_offset(const char *name) { user_type_t *ut; @@ -1534,9 +1572,10 @@ static size_t write_array_tfs(FILE *file, const attr_list_t *attrs, type_t *type if (!pointer_type) pointer_type = RPC_FC_RP; - has_pointer = FALSE; if (write_embedded_types(file, attrs, type->ref, name, FALSE, typestring_offset)) has_pointer = TRUE; + else + has_pointer = type_has_pointers(type->ref); align = 0; size = type_memsize((is_conformant_array(type) ? type->ref : type), &align); @@ -1716,6 +1755,7 @@ static size_t write_struct_tfs(FILE *file, type_t *type, if (type->fields) LIST_FOR_EACH_ENTRY(f, type->fields, var_t, entry) has_pointers |= write_embedded_types(file, f->attrs, f->type, f->name, FALSE, tfsoff); + if (!has_pointers) has_pointers = type_has_pointers(type); array = find_array_or_string_in_struct(type); if (array && !processed(array->type)) @@ -3120,7 +3160,14 @@ void assign_stub_out_args( FILE *file, int indent, const func_t *func ) print_file(file, indent, ""); write_name(file, var); - if (var->type->size_is) + if (is_context_handle(var->type)) + { + fprintf(file, " = NdrContextHandleInitialize(\n"); + print_file(file, indent + 1, "&_StubMsg,\n"); + print_file(file, indent + 1, "(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%d]);\n", + var->type->typestring_offset); + } + else if (var->type->size_is) { unsigned int size, align = 0; type_t *type = var->type; -- 2.11.4.GIT