From 6f10c76e4a6cea0eabbd326946cd4628f42ed0be Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Fri, 11 Jan 2008 13:46:33 +0000 Subject: [PATCH] - Switch to the new widl and new rpcrt4. - Old widl had some more patches applies, and old rpcrt4 had Saveliy Tretiakov's patches applied. They were not explicitly added into this update (some of them might be reworked and got accepted by Wine). svn path=/trunk/; revision=31717 --- reactos/dll/win32/rpcrt4/cproxy.c | 163 +- reactos/dll/win32/rpcrt4/cpsf.c | 21 +- reactos/dll/win32/rpcrt4/cpsf.h | 19 +- reactos/dll/win32/rpcrt4/cstub.c | 467 +- .../win32/{rpcrt4_new => rpcrt4}/epm_towers.h | 0 .../win32/{rpcrt4_new => rpcrt4}/ncastatus.h | 0 .../{rpcrt4_new => rpcrt4}/ndr_clientserver.c | 0 reactos/dll/win32/rpcrt4/ndr_contexth.c | 373 - reactos/dll/win32/rpcrt4/ndr_contexth.h | 60 - .../ndr_contexthandle.c | 0 .../{rpcrt4_new => rpcrt4}/ndr_fullpointer.c | 0 reactos/dll/win32/rpcrt4/ndr_marshall.c | 4469 ++++++++++-- reactos/dll/win32/rpcrt4/ndr_midl.c | 327 - reactos/dll/win32/rpcrt4/ndr_misc.h | 34 +- reactos/dll/win32/rpcrt4/ndr_ole.c | 74 +- reactos/dll/win32/rpcrt4/ndr_stubless.c | 1764 +++-- .../{rpcrt4_new => rpcrt4}/ndr_stubless.h | 0 .../win32/{rpcrt4_new => rpcrt4}/rpc_assoc.c | 0 .../win32/{rpcrt4_new => rpcrt4}/rpc_assoc.h | 0 reactos/dll/win32/rpcrt4/rpc_binding.c | 1234 ++-- reactos/dll/win32/rpcrt4/rpc_binding.h | 147 +- reactos/dll/win32/rpcrt4/rpc_defs.h | 47 +- reactos/dll/win32/rpcrt4/rpc_epmap.c | 147 +- reactos/dll/win32/rpcrt4/rpc_message.c | 906 ++- reactos/dll/win32/rpcrt4/rpc_message.h | 11 +- reactos/dll/win32/rpcrt4/rpc_misc.h | 28 - reactos/dll/win32/rpcrt4/rpc_server.c | 713 +- reactos/dll/win32/rpcrt4/rpc_server.h | 48 +- .../{rpcrt4_new => rpcrt4}/rpc_transport.c | 4 +- reactos/dll/win32/rpcrt4/rpcrt4.rbuild | 17 +- reactos/dll/win32/rpcrt4/rpcrt4.spec | 76 +- reactos/dll/win32/rpcrt4/rpcrt4_main.c | 347 +- .../{rpcrt4_new => rpcrt4}/rpcrt4_ros.diff | 43 +- reactos/dll/win32/rpcrt4/rpcss_np_client.c | 28 +- reactos/dll/win32/rpcrt4/rpcss_np_client.h | 2 +- .../win32/{rpcrt4_new => rpcrt4}/unix_func.c | 0 .../win32/{rpcrt4_new => rpcrt4}/unix_func.h | 0 reactos/dll/win32/rpcrt4_new/cproxy.c | 450 -- reactos/dll/win32/rpcrt4_new/cpsf.c | 307 - reactos/dll/win32/rpcrt4_new/cpsf.h | 56 - reactos/dll/win32/rpcrt4_new/cstub.c | 599 -- reactos/dll/win32/rpcrt4_new/ndr_marshall.c | 6334 ----------------- reactos/dll/win32/rpcrt4_new/ndr_misc.h | 65 - reactos/dll/win32/rpcrt4_new/ndr_ole.c | 393 - reactos/dll/win32/rpcrt4_new/ndr_stubless.c | 1452 ---- reactos/dll/win32/rpcrt4_new/rpc_binding.c | 1586 ----- reactos/dll/win32/rpcrt4_new/rpc_binding.h | 197 - reactos/dll/win32/rpcrt4_new/rpc_defs.h | 212 - reactos/dll/win32/rpcrt4_new/rpc_epmap.c | 384 - reactos/dll/win32/rpcrt4_new/rpc_message.c | 1159 --- reactos/dll/win32/rpcrt4_new/rpc_message.h | 40 - reactos/dll/win32/rpcrt4_new/rpc_server.c | 1147 --- reactos/dll/win32/rpcrt4_new/rpc_server.h | 81 - reactos/dll/win32/rpcrt4_new/rpcrt4.rbuild | 43 - reactos/dll/win32/rpcrt4_new/rpcrt4.rc | 7 - reactos/dll/win32/rpcrt4_new/rpcrt4.spec | 565 -- reactos/dll/win32/rpcrt4_new/rpcrt4_main.c | 1025 --- .../dll/win32/rpcrt4_new/rpcss_np_client.c | 152 - .../dll/win32/rpcrt4_new/rpcss_np_client.h | 26 - reactos/dll/win32/shdocvw/shdocvw.h | 4 +- reactos/tools/widl/ChangeLog | 298 - reactos/tools/widl/Makefile.in | 53 - reactos/tools/widl/client.c | 231 +- reactos/tools/widl/hash.c | 22 +- reactos/tools/widl/header.c | 710 +- reactos/tools/widl/header.h | 67 +- reactos/tools/widl/lex.yy.c | 5082 ------------- reactos/tools/widl/parser.h | 16 +- reactos/tools/widl/parser.l | 270 +- reactos/tools/widl/parser.tab.c | 5433 ++++++++------ reactos/tools/widl/parser.tab.h | 541 +- reactos/tools/widl/parser.y | 1222 +++- .../tools/{widl_20080105 => widl}/parser.yy.c | 0 reactos/tools/widl/proxy.c | 903 +-- reactos/tools/widl/server.c | 352 +- reactos/tools/widl/typegen.c | 3440 ++++++--- reactos/tools/widl/typegen.h | 29 +- reactos/tools/widl/typelib.c | 201 +- reactos/tools/widl/typelib.h | 10 +- reactos/tools/widl/typelib_struct.h | 8 +- reactos/tools/widl/utils.c | 71 +- reactos/tools/widl/utils.h | 16 +- reactos/tools/widl/widl.c | 355 +- reactos/tools/widl/widl.h | 18 +- reactos/tools/widl/widl.mak | 18 +- reactos/tools/widl/widl.man.in | 88 - .../{widl_20080105 => widl}/widl_ros.diff | 0 reactos/tools/widl/widltypes.h | 158 +- reactos/tools/widl/write_msft.c | 602 +- reactos/tools/widl_20080105/client.c | 447 -- reactos/tools/widl_20080105/hash.c | 622 -- reactos/tools/widl_20080105/hash.h | 33 - reactos/tools/widl_20080105/header.c | 1043 --- reactos/tools/widl_20080105/header.h | 93 - reactos/tools/widl_20080105/parser.h | 47 - reactos/tools/widl_20080105/parser.l | 443 -- reactos/tools/widl_20080105/parser.tab.c | 5053 ------------- reactos/tools/widl_20080105/parser.tab.h | 339 - reactos/tools/widl_20080105/parser.y | 2091 ------ reactos/tools/widl_20080105/port/mkstemps.c | 138 - reactos/tools/widl_20080105/proxy.c | 709 -- reactos/tools/widl_20080105/server.c | 453 -- reactos/tools/widl_20080105/typegen.c | 3309 --------- reactos/tools/widl_20080105/typegen.h | 62 - reactos/tools/widl_20080105/typelib.c | 403 -- reactos/tools/widl_20080105/typelib.h | 87 - reactos/tools/widl_20080105/typelib_struct.h | 605 -- reactos/tools/widl_20080105/utils.c | 218 - reactos/tools/widl_20080105/utils.h | 55 - reactos/tools/widl_20080105/widl.c | 658 -- reactos/tools/widl_20080105/widl.h | 76 - reactos/tools/widl_20080105/widl.mak | 131 - reactos/tools/widl_20080105/widltypes.h | 330 - reactos/tools/widl_20080105/write_msft.c | 2533 ------- .../0.9.44.1 - Handle LPSTR in typelibs.diff | 53 - ...dle the size_is attribute on pointers.diff | 11 - .../0.9.44.3 - Constify some data.diff | 44 - ...x top-level and callback conformances.diff | 238 - ...lement NDR for struct field alignment.diff | 75 - .../0.9.44.6 - Allow size_is on strings.diff | 87 - .../widl_new/0.9.44.7 - ReactOS hack.diff | 10 - reactos/tools/widl_new/ChangeLog | 307 - reactos/tools/widl_new/Makefile.in | 46 - reactos/tools/widl_new/client.c | 442 -- reactos/tools/widl_new/hash.c | 615 -- reactos/tools/widl_new/hash.h | 33 - reactos/tools/widl_new/header.c | 944 --- reactos/tools/widl_new/header.h | 75 - reactos/tools/widl_new/parser.h | 41 - reactos/tools/widl_new/parser.l | 443 -- reactos/tools/widl_new/parser.tab.c | 5101 ------------- reactos/tools/widl_new/parser.tab.h | 346 - reactos/tools/widl_new/parser.y | 1978 ----- reactos/tools/widl_new/parser.yy.c | 2160 ------ reactos/tools/widl_new/port/mkstemps.c | 138 - reactos/tools/widl_new/proxy.c | 664 -- reactos/tools/widl_new/server.c | 448 -- reactos/tools/widl_new/typegen.c | 2973 -------- reactos/tools/widl_new/typegen.h | 57 - reactos/tools/widl_new/typelib.c | 399 -- reactos/tools/widl_new/typelib.h | 87 - reactos/tools/widl_new/typelib_struct.h | 605 -- reactos/tools/widl_new/utils.c | 191 - reactos/tools/widl_new/utils.h | 45 - reactos/tools/widl_new/widl.c | 460 -- reactos/tools/widl_new/widl.h | 71 - reactos/tools/widl_new/widl.mak | 131 - reactos/tools/widl_new/widl.man.in | 95 - reactos/tools/widl_new/widltypes.h | 322 - reactos/tools/widl_new/write_msft.c | 2531 ------- 150 files changed, 16463 insertions(+), 73848 deletions(-) rename reactos/dll/win32/{rpcrt4_new => rpcrt4}/epm_towers.h (100%) rename reactos/dll/win32/{rpcrt4_new => rpcrt4}/ncastatus.h (100%) rename reactos/dll/win32/{rpcrt4_new => rpcrt4}/ndr_clientserver.c (100%) delete mode 100644 reactos/dll/win32/rpcrt4/ndr_contexth.c delete mode 100644 reactos/dll/win32/rpcrt4/ndr_contexth.h rename reactos/dll/win32/{rpcrt4_new => rpcrt4}/ndr_contexthandle.c (100%) rename reactos/dll/win32/{rpcrt4_new => rpcrt4}/ndr_fullpointer.c (100%) delete mode 100644 reactos/dll/win32/rpcrt4/ndr_midl.c rename reactos/dll/win32/{rpcrt4_new => rpcrt4}/ndr_stubless.h (100%) rename reactos/dll/win32/{rpcrt4_new => rpcrt4}/rpc_assoc.c (100%) rename reactos/dll/win32/{rpcrt4_new => rpcrt4}/rpc_assoc.h (100%) delete mode 100644 reactos/dll/win32/rpcrt4/rpc_misc.h rename reactos/dll/win32/{rpcrt4_new => rpcrt4}/rpc_transport.c (99%) rename reactos/dll/win32/{rpcrt4_new => rpcrt4}/rpcrt4_ros.diff (89%) rename reactos/dll/win32/{rpcrt4_new => rpcrt4}/unix_func.c (100%) rename reactos/dll/win32/{rpcrt4_new => rpcrt4}/unix_func.h (100%) delete mode 100644 reactos/dll/win32/rpcrt4_new/cproxy.c delete mode 100644 reactos/dll/win32/rpcrt4_new/cpsf.c delete mode 100644 reactos/dll/win32/rpcrt4_new/cpsf.h delete mode 100644 reactos/dll/win32/rpcrt4_new/cstub.c delete mode 100644 reactos/dll/win32/rpcrt4_new/ndr_marshall.c delete mode 100644 reactos/dll/win32/rpcrt4_new/ndr_misc.h delete mode 100644 reactos/dll/win32/rpcrt4_new/ndr_ole.c delete mode 100644 reactos/dll/win32/rpcrt4_new/ndr_stubless.c delete mode 100644 reactos/dll/win32/rpcrt4_new/rpc_binding.c delete mode 100644 reactos/dll/win32/rpcrt4_new/rpc_binding.h delete mode 100644 reactos/dll/win32/rpcrt4_new/rpc_defs.h delete mode 100644 reactos/dll/win32/rpcrt4_new/rpc_epmap.c delete mode 100644 reactos/dll/win32/rpcrt4_new/rpc_message.c delete mode 100644 reactos/dll/win32/rpcrt4_new/rpc_message.h delete mode 100644 reactos/dll/win32/rpcrt4_new/rpc_server.c delete mode 100644 reactos/dll/win32/rpcrt4_new/rpc_server.h delete mode 100644 reactos/dll/win32/rpcrt4_new/rpcrt4.rbuild delete mode 100644 reactos/dll/win32/rpcrt4_new/rpcrt4.rc delete mode 100644 reactos/dll/win32/rpcrt4_new/rpcrt4.spec delete mode 100644 reactos/dll/win32/rpcrt4_new/rpcrt4_main.c delete mode 100644 reactos/dll/win32/rpcrt4_new/rpcss_np_client.c delete mode 100644 reactos/dll/win32/rpcrt4_new/rpcss_np_client.h delete mode 100644 reactos/tools/widl/ChangeLog delete mode 100644 reactos/tools/widl/Makefile.in delete mode 100644 reactos/tools/widl/lex.yy.c rename reactos/tools/{widl_20080105 => widl}/parser.yy.c (100%) delete mode 100644 reactos/tools/widl/widl.man.in rename reactos/tools/{widl_20080105 => widl}/widl_ros.diff (100%) delete mode 100644 reactos/tools/widl_20080105/client.c delete mode 100644 reactos/tools/widl_20080105/hash.c delete mode 100644 reactos/tools/widl_20080105/hash.h delete mode 100644 reactos/tools/widl_20080105/header.c delete mode 100644 reactos/tools/widl_20080105/header.h delete mode 100644 reactos/tools/widl_20080105/parser.h delete mode 100644 reactos/tools/widl_20080105/parser.l delete mode 100644 reactos/tools/widl_20080105/parser.tab.c delete mode 100644 reactos/tools/widl_20080105/parser.tab.h delete mode 100644 reactos/tools/widl_20080105/parser.y delete mode 100644 reactos/tools/widl_20080105/port/mkstemps.c delete mode 100644 reactos/tools/widl_20080105/proxy.c delete mode 100644 reactos/tools/widl_20080105/server.c delete mode 100644 reactos/tools/widl_20080105/typegen.c delete mode 100644 reactos/tools/widl_20080105/typegen.h delete mode 100644 reactos/tools/widl_20080105/typelib.c delete mode 100644 reactos/tools/widl_20080105/typelib.h delete mode 100644 reactos/tools/widl_20080105/typelib_struct.h delete mode 100644 reactos/tools/widl_20080105/utils.c delete mode 100644 reactos/tools/widl_20080105/utils.h delete mode 100644 reactos/tools/widl_20080105/widl.c delete mode 100644 reactos/tools/widl_20080105/widl.h delete mode 100644 reactos/tools/widl_20080105/widl.mak delete mode 100644 reactos/tools/widl_20080105/widltypes.h delete mode 100644 reactos/tools/widl_20080105/write_msft.c delete mode 100644 reactos/tools/widl_new/0.9.44.1 - Handle LPSTR in typelibs.diff delete mode 100644 reactos/tools/widl_new/0.9.44.2 - Handle the size_is attribute on pointers.diff delete mode 100644 reactos/tools/widl_new/0.9.44.3 - Constify some data.diff delete mode 100644 reactos/tools/widl_new/0.9.44.4 - Fix top-level and callback conformances.diff delete mode 100644 reactos/tools/widl_new/0.9.44.5 - Implement NDR for struct field alignment.diff delete mode 100644 reactos/tools/widl_new/0.9.44.6 - Allow size_is on strings.diff delete mode 100644 reactos/tools/widl_new/0.9.44.7 - ReactOS hack.diff delete mode 100644 reactos/tools/widl_new/ChangeLog delete mode 100644 reactos/tools/widl_new/Makefile.in delete mode 100644 reactos/tools/widl_new/client.c delete mode 100644 reactos/tools/widl_new/hash.c delete mode 100644 reactos/tools/widl_new/hash.h delete mode 100644 reactos/tools/widl_new/header.c delete mode 100644 reactos/tools/widl_new/header.h delete mode 100644 reactos/tools/widl_new/parser.h delete mode 100644 reactos/tools/widl_new/parser.l delete mode 100644 reactos/tools/widl_new/parser.tab.c delete mode 100644 reactos/tools/widl_new/parser.tab.h delete mode 100644 reactos/tools/widl_new/parser.y delete mode 100644 reactos/tools/widl_new/parser.yy.c delete mode 100644 reactos/tools/widl_new/port/mkstemps.c delete mode 100644 reactos/tools/widl_new/proxy.c delete mode 100644 reactos/tools/widl_new/server.c delete mode 100644 reactos/tools/widl_new/typegen.c delete mode 100644 reactos/tools/widl_new/typegen.h delete mode 100644 reactos/tools/widl_new/typelib.c delete mode 100644 reactos/tools/widl_new/typelib.h delete mode 100644 reactos/tools/widl_new/typelib_struct.h delete mode 100644 reactos/tools/widl_new/utils.c delete mode 100644 reactos/tools/widl_new/utils.h delete mode 100644 reactos/tools/widl_new/widl.c delete mode 100644 reactos/tools/widl_new/widl.h delete mode 100644 reactos/tools/widl_new/widl.mak delete mode 100644 reactos/tools/widl_new/widl.man.in delete mode 100644 reactos/tools/widl_new/widltypes.h delete mode 100644 reactos/tools/widl_new/write_msft.c diff --git a/reactos/dll/win32/rpcrt4/cproxy.c b/reactos/dll/win32/rpcrt4/cproxy.c index 3597cd49db5..6580bcf143c 100644 --- a/reactos/dll/win32/rpcrt4/cproxy.c +++ b/reactos/dll/win32/rpcrt4/cproxy.c @@ -15,10 +15,9 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * * TODO: Handle non-i386 architectures - * Get rid of #if 0'ed code. */ #include @@ -45,7 +44,7 @@ struct StublessThunk; typedef struct { const IRpcProxyBufferVtbl *lpVtbl; LPVOID *PVtbl; - DWORD RefCount; + LONG RefCount; const MIDL_STUBLESS_PROXY_INFO *stubless; const IID* piid; LPUNKNOWN pUnkOuter; @@ -102,7 +101,7 @@ static HRESULT WINAPI ObjectStubless(DWORD index) PFORMAT_STRING fs = This->stubless->ProcFormatString + This->stubless->FormatStringOffset[index]; unsigned bytes = *(const WORD*)(fs+8) - STACK_ADJUST; - TRACE("(%p)->(%ld)([%d bytes]) ret=%08lx\n", iface, index, bytes, *(DWORD*)(args+bytes)); + TRACE("(%p)->(%d)([%d bytes]) ret=%08x\n", iface, index, bytes, *(DWORD*)(args+bytes)); return NdrClientCall2(This->stubless->pStubDesc, fs, args); } @@ -174,7 +173,7 @@ HRESULT WINAPI StdProxy_Construct(REFIID riid, } } } - else + else This->PVtbl = vtbl->Vtbl; This->lpVtbl = &StdProxy_Vtbl; @@ -223,13 +222,13 @@ static HRESULT WINAPI StdProxy_QueryInterface(LPRPCPROXYBUFFER iface, if (IsEqualGUID(&IID_IUnknown,riid) || IsEqualGUID(This->piid,riid)) { *obj = &This->PVtbl; - This->RefCount++; + InterlockedIncrement(&This->RefCount); return S_OK; } if (IsEqualGUID(&IID_IRpcProxyBuffer,riid)) { *obj = &This->lpVtbl; - This->RefCount++; + InterlockedIncrement(&This->RefCount); return S_OK; } @@ -241,19 +240,19 @@ static ULONG WINAPI StdProxy_AddRef(LPRPCPROXYBUFFER iface) ICOM_THIS_MULTI(StdProxyImpl,lpVtbl,iface); TRACE("(%p)->AddRef()\n",This); - return ++(This->RefCount); + return InterlockedIncrement(&This->RefCount); } static ULONG WINAPI StdProxy_Release(LPRPCPROXYBUFFER iface) { + ULONG refs; ICOM_THIS_MULTI(StdProxyImpl,lpVtbl,iface); TRACE("(%p)->Release()\n",This); - if (!--(This->RefCount)) { + refs = InterlockedDecrement(&This->RefCount); + if (!refs) StdProxy_Destruct((LPRPCPROXYBUFFER)&This->lpVtbl); - return 0; - } - return This->RefCount; + return refs; } static HRESULT WINAPI StdProxy_Connect(LPRPCPROXYBUFFER iface, @@ -285,24 +284,22 @@ static const IRpcProxyBufferVtbl StdProxy_Vtbl = StdProxy_Disconnect }; -HRESULT WINAPI StdProxy_GetChannel(LPVOID iface, - LPRPCCHANNELBUFFER *ppChannel) +static void StdProxy_GetChannel(LPVOID iface, + LPRPCCHANNELBUFFER *ppChannel) { ICOM_THIS_MULTI(StdProxyImpl,PVtbl,iface); TRACE("(%p)->GetChannel(%p) %s\n",This,ppChannel,This->name); *ppChannel = This->pChannel; - return S_OK; } -HRESULT WINAPI StdProxy_GetIID(LPVOID iface, - const IID **ppiid) +static void StdProxy_GetIID(LPVOID iface, + const IID **ppiid) { ICOM_THIS_MULTI(StdProxyImpl,PVtbl,iface); TRACE("(%p)->GetIID(%p) %s\n",This,ppiid,This->name); *ppiid = This->piid; - return S_OK; } HRESULT WINAPI IUnknown_QueryInterface_Proxy(LPUNKNOWN iface, @@ -318,32 +315,136 @@ ULONG WINAPI IUnknown_AddRef_Proxy(LPUNKNOWN iface) { ICOM_THIS_MULTI(StdProxyImpl,PVtbl,iface); TRACE("(%p)->AddRef() %s\n",This,This->name); -#if 0 /* interface refcounting */ - return ++(This->RefCount); -#else /* object refcounting */ return IUnknown_AddRef(This->pUnkOuter); -#endif } ULONG WINAPI IUnknown_Release_Proxy(LPUNKNOWN iface) { ICOM_THIS_MULTI(StdProxyImpl,PVtbl,iface); TRACE("(%p)->Release() %s\n",This,This->name); -#if 0 /* interface refcounting */ - if (!--(This->RefCount)) { - StdProxy_Destruct((LPRPCPROXYBUFFER)&This->lpVtbl); - return 0; - } - return This->RefCount; -#else /* object refcounting */ return IUnknown_Release(This->pUnkOuter); -#endif +} + +/*********************************************************************** + * NdrProxyInitialize [RPCRT4.@] + */ +void WINAPI NdrProxyInitialize(void *This, + PRPC_MESSAGE pRpcMsg, + PMIDL_STUB_MESSAGE pStubMsg, + PMIDL_STUB_DESC pStubDescriptor, + unsigned int ProcNum) +{ + TRACE("(%p,%p,%p,%p,%d)\n", This, pRpcMsg, pStubMsg, pStubDescriptor, ProcNum); + NdrClientInitializeNew(pRpcMsg, pStubMsg, pStubDescriptor, ProcNum); + StdProxy_GetChannel(This, &pStubMsg->pRpcChannelBuffer); + IRpcChannelBuffer_GetDestCtx(pStubMsg->pRpcChannelBuffer, + &pStubMsg->dwDestContext, + &pStubMsg->pvDestContext); + TRACE("channel=%p\n", pStubMsg->pRpcChannelBuffer); +} + +/*********************************************************************** + * NdrProxyGetBuffer [RPCRT4.@] + */ +void WINAPI NdrProxyGetBuffer(void *This, + PMIDL_STUB_MESSAGE pStubMsg) +{ + HRESULT hr; + const IID *riid = NULL; + + TRACE("(%p,%p)\n", This, pStubMsg); + pStubMsg->RpcMsg->BufferLength = pStubMsg->BufferLength; + pStubMsg->dwStubPhase = PROXY_GETBUFFER; + StdProxy_GetIID(This, &riid); + hr = IRpcChannelBuffer_GetBuffer(pStubMsg->pRpcChannelBuffer, + (RPCOLEMESSAGE*)pStubMsg->RpcMsg, + riid); + if (FAILED(hr)) + { + RpcRaiseException(hr); + return; + } + pStubMsg->BufferStart = pStubMsg->RpcMsg->Buffer; + pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->BufferLength; + pStubMsg->Buffer = pStubMsg->BufferStart; + pStubMsg->dwStubPhase = PROXY_MARSHAL; +} + +/*********************************************************************** + * NdrProxySendReceive [RPCRT4.@] + */ +void WINAPI NdrProxySendReceive(void *This, + PMIDL_STUB_MESSAGE pStubMsg) +{ + ULONG Status = 0; + HRESULT hr; + + TRACE("(%p,%p)\n", This, pStubMsg); + + if (!pStubMsg->pRpcChannelBuffer) + { + WARN("Trying to use disconnected proxy %p\n", This); + RpcRaiseException(RPC_E_DISCONNECTED); + } + + pStubMsg->dwStubPhase = PROXY_SENDRECEIVE; + hr = IRpcChannelBuffer_SendReceive(pStubMsg->pRpcChannelBuffer, + (RPCOLEMESSAGE*)pStubMsg->RpcMsg, + &Status); + pStubMsg->dwStubPhase = PROXY_UNMARSHAL; + pStubMsg->BufferLength = pStubMsg->RpcMsg->BufferLength; + pStubMsg->BufferStart = pStubMsg->RpcMsg->Buffer; + pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->BufferLength; + pStubMsg->Buffer = pStubMsg->BufferStart; + + /* raise exception if call failed */ + if (hr == RPC_S_CALL_FAILED) RpcRaiseException(*(DWORD*)pStubMsg->Buffer); + else if (FAILED(hr)) RpcRaiseException(hr); +} + +/*********************************************************************** + * NdrProxyFreeBuffer [RPCRT4.@] + */ +void WINAPI NdrProxyFreeBuffer(void *This, + PMIDL_STUB_MESSAGE pStubMsg) +{ + HRESULT hr; + + TRACE("(%p,%p)\n", This, pStubMsg); + hr = IRpcChannelBuffer_FreeBuffer(pStubMsg->pRpcChannelBuffer, + (RPCOLEMESSAGE*)pStubMsg->RpcMsg); +} + +/*********************************************************************** + * NdrProxyErrorHandler [RPCRT4.@] + */ +HRESULT WINAPI NdrProxyErrorHandler(DWORD dwExceptionCode) +{ + WARN("(0x%08x): a proxy call failed\n", dwExceptionCode); + + if (FAILED(dwExceptionCode)) + return dwExceptionCode; + else + return HRESULT_FROM_WIN32(dwExceptionCode); } HRESULT WINAPI CreateProxyFromTypeInfo( LPTYPEINFO pTypeInfo, LPUNKNOWN pUnkOuter, REFIID riid, LPRPCPROXYBUFFER *ppProxy, LPVOID *ppv ) { + typedef INT (WINAPI *MessageBoxA)(HWND,LPCSTR,LPCSTR,UINT); + HMODULE hUser32 = LoadLibraryA("user32"); + MessageBoxA pMessageBoxA = (void *)GetProcAddress(hUser32, "MessageBoxA"); + FIXME("%p %p %s %p %p\n", pTypeInfo, pUnkOuter, debugstr_guid(riid), ppProxy, ppv); + if (pMessageBoxA) + { + pMessageBoxA(NULL, + "The native implementation of OLEAUT32.DLL cannot be used " + "with Wine's RPCRT4.DLL. Remove OLEAUT32.DLL and try again.\n", + "Wine: Unimplemented CreateProxyFromTypeInfo", + 0x10); + ExitProcess(1); + } return E_NOTIMPL; } diff --git a/reactos/dll/win32/rpcrt4/cpsf.c b/reactos/dll/win32/rpcrt4/cpsf.c index 44bb5a99255..dcf37219195 100644 --- a/reactos/dll/win32/rpcrt4/cpsf.c +++ b/reactos/dll/win32/rpcrt4/cpsf.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include @@ -110,6 +110,12 @@ static HRESULT WINAPI CStdPSFactory_CreateStub(LPPSFACTORYBUFFER iface, pUnkServer,ppStub); if (!FindProxyInfo(This->pProxyFileList,riid,&ProxyInfo,&Index)) return E_NOINTERFACE; + + if(ProxyInfo->pDelegatedIIDs && ProxyInfo->pDelegatedIIDs[Index]) + return CStdStubBuffer_Delegating_Construct(riid, pUnkServer, ProxyInfo->pNamesArray[Index], + ProxyInfo->pStubVtblList[Index], ProxyInfo->pDelegatedIIDs[Index], + iface, ppStub); + return CStdStubBuffer_Construct(riid, pUnkServer, ProxyInfo->pNamesArray[Index], ProxyInfo->pStubVtblList[Index], iface, ppStub); } @@ -138,6 +144,7 @@ HRESULT WINAPI NdrDllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv, *ppv = NULL; if (!pPSFactoryBuffer->lpVtbl) { const ProxyFileInfo **pProxyFileList2; + int max_delegating_vtbl_size = 0; pPSFactoryBuffer->lpVtbl = &CStdPSFactory_Vtbl; pPSFactoryBuffer->RefCount = 0; pPSFactoryBuffer->pProxyFileList = pProxyFileList; @@ -150,11 +157,19 @@ HRESULT WINAPI NdrDllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv, void **pRpcStubVtbl = (void **)&(*pProxyFileList2)->pStubVtblList[i]->Vtbl; int j; + if ((*pProxyFileList2)->pDelegatedIIDs && (*pProxyFileList2)->pDelegatedIIDs[i]) { + pSrcRpcStubVtbl = (void * const *)&CStdStubBuffer_Delegating_Vtbl; + if ((*pProxyFileList2)->pStubVtblList[i]->header.DispatchTableCount > max_delegating_vtbl_size) + max_delegating_vtbl_size = (*pProxyFileList2)->pStubVtblList[i]->header.DispatchTableCount; + } + for (j = 0; j < sizeof(IRpcStubBufferVtbl)/sizeof(void *); j++) if (!pRpcStubVtbl[j]) pRpcStubVtbl[j] = pSrcRpcStubVtbl[j]; } } + if(max_delegating_vtbl_size > 0) + create_delegating_vtbl(max_delegating_vtbl_size); } if (IsEqualGUID(rclsid, pclsid)) return IPSFactoryBuffer_QueryInterface((LPPSFACTORYBUFFER)pPSFactoryBuffer, iid, ppv); @@ -210,7 +225,7 @@ HRESULT WINAPI NdrDllRegisterProxy(HMODULE hDll, if (RegCreateKeyExA(HKEY_CLASSES_ROOT, keyname, 0, NULL, 0, KEY_WRITE, NULL, &key, NULL) == ERROR_SUCCESS) { if (name) - RegSetValueExA(key, NULL, 0, REG_SZ, (LPBYTE)name, strlen(name)); + RegSetValueExA(key, NULL, 0, REG_SZ, (const BYTE *)name, strlen(name)); if (RegCreateKeyExA(key, "ProxyStubClsid32", 0, NULL, 0, KEY_WRITE, NULL, &subkey, NULL) == ERROR_SUCCESS) { snprintf(module, sizeof(module), "{%s}", clsid); @@ -230,9 +245,11 @@ HRESULT WINAPI NdrDllRegisterProxy(HMODULE hDll, TRACE("registering CLSID %s => %s\n", clsid, module); if (RegCreateKeyExA(HKEY_CLASSES_ROOT, keyname, 0, NULL, 0, KEY_WRITE, NULL, &key, NULL) == ERROR_SUCCESS) { + RegSetValueExA(subkey, NULL, 0, REG_SZ, (const BYTE *)"PSFactoryBuffer", strlen("PSFactoryBuffer")); if (RegCreateKeyExA(key, "InProcServer32", 0, NULL, 0, KEY_WRITE, NULL, &subkey, NULL) == ERROR_SUCCESS) { RegSetValueExA(subkey, NULL, 0, REG_SZ, (LPBYTE)module, strlen(module)); + RegSetValueExA(subkey, "ThreadingModel", 0, REG_SZ, (const BYTE *)"Both", strlen("Both")); RegCloseKey(subkey); } RegCloseKey(key); diff --git a/reactos/dll/win32/rpcrt4/cpsf.h b/reactos/dll/win32/rpcrt4/cpsf.h index cf1572b9ac6..5ce8fe6575e 100644 --- a/reactos/dll/win32/rpcrt4/cpsf.h +++ b/reactos/dll/win32/rpcrt4/cpsf.h @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __WINE_CPSF_H @@ -28,10 +28,6 @@ HRESULT WINAPI StdProxy_Construct(REFIID riid, LPPSFACTORYBUFFER pPSFactory, LPRPCPROXYBUFFER *ppProxy, LPVOID *ppvObj); -HRESULT WINAPI StdProxy_GetChannel(LPVOID iface, - LPRPCCHANNELBUFFER *ppChannel); -HRESULT WINAPI StdProxy_GetIID(LPVOID iface, - const IID **piid); HRESULT WINAPI CStdStubBuffer_Construct(REFIID riid, LPUNKNOWN pUnkServer, @@ -40,8 +36,21 @@ HRESULT WINAPI CStdStubBuffer_Construct(REFIID riid, LPPSFACTORYBUFFER pPSFactory, LPRPCSTUBBUFFER *ppStub); +HRESULT WINAPI CStdStubBuffer_Delegating_Construct(REFIID riid, + LPUNKNOWN pUnkServer, + PCInterfaceName name, + CInterfaceStubVtbl *vtbl, + REFIID delegating_iid, + LPPSFACTORYBUFFER pPSFactory, + LPRPCSTUBBUFFER *ppStub); + const MIDL_SERVER_INFO *CStdStubBuffer_GetServerInfo(IRpcStubBuffer *iface); const IRpcStubBufferVtbl CStdStubBuffer_Vtbl; +const IRpcStubBufferVtbl CStdStubBuffer_Delegating_Vtbl; + +void create_delegating_vtbl(DWORD num_methods); + +HRESULT create_stub(REFIID iid, IUnknown *pUnk, IRpcStubBuffer **ppstub); #endif /* __WINE_CPSF_H */ diff --git a/reactos/dll/win32/rpcrt4/cstub.c b/reactos/dll/win32/rpcrt4/cstub.c index 41c09437c3f..cd07c297390 100644 --- a/reactos/dll/win32/rpcrt4/cstub.c +++ b/reactos/dll/win32/rpcrt4/cstub.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include @@ -25,18 +25,38 @@ #include "windef.h" #include "winbase.h" #include "winerror.h" +#include "excpt.h" #include "objbase.h" - #include "rpcproxy.h" #include "wine/debug.h" +#include "wine/exception.h" #include "cpsf.h" WINE_DEFAULT_DEBUG_CHANNEL(ole); -#define STUB_HEADER(This) (((CInterfaceStubHeader*)((This)->lpVtbl))[-1]) +#define STUB_HEADER(This) (((const CInterfaceStubHeader*)((This)->lpVtbl))[-1]) + +static WINE_EXCEPTION_FILTER(stub_filter) +{ + if (GetExceptionInformation()->ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE) + return EXCEPTION_CONTINUE_SEARCH; + return EXCEPTION_EXECUTE_HANDLER; +} + +typedef struct +{ + IUnknownVtbl *base_obj; + IRpcStubBuffer *base_stub; + CStdStubBuffer stub_buffer; +} cstdstubbuffer_delegating_t; + +static inline cstdstubbuffer_delegating_t *impl_from_delegating( IRpcStubBuffer *iface ) +{ + return (cstdstubbuffer_delegating_t*)((char *)iface - FIELD_OFFSET(cstdstubbuffer_delegating_t, stub_buffer)); +} HRESULT WINAPI CStdStubBuffer_Construct(REFIID riid, LPUNKNOWN pUnkServer, @@ -46,7 +66,8 @@ HRESULT WINAPI CStdStubBuffer_Construct(REFIID riid, LPRPCSTUBBUFFER *ppStub) { CStdStubBuffer *This; - + IUnknown *pvServer; + HRESULT r; TRACE("(%p,%p,%p,%p) %s\n", pUnkServer, vtbl, pPSFactory, ppStub, name); TRACE("iid=%s\n", debugstr_guid(vtbl->header.piid)); TRACE("vtbl=%p\n", &vtbl->Vtbl); @@ -56,20 +77,244 @@ HRESULT WINAPI CStdStubBuffer_Construct(REFIID riid, return RPC_E_UNEXPECTED; } + r = IUnknown_QueryInterface(pUnkServer, riid, (void**)&pvServer); + if(FAILED(r)) + return r; + This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(CStdStubBuffer)); - if (!This) return E_OUTOFMEMORY; + if (!This) { + IUnknown_Release(pvServer); + return E_OUTOFMEMORY; + } This->lpVtbl = &vtbl->Vtbl; This->RefCount = 1; - This->pvServerObject = pUnkServer; + This->pvServerObject = pvServer; This->pPSFactory = pPSFactory; *ppStub = (LPRPCSTUBBUFFER)This; - IUnknown_AddRef(This->pvServerObject); IPSFactoryBuffer_AddRef(pPSFactory); return S_OK; } +static CRITICAL_SECTION delegating_vtbl_section; +static CRITICAL_SECTION_DEBUG critsect_debug = +{ + 0, 0, &delegating_vtbl_section, + { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList }, + 0, 0, { (DWORD_PTR)(__FILE__ ": delegating_vtbl_section") } +}; +static CRITICAL_SECTION delegating_vtbl_section = { &critsect_debug, -1, 0, 0, 0, 0 }; + +typedef struct +{ + DWORD ref; + DWORD size; + void **methods; + IUnknownVtbl vtbl; + /* remaining entries in vtbl */ +} ref_counted_vtbl; + +static struct +{ + ref_counted_vtbl *table; +} current_vtbl; + + +static HRESULT WINAPI delegating_QueryInterface(IUnknown *pUnk, REFIID iid, void **ppv) +{ + *ppv = (void *)pUnk; + return S_OK; +} + +static ULONG WINAPI delegating_AddRef(IUnknown *pUnk) +{ + return 1; +} + +static ULONG WINAPI delegating_Release(IUnknown *pUnk) +{ + return 1; +} + +#if defined(__i386__) + +/* The idea here is to replace the first param on the stack + ie. This (which will point to cstdstubbuffer_delegating_t) + with This->stub_buffer.pvServerObject and then jump to the + relevant offset in This->stub_buffer.pvServerObject's vtbl. +*/ +#include "pshpack1.h" +typedef struct { + DWORD mov1; /* mov 0x4(%esp), %eax 8b 44 24 04 */ + WORD mov2; /* mov 0x10(%eax), %eax 8b 40 */ + BYTE sixteen; /* 10 */ + DWORD mov3; /* mov %eax, 0x4(%esp) 89 44 24 04 */ + WORD mov4; /* mov (%eax), %eax 8b 00 */ + WORD mov5; /* mov offset(%eax), %eax 8b 80 */ + DWORD offset; /* xx xx xx xx */ + WORD jmp; /* jmp *%eax ff e0 */ + BYTE pad[3]; /* lea 0x0(%esi), %esi 8d 76 00 */ +} vtbl_method_t; +#include "poppack.h" + +static void fill_table(IUnknownVtbl *vtbl, void **methods, DWORD num) +{ + vtbl_method_t *method; + void **entry; + DWORD i; + + vtbl->QueryInterface = delegating_QueryInterface; + vtbl->AddRef = delegating_AddRef; + vtbl->Release = delegating_Release; + + method = (vtbl_method_t*)methods; + entry = (void**)(vtbl + 1); + + for(i = 3; i < num; i++) + { + *entry = method; + method->mov1 = 0x0424448b; + method->mov2 = 0x408b; + method->sixteen = 0x10; + method->mov3 = 0x04244489; + method->mov4 = 0x008b; + method->mov5 = 0x808b; + method->offset = i << 2; + method->jmp = 0xe0ff; + method->pad[0] = 0x8d; + method->pad[1] = 0x76; + method->pad[2] = 0x00; + + method++; + entry++; + } +} + +#else /* __i386__ */ + +typedef struct {int dummy;} vtbl_method_t; +static void fill_table(IUnknownVtbl *vtbl, DWORD num) +{ + ERR("delegated stubs are not supported on this architecture\n"); +} + +#endif /* __i386__ */ + +void create_delegating_vtbl(DWORD num_methods) +{ + TRACE("%d\n", num_methods); + if(num_methods <= 3) + { + ERR("should have more than %d methods\n", num_methods); + return; + } + + EnterCriticalSection(&delegating_vtbl_section); + if(!current_vtbl.table || num_methods > current_vtbl.table->size) + { + DWORD size; + DWORD old_protect; + if(current_vtbl.table && current_vtbl.table->ref == 0) + { + TRACE("freeing old table\n"); + VirtualFree(current_vtbl.table->methods, + (current_vtbl.table->size - 3) * sizeof(vtbl_method_t), + MEM_RELEASE); + HeapFree(GetProcessHeap(), 0, current_vtbl.table); + } + size = (num_methods - 3) * sizeof(vtbl_method_t); + current_vtbl.table = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(ref_counted_vtbl, vtbl) + num_methods * sizeof(void*)); + current_vtbl.table->ref = 0; + current_vtbl.table->size = num_methods; + current_vtbl.table->methods = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); + fill_table(¤t_vtbl.table->vtbl, current_vtbl.table->methods, num_methods); + VirtualProtect(current_vtbl.table->methods, size, PAGE_EXECUTE_READ, &old_protect); + } + LeaveCriticalSection(&delegating_vtbl_section); +} + +static IUnknownVtbl *get_delegating_vtbl(void) +{ + IUnknownVtbl *ret; + + EnterCriticalSection(&delegating_vtbl_section); + current_vtbl.table->ref++; + ret = ¤t_vtbl.table->vtbl; + LeaveCriticalSection(&delegating_vtbl_section); + return ret; +} + +static void release_delegating_vtbl(IUnknownVtbl *vtbl) +{ + ref_counted_vtbl *table = (ref_counted_vtbl*)((DWORD *)vtbl - 1); + + EnterCriticalSection(&delegating_vtbl_section); + table->ref--; + TRACE("ref now %d\n", table->ref); + if(table->ref == 0 && table != current_vtbl.table) + { + TRACE("... and we're not current so free'ing\n"); + VirtualFree(current_vtbl.table->methods, + (current_vtbl.table->size - 3) * sizeof(vtbl_method_t), + MEM_RELEASE); + HeapFree(GetProcessHeap(), 0, table); + } + LeaveCriticalSection(&delegating_vtbl_section); +} + +HRESULT WINAPI CStdStubBuffer_Delegating_Construct(REFIID riid, + LPUNKNOWN pUnkServer, + PCInterfaceName name, + CInterfaceStubVtbl *vtbl, + REFIID delegating_iid, + LPPSFACTORYBUFFER pPSFactory, + LPRPCSTUBBUFFER *ppStub) +{ + cstdstubbuffer_delegating_t *This; + IUnknown *pvServer; + HRESULT r; + + TRACE("(%p,%p,%p,%p) %s\n", pUnkServer, vtbl, pPSFactory, ppStub, name); + TRACE("iid=%s delegating to %s\n", debugstr_guid(vtbl->header.piid), debugstr_guid(delegating_iid)); + TRACE("vtbl=%p\n", &vtbl->Vtbl); + + if (!IsEqualGUID(vtbl->header.piid, riid)) + { + ERR("IID mismatch during stub creation\n"); + return RPC_E_UNEXPECTED; + } + + r = IUnknown_QueryInterface(pUnkServer, riid, (void**)&pvServer); + if(FAILED(r)) return r; + + This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*This)); + if (!This) + { + IUnknown_Release(pvServer); + return E_OUTOFMEMORY; + } + + This->base_obj = get_delegating_vtbl(); + r = create_stub(delegating_iid, (IUnknown*)&This->base_obj, &This->base_stub); + if(FAILED(r)) + { + release_delegating_vtbl(This->base_obj); + HeapFree(GetProcessHeap(), 0, This); + IUnknown_Release(pvServer); + return r; + } + + This->stub_buffer.lpVtbl = &vtbl->Vtbl; + This->stub_buffer.RefCount = 1; + This->stub_buffer.pvServerObject = pvServer; + This->stub_buffer.pPSFactory = pPSFactory; + *ppStub = (LPRPCSTUBBUFFER)&This->stub_buffer; + + IPSFactoryBuffer_AddRef(pPSFactory); + return S_OK; +} + HRESULT WINAPI CStdStubBuffer_QueryInterface(LPRPCSTUBBUFFER iface, REFIID riid, LPVOID *obj) @@ -77,12 +322,14 @@ HRESULT WINAPI CStdStubBuffer_QueryInterface(LPRPCSTUBBUFFER iface, CStdStubBuffer *This = (CStdStubBuffer *)iface; TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(riid),obj); - if (IsEqualGUID(&IID_IUnknown,riid) || - IsEqualGUID(&IID_IRpcStubBuffer,riid)) { - *obj = This; - This->RefCount++; + if (IsEqualIID(&IID_IUnknown, riid) || + IsEqualIID(&IID_IRpcStubBuffer, riid)) + { + IUnknown_AddRef(iface); + *obj = iface; return S_OK; } + *obj = NULL; return E_NOINTERFACE; } @@ -90,50 +337,81 @@ ULONG WINAPI CStdStubBuffer_AddRef(LPRPCSTUBBUFFER iface) { CStdStubBuffer *This = (CStdStubBuffer *)iface; TRACE("(%p)->AddRef()\n",This); - return ++(This->RefCount); + return InterlockedIncrement(&This->RefCount); } ULONG WINAPI NdrCStdStubBuffer_Release(LPRPCSTUBBUFFER iface, LPPSFACTORYBUFFER pPSF) { CStdStubBuffer *This = (CStdStubBuffer *)iface; + ULONG refs; + TRACE("(%p)->Release()\n",This); - if (!--(This->RefCount)) { + refs = InterlockedDecrement(&This->RefCount); + if (!refs) + { + /* test_Release shows that native doesn't call Disconnect here. + We'll leave it in for the time being. */ IRpcStubBuffer_Disconnect(iface); - if(This->pPSFactory) - IPSFactoryBuffer_Release(This->pPSFactory); + + IPSFactoryBuffer_Release(pPSF); HeapFree(GetProcessHeap(),0,This); - return 0; } - return This->RefCount; + return refs; } ULONG WINAPI NdrCStdStubBuffer2_Release(LPRPCSTUBBUFFER iface, LPPSFACTORYBUFFER pPSF) { - FIXME("Not implemented\n"); - return 0; + cstdstubbuffer_delegating_t *This = impl_from_delegating( iface ); + ULONG refs; + + TRACE("(%p)->Release()\n", This); + + refs = InterlockedDecrement(&This->stub_buffer.RefCount); + if (!refs) + { + /* Just like NdrCStdStubBuffer_Release, we shouldn't call + Disconnect here */ + IRpcStubBuffer_Disconnect((IRpcStubBuffer *)&This->stub_buffer); + + IRpcStubBuffer_Release(This->base_stub); + release_delegating_vtbl(This->base_obj); + + IPSFactoryBuffer_Release(pPSF); + HeapFree(GetProcessHeap(), 0, This); + } + + return refs; } HRESULT WINAPI CStdStubBuffer_Connect(LPRPCSTUBBUFFER iface, LPUNKNOWN lpUnkServer) { - CStdStubBuffer *This = (CStdStubBuffer *)iface; - TRACE("(%p)->Connect(%p)\n",This,lpUnkServer); - This->pvServerObject = lpUnkServer; - return S_OK; + CStdStubBuffer *This = (CStdStubBuffer *)iface; + HRESULT r; + IUnknown *new = NULL; + + TRACE("(%p)->Connect(%p)\n",This,lpUnkServer); + + r = IUnknown_QueryInterface(lpUnkServer, STUB_HEADER(This).piid, (void**)&new); + new = InterlockedExchangePointer((void**)&This->pvServerObject, new); + if(new) + IUnknown_Release(new); + return r; } void WINAPI CStdStubBuffer_Disconnect(LPRPCSTUBBUFFER iface) { - CStdStubBuffer *This = (CStdStubBuffer *)iface; - TRACE("(%p)->Disconnect()\n",This); - if (This->pvServerObject) - { - IUnknown_Release(This->pvServerObject); - This->pvServerObject = NULL; - } + CStdStubBuffer *This = (CStdStubBuffer *)iface; + IUnknown *old; + TRACE("(%p)->Disconnect()\n",This); + + old = InterlockedExchangePointer((void**)&This->pvServerObject, NULL); + + if(old) + IUnknown_Release(old); } HRESULT WINAPI CStdStubBuffer_Invoke(LPRPCSTUBBUFFER iface, @@ -142,13 +420,29 @@ HRESULT WINAPI CStdStubBuffer_Invoke(LPRPCSTUBBUFFER iface, { CStdStubBuffer *This = (CStdStubBuffer *)iface; DWORD dwPhase = STUB_UNMARSHAL; + HRESULT hr = S_OK; + TRACE("(%p)->Invoke(%p,%p)\n",This,pMsg,pChannel); - if (STUB_HEADER(This).pDispatchTable) - STUB_HEADER(This).pDispatchTable[pMsg->iMethod](iface, pChannel, (PRPC_MESSAGE)pMsg, &dwPhase); - else /* pure interpreted */ - NdrStubCall2(iface, pChannel, (PRPC_MESSAGE)pMsg, &dwPhase); - return S_OK; + __TRY + { + if (STUB_HEADER(This).pDispatchTable) + STUB_HEADER(This).pDispatchTable[pMsg->iMethod](iface, pChannel, (PRPC_MESSAGE)pMsg, &dwPhase); + else /* pure interpreted */ + NdrStubCall2(iface, pChannel, (PRPC_MESSAGE)pMsg, &dwPhase); + } + __EXCEPT(stub_filter) + { + DWORD dwExceptionCode = GetExceptionCode(); + WARN("a stub call failed with exception 0x%08x (%d)\n", dwExceptionCode, dwExceptionCode); + if (FAILED(dwExceptionCode)) + hr = dwExceptionCode; + else + hr = HRESULT_FROM_WIN32(dwExceptionCode); + } + __ENDTRY + + return hr; } LPRPCSTUBBUFFER WINAPI CStdStubBuffer_IsIIDSupported(LPRPCSTUBBUFFER iface, @@ -195,8 +489,111 @@ const IRpcStubBufferVtbl CStdStubBuffer_Vtbl = CStdStubBuffer_DebugServerRelease }; +static HRESULT WINAPI CStdStubBuffer_Delegating_Connect(LPRPCSTUBBUFFER iface, + LPUNKNOWN lpUnkServer) +{ + cstdstubbuffer_delegating_t *This = impl_from_delegating(iface); + HRESULT r; + TRACE("(%p)->Connect(%p)\n", This, lpUnkServer); + + r = CStdStubBuffer_Connect(iface, lpUnkServer); + if(SUCCEEDED(r)) + r = IRpcStubBuffer_Connect(This->base_stub, (IUnknown*)&This->base_obj); + + return r; +} + +static void WINAPI CStdStubBuffer_Delegating_Disconnect(LPRPCSTUBBUFFER iface) +{ + cstdstubbuffer_delegating_t *This = impl_from_delegating(iface); + TRACE("(%p)->Disconnect()\n", This); + + IRpcStubBuffer_Disconnect(This->base_stub); + CStdStubBuffer_Disconnect(iface); +} + +static ULONG WINAPI CStdStubBuffer_Delegating_CountRefs(LPRPCSTUBBUFFER iface) +{ + cstdstubbuffer_delegating_t *This = impl_from_delegating(iface); + ULONG ret; + TRACE("(%p)->CountRefs()\n", This); + + ret = CStdStubBuffer_CountRefs(iface); + ret += IRpcStubBuffer_CountRefs(This->base_stub); + + return ret; +} + +const IRpcStubBufferVtbl CStdStubBuffer_Delegating_Vtbl = +{ + CStdStubBuffer_QueryInterface, + CStdStubBuffer_AddRef, + NULL, + CStdStubBuffer_Delegating_Connect, + CStdStubBuffer_Delegating_Disconnect, + CStdStubBuffer_Invoke, + CStdStubBuffer_IsIIDSupported, + CStdStubBuffer_Delegating_CountRefs, + CStdStubBuffer_DebugServerQueryInterface, + CStdStubBuffer_DebugServerRelease +}; + const MIDL_SERVER_INFO *CStdStubBuffer_GetServerInfo(IRpcStubBuffer *iface) { CStdStubBuffer *This = (CStdStubBuffer *)iface; return STUB_HEADER(This).pServerInfo; } + +/************************************************************************ + * NdrStubForwardingFunction [RPCRT4.@] + */ +void __RPC_STUB NdrStubForwardingFunction( IRpcStubBuffer *iface, IRpcChannelBuffer *pChannel, + PRPC_MESSAGE pMsg, DWORD *pdwStubPhase ) +{ + /* Note pMsg is passed intact since RPCOLEMESSAGE is basically a RPC_MESSAGE. */ + + cstdstubbuffer_delegating_t *This = impl_from_delegating(iface); + HRESULT r = IRpcStubBuffer_Invoke(This->base_stub, (RPCOLEMESSAGE*)pMsg, pChannel); + if(FAILED(r)) RpcRaiseException(r); + return; +} + +/*********************************************************************** + * NdrStubInitialize [RPCRT4.@] + */ +void WINAPI NdrStubInitialize(PRPC_MESSAGE pRpcMsg, + PMIDL_STUB_MESSAGE pStubMsg, + PMIDL_STUB_DESC pStubDescriptor, + LPRPCCHANNELBUFFER pRpcChannelBuffer) +{ + TRACE("(%p,%p,%p,%p)\n", pRpcMsg, pStubMsg, pStubDescriptor, pRpcChannelBuffer); + NdrServerInitializeNew(pRpcMsg, pStubMsg, pStubDescriptor); + pStubMsg->pRpcChannelBuffer = pRpcChannelBuffer; + IRpcChannelBuffer_GetDestCtx(pStubMsg->pRpcChannelBuffer, + &pStubMsg->dwDestContext, + &pStubMsg->pvDestContext); +} + +/*********************************************************************** + * NdrStubGetBuffer [RPCRT4.@] + */ +void WINAPI NdrStubGetBuffer(LPRPCSTUBBUFFER iface, + LPRPCCHANNELBUFFER pRpcChannelBuffer, + PMIDL_STUB_MESSAGE pStubMsg) +{ + CStdStubBuffer *This = (CStdStubBuffer *)iface; + HRESULT hr; + + TRACE("(%p, %p, %p)\n", This, pRpcChannelBuffer, pStubMsg); + + pStubMsg->RpcMsg->BufferLength = pStubMsg->BufferLength; + hr = IRpcChannelBuffer_GetBuffer(pRpcChannelBuffer, + (RPCOLEMESSAGE *)pStubMsg->RpcMsg, STUB_HEADER(This).piid); + if (FAILED(hr)) + { + RpcRaiseException(hr); + return; + } + + pStubMsg->Buffer = pStubMsg->RpcMsg->Buffer; +} diff --git a/reactos/dll/win32/rpcrt4_new/epm_towers.h b/reactos/dll/win32/rpcrt4/epm_towers.h similarity index 100% rename from reactos/dll/win32/rpcrt4_new/epm_towers.h rename to reactos/dll/win32/rpcrt4/epm_towers.h diff --git a/reactos/dll/win32/rpcrt4_new/ncastatus.h b/reactos/dll/win32/rpcrt4/ncastatus.h similarity index 100% rename from reactos/dll/win32/rpcrt4_new/ncastatus.h rename to reactos/dll/win32/rpcrt4/ncastatus.h diff --git a/reactos/dll/win32/rpcrt4_new/ndr_clientserver.c b/reactos/dll/win32/rpcrt4/ndr_clientserver.c similarity index 100% rename from reactos/dll/win32/rpcrt4_new/ndr_clientserver.c rename to reactos/dll/win32/rpcrt4/ndr_clientserver.c diff --git a/reactos/dll/win32/rpcrt4/ndr_contexth.c b/reactos/dll/win32/rpcrt4/ndr_contexth.c deleted file mode 100644 index 41fd5c98d85..00000000000 --- a/reactos/dll/win32/rpcrt4/ndr_contexth.c +++ /dev/null @@ -1,373 +0,0 @@ -/* - * Context Handle Functions - * - * Copyright 2006 Saveliy Tretiakov - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "rpc.h" -#include "rpcndr.h" -#include "wine/debug.h" - -#include "rpc_binding.h" -#include "ndr_contexth.h" - -WINE_DEFAULT_DEBUG_CHANNEL(rpcrt4); - -static SContextHandle *CtxList = NULL; - -static CRITICAL_SECTION CtxList_cs; -static CRITICAL_SECTION_DEBUG CtxList_cs_debug = -{ - 0, 0, &CtxList_cs, - { &CtxList_cs_debug.ProcessLocksList, &CtxList_cs_debug.ProcessLocksList }, - 0, 0, { (DWORD_PTR)(__FILE__ ": CtxList_cs") } -}; -static CRITICAL_SECTION CtxList_cs = { &CtxList_cs_debug, -1, 0, 0, 0, 0 }; - -SContextHandle* RPCRT4_SrvAllocCtxHdl() -{ - SContextHandle *Hdl, *Tmp; - - if((Hdl = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(SContextHandle)))==NULL) return NULL; - - EnterCriticalSection(&CtxList_cs); - - if(!CtxList) CtxList = Hdl; - else - { - for(Tmp = CtxList; Tmp->Next; Tmp = Tmp->Next); - Tmp->Next = Hdl; - Hdl->Prev = Tmp; - } - - LeaveCriticalSection(&CtxList_cs); - - return Hdl; -} - -void RPCRT4_SrvFreeCtxHdl(SContextHandle *Hdl) -{ - EnterCriticalSection(&CtxList_cs); - - if(Hdl->Prev && Hdl->Next) - { - ((SContextHandle*)Hdl->Prev)->Next = Hdl->Next; - ((SContextHandle*)Hdl->Next)->Prev = Hdl->Prev; - } - else if(Hdl->Next) - { - ((SContextHandle*)Hdl->Next)->Prev = NULL; - CtxList = (SContextHandle*)Hdl->Next; - } - else if(Hdl->Prev) - ((SContextHandle*)Hdl->Prev)->Next = NULL; - else CtxList = NULL; - - HeapFree(GetProcessHeap(), 0, Hdl); - LeaveCriticalSection(&CtxList_cs); -} - -SContextHandle* RPCRT4_SrvFindCtxHdl(ContextHandleNdr *CtxNdr) -{ - SContextHandle *Hdl, *Ret=NULL; - RPC_STATUS status; - EnterCriticalSection(&CtxList_cs); - - for(Hdl = CtxList; Hdl; Hdl = Hdl->Next) - if(UuidCompare(&Hdl->Ndr.uuid, &CtxNdr->uuid, &status)==0) - { - Ret = Hdl; - break; - } - - LeaveCriticalSection(&CtxList_cs); - return Ret; -} - -SContextHandle* RPCRT4_SrvUnmarshallCtxHdl(ContextHandleNdr *Ndr) -{ - SContextHandle *Hdl = NULL; - RPC_STATUS status; - - if(!Ndr) - { - if((Hdl = RPCRT4_SrvAllocCtxHdl())==NULL) - RpcRaiseException(ERROR_OUTOFMEMORY); - - UuidCreate(&Hdl->Ndr.uuid); - } - else if(!UuidIsNil(&Ndr->uuid, &status)) - Hdl = RPCRT4_SrvFindCtxHdl(Ndr); - - return Hdl; -} - -void RPCRT4_SrvMarshallCtxHdl(SContextHandle *Hdl, ContextHandleNdr *Ndr) -{ - if(!Hdl->Value) - { - RPCRT4_SrvFreeCtxHdl(Hdl); - ZeroMemory(Ndr, sizeof(ContextHandleNdr)); - } - else memcpy(Ndr, &Hdl->Ndr, sizeof(ContextHandleNdr)); -} - -void RPCRT4_DoContextRundownIfNeeded(RpcConnection *Conn) -{ - -} - -/*********************************************************************** - * NDRCContextBinding - */ -RPC_BINDING_HANDLE WINAPI NDRCContextBinding(NDR_CCONTEXT CContext) -{ - if(!CContext) - RpcRaiseException(ERROR_INVALID_HANDLE); - - return (RPC_BINDING_HANDLE)((CContextHandle*)CContext)->Binding; -} - -/*********************************************************************** - * NDRCContextMarshall - */ -void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff ) -{ - CContextHandle *ctx = (CContextHandle*)CContext; - memcpy(pBuff, &ctx->Ndr, sizeof(ContextHandleNdr)); -} - -/*********************************************************************** - * NdrClientContextMarshall - */ -void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg, - NDR_CCONTEXT ContextHandle, - int fCheck) -{ - if(!ContextHandle) - RpcRaiseException(ERROR_INVALID_HANDLE); - - NDRCContextMarshall(ContextHandle, pStubMsg->Buffer); - - pStubMsg->Buffer += sizeof(ContextHandleNdr); - -} - -/*********************************************************************** - * NDRCContextUnmarshall - */ -void WINAPI NDRCContextUnmarshall(NDR_CCONTEXT *pCContext, - RPC_BINDING_HANDLE hBinding, - void *pBuff, - unsigned long DataRepresentation ) -{ - CContextHandle *ctx = (CContextHandle*)*pCContext; - ContextHandleNdr *ndr = (ContextHandleNdr*)pBuff; - RPC_STATUS status; - - if(UuidIsNil(&ndr->uuid, &status)) - { - if(ctx) - { - RPCRT4_DestroyBinding(ctx->Binding); - HeapFree(GetProcessHeap(), 0, ctx); - } - *pCContext = NULL; - } - else - { - ctx = HeapAlloc(GetProcessHeap(), 0, sizeof(CContextHandle)); - if(!ctx) RpcRaiseException(ERROR_OUTOFMEMORY); - - status = RpcBindingCopy(hBinding, (RPC_BINDING_HANDLE*) &ctx->Binding); - if(status != RPC_S_OK) RpcRaiseException(status); - - memcpy(&ctx->Ndr, ndr, sizeof(ContextHandleNdr)); - *pCContext = (NDR_CCONTEXT)ctx; - } -} - -/*********************************************************************** - * NdrClientContextUnmarshall - */ -void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, - NDR_CCONTEXT * pContextHandle, - RPC_BINDING_HANDLE BindHandle) -{ - - if(!pContextHandle || !BindHandle) - RpcRaiseException(ERROR_INVALID_HANDLE); - - NDRCContextUnmarshall(pContextHandle, - (CContextHandle*)BindHandle, - pStubMsg->Buffer, - pStubMsg->RpcMsg->DataRepresentation); - - pStubMsg->Buffer += sizeof(ContextHandleNdr); -} - -/*********************************************************************** - * RpcSmDestroyClientContext - */ -RPC_STATUS WINAPI RpcSmDestroyClientContext(void** ContextHandle) -{ - CContextHandle *ctx = (CContextHandle*)ContextHandle; - - if(!ctx) - return RPC_X_SS_CONTEXT_MISMATCH; - - RPCRT4_DestroyBinding(ctx->Binding); - HeapFree(GetProcessHeap(), 0, ctx); - *ContextHandle = NULL; - - return RPC_S_OK; -} - -/*********************************************************************** - * RpcSsDestroyClientContext - */ -void WINAPI RpcSsDestroyClientContext(void** ContextHandle) -{ - RPC_STATUS status; - - status = RpcSmDestroyClientContext(ContextHandle); - - if(status != RPC_S_OK) - RpcRaiseException(status); -} - -/*********************************************************************** - * NdrContextHandleSize - */ -void WINAPI NdrContextHandleSize(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char* pMemory, - PFORMAT_STRING pFormat) -{ - FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat); -} - -/*********************************************************************** - * NdrContextHandleInitialize - */ -NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg, - PFORMAT_STRING pFormat) -{ - FIXME("(%p, %p): stub\n", pStubMsg, pFormat); - return NULL; -} - -/*********************************************************************** - * NdrServerContextMarshall - */ -void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg, - NDR_SCONTEXT ContextHandle, - NDR_RUNDOWN RundownRoutine) -{ - SContextHandle *Hdl; - RpcBinding *Binding; - - if(!ContextHandle) - RpcRaiseException(ERROR_INVALID_HANDLE); - - Hdl = (SContextHandle*)ContextHandle; - Binding = (RpcBinding*)pStubMsg->RpcMsg->Handle; - Hdl->Rundown = RundownRoutine; - Hdl->Conn = Binding->FromConn; - RPCRT4_SrvMarshallCtxHdl(Hdl, (ContextHandleNdr*)pStubMsg->Buffer); - pStubMsg->Buffer += sizeof(ContextHandleNdr); -} - -/*********************************************************************** - * NdrServerContextUnmarshall - */ -NDR_SCONTEXT WINAPI NdrServerContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg) -{ - SContextHandle *Hdl; - - Hdl = RPCRT4_SrvUnmarshallCtxHdl((ContextHandleNdr*)pStubMsg->Buffer); - return (NDR_SCONTEXT)Hdl; -} - -/*********************************************************************** - * NdrServerContextNewMarshall - */ -void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg, - NDR_SCONTEXT ContextHandle, - NDR_RUNDOWN RundownRoutine, - PFORMAT_STRING pFormat) -{ - FIXME("(%p, %p, %p, %p): stub\n", pStubMsg, ContextHandle, RundownRoutine, pFormat); -} - -/*********************************************************************** - * NdrServerContextNewUnmarshall - */ -NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, - PFORMAT_STRING pFormat) -{ - FIXME("(%p, %p): stub\n", pStubMsg, pFormat); - return NULL; -} - -/*********************************************************************** - * NDRSContextMarshall - */ -void WINAPI NDRSContextMarshall(IN NDR_SCONTEXT CContext, - OUT void *pBuff, - IN NDR_RUNDOWN userRunDownIn) -{ - SContextHandle *Hdl; - - if(!CContext) - RpcRaiseException(ERROR_INVALID_HANDLE); - - Hdl = (SContextHandle*)CContext; - Hdl->Rundown = userRunDownIn; - RPCRT4_SrvMarshallCtxHdl(Hdl, (ContextHandleNdr*)pBuff); -} - -/*********************************************************************** - * NDRSContextUnmarshall - */ -NDR_SCONTEXT WINAPI NDRSContextUnmarshall(IN void *pBuff, - IN unsigned long DataRepresentation) -{ - return (NDR_SCONTEXT) RPCRT4_SrvUnmarshallCtxHdl((ContextHandleNdr*)pBuff); -} - -/*********************************************************************** - * NDRSContextMarshallEx - */ -void WINAPI NDRSContextMarshallEx(IN RPC_BINDING_HANDLE BindingHandle, - IN NDR_SCONTEXT CContext, - OUT void *pBuff, - IN NDR_RUNDOWN userRunDownIn) -{ - FIXME("stub\n"); -} - -/*********************************************************************** - * NDRSContextUnmarshallEx - */ -NDR_SCONTEXT WINAPI NDRSContextUnmarshallEx(IN RPC_BINDING_HANDLE BindingHandle, - IN void *pBuff, - IN unsigned long DataRepresentation) -{ - FIXME("stub\n"); - return NULL; -} diff --git a/reactos/dll/win32/rpcrt4/ndr_contexth.h b/reactos/dll/win32/rpcrt4/ndr_contexth.h deleted file mode 100644 index c953f8f3612..00000000000 --- a/reactos/dll/win32/rpcrt4/ndr_contexth.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Context Handle Functions - * - * Copyright 2006 Saveliy Tretiakov - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#ifndef __WINE_NDR_CONTEXTH_H -#define __WINE_NDR_CONTEXTH_H - -#include "wine/rpcss_shared.h" - -typedef struct _ContextHandleNdr -{ - UINT attributes; - UUID uuid; -} ContextHandleNdr; - -typedef struct _CContextHandle -{ - RpcBinding *Binding; - ContextHandleNdr Ndr; -} CContextHandle; - -/* - Keep this structure compatible with public rpcndr.h - declaration, otherwise NDRSContextValue macro won't work. - typedef struct { - void *pad[2]; - void *userContext; - } *NDR_SCONTEXT; -*/ - -typedef struct _SContextHandle -{ - PVOID Prev; - PVOID Next; - PVOID Value; - NDR_RUNDOWN Rundown; - RpcConnection *Conn; - ContextHandleNdr Ndr; -} SContextHandle; - -void RPCRT4_DoContextRundownIfNeeded(RpcConnection *Conn); - -#endif //__WINE_NDR_CONTEXTH_H diff --git a/reactos/dll/win32/rpcrt4_new/ndr_contexthandle.c b/reactos/dll/win32/rpcrt4/ndr_contexthandle.c similarity index 100% rename from reactos/dll/win32/rpcrt4_new/ndr_contexthandle.c rename to reactos/dll/win32/rpcrt4/ndr_contexthandle.c diff --git a/reactos/dll/win32/rpcrt4_new/ndr_fullpointer.c b/reactos/dll/win32/rpcrt4/ndr_fullpointer.c similarity index 100% rename from reactos/dll/win32/rpcrt4_new/ndr_fullpointer.c rename to reactos/dll/win32/rpcrt4/ndr_fullpointer.c diff --git a/reactos/dll/win32/rpcrt4/ndr_marshall.c b/reactos/dll/win32/rpcrt4/ndr_marshall.c index 9dcb8caceb2..3b6106fe7c5 100644 --- a/reactos/dll/win32/rpcrt4/ndr_marshall.c +++ b/reactos/dll/win32/rpcrt4/ndr_marshall.c @@ -2,6 +2,7 @@ * NDR data marshalling * * Copyright 2002 Greg Turner + * Copyright 2003-2006 CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -15,11 +16,16 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * * TODO: - * - figure out whether we *really* got this right - * - check for errors and throw exceptions + * - Non-conformant strings + * - String structs + * - Byte count pointers + * - transmit_as/represent as + * - Multi-dimensional arrays + * - Conversion functions (NdrConvert) + * - Checks for integer addition overflow in base type and user marshall functions */ #include @@ -31,7 +37,6 @@ #include "windef.h" #include "winbase.h" #include "winerror.h" -#include "winreg.h" #include "ndr_misc.h" #include "rpcndr.h" @@ -41,12 +46,8 @@ #include "wine/debug.h" -#include "rpc_binding.h" - WINE_DEFAULT_DEBUG_CHANNEL(ole); -#define BUFFER_PARANOIA 20 - #if defined(__i386__) # define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \ (*((UINT32 *)(pchar)) = (uint32)) @@ -92,15 +93,20 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole); LITTLE_ENDIAN_UINT32_READ(pchar) #endif -/* _Align must be the desired alignment minus 1, - * e.g. ALIGN_LENGTH(len, 3) to align on a dword boundary. */ -#define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align))&~(_Align)) +/* _Align must be the desired alignment, + * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */ +#define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1)) #define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align)) #define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align) #define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align) +#define ALIGN_POINTER_CLEAR(_Ptr, _Align) \ + do { \ + memset((_Ptr), 0, ((_Align) - (ULONG_PTR)(_Ptr)) & ((_Align) - 1)); \ + ALIGN_POINTER(_Ptr, _Align); \ + } while(0) #define STD_OVERFLOW_CHECK(_Msg) do { \ - TRACE("buffer=%d/%ld\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \ + TRACE("buffer=%d/%d\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \ if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \ ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \ } while (0) @@ -112,9 +118,13 @@ static unsigned char *WINAPI NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE, unsigned ch static unsigned char *WINAPI NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char); static void WINAPI NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING); static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING); -static unsigned long WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING); +static ULONG WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING); -NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = { +static unsigned char *WINAPI NdrContextHandleMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING); +static void WINAPI NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING); +static unsigned char *WINAPI NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char); + +const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = { 0, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, @@ -143,15 +153,20 @@ NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = { /* 0x2a */ NdrEncapsulatedUnionMarshall, NdrNonEncapsulatedUnionMarshall, - 0, + NdrByteCountPointerMarshall, NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall, /* 0x2f */ NdrInterfacePointerMarshall, - /* 0xb0 */ - 0, 0, 0, 0, - NdrUserMarshalMarshall + /* 0x30 */ + NdrContextHandleMarshall, + /* 0xb1 */ + 0, 0, 0, + NdrUserMarshalMarshall, + 0, 0, + /* 0xb7 */ + NdrRangeMarshall }; -NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = { +const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = { 0, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, @@ -180,15 +195,20 @@ NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = { /* 0x2a */ NdrEncapsulatedUnionUnmarshall, NdrNonEncapsulatedUnionUnmarshall, - 0, + NdrByteCountPointerUnmarshall, NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall, /* 0x2f */ NdrInterfacePointerUnmarshall, - /* 0xb0 */ - 0, 0, 0, 0, - NdrUserMarshalUnmarshall + /* 0x30 */ + NdrContextHandleUnmarshall, + /* 0xb1 */ + 0, 0, 0, + NdrUserMarshalUnmarshall, + 0, 0, + /* 0xb7 */ + NdrRangeUnmarshall }; -NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = { +const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = { 0, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, @@ -217,15 +237,20 @@ NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = { /* 0x2a */ NdrEncapsulatedUnionBufferSize, NdrNonEncapsulatedUnionBufferSize, - 0, + NdrByteCountPointerBufferSize, NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize, /* 0x2f */ NdrInterfacePointerBufferSize, - /* 0xb0 */ - 0, 0, 0, 0, - NdrUserMarshalBufferSize + /* 0x30 */ + NdrContextHandleBufferSize, + /* 0xb1 */ + 0, 0, 0, + NdrUserMarshalBufferSize, + 0, 0, + /* 0xb7 */ + NdrRangeBufferSize }; -NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = { +const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = { 0, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, @@ -238,24 +263,36 @@ NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = { NdrPointerMemorySize, NdrPointerMemorySize, /* 0x15 */ NdrSimpleStructMemorySize, NdrSimpleStructMemorySize, - 0, 0, 0, + NdrConformantStructMemorySize, NdrConformantStructMemorySize, + NdrConformantVaryingStructMemorySize, NdrComplexStructMemorySize, /* 0x1b */ - NdrConformantArrayMemorySize, 0, 0, 0, 0, 0, + NdrConformantArrayMemorySize, + NdrConformantVaryingArrayMemorySize, + NdrFixedArrayMemorySize, NdrFixedArrayMemorySize, + NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize, NdrComplexArrayMemorySize, /* 0x22 */ NdrConformantStringMemorySize, 0, 0, NdrConformantStringMemorySize, NdrNonConformantStringMemorySize, 0, 0, 0, /* 0x2a */ - 0, 0, 0, 0, 0, + NdrEncapsulatedUnionMemorySize, + NdrNonEncapsulatedUnionMemorySize, + NdrByteCountPointerMemorySize, + NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize, /* 0x2f */ NdrInterfacePointerMemorySize, - /* 0xb0 */ - 0, 0, 0, 0, - NdrUserMarshalMemorySize + /* 0x30 */ + 0, + /* 0xb1 */ + 0, 0, 0, + NdrUserMarshalMemorySize, + 0, 0, + /* 0xb7 */ + NdrRangeMemorySize }; -NDR_FREE NdrFreer[NDR_TABLE_SIZE] = { +const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = { 0, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, @@ -287,20 +324,78 @@ NDR_FREE NdrFreer[NDR_TABLE_SIZE] = { NdrXmitOrRepAsFree, NdrXmitOrRepAsFree, /* 0x2f */ NdrInterfacePointerFree, - /* 0xb0 */ - 0, 0, 0, 0, - NdrUserMarshalFree + /* 0x30 */ + 0, + /* 0xb1 */ + 0, 0, 0, + NdrUserMarshalFree, + 0, 0, + /* 0xb7 */ + NdrRangeFree }; +typedef struct _NDR_MEMORY_LIST +{ + ULONG magic; + ULONG size; + ULONG reserved; + struct _NDR_MEMORY_LIST *next; +} NDR_MEMORY_LIST; + +#define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L') + +/*********************************************************************** + * NdrAllocate [RPCRT4.@] + * + * Allocates a block of memory using pStubMsg->pfnAllocate. + * + * PARAMS + * pStubMsg [I/O] MIDL_STUB_MESSAGE structure. + * len [I] Size of memory block to allocate. + * + * RETURNS + * The memory block of size len that was allocated. + * + * NOTES + * The memory block is always 8-byte aligned. + * If the function is unable to allocate memory an ERROR_OUTOFMEMORY + * exception is raised. + */ void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, size_t len) { - /* hmm, this is probably supposed to do more? */ - return pStubMsg->pfnAllocate(len); + size_t aligned_len; + size_t adjusted_len; + void *p; + NDR_MEMORY_LIST *mem_list; + + aligned_len = ALIGNED_LENGTH(len, 8); + adjusted_len = aligned_len + sizeof(NDR_MEMORY_LIST); + /* check for overflow */ + if (adjusted_len < len) + { + ERR("overflow of adjusted_len %d, len %d\n", adjusted_len, len); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } + + p = pStubMsg->pfnAllocate(adjusted_len); + if (!p) RpcRaiseException(ERROR_OUTOFMEMORY); + + mem_list = (NDR_MEMORY_LIST *)((char *)p + aligned_len); + mem_list->magic = MEML_MAGIC; + mem_list->size = aligned_len; + mem_list->reserved = 0; + mem_list->next = pStubMsg->pMemoryList; + pStubMsg->pMemoryList = mem_list; + + TRACE("-- %p\n", p); + return p; } static void WINAPI NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer) { - pStubMsg->pfnFree(Pointer); + TRACE("(%p, %p)\n", pStubMsg, Pointer); + + pStubMsg->pfnFree(Pointer); } static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat) @@ -308,8 +403,11 @@ static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat) return (*(const ULONG *)pFormat != -1); } -PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat) +static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat) { + ALIGN_POINTER(pStubMsg->Buffer, 4); + if (pStubMsg->Buffer + 4 > pStubMsg->BufferEnd) + RpcRaiseException(RPC_X_BAD_STUB_DATA); pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); pStubMsg->Buffer += 4; TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount); @@ -319,21 +417,33 @@ PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pForm return pFormat+4; } -static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat) +static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat, ULONG MaxValue) { - if (!IsConformanceOrVariancePresent(pFormat)) + if (pFormat && !IsConformanceOrVariancePresent(pFormat)) { pStubMsg->Offset = 0; pStubMsg->ActualCount = pStubMsg->MaxCount; goto done; } + ALIGN_POINTER(pStubMsg->Buffer, 4); + if (pStubMsg->Buffer + 8 > pStubMsg->BufferEnd) + RpcRaiseException(RPC_X_BAD_STUB_DATA); pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); pStubMsg->Buffer += 4; - TRACE("offset is %ld\n", pStubMsg->Offset); + TRACE("offset is %d\n", pStubMsg->Offset); pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); pStubMsg->Buffer += 4; - TRACE("variance is %ld\n", pStubMsg->ActualCount); + TRACE("variance is %d\n", pStubMsg->ActualCount); + + if ((pStubMsg->ActualCount > MaxValue) || + (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue)) + { + ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n", + pStubMsg->ActualCount, pStubMsg->Offset, MaxValue); + RpcRaiseException(RPC_S_INVALID_BOUND); + return NULL; + } done: if (pStubMsg->fHasNewCorrDesc) @@ -342,12 +452,52 @@ done: return pFormat+4; } +/* writes the conformance value to the buffer */ +static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg) +{ + ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4); + if (pStubMsg->Buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) + RpcRaiseException(RPC_X_BAD_STUB_DATA); + NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount); + pStubMsg->Buffer += 4; +} + +/* writes the variance values to the buffer */ +static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg) +{ + ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4); + if (pStubMsg->Buffer + 8 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) + RpcRaiseException(RPC_X_BAD_STUB_DATA); + NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset); + pStubMsg->Buffer += 4; + NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount); + pStubMsg->Buffer += 4; +} + +/* requests buffer space for the conformance value */ +static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg) +{ + ALIGN_LENGTH(pStubMsg->BufferLength, 4); + if (pStubMsg->BufferLength + 4 < pStubMsg->BufferLength) + RpcRaiseException(RPC_X_BAD_STUB_DATA); + pStubMsg->BufferLength += 4; +} + +/* requests buffer space for the variance values */ +static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg) +{ + ALIGN_LENGTH(pStubMsg->BufferLength, 4); + if (pStubMsg->BufferLength + 8 < pStubMsg->BufferLength) + RpcRaiseException(RPC_X_BAD_STUB_DATA); + pStubMsg->BufferLength += 8; +} + PFORMAT_STRING ComputeConformanceOrVariance( MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory, - PFORMAT_STRING pFormat, ULONG_PTR def, ULONG *pCount) + PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount) { BYTE dtype = pFormat[0] & 0xf; - short ofs = *(short *)&pFormat[2]; + short ofs = *(const short *)&pFormat[2]; LPVOID ptr = NULL; DWORD data = 0; @@ -360,16 +510,16 @@ PFORMAT_STRING ComputeConformanceOrVariance( switch (pFormat[0] & 0xf0) { case RPC_FC_NORMAL_CONFORMANCE: TRACE("normal conformance, ofs=%d\n", ofs); - ptr = pMemory + ofs; + ptr = pMemory; break; case RPC_FC_POINTER_CONFORMANCE: TRACE("pointer conformance, ofs=%d\n", ofs); - ptr = pStubMsg->Memory + ofs; + ptr = pStubMsg->Memory; break; case RPC_FC_TOP_LEVEL_CONFORMANCE: TRACE("toplevel conformance, ofs=%d\n", ofs); if (pStubMsg->StackTop) { - ptr = pStubMsg->StackTop + ofs; + ptr = pStubMsg->StackTop; } else { /* -Os mode, *pCount is already set */ @@ -378,13 +528,13 @@ PFORMAT_STRING ComputeConformanceOrVariance( break; case RPC_FC_CONSTANT_CONFORMANCE: data = ofs | ((DWORD)pFormat[1] << 16); - TRACE("constant conformance, val=%ld\n", data); + TRACE("constant conformance, val=%d\n", data); *pCount = data; goto finish_conf; case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE: FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs); if (pStubMsg->StackTop) { - ptr = pStubMsg->StackTop + ofs; + ptr = pStubMsg->StackTop; } else { /* ? */ @@ -397,7 +547,7 @@ PFORMAT_STRING ComputeConformanceOrVariance( switch (pFormat[1]) { case RPC_FC_DEREFERENCE: - ptr = *(LPVOID*)ptr; + ptr = *(LPVOID*)((char *)ptr + ofs); break; case RPC_FC_CALLBACK: { @@ -409,9 +559,13 @@ PFORMAT_STRING ComputeConformanceOrVariance( pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg); pStubMsg->StackTop = old_stack_top; + + /* the callback function always stores the computed value in MaxCount */ + *pCount = pStubMsg->MaxCount; goto finish_conf; } default: + ptr = (char *)ptr + ofs; break; } @@ -426,9 +580,11 @@ PFORMAT_STRING ComputeConformanceOrVariance( case RPC_FC_USHORT: data = *(USHORT*)ptr; break; + case RPC_FC_CHAR: case RPC_FC_SMALL: data = *(CHAR*)ptr; break; + case RPC_FC_BYTE: case RPC_FC_USMALL: data = *(UCHAR*)ptr; break; @@ -436,15 +592,25 @@ PFORMAT_STRING ComputeConformanceOrVariance( FIXME("unknown conformance data type %x\n", dtype); goto done_conf_grab; } - TRACE("dereferenced data type %x at %p, got %ld\n", dtype, ptr, data); + TRACE("dereferenced data type %x at %p, got %d\n", dtype, ptr, data); done_conf_grab: switch (pFormat[1]) { + case RPC_FC_DEREFERENCE: /* already handled */ case 0: /* no op */ *pCount = data; break; - case RPC_FC_DEREFERENCE: - /* already handled */ + case RPC_FC_ADD_1: + *pCount = data + 1; + break; + case RPC_FC_SUB_1: + *pCount = data - 1; + break; + case RPC_FC_MULT_2: + *pCount = data * 2; + break; + case RPC_FC_DIV_2: + *pCount = data / 2; break; default: FIXME("unknown conformance op %d\n", pFormat[1]); @@ -459,6 +625,69 @@ finish_conf: return pFormat+4; } +/* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if + * the result overflows 32-bits */ +static inline ULONG safe_multiply(ULONG a, ULONG b) +{ + ULONGLONG ret = (ULONGLONG)a * b; + if (ret > 0xffffffff) + { + RpcRaiseException(RPC_S_INVALID_BOUND); + return 0; + } + return ret; +} + +static inline void safe_buffer_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size) +{ + if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */ + (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)) + RpcRaiseException(RPC_X_BAD_STUB_DATA); + pStubMsg->Buffer += size; +} + +static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size) +{ + if (pStubMsg->BufferLength + size < pStubMsg->BufferLength) /* integer overflow of pStubMsg->BufferSize */ + { + ERR("buffer length overflow - BufferLength = %u, size = %u\n", + pStubMsg->BufferLength, size); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } + pStubMsg->BufferLength += size; +} + +/* copies data from the buffer, checking that there is enough data in the buffer + * to do so */ +static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE *pStubMsg, void *p, ULONG size) +{ + if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */ + (pStubMsg->Buffer + size > pStubMsg->BufferEnd)) + { + ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n", + pStubMsg->Buffer, pStubMsg->BufferEnd, size); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } + if (p == pStubMsg->Buffer) + ERR("pointer is the same as the buffer\n"); + memcpy(p, pStubMsg->Buffer, size); + pStubMsg->Buffer += size; +} + +/* copies data to the buffer, checking that there is enough space to do so */ +static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE *pStubMsg, const void *p, ULONG size) +{ + if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */ + (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)) + { + ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n", + pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength, + size); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } + memcpy(pStubMsg->Buffer, p, size); + pStubMsg->Buffer += size; +} /* * NdrConformantString: @@ -483,25 +712,18 @@ finish_conf: unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pszMessage, PFORMAT_STRING pFormat) { - unsigned long len, esize; - unsigned char *c; + ULONG esize, size; TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat); - assert(pFormat); - if (pszMessage == NULL) { - TRACE("string=%s\n", debugstr_a(pszMessage)); - len = 0; - esize = 0; - } - else if (*pFormat == RPC_FC_C_CSTRING) { - TRACE("string=%s\n", debugstr_a(pszMessage)); - len = strlen(pszMessage)+1; + if (*pFormat == RPC_FC_C_CSTRING) { + TRACE("string=%s\n", debugstr_a((char*)pszMessage)); + pStubMsg->ActualCount = strlen((char*)pszMessage)+1; esize = 1; } else if (*pFormat == RPC_FC_C_WSTRING) { TRACE("string=%s\n", debugstr_w((LPWSTR)pszMessage)); - len = strlenW((LPWSTR)pszMessage)+1; + pStubMsg->ActualCount = strlenW((LPWSTR)pszMessage)+1; esize = 2; } else { @@ -510,25 +732,16 @@ unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg, return NULL; } - if (pFormat[1] != RPC_FC_PAD) { - FIXME("sized string format=%d\n", pFormat[1]); - } + if (pFormat[1] == RPC_FC_STRING_SIZED) + pFormat = ComputeConformance(pStubMsg, pszMessage, pFormat + 2, 0); + else + pStubMsg->MaxCount = pStubMsg->ActualCount; + pStubMsg->Offset = 0; + WriteConformance(pStubMsg); + WriteVariance(pStubMsg); - assert( (pStubMsg->BufferLength >= (len*esize + 13)) && (pStubMsg->Buffer != NULL) ); - - c = pStubMsg->Buffer; - memset(c, 0, 12); - NDR_LOCAL_UINT32_WRITE(c, len); /* max length: strlen + 1 (for '\0') */ - c += 8; /* offset: 0 */ - NDR_LOCAL_UINT32_WRITE(c, len); /* actual length: (same) */ - c += 4; - if (len != 0) { - memcpy(c, pszMessage, len*esize); /* the string itself */ - c += len*esize; - } - pStubMsg->Buffer = c; - - STD_OVERFLOW_CHECK(pStubMsg); + size = safe_multiply(esize, pStubMsg->ActualCount); + safe_copy_to_buffer(pStubMsg, pszMessage, size); /* the string itself */ /* success */ return NULL; /* is this always right? */ @@ -540,83 +753,61 @@ unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg, void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) { + ULONG esize; + TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat); - assert(pFormat); - if (pMemory == NULL) { - /* we need 12 octets for the [maxlen, offset, len] DWORDS */ - TRACE("string=NULL\n"); - pStubMsg->BufferLength += 12 + BUFFER_PARANOIA; - } - else if (*pFormat == RPC_FC_C_CSTRING) { - /* we need 12 octets for the [maxlen, offset, len] DWORDS, + 1 octet for '\0' */ + SizeConformance(pStubMsg); + SizeVariance(pStubMsg); + + if (*pFormat == RPC_FC_C_CSTRING) { TRACE("string=%s\n", debugstr_a((char*)pMemory)); - pStubMsg->BufferLength += strlen((char*)pMemory) + 13 + BUFFER_PARANOIA; + pStubMsg->ActualCount = strlen((char*)pMemory)+1; + esize = 1; } else if (*pFormat == RPC_FC_C_WSTRING) { - /* we need 12 octets for the [maxlen, offset, len] DWORDS, + 2 octets for L'\0' */ TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory)); - pStubMsg->BufferLength += strlenW((LPWSTR)pMemory)*2 + 14 + BUFFER_PARANOIA; + pStubMsg->ActualCount = strlenW((LPWSTR)pMemory)+1; + esize = 2; } else { ERR("Unhandled string type: %#x\n", *pFormat); /* FIXME: raise an exception */ + return; } - if (pFormat[1] != RPC_FC_PAD) { - FIXME("sized string format=%d\n", pFormat[1]); - } + if (pFormat[1] == RPC_FC_STRING_SIZED) + pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0); + else + pStubMsg->MaxCount = pStubMsg->ActualCount; + + safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount)); } /************************************************************************ * NdrConformantStringMemorySize [RPCRT4.@] */ -unsigned long WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg, +ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat ) { - unsigned long rslt = 0; + ULONG bufsize, memsize, esize, i; TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat); - - assert(pStubMsg && pFormat); - if (*pFormat == RPC_FC_C_CSTRING) { - rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); /* maxlen */ + ReadConformance(pStubMsg, NULL); + ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount); + + if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount)) + { + ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n", + pStubMsg->ActualCount, pStubMsg->MaxCount); + RpcRaiseException(RPC_S_INVALID_BOUND); } - else if (*pFormat == RPC_FC_C_WSTRING) { - rslt = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer)*2; /* maxlen */ + if (pStubMsg->Offset) + { + ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset); + RpcRaiseException(RPC_S_INVALID_BOUND); } - else { - ERR("Unhandled string type: %#x\n", *pFormat); - /* FIXME: raise an exception */ - } - - if (pFormat[1] != RPC_FC_PAD) { - FIXME("sized string format=%d\n", pFormat[1]); - } - - TRACE(" --> %lu\n", rslt); - return rslt; -} - -/************************************************************************ - * NdrConformantStringUnmarshall [RPCRT4.@] - */ -unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, - unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc ) -{ - unsigned long len, esize, ofs; - - TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n", - pStubMsg, *ppMemory, pFormat, fMustAlloc); - - assert(pFormat && ppMemory && pStubMsg); - - pStubMsg->Buffer += 4; - ofs = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); - pStubMsg->Buffer += 4; - len = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); - pStubMsg->Buffer += 4; if (*pFormat == RPC_FC_C_CSTRING) esize = 1; else if (*pFormat == RPC_FC_C_WSTRING) esize = 2; @@ -626,16 +817,123 @@ unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg esize = 0; } - if (pFormat[1] != RPC_FC_PAD) { - FIXME("sized string format=%d\n", pFormat[1]); + memsize = safe_multiply(esize, pStubMsg->MaxCount); + bufsize = safe_multiply(esize, pStubMsg->ActualCount); + + /* strings must always have null terminating bytes */ + if (bufsize < esize) + { + ERR("invalid string length of %d\n", pStubMsg->ActualCount); + RpcRaiseException(RPC_S_INVALID_BOUND); } - if (fMustAlloc || !*ppMemory) - *ppMemory = NdrAllocate(pStubMsg, len*esize + BUFFER_PARANOIA); + /* verify the buffer is safe to access */ + if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) || + (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd)) + { + ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize, + pStubMsg->BufferEnd, pStubMsg->Buffer); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } - memcpy(*ppMemory, pStubMsg->Buffer, len*esize); + for (i = bufsize - esize; i < bufsize; i++) + if (pStubMsg->Buffer[i] != 0) + { + ERR("string not null-terminated at byte position %d, data is 0x%x\n", + i, pStubMsg->Buffer[i]); + RpcRaiseException(RPC_S_INVALID_BOUND); + } - pStubMsg->Buffer += len*esize; + safe_buffer_increment(pStubMsg, bufsize); + pStubMsg->MemorySize += memsize; + + return pStubMsg->MemorySize; +} + +/************************************************************************ + * NdrConformantStringUnmarshall [RPCRT4.@] + */ +unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, + unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc ) +{ + ULONG bufsize, memsize, esize, i; + + TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n", + pStubMsg, *ppMemory, pFormat, fMustAlloc); + + assert(pFormat && ppMemory && pStubMsg); + + ReadConformance(pStubMsg, NULL); + ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount); + + if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount)) + { + ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n", + pStubMsg->ActualCount, pStubMsg->MaxCount); + RpcRaiseException(RPC_S_INVALID_BOUND); + return NULL; + } + if (pStubMsg->Offset) + { + ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset); + RpcRaiseException(RPC_S_INVALID_BOUND); + return NULL; + } + + if (*pFormat == RPC_FC_C_CSTRING) esize = 1; + else if (*pFormat == RPC_FC_C_WSTRING) esize = 2; + else { + ERR("Unhandled string type: %#x\n", *pFormat); + /* FIXME: raise an exception */ + esize = 0; + } + + memsize = safe_multiply(esize, pStubMsg->MaxCount); + bufsize = safe_multiply(esize, pStubMsg->ActualCount); + + /* strings must always have null terminating bytes */ + if (bufsize < esize) + { + ERR("invalid string length of %d\n", pStubMsg->ActualCount); + RpcRaiseException(RPC_S_INVALID_BOUND); + return NULL; + } + + /* verify the buffer is safe to access */ + if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) || + (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd)) + { + ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize, + pStubMsg->BufferEnd, pStubMsg->Buffer); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + return NULL; + } + + for (i = bufsize - esize; i < bufsize; i++) + if (pStubMsg->Buffer[i] != 0) + { + ERR("string not null-terminated at byte position %d, data is 0x%x\n", + i, pStubMsg->Buffer[i]); + RpcRaiseException(RPC_S_INVALID_BOUND); + return NULL; + } + + if (fMustAlloc) + *ppMemory = NdrAllocate(pStubMsg, memsize); + else + { + if (!pStubMsg->IsClient && !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount)) + /* if the data in the RPC buffer is big enough, we just point straight + * into it */ + *ppMemory = pStubMsg->Buffer; + else if (!*ppMemory) + *ppMemory = NdrAllocate(pStubMsg, memsize); + } + + if (*ppMemory == pStubMsg->Buffer) + safe_buffer_increment(pStubMsg, bufsize); + else + safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize); if (*pFormat == RPC_FC_C_CSTRING) { TRACE("string=%s\n", debugstr_a((char*)*ppMemory)); @@ -654,8 +952,45 @@ unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubM unsigned char *pMemory, PFORMAT_STRING pFormat) { - FIXME("stub\n"); - return NULL; + ULONG esize, size, maxsize; + + TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat); + + maxsize = *(USHORT *)&pFormat[2]; + + if (*pFormat == RPC_FC_CSTRING) + { + ULONG i; + const char *str = (const char *)pMemory; + for (i = 0; i < maxsize && *str; i++, str++) + ; + TRACE("string=%s\n", debugstr_an(str, i)); + pStubMsg->ActualCount = i + 1; + esize = 1; + } + else if (*pFormat == RPC_FC_WSTRING) + { + ULONG i; + const WCHAR *str = (const WCHAR *)pMemory; + for (i = 0; i < maxsize && *str; i++, str++) + ; + TRACE("string=%s\n", debugstr_wn(str, i)); + pStubMsg->ActualCount = i + 1; + esize = 2; + } + else + { + ERR("Unhandled string type: %#x\n", *pFormat); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } + + pStubMsg->Offset = 0; + WriteVariance(pStubMsg); + + size = safe_multiply(esize, pStubMsg->ActualCount); + safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */ + + return NULL; } /*********************************************************************** @@ -666,8 +1001,70 @@ unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStu PFORMAT_STRING pFormat, unsigned char fMustAlloc) { - FIXME("stub\n"); + ULONG bufsize, memsize, esize, i, maxsize; + + TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n", + pStubMsg, *ppMemory, pFormat, fMustAlloc); + + maxsize = *(USHORT *)&pFormat[2]; + + ReadVariance(pStubMsg, NULL, maxsize); + if (pStubMsg->Offset) + { + ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset); + RpcRaiseException(RPC_S_INVALID_BOUND); + } + + if (*pFormat == RPC_FC_CSTRING) esize = 1; + else if (*pFormat == RPC_FC_WSTRING) esize = 2; + else + { + ERR("Unhandled string type: %#x\n", *pFormat); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } + + memsize = esize * maxsize; + bufsize = safe_multiply(esize, pStubMsg->ActualCount); + + if (bufsize < esize) + { + ERR("invalid string length of %d\n", pStubMsg->ActualCount); + RpcRaiseException(RPC_S_INVALID_BOUND); return NULL; + } + + /* verify the buffer is safe to access */ + if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) || + (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd)) + { + ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize, + pStubMsg->BufferEnd, pStubMsg->Buffer); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + return NULL; + } + + /* strings must always have null terminating bytes */ + for (i = bufsize - esize; i < bufsize; i++) + if (pStubMsg->Buffer[i] != 0) + { + ERR("string not null-terminated at byte position %d, data is 0x%x\n", + i, pStubMsg->Buffer[i]); + RpcRaiseException(RPC_S_INVALID_BOUND); + } + + if (fMustAlloc || !*ppMemory) + *ppMemory = NdrAllocate(pStubMsg, memsize); + + safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize); + + if (*pFormat == RPC_FC_CSTRING) { + TRACE("string=%s\n", debugstr_an((char*)*ppMemory, pStubMsg->ActualCount)); + } + else if (*pFormat == RPC_FC_WSTRING) { + TRACE("string=%s\n", debugstr_wn((LPWSTR)*ppMemory, pStubMsg->ActualCount)); + } + + return NULL; } /*********************************************************************** @@ -677,17 +1074,102 @@ void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat) { - FIXME("stub\n"); + ULONG esize, maxsize; + + TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat); + + maxsize = *(USHORT *)&pFormat[2]; + + SizeVariance(pStubMsg); + + if (*pFormat == RPC_FC_CSTRING) + { + ULONG i; + const char *str = (const char *)pMemory; + for (i = 0; i < maxsize && *str; i++, str++) + ; + TRACE("string=%s\n", debugstr_an(str, i)); + pStubMsg->ActualCount = i + 1; + esize = 1; + } + else if (*pFormat == RPC_FC_WSTRING) + { + ULONG i; + const WCHAR *str = (const WCHAR *)pMemory; + for (i = 0; i < maxsize && *str; i++, str++) + ; + TRACE("string=%s\n", debugstr_wn(str, i)); + pStubMsg->ActualCount = i + 1; + esize = 2; + } + else + { + ERR("Unhandled string type: %#x\n", *pFormat); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } + + safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount)); } /*********************************************************************** * NdrNonConformantStringMemorySize [RPCRT4.@] */ -unsigned long WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg, +ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat) { - FIXME("stub\n"); - return 0; + ULONG bufsize, memsize, esize, i, maxsize; + + TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat); + + maxsize = *(USHORT *)&pFormat[2]; + + ReadVariance(pStubMsg, NULL, maxsize); + + if (pStubMsg->Offset) + { + ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset); + RpcRaiseException(RPC_S_INVALID_BOUND); + } + + if (*pFormat == RPC_FC_CSTRING) esize = 1; + else if (*pFormat == RPC_FC_WSTRING) esize = 2; + else + { + ERR("Unhandled string type: %#x\n", *pFormat); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } + + memsize = esize * maxsize; + bufsize = safe_multiply(esize, pStubMsg->ActualCount); + + /* strings must always have null terminating bytes */ + if (bufsize < esize) + { + ERR("invalid string length of %d\n", pStubMsg->ActualCount); + RpcRaiseException(RPC_S_INVALID_BOUND); + } + + /* verify the buffer is safe to access */ + if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) || + (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd)) + { + ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize, + pStubMsg->BufferEnd, pStubMsg->Buffer); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } + + for (i = bufsize - esize; i < bufsize; i++) + if (pStubMsg->Buffer[i] != 0) + { + ERR("string not null-terminated at byte position %d, data is 0x%x\n", + i, pStubMsg->Buffer[i]); + RpcRaiseException(RPC_S_INVALID_BOUND); + } + + safe_buffer_increment(pStubMsg, bufsize); + pStubMsg->MemorySize += memsize; + + return pStubMsg->MemorySize; } static inline void dump_pointer_attr(unsigned char attr) @@ -706,9 +1188,9 @@ static inline void dump_pointer_attr(unsigned char attr) } /*********************************************************************** - * PointerMarshall + * PointerMarshall [internal] */ -void WINAPI PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg, +static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *Buffer, unsigned char *Pointer, PFORMAT_STRING pFormat) @@ -716,39 +1198,53 @@ void WINAPI PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned type = pFormat[0], attr = pFormat[1]; PFORMAT_STRING desc; NDR_MARSHALL m; + ULONG pointer_id; + int pointer_needs_marshaling; TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat); TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr); pFormat += 2; if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat; else desc = pFormat + *(const SHORT*)pFormat; - if (attr & RPC_FC_P_DEREF) { - Pointer = *(unsigned char**)Pointer; - TRACE("deref => %p\n", Pointer); - } switch (type) { case RPC_FC_RP: /* ref pointer (always non-null) */ -#if 0 /* this causes problems for InstallShield so is disabled - we need more tests */ if (!Pointer) + { + ERR("NULL ref pointer is not allowed\n"); RpcRaiseException(RPC_X_NULL_REF_POINTER); -#endif + } + pointer_needs_marshaling = 1; break; case RPC_FC_UP: /* unique pointer */ case RPC_FC_OP: /* object pointer - same as unique here */ - TRACE("writing %p to buffer\n", Pointer); - NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, (unsigned long)Pointer); - pStubMsg->Buffer += 4; + if (Pointer) + pointer_needs_marshaling = 1; + else + pointer_needs_marshaling = 0; + pointer_id = (ULONG)Pointer; + TRACE("writing 0x%08x to buffer\n", pointer_id); + NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id); break; case RPC_FC_FP: + pointer_needs_marshaling = !NdrFullPointerQueryPointer( + pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id); + TRACE("writing 0x%08x to buffer\n", pointer_id); + NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id); + break; default: FIXME("unhandled ptr type=%02x\n", type); RpcRaiseException(RPC_X_BAD_STUB_DATA); + return; } TRACE("calling marshaller for type 0x%x\n", (int)*desc); - if (Pointer) { + if (pointer_needs_marshaling) { + if (attr & RPC_FC_P_DEREF) { + Pointer = *(unsigned char**)Pointer; + TRACE("deref => %p\n", Pointer); + } m = NdrMarshaller[*desc & NDR_TABLE_MASK]; if (m) m(pStubMsg, Pointer, desc); else FIXME("no marshaller for data type=%02x\n", *desc); @@ -758,11 +1254,12 @@ void WINAPI PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg, } /*********************************************************************** - * PointerUnmarshall + * PointerUnmarshall [internal] */ -void WINAPI PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, +static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *Buffer, unsigned char **pPointer, + unsigned char *pSrcPointer, PFORMAT_STRING pFormat, unsigned char fMustAlloc) { @@ -770,81 +1267,158 @@ void WINAPI PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING desc; NDR_UNMARSHALL m; DWORD pointer_id = 0; + int pointer_needs_unmarshaling; - TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pFormat, fMustAlloc); + TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pSrcPointer, pFormat, fMustAlloc); TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr); pFormat += 2; if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat; else desc = pFormat + *(const SHORT*)pFormat; - if (attr & RPC_FC_P_DEREF) { - pPointer = *(unsigned char***)pPointer; - TRACE("deref => %p\n", pPointer); - } switch (type) { case RPC_FC_RP: /* ref pointer (always non-null) */ - pointer_id = ~0UL; + pointer_needs_unmarshaling = 1; break; case RPC_FC_UP: /* unique pointer */ - pointer_id = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); - pStubMsg->Buffer += 4; + pointer_id = NDR_LOCAL_UINT32_READ(Buffer); + TRACE("pointer_id is 0x%08x\n", pointer_id); + if (pointer_id) + pointer_needs_unmarshaling = 1; + else { + *pPointer = NULL; + pointer_needs_unmarshaling = 0; + } break; case RPC_FC_OP: /* object pointer - we must free data before overwriting it */ - pointer_id = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); - pStubMsg->Buffer += 4; - if (*pPointer) - FIXME("free object pointer %p\n", *pPointer); + pointer_id = NDR_LOCAL_UINT32_READ(Buffer); + TRACE("pointer_id is 0x%08x\n", pointer_id); + if (!fMustAlloc && pSrcPointer) + { + FIXME("free object pointer %p\n", pSrcPointer); + fMustAlloc = TRUE; + } + if (pointer_id) + pointer_needs_unmarshaling = 1; + else + pointer_needs_unmarshaling = 0; break; case RPC_FC_FP: + pointer_id = NDR_LOCAL_UINT32_READ(Buffer); + TRACE("pointer_id is 0x%08x\n", pointer_id); + pointer_needs_unmarshaling = !NdrFullPointerQueryRefId( + pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer); + break; default: FIXME("unhandled ptr type=%02x\n", type); RpcRaiseException(RPC_X_BAD_STUB_DATA); + return; } - if (pointer_id) { + if (pointer_needs_unmarshaling) { + unsigned char *base_ptr_val = *pPointer; + unsigned char **current_ptr = pPointer; + if (pStubMsg->IsClient) { + TRACE("client\n"); + /* if we aren't forcing allocation of memory then try to use the existing + * (source) pointer to unmarshall the data into so that [in,out] + * parameters behave correctly. it doesn't matter if the parameter is + * [out] only since in that case the pointer will be NULL. we force + * allocation when the source pointer is NULL here instead of in the type + * unmarshalling routine for the benefit of the deref code below */ + if (!fMustAlloc) { + if (pSrcPointer) { + TRACE("setting *pPointer to %p\n", pSrcPointer); + *pPointer = base_ptr_val = pSrcPointer; + } else + fMustAlloc = TRUE; + } + } else { + TRACE("server\n"); + /* the memory in a stub is never initialised, so we have to work out here + * whether we have to initialise it so we can use the optimisation of + * setting the pointer to the buffer, if possible, or set fMustAlloc to + * TRUE. */ + if (attr & RPC_FC_P_DEREF) { + fMustAlloc = TRUE; + } else { + base_ptr_val = NULL; + *current_ptr = NULL; + } + } + + if (attr & RPC_FC_P_ALLOCALLNODES) + FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n"); + + if (attr & RPC_FC_P_DEREF) { + if (fMustAlloc) { + base_ptr_val = NdrAllocate(pStubMsg, sizeof(void *)); + *pPointer = base_ptr_val; + current_ptr = (unsigned char **)base_ptr_val; + } else + current_ptr = *(unsigned char***)current_ptr; + TRACE("deref => %p\n", current_ptr); + if (!fMustAlloc && !*current_ptr) fMustAlloc = TRUE; + } m = NdrUnmarshaller[*desc & NDR_TABLE_MASK]; - if (m) m(pStubMsg, pPointer, desc, fMustAlloc); + if (m) m(pStubMsg, current_ptr, desc, fMustAlloc); else FIXME("no unmarshaller for data type=%02x\n", *desc); + + if (type == RPC_FC_FP) + NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id, + base_ptr_val); } TRACE("pointer=%p\n", *pPointer); } /*********************************************************************** - * PointerBufferSize + * PointerBufferSize [internal] */ -void WINAPI PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, +static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *Pointer, PFORMAT_STRING pFormat) { unsigned type = pFormat[0], attr = pFormat[1]; PFORMAT_STRING desc; NDR_BUFFERSIZE m; + int pointer_needs_sizing; + ULONG pointer_id; TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat); - TRACE("type=%d, attr=%d\n", type, attr); + TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr); pFormat += 2; if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat; else desc = pFormat + *(const SHORT*)pFormat; - if (attr & RPC_FC_P_DEREF) { - Pointer = *(unsigned char**)Pointer; - TRACE("deref => %p\n", Pointer); - } switch (type) { case RPC_FC_RP: /* ref pointer (always non-null) */ + if (!Pointer) + { + ERR("NULL ref pointer is not allowed\n"); + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } break; case RPC_FC_OP: case RPC_FC_UP: - pStubMsg->BufferLength += 4; /* NULL pointer has no further representation */ if (!Pointer) return; break; case RPC_FC_FP: + pointer_needs_sizing = !NdrFullPointerQueryPointer( + pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id); + if (!pointer_needs_sizing) + return; + break; default: FIXME("unhandled ptr type=%02x\n", type); RpcRaiseException(RPC_X_BAD_STUB_DATA); + return; + } + + if (attr & RPC_FC_P_DEREF) { + Pointer = *(unsigned char**)Pointer; + TRACE("deref => %p\n", Pointer); } m = NdrBufferSizer[*desc & NDR_TABLE_MASK]; @@ -853,53 +1427,79 @@ void WINAPI PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, } /*********************************************************************** - * PointerMemorySize [RPCRT4.@] + * PointerMemorySize [internal] */ -unsigned long WINAPI PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg, +static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *Buffer, PFORMAT_STRING pFormat) { unsigned type = pFormat[0], attr = pFormat[1]; PFORMAT_STRING desc; NDR_MEMORYSIZE m; + DWORD pointer_id = 0; + int pointer_needs_sizing; - FIXME("(%p,%p,%p): stub\n", pStubMsg, Buffer, pFormat); - TRACE("type=%d, attr=", type); dump_pointer_attr(attr); + TRACE("(%p,%p,%p)\n", pStubMsg, Buffer, pFormat); + TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr); pFormat += 2; if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat; else desc = pFormat + *(const SHORT*)pFormat; + + switch (type) { + case RPC_FC_RP: /* ref pointer (always non-null) */ + pointer_needs_sizing = 1; + break; + case RPC_FC_UP: /* unique pointer */ + case RPC_FC_OP: /* object pointer - we must free data before overwriting it */ + pointer_id = NDR_LOCAL_UINT32_READ(Buffer); + TRACE("pointer_id is 0x%08x\n", pointer_id); + if (pointer_id) + pointer_needs_sizing = 1; + else + pointer_needs_sizing = 0; + break; + case RPC_FC_FP: + { + void *pointer; + pointer_id = NDR_LOCAL_UINT32_READ(Buffer); + TRACE("pointer_id is 0x%08x\n", pointer_id); + pointer_needs_sizing = !NdrFullPointerQueryRefId( + pStubMsg->FullPtrXlatTables, pointer_id, 1, &pointer); + break; + } + default: + FIXME("unhandled ptr type=%02x\n", type); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + return 0; + } + if (attr & RPC_FC_P_DEREF) { TRACE("deref\n"); } - switch (type) { - case RPC_FC_RP: /* ref pointer (always non-null) */ - break; - default: - FIXME("unhandled ptr type=%02x\n", type); - RpcRaiseException(RPC_X_BAD_STUB_DATA); + if (pointer_needs_sizing) { + m = NdrMemorySizer[*desc & NDR_TABLE_MASK]; + if (m) m(pStubMsg, desc); + else FIXME("no memorysizer for data type=%02x\n", *desc); } - m = NdrMemorySizer[*desc & NDR_TABLE_MASK]; - if (m) m(pStubMsg, desc); - else FIXME("no memorysizer for data type=%02x\n", *desc); - - return 0; + return pStubMsg->MemorySize; } /*********************************************************************** - * PointerFree [RPCRT4.@] + * PointerFree [internal] */ -void WINAPI PointerFree(PMIDL_STUB_MESSAGE pStubMsg, +static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *Pointer, PFORMAT_STRING pFormat) { unsigned type = pFormat[0], attr = pFormat[1]; PFORMAT_STRING desc; NDR_FREE m; + unsigned char *current_pointer = Pointer; TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat); - TRACE("type=%d, attr=", type); dump_pointer_attr(attr); + TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr); if (attr & RPC_FC_P_DONTFREE) return; pFormat += 2; if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat; @@ -907,20 +1507,29 @@ void WINAPI PointerFree(PMIDL_STUB_MESSAGE pStubMsg, if (!Pointer) return; - if (attr & RPC_FC_P_DEREF) { - Pointer = *(unsigned char**)Pointer; - TRACE("deref => %p\n", Pointer); + if (type == RPC_FC_FP) { + int pointer_needs_freeing = NdrFullPointerFree( + pStubMsg->FullPtrXlatTables, Pointer); + if (!pointer_needs_freeing) + return; } - - m = NdrFreer[*desc & NDR_TABLE_MASK]; - if (m) m(pStubMsg, Pointer, desc); - /* we should check if the memory comes from NdrAllocate, - * and deallocate only if so - checking if the pointer is between - * BufferStart and BufferEnd will not always work since the buffer - * may be reallocated when the server wants to marshal the reply */ - if (Pointer >= (unsigned char *)pStubMsg->RpcMsg->Buffer || - Pointer <= (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) + if (attr & RPC_FC_P_DEREF) { + current_pointer = *(unsigned char**)Pointer; + TRACE("deref => %p\n", current_pointer); + } + + m = NdrFreer[*desc & NDR_TABLE_MASK]; + if (m) m(pStubMsg, current_pointer, desc); + + /* this check stops us from trying to free buffer memory. we don't have to + * worry about clients, since they won't call this function. + * we don't have to check for the buffer being reallocated because + * BufferStart and BufferEnd won't be reset when allocating memory for + * sending the response. we don't have to check for the new buffer here as + * it won't be used a type memory, only for buffer memory */ + if (Pointer >= (unsigned char *)pStubMsg->BufferStart && + Pointer < (unsigned char *)pStubMsg->BufferEnd) goto notfree; if (attr & RPC_FC_P_ONSTACK) { @@ -937,19 +1546,27 @@ notfree: /*********************************************************************** * EmbeddedPointerMarshall */ -unsigned char * WINAPI EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg, +static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat) { unsigned char *Mark = pStubMsg->BufferMark; - unsigned long Offset = pStubMsg->Offset; - unsigned ofs, rep, count, stride, xofs; + unsigned rep, count, stride; + unsigned i; + unsigned char *saved_buffer = NULL; TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); if (*pFormat != RPC_FC_PP) return NULL; pFormat += 2; + if (pStubMsg->PointerBufferMark) + { + saved_buffer = pStubMsg->Buffer; + pStubMsg->Buffer = pStubMsg->PointerBufferMark; + pStubMsg->PointerBufferMark = NULL; + } + while (pFormat[0] != RPC_FC_END) { switch (pFormat[0]) { default: @@ -957,43 +1574,47 @@ unsigned char * WINAPI EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg, case RPC_FC_NO_REPEAT: rep = 1; stride = 0; - ofs = 0; count = 1; - xofs = 0; pFormat += 2; break; case RPC_FC_FIXED_REPEAT: rep = *(const WORD*)&pFormat[2]; stride = *(const WORD*)&pFormat[4]; - ofs = *(const WORD*)&pFormat[6]; count = *(const WORD*)&pFormat[8]; - xofs = 0; pFormat += 10; break; case RPC_FC_VARIABLE_REPEAT: - rep = pStubMsg->MaxCount; + rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount; stride = *(const WORD*)&pFormat[2]; - ofs = *(const WORD*)&pFormat[4]; count = *(const WORD*)&pFormat[6]; - xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0; pFormat += 8; break; } - /* ofs doesn't seem to matter in this context */ - while (rep) { + for (i = 0; i < rep; i++) { PFORMAT_STRING info = pFormat; - unsigned char *membase = pMemory + xofs; + unsigned char *membase = pMemory + (i * stride); + unsigned char *bufbase = Mark + (i * stride); unsigned u; + for (u=0; uMemory; + + pStubMsg->Memory = pMemory; PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4); + pStubMsg->Memory = saved_memory; } - rep--; } pFormat += 8 * count; } + if (saved_buffer) + { + pStubMsg->PointerBufferMark = pStubMsg->Buffer; + pStubMsg->Buffer = saved_buffer; + } + STD_OVERFLOW_CHECK(pStubMsg); return NULL; @@ -1002,81 +1623,104 @@ unsigned char * WINAPI EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg, /*********************************************************************** * EmbeddedPointerUnmarshall */ -unsigned char * WINAPI EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char **ppMemory, +static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, + unsigned char *pDstMemoryPtrs, + unsigned char *pSrcMemoryPtrs, PFORMAT_STRING pFormat, unsigned char fMustAlloc) { unsigned char *Mark = pStubMsg->BufferMark; - unsigned long Offset = pStubMsg->Offset; - unsigned ofs, rep, count, stride, xofs; + unsigned rep, count, stride; + unsigned i; + unsigned char *saved_buffer = NULL; - TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); + TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstMemoryPtrs, pSrcMemoryPtrs, pFormat, fMustAlloc); if (*pFormat != RPC_FC_PP) return NULL; pFormat += 2; + if (pStubMsg->PointerBufferMark) + { + saved_buffer = pStubMsg->Buffer; + pStubMsg->Buffer = pStubMsg->PointerBufferMark; + pStubMsg->PointerBufferMark = NULL; + } + while (pFormat[0] != RPC_FC_END) { + TRACE("pFormat[0] = 0x%x\n", pFormat[0]); switch (pFormat[0]) { default: FIXME("unknown repeat type %d\n", pFormat[0]); case RPC_FC_NO_REPEAT: rep = 1; stride = 0; - ofs = 0; count = 1; - xofs = 0; pFormat += 2; break; case RPC_FC_FIXED_REPEAT: rep = *(const WORD*)&pFormat[2]; stride = *(const WORD*)&pFormat[4]; - ofs = *(const WORD*)&pFormat[6]; count = *(const WORD*)&pFormat[8]; - xofs = 0; pFormat += 10; break; case RPC_FC_VARIABLE_REPEAT: - rep = pStubMsg->MaxCount; + rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount; stride = *(const WORD*)&pFormat[2]; - ofs = *(const WORD*)&pFormat[4]; count = *(const WORD*)&pFormat[6]; - xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0; pFormat += 8; break; } - /* ofs doesn't seem to matter in this context */ - while (rep) { + for (i = 0; i < rep; i++) { PFORMAT_STRING info = pFormat; - unsigned char *membase = *ppMemory + xofs; + unsigned char *memdstbase = pDstMemoryPtrs + (i * stride); + unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride); + unsigned char *bufbase = Mark + (i * stride); unsigned u; + for (u=0; uPointerBufferMark = pStubMsg->Buffer; + pStubMsg->Buffer = saved_buffer; + } + return NULL; } /*********************************************************************** * EmbeddedPointerBufferSize */ -void WINAPI EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, +static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat) { - unsigned long Offset = pStubMsg->Offset; - unsigned ofs, rep, count, stride, xofs; + unsigned rep, count, stride; + unsigned i; + ULONG saved_buffer_length = 0; TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); + + if (pStubMsg->IgnoreEmbeddedPointers) return; + if (*pFormat != RPC_FC_PP) return; pFormat += 2; + if (pStubMsg->PointerLength) + { + saved_buffer_length = pStubMsg->BufferLength; + pStubMsg->BufferLength = pStubMsg->PointerLength; + pStubMsg->PointerLength = 0; + } + while (pFormat[0] != RPC_FC_END) { switch (pFormat[0]) { default: @@ -1084,54 +1728,68 @@ void WINAPI EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, case RPC_FC_NO_REPEAT: rep = 1; stride = 0; - ofs = 0; count = 1; - xofs = 0; pFormat += 2; break; case RPC_FC_FIXED_REPEAT: rep = *(const WORD*)&pFormat[2]; stride = *(const WORD*)&pFormat[4]; - ofs = *(const WORD*)&pFormat[6]; count = *(const WORD*)&pFormat[8]; - xofs = 0; pFormat += 10; break; case RPC_FC_VARIABLE_REPEAT: - rep = pStubMsg->MaxCount; + rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount; stride = *(const WORD*)&pFormat[2]; - ofs = *(const WORD*)&pFormat[4]; count = *(const WORD*)&pFormat[6]; - xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0; pFormat += 8; break; } - /* ofs doesn't seem to matter in this context */ - while (rep) { + for (i = 0; i < rep; i++) { PFORMAT_STRING info = pFormat; - unsigned char *membase = pMemory + xofs; + unsigned char *membase = pMemory + (i * stride); unsigned u; + for (u=0; uMemory; + + pStubMsg->Memory = pMemory; PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4); + pStubMsg->Memory = saved_memory; } - rep--; } pFormat += 8 * count; } + + if (saved_buffer_length) + { + pStubMsg->PointerLength = pStubMsg->BufferLength; + pStubMsg->BufferLength = saved_buffer_length; + } } /*********************************************************************** - * EmbeddedPointerMemorySize + * EmbeddedPointerMemorySize [internal] */ -unsigned long WINAPI EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg, +static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat) { - unsigned long Offset = pStubMsg->Offset; unsigned char *Mark = pStubMsg->BufferMark; - unsigned ofs, rep, count, stride, xofs; + unsigned rep, count, stride; + unsigned i; + unsigned char *saved_buffer = NULL; + + TRACE("(%p,%p)\n", pStubMsg, pFormat); + + if (pStubMsg->IgnoreEmbeddedPointers) return 0; + + if (pStubMsg->PointerBufferMark) + { + saved_buffer = pStubMsg->Buffer; + pStubMsg->Buffer = pStubMsg->PointerBufferMark; + pStubMsg->PointerBufferMark = NULL; + } - FIXME("(%p,%p): stub\n", pStubMsg, pFormat); if (*pFormat != RPC_FC_PP) return 0; pFormat += 2; @@ -1142,53 +1800,52 @@ unsigned long WINAPI EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg, case RPC_FC_NO_REPEAT: rep = 1; stride = 0; - ofs = 0; count = 1; - xofs = 0; pFormat += 2; break; case RPC_FC_FIXED_REPEAT: rep = *(const WORD*)&pFormat[2]; stride = *(const WORD*)&pFormat[4]; - ofs = *(const WORD*)&pFormat[6]; count = *(const WORD*)&pFormat[8]; - xofs = 0; pFormat += 10; break; case RPC_FC_VARIABLE_REPEAT: - rep = pStubMsg->MaxCount; + rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount; stride = *(const WORD*)&pFormat[2]; - ofs = *(const WORD*)&pFormat[4]; count = *(const WORD*)&pFormat[6]; - xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0; pFormat += 8; break; } - /* ofs doesn't seem to matter in this context */ - while (rep) { + for (i = 0; i < rep; i++) { PFORMAT_STRING info = pFormat; + unsigned char *bufbase = Mark + (i * stride); unsigned u; for (u=0; uPointerBufferMark = pStubMsg->Buffer; + pStubMsg->Buffer = saved_buffer; + } + return 0; } /*********************************************************************** - * EmbeddedPointerFree + * EmbeddedPointerFree [internal] */ -void WINAPI EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg, +static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat) { - unsigned long Offset = pStubMsg->Offset; - unsigned ofs, rep, count, stride, xofs; + unsigned rep, count, stride; + unsigned i; TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); if (*pFormat != RPC_FC_PP) return; @@ -1201,38 +1858,35 @@ void WINAPI EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg, case RPC_FC_NO_REPEAT: rep = 1; stride = 0; - ofs = 0; count = 1; - xofs = 0; pFormat += 2; break; case RPC_FC_FIXED_REPEAT: rep = *(const WORD*)&pFormat[2]; stride = *(const WORD*)&pFormat[4]; - ofs = *(const WORD*)&pFormat[6]; count = *(const WORD*)&pFormat[8]; - xofs = 0; pFormat += 10; break; case RPC_FC_VARIABLE_REPEAT: - rep = pStubMsg->MaxCount; + rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount; stride = *(const WORD*)&pFormat[2]; - ofs = *(const WORD*)&pFormat[4]; count = *(const WORD*)&pFormat[6]; - xofs = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? Offset * stride : 0; pFormat += 8; break; } - /* ofs doesn't seem to matter in this context */ - while (rep) { + for (i = 0; i < rep; i++) { PFORMAT_STRING info = pFormat; - unsigned char *membase = pMemory + xofs; + unsigned char *membase = pMemory + (i * stride); unsigned u; + for (u=0; uMemory; + + pStubMsg->Memory = pMemory; PointerFree(pStubMsg, *(unsigned char**)memptr, info+4); + pStubMsg->Memory = saved_memory; } - rep--; } pFormat += 8 * count; } @@ -1245,12 +1899,23 @@ unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat) { + unsigned char *Buffer; + TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); - pStubMsg->BufferMark = pStubMsg->Buffer; - PointerMarshall(pStubMsg, pStubMsg->Buffer, pMemory, pFormat); + /* incremement the buffer here instead of in PointerMarshall, + * as that is used by embedded pointers which already handle the incrementing + * the buffer, and shouldn't write any additional pointer data to the wire */ + if (*pFormat != RPC_FC_RP) + { + ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4); + Buffer = pStubMsg->Buffer; + safe_buffer_increment(pStubMsg, 4); + } + else + Buffer = pStubMsg->Buffer; - STD_OVERFLOW_CHECK(pStubMsg); + PointerMarshall(pStubMsg, Buffer, pMemory, pFormat); return NULL; } @@ -1263,10 +1928,24 @@ unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, unsigned char fMustAlloc) { + unsigned char *Buffer; + TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); - pStubMsg->BufferMark = pStubMsg->Buffer; - PointerUnmarshall(pStubMsg, pStubMsg->Buffer, ppMemory, pFormat, fMustAlloc); + /* incremement the buffer here instead of in PointerUnmarshall, + * as that is used by embedded pointers which already handle the incrementing + * the buffer, and shouldn't read any additional pointer data from the + * buffer */ + if (*pFormat != RPC_FC_RP) + { + ALIGN_POINTER(pStubMsg->Buffer, 4); + Buffer = pStubMsg->Buffer; + safe_buffer_increment(pStubMsg, 4); + } + else + Buffer = pStubMsg->Buffer; + + PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc); return NULL; } @@ -1279,14 +1958,24 @@ void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat) { TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); + + /* incremement the buffer length here instead of in PointerBufferSize, + * as that is used by embedded pointers which already handle the buffer + * length, and shouldn't write anything more to the wire */ + if (*pFormat != RPC_FC_RP) + { + ALIGN_LENGTH(pStubMsg->BufferLength, 4); + safe_buffer_length_increment(pStubMsg, 4); + } + PointerBufferSize(pStubMsg, pMemory, pFormat); } /*********************************************************************** * NdrPointerMemorySize [RPCRT4.@] */ -unsigned long WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg, - PFORMAT_STRING pFormat) +ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg, + PFORMAT_STRING pFormat) { /* unsigned size = *(LPWORD)(pFormat+2); */ FIXME("(%p,%p): stub\n", pStubMsg, pFormat); @@ -1305,6 +1994,24 @@ void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg, PointerFree(pStubMsg, pMemory, pFormat); } +/*********************************************************************** + * NdrSimpleTypeMarshall [RPCRT4.@] + */ +void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, + unsigned char FormatChar ) +{ + NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar); +} + +/*********************************************************************** + * NdrSimpleTypeUnmarshall [RPCRT4.@] + */ +void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, + unsigned char FormatChar ) +{ + NdrBaseTypeUnmarshall(pStubMsg, &pMemory, &FormatChar, 0); +} + /*********************************************************************** * NdrSimpleStructMarshall [RPCRT4.@] */ @@ -1315,23 +2022,14 @@ unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned size = *(const WORD*)(pFormat+2); TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); - memcpy(pStubMsg->Buffer, pMemory, size); + ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1); + pStubMsg->BufferMark = pStubMsg->Buffer; - pStubMsg->Buffer += size; + safe_copy_to_buffer(pStubMsg, pMemory, size); if (pFormat[0] != RPC_FC_STRUCT) EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4); - /* - * This test does not work when NdrSimpleStructMarshall is called - * by an rpc-server to marshall data to return to the client because - * BufferStart and BufferEnd are bogus. MIDL does not update them - * when a new buffer is allocated in order to return data to the caller. - */ -#if 0 - STD_OVERFLOW_CHECK(pStubMsg); -#endif - return NULL; } @@ -1344,53 +2042,32 @@ unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char fMustAlloc) { unsigned size = *(const WORD*)(pFormat+2); + unsigned char *saved_buffer; TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); - if (fMustAlloc) { + ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1); + + if (fMustAlloc) *ppMemory = NdrAllocate(pStubMsg, size); - memcpy(*ppMemory, pStubMsg->Buffer, size); - } else { - if (pStubMsg->ReuseBuffer && !*ppMemory) - /* for servers, we may just point straight into the RPC buffer, I think - * (I guess that's what MS does since MIDL code doesn't try to free) */ + else + { + if (!pStubMsg->IsClient && !*ppMemory) + /* for servers, we just point straight into the RPC buffer */ *ppMemory = pStubMsg->Buffer; - else - /* for clients, memory should be provided by caller */ - memcpy(*ppMemory, pStubMsg->Buffer, size); } - pStubMsg->BufferMark = pStubMsg->Buffer; - pStubMsg->Buffer += size; + saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer; + safe_buffer_increment(pStubMsg, size); + if (pFormat[0] == RPC_FC_PSTRUCT) + EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc); - if (pFormat[0] != RPC_FC_STRUCT) - EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat+4, fMustAlloc); + TRACE("copying %p to %p\n", saved_buffer, *ppMemory); + if (*ppMemory != saved_buffer) + memcpy(*ppMemory, saved_buffer, size); return NULL; } - -/*********************************************************************** - * NdrSimpleTypeUnmarshall [RPCRT4.@] - */ -void WINAPI NdrSimpleTypeMarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - unsigned char FormatChar) -{ - FIXME("stub\n"); -} - - -/*********************************************************************** - * NdrSimpleTypeUnmarshall [RPCRT4.@] - */ -void WINAPI NdrSimpleTypeUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - unsigned char FormatChar) -{ - FIXME("stub\n"); -} - - /*********************************************************************** * NdrSimpleStructBufferSize [RPCRT4.@] */ @@ -1400,7 +2077,10 @@ void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, { unsigned size = *(const WORD*)(pFormat+2); TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); - pStubMsg->BufferLength += size; + + ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1); + + safe_buffer_length_increment(pStubMsg, size); if (pFormat[0] != RPC_FC_STRUCT) EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4); } @@ -1408,14 +2088,20 @@ void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, /*********************************************************************** * NdrSimpleStructMemorySize [RPCRT4.@] */ -unsigned long WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg, - PFORMAT_STRING pFormat) +ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg, + PFORMAT_STRING pFormat) { - /* unsigned size = *(LPWORD)(pFormat+2); */ - FIXME("(%p,%p): stub\n", pStubMsg, pFormat); + unsigned short size = *(const WORD *)(pFormat+2); + + TRACE("(%p,%p)\n", pStubMsg, pFormat); + + ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1); + pStubMsg->MemorySize += size; + safe_buffer_increment(pStubMsg, size); + if (pFormat[0] != RPC_FC_STRUCT) EmbeddedPointerMemorySize(pStubMsg, pFormat+4); - return 0; + return pStubMsg->MemorySize; } /*********************************************************************** @@ -1431,7 +2117,7 @@ void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg, } -unsigned long WINAPI EmbeddedComplexSize(PMIDL_STUB_MESSAGE pStubMsg, +static unsigned long EmbeddedComplexSize(const MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat) { switch (*pFormat) { @@ -1439,9 +2125,22 @@ unsigned long WINAPI EmbeddedComplexSize(PMIDL_STUB_MESSAGE pStubMsg, case RPC_FC_PSTRUCT: case RPC_FC_CSTRUCT: case RPC_FC_BOGUS_STRUCT: + case RPC_FC_SMFARRAY: + case RPC_FC_SMVARRAY: return *(const WORD*)&pFormat[2]; case RPC_FC_USER_MARSHAL: return *(const WORD*)&pFormat[4]; + case RPC_FC_NON_ENCAPSULATED_UNION: + pFormat += 2; + if (pStubMsg->fHasNewCorrDesc) + pFormat += 6; + else + pFormat += 4; + + pFormat += *(const SHORT*)pFormat; + return *(const SHORT*)pFormat; + case RPC_FC_IP: + return sizeof(void *); default: FIXME("unhandled embedded type %02x\n", *pFormat); } @@ -1449,7 +2148,22 @@ unsigned long WINAPI EmbeddedComplexSize(PMIDL_STUB_MESSAGE pStubMsg, } -unsigned char * WINAPI ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg, +static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg, + PFORMAT_STRING pFormat) +{ + NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK]; + + if (!m) + { + FIXME("no memorysizer for data type=%02x\n", *pFormat); + return 0; + } + + return m(pStubMsg, pFormat); +} + + +static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat, PFORMAT_STRING pPointer) @@ -1460,35 +2174,79 @@ unsigned char * WINAPI ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg, while (*pFormat != RPC_FC_END) { switch (*pFormat) { + case RPC_FC_BYTE: + case RPC_FC_CHAR: + case RPC_FC_SMALL: + case RPC_FC_USMALL: + TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory); + safe_copy_to_buffer(pStubMsg, pMemory, 1); + pMemory += 1; + break; + case RPC_FC_WCHAR: case RPC_FC_SHORT: case RPC_FC_USHORT: TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory); - memcpy(pStubMsg->Buffer, pMemory, 2); - pStubMsg->Buffer += 2; + safe_copy_to_buffer(pStubMsg, pMemory, 2); pMemory += 2; break; case RPC_FC_LONG: case RPC_FC_ULONG: case RPC_FC_ENUM32: - TRACE("long=%ld <= %p\n", *(DWORD*)pMemory, pMemory); - memcpy(pStubMsg->Buffer, pMemory, 4); - pStubMsg->Buffer += 4; + TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory); + safe_copy_to_buffer(pStubMsg, pMemory, 4); pMemory += 4; break; + case RPC_FC_HYPER: + TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory); + safe_copy_to_buffer(pStubMsg, pMemory, 8); + pMemory += 8; + break; case RPC_FC_POINTER: + { + unsigned char *saved_buffer; + int pointer_buffer_mark_set = 0; TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory); - NdrPointerMarshall(pStubMsg, *(unsigned char**)pMemory, pPointer); + ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4); + saved_buffer = pStubMsg->Buffer; + if (pStubMsg->PointerBufferMark) + { + pStubMsg->Buffer = pStubMsg->PointerBufferMark; + pStubMsg->PointerBufferMark = NULL; + pointer_buffer_mark_set = 1; + } + else + safe_buffer_increment(pStubMsg, 4); /* for pointer ID */ + PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer); + if (pointer_buffer_mark_set) + { + STD_OVERFLOW_CHECK(pStubMsg); + pStubMsg->PointerBufferMark = pStubMsg->Buffer; + if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) + { + ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n", + saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } + pStubMsg->Buffer = saved_buffer + 4; + } pPointer += 4; pMemory += 4; break; + } case RPC_FC_ALIGNM4: - ALIGN_POINTER(pMemory, 3); + ALIGN_POINTER(pMemory, 4); break; case RPC_FC_ALIGNM8: - ALIGN_POINTER(pMemory, 7); + ALIGN_POINTER(pMemory, 8); break; + case RPC_FC_STRUCTPAD1: case RPC_FC_STRUCTPAD2: - pMemory += 2; + case RPC_FC_STRUCTPAD3: + case RPC_FC_STRUCTPAD4: + case RPC_FC_STRUCTPAD5: + case RPC_FC_STRUCTPAD6: + case RPC_FC_STRUCTPAD7: + pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1; break; case RPC_FC_EMBEDDED_COMPLEX: pMemory += pFormat[1]; @@ -1497,7 +2255,17 @@ unsigned char * WINAPI ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg, size = EmbeddedComplexSize(pStubMsg, desc); TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory); m = NdrMarshaller[*desc & NDR_TABLE_MASK]; - if (m) m(pStubMsg, pMemory, desc); + if (m) + { + /* for some reason interface pointers aren't generated as + * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet + * they still need the derefencing treatment that pointers are + * given */ + if (*desc == RPC_FC_IP) + m(pStubMsg, *(unsigned char **)pMemory, desc); + else + m(pStubMsg, pMemory, desc); + } else FIXME("no marshaller for embedded type %02x\n", *desc); pMemory += size; pFormat += 2; @@ -1505,7 +2273,7 @@ unsigned char * WINAPI ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg, case RPC_FC_PAD: break; default: - FIXME("unhandled format %02x\n", *pFormat); + FIXME("unhandled format 0x%02x\n", *pFormat); } pFormat++; } @@ -1513,11 +2281,10 @@ unsigned char * WINAPI ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg, return pMemory; } -unsigned char * WINAPI ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, +static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat, - PFORMAT_STRING pPointer, - unsigned char fMustAlloc) + PFORMAT_STRING pPointer) { PFORMAT_STRING desc; NDR_UNMARSHALL m; @@ -1525,36 +2292,81 @@ unsigned char * WINAPI ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, while (*pFormat != RPC_FC_END) { switch (*pFormat) { + case RPC_FC_BYTE: + case RPC_FC_CHAR: + case RPC_FC_SMALL: + case RPC_FC_USMALL: + safe_copy_from_buffer(pStubMsg, pMemory, 1); + TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory); + pMemory += 1; + break; + case RPC_FC_WCHAR: case RPC_FC_SHORT: case RPC_FC_USHORT: - memcpy(pMemory, pStubMsg->Buffer, 2); + safe_copy_from_buffer(pStubMsg, pMemory, 2); TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory); - pStubMsg->Buffer += 2; pMemory += 2; break; case RPC_FC_LONG: case RPC_FC_ULONG: case RPC_FC_ENUM32: - memcpy(pMemory, pStubMsg->Buffer, 4); - TRACE("long=%ld => %p\n", *(DWORD*)pMemory, pMemory); - pStubMsg->Buffer += 4; + safe_copy_from_buffer(pStubMsg, pMemory, 4); + TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory); pMemory += 4; break; + case RPC_FC_HYPER: + safe_copy_from_buffer(pStubMsg, pMemory, 8); + TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory); + pMemory += 8; + break; case RPC_FC_POINTER: - *(unsigned char**)pMemory = NULL; + { + unsigned char *saved_buffer; + int pointer_buffer_mark_set = 0; TRACE("pointer => %p\n", pMemory); - NdrPointerUnmarshall(pStubMsg, (unsigned char**)pMemory, pPointer, fMustAlloc); + ALIGN_POINTER(pStubMsg->Buffer, 4); + saved_buffer = pStubMsg->Buffer; + if (pStubMsg->PointerBufferMark) + { + pStubMsg->Buffer = pStubMsg->PointerBufferMark; + pStubMsg->PointerBufferMark = NULL; + pointer_buffer_mark_set = 1; + } + else + safe_buffer_increment(pStubMsg, 4); /* for pointer ID */ + + PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, TRUE); + if (pointer_buffer_mark_set) + { + STD_OVERFLOW_CHECK(pStubMsg); + pStubMsg->PointerBufferMark = pStubMsg->Buffer; + if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) + { + ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n", + saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } + pStubMsg->Buffer = saved_buffer + 4; + } pPointer += 4; pMemory += 4; break; + } case RPC_FC_ALIGNM4: - ALIGN_POINTER(pMemory, 3); + ALIGN_POINTER_CLEAR(pMemory, 4); break; case RPC_FC_ALIGNM8: - ALIGN_POINTER(pMemory, 7); + ALIGN_POINTER_CLEAR(pMemory, 8); break; + case RPC_FC_STRUCTPAD1: case RPC_FC_STRUCTPAD2: - pMemory += 2; + case RPC_FC_STRUCTPAD3: + case RPC_FC_STRUCTPAD4: + case RPC_FC_STRUCTPAD5: + case RPC_FC_STRUCTPAD6: + case RPC_FC_STRUCTPAD7: + memset(pMemory, 0, *pFormat - RPC_FC_STRUCTPAD1 + 1); + pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1; break; case RPC_FC_EMBEDDED_COMPLEX: pMemory += pFormat[1]; @@ -1564,7 +2376,17 @@ unsigned char * WINAPI ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, TRACE("embedded complex (size=%ld) => %p\n", size, pMemory); m = NdrUnmarshaller[*desc & NDR_TABLE_MASK]; memset(pMemory, 0, size); /* just in case */ - if (m) m(pStubMsg, &pMemory, desc, fMustAlloc); + if (m) + { + /* for some reason interface pointers aren't generated as + * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet + * they still need the derefencing treatment that pointers are + * given */ + if (*desc == RPC_FC_IP) + m(pStubMsg, (unsigned char **)pMemory, desc, FALSE); + else + m(pStubMsg, &pMemory, desc, FALSE); + } else FIXME("no unmarshaller for embedded type %02x\n", *desc); pMemory += size; pFormat += 2; @@ -1580,7 +2402,7 @@ unsigned char * WINAPI ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, return pMemory; } -unsigned char * WINAPI ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg, +static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat, PFORMAT_STRING pPointer) @@ -1591,30 +2413,59 @@ unsigned char * WINAPI ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg, while (*pFormat != RPC_FC_END) { switch (*pFormat) { + case RPC_FC_BYTE: + case RPC_FC_CHAR: + case RPC_FC_SMALL: + case RPC_FC_USMALL: + safe_buffer_length_increment(pStubMsg, 1); + pMemory += 1; + break; + case RPC_FC_WCHAR: case RPC_FC_SHORT: case RPC_FC_USHORT: - pStubMsg->BufferLength += 2; + safe_buffer_length_increment(pStubMsg, 2); pMemory += 2; break; case RPC_FC_LONG: case RPC_FC_ULONG: case RPC_FC_ENUM32: - pStubMsg->BufferLength += 4; + safe_buffer_length_increment(pStubMsg, 4); pMemory += 4; break; + case RPC_FC_HYPER: + safe_buffer_length_increment(pStubMsg, 8); + pMemory += 8; + break; case RPC_FC_POINTER: - NdrPointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer); + if (!pStubMsg->IgnoreEmbeddedPointers) + { + int saved_buffer_length = pStubMsg->BufferLength; + pStubMsg->BufferLength = pStubMsg->PointerLength; + pStubMsg->PointerLength = 0; + if(!pStubMsg->BufferLength) + ERR("BufferLength == 0??\n"); + PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer); + pStubMsg->PointerLength = pStubMsg->BufferLength; + pStubMsg->BufferLength = saved_buffer_length; + } + safe_buffer_length_increment(pStubMsg, 4); pPointer += 4; pMemory += 4; break; case RPC_FC_ALIGNM4: - ALIGN_POINTER(pMemory, 3); + ALIGN_POINTER(pMemory, 4); break; case RPC_FC_ALIGNM8: - ALIGN_POINTER(pMemory, 7); + ALIGN_POINTER(pMemory, 8); break; + case RPC_FC_STRUCTPAD1: case RPC_FC_STRUCTPAD2: - pMemory += 2; + case RPC_FC_STRUCTPAD3: + case RPC_FC_STRUCTPAD4: + case RPC_FC_STRUCTPAD5: + case RPC_FC_STRUCTPAD6: + case RPC_FC_STRUCTPAD7: + pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1; break; case RPC_FC_EMBEDDED_COMPLEX: pMemory += pFormat[1]; @@ -1622,7 +2473,17 @@ unsigned char * WINAPI ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg, desc = pFormat + *(const SHORT*)pFormat; size = EmbeddedComplexSize(pStubMsg, desc); m = NdrBufferSizer[*desc & NDR_TABLE_MASK]; - if (m) m(pStubMsg, pMemory, desc); + if (m) + { + /* for some reason interface pointers aren't generated as + * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet + * they still need the derefencing treatment that pointers are + * given */ + if (*desc == RPC_FC_IP) + m(pStubMsg, *(unsigned char **)pMemory, desc); + else + m(pStubMsg, pMemory, desc); + } else FIXME("no buffersizer for embedded type %02x\n", *desc); pMemory += size; pFormat += 2; @@ -1630,7 +2491,7 @@ unsigned char * WINAPI ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg, case RPC_FC_PAD: break; default: - FIXME("unhandled format %d\n", *pFormat); + FIXME("unhandled format 0x%02x\n", *pFormat); } pFormat++; } @@ -1638,7 +2499,7 @@ unsigned char * WINAPI ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg, return pMemory; } -unsigned char * WINAPI ComplexFree(PMIDL_STUB_MESSAGE pStubMsg, +static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat, PFORMAT_STRING pPointer) @@ -1649,6 +2510,13 @@ unsigned char * WINAPI ComplexFree(PMIDL_STUB_MESSAGE pStubMsg, while (*pFormat != RPC_FC_END) { switch (*pFormat) { + case RPC_FC_BYTE: + case RPC_FC_CHAR: + case RPC_FC_SMALL: + case RPC_FC_USMALL: + pMemory += 1; + break; + case RPC_FC_WCHAR: case RPC_FC_SHORT: case RPC_FC_USHORT: pMemory += 2; @@ -1658,19 +2526,28 @@ unsigned char * WINAPI ComplexFree(PMIDL_STUB_MESSAGE pStubMsg, case RPC_FC_ENUM32: pMemory += 4; break; + case RPC_FC_HYPER: + pMemory += 8; + break; case RPC_FC_POINTER: NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer); pPointer += 4; pMemory += 4; break; case RPC_FC_ALIGNM4: - ALIGN_POINTER(pMemory, 3); + ALIGN_POINTER(pMemory, 4); break; case RPC_FC_ALIGNM8: - ALIGN_POINTER(pMemory, 7); + ALIGN_POINTER(pMemory, 8); break; + case RPC_FC_STRUCTPAD1: case RPC_FC_STRUCTPAD2: - pMemory += 2; + case RPC_FC_STRUCTPAD3: + case RPC_FC_STRUCTPAD4: + case RPC_FC_STRUCTPAD5: + case RPC_FC_STRUCTPAD6: + case RPC_FC_STRUCTPAD7: + pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1; break; case RPC_FC_EMBEDDED_COMPLEX: pMemory += pFormat[1]; @@ -1678,7 +2555,17 @@ unsigned char * WINAPI ComplexFree(PMIDL_STUB_MESSAGE pStubMsg, desc = pFormat + *(const SHORT*)pFormat; size = EmbeddedComplexSize(pStubMsg, desc); m = NdrFreer[*desc & NDR_TABLE_MASK]; - if (m) m(pStubMsg, pMemory, desc); + if (m) + { + /* for some reason interface pointers aren't generated as + * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet + * they still need the derefencing treatment that pointers are + * given */ + if (*desc == RPC_FC_IP) + m(pStubMsg, *(unsigned char **)pMemory, desc); + else + m(pStubMsg, pMemory, desc); + } else FIXME("no freer for embedded type %02x\n", *desc); pMemory += size; pFormat += 2; @@ -1686,7 +2573,7 @@ unsigned char * WINAPI ComplexFree(PMIDL_STUB_MESSAGE pStubMsg, case RPC_FC_PAD: break; default: - FIXME("unhandled format %d\n", *pFormat); + FIXME("unhandled format 0x%02x\n", *pFormat); } pFormat++; } @@ -1694,7 +2581,7 @@ unsigned char * WINAPI ComplexFree(PMIDL_STUB_MESSAGE pStubMsg, return pMemory; } -unsigned long WINAPI ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg, +static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat) { PFORMAT_STRING desc; @@ -1702,37 +2589,63 @@ unsigned long WINAPI ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg, while (*pFormat != RPC_FC_END) { switch (*pFormat) { + case RPC_FC_BYTE: + case RPC_FC_CHAR: + case RPC_FC_SMALL: + case RPC_FC_USMALL: + size += 1; + safe_buffer_increment(pStubMsg, 1); + break; + case RPC_FC_WCHAR: case RPC_FC_SHORT: case RPC_FC_USHORT: size += 2; + safe_buffer_increment(pStubMsg, 2); break; case RPC_FC_LONG: case RPC_FC_ULONG: + case RPC_FC_ENUM32: size += 4; + safe_buffer_increment(pStubMsg, 4); + break; + case RPC_FC_HYPER: + size += 8; + safe_buffer_increment(pStubMsg, 8); break; case RPC_FC_POINTER: size += 4; + safe_buffer_increment(pStubMsg, 4); + if (!pStubMsg->IgnoreEmbeddedPointers) + FIXME("embedded pointers\n"); break; case RPC_FC_ALIGNM4: - ALIGN_LENGTH(size, 3); + ALIGN_LENGTH(size, 4); + ALIGN_POINTER(pStubMsg->Buffer, 4); break; case RPC_FC_ALIGNM8: - ALIGN_LENGTH(size, 7); + ALIGN_LENGTH(size, 8); + ALIGN_POINTER(pStubMsg->Buffer, 8); break; + case RPC_FC_STRUCTPAD1: case RPC_FC_STRUCTPAD2: - size += 2; + case RPC_FC_STRUCTPAD3: + case RPC_FC_STRUCTPAD4: + case RPC_FC_STRUCTPAD5: + case RPC_FC_STRUCTPAD6: + case RPC_FC_STRUCTPAD7: + size += *pFormat - RPC_FC_STRUCTPAD1 + 1; break; case RPC_FC_EMBEDDED_COMPLEX: size += pFormat[1]; pFormat += 2; desc = pFormat + *(const SHORT*)pFormat; - size += EmbeddedComplexSize(pStubMsg, desc); + size += EmbeddedComplexMemorySize(pStubMsg, desc); pFormat += 2; continue; case RPC_FC_PAD: break; default: - FIXME("unhandled format %d\n", *pFormat); + FIXME("unhandled format 0x%02x\n", *pFormat); } pFormat++; } @@ -1750,9 +2663,34 @@ unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING conf_array = NULL; PFORMAT_STRING pointer_desc = NULL; unsigned char *OldMemory = pStubMsg->Memory; + int pointer_buffer_mark_set = 0; TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); + if (!pStubMsg->PointerBufferMark) + { + int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers; + /* save buffer length */ + unsigned long saved_buffer_length = pStubMsg->BufferLength; + + /* get the buffer pointer after complex array data, but before + * pointer data */ + pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart; + pStubMsg->IgnoreEmbeddedPointers = 1; + NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat); + pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded; + + /* save it for use by embedded pointer code later */ + pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength; + TRACE("difference = 0x%x\n", pStubMsg->PointerBufferMark - pStubMsg->Buffer); + pointer_buffer_mark_set = 1; + + /* restore the original buffer length */ + pStubMsg->BufferLength = saved_buffer_length; + } + + ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1); + pFormat += 4; if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat; pFormat += 2; @@ -1768,6 +2706,12 @@ unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg, pStubMsg->Memory = OldMemory; + if (pointer_buffer_mark_set) + { + pStubMsg->Buffer = pStubMsg->PointerBufferMark; + pStubMsg->PointerBufferMark = NULL; + } + STD_OVERFLOW_CHECK(pStubMsg); return NULL; @@ -1785,9 +2729,33 @@ unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING conf_array = NULL; PFORMAT_STRING pointer_desc = NULL; unsigned char *pMemory; + int pointer_buffer_mark_set = 0; TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); + if (!pStubMsg->PointerBufferMark) + { + int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers; + /* save buffer pointer */ + unsigned char *saved_buffer = pStubMsg->Buffer; + + /* get the buffer pointer after complex array data, but before + * pointer data */ + pStubMsg->IgnoreEmbeddedPointers = 1; + NdrComplexStructMemorySize(pStubMsg, pFormat); + pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded; + + /* save it for use by embedded pointer code later */ + pStubMsg->PointerBufferMark = pStubMsg->Buffer; + TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->PointerBufferMark - saved_buffer)); + pointer_buffer_mark_set = 1; + + /* restore the original buffer */ + pStubMsg->Buffer = saved_buffer; + } + + ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1); + if (fMustAlloc || !*ppMemory) { *ppMemory = NdrAllocate(pStubMsg, size); @@ -1800,11 +2768,17 @@ unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat; pFormat += 2; - pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc, fMustAlloc); + pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc); if (conf_array) NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc); + if (pointer_buffer_mark_set) + { + pStubMsg->Buffer = pStubMsg->PointerBufferMark; + pStubMsg->PointerBufferMark = NULL; + } + return NULL; } @@ -1818,9 +2792,32 @@ void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING conf_array = NULL; PFORMAT_STRING pointer_desc = NULL; unsigned char *OldMemory = pStubMsg->Memory; + int pointer_length_set = 0; TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); + ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1); + + if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength) + { + int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers; + unsigned long saved_buffer_length = pStubMsg->BufferLength; + + /* get the buffer length after complex struct data, but before + * pointer data */ + pStubMsg->IgnoreEmbeddedPointers = 1; + NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat); + pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded; + + /* save it for use by embedded pointer code later */ + pStubMsg->PointerLength = pStubMsg->BufferLength; + pointer_length_set = 1; + TRACE("difference = 0x%lx\n", pStubMsg->PointerLength - saved_buffer_length); + + /* restore the original buffer length */ + pStubMsg->BufferLength = saved_buffer_length; + } + pFormat += 4; if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat; pFormat += 2; @@ -1835,19 +2832,28 @@ void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array); pStubMsg->Memory = OldMemory; + + if(pointer_length_set) + { + pStubMsg->BufferLength = pStubMsg->PointerLength; + pStubMsg->PointerLength = 0; + } + } /*********************************************************************** * NdrComplexStructMemorySize [RPCRT4.@] */ -unsigned long WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg, - PFORMAT_STRING pFormat) +ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg, + PFORMAT_STRING pFormat) { - /* unsigned size = *(LPWORD)(pFormat+2); */ + unsigned size = *(const WORD*)(pFormat+2); PFORMAT_STRING conf_array = NULL; PFORMAT_STRING pointer_desc = NULL; - FIXME("(%p,%p): stub\n", pStubMsg, pFormat); + TRACE("(%p,%p)\n", pStubMsg, pFormat); + + ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1); pFormat += 4; if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat; @@ -1855,7 +2861,12 @@ unsigned long WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg, if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat; pFormat += 2; - return 0; + ComplexStructMemorySize(pStubMsg, pFormat); + + if (conf_array) + NdrConformantArrayMemorySize(pStubMsg, conf_array); + + return size; } /*********************************************************************** @@ -1895,23 +2906,23 @@ unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat) { DWORD size = 0, esize = *(const WORD*)(pFormat+2); + unsigned char alignment = pFormat[1] + 1; + TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]); pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0); - size = pStubMsg->MaxCount; - NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, size); - pStubMsg->Buffer += 4; + WriteConformance(pStubMsg); - memcpy(pStubMsg->Buffer, pMemory, size*esize); + ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment); + + size = safe_multiply(esize, pStubMsg->MaxCount); pStubMsg->BufferMark = pStubMsg->Buffer; - pStubMsg->Buffer += size*esize; + safe_copy_to_buffer(pStubMsg, pMemory, size); EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat); - STD_OVERFLOW_CHECK(pStubMsg); - return NULL; } @@ -1923,22 +2934,34 @@ unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, unsigned char fMustAlloc) { - DWORD size = 0, esize = *(const WORD*)(pFormat+2); + DWORD size, esize = *(const WORD*)(pFormat+2); + unsigned char alignment = pFormat[1] + 1; + unsigned char *saved_buffer; + TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]); pFormat = ReadConformance(pStubMsg, pFormat+4); - size = pStubMsg->MaxCount; - if (fMustAlloc || !*ppMemory) - *ppMemory = NdrAllocate(pStubMsg, size*esize); + size = safe_multiply(esize, pStubMsg->MaxCount); + ALIGN_POINTER(pStubMsg->Buffer, alignment); - memcpy(*ppMemory, pStubMsg->Buffer, size*esize); + if (fMustAlloc) + *ppMemory = NdrAllocate(pStubMsg, size); + else + { + if (!pStubMsg->IsClient && !*ppMemory) + /* for servers, we just point straight into the RPC buffer */ + *ppMemory = pStubMsg->Buffer; + } - pStubMsg->BufferMark = pStubMsg->Buffer; - pStubMsg->Buffer += size*esize; + saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer; + safe_buffer_increment(pStubMsg, size); + EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc); - EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc); + TRACE("copying %p to %p\n", saved_buffer, *ppMemory); + if (*ppMemory != saved_buffer) + memcpy(*ppMemory, saved_buffer, size); return NULL; } @@ -1950,15 +2973,21 @@ void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat) { - DWORD size = 0, esize = *(const WORD*)(pFormat+2); + DWORD size, esize = *(const WORD*)(pFormat+2); + unsigned char alignment = pFormat[1] + 1; + TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]); pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0); - size = pStubMsg->MaxCount; + SizeConformance(pStubMsg); + + ALIGN_LENGTH(pStubMsg->BufferLength, alignment); + + size = safe_multiply(esize, pStubMsg->MaxCount); /* conformance value plus array */ - pStubMsg->BufferLength += sizeof(DWORD) + size*esize; + safe_buffer_length_increment(pStubMsg, size); EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat); } @@ -1966,21 +2995,26 @@ void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, /*********************************************************************** * NdrConformantArrayMemorySize [RPCRT4.@] */ -unsigned long WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg, - PFORMAT_STRING pFormat) +ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg, + PFORMAT_STRING pFormat) { DWORD size = 0, esize = *(const WORD*)(pFormat+2); - unsigned char *buffer; + unsigned char alignment = pFormat[1] + 1; TRACE("(%p,%p)\n", pStubMsg, pFormat); if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]); - buffer = pStubMsg->Buffer; pFormat = ReadConformance(pStubMsg, pFormat+4); - pStubMsg->Buffer = buffer; - size = pStubMsg->MaxCount; + size = safe_multiply(esize, pStubMsg->MaxCount); + pStubMsg->MemorySize += size; - return size*esize; + ALIGN_POINTER(pStubMsg->Buffer, alignment); + pStubMsg->BufferMark = pStubMsg->Buffer; + safe_buffer_increment(pStubMsg, size); + + EmbeddedPointerMemorySize(pStubMsg, pFormat); + + return pStubMsg->MemorySize; } /*********************************************************************** @@ -1993,6 +3027,8 @@ void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg, TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]); + pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0); + EmbeddedPointerFree(pStubMsg, pMemory, pFormat); } @@ -2004,6 +3040,8 @@ unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStu unsigned char* pMemory, PFORMAT_STRING pFormat ) { + ULONG bufsize; + unsigned char alignment = pFormat[1] + 1; DWORD esize = *(const WORD*)(pFormat+2); TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); @@ -2018,21 +3056,18 @@ unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStu pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0); pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0); - NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount); - pStubMsg->Buffer += 4; - NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset); - pStubMsg->Buffer += 4; - NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount); - pStubMsg->Buffer += 4; + WriteConformance(pStubMsg); + WriteVariance(pStubMsg); + + ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment); + + bufsize = safe_multiply(esize, pStubMsg->ActualCount); - memcpy(pStubMsg->Buffer, pMemory + pStubMsg->Offset, pStubMsg->ActualCount*esize); pStubMsg->BufferMark = pStubMsg->Buffer; - pStubMsg->Buffer += pStubMsg->ActualCount*esize; + safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize); EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat); - STD_OVERFLOW_CHECK(pStubMsg); - return NULL; } @@ -2045,7 +3080,11 @@ unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pS PFORMAT_STRING pFormat, unsigned char fMustAlloc ) { + 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); @@ -2055,15 +3094,24 @@ unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pS RpcRaiseException(RPC_S_INTERNAL_ERROR); return NULL; } - pFormat = ReadConformance(pStubMsg, pFormat); - pFormat = ReadVariance(pStubMsg, pFormat); + + pFormat = ReadConformance(pStubMsg, pFormat+4); + pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount); + + ALIGN_POINTER(pStubMsg->Buffer, alignment); + + bufsize = safe_multiply(esize, pStubMsg->ActualCount); + memsize = safe_multiply(esize, pStubMsg->MaxCount); + offset = pStubMsg->Offset; if (!*ppMemory || fMustAlloc) - *ppMemory = NdrAllocate(pStubMsg, pStubMsg->MaxCount * esize); - memcpy(*ppMemory + pStubMsg->Offset, pStubMsg->Buffer, pStubMsg->ActualCount * esize); - pStubMsg->Buffer += pStubMsg->ActualCount * esize; + *ppMemory = NdrAllocate(pStubMsg, memsize); + saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer; + safe_buffer_increment(pStubMsg, bufsize); - EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc); + EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc); + + memcpy(*ppMemory + offset, saved_buffer, bufsize); return NULL; } @@ -2076,7 +3124,19 @@ void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat ) { - FIXME( "stub\n" ); + TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); + + if (pFormat[0] != RPC_FC_CVARRAY) + { + ERR("invalid format type %x\n", pFormat[0]); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + return; + } + + pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0); + pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0); + + EmbeddedPointerFree(pStubMsg, pMemory, pFormat); } @@ -2086,6 +3146,7 @@ void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg, void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat ) { + unsigned char alignment = pFormat[1] + 1; DWORD esize = *(const WORD*)(pFormat+2); TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); @@ -2102,8 +3163,12 @@ void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg, /* compute length */ pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0); - /* conformance + offset + variance + array */ - pStubMsg->BufferLength += 3*sizeof(DWORD) + pStubMsg->ActualCount*esize; + SizeConformance(pStubMsg); + SizeVariance(pStubMsg); + + ALIGN_LENGTH(pStubMsg->BufferLength, alignment); + + safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount)); EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat); } @@ -2112,11 +3177,36 @@ void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg, /*********************************************************************** * NdrConformantVaryingArrayMemorySize [RPCRT4.@] */ -unsigned long WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg, - PFORMAT_STRING pFormat ) +ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg, + PFORMAT_STRING pFormat ) { - FIXME( "stub\n" ); - return 0; + ULONG bufsize, memsize; + unsigned char alignment = pFormat[1] + 1; + DWORD esize = *(const WORD*)(pFormat+2); + + TRACE("(%p, %p)\n", pStubMsg, pFormat); + + if (pFormat[0] != RPC_FC_CVARRAY) + { + ERR("invalid format type %x\n", pFormat[0]); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + return pStubMsg->MemorySize; + } + + pFormat = ReadConformance(pStubMsg, pFormat+4); + pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount); + + ALIGN_POINTER(pStubMsg->Buffer, alignment); + + bufsize = safe_multiply(esize, pStubMsg->ActualCount); + memsize = safe_multiply(esize, pStubMsg->MaxCount); + + safe_buffer_increment(pStubMsg, bufsize); + pStubMsg->MemorySize += memsize; + + EmbeddedPointerMemorySize(pStubMsg, pFormat); + + return pStubMsg->MemorySize; } @@ -2127,8 +3217,10 @@ unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat) { - ULONG count, def; + ULONG i, count, def; BOOL variance_present; + unsigned char alignment; + int pointer_buffer_mark_set = 0; TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); @@ -2139,6 +3231,37 @@ unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg, return NULL; } + alignment = pFormat[1] + 1; + + if (!pStubMsg->PointerBufferMark) + { + /* save buffer fields that may be changed by buffer sizer functions + * and that may be needed later on */ + int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers; + unsigned long saved_buffer_length = pStubMsg->BufferLength; + unsigned long saved_max_count = pStubMsg->MaxCount; + unsigned long saved_offset = pStubMsg->Offset; + unsigned long saved_actual_count = pStubMsg->ActualCount; + + /* get the buffer pointer after complex array data, but before + * pointer data */ + pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart; + pStubMsg->IgnoreEmbeddedPointers = 1; + NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat); + pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded; + + /* save it for use by embedded pointer code later */ + pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength; + TRACE("difference = 0x%x\n", pStubMsg->Buffer - pStubMsg->BufferStart); + pointer_buffer_mark_set = 1; + + /* restore fields */ + pStubMsg->ActualCount = saved_actual_count; + pStubMsg->Offset = saved_offset; + pStubMsg->MaxCount = saved_max_count; + pStubMsg->BufferLength = saved_buffer_length; + } + def = *(const WORD*)&pFormat[2]; pFormat += 4; @@ -2147,23 +3270,26 @@ unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg, variance_present = IsConformanceOrVariancePresent(pFormat); pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount); - TRACE("variance = %ld\n", pStubMsg->ActualCount); + TRACE("variance = %d\n", pStubMsg->ActualCount); - NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount); - pStubMsg->Buffer += 4; + WriteConformance(pStubMsg); if (variance_present) - { - NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset); - pStubMsg->Buffer += 4; - NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount); - pStubMsg->Buffer += 4; - } + WriteVariance(pStubMsg); - for (count = 0; count < pStubMsg->ActualCount; count++) + ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment); + + count = pStubMsg->ActualCount; + for (i = 0; i < count; i++) pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL); STD_OVERFLOW_CHECK(pStubMsg); + if (pointer_buffer_mark_set) + { + pStubMsg->Buffer = pStubMsg->PointerBufferMark; + pStubMsg->PointerBufferMark = NULL; + } + return NULL; } @@ -2175,8 +3301,12 @@ unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, unsigned char fMustAlloc) { - ULONG count, esize; + ULONG i, count, size; + unsigned char alignment; unsigned char *pMemory; + unsigned char *saved_buffer; + int pointer_buffer_mark_set = 0; + int saved_ignore_embedded; TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); @@ -2187,22 +3317,52 @@ unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, return NULL; } + alignment = pFormat[1] + 1; + + saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers; + /* save buffer pointer */ + saved_buffer = pStubMsg->Buffer; + /* get the buffer pointer after complex array data, but before + * pointer data */ + pStubMsg->IgnoreEmbeddedPointers = 1; + pStubMsg->MemorySize = 0; + NdrComplexArrayMemorySize(pStubMsg, pFormat); + size = pStubMsg->MemorySize; + pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded; + + TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->Buffer - saved_buffer)); + if (!pStubMsg->PointerBufferMark) + { + /* save it for use by embedded pointer code later */ + pStubMsg->PointerBufferMark = pStubMsg->Buffer; + pointer_buffer_mark_set = 1; + } + /* restore the original buffer */ + pStubMsg->Buffer = saved_buffer; + pFormat += 4; pFormat = ReadConformance(pStubMsg, pFormat); - pFormat = ReadVariance(pStubMsg, pFormat); - - esize = ComplexStructSize(pStubMsg, pFormat); + pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount); if (fMustAlloc || !*ppMemory) { - *ppMemory = NdrAllocate(pStubMsg, pStubMsg->MaxCount * esize); - memset(*ppMemory, 0, pStubMsg->MaxCount * esize); + *ppMemory = NdrAllocate(pStubMsg, size); + memset(*ppMemory, 0, size); } + ALIGN_POINTER(pStubMsg->Buffer, alignment); + pMemory = *ppMemory; - for (count = 0; count < pStubMsg->ActualCount; count++) - pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL, fMustAlloc); + count = pStubMsg->ActualCount; + for (i = 0; i < count; i++) + pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL); + + if (pointer_buffer_mark_set) + { + pStubMsg->Buffer = pStubMsg->PointerBufferMark; + pStubMsg->PointerBufferMark = NULL; + } return NULL; } @@ -2214,8 +3374,10 @@ void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat) { - ULONG count, def; + ULONG i, count, def; + unsigned char alignment; BOOL variance_present; + int pointer_length_set = 0; TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); @@ -2226,32 +3388,72 @@ void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, return; } + alignment = pFormat[1] + 1; + + if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength) + { + /* save buffer fields that may be changed by buffer sizer functions + * and that may be needed later on */ + int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers; + unsigned long saved_buffer_length = pStubMsg->BufferLength; + unsigned long saved_max_count = pStubMsg->MaxCount; + unsigned long saved_offset = pStubMsg->Offset; + unsigned long saved_actual_count = pStubMsg->ActualCount; + + /* get the buffer pointer after complex array data, but before + * pointer data */ + pStubMsg->IgnoreEmbeddedPointers = 1; + NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat); + pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded; + + /* save it for use by embedded pointer code later */ + pStubMsg->PointerLength = pStubMsg->BufferLength; + pointer_length_set = 1; + + /* restore fields */ + pStubMsg->ActualCount = saved_actual_count; + pStubMsg->Offset = saved_offset; + pStubMsg->MaxCount = saved_max_count; + pStubMsg->BufferLength = saved_buffer_length; + } def = *(const WORD*)&pFormat[2]; pFormat += 4; pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def); TRACE("conformance = %ld\n", pStubMsg->MaxCount); - pStubMsg->BufferLength += sizeof(ULONG); + SizeConformance(pStubMsg); variance_present = IsConformanceOrVariancePresent(pFormat); pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount); - TRACE("variance = %ld\n", pStubMsg->ActualCount); + TRACE("variance = %d\n", pStubMsg->ActualCount); if (variance_present) - pStubMsg->BufferLength += 2*sizeof(ULONG); + SizeVariance(pStubMsg); - for (count=0; count < pStubMsg->ActualCount; count++) + ALIGN_LENGTH(pStubMsg->BufferLength, alignment); + + count = pStubMsg->ActualCount; + for (i = 0; i < count; i++) pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL); + + if(pointer_length_set) + { + pStubMsg->BufferLength = pStubMsg->PointerLength; + pStubMsg->PointerLength = 0; + } } /*********************************************************************** * NdrComplexArrayMemorySize [RPCRT4.@] */ -unsigned long WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg, - PFORMAT_STRING pFormat) +ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg, + PFORMAT_STRING pFormat) { - DWORD size = 0; - FIXME("(%p,%p): stub\n", pStubMsg, pFormat); + ULONG i, count, esize, SavedMemorySize, MemorySize; + unsigned char alignment; + unsigned char *Buffer; + + TRACE("(%p,%p)\n", pStubMsg, pFormat); if (pFormat[0] != RPC_FC_BOGUS_ARRAY) { @@ -2260,15 +3462,32 @@ unsigned long WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg, return 0; } + alignment = pFormat[1] + 1; + pFormat += 4; pFormat = ReadConformance(pStubMsg, pFormat); - size = pStubMsg->MaxCount; - TRACE("conformance=%ld\n", size); + pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount); - pFormat += 4; + ALIGN_POINTER(pStubMsg->Buffer, alignment); - return 0; + SavedMemorySize = pStubMsg->MemorySize; + + Buffer = pStubMsg->Buffer; + pStubMsg->MemorySize = 0; + esize = ComplexStructMemorySize(pStubMsg, pFormat); + pStubMsg->Buffer = Buffer; + + MemorySize = safe_multiply(pStubMsg->MaxCount, esize); + + count = pStubMsg->ActualCount; + for (i = 0; i < count; i++) + ComplexStructMemorySize(pStubMsg, pFormat); + + pStubMsg->MemorySize = SavedMemorySize; + + pStubMsg->MemorySize += MemorySize; + return MemorySize; } /*********************************************************************** @@ -2278,7 +3497,7 @@ void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat) { - ULONG count, def; + ULONG i, count, def; TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); @@ -2296,18 +3515,31 @@ void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg, TRACE("conformance = %ld\n", pStubMsg->MaxCount); pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount); - TRACE("variance = %ld\n", pStubMsg->ActualCount); + TRACE("variance = %d\n", pStubMsg->ActualCount); - for (count=0; count < pStubMsg->ActualCount; count++) + count = pStubMsg->ActualCount; + for (i = 0; i < count; i++) pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL); } -unsigned long UserMarshalFlags(PMIDL_STUB_MESSAGE pStubMsg) +static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg, + USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat, + USER_MARSHAL_CB *umcb) { - return MAKELONG(pStubMsg->dwDestContext, - pStubMsg->RpcMsg->DataRepresentation); + umcb->Flags = MAKELONG(pStubMsg->dwDestContext, + pStubMsg->RpcMsg->DataRepresentation); + umcb->pStubMsg = pStubMsg; + umcb->pReserve = NULL; + umcb->Signature = USER_MARSHAL_CB_SIGNATURE; + umcb->CBType = cbtype; + umcb->pFormat = pFormat; + umcb->pTypeFormat = NULL /* FIXME */; } +#define USER_MARSHAL_PTR_PREFIX \ + ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \ + ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) ) + /*********************************************************************** * NdrUserMarshalMarshall [RPCRT4.@] */ @@ -2315,15 +3547,42 @@ unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat) { -/* unsigned flags = pFormat[1]; */ + unsigned flags = pFormat[1]; unsigned index = *(const WORD*)&pFormat[2]; - unsigned long uflag = UserMarshalFlags(pStubMsg); + unsigned char *saved_buffer = NULL; + USER_MARSHAL_CB umcb; + TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); TRACE("index=%d\n", index); + UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb); + + if (flags & USER_MARSHAL_POINTER) + { + ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4); + NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX); + pStubMsg->Buffer += 4; + if (pStubMsg->PointerBufferMark) + { + saved_buffer = pStubMsg->Buffer; + pStubMsg->Buffer = pStubMsg->PointerBufferMark; + pStubMsg->PointerBufferMark = NULL; + } + ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 8); + } + else + ALIGN_POINTER_CLEAR(pStubMsg->Buffer, (flags & 0xf) + 1); + pStubMsg->Buffer = pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall( - &uflag, pStubMsg->Buffer, pMemory); + &umcb.Flags, pStubMsg->Buffer, pMemory); + + if (saved_buffer) + { + STD_OVERFLOW_CHECK(pStubMsg); + pStubMsg->PointerBufferMark = pStubMsg->Buffer; + pStubMsg->Buffer = saved_buffer; + } STD_OVERFLOW_CHECK(pStubMsg); @@ -2338,19 +3597,46 @@ unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, unsigned char fMustAlloc) { -/* unsigned flags = pFormat[1];*/ + unsigned flags = pFormat[1]; unsigned index = *(const WORD*)&pFormat[2]; DWORD memsize = *(const WORD*)&pFormat[4]; - unsigned long uflag = UserMarshalFlags(pStubMsg); + unsigned char *saved_buffer = NULL; + USER_MARSHAL_CB umcb; + TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); TRACE("index=%d\n", index); + UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb); + + if (flags & USER_MARSHAL_POINTER) + { + ALIGN_POINTER(pStubMsg->Buffer, 4); + /* skip pointer prefix */ + pStubMsg->Buffer += 4; + if (pStubMsg->PointerBufferMark) + { + saved_buffer = pStubMsg->Buffer; + pStubMsg->Buffer = pStubMsg->PointerBufferMark; + pStubMsg->PointerBufferMark = NULL; + } + ALIGN_POINTER(pStubMsg->Buffer, 8); + } + else + ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1); + if (fMustAlloc || !*ppMemory) *ppMemory = NdrAllocate(pStubMsg, memsize); pStubMsg->Buffer = pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall( - &uflag, pStubMsg->Buffer, *ppMemory); + &umcb.Flags, pStubMsg->Buffer, *ppMemory); + + if (saved_buffer) + { + STD_OVERFLOW_CHECK(pStubMsg); + pStubMsg->PointerBufferMark = pStubMsg->Buffer; + pStubMsg->Buffer = saved_buffer; + } return NULL; } @@ -2362,36 +3648,86 @@ void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat) { -/* unsigned flags = pFormat[1];*/ + unsigned flags = pFormat[1]; unsigned index = *(const WORD*)&pFormat[2]; DWORD bufsize = *(const WORD*)&pFormat[6]; - unsigned long uflag = UserMarshalFlags(pStubMsg); + USER_MARSHAL_CB umcb; + unsigned long saved_buffer_length = 0; + TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); TRACE("index=%d\n", index); + UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb); + + if (flags & USER_MARSHAL_POINTER) + { + ALIGN_LENGTH(pStubMsg->BufferLength, 4); + /* skip pointer prefix */ + safe_buffer_length_increment(pStubMsg, 4); + if (pStubMsg->IgnoreEmbeddedPointers) + return; + if (pStubMsg->PointerLength) + { + saved_buffer_length = pStubMsg->BufferLength; + pStubMsg->BufferLength = pStubMsg->PointerLength; + pStubMsg->PointerLength = 0; + } + ALIGN_LENGTH(pStubMsg->BufferLength, 8); + } + else + ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1); + if (bufsize) { - TRACE("size=%ld\n", bufsize); - pStubMsg->BufferLength += bufsize; - return; + TRACE("size=%d\n", bufsize); + safe_buffer_length_increment(pStubMsg, bufsize); + } + else + pStubMsg->BufferLength = + pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize( + &umcb.Flags, pStubMsg->BufferLength, pMemory); + + if (saved_buffer_length) + { + pStubMsg->PointerLength = pStubMsg->BufferLength; + pStubMsg->BufferLength = saved_buffer_length; } - pStubMsg->BufferLength = - pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize( - &uflag, pStubMsg->BufferLength, pMemory); } /*********************************************************************** * NdrUserMarshalMemorySize [RPCRT4.@] */ -unsigned long WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg, - PFORMAT_STRING pFormat) +ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg, + PFORMAT_STRING pFormat) { + unsigned flags = pFormat[1]; unsigned index = *(const WORD*)&pFormat[2]; -/* DWORD memsize = *(const WORD*)&pFormat[4]; */ - FIXME("(%p,%p): stub\n", pStubMsg, pFormat); + DWORD memsize = *(const WORD*)&pFormat[4]; + DWORD bufsize = *(const WORD*)&pFormat[6]; + + TRACE("(%p,%p)\n", pStubMsg, pFormat); TRACE("index=%d\n", index); - return 0; + pStubMsg->MemorySize += memsize; + + if (flags & USER_MARSHAL_POINTER) + { + ALIGN_POINTER(pStubMsg->Buffer, 4); + /* skip pointer prefix */ + pStubMsg->Buffer += 4; + if (pStubMsg->IgnoreEmbeddedPointers) + return pStubMsg->MemorySize; + ALIGN_POINTER(pStubMsg->Buffer, 8); + } + else + ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1); + + if (!bufsize) + FIXME("not implemented for varying buffer size\n"); + + pStubMsg->Buffer += bufsize; + + return pStubMsg->MemorySize; } /*********************************************************************** @@ -2403,12 +3739,15 @@ void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg, { /* unsigned flags = pFormat[1]; */ unsigned index = *(const WORD*)&pFormat[2]; - unsigned long uflag = UserMarshalFlags(pStubMsg); + USER_MARSHAL_CB umcb; + TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); TRACE("index=%d\n", index); + UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb); + pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree( - &uflag, pMemory); + &umcb.Flags, pMemory); } /*********************************************************************** @@ -2434,21 +3773,23 @@ void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat ) /*********************************************************************** * NdrConvert2 [RPCRT4.@] */ -void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, long NumberParams ) +void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams ) { - FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %ld): stub.\n", + FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n", pStubMsg, pFormat, NumberParams); /* FIXME: since this stub doesn't do any converting, the proper behavior is to raise an exception */ } +#include "pshpack1.h" typedef struct _NDR_CSTRUCT_FORMAT { unsigned char type; unsigned char alignment; unsigned short memory_size; short offset_to_array_description; -} NDR_CSTRUCT_FORMAT; +} NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT; +#include "poppack.h" /*********************************************************************** * NdrConformantStructMarshall [RPCRT4.@] @@ -2457,11 +3798,13 @@ unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat) { - const NDR_CSTRUCT_FORMAT * pCStructFormat = (NDR_CSTRUCT_FORMAT*)pFormat; - pFormat += sizeof(NDR_CSTRUCT_FORMAT); + const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat; + PFORMAT_STRING pCArrayFormat; + ULONG esize, bufsize; TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); + pFormat += sizeof(NDR_CSTRUCT_FORMAT); if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT)) { ERR("invalid format type %x\n", pCStructFormat->type); @@ -2469,20 +3812,39 @@ unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg, return NULL; } + pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description + + pCStructFormat->offset_to_array_description; + if (*pCArrayFormat != RPC_FC_CARRAY) + { + ERR("invalid array format type %x\n", pCStructFormat->type); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + return NULL; + } + esize = *(const WORD*)(pCArrayFormat+2); + + ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, + pCArrayFormat + 4, 0); + + WriteConformance(pStubMsg); + + ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCStructFormat->alignment + 1); + TRACE("memory_size = %d\n", pCStructFormat->memory_size); - /* copy constant sized part of struct */ - memcpy(pStubMsg->Buffer, pMemory, pCStructFormat->memory_size); - pStubMsg->Buffer += pCStructFormat->memory_size; - - if (pCStructFormat->offset_to_array_description) + bufsize = safe_multiply(esize, pStubMsg->MaxCount); + if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */ { - PFORMAT_STRING pArrayFormat = (unsigned char*)&pCStructFormat->offset_to_array_description + - pCStructFormat->offset_to_array_description; - NdrConformantArrayMarshall(pStubMsg, pMemory + pCStructFormat->memory_size, pArrayFormat); + ERR("integer overflow of memory_size %u with bufsize %u\n", + pCStructFormat->memory_size, bufsize); + RpcRaiseException(RPC_X_BAD_STUB_DATA); } + /* copy constant sized part of struct */ + pStubMsg->BufferMark = pStubMsg->Buffer; + safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize); + if (pCStructFormat->type == RPC_FC_CPSTRUCT) EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat); + return NULL; } @@ -2494,52 +3856,65 @@ unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMs PFORMAT_STRING pFormat, unsigned char fMustAlloc) { - const NDR_CSTRUCT_FORMAT * pCStructFormat = (NDR_CSTRUCT_FORMAT*)pFormat; - pFormat += sizeof(NDR_CSTRUCT_FORMAT); + const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat; + PFORMAT_STRING pCArrayFormat; + ULONG esize, bufsize; + unsigned char *saved_buffer; TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); + pFormat += sizeof(NDR_CSTRUCT_FORMAT); if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT)) { ERR("invalid format type %x\n", pCStructFormat->type); RpcRaiseException(RPC_S_INTERNAL_ERROR); return NULL; } + pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description + + pCStructFormat->offset_to_array_description; + if (*pCArrayFormat != RPC_FC_CARRAY) + { + ERR("invalid array format type %x\n", pCStructFormat->type); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + return NULL; + } + esize = *(const WORD*)(pCArrayFormat+2); + + pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4); + + ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1); TRACE("memory_size = %d\n", pCStructFormat->memory_size); - /* work out how much memory to allocate if we need to do so */ - if (!*ppMemory || fMustAlloc) + bufsize = safe_multiply(esize, pStubMsg->MaxCount); + if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */ { - SIZE_T size = pCStructFormat->memory_size; - - if (pCStructFormat->offset_to_array_description) - { - unsigned char *buffer; - PFORMAT_STRING pArrayFormat = (unsigned char*)&pCStructFormat->offset_to_array_description + - pCStructFormat->offset_to_array_description; - buffer = pStubMsg->Buffer; - pStubMsg->Buffer += pCStructFormat->memory_size; - size += NdrConformantArrayMemorySize(pStubMsg, pArrayFormat); - pStubMsg->Buffer = buffer; - } - *ppMemory = NdrAllocate(pStubMsg, size); + ERR("integer overflow of memory_size %u with bufsize %u\n", + pCStructFormat->memory_size, bufsize); + RpcRaiseException(RPC_X_BAD_STUB_DATA); } - /* now copy the data */ - memcpy(*ppMemory, pStubMsg->Buffer, pCStructFormat->memory_size); - pStubMsg->Buffer += pCStructFormat->memory_size; - if (pCStructFormat->offset_to_array_description) + if (fMustAlloc) { - PFORMAT_STRING pArrayFormat = (unsigned char*)&pCStructFormat->offset_to_array_description + - pCStructFormat->offset_to_array_description; - unsigned char *pMemoryArray = *ppMemory + pCStructFormat->memory_size; - /* note that we pass fMustAlloc as 0 as we have already allocated the - * memory */ - NdrConformantArrayUnmarshall(pStubMsg, &pMemoryArray, pArrayFormat, 0); + SIZE_T size = pCStructFormat->memory_size + bufsize; + *ppMemory = NdrAllocate(pStubMsg, size); } + else + { + if (!pStubMsg->IsClient && !*ppMemory) + /* for servers, we just point straight into the RPC buffer */ + *ppMemory = pStubMsg->Buffer; + } + + saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer; + safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize); if (pCStructFormat->type == RPC_FC_CPSTRUCT) - EmbeddedPointerUnmarshall(pStubMsg, ppMemory, pFormat, fMustAlloc); + EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc); + + TRACE("copying %p to %p\n", saved_buffer, *ppMemory); + if (*ppMemory != saved_buffer) + memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize); + return NULL; } @@ -2550,28 +3925,39 @@ void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat) { - const NDR_CSTRUCT_FORMAT * pCStructFormat = (NDR_CSTRUCT_FORMAT*)pFormat; - pFormat += sizeof(NDR_CSTRUCT_FORMAT); + const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat; + PFORMAT_STRING pCArrayFormat; + ULONG esize; + TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); + pFormat += sizeof(NDR_CSTRUCT_FORMAT); if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT)) { ERR("invalid format type %x\n", pCStructFormat->type); RpcRaiseException(RPC_S_INTERNAL_ERROR); return; } + pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description + + pCStructFormat->offset_to_array_description; + if (*pCArrayFormat != RPC_FC_CARRAY) + { + ERR("invalid array format type %x\n", pCStructFormat->type); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + return; + } + esize = *(const WORD*)(pCArrayFormat+2); + + pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0); + SizeConformance(pStubMsg); + + ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1); TRACE("memory_size = %d\n", pCStructFormat->memory_size); - /* add constant sized part of struct to buffer size */ - pStubMsg->BufferLength += pCStructFormat->memory_size; + safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size); + safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize)); - if (pCStructFormat->offset_to_array_description) - { - PFORMAT_STRING pArrayFormat = (unsigned char*)&pCStructFormat->offset_to_array_description + - pCStructFormat->offset_to_array_description; - NdrConformantArrayBufferSize(pStubMsg, pMemory + pCStructFormat->memory_size, pArrayFormat); - } if (pCStructFormat->type == RPC_FC_CPSTRUCT) EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat); } @@ -2579,7 +3965,7 @@ void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, /*********************************************************************** * NdrConformantStructMemorySize [RPCRT4.@] */ -unsigned long WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg, +ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat) { FIXME("stub\n"); @@ -2593,7 +3979,40 @@ void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat) { - FIXME("stub\n"); + const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat; + PFORMAT_STRING pCArrayFormat; + ULONG esize; + + TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); + + pFormat += sizeof(NDR_CSTRUCT_FORMAT); + if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT)) + { + ERR("invalid format type %x\n", pCStructFormat->type); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + return; + } + + pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description + + pCStructFormat->offset_to_array_description; + if (*pCArrayFormat != RPC_FC_CARRAY) + { + ERR("invalid array format type %x\n", pCStructFormat->type); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + return; + } + esize = *(const WORD*)(pCArrayFormat+2); + + ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, + pCArrayFormat + 4, 0); + + TRACE("memory_size = %d\n", pCStructFormat->memory_size); + + /* copy constant sized part of struct */ + pStubMsg->BufferMark = pStubMsg->Buffer; + + if (pCStructFormat->type == RPC_FC_CPSTRUCT) + EmbeddedPointerFree(pStubMsg, pMemory, pFormat); } /*********************************************************************** @@ -2603,7 +4022,77 @@ unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pS unsigned char *pMemory, PFORMAT_STRING pFormat) { - FIXME("stub\n"); + const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat; + PFORMAT_STRING pCVArrayFormat; + ULONG esize, bufsize; + + TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); + + pFormat += sizeof(NDR_CVSTRUCT_FORMAT); + if (pCVStructFormat->type != RPC_FC_CVSTRUCT) + { + ERR("invalid format type %x\n", pCVStructFormat->type); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + return NULL; + } + + pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description + + pCVStructFormat->offset_to_array_description; + switch (*pCVArrayFormat) + { + case RPC_FC_CVARRAY: + esize = *(const WORD*)(pCVArrayFormat+2); + + pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size, + pCVArrayFormat + 4, 0); + pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size, + pCVArrayFormat, 0); + break; + case RPC_FC_C_CSTRING: + TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size)); + pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1; + esize = sizeof(char); + if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED) + pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size, + pCVArrayFormat + 2, 0); + else + pStubMsg->MaxCount = pStubMsg->ActualCount; + break; + case RPC_FC_C_WSTRING: + TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size)); + pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1; + esize = sizeof(WCHAR); + if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED) + pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size, + pCVArrayFormat + 2, 0); + else + pStubMsg->MaxCount = pStubMsg->ActualCount; + break; + default: + ERR("invalid array format type %x\n", *pCVArrayFormat); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + return NULL; + } + + WriteConformance(pStubMsg); + + ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCVStructFormat->alignment + 1); + + TRACE("memory_size = %d\n", pCVStructFormat->memory_size); + + /* write constant sized part */ + pStubMsg->BufferMark = pStubMsg->Buffer; + safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size); + + WriteVariance(pStubMsg); + + bufsize = safe_multiply(esize, pStubMsg->ActualCount); + + /* write array part */ + safe_copy_to_buffer(pStubMsg, pMemory + pCVStructFormat->memory_size, bufsize); + + EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat); + return NULL; } @@ -2615,7 +4104,100 @@ unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE PFORMAT_STRING pFormat, unsigned char fMustAlloc) { - FIXME("stub\n"); + const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat; + PFORMAT_STRING pCVArrayFormat; + ULONG esize, bufsize; + unsigned char cvarray_type; + + TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); + + pFormat += sizeof(NDR_CVSTRUCT_FORMAT); + if (pCVStructFormat->type != RPC_FC_CVSTRUCT) + { + ERR("invalid format type %x\n", pCVStructFormat->type); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + return NULL; + } + + pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description + + pCVStructFormat->offset_to_array_description; + cvarray_type = *pCVArrayFormat; + switch (cvarray_type) + { + case RPC_FC_CVARRAY: + esize = *(const WORD*)(pCVArrayFormat+2); + pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4); + break; + case RPC_FC_C_CSTRING: + esize = sizeof(char); + if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED) + pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2); + else + pCVArrayFormat = ReadConformance(pStubMsg, NULL); + break; + case RPC_FC_C_WSTRING: + esize = sizeof(WCHAR); + if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED) + pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2); + else + pCVArrayFormat = ReadConformance(pStubMsg, NULL); + break; + default: + ERR("invalid array format type %x\n", *pCVArrayFormat); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + return NULL; + } + + ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1); + + TRACE("memory_size = %d\n", pCVStructFormat->memory_size); + + /* work out how much memory to allocate if we need to do so */ + if (!*ppMemory || fMustAlloc) + { + SIZE_T size = pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount); + *ppMemory = NdrAllocate(pStubMsg, size); + } + + /* copy the constant data */ + pStubMsg->BufferMark = pStubMsg->Buffer; + safe_copy_from_buffer(pStubMsg, *ppMemory, pCVStructFormat->memory_size); + + pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount); + + bufsize = safe_multiply(esize, pStubMsg->ActualCount); + + if ((cvarray_type == RPC_FC_C_CSTRING) || + (cvarray_type == RPC_FC_C_WSTRING)) + { + ULONG i; + /* strings must always have null terminating bytes */ + if (bufsize < esize) + { + ERR("invalid string length of %d\n", pStubMsg->ActualCount); + RpcRaiseException(RPC_S_INVALID_BOUND); + return NULL; + } + for (i = bufsize - esize; i < bufsize; i++) + if (pStubMsg->Buffer[i] != 0) + { + ERR("string not null-terminated at byte position %d, data is 0x%x\n", + i, pStubMsg->Buffer[i]); + RpcRaiseException(RPC_S_INVALID_BOUND); + return NULL; + } + } + + /* copy the array data */ + safe_copy_from_buffer(pStubMsg, *ppMemory + pCVStructFormat->memory_size, bufsize); + + if (cvarray_type == RPC_FC_C_CSTRING) + TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size))); + else if (cvarray_type == RPC_FC_C_WSTRING) + TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size))); + + EmbeddedPointerUnmarshall(pStubMsg, *ppMemory, *ppMemory, pFormat, TRUE /* FIXME */); + return NULL; } @@ -2626,17 +4208,134 @@ void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat) { - FIXME("stub\n"); + const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat; + PFORMAT_STRING pCVArrayFormat; + ULONG esize; + + TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); + + pFormat += sizeof(NDR_CVSTRUCT_FORMAT); + if (pCVStructFormat->type != RPC_FC_CVSTRUCT) + { + ERR("invalid format type %x\n", pCVStructFormat->type); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + return; + } + + pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description + + pCVStructFormat->offset_to_array_description; + switch (*pCVArrayFormat) + { + case RPC_FC_CVARRAY: + esize = *(const WORD*)(pCVArrayFormat+2); + + pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size, + pCVArrayFormat + 4, 0); + pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size, + pCVArrayFormat, 0); + break; + case RPC_FC_C_CSTRING: + TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size)); + pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1; + esize = sizeof(char); + if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED) + pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size, + pCVArrayFormat + 2, 0); + else + pStubMsg->MaxCount = pStubMsg->ActualCount; + break; + case RPC_FC_C_WSTRING: + TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size)); + pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1; + esize = sizeof(WCHAR); + if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED) + pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size, + pCVArrayFormat + 2, 0); + else + pStubMsg->MaxCount = pStubMsg->ActualCount; + break; + default: + ERR("invalid array format type %x\n", *pCVArrayFormat); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + return; + } + + SizeConformance(pStubMsg); + + ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1); + + TRACE("memory_size = %d\n", pCVStructFormat->memory_size); + + safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size); + SizeVariance(pStubMsg); + safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize)); + + EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat); } /*********************************************************************** * NdrConformantVaryingStructMemorySize [RPCRT4.@] */ -unsigned long WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg, +ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat) { - FIXME("stub\n"); - return 0; + const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat; + PFORMAT_STRING pCVArrayFormat; + ULONG esize; + unsigned char cvarray_type; + + TRACE("(%p, %p)\n", pStubMsg, pFormat); + + pFormat += sizeof(NDR_CVSTRUCT_FORMAT); + if (pCVStructFormat->type != RPC_FC_CVSTRUCT) + { + ERR("invalid format type %x\n", pCVStructFormat->type); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + return 0; + } + + pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description + + pCVStructFormat->offset_to_array_description; + cvarray_type = *pCVArrayFormat; + switch (cvarray_type) + { + case RPC_FC_CVARRAY: + esize = *(const WORD*)(pCVArrayFormat+2); + pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4); + break; + case RPC_FC_C_CSTRING: + esize = sizeof(char); + if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED) + pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2); + else + pCVArrayFormat = ReadConformance(pStubMsg, NULL); + break; + case RPC_FC_C_WSTRING: + esize = sizeof(WCHAR); + if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED) + pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2); + else + pCVArrayFormat = ReadConformance(pStubMsg, NULL); + break; + default: + ERR("invalid array format type %x\n", *pCVArrayFormat); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + return 0; + } + + ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1); + + TRACE("memory_size = %d\n", pCVStructFormat->memory_size); + + safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size); + pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount); + safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount)); + + pStubMsg->MemorySize += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount); + + EmbeddedPointerMemorySize(pStubMsg, pFormat); + + return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize; } /*********************************************************************** @@ -2646,9 +4345,79 @@ void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat) { - FIXME("stub\n"); + const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat; + PFORMAT_STRING pCVArrayFormat; + ULONG esize; + + TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); + + pFormat += sizeof(NDR_CVSTRUCT_FORMAT); + if (pCVStructFormat->type != RPC_FC_CVSTRUCT) + { + ERR("invalid format type %x\n", pCVStructFormat->type); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + return; + } + + pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description + + pCVStructFormat->offset_to_array_description; + switch (*pCVArrayFormat) + { + case RPC_FC_CVARRAY: + esize = *(const WORD*)(pCVArrayFormat+2); + + pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size, + pCVArrayFormat + 4, 0); + pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size, + pCVArrayFormat, 0); + break; + case RPC_FC_C_CSTRING: + TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size)); + pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1; + esize = sizeof(char); + if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED) + pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size, + pCVArrayFormat + 2, 0); + else + pStubMsg->MaxCount = pStubMsg->ActualCount; + break; + case RPC_FC_C_WSTRING: + TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size)); + pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1; + esize = sizeof(WCHAR); + if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED) + pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size, + pCVArrayFormat + 2, 0); + else + pStubMsg->MaxCount = pStubMsg->ActualCount; + break; + default: + ERR("invalid array format type %x\n", *pCVArrayFormat); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + return; + } + + TRACE("memory_size = %d\n", pCVStructFormat->memory_size); + + EmbeddedPointerFree(pStubMsg, pMemory, pFormat); } +#include "pshpack1.h" +typedef struct +{ + unsigned char type; + unsigned char alignment; + unsigned short total_size; +} NDR_SMFARRAY_FORMAT; + +typedef struct +{ + unsigned char type; + unsigned char alignment; + unsigned long total_size; +} NDR_LGFARRAY_FORMAT; +#include "poppack.h" + /*********************************************************************** * NdrFixedArrayMarshall [RPCRT4.@] */ @@ -2656,7 +4425,38 @@ unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat) { - FIXME("stub\n"); + const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat; + unsigned long total_size; + + TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); + + if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) && + (pSmFArrayFormat->type != RPC_FC_LGFARRAY)) + { + ERR("invalid format type %x\n", pSmFArrayFormat->type); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + return NULL; + } + + ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1); + + if (pSmFArrayFormat->type == RPC_FC_SMFARRAY) + { + total_size = pSmFArrayFormat->total_size; + pFormat = (const unsigned char *)(pSmFArrayFormat + 1); + } + else + { + const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat; + total_size = pLgFArrayFormat->total_size; + pFormat = (const unsigned char *)(pLgFArrayFormat + 1); + } + + pStubMsg->BufferMark = pStubMsg->Buffer; + safe_copy_to_buffer(pStubMsg, pMemory, total_size); + + pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat); + return NULL; } @@ -2668,7 +4468,51 @@ unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, unsigned char fMustAlloc) { - FIXME("stub\n"); + const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat; + unsigned long total_size; + unsigned char *saved_buffer; + + TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); + + if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) && + (pSmFArrayFormat->type != RPC_FC_LGFARRAY)) + { + ERR("invalid format type %x\n", pSmFArrayFormat->type); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + return NULL; + } + + ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1); + + if (pSmFArrayFormat->type == RPC_FC_SMFARRAY) + { + total_size = pSmFArrayFormat->total_size; + pFormat = (const unsigned char *)(pSmFArrayFormat + 1); + } + else + { + const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat; + total_size = pLgFArrayFormat->total_size; + pFormat = (const unsigned char *)(pLgFArrayFormat + 1); + } + + if (fMustAlloc) + *ppMemory = NdrAllocate(pStubMsg, total_size); + else + { + if (!pStubMsg->IsClient && !*ppMemory) + /* for servers, we just point straight into the RPC buffer */ + *ppMemory = pStubMsg->Buffer; + } + + saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer; + safe_buffer_increment(pStubMsg, total_size); + pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc); + + TRACE("copying %p to %p\n", saved_buffer, *ppMemory); + if (*ppMemory != saved_buffer) + memcpy(*ppMemory, saved_buffer, total_size); + return NULL; } @@ -2679,17 +4523,76 @@ void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat) { - FIXME("stub\n"); + const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat; + unsigned long total_size; + + TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); + + if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) && + (pSmFArrayFormat->type != RPC_FC_LGFARRAY)) + { + ERR("invalid format type %x\n", pSmFArrayFormat->type); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + return; + } + + ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1); + + if (pSmFArrayFormat->type == RPC_FC_SMFARRAY) + { + total_size = pSmFArrayFormat->total_size; + pFormat = (const unsigned char *)(pSmFArrayFormat + 1); + } + else + { + const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat; + total_size = pLgFArrayFormat->total_size; + pFormat = (const unsigned char *)(pLgFArrayFormat + 1); + } + safe_buffer_length_increment(pStubMsg, total_size); + + EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat); } /*********************************************************************** * NdrFixedArrayMemorySize [RPCRT4.@] */ -unsigned long WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg, +ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat) { - FIXME("stub\n"); - return 0; + const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat; + ULONG total_size; + + TRACE("(%p, %p)\n", pStubMsg, pFormat); + + if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) && + (pSmFArrayFormat->type != RPC_FC_LGFARRAY)) + { + ERR("invalid format type %x\n", pSmFArrayFormat->type); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + return 0; + } + + ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1); + + if (pSmFArrayFormat->type == RPC_FC_SMFARRAY) + { + total_size = pSmFArrayFormat->total_size; + pFormat = (const unsigned char *)(pSmFArrayFormat + 1); + } + else + { + const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat; + total_size = pLgFArrayFormat->total_size; + pFormat = (const unsigned char *)(pLgFArrayFormat + 1); + } + pStubMsg->BufferMark = pStubMsg->Buffer; + safe_buffer_increment(pStubMsg, total_size); + pStubMsg->MemorySize += total_size; + + EmbeddedPointerMemorySize(pStubMsg, pFormat); + + return total_size; } /*********************************************************************** @@ -2699,7 +4602,27 @@ void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat) { - FIXME("stub\n"); + const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat; + + TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); + + if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) && + (pSmFArrayFormat->type != RPC_FC_LGFARRAY)) + { + ERR("invalid format type %x\n", pSmFArrayFormat->type); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + return; + } + + if (pSmFArrayFormat->type == RPC_FC_SMFARRAY) + pFormat = (const unsigned char *)(pSmFArrayFormat + 1); + else + { + const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat; + pFormat = (const unsigned char *)(pLgFArrayFormat + 1); + } + + EmbeddedPointerFree(pStubMsg, pMemory, pFormat); } /*********************************************************************** @@ -2709,7 +4632,58 @@ unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat) { - FIXME("stub\n"); + unsigned char alignment; + DWORD elements, esize; + ULONG bufsize; + + TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); + + if ((pFormat[0] != RPC_FC_SMVARRAY) && + (pFormat[0] != RPC_FC_LGVARRAY)) + { + ERR("invalid format type %x\n", pFormat[0]); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + return NULL; + } + + alignment = pFormat[1] + 1; + + if (pFormat[0] == RPC_FC_SMVARRAY) + { + pFormat += 2; + pFormat += sizeof(WORD); + elements = *(const WORD*)pFormat; + pFormat += sizeof(WORD); + } + else + { + pFormat += 2; + pFormat += sizeof(DWORD); + elements = *(const DWORD*)pFormat; + pFormat += sizeof(DWORD); + } + + esize = *(const WORD*)pFormat; + pFormat += sizeof(WORD); + + pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0); + if ((pStubMsg->ActualCount > elements) || + (pStubMsg->ActualCount + pStubMsg->Offset > elements)) + { + RpcRaiseException(RPC_S_INVALID_BOUND); + return NULL; + } + + WriteVariance(pStubMsg); + + ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment); + + bufsize = safe_multiply(esize, pStubMsg->ActualCount); + pStubMsg->BufferMark = pStubMsg->Buffer; + safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize); + + EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat); + return NULL; } @@ -2721,7 +4695,60 @@ unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, unsigned char fMustAlloc) { - FIXME("stub\n"); + 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); + + if ((pFormat[0] != RPC_FC_SMVARRAY) && + (pFormat[0] != RPC_FC_LGVARRAY)) + { + ERR("invalid format type %x\n", pFormat[0]); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + return NULL; + } + + alignment = pFormat[1] + 1; + + if (pFormat[0] == RPC_FC_SMVARRAY) + { + pFormat += 2; + size = *(const WORD*)pFormat; + pFormat += sizeof(WORD); + elements = *(const WORD*)pFormat; + pFormat += sizeof(WORD); + } + else + { + pFormat += 2; + size = *(const DWORD*)pFormat; + pFormat += sizeof(DWORD); + elements = *(const DWORD*)pFormat; + pFormat += sizeof(DWORD); + } + + esize = *(const WORD*)pFormat; + pFormat += sizeof(WORD); + + pFormat = ReadVariance(pStubMsg, pFormat, elements); + + ALIGN_POINTER(pStubMsg->Buffer, alignment); + + bufsize = safe_multiply(esize, pStubMsg->ActualCount); + offset = pStubMsg->Offset; + + if (!*ppMemory || fMustAlloc) + *ppMemory = NdrAllocate(pStubMsg, size); + saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer; + safe_buffer_increment(pStubMsg, bufsize); + + EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc); + + memcpy(*ppMemory + offset, saved_buffer, bufsize); + return NULL; } @@ -2732,17 +4759,107 @@ void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat) { - FIXME("stub\n"); + unsigned char alignment; + DWORD elements, esize; + + TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); + + if ((pFormat[0] != RPC_FC_SMVARRAY) && + (pFormat[0] != RPC_FC_LGVARRAY)) + { + ERR("invalid format type %x\n", pFormat[0]); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + return; + } + + alignment = pFormat[1] + 1; + + if (pFormat[0] == RPC_FC_SMVARRAY) + { + pFormat += 2; + pFormat += sizeof(WORD); + elements = *(const WORD*)pFormat; + pFormat += sizeof(WORD); + } + else + { + pFormat += 2; + pFormat += sizeof(DWORD); + elements = *(const DWORD*)pFormat; + pFormat += sizeof(DWORD); + } + + esize = *(const WORD*)pFormat; + pFormat += sizeof(WORD); + + pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0); + if ((pStubMsg->ActualCount > elements) || + (pStubMsg->ActualCount + pStubMsg->Offset > elements)) + { + RpcRaiseException(RPC_S_INVALID_BOUND); + return; + } + + SizeVariance(pStubMsg); + + ALIGN_LENGTH(pStubMsg->BufferLength, alignment); + + safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount)); + + EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat); } /*********************************************************************** * NdrVaryingArrayMemorySize [RPCRT4.@] */ -unsigned long WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg, +ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat) { - FIXME("stub\n"); - return 0; + unsigned char alignment; + DWORD size, elements, esize; + + TRACE("(%p, %p)\n", pStubMsg, pFormat); + + if ((pFormat[0] != RPC_FC_SMVARRAY) && + (pFormat[0] != RPC_FC_LGVARRAY)) + { + ERR("invalid format type %x\n", pFormat[0]); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + return 0; + } + + alignment = pFormat[1] + 1; + + if (pFormat[0] == RPC_FC_SMVARRAY) + { + pFormat += 2; + size = *(const WORD*)pFormat; + pFormat += sizeof(WORD); + elements = *(const WORD*)pFormat; + pFormat += sizeof(WORD); + } + else + { + pFormat += 2; + size = *(const DWORD*)pFormat; + pFormat += sizeof(DWORD); + elements = *(const DWORD*)pFormat; + pFormat += sizeof(DWORD); + } + + esize = *(const WORD*)pFormat; + pFormat += sizeof(WORD); + + pFormat = ReadVariance(pStubMsg, pFormat, elements); + + ALIGN_POINTER(pStubMsg->Buffer, alignment); + + safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount)); + pStubMsg->MemorySize += size; + + EmbeddedPointerMemorySize(pStubMsg, pFormat); + + return pStubMsg->MemorySize; } /*********************************************************************** @@ -2752,7 +4869,382 @@ void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat) { - FIXME("stub\n"); + unsigned char alignment; + DWORD elements; + + TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); + + if ((pFormat[0] != RPC_FC_SMVARRAY) && + (pFormat[0] != RPC_FC_LGVARRAY)) + { + ERR("invalid format type %x\n", pFormat[0]); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + return; + } + + alignment = pFormat[1] + 1; + + if (pFormat[0] == RPC_FC_SMVARRAY) + { + pFormat += 2; + pFormat += sizeof(WORD); + elements = *(const WORD*)pFormat; + pFormat += sizeof(WORD); + } + else + { + pFormat += 2; + pFormat += sizeof(DWORD); + elements = *(const DWORD*)pFormat; + pFormat += sizeof(DWORD); + } + + pFormat += sizeof(WORD); + + pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0); + if ((pStubMsg->ActualCount > elements) || + (pStubMsg->ActualCount + pStubMsg->Offset > elements)) + { + RpcRaiseException(RPC_S_INVALID_BOUND); + return; + } + + EmbeddedPointerFree(pStubMsg, pMemory, pFormat); +} + +static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory) +{ + switch (fc) + { + case RPC_FC_BYTE: + case RPC_FC_CHAR: + case RPC_FC_SMALL: + case RPC_FC_USMALL: + return *(const UCHAR *)pMemory; + case RPC_FC_WCHAR: + case RPC_FC_SHORT: + case RPC_FC_USHORT: + case RPC_FC_ENUM16: + return *(const USHORT *)pMemory; + case RPC_FC_LONG: + case RPC_FC_ULONG: + case RPC_FC_ENUM32: + return *(const ULONG *)pMemory; + default: + FIXME("Unhandled base type: 0x%02x\n", fc); + return 0; + } +} + +static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg, + unsigned long discriminant, + PFORMAT_STRING pFormat) +{ + unsigned short num_arms, arm, type; + + num_arms = *(const SHORT*)pFormat & 0x0fff; + pFormat += 2; + for(arm = 0; arm < num_arms; arm++) + { + if(discriminant == *(const ULONG*)pFormat) + { + pFormat += 4; + break; + } + pFormat += 6; + } + + type = *(const unsigned short*)pFormat; + TRACE("type %04x\n", type); + if(arm == num_arms) /* default arm extras */ + { + if(type == 0xffff) + { + ERR("no arm for 0x%lx and no default case\n", discriminant); + RpcRaiseException(RPC_S_INVALID_TAG); + return NULL; + } + if(type == 0) + { + TRACE("falling back to empty default case for 0x%lx\n", discriminant); + return NULL; + } + } + return pFormat; +} + +static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat) +{ + unsigned short type; + + pFormat += 2; + + pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat); + if(!pFormat) + return NULL; + + type = *(const unsigned short*)pFormat; + if((type & 0xff00) == 0x8000) + { + unsigned char basetype = LOBYTE(type); + return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype); + } + else + { + PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat; + NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK]; + if (m) + { + unsigned char *saved_buffer = NULL; + int pointer_buffer_mark_set = 0; + switch(*desc) + { + case RPC_FC_RP: + case RPC_FC_UP: + case RPC_FC_OP: + case RPC_FC_FP: + ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4); + saved_buffer = pStubMsg->Buffer; + if (pStubMsg->PointerBufferMark) + { + pStubMsg->Buffer = pStubMsg->PointerBufferMark; + pStubMsg->PointerBufferMark = NULL; + pointer_buffer_mark_set = 1; + } + else + safe_buffer_increment(pStubMsg, 4); /* for pointer ID */ + + PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc); + if (pointer_buffer_mark_set) + { + STD_OVERFLOW_CHECK(pStubMsg); + pStubMsg->PointerBufferMark = pStubMsg->Buffer; + if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) + { + ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n", + saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } + pStubMsg->Buffer = saved_buffer + 4; + } + break; + default: + m(pStubMsg, pMemory, desc); + } + } + else FIXME("no marshaller for embedded type %02x\n", *desc); + } + return NULL; +} + +static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg, + unsigned char **ppMemory, + ULONG discriminant, + PFORMAT_STRING pFormat, + unsigned char fMustAlloc) +{ + unsigned short type; + + pFormat += 2; + + pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat); + if(!pFormat) + return NULL; + + type = *(const unsigned short*)pFormat; + if((type & 0xff00) == 0x8000) + { + unsigned char basetype = LOBYTE(type); + return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE); + } + else + { + PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat; + NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK]; + if (m) + { + unsigned char *saved_buffer = NULL; + int pointer_buffer_mark_set = 0; + switch(*desc) + { + case RPC_FC_RP: + case RPC_FC_UP: + case RPC_FC_OP: + case RPC_FC_FP: + **(void***)ppMemory = NULL; + ALIGN_POINTER(pStubMsg->Buffer, 4); + saved_buffer = pStubMsg->Buffer; + if (pStubMsg->PointerBufferMark) + { + pStubMsg->Buffer = pStubMsg->PointerBufferMark; + pStubMsg->PointerBufferMark = NULL; + pointer_buffer_mark_set = 1; + } + else + pStubMsg->Buffer += 4; /* for pointer ID */ + + if (saved_buffer + 4 > pStubMsg->BufferEnd) + { + ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n", + saved_buffer, pStubMsg->BufferEnd); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } + + PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc); + if (pointer_buffer_mark_set) + { + STD_OVERFLOW_CHECK(pStubMsg); + pStubMsg->PointerBufferMark = pStubMsg->Buffer; + pStubMsg->Buffer = saved_buffer + 4; + } + break; + default: + m(pStubMsg, ppMemory, desc, fMustAlloc); + } + } + else FIXME("no marshaller for embedded type %02x\n", *desc); + } + return NULL; +} + +static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg, + unsigned char *pMemory, + ULONG discriminant, + PFORMAT_STRING pFormat) +{ + unsigned short type; + + pFormat += 2; + + pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat); + if(!pFormat) + return; + + type = *(const unsigned short*)pFormat; + if((type & 0xff00) == 0x8000) + { + unsigned char basetype = LOBYTE(type); + NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype); + } + else + { + PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat; + NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK]; + if (m) + { + switch(*desc) + { + case RPC_FC_RP: + case RPC_FC_UP: + case RPC_FC_OP: + case RPC_FC_FP: + ALIGN_LENGTH(pStubMsg->BufferLength, 4); + safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */ + if (!pStubMsg->IgnoreEmbeddedPointers) + { + int saved_buffer_length = pStubMsg->BufferLength; + pStubMsg->BufferLength = pStubMsg->PointerLength; + pStubMsg->PointerLength = 0; + if(!pStubMsg->BufferLength) + ERR("BufferLength == 0??\n"); + PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc); + pStubMsg->PointerLength = pStubMsg->BufferLength; + pStubMsg->BufferLength = saved_buffer_length; + } + break; + default: + m(pStubMsg, pMemory, desc); + } + } + else FIXME("no buffersizer for embedded type %02x\n", *desc); + } +} + +static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg, + ULONG discriminant, + PFORMAT_STRING pFormat) +{ + unsigned short type, size; + + size = *(const unsigned short*)pFormat; + pStubMsg->Memory += size; + pFormat += 2; + + pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat); + if(!pFormat) + return 0; + + type = *(const unsigned short*)pFormat; + if((type & 0xff00) == 0x8000) + { + return NdrBaseTypeMemorySize(pStubMsg, pFormat); + } + else + { + PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat; + NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK]; + unsigned char *saved_buffer; + if (m) + { + switch(*desc) + { + case RPC_FC_RP: + case RPC_FC_UP: + case RPC_FC_OP: + case RPC_FC_FP: + ALIGN_POINTER(pStubMsg->Buffer, 4); + saved_buffer = pStubMsg->Buffer; + safe_buffer_increment(pStubMsg, 4); + ALIGN_LENGTH(pStubMsg->MemorySize, 4); + pStubMsg->MemorySize += 4; + if (!pStubMsg->IgnoreEmbeddedPointers) + PointerMemorySize(pStubMsg, saved_buffer, pFormat); + break; + default: + return m(pStubMsg, desc); + } + } + else FIXME("no marshaller for embedded type %02x\n", *desc); + } + + TRACE("size %d\n", size); + return size; +} + +static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg, + unsigned char *pMemory, + ULONG discriminant, + PFORMAT_STRING pFormat) +{ + unsigned short type; + + pFormat += 2; + + pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat); + if(!pFormat) + return; + + type = *(const unsigned short*)pFormat; + if((type & 0xff00) != 0x8000) + { + PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat; + NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK]; + if (m) + { + switch(*desc) + { + case RPC_FC_RP: + case RPC_FC_UP: + case RPC_FC_OP: + case RPC_FC_FP: + PointerFree(pStubMsg, *(unsigned char **)pMemory, desc); + break; + default: + m(pStubMsg, pMemory, desc); + } + } + else FIXME("no freer for embedded type %02x\n", *desc); + } } /*********************************************************************** @@ -2762,8 +5254,26 @@ unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg unsigned char *pMemory, PFORMAT_STRING pFormat) { - FIXME("stub\n"); - return NULL; + unsigned char switch_type; + unsigned char increment; + ULONG switch_value; + + TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); + pFormat++; + + switch_type = *pFormat & 0xf; + increment = (*pFormat & 0xf0) >> 4; + pFormat++; + + ALIGN_POINTER_CLEAR(pStubMsg->Buffer, increment); + + switch_value = get_discriminant(switch_type, pMemory); + TRACE("got switch value 0x%x\n", switch_value); + + NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type); + pMemory += increment; + + return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat); } /*********************************************************************** @@ -2774,8 +5284,31 @@ unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubM PFORMAT_STRING pFormat, unsigned char fMustAlloc) { - FIXME("stub\n"); - return NULL; + unsigned char switch_type; + unsigned char increment; + ULONG switch_value; + unsigned short size; + unsigned char *pMemoryArm; + + TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); + pFormat++; + + switch_type = *pFormat & 0xf; + increment = (*pFormat & 0xf0) >> 4; + pFormat++; + + ALIGN_POINTER(pStubMsg->Buffer, increment); + switch_value = get_discriminant(switch_type, pStubMsg->Buffer); + TRACE("got switch value 0x%x\n", switch_value); + + size = *(const unsigned short*)pFormat + increment; + if(!*ppMemory || fMustAlloc) + *ppMemory = NdrAllocate(pStubMsg, size); + + NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE); + pMemoryArm = *ppMemory + increment; + + return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, fMustAlloc); } /*********************************************************************** @@ -2785,17 +5318,49 @@ void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat) { - FIXME("stub\n"); + unsigned char switch_type; + unsigned char increment; + ULONG switch_value; + + TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); + pFormat++; + + switch_type = *pFormat & 0xf; + increment = (*pFormat & 0xf0) >> 4; + pFormat++; + + ALIGN_LENGTH(pStubMsg->BufferLength, increment); + switch_value = get_discriminant(switch_type, pMemory); + TRACE("got switch value 0x%x\n", switch_value); + + /* Add discriminant size */ + NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type); + pMemory += increment; + + union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat); } /*********************************************************************** * NdrEncapsulatedUnionMemorySize [RPCRT4.@] */ -unsigned long WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg, +ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat) { - FIXME("stub\n"); - return 0; + unsigned char switch_type; + unsigned char increment; + ULONG switch_value; + + switch_type = *pFormat & 0xf; + increment = (*pFormat & 0xf0) >> 4; + pFormat++; + + ALIGN_POINTER(pStubMsg->Buffer, increment); + switch_value = get_discriminant(switch_type, pStubMsg->Buffer); + TRACE("got switch value 0x%x\n", switch_value); + + pStubMsg->Memory += increment; + + return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat); } /*********************************************************************** @@ -2805,7 +5370,23 @@ void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat) { - FIXME("stub\n"); + unsigned char switch_type; + unsigned char increment; + ULONG switch_value; + + TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); + pFormat++; + + switch_type = *pFormat & 0xf; + increment = (*pFormat & 0xf0) >> 4; + pFormat++; + + switch_value = get_discriminant(switch_type, pMemory); + TRACE("got switch value 0x%x\n", switch_value); + + pMemory += increment; + + return union_arm_free(pStubMsg, pMemory, switch_value, pFormat); } /*********************************************************************** @@ -2815,11 +5396,71 @@ unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStub unsigned char *pMemory, PFORMAT_STRING pFormat) { - FIXME("stub\n"); - return NULL; + unsigned char switch_type; + + TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); + pFormat++; + + switch_type = *pFormat; + pFormat++; + + pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0); + TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount); + /* Marshall discriminant */ + NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type); + + return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat); } -/*********************************************************************** +static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg, + PFORMAT_STRING *ppFormat) +{ + long discriminant = 0; + + switch(**ppFormat) + { + case RPC_FC_BYTE: + case RPC_FC_CHAR: + case RPC_FC_SMALL: + case RPC_FC_USMALL: + { + UCHAR d; + safe_copy_from_buffer(pStubMsg, &d, sizeof(d)); + discriminant = d; + break; + } + case RPC_FC_WCHAR: + case RPC_FC_SHORT: + case RPC_FC_USHORT: + { + USHORT d; + ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT)); + safe_copy_from_buffer(pStubMsg, &d, sizeof(d)); + discriminant = d; + break; + } + case RPC_FC_LONG: + case RPC_FC_ULONG: + { + ULONG d; + ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG)); + safe_copy_from_buffer(pStubMsg, &d, sizeof(d)); + discriminant = d; + break; + } + default: + FIXME("Unhandled base type: 0x%02x\n", **ppFormat); + } + (*ppFormat)++; + + if (pStubMsg->fHasNewCorrDesc) + *ppFormat += 6; + else + *ppFormat += 4; + return discriminant; +} + +/********************************************************************** * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@] */ unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, @@ -2827,8 +5468,24 @@ unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pSt PFORMAT_STRING pFormat, unsigned char fMustAlloc) { - FIXME("stub\n"); - return NULL; + long discriminant; + unsigned short size; + + TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); + pFormat++; + + /* Unmarshall discriminant */ + discriminant = unmarshall_discriminant(pStubMsg, &pFormat); + TRACE("unmarshalled discriminant %lx\n", discriminant); + + pFormat += *(const SHORT*)pFormat; + + size = *(const unsigned short*)pFormat; + + if(!*ppMemory || fMustAlloc) + *ppMemory = NdrAllocate(pStubMsg, size); + + return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, fMustAlloc); } /*********************************************************************** @@ -2838,17 +5495,36 @@ void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat) { - FIXME("stub\n"); + unsigned char switch_type; + + TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); + pFormat++; + + switch_type = *pFormat; + pFormat++; + + pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0); + TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount); + /* Add discriminant size */ + NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type); + + union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat); } /*********************************************************************** * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@] */ -unsigned long WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg, +ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat) { - FIXME("stub\n"); - return 0; + ULONG discriminant; + + pFormat++; + /* Unmarshall discriminant */ + discriminant = unmarshall_discriminant(pStubMsg, &pFormat); + TRACE("unmarshalled discriminant 0x%x\n", discriminant); + + return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat); } /*********************************************************************** @@ -2858,7 +5534,14 @@ void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat) { - FIXME("stub\n"); + TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); + pFormat++; + pFormat++; + + pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0); + TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount); + + return union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat); } /*********************************************************************** @@ -2897,7 +5580,7 @@ void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, /*********************************************************************** * NdrByteCountPointerMemorySize [RPCRT4.@] */ -unsigned long WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg, +ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat) { FIXME("stub\n"); @@ -2950,7 +5633,7 @@ void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg, /*********************************************************************** * NdrXmitOrRepAsMemorySize [RPCRT4.@] */ -unsigned long WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg, +ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat) { FIXME("stub\n"); @@ -2967,6 +5650,193 @@ void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg, FIXME("stub\n"); } +#include "pshpack1.h" +typedef struct +{ + unsigned char type; + unsigned char flags_type; /* flags in upper nibble, type in lower nibble */ + ULONG low_value; + ULONG high_value; +} NDR_RANGE; +#include "poppack.h" + +/*********************************************************************** + * NdrRangeMarshall [internal] + */ +unsigned char *WINAPI NdrRangeMarshall( + PMIDL_STUB_MESSAGE pStubMsg, + unsigned char *pMemory, + PFORMAT_STRING pFormat) +{ + NDR_RANGE *pRange = (NDR_RANGE *)pFormat; + unsigned char base_type; + + TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat); + + if (pRange->type != RPC_FC_RANGE) + { + ERR("invalid format type %x\n", pRange->type); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + return NULL; + } + + base_type = pRange->flags_type & 0xf; + + return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type); +} + +/*********************************************************************** + * NdrRangeUnmarshall + */ +unsigned char *WINAPI NdrRangeUnmarshall( + PMIDL_STUB_MESSAGE pStubMsg, + unsigned char **ppMemory, + PFORMAT_STRING pFormat, + unsigned char fMustAlloc) +{ + NDR_RANGE *pRange = (NDR_RANGE *)pFormat; + unsigned char base_type; + + TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false"); + + if (pRange->type != RPC_FC_RANGE) + { + ERR("invalid format type %x\n", pRange->type); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + return NULL; + } + base_type = pRange->flags_type & 0xf; + + TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n", + base_type, pRange->low_value, pRange->high_value); + +#define RANGE_UNMARSHALL(type, format_spec) \ + do \ + { \ + ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \ + if (fMustAlloc || !*ppMemory) \ + *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \ + if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \ + { \ + ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \ + pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \ + RpcRaiseException(RPC_X_BAD_STUB_DATA); \ + } \ + if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \ + (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \ + { \ + ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \ + *(type *)pStubMsg->Buffer, (type)pRange->low_value, \ + (type)pRange->high_value); \ + RpcRaiseException(RPC_S_INVALID_BOUND); \ + return NULL; \ + } \ + TRACE("*ppMemory: %p\n", *ppMemory); \ + **(type **)ppMemory = *(type *)pStubMsg->Buffer; \ + pStubMsg->Buffer += sizeof(type); \ + } while (0) + + switch(base_type) + { + case RPC_FC_CHAR: + case RPC_FC_SMALL: + RANGE_UNMARSHALL(UCHAR, "%d"); + TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory); + break; + case RPC_FC_BYTE: + case RPC_FC_USMALL: + RANGE_UNMARSHALL(CHAR, "%u"); + TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory); + break; + case RPC_FC_WCHAR: /* FIXME: valid? */ + case RPC_FC_USHORT: + RANGE_UNMARSHALL(USHORT, "%u"); + TRACE("value: 0x%04x\n", **(USHORT **)ppMemory); + break; + case RPC_FC_SHORT: + RANGE_UNMARSHALL(SHORT, "%d"); + TRACE("value: 0x%04x\n", **(USHORT **)ppMemory); + break; + case RPC_FC_LONG: + RANGE_UNMARSHALL(LONG, "%d"); + TRACE("value: 0x%08x\n", **(ULONG **)ppMemory); + break; + case RPC_FC_ULONG: + RANGE_UNMARSHALL(ULONG, "%u"); + TRACE("value: 0x%08x\n", **(ULONG **)ppMemory); + break; + case RPC_FC_ENUM16: + case RPC_FC_ENUM32: + FIXME("Unhandled enum type\n"); + break; + case RPC_FC_ERROR_STATUS_T: /* FIXME: valid? */ + case RPC_FC_FLOAT: + case RPC_FC_DOUBLE: + case RPC_FC_HYPER: + default: + ERR("invalid range base type: 0x%02x\n", base_type); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + } + + return NULL; +} + +/*********************************************************************** + * NdrRangeBufferSize [internal] + */ +void WINAPI NdrRangeBufferSize( + PMIDL_STUB_MESSAGE pStubMsg, + unsigned char *pMemory, + PFORMAT_STRING pFormat) +{ + NDR_RANGE *pRange = (NDR_RANGE *)pFormat; + unsigned char base_type; + + TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat); + + if (pRange->type != RPC_FC_RANGE) + { + ERR("invalid format type %x\n", pRange->type); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + } + base_type = pRange->flags_type & 0xf; + + NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type); +} + +/*********************************************************************** + * NdrRangeMemorySize [internal] + */ +ULONG WINAPI NdrRangeMemorySize( + PMIDL_STUB_MESSAGE pStubMsg, + PFORMAT_STRING pFormat) +{ + NDR_RANGE *pRange = (NDR_RANGE *)pFormat; + unsigned char base_type; + + if (pRange->type != RPC_FC_RANGE) + { + ERR("invalid format type %x\n", pRange->type); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + return 0; + } + base_type = pRange->flags_type & 0xf; + + return NdrBaseTypeMemorySize(pStubMsg, &base_type); +} + +/*********************************************************************** + * NdrRangeFree [internal] + */ +void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg, + unsigned char *pMemory, + PFORMAT_STRING pFormat) +{ + TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat); + + /* nothing to do */ +} + /*********************************************************************** * NdrBaseTypeMarshall [internal] */ @@ -2983,58 +5853,54 @@ static unsigned char *WINAPI NdrBaseTypeMarshall( case RPC_FC_CHAR: case RPC_FC_SMALL: case RPC_FC_USMALL: - *(UCHAR *)pStubMsg->Buffer = *(UCHAR *)pMemory; - pStubMsg->Buffer += sizeof(UCHAR); + safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR)); TRACE("value: 0x%02x\n", *(UCHAR *)pMemory); break; case RPC_FC_WCHAR: case RPC_FC_SHORT: case RPC_FC_USHORT: - ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT) - 1); - *(USHORT *)pStubMsg->Buffer = *(USHORT *)pMemory; - pStubMsg->Buffer += sizeof(USHORT); + ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT)); + safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT)); TRACE("value: 0x%04x\n", *(USHORT *)pMemory); break; case RPC_FC_LONG: case RPC_FC_ULONG: case RPC_FC_ERROR_STATUS_T: case RPC_FC_ENUM32: - ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG) - 1); - *(ULONG *)pStubMsg->Buffer = *(ULONG *)pMemory; - pStubMsg->Buffer += sizeof(ULONG); - TRACE("value: 0x%08lx\n", *(ULONG *)pMemory); + ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONG)); + safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG)); + TRACE("value: 0x%08x\n", *(ULONG *)pMemory); break; case RPC_FC_FLOAT: - ALIGN_POINTER(pStubMsg->Buffer, sizeof(float) - 1); - *(float *)pStubMsg->Buffer = *(float *)pMemory; - pStubMsg->Buffer += sizeof(float); + ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(float)); + safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float)); break; case RPC_FC_DOUBLE: - ALIGN_POINTER(pStubMsg->Buffer, sizeof(double) - 1); - *(double *)pStubMsg->Buffer = *(double *)pMemory; - pStubMsg->Buffer += sizeof(double); + ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(double)); + safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double)); break; case RPC_FC_HYPER: - ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONGLONG) - 1); - *(ULONGLONG *)pStubMsg->Buffer = *(ULONGLONG *)pMemory; - pStubMsg->Buffer += sizeof(ULONGLONG); + ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONGLONG)); + safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG)); TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory)); break; case RPC_FC_ENUM16: /* only 16-bits on the wire, so do a sanity check */ - if (*(UINT *)pMemory > USHRT_MAX) + if (*(UINT *)pMemory > SHRT_MAX) RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE); - ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT) - 1); + ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT)); + if (pStubMsg->Buffer + sizeof(USHORT) > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) + RpcRaiseException(RPC_X_BAD_STUB_DATA); *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory; pStubMsg->Buffer += sizeof(USHORT); TRACE("value: 0x%04x\n", *(UINT *)pMemory); break; + case RPC_FC_IGNORE: + break; default: FIXME("Unhandled base type: 0x%02x\n", *pFormat); } - STD_OVERFLOW_CHECK(pStubMsg); - /* FIXME: what is the correct return value? */ return NULL; } @@ -3050,10 +5916,21 @@ static unsigned char *WINAPI NdrBaseTypeUnmarshall( { TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false"); - if (fMustAlloc || !*ppMemory) - *ppMemory = NdrAllocate(pStubMsg, NdrBaseTypeMemorySize(pStubMsg, pFormat)); - - TRACE("*ppMemory: %p\n", *ppMemory); +#define BASE_TYPE_UNMARSHALL(type) \ + ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \ + if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \ + { \ + *ppMemory = pStubMsg->Buffer; \ + TRACE("*ppMemory: %p\n", *ppMemory); \ + } \ + else \ + { \ + if (fMustAlloc) \ + *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \ + TRACE("*ppMemory: %p\n", *ppMemory); \ + **(type **)ppMemory = *(type *)pStubMsg->Buffer; \ + } \ + pStubMsg->Buffer += sizeof(type); switch(*pFormat) { @@ -3061,55 +5938,52 @@ static unsigned char *WINAPI NdrBaseTypeUnmarshall( case RPC_FC_CHAR: case RPC_FC_SMALL: case RPC_FC_USMALL: - **(UCHAR **)ppMemory = *(UCHAR *)pStubMsg->Buffer; - pStubMsg->Buffer += sizeof(UCHAR); + BASE_TYPE_UNMARSHALL(UCHAR); TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory); break; case RPC_FC_WCHAR: case RPC_FC_SHORT: case RPC_FC_USHORT: - ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT) - 1); - **(USHORT **)ppMemory = *(USHORT *)pStubMsg->Buffer; - pStubMsg->Buffer += sizeof(USHORT); + BASE_TYPE_UNMARSHALL(USHORT); TRACE("value: 0x%04x\n", **(USHORT **)ppMemory); break; case RPC_FC_LONG: case RPC_FC_ULONG: case RPC_FC_ERROR_STATUS_T: case RPC_FC_ENUM32: - ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG) - 1); - **(ULONG **)ppMemory = *(ULONG *)pStubMsg->Buffer; - pStubMsg->Buffer += sizeof(ULONG); - TRACE("value: 0x%08lx\n", **(ULONG **)ppMemory); + BASE_TYPE_UNMARSHALL(ULONG); + TRACE("value: 0x%08x\n", **(ULONG **)ppMemory); break; case RPC_FC_FLOAT: - ALIGN_POINTER(pStubMsg->Buffer, sizeof(float) - 1); - **(float **)ppMemory = *(float *)pStubMsg->Buffer; - pStubMsg->Buffer += sizeof(float); + BASE_TYPE_UNMARSHALL(float); TRACE("value: %f\n", **(float **)ppMemory); break; case RPC_FC_DOUBLE: - ALIGN_POINTER(pStubMsg->Buffer, sizeof(double) - 1); - **(double **)ppMemory = *(double*)pStubMsg->Buffer; - pStubMsg->Buffer += sizeof(double); + BASE_TYPE_UNMARSHALL(double); TRACE("value: %f\n", **(double **)ppMemory); break; case RPC_FC_HYPER: - ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONGLONG) - 1); - **(ULONGLONG **)ppMemory = *(ULONGLONG *)pStubMsg->Buffer; - pStubMsg->Buffer += sizeof(ULONGLONG); + BASE_TYPE_UNMARSHALL(ULONGLONG); TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory)); break; case RPC_FC_ENUM16: - ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT) - 1); + ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT)); + if (fMustAlloc || !*ppMemory) + *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT)); + if (pStubMsg->Buffer + sizeof(USHORT) > pStubMsg->BufferEnd) + RpcRaiseException(RPC_X_BAD_STUB_DATA); + TRACE("*ppMemory: %p\n", *ppMemory); /* 16-bits on the wire, but int in memory */ **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer; pStubMsg->Buffer += sizeof(USHORT); TRACE("value: 0x%08x\n", **(UINT **)ppMemory); break; + case RPC_FC_IGNORE: + break; default: FIXME("Unhandled base type: 0x%02x\n", *pFormat); } +#undef BASE_TYPE_UNMARSHALL /* FIXME: what is the correct return value? */ @@ -3132,36 +6006,38 @@ static void WINAPI NdrBaseTypeBufferSize( case RPC_FC_CHAR: case RPC_FC_SMALL: case RPC_FC_USMALL: - pStubMsg->BufferLength += sizeof(UCHAR); + safe_buffer_length_increment(pStubMsg, sizeof(UCHAR)); break; case RPC_FC_WCHAR: case RPC_FC_SHORT: case RPC_FC_USHORT: case RPC_FC_ENUM16: - ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT) - 1); - pStubMsg->BufferLength += sizeof(USHORT); + ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT)); + safe_buffer_length_increment(pStubMsg, sizeof(USHORT)); break; case RPC_FC_LONG: case RPC_FC_ULONG: case RPC_FC_ENUM32: - ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG) - 1); - pStubMsg->BufferLength += sizeof(ULONG); + ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG)); + safe_buffer_length_increment(pStubMsg, sizeof(ULONG)); break; case RPC_FC_FLOAT: - ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float) - 1); - pStubMsg->BufferLength += sizeof(float); + ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float)); + safe_buffer_length_increment(pStubMsg, sizeof(float)); break; case RPC_FC_DOUBLE: - ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double) - 1); - pStubMsg->BufferLength += sizeof(double); + ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double)); + safe_buffer_length_increment(pStubMsg, sizeof(double)); break; case RPC_FC_HYPER: - ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG) - 1); - pStubMsg->BufferLength += sizeof(ULONGLONG); + ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG)); + safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG)); break; case RPC_FC_ERROR_STATUS_T: - ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t) - 1); - pStubMsg->BufferLength += sizeof(error_status_t); + ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t)); + safe_buffer_length_increment(pStubMsg, sizeof(error_status_t)); + break; + case RPC_FC_IGNORE: break; default: FIXME("Unhandled base type: 0x%02x\n", *pFormat); @@ -3171,35 +6047,56 @@ static void WINAPI NdrBaseTypeBufferSize( /*********************************************************************** * NdrBaseTypeMemorySize [internal] */ -static unsigned long WINAPI NdrBaseTypeMemorySize( +static ULONG WINAPI NdrBaseTypeMemorySize( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat) { + TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat); + switch(*pFormat) { case RPC_FC_BYTE: case RPC_FC_CHAR: case RPC_FC_SMALL: case RPC_FC_USMALL: + safe_buffer_increment(pStubMsg, sizeof(UCHAR)); + pStubMsg->MemorySize += sizeof(UCHAR); return sizeof(UCHAR); case RPC_FC_WCHAR: case RPC_FC_SHORT: case RPC_FC_USHORT: + safe_buffer_increment(pStubMsg, sizeof(USHORT)); + pStubMsg->MemorySize += sizeof(USHORT); return sizeof(USHORT); case RPC_FC_LONG: case RPC_FC_ULONG: + case RPC_FC_ENUM32: + safe_buffer_increment(pStubMsg, sizeof(ULONG)); + pStubMsg->MemorySize += sizeof(ULONG); return sizeof(ULONG); case RPC_FC_FLOAT: + safe_buffer_increment(pStubMsg, sizeof(float)); + pStubMsg->MemorySize += sizeof(float); return sizeof(float); case RPC_FC_DOUBLE: + safe_buffer_increment(pStubMsg, sizeof(double)); + pStubMsg->MemorySize += sizeof(double); return sizeof(double); case RPC_FC_HYPER: + safe_buffer_increment(pStubMsg, sizeof(ULONGLONG)); + pStubMsg->MemorySize += sizeof(ULONGLONG); return sizeof(ULONGLONG); case RPC_FC_ERROR_STATUS_T: + safe_buffer_increment(pStubMsg, sizeof(error_status_t)); + pStubMsg->MemorySize += sizeof(error_status_t); return sizeof(error_status_t); case RPC_FC_ENUM16: - case RPC_FC_ENUM32: - return sizeof(INT); + safe_buffer_increment(pStubMsg, sizeof(USHORT)); + pStubMsg->MemorySize += sizeof(UINT); + return sizeof(UINT); + case RPC_FC_IGNORE: + pStubMsg->MemorySize += sizeof(void *); + return sizeof(void *); default: FIXME("Unhandled base type: 0x%02x\n", *pFormat); return 0; @@ -3217,3 +6114,221 @@ static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg, /* nothing to do */ } + +/*********************************************************************** + * NdrContextHandleBufferSize [internal] + */ +static void WINAPI NdrContextHandleBufferSize( + PMIDL_STUB_MESSAGE pStubMsg, + unsigned char *pMemory, + PFORMAT_STRING pFormat) +{ + TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat); + + if (*pFormat != RPC_FC_BIND_CONTEXT) + { + ERR("invalid format type %x\n", *pFormat); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + } + ALIGN_LENGTH(pStubMsg->BufferLength, 4); + safe_buffer_length_increment(pStubMsg, cbNDRContext); +} + +/*********************************************************************** + * NdrContextHandleMarshall [internal] + */ +static unsigned char *WINAPI NdrContextHandleMarshall( + PMIDL_STUB_MESSAGE pStubMsg, + unsigned char *pMemory, + PFORMAT_STRING pFormat) +{ + TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat); + + if (*pFormat != RPC_FC_BIND_CONTEXT) + { + ERR("invalid format type %x\n", *pFormat); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + } + + if (pFormat[1] & 0x80) + NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE); + else + NdrClientContextMarshall(pStubMsg, (NDR_CCONTEXT *)pMemory, FALSE); + + return NULL; +} + +/*********************************************************************** + * NdrContextHandleUnmarshall [internal] + */ +static unsigned char *WINAPI NdrContextHandleUnmarshall( + PMIDL_STUB_MESSAGE pStubMsg, + unsigned char **ppMemory, + PFORMAT_STRING pFormat, + unsigned char fMustAlloc) +{ + if (*pFormat != RPC_FC_BIND_CONTEXT) + { + ERR("invalid format type %x\n", *pFormat); + RpcRaiseException(RPC_S_INTERNAL_ERROR); + } + + **(NDR_CCONTEXT **)ppMemory = NULL; + NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle); + + return NULL; +} + +/*********************************************************************** + * NdrClientContextMarshall [RPCRT4.@] + */ +void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg, + NDR_CCONTEXT ContextHandle, + int fCheck) +{ + TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck); + + ALIGN_POINTER_CLEAR(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); + } + + /* FIXME: what does fCheck do? */ + NDRCContextMarshall(ContextHandle, + pStubMsg->Buffer); + + pStubMsg->Buffer += cbNDRContext; +} + +/*********************************************************************** + * NdrClientContextUnmarshall [RPCRT4.@] + */ +void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, + NDR_CCONTEXT * pContextHandle, + RPC_BINDING_HANDLE BindHandle) +{ + TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle); + + ALIGN_POINTER(pStubMsg->Buffer, 4); + + if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd) + RpcRaiseException(RPC_X_BAD_STUB_DATA); + + NDRCContextUnmarshall(pContextHandle, + BindHandle, + pStubMsg->Buffer, + pStubMsg->RpcMsg->DataRepresentation); + + pStubMsg->Buffer += cbNDRContext; +} + +void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg, + NDR_SCONTEXT ContextHandle, + NDR_RUNDOWN 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) +{ + 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, + unsigned char* pMemory, + PFORMAT_STRING pFormat) +{ + FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat); +} + +NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg, + PFORMAT_STRING pFormat) +{ + TRACE("(%p, %p)\n", pStubMsg, pFormat); + return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL, + pStubMsg->RpcMsg->DataRepresentation, NULL, 0); +} + +void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg, + NDR_SCONTEXT ContextHandle, + NDR_RUNDOWN RundownRoutine, + PFORMAT_STRING pFormat) +{ + TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat); + + 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); + } + + /* FIXME: do something with pFormat */ + NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle, + pStubMsg->Buffer, RundownRoutine, NULL, 0); + pStubMsg->Buffer += cbNDRContext; +} + +NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, + PFORMAT_STRING pFormat) +{ + NDR_SCONTEXT ContextHandle; + + TRACE("(%p, %p)\n", pStubMsg, pFormat); + + 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); + } + + /* FIXME: do something with pFormat */ + ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, + pStubMsg->Buffer, + pStubMsg->RpcMsg->DataRepresentation, + NULL, 0); + pStubMsg->Buffer += cbNDRContext; + + return ContextHandle; +} diff --git a/reactos/dll/win32/rpcrt4/ndr_midl.c b/reactos/dll/win32/rpcrt4/ndr_midl.c deleted file mode 100644 index e8243ef8ff0..00000000000 --- a/reactos/dll/win32/rpcrt4/ndr_midl.c +++ /dev/null @@ -1,327 +0,0 @@ -/* - * MIDL proxy/stub stuff - * - * Copyright 2002 Ove Kåven, TransGaming Technologies - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * TODO: - * - figure out whether we *really* got this right - * - check for errors and throw exceptions - */ - -#include -#include -#include -#include - -#define COBJMACROS - -#include "windef.h" -#include "winbase.h" -#include "winerror.h" -#include "winreg.h" - -#include "objbase.h" - -#include "rpcproxy.h" - -#include "wine/debug.h" - -#include "cpsf.h" -#include "ndr_misc.h" -#include "rpcndr.h" - -WINE_DEFAULT_DEBUG_CHANNEL(rpc); - -/*********************************************************************** - * NdrProxyInitialize [RPCRT4.@] - */ -void WINAPI NdrProxyInitialize(void *This, - PRPC_MESSAGE pRpcMsg, - PMIDL_STUB_MESSAGE pStubMsg, - PMIDL_STUB_DESC pStubDescriptor, - unsigned int ProcNum) -{ - HRESULT hr; - - TRACE("(%p,%p,%p,%p,%d)\n", This, pRpcMsg, pStubMsg, pStubDescriptor, ProcNum); - NdrClientInitializeNew(pRpcMsg, pStubMsg, pStubDescriptor, ProcNum); - if (This) StdProxy_GetChannel(This, &pStubMsg->pRpcChannelBuffer); - if (pStubMsg->pRpcChannelBuffer) { - hr = IRpcChannelBuffer_GetDestCtx(pStubMsg->pRpcChannelBuffer, - &pStubMsg->dwDestContext, - &pStubMsg->pvDestContext); - } - TRACE("channel=%p\n", pStubMsg->pRpcChannelBuffer); -} - -/*********************************************************************** - * NdrProxyGetBuffer [RPCRT4.@] - */ -void WINAPI NdrProxyGetBuffer(void *This, - PMIDL_STUB_MESSAGE pStubMsg) -{ - HRESULT hr; - const IID *riid = NULL; - - TRACE("(%p,%p)\n", This, pStubMsg); - pStubMsg->RpcMsg->BufferLength = pStubMsg->BufferLength; - pStubMsg->dwStubPhase = PROXY_GETBUFFER; - hr = StdProxy_GetIID(This, &riid); - hr = IRpcChannelBuffer_GetBuffer(pStubMsg->pRpcChannelBuffer, - (RPCOLEMESSAGE*)pStubMsg->RpcMsg, - riid); - pStubMsg->BufferStart = pStubMsg->RpcMsg->Buffer; - pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->BufferLength; - pStubMsg->Buffer = pStubMsg->BufferStart; - pStubMsg->dwStubPhase = PROXY_MARSHAL; -} - -/*********************************************************************** - * NdrProxySendReceive [RPCRT4.@] - */ -void WINAPI NdrProxySendReceive(void *This, - PMIDL_STUB_MESSAGE pStubMsg) -{ - ULONG Status = 0; - HRESULT hr; - - TRACE("(%p,%p)\n", This, pStubMsg); - - if (!pStubMsg->pRpcChannelBuffer) - { - WARN("Trying to use disconnected proxy %p\n", This); - RpcRaiseException(RPC_E_DISCONNECTED); - } - - pStubMsg->dwStubPhase = PROXY_SENDRECEIVE; - hr = IRpcChannelBuffer_SendReceive(pStubMsg->pRpcChannelBuffer, - (RPCOLEMESSAGE*)pStubMsg->RpcMsg, - &Status); - pStubMsg->dwStubPhase = PROXY_UNMARSHAL; - pStubMsg->BufferLength = pStubMsg->RpcMsg->BufferLength; - pStubMsg->BufferStart = pStubMsg->RpcMsg->Buffer; - pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->BufferLength; - pStubMsg->Buffer = pStubMsg->BufferStart; - - /* raise exception if call failed */ - if (hr == RPC_S_CALL_FAILED) RpcRaiseException(*(DWORD*)pStubMsg->Buffer); - else if (FAILED(hr)) RpcRaiseException(hr); -} - -/*********************************************************************** - * NdrProxyFreeBuffer [RPCRT4.@] - */ -void WINAPI NdrProxyFreeBuffer(void *This, - PMIDL_STUB_MESSAGE pStubMsg) -{ - HRESULT hr; - - TRACE("(%p,%p)\n", This, pStubMsg); - hr = IRpcChannelBuffer_FreeBuffer(pStubMsg->pRpcChannelBuffer, - (RPCOLEMESSAGE*)pStubMsg->RpcMsg); -} - -/*********************************************************************** - * NdrProxyErrorHandler [RPCRT4.@] - */ -HRESULT WINAPI NdrProxyErrorHandler(DWORD dwExceptionCode) -{ - WARN("(0x%08lx): a proxy call failed\n", dwExceptionCode); - - if (FAILED(dwExceptionCode)) - return dwExceptionCode; - else - return HRESULT_FROM_WIN32(dwExceptionCode); -} - -/*********************************************************************** - * NdrStubInitialize [RPCRT4.@] - */ -void WINAPI NdrStubInitialize(PRPC_MESSAGE pRpcMsg, - PMIDL_STUB_MESSAGE pStubMsg, - PMIDL_STUB_DESC pStubDescriptor, - LPRPCCHANNELBUFFER pRpcChannelBuffer) -{ - TRACE("(%p,%p,%p,%p)\n", pRpcMsg, pStubMsg, pStubDescriptor, pRpcChannelBuffer); - NdrServerInitializeNew(pRpcMsg, pStubMsg, pStubDescriptor); - pStubMsg->pRpcChannelBuffer = pRpcChannelBuffer; -} - -/*********************************************************************** - * NdrStubGetBuffer [RPCRT4.@] - */ -void WINAPI NdrStubGetBuffer(LPRPCSTUBBUFFER This, - LPRPCCHANNELBUFFER pRpcChannelBuffer, - PMIDL_STUB_MESSAGE pStubMsg) -{ - TRACE("(%p,%p)\n", This, pStubMsg); - pStubMsg->pRpcChannelBuffer = pRpcChannelBuffer; - pStubMsg->RpcMsg->BufferLength = pStubMsg->BufferLength; - I_RpcGetBuffer(pStubMsg->RpcMsg); /* ? */ - pStubMsg->BufferStart = pStubMsg->RpcMsg->Buffer; - pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->BufferLength; - pStubMsg->Buffer = pStubMsg->BufferStart; -} - -/************************************************************************ - * NdrClientInitializeNew [RPCRT4.@] - */ -void WINAPI NdrClientInitializeNew( PRPC_MESSAGE pRpcMessage, PMIDL_STUB_MESSAGE pStubMsg, - PMIDL_STUB_DESC pStubDesc, unsigned int ProcNum ) -{ - TRACE("(pRpcMessage == ^%p, pStubMsg == ^%p, pStubDesc == ^%p, ProcNum == %d)\n", - pRpcMessage, pStubMsg, pStubDesc, ProcNum); - - assert( pRpcMessage && pStubMsg && pStubDesc ); - - memset(pRpcMessage, 0, sizeof(RPC_MESSAGE)); - pRpcMessage->DataRepresentation = NDR_LOCAL_DATA_REPRESENTATION; - - /* not everyone allocates stack space for w2kReserved */ - memset(pStubMsg, 0, FIELD_OFFSET(MIDL_STUB_MESSAGE,pCSInfo)); - - pStubMsg->ReuseBuffer = FALSE; - pStubMsg->IsClient = TRUE; - pStubMsg->StubDesc = pStubDesc; - pStubMsg->pfnAllocate = pStubDesc->pfnAllocate; - pStubMsg->pfnFree = pStubDesc->pfnFree; - pStubMsg->RpcMsg = pRpcMessage; - - pRpcMessage->ProcNum = ProcNum; - pRpcMessage->RpcInterfaceInformation = pStubDesc->RpcInterfaceInformation; -} - -/*********************************************************************** - * NdrServerInitializeNew [RPCRT4.@] - */ -unsigned char* WINAPI NdrServerInitializeNew( PRPC_MESSAGE pRpcMsg, PMIDL_STUB_MESSAGE pStubMsg, - PMIDL_STUB_DESC pStubDesc ) -{ - TRACE("(pRpcMsg == ^%p, pStubMsg == ^%p, pStubDesc == ^%p)\n", pRpcMsg, pStubMsg, pStubDesc); - - assert( pRpcMsg && pStubMsg && pStubDesc ); - - /* not everyone allocates stack space for w2kReserved */ - memset(pStubMsg, 0, FIELD_OFFSET(MIDL_STUB_MESSAGE,pCSInfo)); - - pStubMsg->ReuseBuffer = TRUE; - pStubMsg->IsClient = FALSE; - pStubMsg->StubDesc = pStubDesc; - pStubMsg->pfnAllocate = pStubDesc->pfnAllocate; - pStubMsg->pfnFree = pStubDesc->pfnFree; - pStubMsg->RpcMsg = pRpcMsg; - pStubMsg->Buffer = pStubMsg->BufferStart = pRpcMsg->Buffer; - pStubMsg->BufferLength = pRpcMsg->BufferLength; - pStubMsg->BufferEnd = pStubMsg->Buffer + pStubMsg->BufferLength; - - /* FIXME: determine the proper return value */ - return NULL; -} - -/*********************************************************************** - * NdrGetBuffer [RPCRT4.@] - */ -unsigned char *WINAPI NdrGetBuffer(MIDL_STUB_MESSAGE *stubmsg, unsigned long buflen, RPC_BINDING_HANDLE handle) -{ - TRACE("(stubmsg == ^%p, buflen == %lu, handle == %p): wild guess.\n", stubmsg, buflen, handle); - - assert( stubmsg && stubmsg->RpcMsg ); - - /* I guess this is our chance to put the binding handle into the RPC_MESSAGE */ - stubmsg->RpcMsg->Handle = handle; - - stubmsg->RpcMsg->BufferLength = buflen; - if (I_RpcGetBuffer(stubmsg->RpcMsg) != S_OK) - return NULL; - - stubmsg->Buffer = stubmsg->BufferStart = stubmsg->RpcMsg->Buffer; - stubmsg->BufferLength = stubmsg->RpcMsg->BufferLength; - stubmsg->BufferEnd = stubmsg->Buffer + stubmsg->BufferLength; - return (stubmsg->Buffer = (unsigned char *)stubmsg->RpcMsg->Buffer); -} -/*********************************************************************** - * NdrFreeBuffer [RPCRT4.@] - */ -void WINAPI NdrFreeBuffer(MIDL_STUB_MESSAGE *pStubMsg) -{ - TRACE("(pStubMsg == ^%p): wild guess.\n", pStubMsg); - I_RpcFreeBuffer(pStubMsg->RpcMsg); - pStubMsg->BufferLength = 0; - pStubMsg->Buffer = pStubMsg->BufferEnd = (unsigned char *)(pStubMsg->RpcMsg->Buffer = NULL); -} - -/************************************************************************ - * NdrSendReceive [RPCRT4.@] - */ -unsigned char *WINAPI NdrSendReceive( MIDL_STUB_MESSAGE *stubmsg, unsigned char *buffer ) -{ - RPC_STATUS status; - - TRACE("(stubmsg == ^%p, buffer == ^%p)\n", stubmsg, buffer); - - /* FIXME: how to handle errors? (raise exception?) */ - if (!stubmsg) { - ERR("NULL stub message. No action taken.\n"); - return NULL; - } - if (!stubmsg->RpcMsg) { - ERR("RPC Message not present in stub message. No action taken.\n"); - return NULL; - } - - status = I_RpcSendReceive(stubmsg->RpcMsg); - if (status != RPC_S_OK) - { - WARN("I_RpcSendReceive did not return success.\n"); - /* FIXME: raise exception? */ - //RpcRaiseException(status); - } - - stubmsg->BufferLength = stubmsg->RpcMsg->BufferLength; - stubmsg->BufferStart = stubmsg->RpcMsg->Buffer; - stubmsg->BufferEnd = stubmsg->BufferStart + stubmsg->BufferLength; - stubmsg->Buffer = stubmsg->BufferStart; - - /* FIXME: is this the right return value? */ - return NULL; -} - -/************************************************************************ - * NdrMapCommAndFaultStatus [RPCRT4.@] - */ -RPC_STATUS RPC_ENTRY NdrMapCommAndFaultStatus( PMIDL_STUB_MESSAGE pStubMsg, - unsigned long *pCommStatus, - unsigned long *pFaultStatus, - RPC_STATUS Status ) -{ - FIXME("(%p, %p, %p, %ld): stub\n", pStubMsg, pCommStatus, pFaultStatus, Status); - - *pCommStatus = 0; - *pFaultStatus = 0; - - return RPC_S_OK; -} - -/************************************************************************ - * NdrStubForwardingFunction [RPCRT4.@] - */ -void __RPC_STUB NdrStubForwardingFunction( IRpcStubBuffer *This, IRpcChannelBuffer *pChannel, - PRPC_MESSAGE pMsg, DWORD *pdwStubPhase ) -{ - FIXME("Not implemented\n"); - return; -} diff --git a/reactos/dll/win32/rpcrt4/ndr_misc.h b/reactos/dll/win32/rpcrt4/ndr_misc.h index 0abeaed5b04..ebd70b8d826 100644 --- a/reactos/dll/win32/rpcrt4/ndr_misc.h +++ b/reactos/dll/win32/rpcrt4/ndr_misc.h @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __WINE_NDR_MISC_H @@ -30,22 +30,36 @@ struct IPSFactoryBuffer; -#define ComputeConformance(pStubMsg, pMemory, pFormat, def) ComputeConformanceOrVariance(pStubMsg, pMemory, pFormat, def, &pStubMsg->MaxCount) -#define ComputeVariance(pStubMsg, pMemory, pFormat, def) ComputeConformanceOrVariance(pStubMsg, pMemory, pFormat, def, &pStubMsg->ActualCount) PFORMAT_STRING ComputeConformanceOrVariance( MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory, - PFORMAT_STRING pFormat, ULONG_PTR def, ULONG *pCount); + PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount); + +static inline PFORMAT_STRING ComputeConformance(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat, ULONG def) +{ + return ComputeConformanceOrVariance(pStubMsg, pMemory, pFormat, def, &pStubMsg->MaxCount); +} + +static inline PFORMAT_STRING ComputeVariance(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat, ULONG def) +{ + PFORMAT_STRING ret; + ULONG_PTR ActualCount = pStubMsg->ActualCount; + + pStubMsg->Offset = 0; + ret = ComputeConformanceOrVariance(pStubMsg, pMemory, pFormat, def, &ActualCount); + pStubMsg->ActualCount = (ULONG)ActualCount; + return ret; +} typedef unsigned char* (WINAPI *NDR_MARSHALL) (PMIDL_STUB_MESSAGE, unsigned char*, PFORMAT_STRING); typedef unsigned char* (WINAPI *NDR_UNMARSHALL)(PMIDL_STUB_MESSAGE, unsigned char**,PFORMAT_STRING, unsigned char); typedef void (WINAPI *NDR_BUFFERSIZE)(PMIDL_STUB_MESSAGE, unsigned char*, PFORMAT_STRING); -typedef unsigned long (WINAPI *NDR_MEMORYSIZE)(PMIDL_STUB_MESSAGE, PFORMAT_STRING); +typedef ULONG (WINAPI *NDR_MEMORYSIZE)(PMIDL_STUB_MESSAGE, PFORMAT_STRING); typedef void (WINAPI *NDR_FREE) (PMIDL_STUB_MESSAGE, unsigned char*, PFORMAT_STRING); -extern NDR_MARSHALL NdrMarshaller[]; -extern NDR_UNMARSHALL NdrUnmarshaller[]; -extern NDR_BUFFERSIZE NdrBufferSizer[]; -extern NDR_MEMORYSIZE NdrMemorySizer[]; -extern NDR_FREE NdrFreer[]; +extern const NDR_MARSHALL NdrMarshaller[]; +extern const NDR_UNMARSHALL NdrUnmarshaller[]; +extern const NDR_BUFFERSIZE NdrBufferSizer[]; +extern const NDR_MEMORYSIZE NdrMemorySizer[]; +extern const NDR_FREE NdrFreer[]; #endif /* __WINE_NDR_MISC_H */ diff --git a/reactos/dll/win32/rpcrt4/ndr_ole.c b/reactos/dll/win32/rpcrt4/ndr_ole.c index 4bdeefe633d..5c1845a2e1d 100644 --- a/reactos/dll/win32/rpcrt4/ndr_ole.c +++ b/reactos/dll/win32/rpcrt4/ndr_ole.c @@ -15,12 +15,10 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * * TODO: - * - figure out whether we *really* got this right - * - check for errors and throw exceptions - * - what are the marshalling functions supposed to return? + * - fix the wire-protocol to match MS/RPC * - finish RpcStream_Vtbl */ @@ -35,13 +33,14 @@ #include "windef.h" #include "winbase.h" #include "winerror.h" -#include "winreg.h" #include "objbase.h" #include "ndr_misc.h" #include "rpcndr.h" +#include "rpcproxy.h" #include "wine/rpcfc.h" +#include "cpsf.h" #include "wine/debug.h" @@ -83,7 +82,7 @@ typedef struct RpcStreamImpl DWORD RefCount; PMIDL_STUB_MESSAGE pMsg; LPDWORD size; - char *data; + unsigned char *data; DWORD pos; } RpcStreamImpl; @@ -112,7 +111,7 @@ static ULONG WINAPI RpcStream_Release(LPSTREAM iface) { RpcStreamImpl *This = (RpcStreamImpl *)iface; if (!--(This->RefCount)) { - TRACE("size=%ld\n", *This->size); + TRACE("size=%d\n", *This->size); This->pMsg->Buffer = (unsigned char*)This->data + *This->size; HeapFree(GetProcessHeap(),0,This); return 0; @@ -146,7 +145,7 @@ static HRESULT WINAPI RpcStream_Write(LPSTREAM iface, ULONG *pcbWritten) { RpcStreamImpl *This = (RpcStreamImpl *)iface; - if (This->data + cb > (char *)This->pMsg->BufferEnd) + if (This->data + cb > (unsigned char *)This->pMsg->RpcMsg->Buffer + This->pMsg->BufferLength) return STG_E_MEDIUMFULL; memcpy(This->data + This->pos, pv, cb); This->pos += cb; @@ -216,10 +215,10 @@ static LPSTREAM RpcStream_Create(PMIDL_STUB_MESSAGE pStubMsg, BOOL init) This->RefCount = 1; This->pMsg = pStubMsg; This->size = (LPDWORD)pStubMsg->Buffer; - This->data = (char*)(This->size + 1); + This->data = (unsigned char*)(This->size + 1); This->pos = 0; if (init) *This->size = 0; - TRACE("init size=%ld\n", *This->size); + TRACE("init size=%d\n", *This->size); return (LPSTREAM)This; } @@ -254,7 +253,7 @@ unsigned char * WINAPI NdrInterfacePointerMarshall(PMIDL_STUB_MESSAGE pStubMsg, TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); pStubMsg->MaxCount = 0; if (!LoadCOM()) return NULL; - if (pStubMsg->Buffer + sizeof(DWORD) < (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) { + if (pStubMsg->Buffer + sizeof(DWORD) <= (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) { stream = RpcStream_Create(pStubMsg, TRUE); if (stream) { if (pMemory) @@ -288,12 +287,14 @@ unsigned char * WINAPI NdrInterfacePointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg *(LPVOID*)ppMemory = NULL; if (pStubMsg->Buffer + sizeof(DWORD) < (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) { stream = RpcStream_Create(pStubMsg, FALSE); - if (stream) { + if (!stream) RpcRaiseException(E_OUTOFMEMORY); + if (*((RpcStreamImpl *)stream)->size != 0) hr = COM_UnmarshalInterface(stream, &IID_NULL, (LPVOID*)ppMemory); - IStream_Release(stream); - if (FAILED(hr)) + else + hr = S_OK; + IStream_Release(stream); + if (FAILED(hr)) RpcRaiseException(hr); - } } return NULL; } @@ -314,18 +315,27 @@ void WINAPI NdrInterfacePointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, hr = COM_GetMarshalSizeMax(&size, riid, (LPUNKNOWN)pMemory, pStubMsg->dwDestContext, pStubMsg->pvDestContext, MSHLFLAGS_NORMAL); - TRACE("size=%ld\n", size); + TRACE("size=%d\n", size); pStubMsg->BufferLength += sizeof(DWORD) + size; } /*********************************************************************** * NdrInterfacePointerMemorySize [RPCRT4.@] */ -unsigned long WINAPI NdrInterfacePointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg, - PFORMAT_STRING pFormat) +ULONG WINAPI NdrInterfacePointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg, + PFORMAT_STRING pFormat) { - FIXME("(%p,%p): stub\n", pStubMsg, pFormat); - return 0; + ULONG size; + + TRACE("(%p,%p)\n", pStubMsg, pFormat); + + size = *(ULONG *)pStubMsg->Buffer; + pStubMsg->Buffer += 4; + pStubMsg->MemorySize += 4; + + pStubMsg->Buffer += size; + + return pStubMsg->MemorySize; } /*********************************************************************** @@ -357,3 +367,27 @@ void WINAPI NdrOleFree(void *NodeToFree) if (!LoadCOM()) return; COM_MemFree(NodeToFree); } + +/*********************************************************************** + * Helper function to create a stub. + * This probably looks very much like NdrpCreateStub. + */ +HRESULT create_stub(REFIID iid, IUnknown *pUnk, IRpcStubBuffer **ppstub) +{ + CLSID clsid; + IPSFactoryBuffer *psfac; + HRESULT r; + + if(!LoadCOM()) return E_FAIL; + + r = COM_GetPSClsid( iid, &clsid ); + if(FAILED(r)) return r; + + r = COM_GetClassObject( &clsid, CLSCTX_INPROC_SERVER, NULL, &IID_IPSFactoryBuffer, (void**)&psfac ); + if(FAILED(r)) return r; + + r = IPSFactoryBuffer_CreateStub(psfac, iid, pUnk, ppstub); + + IPSFactoryBuffer_Release(psfac); + return r; +} diff --git a/reactos/dll/win32/rpcrt4/ndr_stubless.c b/reactos/dll/win32/rpcrt4/ndr_stubless.c index ec31fda0935..c21b8098198 100644 --- a/reactos/dll/win32/rpcrt4/ndr_stubless.c +++ b/reactos/dll/win32/rpcrt4/ndr_stubless.c @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * * TODO: * - Pipes @@ -33,7 +33,6 @@ #include "windef.h" #include "winbase.h" #include "winerror.h" -#include "winreg.h" #include "objbase.h" #include "rpc.h" @@ -43,8 +42,9 @@ #include "wine/debug.h" #include "wine/rpcfc.h" -#include "ndr_misc.h" #include "cpsf.h" +#include "ndr_misc.h" +#include "ndr_stubless.h" WINE_DEFAULT_DEBUG_CHANNEL(rpc); @@ -89,17 +89,23 @@ static inline void call_freer(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemor { NDR_FREE m = NdrFreer[pFormat[0] & NDR_TABLE_MASK]; if (m) m(pStubMsg, pMemory, pFormat); - else - { - FIXME("format type 0x%x not implemented\n", pFormat[0]); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - } } static inline unsigned long call_memory_sizer(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat) { NDR_MEMORYSIZE m = NdrMemorySizer[pFormat[0] & NDR_TABLE_MASK]; - if (m) return m(pStubMsg, pFormat); + if (m) + { + unsigned char *saved_buffer = pStubMsg->Buffer; + unsigned long ret; + int saved_ignore_embedded_pointers = pStubMsg->IgnoreEmbeddedPointers; + pStubMsg->MemorySize = 0; + pStubMsg->IgnoreEmbeddedPointers = 1; + ret = m(pStubMsg, pFormat); + pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded_pointers; + pStubMsg->Buffer = saved_buffer; + return ret; + } else { FIXME("format type 0x%x not implemented\n", pFormat[0]); @@ -108,279 +114,12 @@ static inline unsigned long call_memory_sizer(PMIDL_STUB_MESSAGE pStubMsg, PFORM } } -/* there can't be any alignment with the structures in this file */ -#include "pshpack1.h" - #define STUBLESS_UNMARSHAL 1 #define STUBLESS_CALLSERVER 2 #define STUBLESS_CALCSIZE 3 #define STUBLESS_GETBUFFER 4 #define STUBLESS_MARSHAL 5 - -/* From http://msdn.microsoft.com/library/default.asp?url=/library/en-us/rpc/rpc/parameter_descriptors.asp */ -typedef struct _NDR_PROC_HEADER -{ - /* type of handle to use: - * RPC_FC_BIND_EXPLICIT = 0 - Explicit handle. - * Handle is passed as a parameter to the function. - * Indicates that explicit handle information follows the header, - * which actually describes the handle. - * RPC_FC_BIND_GENERIC = 31 - Implicit handle with custom binding routines - * (MIDL_STUB_DESC::IMPLICIT_HANDLE_INFO::pGenericBindingInfo) - * RPC_FC_BIND_PRIMITIVE = 32 - Implicit handle using handle_t created by - * calling application - * RPC_FC_AUTO_HANDLE = 33 - Automatic handle - * RPC_FC_CALLBACK_HANDLE = 34 - undocmented - */ - unsigned char handle_type; - - /* procedure flags: - * Oi_FULL_PTR_USED = 0x01 - A full pointer can have the value NULL and can - * change during the call from NULL to non-NULL and supports aliasing - * and cycles. Indicates that the NdrFullPointerXlatInit function - * should be called. - * Oi_RPCSS_ALLOC_USED = 0x02 - Use RpcSS allocate/free routines instead of - * normal allocate/free routines - * Oi_OBJECT_PROC = 0x04 - Indicates a procedure that is part of an OLE - * interface, rather than a DCE RPC interface. - * Oi_HAS_RPCFLAGS = 0x08 - Indicates that the rpc_flags element is - * present in the header. - * Oi_HAS_COMM_OR_FAULT = 0x20 - If Oi_OBJECT_PROC not present only then - * indicates that the procedure has the comm_status or fault_status - * MIDL attribute. - * Oi_OBJ_USE_V2_INTERPRETER = 0x20 - If Oi_OBJECT_PROC present only - * then indicates that the format string is in -Oif or -Oicf format - * Oi_USE_NEW_INIT_ROUTINES = 0x40 - Use NdrXInitializeNew instead of - * NdrXInitialize? - */ - unsigned char Oi_flags; - - /* the zero-based index of the procedure */ - unsigned short proc_num; - - /* total size of all parameters on the stack, including any "this" - * pointer and/or return value */ - unsigned short stack_size; -} NDR_PROC_HEADER; - -/* same as above struct except additional element rpc_flags */ -typedef struct _NDR_PROC_HEADER_RPC -{ - unsigned char handle_type; - unsigned char Oi_flags; - - /* - * RPCF_Idempotent = 0x0001 - [idempotent] MIDL attribute - * RPCF_Broadcast = 0x0002 - [broadcast] MIDL attribute - * RPCF_Maybe = 0x0004 - [maybe] MIDL attribute - * Reserved = 0x0008 - 0x0080 - * RPCF_Message = 0x0100 - [message] MIDL attribute - * Reserved = 0x0200 - 0x1000 - * RPCF_InputSynchronous = 0x2000 - unknown - * RPCF_Asynchronous = 0x4000 - [async] MIDL attribute - * Reserved = 0x8000 - */ - unsigned long rpc_flags; - unsigned short proc_num; - unsigned short stack_size; - -} NDR_PROC_HEADER_RPC; - -typedef struct _NDR_PROC_PARTIAL_OIF_HEADER -{ - /* the pre-computed client buffer size so that interpreter can skip all - * or some (if the flag RPC_FC_PROC_OI2F_CLTMUSTSIZE is specified) of the - * sizing pass */ - unsigned short constant_client_buffer_size; - - /* the pre-computed server buffer size so that interpreter can skip all - * or some (if the flag RPC_FC_PROC_OI2F_SRVMUSTSIZE is specified) of the - * sizing pass */ - unsigned short constant_server_buffer_size; - - /* -Oif flags: - * RPC_FC_PROC_OI2F_SRVMUSTSIZE = 0x01 - the server must perform a - * sizing pass. - * RPC_FC_PROC_OI2F_CLTMUSTSIZE = 0x02 - the client must perform a - * sizing pass. - * RPC_FC_PROC_OI2F_HASRETURN = 0x04 - procedure has a return value. - * RPC_FC_PROC_OI2F_HASPIPES = 0x08 - the pipe package should be used. - * RPC_FC_PROC_OI2F_HASASYNCUUID = 0x20 - indicates an asynchronous DCOM - * procedure. - * RPC_FC_PROC_OI2F_HASEXTS = 0x40 - indicates that Windows 2000 - * extensions are in use. - * RPC_FC_PROC_OI2F_HASASYNCHND = 0x80 - indicates an asynchronous RPC - * procedure. - */ - unsigned char Oif_flags; - - /* number of params */ - unsigned char number_of_params; -} NDR_PROC_PARTIAL_OIF_HEADER; - -/* Windows 2000 extensions */ -typedef struct _NDR_PROC_EXTENSION -{ - /* size in bytes of all following extensions */ - unsigned char extension_version; - - /* extension flags: - * HasNewCorrDesc = 0x01 - indicates new correlation descriptors in use - * ClientCorrCheck = 0x02 - client needs correlation check - * ServerCorrCheck = 0x04 - server needs correlation check - * HasNotify = 0x08 - should call MIDL [notify] routine @ NotifyIndex - * HasNotify2 = 0x10 - should call MIDL [notify_flag] routine @ - * NotifyIndex - */ - unsigned char ext_flags; - - /* client cache size hint */ - unsigned short ClientCorrHint; - - /* server cache size hint */ - unsigned short ServerCorrHint; - - /* index of routine in MIDL_STUB_DESC::NotifyRoutineTable to call if - * HasNotify or HasNotify2 flag set */ - unsigned short NotifyIndex; -} NDR_PROC_EXTENSION; - -/* usually generated only on IA64 */ -typedef struct _NDR_PROC_EXTENSION_64 -{ - NDR_PROC_EXTENSION ext; - - /* needed only on IA64 to cope with float/register loading */ - unsigned short FloatDoubleMask; -} NDR_PROC_EXTENSION_64; - - -typedef struct _NDR_PARAM_OI_BASETYPE -{ - /* parameter direction. One of: - * FC_IN_PARAM_BASETYPE = 0x4e - an in param - * FC_RETURN_PARAM_BASETYPE = 0x53 - a return param - */ - unsigned char param_direction; - - /* One of: FC_BYTE,FC_CHAR,FC_SMALL,FC_USMALL,FC_WCHAR,FC_SHORT,FC_USHORT, - * FC_LONG,FC_ULONG,FC_FLOAT,FC_HYPER,FC_DOUBLE,FC_ENUM16,FC_ENUM32, - * FC_ERROR_STATUS_T,FC_INT3264,FC_UINT3264 */ - unsigned char type_format_char; -} NDR_PARAM_OI_BASETYPE; - -typedef struct _NDR_PARAM_OI_OTHER -{ - /* One of: - * FC_IN_PARAM = 0x4d - An in param - * FC_IN_OUT_PARAM = 0x50 - An in/out param - * FC_OUT_PARAM = 0x51 - An out param - * FC_RETURN_PARAM = 0x52 - A return value - * FC_IN_PARAM_NO_FREE_INST = 0x4f - A param for which no freeing is done - */ - unsigned char param_direction; - - /* Size of param on stack in NUMBERS OF INTS */ - unsigned char stack_size; - - /* offset in the type format string table */ - unsigned short type_offset; -} NDR_PARAM_OI_OTHER; - -typedef struct _NDR_PARAM_OIF_BASETYPE -{ - PARAM_ATTRIBUTES param_attributes; - - /* the offset on the calling stack where the parameter is located */ - unsigned short stack_offset; - - /* see NDR_PARAM_OI_BASETYPE::type_format_char */ - unsigned char type_format_char; - - /* always FC_PAD */ - unsigned char unused; -} NDR_PARAM_OIF_BASETYPE; - -typedef struct _NDR_PARAM_OIF_OTHER -{ - PARAM_ATTRIBUTES param_attributes; - - /* see NDR_PARAM_OIF_BASETYPE::stack_offset */ - unsigned short stack_offset; - - /* offset into the provided type format string where the type for this - * parameter starts */ - unsigned short type_offset; -} NDR_PARAM_OIF_OTHER; - -/* explicit handle description for FC_BIND_PRIMITIVE type */ -typedef struct _NDR_EHD_PRIMITIVE -{ - /* FC_BIND_PRIMITIVE */ - unsigned char handle_type; - - /* is the handle passed in via a pointer? */ - unsigned char flag; - - /* offset from the beginning of the stack to the handle in bytes */ - unsigned short offset; -} NDR_EHD_PRIMITIVE; - -/* explicit handle description for FC_BIND_GENERIC type */ -typedef struct _NDR_EHD_GENERIC -{ - /* FC_BIND_GENERIC */ - unsigned char handle_type; - - /* upper 4bits is a flag indicating whether the handle is passed in - * via a pointer. lower 4bits is the size of the user defined generic - * handle type. the size must be less than or equal to the machine - * register size */ - unsigned char flag_and_size; - - /* offset from the beginning of the stack to the handle in bytes */ - unsigned short offset; - - /* the index into the aGenericBindingRoutinesPairs field of MIDL_STUB_DESC - * giving the bind and unbind routines for the handle */ - unsigned char binding_routine_pair_index; - - /* FC_PAD */ - unsigned char unused; -} NDR_EHD_GENERIC; - -/* explicit handle description for FC_BIND_CONTEXT type */ -typedef struct _NDR_EHD_CONTEXT -{ - /* FC_BIND_CONTEXT */ - unsigned char handle_type; - - /* Any of the following flags: - * NDR_CONTEXT_HANDLE_CANNOT_BE_NULL = 0x01 - * NDR_CONTEXT_HANDLE_SERIALIZE = 0x02 - * NDR_CONTEXT_HANDLE_NO_SERIALIZE = 0x04 - * NDR_STRICT_CONTEXT_HANDLE = 0x08 - * HANDLE_PARAM_IS_OUT = 0x20 - * HANDLE_PARAM_IS_RETURN = 0x21 - * HANDLE_PARAM_IS_IN = 0x40 - * HANDLE_PARAM_IS_VIA_PTR = 0x80 - */ - unsigned char flags; - - /* offset from the beginning of the stack to the handle in bytes */ - unsigned short offset; - - /* zero-based index on rundown routine in apfnNdrRundownRoutines field - * of MIDL_STUB_DESC */ - unsigned char context_rundown_routine_index; - - /* varies depending on NDR version used. - * V1: zero-based index into parameters - * V2: zero-based index into handles that are parameters */ - unsigned char param_num; -} NDR_EHD_CONTEXT; - -#include "poppack.h" +#define STUBLESS_FREE 6 void WINAPI NdrRpcSmSetClientToOsf(PMIDL_STUB_MESSAGE pMessage) { @@ -406,8 +145,393 @@ static void WINAPI dump_RPC_FC_PROC_PF(PARAM_ATTRIBUTES param_attributes) if (param_attributes.ServerAllocSize) TRACE(" ServerAllocSize = %d", param_attributes.ServerAllocSize * 8); } -/* FIXME: this will be different on other plaftorms than i386 */ -#define ARG_FROM_OFFSET(args, offset) (*(unsigned char **)args + offset) +static void WINAPI dump_INTERPRETER_OPT_FLAGS(INTERPRETER_OPT_FLAGS Oi2Flags) +{ + if (Oi2Flags.ServerMustSize) TRACE(" ServerMustSize"); + if (Oi2Flags.ClientMustSize) TRACE(" ClientMustSize"); + if (Oi2Flags.HasReturn) TRACE(" HasReturn"); + if (Oi2Flags.HasPipes) TRACE(" HasPipes"); + if (Oi2Flags.Unused) TRACE(" Unused"); + if (Oi2Flags.HasAsyncUuid) TRACE(" HasAsyncUuid"); + if (Oi2Flags.HasExtensions) TRACE(" HasExtensions"); + if (Oi2Flags.HasAsyncHandle) TRACE(" HasAsyncHandle"); + TRACE("\n"); +} + +#define ARG_FROM_OFFSET(stubMsg, offset) ((stubMsg).StackTop + (offset)) + +static PFORMAT_STRING client_get_handle( + PMIDL_STUB_MESSAGE pStubMsg, const NDR_PROC_HEADER *pProcHeader, + PFORMAT_STRING pFormat, handle_t *phBinding) +{ + /* binding */ + switch (pProcHeader->handle_type) + { + /* explicit binding: parse additional section */ + case RPC_FC_BIND_EXPLICIT: + switch (*pFormat) /* handle_type */ + { + case RPC_FC_BIND_PRIMITIVE: /* explicit primitive */ + { + const NDR_EHD_PRIMITIVE *pDesc = (const NDR_EHD_PRIMITIVE *)pFormat; + + TRACE("Explicit primitive handle @ %d\n", pDesc->offset); + + if (pDesc->flag) /* pointer to binding */ + *phBinding = **(handle_t **)ARG_FROM_OFFSET(*pStubMsg, pDesc->offset); + else + *phBinding = *(handle_t *)ARG_FROM_OFFSET(*pStubMsg, pDesc->offset); + return pFormat + sizeof(NDR_EHD_PRIMITIVE); + } + case RPC_FC_BIND_GENERIC: /* explicit generic */ + { + const NDR_EHD_GENERIC *pDesc = (const NDR_EHD_GENERIC *)pFormat; + void *pObject = NULL; + void *pArg; + const GENERIC_BINDING_ROUTINE_PAIR *pGenPair; + + TRACE("Explicit generic binding handle #%d\n", pDesc->binding_routine_pair_index); + + if (pDesc->flag_and_size & HANDLE_PARAM_IS_VIA_PTR) + pArg = *(void **)ARG_FROM_OFFSET(*pStubMsg, pDesc->offset); + else + pArg = (void *)ARG_FROM_OFFSET(*pStubMsg, pDesc->offset); + memcpy(&pObject, pArg, pDesc->flag_and_size & 0xf); + pGenPair = &pStubMsg->StubDesc->aGenericBindingRoutinePairs[pDesc->binding_routine_pair_index]; + *phBinding = pGenPair->pfnBind(pObject); + return pFormat + sizeof(NDR_EHD_GENERIC); + } + case RPC_FC_BIND_CONTEXT: /* explicit context */ + { + const NDR_EHD_CONTEXT *pDesc = (const NDR_EHD_CONTEXT *)pFormat; + NDR_CCONTEXT context_handle; + TRACE("Explicit bind context\n"); + if (pDesc->flags & HANDLE_PARAM_IS_VIA_PTR) + { + TRACE("\tHANDLE_PARAM_IS_VIA_PTR\n"); + context_handle = **(NDR_CCONTEXT **)ARG_FROM_OFFSET(*pStubMsg, pDesc->offset); + } + else + context_handle = *(NDR_CCONTEXT *)ARG_FROM_OFFSET(*pStubMsg, pDesc->offset); + if ((pDesc->flags & NDR_CONTEXT_HANDLE_CANNOT_BE_NULL) && + !context_handle) + { + ERR("null context handle isn't allowed\n"); + RpcRaiseException(RPC_X_SS_IN_NULL_CONTEXT); + return NULL; + } + *phBinding = NDRCContextBinding(context_handle); + /* FIXME: should we store this structure in stubMsg.pContext? */ + return pFormat + sizeof(NDR_EHD_CONTEXT); + } + default: + ERR("bad explicit binding handle type (0x%02x)\n", pProcHeader->handle_type); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } + break; + case RPC_FC_BIND_GENERIC: /* implicit generic */ + FIXME("RPC_FC_BIND_GENERIC\n"); + RpcRaiseException(RPC_X_BAD_STUB_DATA); /* FIXME: remove when implemented */ + break; + case RPC_FC_BIND_PRIMITIVE: /* implicit primitive */ + TRACE("Implicit primitive handle\n"); + *phBinding = *pStubMsg->StubDesc->IMPLICIT_HANDLE_INFO.pPrimitiveHandle; + break; + case RPC_FC_CALLBACK_HANDLE: /* implicit callback */ + FIXME("RPC_FC_CALLBACK_HANDLE\n"); + break; + case RPC_FC_AUTO_HANDLE: /* implicit auto handle */ + /* strictly speaking, it isn't necessary to set hBinding here + * since it isn't actually used (hence the automatic in its name), + * but then why does MIDL generate a valid entry in the + * MIDL_STUB_DESC for it? */ + TRACE("Implicit auto handle\n"); + *phBinding = *pStubMsg->StubDesc->IMPLICIT_HANDLE_INFO.pAutoHandle; + break; + default: + ERR("bad implicit binding handle type (0x%02x)\n", pProcHeader->handle_type); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } + return pFormat; +} + +static void client_free_handle( + PMIDL_STUB_MESSAGE pStubMsg, const NDR_PROC_HEADER *pProcHeader, + PFORMAT_STRING pFormat, handle_t hBinding) +{ + /* binding */ + switch (pProcHeader->handle_type) + { + /* explicit binding: parse additional section */ + case RPC_FC_BIND_EXPLICIT: + switch (*pFormat) /* handle_type */ + { + case RPC_FC_BIND_GENERIC: /* explicit generic */ + { + const NDR_EHD_GENERIC *pDesc = (const NDR_EHD_GENERIC *)pFormat; + void *pObject = NULL; + void *pArg; + const GENERIC_BINDING_ROUTINE_PAIR *pGenPair; + + TRACE("Explicit generic binding handle #%d\n", pDesc->binding_routine_pair_index); + + if (pDesc->flag_and_size & HANDLE_PARAM_IS_VIA_PTR) + pArg = *(void **)ARG_FROM_OFFSET(*pStubMsg, pDesc->offset); + else + pArg = (void *)ARG_FROM_OFFSET(*pStubMsg, pDesc->offset); + memcpy(&pObject, pArg, pDesc->flag_and_size & 0xf); + pGenPair = &pStubMsg->StubDesc->aGenericBindingRoutinePairs[pDesc->binding_routine_pair_index]; + pGenPair->pfnUnbind(pObject, hBinding); + break; + } + case RPC_FC_BIND_CONTEXT: /* explicit context */ + case RPC_FC_BIND_PRIMITIVE: /* explicit primitive */ + break; + default: + ERR("bad explicit binding handle type (0x%02x)\n", pProcHeader->handle_type); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } + break; + case RPC_FC_BIND_GENERIC: /* implicit generic */ + FIXME("RPC_FC_BIND_GENERIC\n"); + RpcRaiseException(RPC_X_BAD_STUB_DATA); /* FIXME: remove when implemented */ + break; + case RPC_FC_CALLBACK_HANDLE: /* implicit callback */ + case RPC_FC_BIND_PRIMITIVE: /* implicit primitive */ + case RPC_FC_AUTO_HANDLE: /* implicit auto handle */ + break; + default: + ERR("bad implicit binding handle type (0x%02x)\n", pProcHeader->handle_type); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } +} + +static void client_do_args(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, + int phase, unsigned short number_of_params, unsigned char *pRetVal) +{ + /* current format string offset */ + int current_offset = 0; + /* current stack offset */ + unsigned short current_stack_offset = 0; + /* counter */ + unsigned short i; + + for (i = 0; i < number_of_params; i++) + { + const NDR_PARAM_OIF_BASETYPE *pParam = + (const NDR_PARAM_OIF_BASETYPE *)&pFormat[current_offset]; + unsigned char * pArg; + + current_stack_offset = pParam->stack_offset; + pArg = ARG_FROM_OFFSET(*pStubMsg, current_stack_offset); + + TRACE("param[%d]: new format\n", i); + TRACE("\tparam_attributes:"); dump_RPC_FC_PROC_PF(pParam->param_attributes); TRACE("\n"); + TRACE("\tstack_offset: 0x%x\n", current_stack_offset); + TRACE("\tmemory addr (before): %p\n", pArg); + + if (pParam->param_attributes.IsBasetype) + { + const unsigned char * pTypeFormat = + &pParam->type_format_char; + + if (pParam->param_attributes.IsSimpleRef) + pArg = *(unsigned char **)pArg; + + TRACE("\tbase type: 0x%02x\n", *pTypeFormat); + + switch (phase) + { + case PROXY_CALCSIZE: + if (pParam->param_attributes.IsIn) + call_buffer_sizer(pStubMsg, pArg, pTypeFormat); + break; + case PROXY_MARSHAL: + if (pParam->param_attributes.IsIn) + call_marshaller(pStubMsg, pArg, pTypeFormat); + break; + case PROXY_UNMARSHAL: + if (pParam->param_attributes.IsOut) + { + if (pParam->param_attributes.IsReturn) + call_unmarshaller(pStubMsg, &pRetVal, pTypeFormat, 0); + else + call_unmarshaller(pStubMsg, &pArg, pTypeFormat, 0); + TRACE("pRetVal = %p\n", pRetVal); + } + break; + default: + RpcRaiseException(RPC_S_INTERNAL_ERROR); + } + + current_offset += sizeof(NDR_PARAM_OIF_BASETYPE); + } + else + { + const NDR_PARAM_OIF_OTHER *pParamOther = + (const NDR_PARAM_OIF_OTHER *)&pFormat[current_offset]; + + const unsigned char * pTypeFormat = + &(pStubMsg->StubDesc->pFormatTypes[pParamOther->type_offset]); + + /* if a simple ref pointer then we have to do the + * check for the pointer being non-NULL. */ + if (pParam->param_attributes.IsSimpleRef) + { + if (!*(unsigned char **)pArg) + RpcRaiseException(RPC_X_NULL_REF_POINTER); + } + + TRACE("\tcomplex type: 0x%02x\n", *pTypeFormat); + + switch (phase) + { + case PROXY_CALCSIZE: + if (pParam->param_attributes.IsIn) + { + if (pParam->param_attributes.IsByValue) + call_buffer_sizer(pStubMsg, pArg, pTypeFormat); + else + call_buffer_sizer(pStubMsg, *(unsigned char **)pArg, pTypeFormat); + } + break; + case PROXY_MARSHAL: + if (pParam->param_attributes.IsIn) + { + if (pParam->param_attributes.IsByValue) + call_marshaller(pStubMsg, pArg, pTypeFormat); + else + call_marshaller(pStubMsg, *(unsigned char **)pArg, pTypeFormat); + } + break; + case PROXY_UNMARSHAL: + if (pParam->param_attributes.IsOut) + { + if (pParam->param_attributes.IsReturn) + call_unmarshaller(pStubMsg, &pRetVal, pTypeFormat, 0); + else if (pParam->param_attributes.IsByValue) + call_unmarshaller(pStubMsg, &pArg, pTypeFormat, 0); + else + call_unmarshaller(pStubMsg, (unsigned char **)pArg, pTypeFormat, 0); + } + break; + default: + RpcRaiseException(RPC_S_INTERNAL_ERROR); + } + + current_offset += sizeof(NDR_PARAM_OIF_OTHER); + } + TRACE("\tmemory addr (after): %p\n", pArg); + } +} + +static void client_do_args_old_format(PMIDL_STUB_MESSAGE pStubMsg, + PFORMAT_STRING pFormat, int phase, unsigned short stack_size, + unsigned char *pRetVal, BOOL object_proc) +{ + /* current format string offset */ + int current_offset = 0; + /* current stack offset */ + unsigned short current_stack_offset = 0; + /* counter */ + unsigned short i; + + /* NOTE: V1 style format does't terminate on the number_of_params + * condition as it doesn't have this attribute. Instead it + * terminates when the stack size given in the header is exceeded. + */ + for (i = 0; TRUE; i++) + { + const NDR_PARAM_OI_BASETYPE *pParam = + (const NDR_PARAM_OI_BASETYPE *)&pFormat[current_offset]; + /* note: current_stack_offset starts after the This pointer + * if present, so adjust this */ + unsigned short current_stack_offset_adjusted = current_stack_offset + + (object_proc ? sizeof(void *) : 0); + unsigned char * pArg = ARG_FROM_OFFSET(*pStubMsg, current_stack_offset_adjusted); + + /* no more parameters; exit loop */ + if (current_stack_offset_adjusted >= stack_size) + break; + + TRACE("param[%d]: old format\n", i); + TRACE("\tparam_direction: 0x%x\n", pParam->param_direction); + TRACE("\tstack_offset: 0x%x\n", current_stack_offset_adjusted); + TRACE("\tmemory addr (before): %p\n", pArg); + + if (pParam->param_direction == RPC_FC_IN_PARAM_BASETYPE || + pParam->param_direction == RPC_FC_RETURN_PARAM_BASETYPE) + { + const unsigned char * pTypeFormat = + &pParam->type_format_char; + + TRACE("\tbase type 0x%02x\n", *pTypeFormat); + + switch (phase) + { + case PROXY_CALCSIZE: + if (pParam->param_direction == RPC_FC_IN_PARAM_BASETYPE) + call_buffer_sizer(pStubMsg, pArg, pTypeFormat); + break; + case PROXY_MARSHAL: + if (pParam->param_direction == RPC_FC_IN_PARAM_BASETYPE) + call_marshaller(pStubMsg, pArg, pTypeFormat); + break; + case PROXY_UNMARSHAL: + if (pParam->param_direction == RPC_FC_RETURN_PARAM_BASETYPE) + { + if (pParam->param_direction & RPC_FC_RETURN_PARAM) + call_unmarshaller(pStubMsg, (unsigned char **)pRetVal, pTypeFormat, 0); + else + call_unmarshaller(pStubMsg, &pArg, pTypeFormat, 0); + } + break; + default: + RpcRaiseException(RPC_S_INTERNAL_ERROR); + } + + current_stack_offset += call_memory_sizer(pStubMsg, pTypeFormat); + current_offset += sizeof(NDR_PARAM_OI_BASETYPE); + } + else + { + const NDR_PARAM_OI_OTHER *pParamOther = + (const NDR_PARAM_OI_OTHER *)&pFormat[current_offset]; + + const unsigned char *pTypeFormat = + &pStubMsg->StubDesc->pFormatTypes[pParamOther->type_offset]; + + TRACE("\tcomplex type 0x%02x\n", *pTypeFormat); + + switch (phase) + { + case PROXY_CALCSIZE: + if (pParam->param_direction == RPC_FC_IN_PARAM || + pParam->param_direction & RPC_FC_IN_OUT_PARAM) + call_buffer_sizer(pStubMsg, *(unsigned char **)pArg, pTypeFormat); + break; + case PROXY_MARSHAL: + if (pParam->param_direction == RPC_FC_IN_PARAM || + pParam->param_direction & RPC_FC_IN_OUT_PARAM) + call_marshaller(pStubMsg, *(unsigned char **)pArg, pTypeFormat); + break; + case PROXY_UNMARSHAL: + if (pParam->param_direction == RPC_FC_IN_OUT_PARAM || + pParam->param_direction == RPC_FC_OUT_PARAM) + call_unmarshaller(pStubMsg, (unsigned char **)pArg, pTypeFormat, 0); + else if (pParam->param_direction == RPC_FC_RETURN_PARAM) + call_unmarshaller(pStubMsg, (unsigned char **)pRetVal, pTypeFormat, 0); + break; + default: + RpcRaiseException(RPC_S_INTERNAL_ERROR); + } + + current_stack_offset += pParamOther->stack_size * sizeof(INT); + current_offset += sizeof(NDR_PARAM_OI_OTHER); + } + TRACE("\tmemory addr (after): %p\n", pArg); + } +} /* the return type should be CLIENT_CALL_RETURN, but this is incompatible * with the way gcc returns structures. "void *" should be the largest type @@ -415,8 +539,6 @@ static void WINAPI dump_RPC_FC_PROC_PF(PARAM_ATTRIBUTES param_attributes) LONG_PTR WINAPIV NdrClientCall2(PMIDL_STUB_DESC pStubDesc, PFORMAT_STRING pFormat, ...) { /* pointer to start of stack where arguments start */ - /* FIXME: not portable */ - unsigned char *args = (unsigned char *)(&pFormat+1); RPC_MESSAGE rpcMsg; MIDL_STUB_MESSAGE stubMsg; handle_t hBinding = NULL; @@ -424,192 +546,128 @@ LONG_PTR WINAPIV NdrClientCall2(PMIDL_STUB_DESC pStubDesc, PFORMAT_STRING pForma unsigned short procedure_number; /* size of stack */ unsigned short stack_size; - /* current stack offset */ - unsigned short current_stack_offset; /* number of parameters. optional for client to give it to us */ unsigned char number_of_params = ~0; - /* counter */ - unsigned short i; /* cache of Oif_flags from v2 procedure header */ - unsigned char Oif_flags = 0; - /* cache of extension flags from NDR_PROC_EXTENSION */ - unsigned char ext_flags = 0; + INTERPRETER_OPT_FLAGS Oif_flags = { 0 }; + /* cache of extension flags from NDR_PROC_HEADER_EXTS */ + INTERPRETER_OPT_FLAGS2 ext_flags = { 0 }; /* the type of pass we are currently doing */ int phase; /* header for procedure string */ const NDR_PROC_HEADER * pProcHeader = (const NDR_PROC_HEADER *)&pFormat[0]; - /* offset in format string for start of params */ - int parameter_start_offset; - /* current format string offset */ - int current_offset; /* -Oif or -Oicf generated format */ BOOL bV2Format = FALSE; /* the value to return to the client from the remote procedure */ LONG_PTR RetVal = 0; /* the pointer to the object when in OLE mode */ void * This = NULL; + PFORMAT_STRING pHandleFormat; TRACE("pStubDesc %p, pFormat %p, ...\n", pStubDesc, pFormat); - TRACE("&first_argument = %p -> %p\n", args, ARG_FROM_OFFSET(args, 0)); /* Later NDR language versions probably won't be backwards compatible */ if (pStubDesc->Version > 0x50002) { - FIXME("Incompatible stub description version: 0x%lx\n", pStubDesc->Version); + FIXME("Incompatible stub description version: 0x%x\n", pStubDesc->Version); RpcRaiseException(RPC_X_WRONG_STUB_VERSION); } if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCFLAGS) { - NDR_PROC_HEADER_RPC * pProcHeader = (NDR_PROC_HEADER_RPC *)&pFormat[0]; + const NDR_PROC_HEADER_RPC *pProcHeader = (const NDR_PROC_HEADER_RPC *)&pFormat[0]; stack_size = pProcHeader->stack_size; procedure_number = pProcHeader->proc_num; - current_offset = sizeof(NDR_PROC_HEADER_RPC); + pFormat += sizeof(NDR_PROC_HEADER_RPC); } else { stack_size = pProcHeader->stack_size; procedure_number = pProcHeader->proc_num; - TRACE("proc num: %d\n", procedure_number); - current_offset = sizeof(NDR_PROC_HEADER); + pFormat += sizeof(NDR_PROC_HEADER); } + TRACE("stack size: 0x%x\n", stack_size); + TRACE("proc num: %d\n", procedure_number); + + /* create the full pointer translation tables, if requested */ + if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_FULLPTR) + stubMsg.FullPtrXlatTables = NdrFullPointerXlatInit(0,XLAT_CLIENT); + + if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT) + { + /* object is always the first argument */ + This = **(void *const **)(&pFormat+1); + NdrProxyInitialize(This, &rpcMsg, &stubMsg, pStubDesc, procedure_number); + } + else + NdrClientInitializeNew(&rpcMsg, &stubMsg, pStubDesc, procedure_number); TRACE("Oi_flags = 0x%02x\n", pProcHeader->Oi_flags); - TRACE("MIDL stub version = 0x%lx\n", pStubDesc->MIDLVersion); + TRACE("MIDL stub version = 0x%x\n", pStubDesc->MIDLVersion); + + /* needed for conformance of top-level objects */ +#ifdef __i386__ + stubMsg.StackTop = *(unsigned char **)(&pFormat+1); +#else +# warning Stack not retrieved for your CPU architecture +#endif + + pHandleFormat = pFormat; /* we only need a handle if this isn't an object method */ if (!(pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT)) { - /* binding */ - switch (pProcHeader->handle_type) - { - /* explicit binding: parse additional section */ - case RPC_FC_BIND_EXPLICIT: - switch (pFormat[current_offset]) /* handle_type */ - { - case RPC_FC_BIND_PRIMITIVE: /* explicit primitive */ - { - NDR_EHD_PRIMITIVE * pDesc = (NDR_EHD_PRIMITIVE *)&pFormat[current_offset]; - - TRACE("Explicit primitive handle @ %d\n", pDesc->offset); - - if (pDesc->flag) /* pointer to binding */ - hBinding = **(handle_t **)ARG_FROM_OFFSET(args, pDesc->offset); - else - hBinding = *(handle_t *)ARG_FROM_OFFSET(args, pDesc->offset); - current_offset += sizeof(NDR_EHD_PRIMITIVE); - break; - } - case RPC_FC_BIND_GENERIC: /* explicit generic */ - FIXME("RPC_FC_BIND_GENERIC\n"); - RpcRaiseException(RPC_X_WRONG_STUB_VERSION); /* FIXME: remove when implemented */ - current_offset += sizeof(NDR_EHD_GENERIC); - break; - case RPC_FC_BIND_CONTEXT: /* explicit context */ - { - NDR_EHD_CONTEXT * pDesc = (NDR_EHD_CONTEXT *)&pFormat[current_offset]; - TRACE("Explicit bind context\n"); - hBinding = NDRCContextBinding(*(NDR_CCONTEXT *)ARG_FROM_OFFSET(args, pDesc->offset)); - /* FIXME: should we store this structure in stubMsg.pContext? */ - current_offset += sizeof(NDR_EHD_CONTEXT); - break; - } - default: - ERR("bad explicit binding handle type (0x%02x)\n", pProcHeader->handle_type); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - } - break; - case RPC_FC_BIND_GENERIC: /* implicit generic */ - FIXME("RPC_FC_BIND_GENERIC\n"); - RpcRaiseException(RPC_X_BAD_STUB_DATA); /* FIXME: remove when implemented */ - break; - case RPC_FC_BIND_PRIMITIVE: /* implicit primitive */ - TRACE("Implicit primitive handle\n"); - hBinding = *pStubDesc->IMPLICIT_HANDLE_INFO.pPrimitiveHandle; - break; - case RPC_FC_CALLBACK_HANDLE: /* implicit callback */ - FIXME("RPC_FC_CALLBACK_HANDLE\n"); - break; - case RPC_FC_AUTO_HANDLE: /* implicit auto handle */ - /* strictly speaking, it isn't necessary to set hBinding here - * since it isn't actually used (hence the automatic in its name), - * but then why does MIDL generate a valid entry in the - * MIDL_STUB_DESC for it? */ - TRACE("Implicit auto handle\n"); - hBinding = *pStubDesc->IMPLICIT_HANDLE_INFO.pAutoHandle; - break; - default: - ERR("bad implicit binding handle type (0x%02x)\n", pProcHeader->handle_type); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - } + pFormat = client_get_handle(&stubMsg, pProcHeader, pHandleFormat, &hBinding); + if (!pFormat) return 0; } bV2Format = (pStubDesc->Version >= 0x20000); if (bV2Format) { - NDR_PROC_PARTIAL_OIF_HEADER * pOIFHeader = - (NDR_PROC_PARTIAL_OIF_HEADER*)&pFormat[current_offset]; + const NDR_PROC_PARTIAL_OIF_HEADER *pOIFHeader = + (const NDR_PROC_PARTIAL_OIF_HEADER *)pFormat; - Oif_flags = pOIFHeader->Oif_flags; + Oif_flags = pOIFHeader->Oi2Flags; number_of_params = pOIFHeader->number_of_params; - current_offset += sizeof(NDR_PROC_PARTIAL_OIF_HEADER); + pFormat += sizeof(NDR_PROC_PARTIAL_OIF_HEADER); } - TRACE("Oif_flags = 0x%02x\n", Oif_flags); + TRACE("Oif_flags = "); dump_INTERPRETER_OPT_FLAGS(Oif_flags); - if (Oif_flags & RPC_FC_PROC_OI2F_HASEXTS) + if (Oif_flags.HasExtensions) { - NDR_PROC_EXTENSION * pExtensions = - (NDR_PROC_EXTENSION *)&pFormat[current_offset]; - ext_flags = pExtensions->ext_flags; - current_offset += pExtensions->extension_version; + const NDR_PROC_HEADER_EXTS *pExtensions = + (const NDR_PROC_HEADER_EXTS *)pFormat; + ext_flags = pExtensions->Flags2; + pFormat += pExtensions->Size; } - if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT) - { - /* object is always the first argument */ - This = *(void **)ARG_FROM_OFFSET(args, 0); - NdrProxyInitialize(This, &rpcMsg, &stubMsg, pStubDesc, procedure_number); - } - else - NdrClientInitializeNew(&rpcMsg, &stubMsg, pStubDesc, procedure_number); - - /* create the full pointer translation tables, if requested */ - if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_FULLPTR) -#if 0 - stubMsg.FullPtrXlatTables = NdrFullPointerXlatInit(0,XLAT_CLIENT); -#else - FIXME("initialize full pointer translation tables\n"); -#endif - stubMsg.BufferLength = 0; /* store the RPC flags away */ if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCFLAGS) - rpcMsg.RpcFlags = ((NDR_PROC_HEADER_RPC *)pProcHeader)->rpc_flags; + rpcMsg.RpcFlags = ((const NDR_PROC_HEADER_RPC *)pProcHeader)->rpc_flags; /* use alternate memory allocation routines */ if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCSSALLOC) NdrRpcSmSetClientToOsf(&stubMsg); - if (Oif_flags & RPC_FC_PROC_OI2F_HASPIPES) + if (Oif_flags.HasPipes) { FIXME("pipes not supported yet\n"); RpcRaiseException(RPC_X_WRONG_STUB_VERSION); /* FIXME: remove when implemented */ /* init pipes package */ /* NdrPipesInitialize(...) */ } - if (ext_flags & RPC_FC_PROC_EXT_NEWCORRDESC) + if (ext_flags.HasNewCorrDesc) { /* initialize extra correlation package */ FIXME("new correlation description not implemented\n"); stubMsg.fHasNewCorrDesc = TRUE; } - parameter_start_offset = current_offset; - /* order of phases: * 1. PROXY_CALCSIZE - calculate the buffer size * 2. PROXY_GETBUFFER - allocate the buffer @@ -626,7 +684,7 @@ LONG_PTR WINAPIV NdrClientCall2(PMIDL_STUB_DESC pStubDesc, PFORMAT_STRING pForma /* allocate the buffer */ if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT) NdrProxyGetBuffer(This, &stubMsg); - else if (Oif_flags & RPC_FC_PROC_OI2F_HASPIPES) + else if (Oif_flags.HasPipes) /* NdrGetPipeBuffer(...) */ FIXME("pipes not supported yet\n"); else @@ -646,7 +704,7 @@ LONG_PTR WINAPIV NdrClientCall2(PMIDL_STUB_DESC pStubDesc, PFORMAT_STRING pForma * params */ if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT) NdrProxySendReceive(This, &stubMsg); - else if (Oif_flags & RPC_FC_PROC_OI2F_HASPIPES) + else if (Oif_flags.HasPipes) /* NdrPipesSendReceive(...) */ FIXME("pipes not supported yet\n"); else @@ -670,213 +728,13 @@ LONG_PTR WINAPIV NdrClientCall2(PMIDL_STUB_DESC pStubDesc, PFORMAT_STRING pForma case PROXY_CALCSIZE: case PROXY_MARSHAL: case PROXY_UNMARSHAL: - current_offset = parameter_start_offset; - current_stack_offset = 0; - - /* NOTE: V1 style format does't terminate on the number_of_params - * condition as it doesn't have this attribute. Instead it - * terminates when the stack size given in the header is exceeded. - */ - for (i = 0; i < number_of_params; i++) - { - if (bV2Format) /* new parameter format */ - { - NDR_PARAM_OIF_BASETYPE * pParam = - (NDR_PARAM_OIF_BASETYPE *)&pFormat[current_offset]; - unsigned char * pArg; - - current_stack_offset = pParam->stack_offset; - pArg = ARG_FROM_OFFSET(args, current_stack_offset); - - TRACE("param[%d]: new format\n", i); - TRACE("\tparam_attributes:"); dump_RPC_FC_PROC_PF(pParam->param_attributes); TRACE("\n"); - TRACE("\tstack_offset: 0x%x\n", current_stack_offset); - TRACE("\tmemory addr (before): %p\n", pArg); - - if (pParam->param_attributes.IsBasetype) - { - const unsigned char * pTypeFormat = - &pParam->type_format_char; - - if (pParam->param_attributes.IsSimpleRef) - pArg = *(unsigned char **)pArg; - - TRACE("\tbase type: 0x%02x\n", *pTypeFormat); - - switch (phase) - { - case PROXY_CALCSIZE: - if (pParam->param_attributes.IsIn) - call_buffer_sizer(&stubMsg, pArg, pTypeFormat); - break; - case PROXY_MARSHAL: - if (pParam->param_attributes.IsIn) - call_marshaller(&stubMsg, pArg, pTypeFormat); - break; - case PROXY_UNMARSHAL: - if (pParam->param_attributes.IsOut) - { - unsigned char *pRetVal = (unsigned char *)&RetVal; - if (pParam->param_attributes.IsReturn) - call_unmarshaller(&stubMsg, &pRetVal, pTypeFormat, 0); - else - call_unmarshaller(&stubMsg, &pArg, pTypeFormat, 0); - TRACE("pRetVal = %p\n", pRetVal); - } - break; - default: - RpcRaiseException(RPC_S_INTERNAL_ERROR); - } - - current_offset += sizeof(NDR_PARAM_OIF_BASETYPE); - } - else - { - NDR_PARAM_OIF_OTHER * pParamOther = - (NDR_PARAM_OIF_OTHER *)&pFormat[current_offset]; - - const unsigned char * pTypeFormat = - &(pStubDesc->pFormatTypes[pParamOther->type_offset]); - - /* if a simple ref pointer then we have to do the - * check for the pointer being non-NULL. */ - if (pParam->param_attributes.IsSimpleRef) - { - if (!*(unsigned char **)pArg) - RpcRaiseException(RPC_X_NULL_REF_POINTER); - } - - TRACE("\tcomplex type: 0x%02x\n", *pTypeFormat); - - switch (phase) - { - case PROXY_CALCSIZE: - if (pParam->param_attributes.IsIn) - { - if (pParam->param_attributes.IsByValue) - call_buffer_sizer(&stubMsg, pArg, pTypeFormat); - else - call_buffer_sizer(&stubMsg, *(unsigned char **)pArg, pTypeFormat); - } - break; - case PROXY_MARSHAL: - if (pParam->param_attributes.IsIn) - { - if (pParam->param_attributes.IsByValue) - call_marshaller(&stubMsg, pArg, pTypeFormat); - else - call_marshaller(&stubMsg, *(unsigned char **)pArg, pTypeFormat); - } - break; - case PROXY_UNMARSHAL: - if (pParam->param_attributes.IsOut) - { - unsigned char *pRetVal = (unsigned char *)&RetVal; - if (pParam->param_attributes.IsReturn) - call_unmarshaller(&stubMsg, &pRetVal, pTypeFormat, 0); - else if (pParam->param_attributes.IsByValue) - call_unmarshaller(&stubMsg, &pArg, pTypeFormat, 0); - else - call_unmarshaller(&stubMsg, (unsigned char **)pArg, pTypeFormat, 0); - } - break; - default: - RpcRaiseException(RPC_S_INTERNAL_ERROR); - } - - current_offset += sizeof(NDR_PARAM_OIF_OTHER); - } - TRACE("\tmemory addr (after): %p\n", pArg); - } - else /* old parameter format */ - { - NDR_PARAM_OI_BASETYPE * pParam = - (NDR_PARAM_OI_BASETYPE *)&pFormat[current_offset]; - unsigned char * pArg = ARG_FROM_OFFSET(args, current_stack_offset); - - /* no more parameters; exit loop */ - if (current_stack_offset > stack_size) - break; - - TRACE("param[%d]: old format\n", i); - TRACE("\tparam_direction: %x\n", pParam->param_direction); - TRACE("\tstack_offset: 0x%x\n", current_stack_offset); - TRACE("\tmemory addr (before): %p\n", pArg); - - if (pParam->param_direction == RPC_FC_IN_PARAM_BASETYPE || - pParam->param_direction == RPC_FC_RETURN_PARAM_BASETYPE) - { - const unsigned char * pTypeFormat = - &pParam->type_format_char; - - TRACE("\tbase type 0x%02x\n", *pTypeFormat); - - switch (phase) - { - case PROXY_CALCSIZE: - if (pParam->param_direction == RPC_FC_IN_PARAM_BASETYPE) - call_buffer_sizer(&stubMsg, pArg, pTypeFormat); - break; - case PROXY_MARSHAL: - if (pParam->param_direction == RPC_FC_IN_PARAM_BASETYPE) - call_marshaller(&stubMsg, pArg, pTypeFormat); - break; - case PROXY_UNMARSHAL: - if (pParam->param_direction == RPC_FC_RETURN_PARAM_BASETYPE) - { - if (pParam->param_direction & RPC_FC_RETURN_PARAM) - call_unmarshaller(&stubMsg, (unsigned char **)&RetVal, pTypeFormat, 0); - else - call_unmarshaller(&stubMsg, &pArg, pTypeFormat, 0); - } - break; - default: - RpcRaiseException(RPC_S_INTERNAL_ERROR); - } - - current_stack_offset += call_memory_sizer(&stubMsg, pTypeFormat); - current_offset += sizeof(NDR_PARAM_OI_BASETYPE); - } - else - { - NDR_PARAM_OI_OTHER * pParamOther = - (NDR_PARAM_OI_OTHER *)&pFormat[current_offset]; - - const unsigned char *pTypeFormat = - &pStubDesc->pFormatTypes[pParamOther->type_offset]; - - TRACE("\tcomplex type 0x%02x\n", *pTypeFormat); - - switch (phase) - { - case PROXY_CALCSIZE: - if (pParam->param_direction == RPC_FC_IN_PARAM || - pParam->param_direction & RPC_FC_IN_OUT_PARAM) - call_buffer_sizer(&stubMsg, pArg, pTypeFormat); - break; - case PROXY_MARSHAL: - if (pParam->param_direction == RPC_FC_IN_PARAM || - pParam->param_direction & RPC_FC_IN_OUT_PARAM) - call_marshaller(&stubMsg, pArg, pTypeFormat); - break; - case PROXY_UNMARSHAL: - if (pParam->param_direction == RPC_FC_IN_OUT_PARAM || - pParam->param_direction == RPC_FC_OUT_PARAM) - call_unmarshaller(&stubMsg, &pArg, pTypeFormat, 0); - else if (pParam->param_direction == RPC_FC_RETURN_PARAM) - call_unmarshaller(&stubMsg, (unsigned char **)&RetVal, pTypeFormat, 0); - break; - default: - RpcRaiseException(RPC_S_INTERNAL_ERROR); - } - - current_stack_offset += pParamOther->stack_size * sizeof(INT); - current_offset += sizeof(NDR_PARAM_OI_OTHER); - } - TRACE("\tmemory addr (after): %p\n", pArg); - } - } - + if (bV2Format) + client_do_args(&stubMsg, pFormat, phase, number_of_params, + (unsigned char *)&RetVal); + else + client_do_args_old_format(&stubMsg, pFormat, phase, stack_size, + (unsigned char *)&RetVal, + (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT)); break; default: ERR("shouldn't reach here. phase %d\n", phase); @@ -884,30 +742,29 @@ LONG_PTR WINAPIV NdrClientCall2(PMIDL_STUB_DESC pStubDesc, PFORMAT_STRING pForma } } - /* FIXME: unbind the binding handle */ - - if (ext_flags & RPC_FC_PROC_EXT_NEWCORRDESC) + if (ext_flags.HasNewCorrDesc) { /* free extra correlation package */ /* NdrCorrelationFree(&stubMsg); */ } - if (Oif_flags & RPC_FC_PROC_OI2F_HASPIPES) + if (Oif_flags.HasPipes) { /* NdrPipesDone(...) */ } -#if 0 /* free the full pointer translation tables */ if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_FULLPTR) NdrFullPointerXlatFree(stubMsg.FullPtrXlatTables); -#endif /* free marshalling buffer */ if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT) NdrProxyFreeBuffer(This, &stubMsg); else + { NdrFreeBuffer(&stubMsg); + client_free_handle(&stubMsg, pProcHeader, pHandleFormat, hBinding); + } TRACE("RetVal = 0x%lx\n", RetVal); @@ -936,9 +793,9 @@ __declspec(naked) LONG_PTR __cdecl call_server_func(SERVER_ROUTINE func, unsigne rep movsd ; Copy dword blocks call [ebp+8] ; Call function lea esp, [ebp-8] ; Restore stack - pop ebp ; Restore registers - pop esi + pop esi ; Restore registers pop edi + pop ebp ret } } @@ -951,7 +808,7 @@ __ASM_GLOBAL_FUNC(call_server_func, "pushl %esi\n\t" "movl 16(%ebp), %eax\n\t" /* Get stack size */ "subl %eax, %esp\n\t" /* Make room in stack for arguments */ - "andl $~15, %esp\n\t" /* Make sure stack has 16-byte alignment for MacOS X */ + "andl $~15, %esp\n\t" /* Make sure stack has 16-byte alignment for Mac OS X */ "movl %esp, %edi\n\t" "movl %eax, %ecx\n\t" "movl 12(%ebp), %esi\n\t" @@ -963,7 +820,7 @@ __ASM_GLOBAL_FUNC(call_server_func, "popl %esi\n\t" /* Restore registers */ "popl %edi\n\t" "popl %ebp\n\t" - "ret\n" ); + "ret\n" ) #else #warning call_server_func not implemented for your architecture LONG_PTR __cdecl call_server_func(SERVER_ROUTINE func, unsigned char * args, unsigned short stack_size) @@ -973,12 +830,347 @@ LONG_PTR __cdecl call_server_func(SERVER_ROUTINE func, unsigned char * args, uns } #endif -/* FIXME: need to free some stuff in here too */ -long WINAPI NdrStubCall2( +static DWORD calc_arg_size(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat) +{ + DWORD size; + switch(*pFormat) + { + case RPC_FC_STRUCT: + size = *(const WORD*)(pFormat + 2); + break; + case RPC_FC_CARRAY: + size = *(const WORD*)(pFormat + 2); + ComputeConformance(pStubMsg, NULL, pFormat + 4, 0); + size *= pStubMsg->MaxCount; + break; + case RPC_FC_SMFARRAY: + size = *(const WORD*)(pFormat + 2); + break; + case RPC_FC_LGFARRAY: + size = *(const DWORD*)(pFormat + 2); + break; + default: + FIXME("Unhandled type %02x\n", *pFormat); + /* fallthrough */ + case RPC_FC_RP: + size = sizeof(void *); + break; + } + return size; +} + +static LONG_PTR *stub_do_args(MIDL_STUB_MESSAGE *pStubMsg, + PFORMAT_STRING pFormat, int phase, + unsigned char *args, + unsigned short number_of_params) +{ + /* counter */ + unsigned short i; + /* current format string offset */ + int current_offset = 0; + /* current stack offset */ + unsigned short current_stack_offset = 0; + /* location to put retval into */ + LONG_PTR *retval_ptr = NULL; + + for (i = 0; i < number_of_params; i++) + { + const NDR_PARAM_OIF_BASETYPE *pParam = + (const NDR_PARAM_OIF_BASETYPE *)&pFormat[current_offset]; + unsigned char *pArg; + + current_stack_offset = pParam->stack_offset; + pArg = (unsigned char *)(args+current_stack_offset); + + TRACE("param[%d]: new format\n", i); + TRACE("\tparam_attributes:"); dump_RPC_FC_PROC_PF(pParam->param_attributes); TRACE("\n"); + TRACE("\tstack_offset: 0x%x\n", current_stack_offset); + TRACE("\tmemory addr (before): %p -> %p\n", pArg, *(unsigned char **)pArg); + + if (pParam->param_attributes.IsBasetype) + { + const unsigned char *pTypeFormat = + &pParam->type_format_char; + + TRACE("\tbase type: 0x%02x\n", *pTypeFormat); + + switch (phase) + { + case STUBLESS_MARSHAL: + if (pParam->param_attributes.IsOut || pParam->param_attributes.IsReturn) + { + if (pParam->param_attributes.IsSimpleRef) + call_marshaller(pStubMsg, *(unsigned char **)pArg, pTypeFormat); + else + call_marshaller(pStubMsg, pArg, pTypeFormat); + } + break; + case STUBLESS_FREE: + if (pParam->param_attributes.ServerAllocSize) + HeapFree(GetProcessHeap(), 0, *(void **)pArg); + break; + case STUBLESS_UNMARSHAL: + if (pParam->param_attributes.ServerAllocSize) + *(void **)pArg = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + pParam->param_attributes.ServerAllocSize * 8); + + if (pParam->param_attributes.IsIn) + { + if (pParam->param_attributes.IsSimpleRef) + call_unmarshaller(pStubMsg, (unsigned char **)pArg, pTypeFormat, 0); + else + call_unmarshaller(pStubMsg, &pArg, pTypeFormat, 0); + } + + /* make a note of the address of the return value parameter for later */ + if (pParam->param_attributes.IsReturn) + retval_ptr = (LONG_PTR *)pArg; + + break; + case STUBLESS_CALCSIZE: + if (pParam->param_attributes.IsOut || pParam->param_attributes.IsReturn) + { + if (pParam->param_attributes.IsSimpleRef) + call_buffer_sizer(pStubMsg, *(unsigned char **)pArg, pTypeFormat); + else + call_buffer_sizer(pStubMsg, pArg, pTypeFormat); + } + break; + default: + RpcRaiseException(RPC_S_INTERNAL_ERROR); + } + + current_offset += sizeof(NDR_PARAM_OIF_BASETYPE); + } + else + { + const NDR_PARAM_OIF_OTHER *pParamOther = + (const NDR_PARAM_OIF_OTHER *)&pFormat[current_offset]; + + const unsigned char * pTypeFormat = + &(pStubMsg->StubDesc->pFormatTypes[pParamOther->type_offset]); + + TRACE("\tcomplex type 0x%02x\n", *pTypeFormat); + + switch (phase) + { + case STUBLESS_MARSHAL: + if (pParam->param_attributes.IsOut || pParam->param_attributes.IsReturn) + { + if (pParam->param_attributes.IsByValue) + call_marshaller(pStubMsg, pArg, pTypeFormat); + else + call_marshaller(pStubMsg, *(unsigned char **)pArg, pTypeFormat); + } + break; + case STUBLESS_FREE: + if (pParam->param_attributes.MustFree) + { + if (pParam->param_attributes.IsByValue) + call_freer(pStubMsg, pArg, pTypeFormat); + else + call_freer(pStubMsg, *(unsigned char **)pArg, pTypeFormat); + } + + if (pParam->param_attributes.IsOut && + !pParam->param_attributes.IsIn && + !pParam->param_attributes.IsByValue && + !pParam->param_attributes.ServerAllocSize) + { + pStubMsg->pfnFree(*(void **)pArg); + } + + if (pParam->param_attributes.ServerAllocSize) + HeapFree(GetProcessHeap(), 0, *(void **)pArg); + /* FIXME: call call_freer here for IN types with MustFree set */ + break; + case STUBLESS_UNMARSHAL: + if (pParam->param_attributes.ServerAllocSize) + *(void **)pArg = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + pParam->param_attributes.ServerAllocSize * 8); + + if (pParam->param_attributes.IsIn) + { + if (pParam->param_attributes.IsByValue) + call_unmarshaller(pStubMsg, &pArg, pTypeFormat, 0); + else + call_unmarshaller(pStubMsg, (unsigned char **)pArg, pTypeFormat, 0); + } + else if (pParam->param_attributes.IsOut && + !pParam->param_attributes.ServerAllocSize && + !pParam->param_attributes.IsByValue) + { + DWORD size = calc_arg_size(pStubMsg, pTypeFormat); + + if(size) + { + *(void **)pArg = NdrAllocate(pStubMsg, size); + memset(*(void **)pArg, 0, size); + } + } + break; + case STUBLESS_CALCSIZE: + if (pParam->param_attributes.IsOut || pParam->param_attributes.IsReturn) + { + if (pParam->param_attributes.IsByValue) + call_buffer_sizer(pStubMsg, pArg, pTypeFormat); + else + call_buffer_sizer(pStubMsg, *(unsigned char **)pArg, pTypeFormat); + } + break; + default: + RpcRaiseException(RPC_S_INTERNAL_ERROR); + } + + current_offset += sizeof(NDR_PARAM_OIF_OTHER); + } + TRACE("\tmemory addr (after): %p -> %p\n", pArg, *(unsigned char **)pArg); + } + + return retval_ptr; +} + +static LONG_PTR *stub_do_old_args(MIDL_STUB_MESSAGE *pStubMsg, + PFORMAT_STRING pFormat, int phase, + unsigned char *args, + unsigned short stack_size, BOOL object) +{ + /* counter */ + unsigned short i; + /* current format string offset */ + int current_offset = 0; + /* current stack offset */ + unsigned short current_stack_offset = 0; + /* location to put retval into */ + LONG_PTR *retval_ptr = NULL; + + for (i = 0; TRUE; i++) + { + const NDR_PARAM_OI_BASETYPE *pParam = + (const NDR_PARAM_OI_BASETYPE *)&pFormat[current_offset]; + /* note: current_stack_offset starts after the This pointer + * if present, so adjust this */ + unsigned short current_stack_offset_adjusted = current_stack_offset + + (object ? sizeof(void *) : 0); + unsigned char *pArg = (unsigned char *)(args+current_stack_offset_adjusted); + + /* no more parameters; exit loop */ + if (current_stack_offset_adjusted >= stack_size) + break; + + TRACE("param[%d]: old format\n", i); + TRACE("\tparam_direction: 0x%x\n", pParam->param_direction); + TRACE("\tstack_offset: 0x%x\n", current_stack_offset_adjusted); + + if (pParam->param_direction == RPC_FC_IN_PARAM_BASETYPE || + pParam->param_direction == RPC_FC_RETURN_PARAM_BASETYPE) + { + const unsigned char *pTypeFormat = + &pParam->type_format_char; + + TRACE("\tbase type 0x%02x\n", *pTypeFormat); + + switch (phase) + { + case STUBLESS_MARSHAL: + if (pParam->param_direction == RPC_FC_RETURN_PARAM_BASETYPE) + call_marshaller(pStubMsg, pArg, pTypeFormat); + break; + case STUBLESS_FREE: + if (pParam->param_direction == RPC_FC_IN_PARAM_BASETYPE) + call_freer(pStubMsg, pArg, pTypeFormat); + break; + case STUBLESS_UNMARSHAL: + if (pParam->param_direction == RPC_FC_IN_PARAM_BASETYPE) + call_unmarshaller(pStubMsg, &pArg, pTypeFormat, 0); + else if (pParam->param_direction == RPC_FC_RETURN_PARAM_BASETYPE) + retval_ptr = (LONG_PTR *)pArg; + break; + case STUBLESS_CALCSIZE: + if (pParam->param_direction == RPC_FC_RETURN_PARAM_BASETYPE) + call_buffer_sizer(pStubMsg, pArg, pTypeFormat); + break; + default: + RpcRaiseException(RPC_S_INTERNAL_ERROR); + } + + current_stack_offset += call_memory_sizer(pStubMsg, pTypeFormat); + current_offset += sizeof(NDR_PARAM_OI_BASETYPE); + } + else + { + const NDR_PARAM_OI_OTHER *pParamOther = + (const NDR_PARAM_OI_OTHER *)&pFormat[current_offset]; + + const unsigned char * pTypeFormat = + &pStubMsg->StubDesc->pFormatTypes[pParamOther->type_offset]; + + TRACE("\tcomplex type 0x%02x\n", *pTypeFormat); + + switch (phase) + { + case STUBLESS_MARSHAL: + if (pParam->param_direction == RPC_FC_OUT_PARAM || + pParam->param_direction == RPC_FC_IN_OUT_PARAM || + pParam->param_direction == RPC_FC_RETURN_PARAM) + call_marshaller(pStubMsg, *(unsigned char **)pArg, pTypeFormat); + break; + case STUBLESS_FREE: + if (pParam->param_direction == RPC_FC_IN_OUT_PARAM || + pParam->param_direction == RPC_FC_IN_PARAM) + call_freer(pStubMsg, *(unsigned char **)pArg, pTypeFormat); + else if (pParam->param_direction == RPC_FC_OUT_PARAM) + pStubMsg->pfnFree(*(void **)pArg); + break; + case STUBLESS_UNMARSHAL: + if (pParam->param_direction == RPC_FC_IN_OUT_PARAM || + pParam->param_direction == RPC_FC_IN_PARAM) + call_unmarshaller(pStubMsg, (unsigned char **)pArg, pTypeFormat, 0); + else if (pParam->param_direction == RPC_FC_RETURN_PARAM) + retval_ptr = (LONG_PTR *)pArg; + else if (pParam->param_direction == RPC_FC_OUT_PARAM) + { + DWORD size = calc_arg_size(pStubMsg, pTypeFormat); + + if(size) + { + *(void **)pArg = NdrAllocate(pStubMsg, size); + memset(*(void **)pArg, 0, size); + } + } + break; + case STUBLESS_CALCSIZE: + if (pParam->param_direction == RPC_FC_OUT_PARAM || + pParam->param_direction == RPC_FC_IN_OUT_PARAM || + pParam->param_direction == RPC_FC_RETURN_PARAM) + call_buffer_sizer(pStubMsg, *(unsigned char **)pArg, pTypeFormat); + break; + default: + RpcRaiseException(RPC_S_INTERNAL_ERROR); + } + + current_stack_offset += pParamOther->stack_size * sizeof(INT); + current_offset += sizeof(NDR_PARAM_OI_OTHER); + } + } + + return retval_ptr; +} + +/*********************************************************************** + * NdrStubCall2 [RPCRT4.@] + * + * Unmarshals [in] parameters, calls either a method in an object or a server + * function, marshals any [out] parameters and frees any allocated data. + * + * NOTES + * Used by stubless MIDL-generated code. + */ +LONG WINAPI NdrStubCall2( struct IRpcStubBuffer * pThis, struct IRpcChannelBuffer * pChannel, PRPC_MESSAGE pRpcMsg, - unsigned long * pdwStubPhase) + DWORD * pdwStubPhase) { const MIDL_SERVER_INFO *pServerInfo; const MIDL_STUB_DESC *pStubDesc; @@ -988,16 +1180,12 @@ long WINAPI NdrStubCall2( unsigned char * args; /* size of stack */ unsigned short stack_size; - /* current stack offset */ - unsigned short current_stack_offset; /* number of parameters. optional for client to give it to us */ unsigned char number_of_params = ~0; - /* counter */ - unsigned short i; /* cache of Oif_flags from v2 procedure header */ - unsigned char Oif_flags = 0; - /* cache of extension flags from NDR_PROC_EXTENSION */ - unsigned char ext_flags = 0; + INTERPRETER_OPT_FLAGS Oif_flags = { 0 }; + /* cache of extension flags from NDR_PROC_HEADER_EXTS */ + INTERPRETER_OPT_FLAGS2 ext_flags = { 0 }; /* the type of pass we are currently doing */ int phase; /* header for procedure string */ @@ -1008,9 +1196,8 @@ long WINAPI NdrStubCall2( int current_offset; /* -Oif or -Oicf generated format */ BOOL bV2Format = FALSE; - /* the return value (not from this function, but to be put back onto - * the wire */ - LONG_PTR RetVal = 0; + /* location to put retval into */ + LONG_PTR *retval_ptr = NULL; TRACE("pThis %p, pChannel %p, pRpcMsg %p, pdwStubPhase %p\n", pThis, pChannel, pRpcMsg, pdwStubPhase); @@ -1026,13 +1213,17 @@ long WINAPI NdrStubCall2( /* Later NDR language versions probably won't be backwards compatible */ if (pStubDesc->Version > 0x50002) { - FIXME("Incompatible stub description version: 0x%lx\n", pStubDesc->Version); + FIXME("Incompatible stub description version: 0x%x\n", pStubDesc->Version); RpcRaiseException(RPC_X_WRONG_STUB_VERSION); } + /* create the full pointer translation tables, if requested */ + if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_FULLPTR) + stubMsg.FullPtrXlatTables = NdrFullPointerXlatInit(0,XLAT_SERVER); + if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCFLAGS) { - NDR_PROC_HEADER_RPC * pProcHeader = (NDR_PROC_HEADER_RPC *)&pFormat[0]; + const NDR_PROC_HEADER_RPC *pProcHeader = (const NDR_PROC_HEADER_RPC *)&pFormat[0]; stack_size = pProcHeader->stack_size; current_offset = sizeof(NDR_PROC_HEADER_RPC); @@ -1080,23 +1271,23 @@ long WINAPI NdrStubCall2( if (bV2Format) { - NDR_PROC_PARTIAL_OIF_HEADER * pOIFHeader = - (NDR_PROC_PARTIAL_OIF_HEADER*)&pFormat[current_offset]; + const NDR_PROC_PARTIAL_OIF_HEADER *pOIFHeader = + (const NDR_PROC_PARTIAL_OIF_HEADER *)&pFormat[current_offset]; - Oif_flags = pOIFHeader->Oif_flags; + Oif_flags = pOIFHeader->Oi2Flags; number_of_params = pOIFHeader->number_of_params; current_offset += sizeof(NDR_PROC_PARTIAL_OIF_HEADER); } - TRACE("Oif_flags = 0x%02x\n", Oif_flags); + TRACE("Oif_flags = "); dump_INTERPRETER_OPT_FLAGS(Oif_flags); - if (Oif_flags & RPC_FC_PROC_OI2F_HASEXTS) + if (Oif_flags.HasExtensions) { - NDR_PROC_EXTENSION * pExtensions = - (NDR_PROC_EXTENSION *)&pFormat[current_offset]; - ext_flags = pExtensions->ext_flags; - current_offset += pExtensions->extension_version; + const NDR_PROC_HEADER_EXTS *pExtensions = + (const NDR_PROC_HEADER_EXTS *)&pFormat[current_offset]; + ext_flags = pExtensions->Flags2; + current_offset += pExtensions->Size; } if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT) @@ -1104,17 +1295,9 @@ long WINAPI NdrStubCall2( else NdrServerInitializeNew(pRpcMsg, &stubMsg, pStubDesc); - /* create the full pointer translation tables, if requested */ - if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_FULLPTR) -#if 0 - stubMsg.FullPtrXlatTables = NdrFullPointerXlatInit(0,XLAT_SERVER); -#else - FIXME("initialize full pointer translation tables\n"); -#endif - /* store the RPC flags away */ if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCFLAGS) - pRpcMsg->RpcFlags = ((NDR_PROC_HEADER_RPC *)pProcHeader)->rpc_flags; + pRpcMsg->RpcFlags = ((const NDR_PROC_HEADER_RPC *)pProcHeader)->rpc_flags; /* use alternate memory allocation routines */ if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCSSALLOC) @@ -1124,21 +1307,20 @@ long WINAPI NdrStubCall2( FIXME("Set RPCSS memory allocation routines\n"); #endif - if (Oif_flags & RPC_FC_PROC_OI2F_HASPIPES) + if (Oif_flags.HasPipes) { FIXME("pipes not supported yet\n"); RpcRaiseException(RPC_X_WRONG_STUB_VERSION); /* FIXME: remove when implemented */ /* init pipes package */ /* NdrPipesInitialize(...) */ } - if (ext_flags & RPC_FC_PROC_EXT_NEWCORRDESC) + if (ext_flags.HasNewCorrDesc) { /* initialize extra correlation package */ FIXME("new correlation description not implemented\n"); stubMsg.fHasNewCorrDesc = TRUE; } - /* convert strings, floating point values and endianess into our * preferred format */ if ((pRpcMsg->DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION) @@ -1148,8 +1330,8 @@ long WINAPI NdrStubCall2( TRACE("allocating memory for stack of size %x\n", stack_size); - args = HeapAlloc(GetProcessHeap(), 0, stack_size); - ZeroMemory(args, stack_size); + args = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, stack_size); + stubMsg.StackTop = args; /* used by conformance of top-level objects */ /* add the implicit This pointer as the first arg to the function if we * are calling an object method */ @@ -1163,28 +1345,39 @@ long WINAPI NdrStubCall2( * 4. STUBLESS_GETBUFFER - allocate [out] buffer * 5. STUBLESS_MARHSAL - marshal [out] params to buffer */ - for (phase = STUBLESS_UNMARSHAL; phase <= STUBLESS_MARSHAL; phase++) + for (phase = STUBLESS_UNMARSHAL; phase <= STUBLESS_FREE; phase++) { TRACE("phase = %d\n", phase); switch (phase) { case STUBLESS_CALLSERVER: /* call the server function */ - if (pServerInfo->ThunkTable) - { - stubMsg.StackTop = args; + if (pServerInfo->ThunkTable && pServerInfo->ThunkTable[pRpcMsg->ProcNum]) pServerInfo->ThunkTable[pRpcMsg->ProcNum](&stubMsg); - /* FIXME: RetVal is stored as the last argument - retrieve it */ - } - else if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT) - { - SERVER_ROUTINE *vtbl = *(SERVER_ROUTINE **)((CStdStubBuffer *)pThis)->pvServerObject; - RetVal = call_server_func(vtbl[pRpcMsg->ProcNum], args, stack_size); - } else - RetVal = call_server_func(pServerInfo->DispatchTable[pRpcMsg->ProcNum], args, stack_size); + { + SERVER_ROUTINE func; + LONG_PTR retval; - TRACE("stub implementation returned %p\n", (void *)RetVal); + if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT) + { + SERVER_ROUTINE *vtbl = *(SERVER_ROUTINE **)((CStdStubBuffer *)pThis)->pvServerObject; + func = vtbl[pRpcMsg->ProcNum]; + } + else + func = pServerInfo->DispatchTable[pRpcMsg->ProcNum]; + + /* FIXME: what happens with return values that don't fit into a single register on x86? */ + retval = call_server_func(func, args, stack_size); + + if (retval_ptr) + { + TRACE("stub implementation returned 0x%lx\n", retval); + *retval_ptr = retval; + } + else + TRACE("void stub implementation\n"); + } stubMsg.Buffer = NULL; stubMsg.BufferLength = 0; @@ -1210,234 +1403,14 @@ long WINAPI NdrStubCall2( case STUBLESS_MARSHAL: case STUBLESS_UNMARSHAL: case STUBLESS_CALCSIZE: - current_offset = parameter_start_offset; - current_stack_offset = 0; - - /* NOTE: V1 style format does't terminate on the number_of_params - * condition as it doesn't have this attribute. Instead it - * terminates when the stack size given in the header is exceeded. - */ - for (i = 0; i < number_of_params; i++) - { - if (bV2Format) /* new parameter format */ - { - const NDR_PARAM_OIF_BASETYPE *pParam = - (NDR_PARAM_OIF_BASETYPE *)&pFormat[current_offset]; - unsigned char *pArg; - - current_stack_offset = pParam->stack_offset; - pArg = (unsigned char *)(args+current_stack_offset); - - TRACE("param[%d]: new format\n", i); - TRACE("\tparam_attributes:"); dump_RPC_FC_PROC_PF(pParam->param_attributes); TRACE("\n"); - TRACE("\tstack_offset: %x\n", current_stack_offset); - TRACE("\tmemory addr (before): %p -> %p\n", pArg, *(unsigned char **)pArg); - - if (pParam->param_attributes.ServerAllocSize) - FIXME("ServerAllocSize of %d ignored for parameter %d\n", - pParam->param_attributes.ServerAllocSize * 8, i); - - if (pParam->param_attributes.IsBasetype) - { - const unsigned char *pTypeFormat = - &pParam->type_format_char; - - TRACE("\tbase type: 0x%02x\n", *pTypeFormat); - - switch (phase) - { - case STUBLESS_MARSHAL: - if (pParam->param_attributes.IsReturn) - call_marshaller(&stubMsg, (unsigned char *)&RetVal, pTypeFormat); - else if (pParam->param_attributes.IsOut) - { - if (pParam->param_attributes.IsSimpleRef) - call_marshaller(&stubMsg, *(unsigned char **)pArg, pTypeFormat); - else - call_marshaller(&stubMsg, pArg, pTypeFormat); - } - /* FIXME: call call_freer here */ - break; - case STUBLESS_UNMARSHAL: - if (pParam->param_attributes.IsIn) - { - if (pParam->param_attributes.IsSimpleRef) - call_unmarshaller(&stubMsg, (unsigned char **)pArg, pTypeFormat, 0); - else - call_unmarshaller(&stubMsg, &pArg, pTypeFormat, 0); - } - break; - case STUBLESS_CALCSIZE: - if (pParam->param_attributes.IsReturn) - call_buffer_sizer(&stubMsg, (unsigned char *)&RetVal, pTypeFormat); - else if (pParam->param_attributes.IsOut) - { - if (pParam->param_attributes.IsSimpleRef) - call_buffer_sizer(&stubMsg, *(unsigned char **)pArg, pTypeFormat); - else - call_buffer_sizer(&stubMsg, pArg, pTypeFormat); - } - break; - default: - RpcRaiseException(RPC_S_INTERNAL_ERROR); - } - - current_offset += sizeof(NDR_PARAM_OIF_BASETYPE); - } - else - { - NDR_PARAM_OIF_OTHER * pParamOther = - (NDR_PARAM_OIF_OTHER *)&pFormat[current_offset]; - - const unsigned char * pTypeFormat = - &(pStubDesc->pFormatTypes[pParamOther->type_offset]); - - TRACE("\tcomplex type 0x%02x\n", *pTypeFormat); - - switch (phase) - { - case STUBLESS_MARSHAL: - if (pParam->param_attributes.IsReturn) - call_marshaller(&stubMsg, (unsigned char *)&RetVal, pTypeFormat); - else if (pParam->param_attributes.IsOut) - { - if (pParam->param_attributes.IsByValue) - call_marshaller(&stubMsg, pArg, pTypeFormat); - else - { - call_marshaller(&stubMsg, *(unsigned char **)pArg, pTypeFormat); - stubMsg.pfnFree(*(void **)pArg); - } - } - /* FIXME: call call_freer here for IN types */ - break; - case STUBLESS_UNMARSHAL: - if (pParam->param_attributes.IsIn) - { - if (pParam->param_attributes.IsByValue) - call_unmarshaller(&stubMsg, &pArg, pTypeFormat, 0); - else - call_unmarshaller(&stubMsg, (unsigned char **)pArg, pTypeFormat, 0); - } - else if ((pParam->param_attributes.IsOut) && - !(pParam->param_attributes.IsByValue)) - { - *(void **)pArg = NdrAllocate(&stubMsg, sizeof(void *)); - **(void ***)pArg = 0; - } - break; - case STUBLESS_CALCSIZE: - if (pParam->param_attributes.IsReturn) - call_buffer_sizer(&stubMsg, (unsigned char *)&RetVal, pTypeFormat); - else if (pParam->param_attributes.IsOut) - { - if (pParam->param_attributes.IsByValue) - call_buffer_sizer(&stubMsg, pArg, pTypeFormat); - else - call_buffer_sizer(&stubMsg, *(unsigned char **)pArg, pTypeFormat); - } - break; - default: - RpcRaiseException(RPC_S_INTERNAL_ERROR); - } - - current_offset += sizeof(NDR_PARAM_OIF_OTHER); - } - TRACE("\tmemory addr (after): %p -> %p\n", pArg, *(unsigned char **)pArg); - } - else /* old parameter format */ - { - NDR_PARAM_OI_BASETYPE *pParam = - (NDR_PARAM_OI_BASETYPE *)&pFormat[current_offset]; - unsigned char *pArg = (unsigned char *)(args+current_stack_offset); - - /* no more parameters; exit loop */ - if (current_stack_offset > stack_size) - break; - - TRACE("param[%d]: old format\n\tparam_direction: 0x%x\n", i, pParam->param_direction); - - if (pParam->param_direction == RPC_FC_IN_PARAM_BASETYPE || - pParam->param_direction == RPC_FC_RETURN_PARAM_BASETYPE) - { - const unsigned char *pTypeFormat = - &pParam->type_format_char; - - TRACE("\tbase type 0x%02x\n", *pTypeFormat); - - switch (phase) - { - case STUBLESS_MARSHAL: - if (pParam->param_direction == RPC_FC_RETURN_PARAM_BASETYPE) - { - unsigned char *pRetVal = (unsigned char *)&RetVal; - call_marshaller(&stubMsg, (unsigned char *)&pRetVal, pTypeFormat); - } - break; - case STUBLESS_UNMARSHAL: - if (pParam->param_direction == RPC_FC_IN_PARAM_BASETYPE) - call_unmarshaller(&stubMsg, &pArg, pTypeFormat, 0); - break; - case STUBLESS_CALCSIZE: - if (pParam->param_direction == RPC_FC_RETURN_PARAM_BASETYPE) - { - unsigned char * pRetVal = (unsigned char *)&RetVal; - call_buffer_sizer(&stubMsg, (unsigned char *)&pRetVal, pTypeFormat); - } - break; - default: - RpcRaiseException(RPC_S_INTERNAL_ERROR); - } - - current_stack_offset += call_memory_sizer(&stubMsg, pTypeFormat); - current_offset += sizeof(NDR_PARAM_OI_BASETYPE); - } - else - { - NDR_PARAM_OI_OTHER * pParamOther = - (NDR_PARAM_OI_OTHER *)&pFormat[current_offset]; - - const unsigned char * pTypeFormat = - &pStubDesc->pFormatTypes[pParamOther->type_offset]; - - TRACE("\tcomplex type 0x%02x\n", *pTypeFormat); - - switch (phase) - { - case STUBLESS_MARSHAL: - if (pParam->param_direction == RPC_FC_RETURN_PARAM) - { - unsigned char *pRetVal = (unsigned char *)&RetVal; - call_marshaller(&stubMsg, (unsigned char *)&pRetVal, pTypeFormat); - } - else if (pParam->param_direction == RPC_FC_OUT_PARAM || - pParam->param_direction == RPC_FC_IN_OUT_PARAM) - call_marshaller(&stubMsg, pArg, pTypeFormat); - break; - case STUBLESS_UNMARSHAL: - if (pParam->param_direction == RPC_FC_IN_OUT_PARAM || - pParam->param_direction == RPC_FC_IN_PARAM) - call_unmarshaller(&stubMsg, &pArg, pTypeFormat, 0); - break; - case STUBLESS_CALCSIZE: - if (pParam->param_direction == RPC_FC_RETURN_PARAM) - { - unsigned char * pRetVal = (unsigned char *)&RetVal; - call_buffer_sizer(&stubMsg, (unsigned char *)&pRetVal, pTypeFormat); - } - else if (pParam->param_direction == RPC_FC_OUT_PARAM || - pParam->param_direction == RPC_FC_IN_OUT_PARAM) - call_buffer_sizer(&stubMsg, pArg, pTypeFormat); - break; - default: - RpcRaiseException(RPC_S_INTERNAL_ERROR); - } - - current_stack_offset += pParamOther->stack_size * sizeof(INT); - current_offset += sizeof(NDR_PARAM_OI_OTHER); - } - } - } + case STUBLESS_FREE: + if (bV2Format) + retval_ptr = stub_do_args(&stubMsg, &pFormat[parameter_start_offset], + phase, args, number_of_params); + else + retval_ptr = stub_do_old_args(&stubMsg, &pFormat[parameter_start_offset], + phase, args, stack_size, + (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT)); break; default: @@ -1448,22 +1421,20 @@ long WINAPI NdrStubCall2( pRpcMsg->BufferLength = (unsigned int)(stubMsg.Buffer - (unsigned char *)pRpcMsg->Buffer); - if (ext_flags & RPC_FC_PROC_EXT_NEWCORRDESC) + if (ext_flags.HasNewCorrDesc) { /* free extra correlation package */ /* NdrCorrelationFree(&stubMsg); */ } - if (Oif_flags & RPC_FC_PROC_OI2F_HASPIPES) + if (Oif_flags.HasPipes) { /* NdrPipesDone(...) */ } -#if 0 /* free the full pointer translation tables */ if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_FULLPTR) NdrFullPointerXlatFree(stubMsg.FullPtrXlatTables); -#endif /* free server function stack */ HeapFree(GetProcessHeap(), 0, args); @@ -1471,6 +1442,9 @@ long WINAPI NdrStubCall2( return S_OK; } +/*********************************************************************** + * NdrServerCall2 [RPCRT4.@] + */ void WINAPI NdrServerCall2(PRPC_MESSAGE pRpcMsg) { DWORD dwPhase; diff --git a/reactos/dll/win32/rpcrt4_new/ndr_stubless.h b/reactos/dll/win32/rpcrt4/ndr_stubless.h similarity index 100% rename from reactos/dll/win32/rpcrt4_new/ndr_stubless.h rename to reactos/dll/win32/rpcrt4/ndr_stubless.h diff --git a/reactos/dll/win32/rpcrt4_new/rpc_assoc.c b/reactos/dll/win32/rpcrt4/rpc_assoc.c similarity index 100% rename from reactos/dll/win32/rpcrt4_new/rpc_assoc.c rename to reactos/dll/win32/rpcrt4/rpc_assoc.c diff --git a/reactos/dll/win32/rpcrt4_new/rpc_assoc.h b/reactos/dll/win32/rpcrt4/rpc_assoc.h similarity index 100% rename from reactos/dll/win32/rpcrt4_new/rpc_assoc.h rename to reactos/dll/win32/rpcrt4/rpc_assoc.h diff --git a/reactos/dll/win32/rpcrt4/rpc_binding.c b/reactos/dll/win32/rpcrt4/rpc_binding.c index 88e52034ff0..24769e2ce60 100644 --- a/reactos/dll/win32/rpcrt4/rpc_binding.c +++ b/reactos/dll/win32/rpcrt4/rpc_binding.c @@ -4,6 +4,7 @@ * Copyright 2001 Ove Kåven, TransGaming Technologies * Copyright 2003 Mike Hearn * Copyright 2004 Filip Navara + * Copyright 2006 CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -17,10 +18,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * TODO: - * - a whole lot + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include @@ -32,7 +30,6 @@ #include "winbase.h" #include "winnls.h" #include "winerror.h" -#include "winreg.h" #include "winternl.h" #include "wine/unicode.h" @@ -42,7 +39,7 @@ #include "wine/debug.h" #include "rpc_binding.h" -#include "rpc_message.h" +#include "rpc_assoc.h" WINE_DEFAULT_DEBUG_CHANNEL(rpc); @@ -59,7 +56,7 @@ LPSTR RPCRT4_strndupA(LPCSTR src, INT slen) return s; } -LPSTR RPCRT4_strdupWtoA(LPWSTR src) +LPSTR RPCRT4_strdupWtoA(LPCWSTR src) { DWORD len; LPSTR s; @@ -70,7 +67,7 @@ LPSTR RPCRT4_strdupWtoA(LPWSTR src) return s; } -LPWSTR RPCRT4_strdupAtoW(LPSTR src) +LPWSTR RPCRT4_strdupAtoW(LPCSTR src) { DWORD len; LPWSTR s; @@ -81,7 +78,18 @@ LPWSTR RPCRT4_strdupAtoW(LPSTR src) return s; } -LPWSTR RPCRT4_strndupW(LPWSTR src, INT slen) +static LPWSTR RPCRT4_strndupAtoW(LPCSTR src, INT slen) +{ + DWORD len; + LPWSTR s; + if (!src) return NULL; + len = MultiByteToWideChar(CP_ACP, 0, src, slen, NULL, 0); + s = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, src, slen, s, len); + return s; +} + +LPWSTR RPCRT4_strndupW(LPCWSTR src, INT slen) { DWORD len; LPWSTR s; @@ -99,219 +107,6 @@ void RPCRT4_strfree(LPSTR src) HeapFree(GetProcessHeap(), 0, src); } -RPC_STATUS RPCRT4_CreateConnection(RpcConnection** Connection, BOOL server, LPSTR Protseq, LPSTR NetworkAddr, LPSTR Endpoint, LPSTR NetworkOptions, RpcBinding* Binding) -{ - RpcConnection* NewConnection; - - NewConnection = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RpcConnection)); - NewConnection->server = server; - NewConnection->Protseq = RPCRT4_strdupA(Protseq); - NewConnection->NetworkAddr = RPCRT4_strdupA(NetworkAddr); - NewConnection->Endpoint = RPCRT4_strdupA(Endpoint); - NewConnection->Used = Binding; - NewConnection->MaxTransmissionSize = RPC_MAX_PACKET_SIZE; - - TRACE("connection: %p\n", NewConnection); - *Connection = NewConnection; - - return RPC_S_OK; -} - -RPC_STATUS RPCRT4_DestroyConnection(RpcConnection* Connection) -{ - TRACE("connection: %p\n", Connection); - - RPCRT4_CloseConnection(Connection); - RPCRT4_strfree(Connection->Endpoint); - RPCRT4_strfree(Connection->NetworkAddr); - RPCRT4_strfree(Connection->Protseq); - HeapFree(GetProcessHeap(), 0, Connection); - return RPC_S_OK; -} - -RPC_STATUS RPCRT4_OpenConnection(RpcConnection* Connection) -{ - TRACE("(Connection == ^%p)\n", Connection); - if (!Connection->conn) { - if (Connection->server) { /* server */ - /* protseq=ncalrpc: supposed to use NT LPC ports, - * but we'll implement it with named pipes for now */ - if (strcmp(Connection->Protseq, "ncalrpc") == 0) { - static LPCSTR prefix = "\\\\.\\pipe\\lrpc\\"; - LPSTR pname; - pname = HeapAlloc(GetProcessHeap(), 0, strlen(prefix) + strlen(Connection->Endpoint) + 1); - strcat(strcpy(pname, prefix), Connection->Endpoint); - TRACE("listening on %s\n", pname); - Connection->conn = CreateNamedPipeA(pname, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, - PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, PIPE_UNLIMITED_INSTANCES, - RPC_MAX_PACKET_SIZE, RPC_MAX_PACKET_SIZE, 5000, NULL); - HeapFree(GetProcessHeap(), 0, pname); - memset(&Connection->ovl, 0, sizeof(Connection->ovl)); - Connection->ovl[0].hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); - Connection->ovl[1].hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); - if (!ConnectNamedPipe(Connection->conn, &Connection->ovl[0])) { - WARN("Couldn't ConnectNamedPipe (error was %ld)\n", GetLastError()); - if (GetLastError() == ERROR_PIPE_CONNECTED) { - SetEvent(Connection->ovl[0].hEvent); - return RPC_S_OK; - } else if (GetLastError() == ERROR_IO_PENDING) { - return RPC_S_OK; - } - return RPC_S_SERVER_UNAVAILABLE; - } - } - /* protseq=ncacn_np: named pipes */ - else if (strcmp(Connection->Protseq, "ncacn_np") == 0) { - static LPCSTR prefix = "\\\\."; - LPSTR pname; - pname = HeapAlloc(GetProcessHeap(), 0, strlen(prefix) + strlen(Connection->Endpoint) + 1); - strcat(strcpy(pname, prefix), Connection->Endpoint); - TRACE("listening on %s\n", pname); - Connection->conn = CreateNamedPipeA(pname, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, - PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, - RPC_MAX_PACKET_SIZE, RPC_MAX_PACKET_SIZE, 5000, NULL); - HeapFree(GetProcessHeap(), 0, pname); - memset(&Connection->ovl, 0, sizeof(Connection->ovl)); - Connection->ovl[0].hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); - Connection->ovl[1].hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); - if (!ConnectNamedPipe(Connection->conn, &Connection->ovl[0])) { - if (GetLastError() == ERROR_PIPE_CONNECTED) { - SetEvent(Connection->ovl[0].hEvent); - return RPC_S_OK; - } else if (GetLastError() == ERROR_IO_PENDING) { - return RPC_S_OK; - } - WARN("Couldn't ConnectNamedPipe (error was %ld)\n", GetLastError()); - return RPC_S_SERVER_UNAVAILABLE; - } - } - else { - ERR("protseq %s not supported\n", Connection->Protseq); - return RPC_S_PROTSEQ_NOT_SUPPORTED; - } - } - else { /* client */ - /* protseq=ncalrpc: supposed to use NT LPC ports, - * but we'll implement it with named pipes for now */ - if (strcmp(Connection->Protseq, "ncalrpc") == 0) { - static LPCSTR prefix = "\\\\.\\pipe\\lrpc\\"; - LPSTR pname; - HANDLE conn; - DWORD err; - DWORD dwMode; - - pname = HeapAlloc(GetProcessHeap(), 0, strlen(prefix) + strlen(Connection->Endpoint) + 1); - strcat(strcpy(pname, prefix), Connection->Endpoint); - TRACE("connecting to %s\n", pname); - while (TRUE) { - if (WaitNamedPipeA(pname, NMPWAIT_WAIT_FOREVER)) { - conn = CreateFileA(pname, GENERIC_READ|GENERIC_WRITE, 0, NULL, - OPEN_EXISTING, 0, 0); - if (conn != INVALID_HANDLE_VALUE) break; - err = GetLastError(); - if (err == ERROR_PIPE_BUSY) continue; - TRACE("connection failed, error=%lx\n", err); - HeapFree(GetProcessHeap(), 0, pname); - return RPC_S_SERVER_TOO_BUSY; - } else { - err = GetLastError(); - WARN("connection failed, error=%lx\n", err); - HeapFree(GetProcessHeap(), 0, pname); - return RPC_S_SERVER_UNAVAILABLE; - } - } - - /* success */ - HeapFree(GetProcessHeap(), 0, pname); - memset(&Connection->ovl, 0, sizeof(Connection->ovl)); - /* pipe is connected; change to message-read mode. */ - dwMode = PIPE_READMODE_MESSAGE; - SetNamedPipeHandleState(conn, &dwMode, NULL, NULL); - Connection->ovl[0].hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); - Connection->ovl[1].hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); - Connection->conn = conn; - } - /* protseq=ncacn_np: named pipes */ - else if (strcmp(Connection->Protseq, "ncacn_np") == 0) { - static LPCSTR prefix = "\\\\."; - LPSTR pname; - HANDLE conn; - DWORD err; - DWORD dwMode; - - pname = HeapAlloc(GetProcessHeap(), 0, strlen(prefix) + strlen(Connection->Endpoint) + 1); - strcat(strcpy(pname, prefix), Connection->Endpoint); - TRACE("connecting to %s\n", pname); - conn = CreateFileA(pname, GENERIC_READ|GENERIC_WRITE, 0, NULL, - OPEN_EXISTING, 0, 0); - if (conn == INVALID_HANDLE_VALUE) { - err = GetLastError(); - /* we don't need to handle ERROR_PIPE_BUSY here, - * the doc says that it is returned to the app */ - WARN("connection failed, error=%lx\n", err); - HeapFree(GetProcessHeap(), 0, pname); - if (err == ERROR_PIPE_BUSY) - return RPC_S_SERVER_TOO_BUSY; - else - return RPC_S_SERVER_UNAVAILABLE; - } - - /* success */ - HeapFree(GetProcessHeap(), 0, pname); - memset(&Connection->ovl, 0, sizeof(Connection->ovl)); - /* pipe is connected; change to message-read mode. */ - dwMode = PIPE_READMODE_MESSAGE; - SetNamedPipeHandleState(conn, &dwMode, NULL, NULL); - Connection->ovl[0].hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); - Connection->ovl[1].hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); - Connection->conn = conn; - } else { - ERR("protseq %s not supported\n", Connection->Protseq); - return RPC_S_PROTSEQ_NOT_SUPPORTED; - } - } - } - return RPC_S_OK; -} - -RPC_STATUS RPCRT4_CloseConnection(RpcConnection* Connection) -{ - TRACE("(Connection == ^%p)\n", Connection); - if (Connection->conn) { - FlushFileBuffers(Connection->conn); - CloseHandle(Connection->conn); - Connection->conn = 0; - } - if (Connection->ovl[0].hEvent) { - CloseHandle(Connection->ovl[0].hEvent); - Connection->ovl[0].hEvent = 0; - } - if (Connection->ovl[1].hEvent) { - CloseHandle(Connection->ovl[1].hEvent); - Connection->ovl[1].hEvent = 0; - } - return RPC_S_OK; -} - -RPC_STATUS RPCRT4_SpawnConnection(RpcConnection** Connection, RpcConnection* OldConnection) -{ - RpcConnection* NewConnection; - RPC_STATUS err = RPCRT4_CreateConnection(&NewConnection, OldConnection->server, OldConnection->Protseq, - OldConnection->NetworkAddr, OldConnection->Endpoint, NULL, NULL); - if (err == RPC_S_OK) { - /* because of the way named pipes work, we'll transfer the connected pipe - * to the child, then reopen the server binding to continue listening */ - NewConnection->conn = OldConnection->conn; - NewConnection->ovl[0] = OldConnection->ovl[0]; - NewConnection->ovl[1] = OldConnection->ovl[1]; - OldConnection->conn = 0; - memset(&OldConnection->ovl, 0, sizeof(OldConnection->ovl)); - *Connection = NewConnection; - RPCRT4_OpenConnection(OldConnection); - } - return err; -} - static RPC_STATUS RPCRT4_AllocBinding(RpcBinding** Binding, BOOL server) { RpcBinding* NewBinding; @@ -325,7 +120,7 @@ static RPC_STATUS RPCRT4_AllocBinding(RpcBinding** Binding, BOOL server) return RPC_S_OK; } -RPC_STATUS RPCRT4_CreateBindingA(RpcBinding** Binding, BOOL server, LPSTR Protseq) +static RPC_STATUS RPCRT4_CreateBindingA(RpcBinding** Binding, BOOL server, LPCSTR Protseq) { RpcBinding* NewBinding; @@ -338,7 +133,7 @@ RPC_STATUS RPCRT4_CreateBindingA(RpcBinding** Binding, BOOL server, LPSTR Protse return RPC_S_OK; } -RPC_STATUS RPCRT4_CreateBindingW(RpcBinding** Binding, BOOL server, LPWSTR Protseq) +static RPC_STATUS RPCRT4_CreateBindingW(RpcBinding** Binding, BOOL server, LPCWSTR Protseq) { RpcBinding* NewBinding; @@ -351,9 +146,12 @@ RPC_STATUS RPCRT4_CreateBindingW(RpcBinding** Binding, BOOL server, LPWSTR Prots return RPC_S_OK; } -RPC_STATUS RPCRT4_CompleteBindingA(RpcBinding* Binding, LPSTR NetworkAddr, LPSTR Endpoint, LPSTR NetworkOptions) +static RPC_STATUS RPCRT4_CompleteBindingA(RpcBinding* Binding, LPCSTR NetworkAddr, + LPCSTR Endpoint, LPCSTR NetworkOptions) { - TRACE("(RpcBinding == ^%p, NetworkAddr == \"%s\", EndPoint == \"%s\", NetworkOptions == \"%s\")\n", Binding, + RPC_STATUS status; + + TRACE("(RpcBinding == ^%p, NetworkAddr == %s, EndPoint == %s, NetworkOptions == %s)\n", Binding, debugstr_a(NetworkAddr), debugstr_a(Endpoint), debugstr_a(NetworkOptions)); RPCRT4_strfree(Binding->NetworkAddr); @@ -364,14 +162,25 @@ RPC_STATUS RPCRT4_CompleteBindingA(RpcBinding* Binding, LPSTR NetworkAddr, LPST } else { Binding->Endpoint = RPCRT4_strdupA(""); } + HeapFree(GetProcessHeap(), 0, Binding->NetworkOptions); + Binding->NetworkOptions = RPCRT4_strdupAtoW(NetworkOptions); if (!Binding->Endpoint) ERR("out of memory?\n"); + status = RPCRT4_GetAssociation(Binding->Protseq, Binding->NetworkAddr, + Binding->Endpoint, Binding->NetworkOptions, + &Binding->Assoc); + if (status != RPC_S_OK) + return status; + return RPC_S_OK; } -RPC_STATUS RPCRT4_CompleteBindingW(RpcBinding* Binding, LPWSTR NetworkAddr, LPWSTR Endpoint, LPWSTR NetworkOptions) +static RPC_STATUS RPCRT4_CompleteBindingW(RpcBinding* Binding, LPCWSTR NetworkAddr, + LPCWSTR Endpoint, LPCWSTR NetworkOptions) { - TRACE("(RpcBinding == ^%p, NetworkAddr == \"%s\", EndPoint == \"%s\", NetworkOptions == \"%s\")\n", Binding, + RPC_STATUS status; + + TRACE("(RpcBinding == ^%p, NetworkAddr == %s, EndPoint == %s, NetworkOptions == %s)\n", Binding, debugstr_w(NetworkAddr), debugstr_w(Endpoint), debugstr_w(NetworkOptions)); RPCRT4_strfree(Binding->NetworkAddr); @@ -383,23 +192,41 @@ RPC_STATUS RPCRT4_CompleteBindingW(RpcBinding* Binding, LPWSTR NetworkAddr, LPWS Binding->Endpoint = RPCRT4_strdupA(""); } if (!Binding->Endpoint) ERR("out of memory?\n"); + HeapFree(GetProcessHeap(), 0, Binding->NetworkOptions); + Binding->NetworkOptions = RPCRT4_strdupW(NetworkOptions); + + status = RPCRT4_GetAssociation(Binding->Protseq, Binding->NetworkAddr, + Binding->Endpoint, Binding->NetworkOptions, + &Binding->Assoc); + if (status != RPC_S_OK) + return status; return RPC_S_OK; } -RPC_STATUS RPCRT4_ResolveBinding(RpcBinding* Binding, LPSTR Endpoint) +RPC_STATUS RPCRT4_ResolveBinding(RpcBinding* Binding, LPCSTR Endpoint) { + RPC_STATUS status; + TRACE("(RpcBinding == ^%p, EndPoint == \"%s\"\n", Binding, Endpoint); RPCRT4_strfree(Binding->Endpoint); Binding->Endpoint = RPCRT4_strdupA(Endpoint); + RpcAssoc_Release(Binding->Assoc); + Binding->Assoc = NULL; + status = RPCRT4_GetAssociation(Binding->Protseq, Binding->NetworkAddr, + Binding->Endpoint, Binding->NetworkOptions, + &Binding->Assoc); + if (status != RPC_S_OK) + return status; + return RPC_S_OK; } -RPC_STATUS RPCRT4_SetBindingObject(RpcBinding* Binding, UUID* ObjectUuid) +RPC_STATUS RPCRT4_SetBindingObject(RpcBinding* Binding, const UUID* ObjectUuid) { - TRACE("(*RpcBinding == ^%p, UUID == %s)\n", Binding, debugstr_guid(ObjectUuid)); + TRACE("(*RpcBinding == ^%p, UUID == %s)\n", Binding, debugstr_guid(ObjectUuid)); if (ObjectUuid) memcpy(&Binding->ObjectUuid, ObjectUuid, sizeof(UUID)); else UuidCreateNil(&Binding->ObjectUuid); return RPC_S_OK; @@ -411,7 +238,7 @@ RPC_STATUS RPCRT4_MakeBinding(RpcBinding** Binding, RpcConnection* Connection) TRACE("(RpcBinding == ^%p, Connection == ^%p)\n", Binding, Connection); RPCRT4_AllocBinding(&NewBinding, Connection->server); - NewBinding->Protseq = RPCRT4_strdupA(Connection->Protseq); + NewBinding->Protseq = RPCRT4_strdupA(rpcrt4_conn_get_name(Connection)); NewBinding->NetworkAddr = RPCRT4_strdupA(Connection->NetworkAddr); NewBinding->Endpoint = RPCRT4_strdupA(Connection->Endpoint); NewBinding->FromConn = Connection; @@ -435,118 +262,52 @@ RPC_STATUS RPCRT4_DestroyBinding(RpcBinding* Binding) return RPC_S_OK; TRACE("binding: %p\n", Binding); - /* FIXME: release connections */ + if (Binding->Assoc) RpcAssoc_Release(Binding->Assoc); RPCRT4_strfree(Binding->Endpoint); RPCRT4_strfree(Binding->NetworkAddr); RPCRT4_strfree(Binding->Protseq); + HeapFree(GetProcessHeap(), 0, Binding->NetworkOptions); + if (Binding->AuthInfo) RpcAuthInfo_Release(Binding->AuthInfo); + if (Binding->QOS) RpcQualityOfService_Release(Binding->QOS); HeapFree(GetProcessHeap(), 0, Binding); return RPC_S_OK; } RPC_STATUS RPCRT4_OpenBinding(RpcBinding* Binding, RpcConnection** Connection, - PRPC_SYNTAX_IDENTIFIER TransferSyntax, - PRPC_SYNTAX_IDENTIFIER InterfaceId) + const RPC_SYNTAX_IDENTIFIER *TransferSyntax, + const RPC_SYNTAX_IDENTIFIER *InterfaceId) { - RpcConnection* NewConnection; - RPC_STATUS status; - TRACE("(Binding == ^%p)\n", Binding); - /* if we try to bind a new interface and the connection is already opened, - * close the current connection and create a new with the new binding. */ - if (!Binding->server && Binding->FromConn && - memcmp(&Binding->FromConn->ActiveInterface, InterfaceId, - sizeof(RPC_SYNTAX_IDENTIFIER))) { - - TRACE("releasing pre-existing connection\n"); - RPCRT4_DestroyConnection(Binding->FromConn); - Binding->FromConn = NULL; + if (!Binding->server) { + return RpcAssoc_GetClientConnection(Binding->Assoc, InterfaceId, + TransferSyntax, Binding->AuthInfo, Binding->QOS, Connection); } else { /* we already have a connection with acceptable binding, so use it */ if (Binding->FromConn) { *Connection = Binding->FromConn; return RPC_S_OK; + } else { + ERR("no connection in binding\n"); + return RPC_S_INTERNAL_ERROR; } } - - /* create a new connection */ - RPCRT4_CreateConnection(&NewConnection, Binding->server, Binding->Protseq, Binding->NetworkAddr, Binding->Endpoint, NULL, Binding); - *Connection = NewConnection; - status = RPCRT4_OpenConnection(NewConnection); - if (status != RPC_S_OK) { - return status; - } - - /* we need to send a binding packet if we are client. */ - if (!(*Connection)->server) { - RpcPktHdr *hdr; - DWORD count; - BYTE *response; - RpcPktHdr *response_hdr; - - TRACE("sending bind request to server\n"); - - hdr = RPCRT4_BuildBindHeader(NDR_LOCAL_DATA_REPRESENTATION, - RPC_MAX_PACKET_SIZE, RPC_MAX_PACKET_SIZE, - InterfaceId, TransferSyntax); - - status = RPCRT4_Send(*Connection, hdr, NULL, 0); - if (status != RPC_S_OK) { - RPCRT4_DestroyConnection(*Connection); - return status; - } - - response = HeapAlloc(GetProcessHeap(), 0, RPC_MAX_PACKET_SIZE); - if (response == NULL) { - WARN("Can't allocate memory for binding response\n"); - RPCRT4_DestroyConnection(*Connection); - return E_OUTOFMEMORY; - } - - /* get a reply */ - if (!ReadFile(NewConnection->conn, response, RPC_MAX_PACKET_SIZE, &count, NULL)) { - WARN("ReadFile failed with error %ld\n", GetLastError()); - RPCRT4_DestroyConnection(*Connection); - return RPC_S_PROTOCOL_ERROR; - } - - if (count < sizeof(response_hdr->common)) { - WARN("received invalid header\n"); - RPCRT4_DestroyConnection(*Connection); - return RPC_S_PROTOCOL_ERROR; - } - - response_hdr = (RpcPktHdr*)response; - - if (response_hdr->common.rpc_ver != RPC_VER_MAJOR || - response_hdr->common.rpc_ver_minor != RPC_VER_MINOR || - response_hdr->common.ptype != PKT_BIND_ACK) { - WARN("invalid protocol version or rejection packet\n"); - RPCRT4_DestroyConnection(*Connection); - return RPC_S_PROTOCOL_ERROR; - } - - if (response_hdr->bind_ack.max_tsize < RPC_MIN_PACKET_SIZE) { - WARN("server doesn't allow large enough packets\n"); - RPCRT4_DestroyConnection(*Connection); - return RPC_S_PROTOCOL_ERROR; - } - - /* FIXME: do more checks? */ - - (*Connection)->MaxTransmissionSize = response_hdr->bind_ack.max_tsize; - (*Connection)->ActiveInterface = *InterfaceId; - } - - return RPC_S_OK; } RPC_STATUS RPCRT4_CloseBinding(RpcBinding* Binding, RpcConnection* Connection) { TRACE("(Binding == ^%p)\n", Binding); if (!Connection) return RPC_S_OK; - if (Binding->FromConn == Connection) return RPC_S_OK; - return RPCRT4_DestroyConnection(Connection); + if (Binding->server) { + /* don't destroy a connection that is cached in the binding */ + if (Binding->FromConn == Connection) + return RPC_S_OK; + return RPCRT4_DestroyConnection(Connection); + } + else { + RpcAssoc_ReleaseIdleConnection(Binding->Assoc, Connection); + return RPC_S_OK; + } } /* utility functions for string composing and parsing */ @@ -582,7 +343,7 @@ static LPWSTR RPCRT4_strconcatW(LPWSTR dst, LPCWSTR src) { DWORD len = strlenW(dst), slen = strlenW(src); LPWSTR ndst = HeapReAlloc(GetProcessHeap(), 0, dst, (len+slen+2)*sizeof(WCHAR)); - if (!ndst) + if (!ndst) { HeapFree(GetProcessHeap(), 0, dst); return NULL; @@ -592,49 +353,13 @@ static LPWSTR RPCRT4_strconcatW(LPWSTR dst, LPCWSTR src) return ndst; } -/*********************************************************************** - * RpcBindingCopy (RPCRT4.@) - */ -RPC_STATUS RPC_ENTRY RpcBindingCopy( - RPC_BINDING_HANDLE SourceBinding, - RPC_BINDING_HANDLE* DestinationBinding) -{ - TRACE("RpcBindingCopy(%p, %p) called:\n", SourceBinding, DestinationBinding); - RpcBinding *DestBinding = 0, *SrcBinding = (RpcBinding*)SourceBinding; - - if(SrcBinding->server) - { - *DestinationBinding = NULL; - return RPC_S_WRONG_KIND_OF_BINDING; - } - - DestBinding = (RpcBinding*) - HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RpcBinding)); - - if(!DestBinding) - { - *DestinationBinding = NULL; - return ERROR_NOT_ENOUGH_MEMORY; - } - - memcpy(DestBinding, SrcBinding, sizeof(RpcBinding)); - DestBinding->refs = 1; - DestBinding->Next = NULL; // FIXME: ? - DestBinding->server = FALSE; - DestBinding->Protseq = RPCRT4_strndupA(SrcBinding->Protseq, -1); - DestBinding->NetworkAddr = RPCRT4_strndupA(SrcBinding->NetworkAddr, -1); - DestBinding->Endpoint = RPCRT4_strndupA(SrcBinding->Endpoint, -1); - - *DestinationBinding = DestBinding; - return RPC_S_OK; -} /*********************************************************************** * RpcStringBindingComposeA (RPCRT4.@) */ -RPC_STATUS WINAPI RpcStringBindingComposeA(unsigned char *ObjUuid, unsigned char *Protseq, - unsigned char *NetworkAddr, unsigned char *Endpoint, - unsigned char *Options, unsigned char** StringBinding ) +RPC_STATUS WINAPI RpcStringBindingComposeA(RPC_CSTR ObjUuid, RPC_CSTR Protseq, + RPC_CSTR NetworkAddr, RPC_CSTR Endpoint, + RPC_CSTR Options, RPC_CSTR *StringBinding ) { DWORD len = 1; LPSTR data; @@ -684,12 +409,12 @@ RPC_STATUS WINAPI RpcStringBindingComposeA(unsigned char *ObjUuid, unsigned char /*********************************************************************** * RpcStringBindingComposeW (RPCRT4.@) */ -RPC_STATUS WINAPI RpcStringBindingComposeW( LPWSTR ObjUuid, LPWSTR Protseq, - LPWSTR NetworkAddr, LPWSTR Endpoint, - LPWSTR Options, LPWSTR* StringBinding ) +RPC_STATUS WINAPI RpcStringBindingComposeW( RPC_WSTR ObjUuid, RPC_WSTR Protseq, + RPC_WSTR NetworkAddr, RPC_WSTR Endpoint, + RPC_WSTR Options, RPC_WSTR* StringBinding ) { DWORD len = 1; - LPWSTR data; + RPC_WSTR data; TRACE("(%s,%s,%s,%s,%s,%p)\n", debugstr_w( ObjUuid ), debugstr_w( Protseq ), @@ -737,9 +462,9 @@ RPC_STATUS WINAPI RpcStringBindingComposeW( LPWSTR ObjUuid, LPWSTR Protseq, /*********************************************************************** * RpcStringBindingParseA (RPCRT4.@) */ -RPC_STATUS WINAPI RpcStringBindingParseA( unsigned char *StringBinding, unsigned char **ObjUuid, - unsigned char **Protseq, unsigned char **NetworkAddr, - unsigned char **Endpoint, unsigned char **Options) +RPC_STATUS WINAPI RpcStringBindingParseA( RPC_CSTR StringBinding, RPC_CSTR *ObjUuid, + RPC_CSTR *Protseq, RPC_CSTR *NetworkAddr, + RPC_CSTR *Endpoint, RPC_CSTR *Options) { CHAR *data, *next; static const char ep_opt[] = "endpoint="; @@ -802,7 +527,7 @@ RPC_STATUS WINAPI RpcStringBindingParseA( unsigned char *StringBinding, unsigned /* FIXME: this is kind of inefficient */ *Options = (unsigned char*) RPCRT4_strconcatA( (char*)*Options, opt); HeapFree(GetProcessHeap(), 0, opt); - } else + } else *Options = (unsigned char*) opt; } } @@ -811,7 +536,7 @@ RPC_STATUS WINAPI RpcStringBindingParseA( unsigned char *StringBinding, unsigned data = close+1; if (*data) goto fail; } - else if (NetworkAddr) + else if (NetworkAddr) *NetworkAddr = (unsigned char*)RPCRT4_strdupA(data); return RPC_S_OK; @@ -828,9 +553,9 @@ fail: /*********************************************************************** * RpcStringBindingParseW (RPCRT4.@) */ -RPC_STATUS WINAPI RpcStringBindingParseW( LPWSTR StringBinding, LPWSTR *ObjUuid, - LPWSTR *Protseq, LPWSTR *NetworkAddr, - LPWSTR *Endpoint, LPWSTR *Options) +RPC_STATUS WINAPI RpcStringBindingParseW( RPC_WSTR StringBinding, RPC_WSTR *ObjUuid, + RPC_WSTR *Protseq, RPC_WSTR *NetworkAddr, + RPC_WSTR *Endpoint, RPC_WSTR *Options) { WCHAR *data, *next; static const WCHAR ep_opt[] = {'e','n','d','p','o','i','n','t','=',0}; @@ -893,7 +618,7 @@ RPC_STATUS WINAPI RpcStringBindingParseW( LPWSTR StringBinding, LPWSTR *ObjUuid, /* FIXME: this is kind of inefficient */ *Options = RPCRT4_strconcatW(*Options, opt); HeapFree(GetProcessHeap(), 0, opt); - } else + } else *Options = opt; } } @@ -901,7 +626,7 @@ RPC_STATUS WINAPI RpcStringBindingParseW( LPWSTR StringBinding, LPWSTR *ObjUuid, data = close+1; if (*data) goto fail; - } else if (NetworkAddr) + } else if (NetworkAddr) *NetworkAddr = RPCRT4_strdupW(data); return RPC_S_OK; @@ -926,7 +651,7 @@ RPC_STATUS WINAPI RpcBindingFree( RPC_BINDING_HANDLE* Binding ) if (status == RPC_S_OK) *Binding = 0; return status; } - + /*********************************************************************** * RpcBindingVectorFree (RPCRT4.@) */ @@ -943,7 +668,7 @@ RPC_STATUS WINAPI RpcBindingVectorFree( RPC_BINDING_VECTOR** BindingVector ) *BindingVector = NULL; return RPC_S_OK; } - + /*********************************************************************** * RpcBindingInqObject (RPCRT4.@) */ @@ -955,7 +680,7 @@ RPC_STATUS WINAPI RpcBindingInqObject( RPC_BINDING_HANDLE Binding, UUID* ObjectU memcpy(ObjectUuid, &bind->ObjectUuid, sizeof(UUID)); return RPC_S_OK; } - + /*********************************************************************** * RpcBindingSetObject (RPCRT4.@) */ @@ -971,11 +696,11 @@ RPC_STATUS WINAPI RpcBindingSetObject( RPC_BINDING_HANDLE Binding, UUID* ObjectU /*********************************************************************** * RpcBindingFromStringBindingA (RPCRT4.@) */ -RPC_STATUS WINAPI RpcBindingFromStringBindingA( unsigned char *StringBinding, RPC_BINDING_HANDLE* Binding ) +RPC_STATUS WINAPI RpcBindingFromStringBindingA( RPC_CSTR StringBinding, RPC_BINDING_HANDLE* Binding ) { RPC_STATUS ret; RpcBinding* bind = NULL; - unsigned char *ObjectUuid, *Protseq, *NetworkAddr, *Endpoint, *Options; + RPC_CSTR ObjectUuid, Protseq, NetworkAddr, Endpoint, Options; UUID Uuid; TRACE("(%s,%p)\n", debugstr_a((char*)StringBinding), Binding); @@ -999,9 +724,9 @@ RPC_STATUS WINAPI RpcBindingFromStringBindingA( unsigned char *StringBinding, RP RpcStringFreeA((unsigned char**)&Protseq); RpcStringFreeA((unsigned char**)&ObjectUuid); - if (ret == RPC_S_OK) + if (ret == RPC_S_OK) *Binding = (RPC_BINDING_HANDLE)bind; - else + else RPCRT4_DestroyBinding(bind); return ret; @@ -1010,11 +735,11 @@ RPC_STATUS WINAPI RpcBindingFromStringBindingA( unsigned char *StringBinding, RP /*********************************************************************** * RpcBindingFromStringBindingW (RPCRT4.@) */ -RPC_STATUS WINAPI RpcBindingFromStringBindingW( LPWSTR StringBinding, RPC_BINDING_HANDLE* Binding ) +RPC_STATUS WINAPI RpcBindingFromStringBindingW( RPC_WSTR StringBinding, RPC_BINDING_HANDLE* Binding ) { RPC_STATUS ret; RpcBinding* bind = NULL; - LPWSTR ObjectUuid, Protseq, NetworkAddr, Endpoint, Options; + RPC_WSTR ObjectUuid, Protseq, NetworkAddr, Endpoint, Options; UUID Uuid; TRACE("(%s,%p)\n", debugstr_w(StringBinding), Binding); @@ -1045,33 +770,33 @@ RPC_STATUS WINAPI RpcBindingFromStringBindingW( LPWSTR StringBinding, RPC_BINDIN return ret; } - + /*********************************************************************** * RpcBindingToStringBindingA (RPCRT4.@) */ -RPC_STATUS WINAPI RpcBindingToStringBindingA( RPC_BINDING_HANDLE Binding, unsigned char** StringBinding ) +RPC_STATUS WINAPI RpcBindingToStringBindingA( RPC_BINDING_HANDLE Binding, RPC_CSTR *StringBinding ) { RPC_STATUS ret; RpcBinding* bind = (RpcBinding*)Binding; - LPSTR ObjectUuid; + RPC_CSTR ObjectUuid; TRACE("(%p,%p)\n", Binding, StringBinding); - ret = UuidToStringA(&bind->ObjectUuid, (unsigned char**)&ObjectUuid); + ret = UuidToStringA(&bind->ObjectUuid, &ObjectUuid); if (ret != RPC_S_OK) return ret; - ret = RpcStringBindingComposeA((unsigned char*) ObjectUuid, (unsigned char*)bind->Protseq, (unsigned char*) bind->NetworkAddr, + ret = RpcStringBindingComposeA(ObjectUuid, (unsigned char*)bind->Protseq, (unsigned char*) bind->NetworkAddr, (unsigned char*) bind->Endpoint, NULL, StringBinding); - RpcStringFreeA((unsigned char**)&ObjectUuid); + RpcStringFreeA(&ObjectUuid); return ret; } - + /*********************************************************************** * RpcBindingToStringBindingW (RPCRT4.@) */ -RPC_STATUS WINAPI RpcBindingToStringBindingW( RPC_BINDING_HANDLE Binding, unsigned short** StringBinding ) +RPC_STATUS WINAPI RpcBindingToStringBindingW( RPC_BINDING_HANDLE Binding, RPC_WSTR *StringBinding ) { RPC_STATUS ret; unsigned char *str = NULL; @@ -1100,46 +825,37 @@ RPC_STATUS WINAPI I_RpcBindingSetAsync( RPC_BINDING_HANDLE Binding, RPC_BLOCKING } /*********************************************************************** - * RpcNetworkIsProtseqValidA (RPCRT4.@) + * RpcBindingCopy (RPCRT4.@) */ -RPC_STATUS WINAPI RpcNetworkIsProtseqValidA(unsigned char *protseq) { - UNICODE_STRING protseqW; +RPC_STATUS RPC_ENTRY RpcBindingCopy( + RPC_BINDING_HANDLE SourceBinding, + RPC_BINDING_HANDLE* DestinationBinding) +{ + RpcBinding *DestBinding; + RpcBinding *SrcBinding = (RpcBinding*)SourceBinding; + RPC_STATUS status; - if (!protseq) return RPC_S_INVALID_RPC_PROTSEQ; /* ? */ + TRACE("(%p, %p)\n", SourceBinding, DestinationBinding); - if (RtlCreateUnicodeStringFromAsciiz(&protseqW, (char*)protseq)) { - RPC_STATUS ret = RpcNetworkIsProtseqValidW(protseqW.Buffer); - RtlFreeUnicodeString(&protseqW); - return ret; - } else return RPC_S_OUT_OF_MEMORY; -} + status = RPCRT4_AllocBinding(&DestBinding, SrcBinding->server); + if (status != RPC_S_OK) return status; -/*********************************************************************** - * RpcNetworkIsProtseqValidW (RPCRT4.@) - * - * Checks if the given protocol sequence is known by the RPC system. - * If it is, returns RPC_S_OK, otherwise RPC_S_PROTSEQ_NOT_SUPPORTED. - * - * We currently support: - * ncalrpc local-only rpc over LPC (LPC is not really used) - * ncacn_np rpc over named pipes - */ -RPC_STATUS WINAPI RpcNetworkIsProtseqValidW(LPWSTR protseq) { - static const WCHAR protseqsW[][15] = { - {'n','c','a','l','r','p','c',0}, - {'n','c','a','c','n','_','n','p',0} - }; - static const int count = sizeof(protseqsW) / sizeof(protseqsW[0]); - int i; + DestBinding->ObjectUuid = SrcBinding->ObjectUuid; + DestBinding->BlockingFn = SrcBinding->BlockingFn; + DestBinding->Protseq = RPCRT4_strndupA(SrcBinding->Protseq, -1); + DestBinding->NetworkAddr = RPCRT4_strndupA(SrcBinding->NetworkAddr, -1); + DestBinding->Endpoint = RPCRT4_strndupA(SrcBinding->Endpoint, -1); + DestBinding->NetworkOptions = RPCRT4_strdupW(SrcBinding->NetworkOptions); + if (SrcBinding->Assoc) SrcBinding->Assoc->refs++; + DestBinding->Assoc = SrcBinding->Assoc; - if (!protseq) return RPC_S_INVALID_RPC_PROTSEQ; /* ? */ + if (SrcBinding->AuthInfo) RpcAuthInfo_AddRef(SrcBinding->AuthInfo); + DestBinding->AuthInfo = SrcBinding->AuthInfo; + if (SrcBinding->QOS) RpcQualityOfService_AddRef(SrcBinding->QOS); + DestBinding->QOS = SrcBinding->QOS; - for (i = 0; i < count; i++) { - if (!strcmpW(protseq, protseqsW[i])) return RPC_S_OK; - } - - FIXME("Unknown protseq %s - we probably need to implement it one day\n", debugstr_w(protseq)); - return RPC_S_PROTSEQ_NOT_SUPPORTED; + *DestinationBinding = DestBinding; + return RPC_S_OK; } /*********************************************************************** @@ -1191,6 +907,349 @@ RPC_STATUS WINAPI RpcRevertToSelfEx(RPC_BINDING_HANDLE BindingHandle) return RPC_S_OK; } +static inline BOOL has_nt_auth_identity(ULONG AuthnLevel) +{ + switch (AuthnLevel) + { + case RPC_C_AUTHN_GSS_NEGOTIATE: + case RPC_C_AUTHN_WINNT: + case RPC_C_AUTHN_GSS_KERBEROS: + return TRUE; + default: + return FALSE; + } +} + +static RPC_STATUS RpcAuthInfo_Create(ULONG AuthnLevel, ULONG AuthnSvc, + CredHandle cred, TimeStamp exp, + ULONG cbMaxToken, + RPC_AUTH_IDENTITY_HANDLE identity, + RpcAuthInfo **ret) +{ + RpcAuthInfo *AuthInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(*AuthInfo)); + if (!AuthInfo) + return ERROR_OUTOFMEMORY; + + AuthInfo->refs = 1; + AuthInfo->AuthnLevel = AuthnLevel; + AuthInfo->AuthnSvc = AuthnSvc; + AuthInfo->cred = cred; + AuthInfo->exp = exp; + AuthInfo->cbMaxToken = cbMaxToken; + AuthInfo->identity = identity; + + /* duplicate the SEC_WINNT_AUTH_IDENTITY structure, if applicable, to + * enable better matching in RpcAuthInfo_IsEqual */ + if (identity && has_nt_auth_identity(AuthnSvc)) + { + const SEC_WINNT_AUTH_IDENTITY_W *nt_identity = identity; + AuthInfo->nt_identity = HeapAlloc(GetProcessHeap(), 0, sizeof(*AuthInfo->nt_identity)); + if (!AuthInfo->nt_identity) + { + HeapFree(GetProcessHeap(), 0, AuthInfo); + return ERROR_OUTOFMEMORY; + } + + AuthInfo->nt_identity->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE; + if (nt_identity->Flags & SEC_WINNT_AUTH_IDENTITY_UNICODE) + AuthInfo->nt_identity->User = RPCRT4_strndupW(nt_identity->User, nt_identity->UserLength); + else + AuthInfo->nt_identity->User = RPCRT4_strndupAtoW((const char *)nt_identity->User, nt_identity->UserLength); + AuthInfo->nt_identity->UserLength = nt_identity->UserLength; + if (nt_identity->Flags & SEC_WINNT_AUTH_IDENTITY_UNICODE) + AuthInfo->nt_identity->Domain = RPCRT4_strndupW(nt_identity->Domain, nt_identity->DomainLength); + else + AuthInfo->nt_identity->Domain = RPCRT4_strndupAtoW((const char *)nt_identity->Domain, nt_identity->DomainLength); + AuthInfo->nt_identity->DomainLength = nt_identity->DomainLength; + if (nt_identity->Flags & SEC_WINNT_AUTH_IDENTITY_UNICODE) + AuthInfo->nt_identity->Password = RPCRT4_strndupW(nt_identity->Password, nt_identity->PasswordLength); + else + AuthInfo->nt_identity->Password = RPCRT4_strndupAtoW((const char *)nt_identity->Password, nt_identity->PasswordLength); + AuthInfo->nt_identity->PasswordLength = nt_identity->PasswordLength; + + if (!AuthInfo->nt_identity->User || + !AuthInfo->nt_identity->Domain || + !AuthInfo->nt_identity->Password) + { + HeapFree(GetProcessHeap(), 0, AuthInfo->nt_identity->User); + HeapFree(GetProcessHeap(), 0, AuthInfo->nt_identity->Domain); + HeapFree(GetProcessHeap(), 0, AuthInfo->nt_identity->Password); + HeapFree(GetProcessHeap(), 0, AuthInfo->nt_identity); + HeapFree(GetProcessHeap(), 0, AuthInfo); + return ERROR_OUTOFMEMORY; + } + } + else + AuthInfo->nt_identity = NULL; + *ret = AuthInfo; + return RPC_S_OK; +} + +ULONG RpcAuthInfo_AddRef(RpcAuthInfo *AuthInfo) +{ + return InterlockedIncrement(&AuthInfo->refs); +} + +ULONG RpcAuthInfo_Release(RpcAuthInfo *AuthInfo) +{ + ULONG refs = InterlockedDecrement(&AuthInfo->refs); + + if (!refs) + { + FreeCredentialsHandle(&AuthInfo->cred); + if (AuthInfo->nt_identity) + { + HeapFree(GetProcessHeap(), 0, AuthInfo->nt_identity->User); + HeapFree(GetProcessHeap(), 0, AuthInfo->nt_identity->Domain); + HeapFree(GetProcessHeap(), 0, AuthInfo->nt_identity->Password); + HeapFree(GetProcessHeap(), 0, AuthInfo->nt_identity); + } + HeapFree(GetProcessHeap(), 0, AuthInfo); + } + + return refs; +} + +BOOL RpcAuthInfo_IsEqual(const RpcAuthInfo *AuthInfo1, const RpcAuthInfo *AuthInfo2) +{ + if (AuthInfo1 == AuthInfo2) + return TRUE; + + if (!AuthInfo1 || !AuthInfo2) + return FALSE; + + if ((AuthInfo1->AuthnLevel != AuthInfo2->AuthnLevel) || + (AuthInfo1->AuthnSvc != AuthInfo2->AuthnSvc)) + return FALSE; + + if (AuthInfo1->identity == AuthInfo2->identity) + return TRUE; + + if (!AuthInfo1->identity || !AuthInfo2->identity) + return FALSE; + + if (has_nt_auth_identity(AuthInfo1->AuthnSvc)) + { + const SEC_WINNT_AUTH_IDENTITY_W *identity1 = AuthInfo1->nt_identity; + const SEC_WINNT_AUTH_IDENTITY_W *identity2 = AuthInfo2->nt_identity; + /* compare user names */ + if (identity1->UserLength != identity2->UserLength || + memcmp(identity1->User, identity2->User, identity1->UserLength)) + return FALSE; + /* compare domain names */ + if (identity1->DomainLength != identity2->DomainLength || + memcmp(identity1->Domain, identity2->Domain, identity1->DomainLength)) + return FALSE; + /* compare passwords */ + if (identity1->PasswordLength != identity2->PasswordLength || + memcmp(identity1->Password, identity2->Password, identity1->PasswordLength)) + return FALSE; + } + else + return FALSE; + + return TRUE; +} + +static RPC_STATUS RpcQualityOfService_Create(const RPC_SECURITY_QOS *qos_src, BOOL unicode, RpcQualityOfService **qos_dst) +{ + RpcQualityOfService *qos = HeapAlloc(GetProcessHeap(), 0, sizeof(*qos)); + + if (!qos) + return RPC_S_OUT_OF_RESOURCES; + + qos->refs = 1; + qos->qos = HeapAlloc(GetProcessHeap(), 0, sizeof(*qos->qos)); + if (!qos->qos) goto error; + qos->qos->Version = qos_src->Version; + qos->qos->Capabilities = qos_src->Capabilities; + qos->qos->IdentityTracking = qos_src->IdentityTracking; + qos->qos->ImpersonationType = qos_src->ImpersonationType; + qos->qos->AdditionalSecurityInfoType = 0; + + if (qos_src->Version >= 2) + { + const RPC_SECURITY_QOS_V2_W *qos_src2 = (const RPC_SECURITY_QOS_V2_W *)qos_src; + qos->qos->AdditionalSecurityInfoType = qos_src2->AdditionalSecurityInfoType; + if (qos_src2->AdditionalSecurityInfoType == RPC_C_AUTHN_INFO_TYPE_HTTP) + { + const RPC_HTTP_TRANSPORT_CREDENTIALS_W *http_credentials_src = qos_src2->u.HttpCredentials; + RPC_HTTP_TRANSPORT_CREDENTIALS_W *http_credentials_dst; + + http_credentials_dst = HeapAlloc(GetProcessHeap(), 0, sizeof(*http_credentials_dst)); + qos->qos->u.HttpCredentials = http_credentials_dst; + if (!http_credentials_dst) goto error; + http_credentials_dst->TransportCredentials = NULL; + http_credentials_dst->Flags = http_credentials_src->Flags; + http_credentials_dst->AuthenticationTarget = http_credentials_src->AuthenticationTarget; + http_credentials_dst->NumberOfAuthnSchemes = http_credentials_src->NumberOfAuthnSchemes; + http_credentials_dst->AuthnSchemes = NULL; + http_credentials_dst->ServerCertificateSubject = NULL; + if (http_credentials_src->TransportCredentials) + { + SEC_WINNT_AUTH_IDENTITY_W *cred_dst; + cred_dst = http_credentials_dst->TransportCredentials = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*cred_dst)); + if (!cred_dst) goto error; + cred_dst->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE; + if (unicode) + { + const SEC_WINNT_AUTH_IDENTITY_W *cred_src = http_credentials_src->TransportCredentials; + cred_dst->UserLength = cred_src->UserLength; + cred_dst->PasswordLength = cred_src->PasswordLength; + cred_dst->DomainLength = cred_src->DomainLength; + cred_dst->User = RPCRT4_strndupW(cred_src->User, cred_src->UserLength); + cred_dst->Password = RPCRT4_strndupW(cred_src->Password, cred_src->PasswordLength); + cred_dst->Domain = RPCRT4_strndupW(cred_src->Domain, cred_src->DomainLength); + } + else + { + const SEC_WINNT_AUTH_IDENTITY_A *cred_src = (const SEC_WINNT_AUTH_IDENTITY_A *)http_credentials_src->TransportCredentials; + cred_dst->UserLength = MultiByteToWideChar(CP_ACP, 0, (char *)cred_src->User, cred_src->UserLength, NULL, 0); + cred_dst->DomainLength = MultiByteToWideChar(CP_ACP, 0, (char *)cred_src->Domain, cred_src->DomainLength, NULL, 0); + cred_dst->PasswordLength = MultiByteToWideChar(CP_ACP, 0, (char *)cred_src->Password, cred_src->PasswordLength, NULL, 0); + cred_dst->User = HeapAlloc(GetProcessHeap(), 0, cred_dst->UserLength * sizeof(WCHAR)); + cred_dst->Password = HeapAlloc(GetProcessHeap(), 0, cred_dst->PasswordLength * sizeof(WCHAR)); + cred_dst->Domain = HeapAlloc(GetProcessHeap(), 0, cred_dst->DomainLength * sizeof(WCHAR)); + if (!cred_dst || !cred_dst->Password || !cred_dst->Domain) goto error; + MultiByteToWideChar(CP_ACP, 0, (char *)cred_src->User, cred_src->UserLength, cred_dst->User, cred_dst->UserLength); + MultiByteToWideChar(CP_ACP, 0, (char *)cred_src->Domain, cred_src->DomainLength, cred_dst->Domain, cred_dst->DomainLength); + MultiByteToWideChar(CP_ACP, 0, (char *)cred_src->Password, cred_src->PasswordLength, cred_dst->Password, cred_dst->PasswordLength); + } + } + if (http_credentials_src->NumberOfAuthnSchemes) + { + http_credentials_dst->AuthnSchemes = HeapAlloc(GetProcessHeap(), 0, http_credentials_src->NumberOfAuthnSchemes * sizeof(*http_credentials_dst->AuthnSchemes)); + if (!http_credentials_dst->AuthnSchemes) goto error; + memcpy(http_credentials_dst->AuthnSchemes, http_credentials_src->AuthnSchemes, http_credentials_src->NumberOfAuthnSchemes * sizeof(*http_credentials_dst->AuthnSchemes)); + } + if (http_credentials_src->ServerCertificateSubject) + { + if (unicode) + http_credentials_dst->ServerCertificateSubject = + RPCRT4_strndupW(http_credentials_src->ServerCertificateSubject, + strlenW(http_credentials_src->ServerCertificateSubject)); + else + http_credentials_dst->ServerCertificateSubject = + RPCRT4_strdupAtoW((char *)http_credentials_src->ServerCertificateSubject); + if (!http_credentials_dst->ServerCertificateSubject) goto error; + } + } + } + *qos_dst = qos; + return RPC_S_OK; + +error: + if (qos->qos) + { + if (qos->qos->AdditionalSecurityInfoType == RPC_C_AUTHN_INFO_TYPE_HTTP && + qos->qos->u.HttpCredentials) + { + if (qos->qos->u.HttpCredentials->TransportCredentials) + { + HeapFree(GetProcessHeap(), 0, qos->qos->u.HttpCredentials->TransportCredentials->User); + HeapFree(GetProcessHeap(), 0, qos->qos->u.HttpCredentials->TransportCredentials->Domain); + HeapFree(GetProcessHeap(), 0, qos->qos->u.HttpCredentials->TransportCredentials->Password); + HeapFree(GetProcessHeap(), 0, qos->qos->u.HttpCredentials->TransportCredentials); + } + HeapFree(GetProcessHeap(), 0, qos->qos->u.HttpCredentials->AuthnSchemes); + HeapFree(GetProcessHeap(), 0, qos->qos->u.HttpCredentials->ServerCertificateSubject); + HeapFree(GetProcessHeap(), 0, qos->qos->u.HttpCredentials); + } + HeapFree(GetProcessHeap(), 0, qos->qos); + } + HeapFree(GetProcessHeap(), 0, qos); + return RPC_S_OUT_OF_RESOURCES; +} + +ULONG RpcQualityOfService_AddRef(RpcQualityOfService *qos) +{ + return InterlockedIncrement(&qos->refs); +} + +ULONG RpcQualityOfService_Release(RpcQualityOfService *qos) +{ + ULONG refs = InterlockedDecrement(&qos->refs); + + if (!refs) + { + if (qos->qos->AdditionalSecurityInfoType == RPC_C_AUTHN_INFO_TYPE_HTTP) + { + if (qos->qos->u.HttpCredentials->TransportCredentials) + { + HeapFree(GetProcessHeap(), 0, qos->qos->u.HttpCredentials->TransportCredentials->User); + HeapFree(GetProcessHeap(), 0, qos->qos->u.HttpCredentials->TransportCredentials->Domain); + HeapFree(GetProcessHeap(), 0, qos->qos->u.HttpCredentials->TransportCredentials->Password); + HeapFree(GetProcessHeap(), 0, qos->qos->u.HttpCredentials->TransportCredentials); + } + HeapFree(GetProcessHeap(), 0, qos->qos->u.HttpCredentials->AuthnSchemes); + HeapFree(GetProcessHeap(), 0, qos->qos->u.HttpCredentials->ServerCertificateSubject); + HeapFree(GetProcessHeap(), 0, qos->qos->u.HttpCredentials); + } + HeapFree(GetProcessHeap(), 0, qos->qos); + HeapFree(GetProcessHeap(), 0, qos); + } + return refs; +} + +BOOL RpcQualityOfService_IsEqual(const RpcQualityOfService *qos1, const RpcQualityOfService *qos2) +{ + if (qos1 == qos2) + return TRUE; + + if (!qos1 || !qos2) + return FALSE; + + TRACE("qos1 = { %ld %ld %ld %ld }, qos2 = { %ld %ld %ld %ld }\n", + qos1->qos->Capabilities, qos1->qos->IdentityTracking, + qos1->qos->ImpersonationType, qos1->qos->AdditionalSecurityInfoType, + qos2->qos->Capabilities, qos2->qos->IdentityTracking, + qos2->qos->ImpersonationType, qos2->qos->AdditionalSecurityInfoType); + + if ((qos1->qos->Capabilities != qos2->qos->Capabilities) || + (qos1->qos->IdentityTracking != qos2->qos->IdentityTracking) || + (qos1->qos->ImpersonationType != qos2->qos->ImpersonationType) || + (qos1->qos->AdditionalSecurityInfoType != qos2->qos->AdditionalSecurityInfoType)) + return FALSE; + + if (qos1->qos->AdditionalSecurityInfoType == RPC_C_AUTHN_INFO_TYPE_HTTP) + { + const RPC_HTTP_TRANSPORT_CREDENTIALS_W *http_credentials1 = qos1->qos->u.HttpCredentials; + const RPC_HTTP_TRANSPORT_CREDENTIALS_W *http_credentials2 = qos2->qos->u.HttpCredentials; + + if (http_credentials1->Flags != http_credentials2->Flags) + return FALSE; + + if (http_credentials1->AuthenticationTarget != http_credentials2->AuthenticationTarget) + return FALSE; + + /* authentication schemes and server certificate subject not currently used */ + + if (http_credentials1->TransportCredentials != http_credentials2->TransportCredentials) + { + const SEC_WINNT_AUTH_IDENTITY_W *identity1 = http_credentials1->TransportCredentials; + const SEC_WINNT_AUTH_IDENTITY_W *identity2 = http_credentials2->TransportCredentials; + + if (!identity1 || !identity2) + return FALSE; + + /* compare user names */ + if (identity1->UserLength != identity2->UserLength || + memcmp(identity1->User, identity2->User, identity1->UserLength)) + return FALSE; + /* compare domain names */ + if (identity1->DomainLength != identity2->DomainLength || + memcmp(identity1->Domain, identity2->Domain, identity1->DomainLength)) + return FALSE; + /* compare passwords */ + if (identity1->PasswordLength != identity2->PasswordLength || + memcmp(identity1->Password, identity2->Password, identity1->PasswordLength)) + return FALSE; + } + } + + return TRUE; +} + /*********************************************************************** * RpcRevertToSelf (RPCRT4.@) */ @@ -1200,3 +1259,328 @@ RPC_STATUS WINAPI RpcRevertToSelf(void) RevertToSelf(); return RPC_S_OK; } + +/*********************************************************************** + * RpcMgmtSetComTimeout (RPCRT4.@) + */ +RPC_STATUS WINAPI RpcMgmtSetComTimeout(RPC_BINDING_HANDLE BindingHandle, unsigned int Timeout) +{ + FIXME("(%p, %d): stub\n", BindingHandle, Timeout); + return RPC_S_OK; +} + +/*********************************************************************** + * RpcBindingInqAuthInfoExA (RPCRT4.@) + */ +RPCRTAPI RPC_STATUS RPC_ENTRY +RpcBindingInqAuthInfoExA( RPC_BINDING_HANDLE Binding, RPC_CSTR *ServerPrincName, ULONG *AuthnLevel, + ULONG *AuthnSvc, RPC_AUTH_IDENTITY_HANDLE *AuthIdentity, ULONG *AuthzSvc, + ULONG RpcQosVersion, RPC_SECURITY_QOS *SecurityQOS ) +{ + FIXME("%p %p %p %p %p %p %u %p\n", Binding, ServerPrincName, AuthnLevel, + AuthnSvc, AuthIdentity, AuthzSvc, RpcQosVersion, SecurityQOS); + return RPC_S_INVALID_BINDING; +} + +/*********************************************************************** + * RpcBindingInqAuthInfoExW (RPCRT4.@) + */ +RPCRTAPI RPC_STATUS RPC_ENTRY +RpcBindingInqAuthInfoExW( RPC_BINDING_HANDLE Binding, RPC_WSTR *ServerPrincName, ULONG *AuthnLevel, + ULONG *AuthnSvc, RPC_AUTH_IDENTITY_HANDLE *AuthIdentity, ULONG *AuthzSvc, + ULONG RpcQosVersion, RPC_SECURITY_QOS *SecurityQOS ) +{ + FIXME("%p %p %p %p %p %p %u %p\n", Binding, ServerPrincName, AuthnLevel, + AuthnSvc, AuthIdentity, AuthzSvc, RpcQosVersion, SecurityQOS); + return RPC_S_INVALID_BINDING; +} + +/*********************************************************************** + * RpcBindingInqAuthInfoA (RPCRT4.@) + */ +RPCRTAPI RPC_STATUS RPC_ENTRY +RpcBindingInqAuthInfoA( RPC_BINDING_HANDLE Binding, RPC_CSTR *ServerPrincName, ULONG *AuthnLevel, + ULONG *AuthnSvc, RPC_AUTH_IDENTITY_HANDLE *AuthIdentity, ULONG *AuthzSvc ) +{ + FIXME("%p %p %p %p %p %p\n", Binding, ServerPrincName, AuthnLevel, + AuthnSvc, AuthIdentity, AuthzSvc); + return RPC_S_INVALID_BINDING; +} + +/*********************************************************************** + * RpcBindingInqAuthInfoW (RPCRT4.@) + */ +RPCRTAPI RPC_STATUS RPC_ENTRY +RpcBindingInqAuthInfoW( RPC_BINDING_HANDLE Binding, RPC_WSTR *ServerPrincName, ULONG *AuthnLevel, + ULONG *AuthnSvc, RPC_AUTH_IDENTITY_HANDLE *AuthIdentity, ULONG *AuthzSvc ) +{ + FIXME("%p %p %p %p %p %p\n", Binding, ServerPrincName, AuthnLevel, + AuthnSvc, AuthIdentity, AuthzSvc); + return RPC_S_INVALID_BINDING; +} + +/*********************************************************************** + * RpcBindingSetAuthInfoExA (RPCRT4.@) + */ +RPCRTAPI RPC_STATUS RPC_ENTRY +RpcBindingSetAuthInfoExA( RPC_BINDING_HANDLE Binding, RPC_CSTR ServerPrincName, + ULONG AuthnLevel, ULONG AuthnSvc, + RPC_AUTH_IDENTITY_HANDLE AuthIdentity, ULONG AuthzSvr, + RPC_SECURITY_QOS *SecurityQos ) +{ + RpcBinding* bind = (RpcBinding*)Binding; + SECURITY_STATUS r; + CredHandle cred; + TimeStamp exp; + ULONG package_count; + ULONG i; + PSecPkgInfoA packages; + ULONG cbMaxToken; + + TRACE("%p %s %u %u %p %u %p\n", Binding, debugstr_a((const char*)ServerPrincName), + AuthnLevel, AuthnSvc, AuthIdentity, AuthzSvr, SecurityQos); + + if (SecurityQos) + { + RPC_STATUS status; + + TRACE("SecurityQos { Version=%ld, Capabilties=0x%lx, IdentityTracking=%ld, ImpersonationLevel=%ld", + SecurityQos->Version, SecurityQos->Capabilities, SecurityQos->IdentityTracking, SecurityQos->ImpersonationType); + if (SecurityQos->Version >= 2) + { + const RPC_SECURITY_QOS_V2_A *SecurityQos2 = (const RPC_SECURITY_QOS_V2_A *)SecurityQos; + TRACE(", AdditionalSecurityInfoType=%ld", SecurityQos2->AdditionalSecurityInfoType); + if (SecurityQos2->AdditionalSecurityInfoType == RPC_C_AUTHN_INFO_TYPE_HTTP) + TRACE(", { %p, 0x%lx, %ld, %ld, %p, %s }", + SecurityQos2->u.HttpCredentials->TransportCredentials, + SecurityQos2->u.HttpCredentials->Flags, + SecurityQos2->u.HttpCredentials->AuthenticationTarget, + SecurityQos2->u.HttpCredentials->NumberOfAuthnSchemes, + SecurityQos2->u.HttpCredentials->AuthnSchemes, + SecurityQos2->u.HttpCredentials->ServerCertificateSubject); + } + TRACE("}\n"); + status = RpcQualityOfService_Create(SecurityQos, FALSE, &bind->QOS); + if (status != RPC_S_OK) + return status; + } + else + { + if (bind->QOS) RpcQualityOfService_Release(bind->QOS); + bind->QOS = NULL; + } + + if (AuthnSvc == RPC_C_AUTHN_DEFAULT) + AuthnSvc = RPC_C_AUTHN_WINNT; + + /* FIXME: the mapping should probably be retrieved using SSPI somehow */ + if (AuthnLevel == RPC_C_AUTHN_LEVEL_DEFAULT) + AuthnLevel = RPC_C_AUTHN_LEVEL_NONE; + + if ((AuthnLevel == RPC_C_AUTHN_LEVEL_NONE) || (AuthnSvc == RPC_C_AUTHN_NONE)) + { + if (bind->AuthInfo) RpcAuthInfo_Release(bind->AuthInfo); + bind->AuthInfo = NULL; + return RPC_S_OK; + } + + if (AuthnLevel > RPC_C_AUTHN_LEVEL_PKT_PRIVACY) + { + FIXME("unknown AuthnLevel %u\n", AuthnLevel); + return RPC_S_UNKNOWN_AUTHN_LEVEL; + } + + if (AuthzSvr) + { + FIXME("unsupported AuthzSvr %u\n", AuthzSvr); + return RPC_S_UNKNOWN_AUTHZ_SERVICE; + } + + r = EnumerateSecurityPackagesA(&package_count, &packages); + if (r != SEC_E_OK) + { + ERR("EnumerateSecurityPackagesA failed with error 0x%08x\n", r); + return RPC_S_SEC_PKG_ERROR; + } + + for (i = 0; i < package_count; i++) + if (packages[i].wRPCID == AuthnSvc) + break; + + if (i == package_count) + { + FIXME("unsupported AuthnSvc %u\n", AuthnSvc); + FreeContextBuffer(packages); + return RPC_S_UNKNOWN_AUTHN_SERVICE; + } + + TRACE("found package %s for service %u\n", packages[i].Name, AuthnSvc); + r = AcquireCredentialsHandleA((SEC_CHAR *)ServerPrincName, packages[i].Name, SECPKG_CRED_OUTBOUND, NULL, + AuthIdentity, NULL, NULL, &cred, &exp); + cbMaxToken = packages[i].cbMaxToken; + FreeContextBuffer(packages); + if (r == ERROR_SUCCESS) + { + if (bind->AuthInfo) RpcAuthInfo_Release(bind->AuthInfo); + bind->AuthInfo = NULL; + r = RpcAuthInfo_Create(AuthnLevel, AuthnSvc, cred, exp, cbMaxToken, + AuthIdentity, &bind->AuthInfo); + if (r != RPC_S_OK) + FreeCredentialsHandle(&cred); + return RPC_S_OK; + } + else + { + ERR("AcquireCredentialsHandleA failed with error 0x%08x\n", r); + return RPC_S_SEC_PKG_ERROR; + } +} + +/*********************************************************************** + * RpcBindingSetAuthInfoExW (RPCRT4.@) + */ +RPCRTAPI RPC_STATUS RPC_ENTRY +RpcBindingSetAuthInfoExW( RPC_BINDING_HANDLE Binding, RPC_WSTR ServerPrincName, ULONG AuthnLevel, + ULONG AuthnSvc, RPC_AUTH_IDENTITY_HANDLE AuthIdentity, ULONG AuthzSvr, + RPC_SECURITY_QOS *SecurityQos ) +{ + RpcBinding* bind = (RpcBinding*)Binding; + SECURITY_STATUS r; + CredHandle cred; + TimeStamp exp; + ULONG package_count; + ULONG i; + PSecPkgInfoW packages; + ULONG cbMaxToken; + + TRACE("%p %s %u %u %p %u %p\n", Binding, debugstr_w((const WCHAR*)ServerPrincName), + AuthnLevel, AuthnSvc, AuthIdentity, AuthzSvr, SecurityQos); + + if (SecurityQos) + { + RPC_STATUS status; + + TRACE("SecurityQos { Version=%ld, Capabilties=0x%lx, IdentityTracking=%ld, ImpersonationLevel=%ld", + SecurityQos->Version, SecurityQos->Capabilities, SecurityQos->IdentityTracking, SecurityQos->ImpersonationType); + if (SecurityQos->Version >= 2) + { + const RPC_SECURITY_QOS_V2_W *SecurityQos2 = (const RPC_SECURITY_QOS_V2_W *)SecurityQos; + TRACE(", AdditionalSecurityInfoType=%ld", SecurityQos2->AdditionalSecurityInfoType); + if (SecurityQos2->AdditionalSecurityInfoType == RPC_C_AUTHN_INFO_TYPE_HTTP) + TRACE(", { %p, 0x%lx, %ld, %ld, %p, %s }", + SecurityQos2->u.HttpCredentials->TransportCredentials, + SecurityQos2->u.HttpCredentials->Flags, + SecurityQos2->u.HttpCredentials->AuthenticationTarget, + SecurityQos2->u.HttpCredentials->NumberOfAuthnSchemes, + SecurityQos2->u.HttpCredentials->AuthnSchemes, + debugstr_w(SecurityQos2->u.HttpCredentials->ServerCertificateSubject)); + } + TRACE("}\n"); + status = RpcQualityOfService_Create(SecurityQos, TRUE, &bind->QOS); + if (status != RPC_S_OK) + return status; + } + else + { + if (bind->QOS) RpcQualityOfService_Release(bind->QOS); + bind->QOS = NULL; + } + + if (AuthnSvc == RPC_C_AUTHN_DEFAULT) + AuthnSvc = RPC_C_AUTHN_WINNT; + + /* FIXME: the mapping should probably be retrieved using SSPI somehow */ + if (AuthnLevel == RPC_C_AUTHN_LEVEL_DEFAULT) + AuthnLevel = RPC_C_AUTHN_LEVEL_NONE; + + if ((AuthnLevel == RPC_C_AUTHN_LEVEL_NONE) || (AuthnSvc == RPC_C_AUTHN_NONE)) + { + if (bind->AuthInfo) RpcAuthInfo_Release(bind->AuthInfo); + bind->AuthInfo = NULL; + return RPC_S_OK; + } + + if (AuthnLevel > RPC_C_AUTHN_LEVEL_PKT_PRIVACY) + { + FIXME("unknown AuthnLevel %u\n", AuthnLevel); + return RPC_S_UNKNOWN_AUTHN_LEVEL; + } + + if (AuthzSvr) + { + FIXME("unsupported AuthzSvr %u\n", AuthzSvr); + return RPC_S_UNKNOWN_AUTHZ_SERVICE; + } + + r = EnumerateSecurityPackagesW(&package_count, &packages); + if (r != SEC_E_OK) + { + ERR("EnumerateSecurityPackagesA failed with error 0x%08x\n", r); + return RPC_S_SEC_PKG_ERROR; + } + + for (i = 0; i < package_count; i++) + if (packages[i].wRPCID == AuthnSvc) + break; + + if (i == package_count) + { + FIXME("unsupported AuthnSvc %u\n", AuthnSvc); + FreeContextBuffer(packages); + return RPC_S_UNKNOWN_AUTHN_SERVICE; + } + + TRACE("found package %s for service %u\n", debugstr_w(packages[i].Name), AuthnSvc); + r = AcquireCredentialsHandleW((SEC_WCHAR *)ServerPrincName, packages[i].Name, SECPKG_CRED_OUTBOUND, NULL, + AuthIdentity, NULL, NULL, &cred, &exp); + cbMaxToken = packages[i].cbMaxToken; + FreeContextBuffer(packages); + if (r == ERROR_SUCCESS) + { + if (bind->AuthInfo) RpcAuthInfo_Release(bind->AuthInfo); + bind->AuthInfo = NULL; + r = RpcAuthInfo_Create(AuthnLevel, AuthnSvc, cred, exp, cbMaxToken, + AuthIdentity, &bind->AuthInfo); + if (r != RPC_S_OK) + FreeCredentialsHandle(&cred); + return RPC_S_OK; + } + else + { + ERR("AcquireCredentialsHandleA failed with error 0x%08x\n", r); + return RPC_S_SEC_PKG_ERROR; + } +} + +/*********************************************************************** + * RpcBindingSetAuthInfoA (RPCRT4.@) + */ +RPCRTAPI RPC_STATUS RPC_ENTRY +RpcBindingSetAuthInfoA( RPC_BINDING_HANDLE Binding, RPC_CSTR ServerPrincName, ULONG AuthnLevel, + ULONG AuthnSvc, RPC_AUTH_IDENTITY_HANDLE AuthIdentity, ULONG AuthzSvr ) +{ + TRACE("%p %s %u %u %p %u\n", Binding, debugstr_a((const char*)ServerPrincName), + AuthnLevel, AuthnSvc, AuthIdentity, AuthzSvr); + return RpcBindingSetAuthInfoExA(Binding, ServerPrincName, AuthnLevel, AuthnSvc, AuthIdentity, AuthzSvr, NULL); +} + +/*********************************************************************** + * RpcBindingSetAuthInfoW (RPCRT4.@) + */ +RPCRTAPI RPC_STATUS RPC_ENTRY +RpcBindingSetAuthInfoW( RPC_BINDING_HANDLE Binding, RPC_WSTR ServerPrincName, ULONG AuthnLevel, + ULONG AuthnSvc, RPC_AUTH_IDENTITY_HANDLE AuthIdentity, ULONG AuthzSvr ) +{ + TRACE("%p %s %u %u %p %u\n", Binding, debugstr_w((const WCHAR*)ServerPrincName), + AuthnLevel, AuthnSvc, AuthIdentity, AuthzSvr); + return RpcBindingSetAuthInfoExW(Binding, ServerPrincName, AuthnLevel, AuthnSvc, AuthIdentity, AuthzSvr, NULL); +} + +/*********************************************************************** + * RpcBindingSetOption (RPCRT4.@) + */ +RPC_STATUS WINAPI RpcBindingSetOption(RPC_BINDING_HANDLE BindingHandle, ULONG Option, ULONG OptionValue) +{ + FIXME("(%p, %d, %d): stub\n", BindingHandle, Option, OptionValue); + return RPC_S_OK; +} diff --git a/reactos/dll/win32/rpcrt4/rpc_binding.h b/reactos/dll/win32/rpcrt4/rpc_binding.h index e0f39aad4ed..ed8d4ea062d 100644 --- a/reactos/dll/win32/rpcrt4/rpc_binding.h +++ b/reactos/dll/win32/rpcrt4/rpc_binding.h @@ -15,29 +15,87 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __WINE_RPC_BINDING_H #define __WINE_RPC_BINDING_H #include "wine/rpcss_shared.h" +#include "rpcndr.h" +#include "security.h" +#include "wine/list.h" + + +typedef struct _RpcAuthInfo +{ + LONG refs; + + ULONG AuthnLevel; + ULONG AuthnSvc; + CredHandle cred; + TimeStamp exp; + ULONG cbMaxToken; + /* the auth identity pointer that the application passed us (freed by application) */ + RPC_AUTH_IDENTITY_HANDLE *identity; + /* our copy of NT auth identity structure, if the authentication service + * takes an NT auth identity */ + SEC_WINNT_AUTH_IDENTITY_W *nt_identity; +} RpcAuthInfo; + +typedef struct _RpcQualityOfService +{ + LONG refs; + + RPC_SECURITY_QOS_V2_W *qos; +} RpcQualityOfService; + +struct connection_ops; typedef struct _RpcConnection { - struct _RpcConnection* Next; - struct _RpcBinding* Used; BOOL server; - LPSTR Protseq; LPSTR NetworkAddr; LPSTR Endpoint; - HANDLE conn, thread; - OVERLAPPED ovl[2]; + LPWSTR NetworkOptions; + const struct connection_ops *ops; USHORT MaxTransmissionSize; + + /* authentication */ + CtxtHandle ctx; + TimeStamp exp; + ULONG attr; + RpcAuthInfo *AuthInfo; + ULONG encryption_auth_len; + ULONG signature_auth_len; + RpcQualityOfService *QOS; + + /* client-only */ + struct list conn_pool_entry; + ULONG assoc_group_id; /* association group returned during binding */ + + /* server-only */ /* The active interface bound to server. */ RPC_SYNTAX_IDENTIFIER ActiveInterface; + USHORT NextCallId; + struct _RpcConnection* Next; + struct _RpcBinding *server_binding; } RpcConnection; +struct connection_ops { + const char *name; + unsigned char epm_protocols[2]; /* only floors 3 and 4. see http://www.opengroup.org/onlinepubs/9629399/apdxl.htm */ + RpcConnection *(*alloc)(void); + RPC_STATUS (*open_connection_client)(RpcConnection *conn); + RPC_STATUS (*handoff)(RpcConnection *old_conn, RpcConnection *new_conn); + int (*read)(RpcConnection *conn, void *buffer, unsigned int len); + int (*write)(RpcConnection *conn, const void *buffer, unsigned int len); + int (*close)(RpcConnection *conn); + void (*cancel_call)(RpcConnection *conn); + size_t (*get_top_of_tower)(unsigned char *tower_data, const char *networkaddr, const char *endpoint); + RPC_STATUS (*parse_top_of_tower)(const unsigned char *tower_data, size_t tower_size, char **networkaddr, char **endpoint); +}; + /* don't know what MS's structure looks like */ typedef struct _RpcBinding { @@ -48,39 +106,92 @@ typedef struct _RpcBinding LPSTR Protseq; LPSTR NetworkAddr; LPSTR Endpoint; + LPWSTR NetworkOptions; RPC_BLOCKING_FN BlockingFn; ULONG ServerTid; RpcConnection* FromConn; + struct _RpcAssoc *Assoc; + + /* authentication */ + RpcAuthInfo *AuthInfo; + RpcQualityOfService *QOS; } RpcBinding; LPSTR RPCRT4_strndupA(LPCSTR src, INT len); -LPWSTR RPCRT4_strndupW(LPWSTR src, INT len); -LPSTR RPCRT4_strdupWtoA(LPWSTR src); -LPWSTR RPCRT4_strdupAtoW(LPSTR src); +LPWSTR RPCRT4_strndupW(LPCWSTR src, INT len); +LPSTR RPCRT4_strdupWtoA(LPCWSTR src); +LPWSTR RPCRT4_strdupAtoW(LPCSTR src); void RPCRT4_strfree(LPSTR src); #define RPCRT4_strdupA(x) RPCRT4_strndupA((x),-1) #define RPCRT4_strdupW(x) RPCRT4_strndupW((x),-1) -RPC_STATUS RPCRT4_CreateConnection(RpcConnection** Connection, BOOL server, LPSTR Protseq, LPSTR NetworkAddr, LPSTR Endpoint, LPSTR NetworkOptions, RpcBinding* Binding); +ULONG RpcAuthInfo_AddRef(RpcAuthInfo *AuthInfo); +ULONG RpcAuthInfo_Release(RpcAuthInfo *AuthInfo); +BOOL RpcAuthInfo_IsEqual(const RpcAuthInfo *AuthInfo1, const RpcAuthInfo *AuthInfo2); +ULONG RpcQualityOfService_AddRef(RpcQualityOfService *qos); +ULONG RpcQualityOfService_Release(RpcQualityOfService *qos); +BOOL RpcQualityOfService_IsEqual(const RpcQualityOfService *qos1, const RpcQualityOfService *qos2); + +RPC_STATUS RPCRT4_CreateConnection(RpcConnection** Connection, BOOL server, LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint, LPCWSTR NetworkOptions, RpcAuthInfo* AuthInfo, RpcQualityOfService *QOS); RPC_STATUS RPCRT4_DestroyConnection(RpcConnection* Connection); -RPC_STATUS RPCRT4_OpenConnection(RpcConnection* Connection); +RPC_STATUS RPCRT4_OpenClientConnection(RpcConnection* Connection); RPC_STATUS RPCRT4_CloseConnection(RpcConnection* Connection); RPC_STATUS RPCRT4_SpawnConnection(RpcConnection** Connection, RpcConnection* OldConnection); -RPC_STATUS RPCRT4_CreateBindingA(RpcBinding** Binding, BOOL server, LPSTR Protseq); -RPC_STATUS RPCRT4_CreateBindingW(RpcBinding** Binding, BOOL server, LPWSTR Protseq); -RPC_STATUS RPCRT4_CompleteBindingA(RpcBinding* Binding, LPSTR NetworkAddr, LPSTR Endpoint, LPSTR NetworkOptions); -RPC_STATUS RPCRT4_CompleteBindingW(RpcBinding* Binding, LPWSTR NetworkAddr, LPWSTR Endpoint, LPWSTR NetworkOptions); -RPC_STATUS RPCRT4_ResolveBinding(RpcBinding* Binding, LPSTR Endpoint); -RPC_STATUS RPCRT4_SetBindingObject(RpcBinding* Binding, UUID* ObjectUuid); +RPC_STATUS RPCRT4_ResolveBinding(RpcBinding* Binding, LPCSTR Endpoint); +RPC_STATUS RPCRT4_SetBindingObject(RpcBinding* Binding, const UUID* ObjectUuid); RPC_STATUS RPCRT4_MakeBinding(RpcBinding** Binding, RpcConnection* Connection); RPC_STATUS RPCRT4_ExportBinding(RpcBinding** Binding, RpcBinding* OldBinding); RPC_STATUS RPCRT4_DestroyBinding(RpcBinding* Binding); -RPC_STATUS RPCRT4_OpenBinding(RpcBinding* Binding, RpcConnection** Connection, PRPC_SYNTAX_IDENTIFIER TransferSyntax, PRPC_SYNTAX_IDENTIFIER InterfaceId); +RPC_STATUS RPCRT4_OpenBinding(RpcBinding* Binding, RpcConnection** Connection, + const RPC_SYNTAX_IDENTIFIER *TransferSyntax, const RPC_SYNTAX_IDENTIFIER *InterfaceId); RPC_STATUS RPCRT4_CloseBinding(RpcBinding* Binding, RpcConnection* Connection); BOOL RPCRT4_RPCSSOnDemandCall(PRPCSS_NP_MESSAGE msg, char *vardata_payload, PRPCSS_NP_REPLY reply); HANDLE RPCRT4_GetMasterMutex(void); HANDLE RPCRT4_RpcssNPConnect(void); +static inline const char *rpcrt4_conn_get_name(const RpcConnection *Connection) +{ + return Connection->ops->name; +} + +static inline int rpcrt4_conn_read(RpcConnection *Connection, + void *buffer, unsigned int len) +{ + return Connection->ops->read(Connection, buffer, len); +} + +static inline int rpcrt4_conn_write(RpcConnection *Connection, + const void *buffer, unsigned int len) +{ + return Connection->ops->write(Connection, buffer, len); +} + +static inline int rpcrt4_conn_close(RpcConnection *Connection) +{ + return Connection->ops->close(Connection); +} + +static inline void rpcrt4_conn_cancel_call(RpcConnection *Connection) +{ + Connection->ops->cancel_call(Connection); +} + +static inline RPC_STATUS rpcrt4_conn_handoff(RpcConnection *old_conn, RpcConnection *new_conn) +{ + return old_conn->ops->handoff(old_conn, new_conn); +} + +/* floors 3 and up */ +RPC_STATUS RpcTransport_GetTopOfTower(unsigned char *tower_data, size_t *tower_size, const char *protseq, const char *networkaddr, const char *endpoint); +RPC_STATUS RpcTransport_ParseTopOfTower(const unsigned char *tower_data, size_t tower_size, char **protseq, char **networkaddr, char **endpoint); + +void RPCRT4_SetThreadCurrentConnection(RpcConnection *Connection); +void RPCRT4_SetThreadCurrentCallHandle(RpcBinding *Binding); +RpcBinding *RPCRT4_GetThreadCurrentCallHandle(void); +void RPCRT4_PushThreadContextHandle(NDR_SCONTEXT SContext); +void RPCRT4_RemoveThreadContextHandle(NDR_SCONTEXT SContext); +NDR_SCONTEXT RPCRT4_PopThreadContextHandle(void); + #endif diff --git a/reactos/dll/win32/rpcrt4/rpc_defs.h b/reactos/dll/win32/rpcrt4/rpc_defs.h index dd4402082a8..c0c3609f1cc 100644 --- a/reactos/dll/win32/rpcrt4/rpc_defs.h +++ b/reactos/dll/win32/rpcrt4/rpc_defs.h @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __WINE_RPC_DEFS_H @@ -58,10 +58,10 @@ typedef struct RpcPktCommonHdr common; unsigned long alloc_hint; /* Data size in bytes excluding header and tail. */ unsigned short context_id; /* Presentation context identifier */ - unsigned char alert_count; /* Pending alert count */ - unsigned char padding[3]; /* Force alignment! */ + unsigned char cancel_count; /* Received cancel count */ + unsigned char reserved; /* Force alignment! */ unsigned long status; /* Runtime fault code (RPC_STATUS) */ - unsigned long reserved; + unsigned long reserved2; } RpcPktFaultHdr; typedef struct @@ -88,9 +88,8 @@ typedef struct typedef struct { - unsigned char padding1[2]; /* Force alignment! */ unsigned char num_results; /* Number of results */ - unsigned char padding2[3]; /* Force alignment! */ + unsigned char reserved[3]; /* Force alignment! */ struct { unsigned short result; unsigned short reason; @@ -103,9 +102,10 @@ typedef struct unsigned short max_tsize; /* Maximum transmission fragment size */ unsigned short max_rsize; /* Maximum receive fragment size */ unsigned long assoc_gid; /* Associated group id */ - /* + /* * Following this header are these fields: * RpcAddressString server_address; + * [0 - 3 bytes of padding so that results is 4-byte aligned] * RpcResults results; * RPC_SYNTAX_IDENTIFIER transfer; */ @@ -134,6 +134,18 @@ typedef union RpcPktBindNAckHdr bind_nack; } RpcPktHdr; +typedef struct +{ + unsigned char auth_type; /* authentication scheme in use */ + unsigned char auth_level; /* RPC_C_AUTHN_LEVEL* */ + unsigned char auth_pad_length; /* length of padding to restore n % 4 alignment */ + unsigned char auth_reserved; /* reserved, must be zero */ + unsigned long auth_context_id; /* unique value for the authenticated connection */ +} RpcAuthVerifier; + +#define RPC_AUTH_VERIFIER_LEN(common_hdr) \ + ((common_hdr)->auth_len ? (common_hdr)->auth_len + sizeof(RpcAuthVerifier) : 0) + #define RPC_VER_MAJOR 5 #define RPC_VER_MINOR 0 @@ -160,13 +172,30 @@ typedef union #define PKT_BIND_NACK 13 #define PKT_ALTER_CONTEXT 14 #define PKT_ALTER_CONTEXT_RESP 15 +#define PKT_AUTH3 16 #define PKT_SHUTDOWN 17 #define PKT_CO_CANCEL 18 #define PKT_ORPHANED 19 -#define RESULT_ACCEPT 0 +#define RESULT_ACCEPT 0 +#define RESULT_USER_REJECTION 1 +#define RESULT_PROVIDER_REJECTION 2 -#define NO_REASON 0 +#define REASON_NONE 0 +#define REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED 1 +#define REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED 2 +#define REASON_LOCAL_LIMIT_EXCEEDED 3 + +#define REJECT_REASON_NOT_SPECIFIED 0 +#define REJECT_TEMPORARY_CONGESTION 1 +#define REJECT_LOCAL_LIMIT_EXCEEDED 2 +#define REJECT_CALLED_PADDR_UNKNOWN 3 /* not used */ +#define REJECT_PROTOCOL_VERSION_NOT_SUPPORTED 4 +#define REJECT_DEFAULT_CONTEXT_NOT_SUPPORTED 5 /* not used */ +#define REJECT_USER_DATA_NOT_READABLE 6 /* not used */ +#define REJECT_NO_PSAP_AVAILABLE 7 /* not used */ +#define REJECT_UNKNOWN_AUTHN_SERVICE 8 +#define REJECT_INVALID_CHECKSUM 9 #define NCADG_IP_UDP 0x08 #define NCACN_IP_TCP 0x07 diff --git a/reactos/dll/win32/rpcrt4/rpc_epmap.c b/reactos/dll/win32/rpcrt4/rpc_epmap.c index 5d19262755c..cac3f626c1a 100644 --- a/reactos/dll/win32/rpcrt4/rpc_epmap.c +++ b/reactos/dll/win32/rpcrt4/rpc_epmap.c @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * * TODO: * - actually do things right @@ -29,13 +29,13 @@ #include "windef.h" #include "winbase.h" #include "winerror.h" -#include "winreg.h" #include "rpc.h" #include "wine/debug.h" #include "rpc_binding.h" +#include "epm_towers.h" WINE_DEFAULT_DEBUG_CHANNEL(ole); @@ -67,7 +67,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole); * RpcEpRegisterA (RPCRT4.@) */ RPC_STATUS WINAPI RpcEpRegisterA( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *BindingVector, - UUID_VECTOR *UuidVector, unsigned char *Annotation ) + UUID_VECTOR *UuidVector, RPC_CSTR Annotation ) { RPCSS_NP_MESSAGE msg; RPCSS_NP_REPLY reply; @@ -231,7 +231,7 @@ RPC_STATUS WINAPI RpcEpResolveBinding( RPC_BINDING_HANDLE Binding, RPC_IF_HANDLE msg.message_type = RPCSS_NP_MESSAGE_TYPEID_RESOLVEEPMSG; msg.message.resolveepmsg.iface = If->InterfaceId; msg.message.resolveepmsg.object = bind->ObjectUuid; - + msg.vardata_payload_size = strlen(bind->Protseq) + 1; /* send the message */ @@ -241,7 +241,144 @@ RPC_STATUS WINAPI RpcEpResolveBinding( RPC_BINDING_HANDLE Binding, RPC_IF_HANDLE /* empty-string result means not registered */ if (reply.as_string[0] == '\0') return EPT_S_NOT_REGISTERED; - + /* otherwise we fully bind the handle & return RPC_S_OK */ return RPCRT4_ResolveBinding(Binding, reply.as_string); } + +typedef unsigned int unsigned32; +typedef struct twr_t + { + unsigned32 tower_length; + /* [size_is] */ BYTE tower_octet_string[ 1 ]; + } twr_t; + +/*********************************************************************** + * TowerExplode (RPCRT4.@) + */ +RPC_STATUS WINAPI TowerExplode( + const twr_t *tower, PRPC_SYNTAX_IDENTIFIER object, PRPC_SYNTAX_IDENTIFIER syntax, + char **protseq, char **endpoint, char **address) +{ + size_t tower_size; + RPC_STATUS status; + const unsigned char *p; + u_int16 floor_count; + const twr_uuid_floor_t *object_floor; + const twr_uuid_floor_t *syntax_floor; + + if (protseq) + *protseq = NULL; + if (endpoint) + *endpoint = NULL; + if (address) + *address = NULL; + + tower_size = tower->tower_length; + + if (tower_size < sizeof(u_int16)) + return EPT_S_NOT_REGISTERED; + + p = &tower->tower_octet_string[0]; + + floor_count = *(const u_int16 *)p; + p += sizeof(u_int16); + tower_size -= sizeof(u_int16); + TRACE("floor_count: %d\n", floor_count); + /* FIXME: should we do something with the floor count? at the moment we don't */ + + if (tower_size < sizeof(*object_floor) + sizeof(*syntax_floor)) + return EPT_S_NOT_REGISTERED; + + object_floor = (const twr_uuid_floor_t *)p; + p += sizeof(*object_floor); + tower_size -= sizeof(*object_floor); + syntax_floor = (const twr_uuid_floor_t *)p; + p += sizeof(*syntax_floor); + tower_size -= sizeof(*syntax_floor); + + if ((object_floor->count_lhs != sizeof(object_floor->protid) + + sizeof(object_floor->uuid) + sizeof(object_floor->major_version)) || + (object_floor->protid != EPM_PROTOCOL_UUID) || + (object_floor->count_rhs != sizeof(object_floor->minor_version))) + return EPT_S_NOT_REGISTERED; + + if ((syntax_floor->count_lhs != sizeof(syntax_floor->protid) + + sizeof(syntax_floor->uuid) + sizeof(syntax_floor->major_version)) || + (syntax_floor->protid != EPM_PROTOCOL_UUID) || + (syntax_floor->count_rhs != sizeof(syntax_floor->minor_version))) + return EPT_S_NOT_REGISTERED; + + status = RpcTransport_ParseTopOfTower(p, tower_size, protseq, address, endpoint); + if ((status == RPC_S_OK) && syntax && object) + { + syntax->SyntaxGUID = syntax_floor->uuid; + syntax->SyntaxVersion.MajorVersion = syntax_floor->major_version; + syntax->SyntaxVersion.MinorVersion = syntax_floor->minor_version; + object->SyntaxGUID = object_floor->uuid; + object->SyntaxVersion.MajorVersion = object_floor->major_version; + object->SyntaxVersion.MinorVersion = object_floor->minor_version; + } + return status; +} + +/*********************************************************************** + * TowerConstruct (RPCRT4.@) + */ +RPC_STATUS WINAPI TowerConstruct( + const RPC_SYNTAX_IDENTIFIER *object, const RPC_SYNTAX_IDENTIFIER *syntax, + const char *protseq, const char *endpoint, const char *address, + twr_t **tower) +{ + size_t tower_size; + RPC_STATUS status; + unsigned char *p; + twr_uuid_floor_t *object_floor; + twr_uuid_floor_t *syntax_floor; + + *tower = NULL; + + status = RpcTransport_GetTopOfTower(NULL, &tower_size, protseq, address, endpoint); + + if (status != RPC_S_OK) + return status; + + tower_size += sizeof(u_int16) + sizeof(*object_floor) + sizeof(*syntax_floor); + *tower = I_RpcAllocate(FIELD_OFFSET(twr_t, tower_octet_string[tower_size])); + if (!*tower) + return RPC_S_OUT_OF_RESOURCES; + + (*tower)->tower_length = tower_size; + p = &(*tower)->tower_octet_string[0]; + *(u_int16 *)p = 5; /* number of floors */ + p += sizeof(u_int16); + object_floor = (twr_uuid_floor_t *)p; + p += sizeof(*object_floor); + syntax_floor = (twr_uuid_floor_t *)p; + p += sizeof(*syntax_floor); + + object_floor->count_lhs = sizeof(object_floor->protid) + sizeof(object_floor->uuid) + + sizeof(object_floor->major_version); + object_floor->protid = EPM_PROTOCOL_UUID; + object_floor->count_rhs = sizeof(object_floor->minor_version); + object_floor->uuid = object->SyntaxGUID; + object_floor->major_version = object->SyntaxVersion.MajorVersion; + object_floor->minor_version = object->SyntaxVersion.MinorVersion; + + syntax_floor->count_lhs = sizeof(syntax_floor->protid) + sizeof(syntax_floor->uuid) + + sizeof(syntax_floor->major_version); + syntax_floor->protid = EPM_PROTOCOL_UUID; + syntax_floor->count_rhs = sizeof(syntax_floor->minor_version); + syntax_floor->uuid = syntax->SyntaxGUID; + syntax_floor->major_version = syntax->SyntaxVersion.MajorVersion; + syntax_floor->minor_version = syntax->SyntaxVersion.MinorVersion; + + status = RpcTransport_GetTopOfTower(p, &tower_size, protseq, address, endpoint); + if (status != RPC_S_OK) + { + I_RpcFree(*tower); + *tower = NULL; + return status; + } + return RPC_S_OK; +} diff --git a/reactos/dll/win32/rpcrt4/rpc_message.c b/reactos/dll/win32/rpcrt4/rpc_message.c index 203528118b4..1248e4605fa 100644 --- a/reactos/dll/win32/rpcrt4/rpc_message.c +++ b/reactos/dll/win32/rpcrt4/rpc_message.c @@ -3,6 +3,7 @@ * * Copyright 2001-2002 Ove Kåven, TransGaming Technologies * Copyright 2004 Filip Navara + * Copyright 2006 CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -16,11 +17,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * TODO: - * - figure out whether we *really* got this right - * - check for errors and throw exceptions + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include @@ -30,7 +27,6 @@ #include "windef.h" #include "winbase.h" #include "winerror.h" -#include "winreg.h" #include "rpc.h" #include "rpcndr.h" @@ -39,13 +35,30 @@ #include "wine/debug.h" #include "rpc_binding.h" -#include "rpc_misc.h" #include "rpc_defs.h" #include "rpc_message.h" +#include "ncastatus.h" WINE_DEFAULT_DEBUG_CHANNEL(rpc); -static DWORD RPCRT4_GetHeaderSize(RpcPktHdr *Header) +/* note: the DCE/RPC spec says the alignment amount should be 4, but + * MS/RPC servers seem to always use 16 */ +#define AUTH_ALIGNMENT 16 + +/* gets the amount needed to round a value up to the specified alignment */ +#define ROUND_UP_AMOUNT(value, alignment) \ + (((alignment) - (((value) % (alignment)))) % (alignment)) +#define ROUND_UP(value, alignment) (((value) + ((alignment) - 1)) & ~((alignment)-1)) + +enum secure_packet_direction +{ + SECURE_PACKET_SEND, + SECURE_PACKET_RECEIVE +}; + +static RPC_STATUS I_RpcReAllocateBuffer(PRPC_MESSAGE pMsg); + +static DWORD RPCRT4_GetHeaderSize(const RpcPktHdr *Header) { static const DWORD header_sizes[] = { sizeof(Header->request), 0, sizeof(Header->response), @@ -54,7 +67,7 @@ static DWORD RPCRT4_GetHeaderSize(RpcPktHdr *Header) 0, 0, 0, 0, 0 }; ULONG ret = 0; - + if (Header->common.ptype < sizeof(header_sizes) / sizeof(header_sizes[0])) { ret = header_sizes[Header->common.ptype]; if (ret == 0) @@ -68,6 +81,19 @@ static DWORD RPCRT4_GetHeaderSize(RpcPktHdr *Header) return ret; } +static int packet_has_body(const RpcPktHdr *Header) +{ + return (Header->common.ptype == PKT_FAULT) || + (Header->common.ptype == PKT_REQUEST) || + (Header->common.ptype == PKT_RESPONSE); +} + +static int packet_has_auth_verifier(const RpcPktHdr *Header) +{ + return !(Header->common.ptype == PKT_BIND_NACK) && + !(Header->common.ptype == PKT_SHUTDOWN); +} + static VOID RPCRT4_BuildCommonHeader(RpcPktHdr *Header, unsigned char PacketType, unsigned long DataRepresentation) { @@ -82,7 +108,7 @@ static VOID RPCRT4_BuildCommonHeader(RpcPktHdr *Header, unsigned char PacketType Header->common.call_id = 1; Header->common.flags = 0; /* Flags and fragment length are computed in RPCRT4_Send. */ -} +} static RpcPktHdr *RPCRT4_BuildRequestHeader(unsigned long DataRepresentation, unsigned long BufferLength, @@ -114,7 +140,7 @@ static RpcPktHdr *RPCRT4_BuildRequestHeader(unsigned long DataRepresentation, return header; } -static RpcPktHdr *RPCRT4_BuildResponseHeader(unsigned long DataRepresentation, +RpcPktHdr *RPCRT4_BuildResponseHeader(unsigned long DataRepresentation, unsigned long BufferLength) { RpcPktHdr *header; @@ -151,8 +177,9 @@ RpcPktHdr *RPCRT4_BuildFaultHeader(unsigned long DataRepresentation, RpcPktHdr *RPCRT4_BuildBindHeader(unsigned long DataRepresentation, unsigned short MaxTransmissionSize, unsigned short MaxReceiveSize, - RPC_SYNTAX_IDENTIFIER *AbstractId, - RPC_SYNTAX_IDENTIFIER *TransferId) + unsigned long AssocGroupId, + const RPC_SYNTAX_IDENTIFIER *AbstractId, + const RPC_SYNTAX_IDENTIFIER *TransferId) { RpcPktHdr *header; @@ -165,6 +192,7 @@ RpcPktHdr *RPCRT4_BuildBindHeader(unsigned long DataRepresentation, header->common.frag_len = sizeof(header->bind); header->bind.max_tsize = MaxTransmissionSize; header->bind.max_rsize = MaxReceiveSize; + header->bind.assoc_gid = AssocGroupId; header->bind.num_elements = 1; header->bind.num_syntaxes = 1; memcpy(&header->bind.abstract, AbstractId, sizeof(RPC_SYNTAX_IDENTIFIER)); @@ -173,6 +201,22 @@ RpcPktHdr *RPCRT4_BuildBindHeader(unsigned long DataRepresentation, return header; } +static RpcPktHdr *RPCRT4_BuildAuthHeader(unsigned long DataRepresentation) +{ + RpcPktHdr *header; + + header = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + sizeof(header->common) + 12); + if (header == NULL) + return NULL; + + RPCRT4_BuildCommonHeader(header, PKT_AUTH3, DataRepresentation); + header->common.frag_len = 0x14; + header->common.auth_len = 0; + + return header; +} + RpcPktHdr *RPCRT4_BuildBindNackHeader(unsigned long DataRepresentation, unsigned char RpcVersion, unsigned char RpcVersionMinor) @@ -186,6 +230,7 @@ RpcPktHdr *RPCRT4_BuildBindNackHeader(unsigned long DataRepresentation, RPCRT4_BuildCommonHeader(header, PKT_BIND_NACK, DataRepresentation); header->common.frag_len = sizeof(header->bind_nack); + header->bind_nack.reject_reason = REJECT_REASON_NOT_SPECIFIED; header->bind_nack.protocols_count = 1; header->bind_nack.protocols[0].rpc_ver = RpcVersion; header->bind_nack.protocols[0].rpc_ver_minor = RpcVersionMinor; @@ -196,10 +241,11 @@ RpcPktHdr *RPCRT4_BuildBindNackHeader(unsigned long DataRepresentation, RpcPktHdr *RPCRT4_BuildBindAckHeader(unsigned long DataRepresentation, unsigned short MaxTransmissionSize, unsigned short MaxReceiveSize, - LPSTR ServerAddress, + unsigned long AssocGroupId, + LPCSTR ServerAddress, unsigned long Result, unsigned long Reason, - RPC_SYNTAX_IDENTIFIER *TransferId) + const RPC_SYNTAX_IDENTIFIER *TransferId) { RpcPktHdr *header; unsigned long header_size; @@ -207,9 +253,10 @@ RpcPktHdr *RPCRT4_BuildBindAckHeader(unsigned long DataRepresentation, RpcResults *results; RPC_SYNTAX_IDENTIFIER *transfer_id; - header_size = sizeof(header->bind_ack) + sizeof(RpcResults) + - sizeof(RPC_SYNTAX_IDENTIFIER) + sizeof(RpcAddressString) + - strlen(ServerAddress); + header_size = sizeof(header->bind_ack) + + ROUND_UP(FIELD_OFFSET(RpcAddressString, string[strlen(ServerAddress) + 1]), 4) + + sizeof(RpcResults) + + sizeof(RPC_SYNTAX_IDENTIFIER); header = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, header_size); if (header == NULL) { @@ -220,10 +267,12 @@ RpcPktHdr *RPCRT4_BuildBindAckHeader(unsigned long DataRepresentation, header->common.frag_len = header_size; header->bind_ack.max_tsize = MaxTransmissionSize; header->bind_ack.max_rsize = MaxReceiveSize; + header->bind_ack.assoc_gid = AssocGroupId; server_address = (RpcAddressString*)(&header->bind_ack + 1); server_address->length = strlen(ServerAddress) + 1; strcpy(server_address->string, ServerAddress); - results = (RpcResults*)((ULONG_PTR)server_address + sizeof(RpcAddressString) + server_address->length - 1); + /* results is 4-byte aligned */ + results = (RpcResults*)((ULONG_PTR)server_address + ROUND_UP(FIELD_OFFSET(RpcAddressString, string[server_address->length]), 4)); results->num_results = 1; results->results[0].result = Result; results->results[0].reason = Reason; @@ -238,104 +287,430 @@ VOID RPCRT4_FreeHeader(RpcPktHdr *Header) HeapFree(GetProcessHeap(), 0, Header); } +NCA_STATUS RPC2NCA_STATUS(RPC_STATUS status) +{ + switch (status) + { + case ERROR_INVALID_HANDLE: return NCA_S_FAULT_CONTEXT_MISMATCH; + case ERROR_OUTOFMEMORY: return NCA_S_FAULT_REMOTE_NO_MEMORY; + case RPC_S_NOT_LISTENING: return NCA_S_SERVER_TOO_BUSY; + case RPC_S_UNKNOWN_IF: return NCA_S_UNK_IF; + case RPC_S_SERVER_TOO_BUSY: return NCA_S_SERVER_TOO_BUSY; + case RPC_S_CALL_FAILED: return NCA_S_FAULT_UNSPEC; + case RPC_S_CALL_FAILED_DNE: return NCA_S_MANAGER_NOT_ENTERED; + case RPC_S_PROTOCOL_ERROR: return NCA_S_PROTO_ERROR; + case RPC_S_UNSUPPORTED_TYPE: return NCA_S_UNSUPPORTED_TYPE; + case RPC_S_INVALID_TAG: return NCA_S_FAULT_INVALID_TAG; + case RPC_S_INVALID_BOUND: return NCA_S_FAULT_INVALID_BOUND; + case RPC_S_PROCNUM_OUT_OF_RANGE: return NCA_S_OP_RNG_ERROR; + case RPC_X_SS_HANDLES_MISMATCH: return NCA_S_FAULT_CONTEXT_MISMATCH; + case RPC_S_CALL_CANCELLED: return NCA_S_FAULT_CANCEL; + case RPC_S_COMM_FAILURE: return NCA_S_COMM_FAILURE; + case RPC_X_WRONG_PIPE_ORDER: return NCA_S_FAULT_PIPE_ORDER; + case RPC_X_PIPE_CLOSED: return NCA_S_FAULT_PIPE_CLOSED; + case RPC_X_PIPE_DISCIPLINE_ERROR: return NCA_S_FAULT_PIPE_DISCIPLINE; + case RPC_X_PIPE_EMPTY: return NCA_S_FAULT_PIPE_EMPTY; + case STATUS_FLOAT_DIVIDE_BY_ZERO: return NCA_S_FAULT_FP_DIV_ZERO; + case STATUS_FLOAT_INVALID_OPERATION: return NCA_S_FAULT_FP_ERROR; + case STATUS_FLOAT_OVERFLOW: return NCA_S_FAULT_FP_OVERFLOW; + case STATUS_FLOAT_UNDERFLOW: return NCA_S_FAULT_FP_UNDERFLOW; + case STATUS_INTEGER_DIVIDE_BY_ZERO: return NCA_S_FAULT_INT_DIV_BY_ZERO; + case STATUS_INTEGER_OVERFLOW: return NCA_S_FAULT_INT_OVERFLOW; + default: return status; + } +} + +RPC_STATUS NCA2RPC_STATUS(NCA_STATUS status) +{ + switch (status) + { + case NCA_S_COMM_FAILURE: return RPC_S_COMM_FAILURE; + case NCA_S_OP_RNG_ERROR: return RPC_S_PROCNUM_OUT_OF_RANGE; + case NCA_S_UNK_IF: return RPC_S_UNKNOWN_IF; + case NCA_S_YOU_CRASHED: return RPC_S_CALL_FAILED; + case NCA_S_PROTO_ERROR: return RPC_S_PROTOCOL_ERROR; + case NCA_S_OUT_ARGS_TOO_BIG: return ERROR_NOT_ENOUGH_SERVER_MEMORY; + case NCA_S_SERVER_TOO_BUSY: return RPC_S_SERVER_TOO_BUSY; + case NCA_S_UNSUPPORTED_TYPE: return RPC_S_UNSUPPORTED_TYPE; + case NCA_S_FAULT_INT_DIV_BY_ZERO: return RPC_S_ZERO_DIVIDE; + case NCA_S_FAULT_ADDR_ERROR: return RPC_S_ADDRESS_ERROR; + case NCA_S_FAULT_FP_DIV_ZERO: return RPC_S_FP_DIV_ZERO; + case NCA_S_FAULT_FP_UNDERFLOW: return RPC_S_FP_UNDERFLOW; + case NCA_S_FAULT_FP_OVERFLOW: return RPC_S_FP_OVERFLOW; + case NCA_S_FAULT_INVALID_TAG: return RPC_S_INVALID_TAG; + case NCA_S_FAULT_INVALID_BOUND: return RPC_S_INVALID_BOUND; + case NCA_S_RPC_VERSION_MISMATCH: return RPC_S_PROTOCOL_ERROR; + case NCA_S_UNSPEC_REJECT: return RPC_S_CALL_FAILED_DNE; + case NCA_S_BAD_ACTID: return RPC_S_CALL_FAILED_DNE; + case NCA_S_WHO_ARE_YOU_FAILED: return RPC_S_CALL_FAILED; + case NCA_S_MANAGER_NOT_ENTERED: return RPC_S_CALL_FAILED_DNE; + case NCA_S_FAULT_CANCEL: return RPC_S_CALL_CANCELLED; + case NCA_S_FAULT_ILL_INST: return RPC_S_ADDRESS_ERROR; + case NCA_S_FAULT_FP_ERROR: return RPC_S_FP_OVERFLOW; + case NCA_S_FAULT_INT_OVERFLOW: return RPC_S_ADDRESS_ERROR; + case NCA_S_FAULT_UNSPEC: return RPC_S_CALL_FAILED; + case NCA_S_FAULT_PIPE_EMPTY: return RPC_X_PIPE_EMPTY; + case NCA_S_FAULT_PIPE_CLOSED: return RPC_X_PIPE_CLOSED; + case NCA_S_FAULT_PIPE_ORDER: return RPC_X_WRONG_PIPE_ORDER; + case NCA_S_FAULT_PIPE_DISCIPLINE: return RPC_X_PIPE_DISCIPLINE_ERROR; + case NCA_S_FAULT_PIPE_COMM_ERROR: return RPC_S_COMM_FAILURE; + case NCA_S_FAULT_PIPE_MEMORY: return ERROR_OUTOFMEMORY; + case NCA_S_FAULT_CONTEXT_MISMATCH: return ERROR_INVALID_HANDLE; + case NCA_S_FAULT_REMOTE_NO_MEMORY: return ERROR_NOT_ENOUGH_SERVER_MEMORY; + default: return status; + } +} + +static RPC_STATUS RPCRT4_SecurePacket(RpcConnection *Connection, + enum secure_packet_direction dir, + RpcPktHdr *hdr, unsigned int hdr_size, + unsigned char *stub_data, unsigned int stub_data_size, + RpcAuthVerifier *auth_hdr, + unsigned char *auth_value, unsigned int auth_value_size) +{ + SecBufferDesc message; + SecBuffer buffers[4]; + SECURITY_STATUS sec_status; + + message.ulVersion = SECBUFFER_VERSION; + message.cBuffers = sizeof(buffers)/sizeof(buffers[0]); + message.pBuffers = buffers; + + buffers[0].cbBuffer = hdr_size; + buffers[0].BufferType = SECBUFFER_DATA|SECBUFFER_READONLY_WITH_CHECKSUM; + buffers[0].pvBuffer = hdr; + buffers[1].cbBuffer = stub_data_size; + buffers[1].BufferType = SECBUFFER_DATA; + buffers[1].pvBuffer = stub_data; + buffers[2].cbBuffer = sizeof(*auth_hdr); + buffers[2].BufferType = SECBUFFER_DATA|SECBUFFER_READONLY_WITH_CHECKSUM; + buffers[2].pvBuffer = auth_hdr; + buffers[3].cbBuffer = auth_value_size; + buffers[3].BufferType = SECBUFFER_TOKEN; + buffers[3].pvBuffer = auth_value; + + if (dir == SECURE_PACKET_SEND) + { + if ((auth_hdr->auth_level == RPC_C_AUTHN_LEVEL_PKT_PRIVACY) && packet_has_body(hdr)) + { + sec_status = EncryptMessage(&Connection->ctx, 0, &message, 0 /* FIXME */); + if (sec_status != SEC_E_OK) + { + ERR("EncryptMessage failed with 0x%08x\n", sec_status); + return RPC_S_SEC_PKG_ERROR; + } + } + else if (auth_hdr->auth_level != RPC_C_AUTHN_LEVEL_NONE) + { + sec_status = MakeSignature(&Connection->ctx, 0, &message, 0 /* FIXME */); + if (sec_status != SEC_E_OK) + { + ERR("MakeSignature failed with 0x%08x\n", sec_status); + return RPC_S_SEC_PKG_ERROR; + } + } + } + else if (dir == SECURE_PACKET_RECEIVE) + { + if ((auth_hdr->auth_level == RPC_C_AUTHN_LEVEL_PKT_PRIVACY) && packet_has_body(hdr)) + { + sec_status = DecryptMessage(&Connection->ctx, &message, 0 /* FIXME */, 0); + if (sec_status != SEC_E_OK) + { + ERR("DecryptMessage failed with 0x%08x\n", sec_status); + return RPC_S_SEC_PKG_ERROR; + } + } + else if (auth_hdr->auth_level != RPC_C_AUTHN_LEVEL_NONE) + { + sec_status = VerifySignature(&Connection->ctx, &message, 0 /* FIXME */, NULL); + if (sec_status != SEC_E_OK) + { + ERR("VerifySignature failed with 0x%08x\n", sec_status); + return RPC_S_SEC_PKG_ERROR; + } + } + } + + return RPC_S_OK; +} + +/*********************************************************************** + * RPCRT4_SendAuth (internal) + * + * Transmit a packet with authorization data over connection in acceptable fragments. + */ +static RPC_STATUS RPCRT4_SendAuth(RpcConnection *Connection, RpcPktHdr *Header, + void *Buffer, unsigned int BufferLength, + const void *Auth, unsigned int AuthLength) +{ + PUCHAR buffer_pos; + DWORD hdr_size; + LONG count; + unsigned char *pkt; + LONG alen; + RPC_STATUS status; + + RPCRT4_SetThreadCurrentConnection(Connection); + + buffer_pos = Buffer; + /* The packet building functions save the packet header size, so we can use it. */ + hdr_size = Header->common.frag_len; + if (AuthLength) + Header->common.auth_len = AuthLength; + else if (Connection->AuthInfo && packet_has_auth_verifier(Header)) + { + if ((Connection->AuthInfo->AuthnLevel == RPC_C_AUTHN_LEVEL_PKT_PRIVACY) && packet_has_body(Header)) + Header->common.auth_len = Connection->encryption_auth_len; + else + Header->common.auth_len = Connection->signature_auth_len; + } + else + Header->common.auth_len = 0; + Header->common.flags |= RPC_FLG_FIRST; + Header->common.flags &= ~RPC_FLG_LAST; + + alen = RPC_AUTH_VERIFIER_LEN(&Header->common); + + while (!(Header->common.flags & RPC_FLG_LAST)) { + unsigned char auth_pad_len = Header->common.auth_len ? ROUND_UP_AMOUNT(BufferLength, AUTH_ALIGNMENT) : 0; + unsigned int pkt_size = BufferLength + hdr_size + alen + auth_pad_len; + + /* decide if we need to split the packet into fragments */ + if (pkt_size <= Connection->MaxTransmissionSize) { + Header->common.flags |= RPC_FLG_LAST; + Header->common.frag_len = pkt_size; + } else { + auth_pad_len = 0; + /* make sure packet payload will be a multiple of 16 */ + Header->common.frag_len = + ((Connection->MaxTransmissionSize - hdr_size - alen) & ~(AUTH_ALIGNMENT-1)) + + hdr_size + alen; + } + + pkt = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Header->common.frag_len); + + memcpy(pkt, Header, hdr_size); + + /* fragment consisted of header only and is the last one */ + if (hdr_size == Header->common.frag_len) + goto write; + + memcpy(pkt + hdr_size, buffer_pos, Header->common.frag_len - hdr_size - auth_pad_len - alen); + + /* add the authorization info */ + if (Connection->AuthInfo && packet_has_auth_verifier(Header)) + { + RpcAuthVerifier *auth_hdr = (RpcAuthVerifier *)&pkt[Header->common.frag_len - alen]; + + auth_hdr->auth_type = Connection->AuthInfo->AuthnSvc; + auth_hdr->auth_level = Connection->AuthInfo->AuthnLevel; + auth_hdr->auth_pad_length = auth_pad_len; + auth_hdr->auth_reserved = 0; + /* a unique number... */ + auth_hdr->auth_context_id = (unsigned long)Connection; + + if (AuthLength) + memcpy(auth_hdr + 1, Auth, AuthLength); + else + { + status = RPCRT4_SecurePacket(Connection, SECURE_PACKET_SEND, + (RpcPktHdr *)pkt, hdr_size, + pkt + hdr_size, Header->common.frag_len - hdr_size - alen, + auth_hdr, + (unsigned char *)(auth_hdr + 1), Header->common.auth_len); + if (status != RPC_S_OK) + { + HeapFree(GetProcessHeap(), 0, pkt); + RPCRT4_SetThreadCurrentConnection(NULL); + return status; + } + } + } + +write: + count = rpcrt4_conn_write(Connection, pkt, Header->common.frag_len); + HeapFree(GetProcessHeap(), 0, pkt); + if (count<0) { + WARN("rpcrt4_conn_write failed (auth)\n"); + RPCRT4_SetThreadCurrentConnection(NULL); + return RPC_S_CALL_FAILED; + } + + buffer_pos += Header->common.frag_len - hdr_size - alen - auth_pad_len; + BufferLength -= Header->common.frag_len - hdr_size - alen - auth_pad_len; + Header->common.flags &= ~RPC_FLG_FIRST; + } + + RPCRT4_SetThreadCurrentConnection(NULL); + return RPC_S_OK; +} + +/*********************************************************************** + * RPCRT4_ClientAuthorize (internal) + * + * Authorize a client connection. A NULL in param signifies a new connection. + */ +static RPC_STATUS RPCRT4_ClientAuthorize(RpcConnection *conn, SecBuffer *in, + SecBuffer *out) +{ + SECURITY_STATUS r; + SecBufferDesc out_desc; + SecBufferDesc inp_desc; + SecPkgContext_Sizes secctx_sizes; + BOOL continue_needed; + ULONG context_req = ISC_REQ_CONNECTION | ISC_REQ_USE_DCE_STYLE | + ISC_REQ_MUTUAL_AUTH | ISC_REQ_DELEGATE; + + if (conn->AuthInfo->AuthnLevel == RPC_C_AUTHN_LEVEL_PKT_INTEGRITY) + context_req |= ISC_REQ_INTEGRITY; + else if (conn->AuthInfo->AuthnLevel == RPC_C_AUTHN_LEVEL_PKT_PRIVACY) + context_req |= ISC_REQ_CONFIDENTIALITY | ISC_REQ_INTEGRITY; + + out->BufferType = SECBUFFER_TOKEN; + out->cbBuffer = conn->AuthInfo->cbMaxToken; + out->pvBuffer = HeapAlloc(GetProcessHeap(), 0, out->cbBuffer); + if (!out->pvBuffer) return ERROR_OUTOFMEMORY; + + out_desc.ulVersion = 0; + out_desc.cBuffers = 1; + out_desc.pBuffers = out; + + inp_desc.cBuffers = 1; + inp_desc.pBuffers = in; + inp_desc.ulVersion = 0; + + r = InitializeSecurityContextA(&conn->AuthInfo->cred, in ? &conn->ctx : NULL, + NULL, context_req, 0, SECURITY_NETWORK_DREP, + in ? &inp_desc : NULL, 0, &conn->ctx, &out_desc, &conn->attr, + &conn->exp); + if (FAILED(r)) + { + WARN("InitializeSecurityContext failed with error 0x%08x\n", r); + goto failed; + } + + TRACE("r = 0x%08x, attr = 0x%08x\n", r, conn->attr); + continue_needed = ((r == SEC_I_CONTINUE_NEEDED) || + (r == SEC_I_COMPLETE_AND_CONTINUE)); + + if ((r == SEC_I_COMPLETE_NEEDED) || (r == SEC_I_COMPLETE_AND_CONTINUE)) + { + TRACE("complete needed\n"); + r = CompleteAuthToken(&conn->ctx, &out_desc); + if (FAILED(r)) + { + WARN("CompleteAuthToken failed with error 0x%08x\n", r); + goto failed; + } + } + + TRACE("cbBuffer = %ld\n", out->cbBuffer); + + if (!continue_needed) + { + r = QueryContextAttributesA(&conn->ctx, SECPKG_ATTR_SIZES, &secctx_sizes); + if (FAILED(r)) + { + WARN("QueryContextAttributes failed with error 0x%08x\n", r); + goto failed; + } + conn->signature_auth_len = secctx_sizes.cbMaxSignature; + conn->encryption_auth_len = secctx_sizes.cbSecurityTrailer; + } + + return RPC_S_OK; + +failed: + HeapFree(GetProcessHeap(), 0, out->pvBuffer); + out->pvBuffer = NULL; + return ERROR_ACCESS_DENIED; /* FIXME: is this correct? */ +} + +/*********************************************************************** + * RPCRT4_AuthorizeBinding (internal) + */ +static RPC_STATUS RPCRT_AuthorizeConnection(RpcConnection* conn, + BYTE *challenge, ULONG count) +{ + SecBuffer inp, out; + RpcPktHdr *resp_hdr; + RPC_STATUS status; + + TRACE("challenge %s, %d bytes\n", challenge, count); + + inp.BufferType = SECBUFFER_TOKEN; + inp.pvBuffer = challenge; + inp.cbBuffer = count; + + status = RPCRT4_ClientAuthorize(conn, &inp, &out); + if (status) return status; + + resp_hdr = RPCRT4_BuildAuthHeader(NDR_LOCAL_DATA_REPRESENTATION); + if (!resp_hdr) + return E_OUTOFMEMORY; + + status = RPCRT4_SendAuth(conn, resp_hdr, NULL, 0, out.pvBuffer, out.cbBuffer); + + HeapFree(GetProcessHeap(), 0, out.pvBuffer); + RPCRT4_FreeHeader(resp_hdr); + + return status; +} + /*********************************************************************** * RPCRT4_Send (internal) - * + * * Transmit a packet over connection in acceptable fragments. */ RPC_STATUS RPCRT4_Send(RpcConnection *Connection, RpcPktHdr *Header, void *Buffer, unsigned int BufferLength) { - PUCHAR buffer_pos; - DWORD hdr_size, count; + RPC_STATUS r; + SecBuffer out; - buffer_pos = Buffer; - /* The packet building functions save the packet header size, so we can use it. */ - hdr_size = Header->common.frag_len; - Header->common.flags |= RPC_FLG_FIRST; - Header->common.flags &= ~RPC_FLG_LAST; - while (!(Header->common.flags & RPC_FLG_LAST)) { - /* decide if we need to split the packet into fragments */ - if ((BufferLength + hdr_size) <= Connection->MaxTransmissionSize) { - Header->common.flags |= RPC_FLG_LAST; - Header->common.frag_len = BufferLength + hdr_size; - } else { - Header->common.frag_len = Connection->MaxTransmissionSize; - } - - /* transmit packet header */ - if (!WriteFile(Connection->conn, Header, hdr_size, &count, &Connection->ovl[1]) && - ERROR_IO_PENDING != GetLastError()) { - WARN("WriteFile failed with error %ld\n", GetLastError()); - return GetLastError(); - } - if (!GetOverlappedResult(Connection->conn, &Connection->ovl[1], &count, TRUE)) { - WARN("GetOverlappedResult failed with error %ld\n", GetLastError()); - return GetLastError(); - } - - /* fragment consisted of header only and is the last one */ - if (hdr_size == Header->common.frag_len && - Header->common.flags & RPC_FLG_LAST) { - return RPC_S_OK; - } - - /* send the fragment data */ - if (!WriteFile(Connection->conn, buffer_pos, Header->common.frag_len - hdr_size, &count, &Connection->ovl[1]) && - ERROR_IO_PENDING != GetLastError()) { - WARN("WriteFile failed with error %ld\n", GetLastError()); - return GetLastError(); - } - if (!GetOverlappedResult(Connection->conn, &Connection->ovl[1], &count, TRUE)) { - WARN("GetOverlappedResult failed with error %ld\n", GetLastError()); - return GetLastError(); - } - - buffer_pos += Header->common.frag_len - hdr_size; - BufferLength -= Header->common.frag_len - hdr_size; - Header->common.flags &= ~RPC_FLG_FIRST; + if (!Connection->AuthInfo || SecIsValidHandle(&Connection->ctx)) + { + return RPCRT4_SendAuth(Connection, Header, Buffer, BufferLength, NULL, 0); } - return RPC_S_OK; + /* tack on a negotiate packet */ + RPCRT4_ClientAuthorize(Connection, NULL, &out); + r = RPCRT4_SendAuth(Connection, Header, Buffer, BufferLength, out.pvBuffer, out.cbBuffer); + HeapFree(GetProcessHeap(), 0, out.pvBuffer); + + return r; } /*********************************************************************** * RPCRT4_Receive (internal) - * + * * Receive a packet from connection and merge the fragments. */ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header, PRPC_MESSAGE pMsg) { RPC_STATUS status; - DWORD dwRead, hdr_length; + DWORD hdr_length; + LONG dwRead; unsigned short first_flag; unsigned long data_length; unsigned long buffer_length; - unsigned char *buffer_ptr; + unsigned long auth_length; + unsigned char *auth_data = NULL; RpcPktCommonHdr common_hdr; *Header = NULL; TRACE("(%p, %p, %p)\n", Connection, Header, pMsg); + RPCRT4_SetThreadCurrentConnection(Connection); + /* read packet common header */ - if (!ReadFile(Connection->conn, &common_hdr, sizeof(common_hdr), &dwRead, &Connection->ovl[0]) && - ERROR_IO_PENDING != GetLastError()) { - WARN("ReadFile failed with error %ld\n", GetLastError()); - status = RPC_S_PROTOCOL_ERROR; - goto fail; - } - if (!GetOverlappedResult(Connection->conn, &Connection->ovl[0], &dwRead, TRUE)) { - if (GetLastError() != ERROR_MORE_DATA) { - WARN("GetOverlappedResult failed with error %ld\n", GetLastError()); - status = RPC_S_PROTOCOL_ERROR; - goto fail; - } - } + dwRead = rpcrt4_conn_read(Connection, &common_hdr, sizeof(common_hdr)); if (dwRead != sizeof(common_hdr)) { - WARN("Short read of header, %ld/%d bytes\n", dwRead, sizeof(common_hdr)); - status = RPC_S_PROTOCOL_ERROR; + WARN("Short read of header, %d bytes\n", dwRead); + status = RPC_S_CALL_FAILED; goto fail; } @@ -358,27 +733,13 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header, memcpy(*Header, &common_hdr, sizeof(common_hdr)); /* read the rest of packet header */ - if (!ReadFile(Connection->conn, &(*Header)->common + 1, - hdr_length - sizeof(common_hdr), &dwRead, &Connection->ovl[0]) && - ERROR_IO_PENDING != GetLastError()) { - WARN("ReadFile failed with error %ld\n", GetLastError()); - status = RPC_S_PROTOCOL_ERROR; - goto fail; - } - if (!GetOverlappedResult(Connection->conn, &Connection->ovl[0], &dwRead, TRUE)) { - if (GetLastError() != ERROR_MORE_DATA) { - WARN("GetOverlappedResult failed with error %ld\n", GetLastError()); - status = RPC_S_PROTOCOL_ERROR; - goto fail; - } - } + dwRead = rpcrt4_conn_read(Connection, &(*Header)->common + 1, hdr_length - sizeof(common_hdr)); if (dwRead != hdr_length - sizeof(common_hdr)) { - WARN("bad header length, %ld/%ld bytes\n", dwRead, hdr_length - sizeof(common_hdr)); - status = RPC_S_PROTOCOL_ERROR; + WARN("bad header length, %d bytes, hdr_length %d\n", dwRead, hdr_length); + status = RPC_S_CALL_FAILED; goto fail; } - /* read packet body */ switch (common_hdr.ptype) { case PKT_RESPONSE: @@ -388,7 +749,7 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header, pMsg->BufferLength = (*Header)->request.alloc_hint; break; default: - pMsg->BufferLength = common_hdr.frag_len - hdr_length; + pMsg->BufferLength = common_hdr.frag_len - hdr_length - RPC_AUTH_VERIFIER_LEN(&common_hdr); } TRACE("buffer length = %u\n", pMsg->BufferLength); @@ -397,89 +758,161 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header, if (status != RPC_S_OK) goto fail; first_flag = RPC_FLG_FIRST; + auth_length = common_hdr.auth_len; + if (auth_length) { + auth_data = HeapAlloc(GetProcessHeap(), 0, RPC_AUTH_VERIFIER_LEN(&common_hdr)); + if (!auth_data) { + status = RPC_S_OUT_OF_RESOURCES; + goto fail; + } + } buffer_length = 0; - buffer_ptr = pMsg->Buffer; - while (buffer_length < pMsg->BufferLength) + while (TRUE) { - data_length = (*Header)->common.frag_len - hdr_length; - if (((*Header)->common.flags & RPC_FLG_FIRST) != first_flag || - data_length + buffer_length > pMsg->BufferLength) { - TRACE("invalid packet flags or buffer length\n"); + unsigned int header_auth_len = RPC_AUTH_VERIFIER_LEN(&(*Header)->common); + + /* verify header fields */ + + if (((*Header)->common.frag_len < hdr_length) || + ((*Header)->common.frag_len - hdr_length < header_auth_len)) { + WARN("frag_len %d too small for hdr_length %d and auth_len %d\n", + (*Header)->common.frag_len, hdr_length, header_auth_len); status = RPC_S_PROTOCOL_ERROR; goto fail; } - if (data_length == 0) dwRead = 0; else { - if (!ReadFile(Connection->conn, buffer_ptr, data_length, &dwRead, &Connection->ovl[0]) && - ERROR_IO_PENDING != GetLastError()) { - WARN("ReadFile failed with error %ld\n", GetLastError()); + if ((*Header)->common.auth_len != auth_length) { + WARN("auth_len header field changed from %ld to %d\n", + auth_length, (*Header)->common.auth_len); + status = RPC_S_PROTOCOL_ERROR; + goto fail; + } + + if (((*Header)->common.flags & RPC_FLG_FIRST) != first_flag) { + TRACE("invalid packet flags\n"); + status = RPC_S_PROTOCOL_ERROR; + goto fail; + } + + data_length = (*Header)->common.frag_len - hdr_length - header_auth_len; + if (data_length + buffer_length > pMsg->BufferLength) { + TRACE("allocation hint exceeded, new buffer length = %ld\n", + data_length + buffer_length); + pMsg->BufferLength = data_length + buffer_length; + status = I_RpcReAllocateBuffer(pMsg); + if (status != RPC_S_OK) goto fail; + } + + if (data_length == 0) dwRead = 0; else + dwRead = rpcrt4_conn_read(Connection, + (unsigned char *)pMsg->Buffer + buffer_length, data_length); + if (dwRead != data_length) { + WARN("bad data length, %d/%ld\n", dwRead, data_length); + status = RPC_S_CALL_FAILED; + goto fail; + } + + if (header_auth_len) { + if (header_auth_len < sizeof(RpcAuthVerifier)) { + WARN("bad auth verifier length %d\n", header_auth_len); status = RPC_S_PROTOCOL_ERROR; goto fail; } - if (!GetOverlappedResult(Connection->conn, &Connection->ovl[0], &dwRead, TRUE)) { - if (GetLastError() != ERROR_MORE_DATA) { - WARN("GetOverlappedResult failed with error %ld\n", GetLastError()); - status = RPC_S_PROTOCOL_ERROR; - goto fail; - } - } - } - if (dwRead != data_length) { - WARN("bad data length, %ld/%ld\n", dwRead, data_length); - status = RPC_S_PROTOCOL_ERROR; - goto fail; - } - /* when there is no more data left, it should be the last packet */ - if (buffer_length == pMsg->BufferLength && - ((*Header)->common.flags & RPC_FLG_LAST) == 0) { - WARN("no more data left, but not last packet\n"); - status = RPC_S_PROTOCOL_ERROR; - goto fail; + /* FIXME: we should accumulate authentication data for the bind, + * bind_ack, alter_context and alter_context_response if necessary. + * however, the details of how this is done is very sketchy in the + * DCE/RPC spec. for all other packet types that have authentication + * verifier data then it is just duplicated in all the fragments */ + dwRead = rpcrt4_conn_read(Connection, auth_data, header_auth_len); + if (dwRead != header_auth_len) { + WARN("bad authentication data length, %d/%d\n", dwRead, + header_auth_len); + status = RPC_S_CALL_FAILED; + goto fail; + } + + /* these packets are handled specially, not by the generic SecurePacket + * function */ + if ((common_hdr.ptype != PKT_BIND) && + (common_hdr.ptype != PKT_BIND_ACK) && + (common_hdr.ptype != PKT_AUTH3)) + { + status = RPCRT4_SecurePacket(Connection, SECURE_PACKET_RECEIVE, + *Header, hdr_length, + (unsigned char *)pMsg->Buffer + buffer_length, data_length, + (RpcAuthVerifier *)auth_data, + (unsigned char *)auth_data + sizeof(RpcAuthVerifier), + header_auth_len - sizeof(RpcAuthVerifier)); + if (status != RPC_S_OK) goto fail; + } } buffer_length += data_length; - if (buffer_length < pMsg->BufferLength) { + if (!((*Header)->common.flags & RPC_FLG_LAST)) { TRACE("next header\n"); /* read the header of next packet */ - if (!ReadFile(Connection->conn, *Header, hdr_length, &dwRead, &Connection->ovl[0]) && - ERROR_IO_PENDING != GetLastError()) { - WARN("ReadFile failed with error %ld\n", GetLastError()); - status = GetLastError(); - goto fail; - } - if (!GetOverlappedResult(Connection->conn, &Connection->ovl[0], &dwRead, TRUE)) { - if (GetLastError() != ERROR_MORE_DATA) { - WARN("GetOverlappedResult failed with error %ld\n", GetLastError()); - status = RPC_S_PROTOCOL_ERROR; - goto fail; - } - } + dwRead = rpcrt4_conn_read(Connection, *Header, hdr_length); if (dwRead != hdr_length) { - WARN("invalid packet header size (%ld)\n", dwRead); - status = RPC_S_PROTOCOL_ERROR; + WARN("invalid packet header size (%d)\n", dwRead); + status = RPC_S_CALL_FAILED; goto fail; } - buffer_ptr += data_length; first_flag = 0; + } else { + break; } } + pMsg->BufferLength = buffer_length; + + /* respond to authorization request */ + if (common_hdr.ptype == PKT_BIND_ACK && auth_length > sizeof(RpcAuthVerifier)) + { + status = RPCRT_AuthorizeConnection(Connection, + auth_data + sizeof(RpcAuthVerifier), + auth_length); + if (status) + goto fail; + } /* success */ status = RPC_S_OK; fail: - if (status != RPC_S_OK && *Header) { + RPCRT4_SetThreadCurrentConnection(NULL); + if (status != RPC_S_OK) { RPCRT4_FreeHeader(*Header); *Header = NULL; } + HeapFree(GetProcessHeap(), 0, auth_data); return status; } /*********************************************************************** * I_RpcGetBuffer [RPCRT4.@] + * + * Allocates a buffer for use by I_RpcSend or I_RpcSendReceive and binds to the + * server interface. + * + * PARAMS + * pMsg [I/O] RPC message information. + * + * RETURNS + * Success: RPC_S_OK. + * Failure: RPC_S_INVALID_BINDING if pMsg->Handle is invalid. + * RPC_S_SERVER_UNAVAILABLE if unable to connect to server. + * ERROR_OUTOFMEMORY if buffer allocation failed. + * + * NOTES + * The pMsg->BufferLength field determines the size of the buffer to allocate, + * in bytes. + * + * Use I_RpcFreeBuffer() to unbind from the server and free the message buffer. + * + * SEE ALSO + * I_RpcFreeBuffer(), I_RpcSend(), I_RpcReceive(), I_RpcSendReceive(). */ RPC_STATUS WINAPI I_RpcGetBuffer(PRPC_MESSAGE pMsg) { @@ -492,8 +925,32 @@ RPC_STATUS WINAPI I_RpcGetBuffer(PRPC_MESSAGE pMsg) return pMsg->Buffer ? S_OK : E_OUTOFMEMORY; } +/*********************************************************************** + * I_RpcReAllocateBuffer (internal) + */ +static RPC_STATUS I_RpcReAllocateBuffer(PRPC_MESSAGE pMsg) +{ + TRACE("(%p): BufferLength=%d\n", pMsg, pMsg->BufferLength); + pMsg->Buffer = HeapReAlloc(GetProcessHeap(), 0, pMsg->Buffer, pMsg->BufferLength); + + TRACE("Buffer=%p\n", pMsg->Buffer); + return pMsg->Buffer ? RPC_S_OK : RPC_S_OUT_OF_RESOURCES; +} + /*********************************************************************** * I_RpcFreeBuffer [RPCRT4.@] + * + * Frees a buffer allocated by I_RpcGetBuffer or I_RpcReceive and unbinds from + * the server interface. + * + * PARAMS + * pMsg [I/O] RPC message information. + * + * RETURNS + * RPC_S_OK. + * + * SEE ALSO + * I_RpcGetBuffer(), I_RpcReceive(). */ RPC_STATUS WINAPI I_RpcFreeBuffer(PRPC_MESSAGE pMsg) { @@ -506,63 +963,83 @@ RPC_STATUS WINAPI I_RpcFreeBuffer(PRPC_MESSAGE pMsg) /*********************************************************************** * I_RpcSend [RPCRT4.@] + * + * Sends a message to the server. + * + * PARAMS + * pMsg [I/O] RPC message information. + * + * RETURNS + * Unknown. + * + * NOTES + * The buffer must have been allocated with I_RpcGetBuffer(). + * + * SEE ALSO + * I_RpcGetBuffer(), I_RpcReceive(), I_RpcSendReceive(). */ RPC_STATUS WINAPI I_RpcSend(PRPC_MESSAGE pMsg) { RpcBinding* bind = (RpcBinding*)pMsg->Handle; RpcConnection* conn; RPC_CLIENT_INTERFACE* cif = NULL; - RPC_SERVER_INTERFACE* sif = NULL; RPC_STATUS status; RpcPktHdr *hdr; TRACE("(%p)\n", pMsg); - if (!bind) return RPC_S_INVALID_BINDING; + if (!bind || bind->server) return RPC_S_INVALID_BINDING; - if (bind->server) { - sif = pMsg->RpcInterfaceInformation; - if (!sif) return RPC_S_INTERFACE_NOT_FOUND; /* ? */ - status = RPCRT4_OpenBinding(bind, &conn, &sif->TransferSyntax, - &sif->InterfaceId); - } else { - cif = pMsg->RpcInterfaceInformation; - if (!cif) return RPC_S_INTERFACE_NOT_FOUND; /* ? */ - status = RPCRT4_OpenBinding(bind, &conn, &cif->TransferSyntax, - &cif->InterfaceId); + cif = pMsg->RpcInterfaceInformation; + if (!cif) return RPC_S_INTERFACE_NOT_FOUND; /* ? */ + + if (!bind->Endpoint || !bind->Endpoint[0]) + { + TRACE("automatically resolving partially bound binding\n"); + status = RpcEpResolveBinding(bind, cif); + if (status != RPC_S_OK) return status; } + status = RPCRT4_OpenBinding(bind, &conn, &cif->TransferSyntax, + &cif->InterfaceId); if (status != RPC_S_OK) return status; - if (bind->server) { - if (pMsg->RpcFlags & WINE_RPCFLAG_EXCEPTION) { - hdr = RPCRT4_BuildFaultHeader(pMsg->DataRepresentation, - RPC_S_CALL_FAILED); - } else { - hdr = RPCRT4_BuildResponseHeader(pMsg->DataRepresentation, - pMsg->BufferLength); - } - } else { - hdr = RPCRT4_BuildRequestHeader(pMsg->DataRepresentation, - pMsg->BufferLength, pMsg->ProcNum, - &bind->ObjectUuid); + hdr = RPCRT4_BuildRequestHeader(pMsg->DataRepresentation, + pMsg->BufferLength, pMsg->ProcNum, + &bind->ObjectUuid); + if (!hdr) + { + RPCRT4_CloseBinding(bind, conn); + return ERROR_OUTOFMEMORY; } + hdr->common.call_id = conn->NextCallId++; status = RPCRT4_Send(conn, hdr, pMsg->Buffer, pMsg->BufferLength); RPCRT4_FreeHeader(hdr); - /* success */ - if (!bind->server) { - /* save the connection, so the response can be read from it */ - pMsg->ReservedForRuntime = conn; - return RPC_S_OK; - } - RPCRT4_CloseBinding(bind, conn); - status = RPC_S_OK; - + /* save the connection, so the response can be read from it */ + pMsg->ReservedForRuntime = conn; return status; } +/* is this status something that the server can't recover from? */ +static inline BOOL is_hard_error(RPC_STATUS status) +{ + switch (status) + { + case 0: /* user-defined fault */ + case ERROR_ACCESS_DENIED: + case ERROR_INVALID_PARAMETER: + case RPC_S_PROTOCOL_ERROR: + case RPC_S_CALL_FAILED: + case RPC_S_CALL_FAILED_DNE: + case RPC_S_SEC_PKG_ERROR: + return TRUE; + default: + return FALSE; + } +} + /*********************************************************************** * I_RpcReceive [RPCRT4.@] */ @@ -590,6 +1067,14 @@ RPC_STATUS WINAPI I_RpcReceive(PRPC_MESSAGE pMsg) } else { cif = pMsg->RpcInterfaceInformation; if (!cif) return RPC_S_INTERFACE_NOT_FOUND; /* ? */ + + if (!bind->Endpoint || !bind->Endpoint[0]) + { + TRACE("automatically resolving partially bound binding\n"); + status = RpcEpResolveBinding(bind, cif); + if (status != RPC_S_OK) return status; + } + status = RPCRT4_OpenBinding(bind, &conn, &cif->TransferSyntax, &cif->InterfaceId); } @@ -602,46 +1087,73 @@ RPC_STATUS WINAPI I_RpcReceive(PRPC_MESSAGE pMsg) goto fail; } - status = RPC_S_PROTOCOL_ERROR; - switch (hdr->common.ptype) { case PKT_RESPONSE: - if (bind->server) goto fail; + if (bind->server) { + status = RPC_S_PROTOCOL_ERROR; + goto fail; + } break; case PKT_REQUEST: - if (!bind->server) goto fail; + if (!bind->server) { + status = RPC_S_PROTOCOL_ERROR; + goto fail; + } break; case PKT_FAULT: - pMsg->RpcFlags |= WINE_RPCFLAG_EXCEPTION; - ERR ("we got fault packet with status %lx\n", hdr->fault.status); - status = RPC_S_CALL_FAILED; /* ? */ - goto fail; + ERR ("we got fault packet with status 0x%lx\n", hdr->fault.status); + status = NCA2RPC_STATUS(hdr->fault.status); + if (is_hard_error(status)) + goto fail; + break; default: WARN("bad packet type %d\n", hdr->common.ptype); + status = RPC_S_PROTOCOL_ERROR; goto fail; } /* success */ - status = RPC_S_OK; + RPCRT4_CloseBinding(bind, conn); + RPCRT4_FreeHeader(hdr); + return status; fail: - if (hdr) { - RPCRT4_FreeHeader(hdr); - } - RPCRT4_CloseBinding(bind, conn); + RPCRT4_FreeHeader(hdr); + RPCRT4_DestroyConnection(conn); return status; } /*********************************************************************** * I_RpcSendReceive [RPCRT4.@] + * + * Sends a message to the server and receives the response. + * + * PARAMS + * pMsg [I/O] RPC message information. + * + * RETURNS + * Success: RPC_S_OK. + * Failure: Any error code. + * + * NOTES + * The buffer must have been allocated with I_RpcGetBuffer(). + * + * SEE ALSO + * I_RpcGetBuffer(), I_RpcSend(), I_RpcReceive(). */ RPC_STATUS WINAPI I_RpcSendReceive(PRPC_MESSAGE pMsg) { RPC_STATUS status; + RPC_MESSAGE original_message; TRACE("(%p)\n", pMsg); + + original_message = *pMsg; status = I_RpcSend(pMsg); if (status == RPC_S_OK) status = I_RpcReceive(pMsg); + /* free the buffer replaced by a new buffer in I_RpcReceive */ + if (status == RPC_S_OK) + I_RpcFreeBuffer(&original_message); return status; } diff --git a/reactos/dll/win32/rpcrt4/rpc_message.h b/reactos/dll/win32/rpcrt4/rpc_message.h index 59ee9c050ec..cbf83d30ce0 100644 --- a/reactos/dll/win32/rpcrt4/rpc_message.h +++ b/reactos/dll/win32/rpcrt4/rpc_message.h @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __WINE_RPC_MESSAGE_H @@ -24,12 +24,17 @@ #include "wine/rpcss_shared.h" #include "rpc_defs.h" +typedef unsigned int NCA_STATUS; + RpcPktHdr *RPCRT4_BuildFaultHeader(unsigned long DataRepresentation, RPC_STATUS Status); -RpcPktHdr *RPCRT4_BuildBindHeader(unsigned long DataRepresentation, unsigned short MaxTransmissionSize, unsigned short MaxReceiveSize, RPC_SYNTAX_IDENTIFIER *AbstractId, RPC_SYNTAX_IDENTIFIER *TransferId); +RpcPktHdr *RPCRT4_BuildResponseHeader(unsigned long DataRepresentation, unsigned long BufferLength); +RpcPktHdr *RPCRT4_BuildBindHeader(unsigned long DataRepresentation, unsigned short MaxTransmissionSize, unsigned short MaxReceiveSize, unsigned long AssocGroupId, const RPC_SYNTAX_IDENTIFIER *AbstractId, const RPC_SYNTAX_IDENTIFIER *TransferId); RpcPktHdr *RPCRT4_BuildBindNackHeader(unsigned long DataRepresentation, unsigned char RpcVersion, unsigned char RpcVersionMinor); -RpcPktHdr *RPCRT4_BuildBindAckHeader(unsigned long DataRepresentation, unsigned short MaxTransmissionSize, unsigned short MaxReceiveSize, LPSTR ServerAddress, unsigned long Result, unsigned long Reason, RPC_SYNTAX_IDENTIFIER *TransferId); +RpcPktHdr *RPCRT4_BuildBindAckHeader(unsigned long DataRepresentation, unsigned short MaxTransmissionSize, unsigned short MaxReceiveSize, unsigned long AssocGroupId, LPCSTR ServerAddress, unsigned long Result, unsigned long Reason, const RPC_SYNTAX_IDENTIFIER *TransferId); VOID RPCRT4_FreeHeader(RpcPktHdr *Header); RPC_STATUS RPCRT4_Send(RpcConnection *Connection, RpcPktHdr *Header, void *Buffer, unsigned int BufferLength); RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header, PRPC_MESSAGE pMsg); +NCA_STATUS RPC2NCA_STATUS(RPC_STATUS status); +RPC_STATUS NCA2RPC_STATUS(NCA_STATUS status); #endif diff --git a/reactos/dll/win32/rpcrt4/rpc_misc.h b/reactos/dll/win32/rpcrt4/rpc_misc.h deleted file mode 100644 index 49c483e5c4b..00000000000 --- a/reactos/dll/win32/rpcrt4/rpc_misc.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * RPC definitions - * - * Copyright 2003 Ove Kåven, TransGaming Technologies - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __WINE_RPC_MISC_H -#define __WINE_RPC_MISC_H - -/* flags for RPC_MESSAGE.RpcFlags */ -#define WINE_RPCFLAG_EXCEPTION 0x0001 - -#endif /* __WINE_RPC_MISC_H */ diff --git a/reactos/dll/win32/rpcrt4/rpc_server.c b/reactos/dll/win32/rpcrt4/rpc_server.c index f04627a6c69..34c71c78c5c 100644 --- a/reactos/dll/win32/rpcrt4/rpc_server.c +++ b/reactos/dll/win32/rpcrt4/rpc_server.c @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * * TODO: * - a whole lot @@ -33,7 +33,6 @@ #include "windef.h" #include "winbase.h" #include "winerror.h" -#include "winreg.h" #include "rpc.h" #include "rpcndr.h" @@ -43,17 +42,15 @@ #include "wine/exception.h" #include "rpc_server.h" -#include "rpc_misc.h" +#include "rpc_assoc.h" #include "rpc_message.h" #include "rpc_defs.h" - -#define MAX_THREADS 128 +#include "ncastatus.h" WINE_DEFAULT_DEBUG_CHANNEL(rpc); typedef struct _RpcPacket { - struct _RpcPacket* next; struct _RpcConnection* conn; RpcPktHdr* hdr; RPC_MESSAGE* msg; @@ -69,8 +66,9 @@ typedef struct _RpcObjTypeMap static RpcObjTypeMap *RpcObjTypeMaps; -static RpcServerProtseq* protseqs; -static RpcServerInterface* ifs; +/* list of type RpcServerProtseq */ +static struct list protseqs = LIST_INIT(protseqs); +static struct list server_interfaces = LIST_INIT(server_interfaces); static CRITICAL_SECTION server_cs; static CRITICAL_SECTION_DEBUG server_cs_debug = @@ -96,31 +94,10 @@ static BOOL std_listen; static LONG manual_listen_count; /* total listeners including auto listeners */ static LONG listen_count; -/* set on change of configuration (e.g. listening on new protseq) */ -static HANDLE mgr_event; -/* mutex for ensuring only one thread can change state at a time */ -static HANDLE mgr_mutex; -/* set when server thread has finished opening connections */ -static HANDLE server_ready_event; - -static CRITICAL_SECTION spacket_cs; -static CRITICAL_SECTION_DEBUG spacket_cs_debug = -{ - 0, 0, &spacket_cs, - { &spacket_cs_debug.ProcessLocksList, &spacket_cs_debug.ProcessLocksList }, - 0, 0, { (DWORD_PTR)(__FILE__ ": spacket_cs") } -}; -static CRITICAL_SECTION spacket_cs = { &spacket_cs_debug, -1, 0, 0, 0, 0 }; - -static RpcPacket* spacket_head; -static RpcPacket* spacket_tail; -static HANDLE server_sem; - -static LONG worker_count, worker_free, worker_tls; static UUID uuid_nil; -inline static RpcObjTypeMap *LookupObjTypeMap(UUID *ObjUuid) +static inline RpcObjTypeMap *LookupObjTypeMap(UUID *ObjUuid) { RpcObjTypeMap *rslt = RpcObjTypeMaps; RPC_STATUS dummy; @@ -133,7 +110,7 @@ inline static RpcObjTypeMap *LookupObjTypeMap(UUID *ObjUuid) return rslt; } -inline static UUID *LookupObjType(UUID *ObjUuid) +static inline UUID *LookupObjType(UUID *ObjUuid) { RpcObjTypeMap *map = LookupObjTypeMap(ObjUuid); if (map) @@ -143,96 +120,61 @@ inline static UUID *LookupObjType(UUID *ObjUuid) } static RpcServerInterface* RPCRT4_find_interface(UUID* object, - RPC_SYNTAX_IDENTIFIER* if_id, + const RPC_SYNTAX_IDENTIFIER* if_id, BOOL check_object) { UUID* MgrType = NULL; - RpcServerInterface* cif = NULL; + RpcServerInterface* cif; RPC_STATUS status; if (check_object) MgrType = LookupObjType(object); EnterCriticalSection(&server_cs); - cif = ifs; - while (cif) { + LIST_FOR_EACH_ENTRY(cif, &server_interfaces, RpcServerInterface, entry) { if (!memcmp(if_id, &cif->If->InterfaceId, sizeof(RPC_SYNTAX_IDENTIFIER)) && (check_object == FALSE || UuidEqual(MgrType, &cif->MgrTypeUuid, &status)) && - std_listen) break; - cif = cif->Next; + std_listen) { + InterlockedIncrement(&cif->CurrentCalls); + break; + } } LeaveCriticalSection(&server_cs); + if (&cif->entry == &server_interfaces) cif = NULL; TRACE("returning %p for %s\n", cif, debugstr_guid(object)); return cif; } -static void RPCRT4_push_packet(RpcPacket* packet) +static void RPCRT4_release_server_interface(RpcServerInterface *sif) { - packet->next = NULL; - EnterCriticalSection(&spacket_cs); - if (spacket_tail) { - spacket_tail->next = packet; - spacket_tail = packet; - } else { - spacket_head = packet; - spacket_tail = packet; + if (!InterlockedDecrement(&sif->CurrentCalls) && + sif->CallsCompletedEvent) { + /* sif must have been removed from server_interfaces before + * CallsCompletedEvent is set */ + SetEvent(sif->CallsCompletedEvent); + HeapFree(GetProcessHeap(), 0, sif); } - LeaveCriticalSection(&spacket_cs); } -static RpcPacket* RPCRT4_pop_packet(void) -{ - RpcPacket* packet; - EnterCriticalSection(&spacket_cs); - packet = spacket_head; - if (packet) { - spacket_head = packet->next; - if (!spacket_head) spacket_tail = NULL; - } - LeaveCriticalSection(&spacket_cs); - if (packet) packet->next = NULL; - return packet; -} - -#ifndef __REACTOS__ -typedef struct { - PRPC_MESSAGE msg; - void* buf; -} packet_state; - static WINE_EXCEPTION_FILTER(rpc_filter) { - packet_state* state; - PRPC_MESSAGE msg; - state = TlsGetValue(worker_tls); - msg = state->msg; - if (msg->Buffer != state->buf) I_RpcFreeBuffer(msg); - msg->RpcFlags |= WINE_RPCFLAG_EXCEPTION; - msg->BufferLength = sizeof(DWORD); - I_RpcGetBuffer(msg); - *(DWORD*)msg->Buffer = GetExceptionCode(); - WARN("exception caught with code 0x%08lx = %ld\n", *(DWORD*)msg->Buffer, *(DWORD*)msg->Buffer); + WARN("exception caught with code 0x%08x = %d\n", GetExceptionCode(), GetExceptionCode()); TRACE("returning failure packet\n"); + /* catch every exception */ return EXCEPTION_EXECUTE_HANDLER; } -#endif static void RPCRT4_process_packet(RpcConnection* conn, RpcPktHdr* hdr, RPC_MESSAGE* msg) { RpcServerInterface* sif; RPC_DISPATCH_FUNCTION func; -#ifndef __REACTOS__ - packet_state state; -#endif UUID *object_uuid; - RpcPktHdr *response; + RpcPktHdr *response = NULL; void *buf = msg->Buffer; RPC_STATUS status; + BOOL exception; + NDR_SCONTEXT context_handle; -#ifndef __REACTOS__ - state.msg = msg; - state.buf = buf; - TlsSetValue(worker_tls, &state); -#endif + msg->Handle = (RPC_BINDING_HANDLE)conn->server_binding; switch (hdr->common.ptype) { case PKT_BIND: @@ -240,11 +182,21 @@ static void RPCRT4_process_packet(RpcConnection* conn, RpcPktHdr* hdr, RPC_MESSA /* FIXME: do more checks! */ if (hdr->bind.max_tsize < RPC_MIN_PACKET_SIZE || - !UuidIsNil(&conn->ActiveInterface.SyntaxGUID, &status)) { + !UuidIsNil(&conn->ActiveInterface.SyntaxGUID, &status) || + conn->server_binding) { TRACE("packet size less than min size, or active interface syntax guid non-null\n"); sif = NULL; } else { - sif = RPCRT4_find_interface(NULL, &hdr->bind.abstract, FALSE); + /* create temporary binding */ + if (RPCRT4_MakeBinding(&conn->server_binding, conn) == RPC_S_OK && + RpcServerAssoc_GetAssociation(rpcrt4_conn_get_name(conn), + conn->NetworkAddr, conn->Endpoint, + conn->NetworkOptions, + hdr->bind.assoc_gid, + &conn->server_binding->Assoc) == RPC_S_OK) + sif = RPCRT4_find_interface(NULL, &hdr->bind.abstract, FALSE); + else + sif = NULL; } if (sif == NULL) { TRACE("rejecting bind request on connection %p\n", conn); @@ -252,22 +204,28 @@ static void RPCRT4_process_packet(RpcConnection* conn, RpcPktHdr* hdr, RPC_MESSA response = RPCRT4_BuildBindNackHeader(NDR_LOCAL_DATA_REPRESENTATION, RPC_VER_MAJOR, RPC_VER_MINOR); } else { - TRACE("accepting bind request on connection %p\n", conn); + TRACE("accepting bind request on connection %p for %s\n", conn, + debugstr_guid(&hdr->bind.abstract.SyntaxGUID)); /* accept. */ response = RPCRT4_BuildBindAckHeader(NDR_LOCAL_DATA_REPRESENTATION, RPC_MAX_PACKET_SIZE, RPC_MAX_PACKET_SIZE, + conn->server_binding->Assoc->assoc_group_id, conn->Endpoint, - RESULT_ACCEPT, NO_REASON, + RESULT_ACCEPT, REASON_NONE, &sif->If->TransferSyntax); /* save the interface for later use */ conn->ActiveInterface = hdr->bind.abstract; conn->MaxTransmissionSize = hdr->bind.max_tsize; + + RPCRT4_release_server_interface(sif); } - if (RPCRT4_Send(conn, response, NULL, 0) != RPC_S_OK) + status = RPCRT4_Send(conn, response, NULL, 0); + RPCRT4_FreeHeader(response); + if (status != RPC_S_OK) goto fail; break; @@ -277,10 +235,12 @@ static void RPCRT4_process_packet(RpcConnection* conn, RpcPktHdr* hdr, RPC_MESSA /* fail if the connection isn't bound with an interface */ if (UuidIsNil(&conn->ActiveInterface.SyntaxGUID, &status)) { + /* FIXME: should send BindNack instead */ response = RPCRT4_BuildFaultHeader(NDR_LOCAL_DATA_REPRESENTATION, status); RPCRT4_Send(conn, response, NULL, 0); + RPCRT4_FreeHeader(response); break; } @@ -291,6 +251,15 @@ static void RPCRT4_process_packet(RpcConnection* conn, RpcPktHdr* hdr, RPC_MESSA } sif = RPCRT4_find_interface(object_uuid, &conn->ActiveInterface, TRUE); + if (!sif) { + WARN("interface %s no longer registered, returning fault packet\n", debugstr_guid(&conn->ActiveInterface.SyntaxGUID)); + response = RPCRT4_BuildFaultHeader(NDR_LOCAL_DATA_REPRESENTATION, + NCA_S_UNK_IF); + + RPCRT4_Send(conn, response, NULL, 0); + RPCRT4_FreeHeader(response); + break; + } msg->RpcInterfaceInformation = sif->If; /* copy the endpoint vector from sif to msg so that midl-generated code will use it */ msg->ManagerEpv = sif->MgrEpv; @@ -306,38 +275,62 @@ static void RPCRT4_process_packet(RpcConnection* conn, RpcPktHdr* hdr, RPC_MESSA func = *sif->If->DispatchTable->DispatchTable; } else { if (msg->ProcNum >= sif->If->DispatchTable->DispatchTableCount) { - ERR("invalid procnum\n"); - func = NULL; + WARN("invalid procnum (%d/%d)\n", msg->ProcNum, sif->If->DispatchTable->DispatchTableCount); + response = RPCRT4_BuildFaultHeader(NDR_LOCAL_DATA_REPRESENTATION, + NCA_S_OP_RNG_ERROR); + + RPCRT4_Send(conn, response, NULL, 0); + RPCRT4_FreeHeader(response); } func = sif->If->DispatchTable->DispatchTable[msg->ProcNum]; } /* put in the drep. FIXME: is this more universally applicable? perhaps we should move this outward... */ - msg->DataRepresentation = + msg->DataRepresentation = MAKELONG( MAKEWORD(hdr->common.drep[0], hdr->common.drep[1]), MAKEWORD(hdr->common.drep[2], hdr->common.drep[3])); + exception = FALSE; + /* dispatch */ -#ifndef __REACTOS__ + RPCRT4_SetThreadCurrentCallHandle(msg->Handle); __TRY { if (func) func(msg); } __EXCEPT(rpc_filter) { - /* failure packet was created in rpc_filter */ + exception = TRUE; + if (GetExceptionCode() == STATUS_ACCESS_VIOLATION) + status = ERROR_NOACCESS; + else + status = GetExceptionCode(); + response = RPCRT4_BuildFaultHeader(msg->DataRepresentation, + RPC2NCA_STATUS(status)); } __ENDTRY -#else - if (func) func(msg); -#endif + RPCRT4_SetThreadCurrentCallHandle(NULL); + + /* release any unmarshalled context handles */ + while ((context_handle = RPCRT4_PopThreadContextHandle()) != NULL) + RpcServerAssoc_ReleaseContextHandle(conn->server_binding->Assoc, context_handle, TRUE); + + if (!exception) + response = RPCRT4_BuildResponseHeader(msg->DataRepresentation, + msg->BufferLength); /* send response packet */ - I_RpcSend(msg); + if (response) { + status = RPCRT4_Send(conn, response, exception ? NULL : msg->Buffer, + exception ? 0 : msg->BufferLength); + RPCRT4_FreeHeader(response); + } else + ERR("out of memory\n"); msg->RpcInterfaceInformation = NULL; + RPCRT4_release_server_interface(sif); break; default: - FIXME("unhandled packet type\n"); + FIXME("unhandled packet type %u\n", hdr->common.ptype); break; } @@ -346,69 +339,25 @@ fail: if (msg->Buffer == buf) msg->Buffer = NULL; TRACE("freeing Buffer=%p\n", buf); HeapFree(GetProcessHeap(), 0, buf); - RPCRT4_DestroyBinding(msg->Handle); msg->Handle = 0; I_RpcFreeBuffer(msg); msg->Buffer = NULL; RPCRT4_FreeHeader(hdr); -#ifndef __REACTOS__ - TlsSetValue(worker_tls, NULL); -#endif + HeapFree(GetProcessHeap(), 0, msg); } static DWORD CALLBACK RPCRT4_worker_thread(LPVOID the_arg) { - DWORD obj; - RpcPacket* pkt; - - for (;;) { - /* idle timeout after 5s */ - obj = WaitForSingleObject(server_sem, 5000); - if (obj == WAIT_TIMEOUT) { - /* if another idle thread exist, self-destruct */ - if (worker_free > 1) break; - continue; - } - pkt = RPCRT4_pop_packet(); - if (!pkt) continue; - InterlockedDecrement(&worker_free); - for (;;) { - RPCRT4_process_packet(pkt->conn, pkt->hdr, pkt->msg); - HeapFree(GetProcessHeap(), 0, pkt); - /* try to grab another packet here without waiting - * on the semaphore, in case it hits max */ - pkt = RPCRT4_pop_packet(); - if (!pkt) break; - /* decrement semaphore */ - WaitForSingleObject(server_sem, 0); - } - InterlockedIncrement(&worker_free); - } - InterlockedDecrement(&worker_free); - InterlockedDecrement(&worker_count); + RpcPacket *pkt = the_arg; + RPCRT4_process_packet(pkt->conn, pkt->hdr, pkt->msg); + HeapFree(GetProcessHeap(), 0, pkt); return 0; } -static void RPCRT4_create_worker_if_needed(void) -{ - if (!worker_free && worker_count < MAX_THREADS) { - HANDLE thread; - InterlockedIncrement(&worker_count); - InterlockedIncrement(&worker_free); - thread = CreateThread(NULL, 0, RPCRT4_worker_thread, NULL, 0, NULL); - if (thread) CloseHandle(thread); - else { - InterlockedDecrement(&worker_free); - InterlockedDecrement(&worker_count); - } - } -} - static DWORD CALLBACK RPCRT4_io_thread(LPVOID the_arg) { RpcConnection* conn = (RpcConnection*)the_arg; RpcPktHdr *hdr; - RpcBinding *pbind; RPC_MESSAGE *msg; RPC_STATUS status; RpcPacket *packet; @@ -418,14 +367,10 @@ static DWORD CALLBACK RPCRT4_io_thread(LPVOID the_arg) for (;;) { msg = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RPC_MESSAGE)); - /* create temporary binding for dispatch, it will be freed in - * RPCRT4_process_packet */ - RPCRT4_MakeBinding(&pbind, conn); - msg->Handle = (RPC_BINDING_HANDLE)pbind; - status = RPCRT4_Receive(conn, &hdr, msg); if (status != RPC_S_OK) { WARN("receive failed with error %lx\n", status); + HeapFree(GetProcessHeap(), 0, msg); break; } @@ -436,23 +381,20 @@ static DWORD CALLBACK RPCRT4_io_thread(LPVOID the_arg) packet->conn = conn; packet->hdr = hdr; packet->msg = msg; - RPCRT4_create_worker_if_needed(); - RPCRT4_push_packet(packet); - ReleaseSemaphore(server_sem, 1, NULL); + QueueUserWorkItem(RPCRT4_worker_thread, packet, WT_EXECUTELONGFUNCTION); #endif msg = NULL; } - HeapFree(GetProcessHeap(), 0, msg); RPCRT4_DestroyConnection(conn); return 0; } -static void RPCRT4_new_client(RpcConnection* conn) +void RPCRT4_new_client(RpcConnection* conn) { HANDLE thread = CreateThread(NULL, 0, RPCRT4_io_thread, conn, 0, NULL); if (!thread) { DWORD err = GetLastError(); - ERR("failed to create thread, error=%08lx\n", err); + ERR("failed to create thread, error=%08x\n", err); RPCRT4_DestroyConnection(conn); } /* we could set conn->thread, but then we'd have to make the io_thread wait @@ -465,128 +407,96 @@ static void RPCRT4_new_client(RpcConnection* conn) static DWORD CALLBACK RPCRT4_server_thread(LPVOID the_arg) { - HANDLE m_event = mgr_event, b_handle; - HANDLE *objs = NULL; - DWORD count, res; - RpcServerProtseq* cps; + int res; + unsigned int count; + void *objs = NULL; + RpcServerProtseq* cps = the_arg; RpcConnection* conn; - RpcConnection* cconn; BOOL set_ready_event = FALSE; TRACE("(the_arg == ^%p)\n", the_arg); for (;;) { - EnterCriticalSection(&server_cs); - /* open and count connections */ - count = 1; - cps = protseqs; - while (cps) { - conn = cps->conn; - while (conn) { - RPCRT4_OpenConnection(conn); - if (conn->ovl[0].hEvent) count++; - conn = conn->Next; - } - cps = cps->Next; - } - /* make array of connections */ - if (objs) - objs = HeapReAlloc(GetProcessHeap(), 0, objs, count*sizeof(HANDLE)); - else - objs = HeapAlloc(GetProcessHeap(), 0, count*sizeof(HANDLE)); - - objs[0] = m_event; - count = 1; - cps = protseqs; - while (cps) { - conn = cps->conn; - while (conn) { - if (conn->ovl[0].hEvent) objs[count++] = conn->ovl[0].hEvent; - conn = conn->Next; - } - cps = cps->Next; - } - LeaveCriticalSection(&server_cs); + objs = cps->ops->get_wait_array(cps, objs, &count); if (set_ready_event) { /* signal to function that changed state that we are now sync'ed */ - SetEvent(server_ready_event); + SetEvent(cps->server_ready_event); set_ready_event = FALSE; } /* start waiting */ - res = WaitForMultipleObjects(count, objs, FALSE, INFINITE); - if (res == WAIT_OBJECT_0) { + res = cps->ops->wait_for_new_connection(cps, count, objs); + if (res == -1) + break; + else if (res == 0) + { if (!std_listen) { - SetEvent(server_ready_event); + SetEvent(cps->server_ready_event); break; } set_ready_event = TRUE; } - else if (res == WAIT_FAILED) { - ERR("wait failed\n"); - } - else { - b_handle = objs[res - WAIT_OBJECT_0]; - /* find which connection got a RPC */ - EnterCriticalSection(&server_cs); - conn = NULL; - cps = protseqs; - while (cps) { - conn = cps->conn; - while (conn) { - if (conn->ovl[0].hEvent == b_handle) break; - conn = conn->Next; - } - if (conn) break; - cps = cps->Next; - } - cconn = NULL; - if (conn) RPCRT4_SpawnConnection(&cconn, conn); - LeaveCriticalSection(&server_cs); - if (!conn) { - ERR("failed to locate connection for handle %p\n", b_handle); - } - if (cconn) RPCRT4_new_client(cconn); - } } - HeapFree(GetProcessHeap(), 0, objs); - EnterCriticalSection(&server_cs); + cps->ops->free_wait_array(cps, objs); + EnterCriticalSection(&cps->cs); /* close connections */ - cps = protseqs; - while (cps) { - conn = cps->conn; - while (conn) { - RPCRT4_CloseConnection(conn); - conn = conn->Next; - } - cps = cps->Next; + conn = cps->conn; + while (conn) { + RPCRT4_CloseConnection(conn); + conn = conn->Next; } - LeaveCriticalSection(&server_cs); + LeaveCriticalSection(&cps->cs); return 0; } /* tells the server thread that the state has changed and waits for it to * make the changes */ -static void RPCRT4_sync_with_server_thread(void) +static void RPCRT4_sync_with_server_thread(RpcServerProtseq *ps) { /* make sure we are the only thread sync'ing the server state, otherwise * there is a race with the server thread setting an older state and setting * the server_ready_event when the new state hasn't yet been applied */ - WaitForSingleObject(mgr_mutex, INFINITE); + WaitForSingleObject(ps->mgr_mutex, INFINITE); + + ps->ops->signal_state_changed(ps); - SetEvent(mgr_event); /* wait for server thread to make the requested changes before returning */ - WaitForSingleObject(server_ready_event, INFINITE); + WaitForSingleObject(ps->server_ready_event, INFINITE); - ReleaseMutex(mgr_mutex); + ReleaseMutex(ps->mgr_mutex); +} + +static RPC_STATUS RPCRT4_start_listen_protseq(RpcServerProtseq *ps, BOOL auto_listen) +{ + RPC_STATUS status = RPC_S_OK; + HANDLE server_thread; + + EnterCriticalSection(&listen_cs); + if (ps->is_listening) goto done; + + if (!ps->mgr_mutex) ps->mgr_mutex = CreateMutexW(NULL, FALSE, NULL); + if (!ps->server_ready_event) ps->server_ready_event = CreateEventW(NULL, FALSE, FALSE, NULL); + server_thread = CreateThread(NULL, 0, RPCRT4_server_thread, ps, 0, NULL); + if (!server_thread) + { + status = RPC_S_OUT_OF_RESOURCES; + goto done; + } + ps->is_listening = TRUE; + CloseHandle(server_thread); + +done: + LeaveCriticalSection(&listen_cs); + return status; } static RPC_STATUS RPCRT4_start_listen(BOOL auto_listen) { RPC_STATUS status = RPC_S_ALREADY_LISTENING; + RpcServerProtseq *cps; TRACE("\n"); @@ -594,21 +504,27 @@ static RPC_STATUS RPCRT4_start_listen(BOOL auto_listen) if (auto_listen || (manual_listen_count++ == 0)) { status = RPC_S_OK; - if (++listen_count == 1) { - HANDLE server_thread; - /* first listener creates server thread */ - if (!mgr_mutex) mgr_mutex = CreateMutexW(NULL, FALSE, NULL); - if (!mgr_event) mgr_event = CreateEventW(NULL, FALSE, FALSE, NULL); - if (!server_ready_event) server_ready_event = CreateEventW(NULL, FALSE, FALSE, NULL); - if (!server_sem) server_sem = CreateSemaphoreW(NULL, 0, MAX_THREADS, NULL); - if (!worker_tls) worker_tls = TlsAlloc(); + if (++listen_count == 1) std_listen = TRUE; - server_thread = CreateThread(NULL, 0, RPCRT4_server_thread, NULL, 0, NULL); - CloseHandle(server_thread); - } } LeaveCriticalSection(&listen_cs); + if (std_listen) + { + EnterCriticalSection(&server_cs); + LIST_FOR_EACH_ENTRY(cps, &protseqs, RpcServerProtseq, entry) + { + status = RPCRT4_start_listen_protseq(cps, TRUE); + if (status != RPC_S_OK) + break; + + /* make sure server is actually listening on the interface before + * returning */ + RPCRT4_sync_with_server_thread(cps); + } + LeaveCriticalSection(&server_cs); + } + return status; } @@ -618,9 +534,14 @@ static void RPCRT4_stop_listen(BOOL auto_listen) if (auto_listen || (--manual_listen_count == 0)) { if (listen_count != 0 && --listen_count == 0) { + RpcServerProtseq *cps; + std_listen = FALSE; LeaveCriticalSection(&listen_cs); - RPCRT4_sync_with_server_thread(); + + LIST_FOR_EACH_ENTRY(cps, &protseqs, RpcServerProtseq, entry) + RPCRT4_sync_with_server_thread(cps); + return; } assert(listen_count >= 0); @@ -628,18 +549,22 @@ static void RPCRT4_stop_listen(BOOL auto_listen) LeaveCriticalSection(&listen_cs); } -static RPC_STATUS RPCRT4_use_protseq(RpcServerProtseq* ps) +static RPC_STATUS RPCRT4_use_protseq(RpcServerProtseq* ps, LPSTR endpoint) { - RPCRT4_CreateConnection(&ps->conn, TRUE, ps->Protseq, NULL, ps->Endpoint, NULL, NULL); + RPC_STATUS status; - EnterCriticalSection(&server_cs); - ps->Next = protseqs; - protseqs = ps; - LeaveCriticalSection(&server_cs); + status = ps->ops->open_endpoint(ps, endpoint); + if (status != RPC_S_OK) + return status; - if (std_listen) RPCRT4_sync_with_server_thread(); + if (std_listen) + { + status = RPCRT4_start_listen_protseq(ps, FALSE); + if (status == RPC_S_OK) + RPCRT4_sync_with_server_thread(ps); + } - return RPC_S_OK; + return status; } /*********************************************************************** @@ -660,14 +585,14 @@ RPC_STATUS WINAPI RpcServerInqBindings( RPC_BINDING_VECTOR** BindingVector ) EnterCriticalSection(&server_cs); /* count connections */ count = 0; - ps = protseqs; - while (ps) { + LIST_FOR_EACH_ENTRY(ps, &protseqs, RpcServerProtseq, entry) { + EnterCriticalSection(&ps->cs); conn = ps->conn; while (conn) { count++; conn = conn->Next; } - ps = ps->Next; + LeaveCriticalSection(&ps->cs); } if (count) { /* export bindings */ @@ -676,8 +601,8 @@ RPC_STATUS WINAPI RpcServerInqBindings( RPC_BINDING_VECTOR** BindingVector ) sizeof(RPC_BINDING_HANDLE)*(count-1)); (*BindingVector)->Count = count; count = 0; - ps = protseqs; - while (ps) { + LIST_FOR_EACH_ENTRY(ps, &protseqs, RpcServerProtseq, entry) { + EnterCriticalSection(&ps->cs); conn = ps->conn; while (conn) { RPCRT4_MakeBinding((RpcBinding**)&(*BindingVector)->BindingH[count], @@ -685,7 +610,7 @@ RPC_STATUS WINAPI RpcServerInqBindings( RPC_BINDING_VECTOR** BindingVector ) count++; conn = conn->Next; } - ps = ps->Next; + LeaveCriticalSection(&ps->cs); } status = RPC_S_OK; } else { @@ -699,81 +624,145 @@ RPC_STATUS WINAPI RpcServerInqBindings( RPC_BINDING_VECTOR** BindingVector ) /*********************************************************************** * RpcServerUseProtseqEpA (RPCRT4.@) */ -RPC_STATUS WINAPI RpcServerUseProtseqEpA( unsigned char *Protseq, UINT MaxCalls, unsigned char *Endpoint, LPVOID SecurityDescriptor ) +RPC_STATUS WINAPI RpcServerUseProtseqEpA( RPC_CSTR Protseq, UINT MaxCalls, RPC_CSTR Endpoint, LPVOID SecurityDescriptor ) { RPC_POLICY policy; - + TRACE( "(%s,%u,%s,%p)\n", Protseq, MaxCalls, Endpoint, SecurityDescriptor ); - + /* This should provide the default behaviour */ policy.Length = sizeof( policy ); policy.EndpointFlags = 0; policy.NICFlags = 0; - + return RpcServerUseProtseqEpExA( Protseq, MaxCalls, Endpoint, SecurityDescriptor, &policy ); } /*********************************************************************** * RpcServerUseProtseqEpW (RPCRT4.@) */ -RPC_STATUS WINAPI RpcServerUseProtseqEpW( LPWSTR Protseq, UINT MaxCalls, LPWSTR Endpoint, LPVOID SecurityDescriptor ) +RPC_STATUS WINAPI RpcServerUseProtseqEpW( RPC_WSTR Protseq, UINT MaxCalls, RPC_WSTR Endpoint, LPVOID SecurityDescriptor ) { RPC_POLICY policy; - + TRACE( "(%s,%u,%s,%p)\n", debugstr_w( Protseq ), MaxCalls, debugstr_w( Endpoint ), SecurityDescriptor ); - + /* This should provide the default behaviour */ policy.Length = sizeof( policy ); policy.EndpointFlags = 0; policy.NICFlags = 0; - + return RpcServerUseProtseqEpExW( Protseq, MaxCalls, Endpoint, SecurityDescriptor, &policy ); } +/*********************************************************************** + * alloc_serverprotoseq (internal) + * + * Must be called with server_cs held. + */ +static RPC_STATUS alloc_serverprotoseq(UINT MaxCalls, char *Protseq, RpcServerProtseq **ps) +{ + const struct protseq_ops *ops = rpcrt4_get_protseq_ops(Protseq); + + if (!ops) + { + FIXME("protseq %s not supported\n", debugstr_a(Protseq)); + return RPC_S_PROTSEQ_NOT_SUPPORTED; + } + + *ps = ops->alloc(); + if (!*ps) + return RPC_S_OUT_OF_RESOURCES; + (*ps)->MaxCalls = MaxCalls; + (*ps)->Protseq = Protseq; + (*ps)->ops = ops; + (*ps)->MaxCalls = 0; + (*ps)->conn = NULL; + InitializeCriticalSection(&(*ps)->cs); + (*ps)->is_listening = FALSE; + (*ps)->mgr_mutex = NULL; + (*ps)->server_ready_event = NULL; + + list_add_head(&protseqs, &(*ps)->entry); + + TRACE("new protseq %p created for %s\n", *ps, Protseq); + + return RPC_S_OK; +} + +/* Finds a given protseq or creates a new one if one doesn't already exist */ +static RPC_STATUS RPCRT4_get_or_create_serverprotseq(UINT MaxCalls, char *Protseq, RpcServerProtseq **ps) +{ + RPC_STATUS status; + RpcServerProtseq *cps; + + EnterCriticalSection(&server_cs); + + LIST_FOR_EACH_ENTRY(cps, &protseqs, RpcServerProtseq, entry) + if (!strcmp(cps->Protseq, Protseq)) + { + TRACE("found existing protseq object for %s\n", Protseq); + *ps = cps; + LeaveCriticalSection(&server_cs); + return S_OK; + } + + status = alloc_serverprotoseq(MaxCalls, Protseq, ps); + + LeaveCriticalSection(&server_cs); + + return status; +} + /*********************************************************************** * RpcServerUseProtseqEpExA (RPCRT4.@) */ -RPC_STATUS WINAPI RpcServerUseProtseqEpExA( unsigned char *Protseq, UINT MaxCalls, unsigned char *Endpoint, LPVOID SecurityDescriptor, +RPC_STATUS WINAPI RpcServerUseProtseqEpExA( RPC_CSTR Protseq, UINT MaxCalls, RPC_CSTR Endpoint, LPVOID SecurityDescriptor, PRPC_POLICY lpPolicy ) { + char *szps = (char*)Protseq, *szep = (char*)Endpoint; RpcServerProtseq* ps; + RPC_STATUS status; - TRACE("(%s,%u,%s,%p,{%u,%lu,%lu})\n", debugstr_a( (char*)Protseq ), MaxCalls, - debugstr_a( (char*)Endpoint ), SecurityDescriptor, + TRACE("(%s,%u,%s,%p,{%u,%lu,%lu})\n", debugstr_a(szps), MaxCalls, + debugstr_a(szep), SecurityDescriptor, lpPolicy->Length, lpPolicy->EndpointFlags, lpPolicy->NICFlags ); - ps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RpcServerProtseq)); - ps->MaxCalls = MaxCalls; - ps->Protseq = RPCRT4_strdupA((char*)Protseq); - ps->Endpoint = RPCRT4_strdupA((char*)Endpoint); + status = RPCRT4_get_or_create_serverprotseq(MaxCalls, RPCRT4_strdupA(szps), &ps); + if (status != RPC_S_OK) + return status; - return RPCRT4_use_protseq(ps); + return RPCRT4_use_protseq(ps, szep); } /*********************************************************************** * RpcServerUseProtseqEpExW (RPCRT4.@) */ -RPC_STATUS WINAPI RpcServerUseProtseqEpExW( LPWSTR Protseq, UINT MaxCalls, LPWSTR Endpoint, LPVOID SecurityDescriptor, +RPC_STATUS WINAPI RpcServerUseProtseqEpExW( RPC_WSTR Protseq, UINT MaxCalls, RPC_WSTR Endpoint, LPVOID SecurityDescriptor, PRPC_POLICY lpPolicy ) { RpcServerProtseq* ps; + RPC_STATUS status; + LPSTR EndpointA; TRACE("(%s,%u,%s,%p,{%u,%lu,%lu})\n", debugstr_w( Protseq ), MaxCalls, debugstr_w( Endpoint ), SecurityDescriptor, lpPolicy->Length, lpPolicy->EndpointFlags, lpPolicy->NICFlags ); - ps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RpcServerProtseq)); - ps->MaxCalls = MaxCalls; - ps->Protseq = RPCRT4_strdupWtoA(Protseq); - ps->Endpoint = RPCRT4_strdupWtoA(Endpoint); + status = RPCRT4_get_or_create_serverprotseq(MaxCalls, RPCRT4_strdupWtoA(Protseq), &ps); + if (status != RPC_S_OK) + return status; - return RPCRT4_use_protseq(ps); + EndpointA = RPCRT4_strdupWtoA(Endpoint); + status = RPCRT4_use_protseq(ps, EndpointA); + RPCRT4_strfree(EndpointA); + return status; } /*********************************************************************** * RpcServerUseProtseqA (RPCRT4.@) */ -RPC_STATUS WINAPI RpcServerUseProtseqA(unsigned char *Protseq, unsigned int MaxCalls, void *SecurityDescriptor) +RPC_STATUS WINAPI RpcServerUseProtseqA(RPC_CSTR Protseq, unsigned int MaxCalls, void *SecurityDescriptor) { TRACE("(Protseq == %s, MaxCalls == %d, SecurityDescriptor == ^%p)\n", debugstr_a((char*)Protseq), MaxCalls, SecurityDescriptor); return RpcServerUseProtseqEpA(Protseq, MaxCalls, NULL, SecurityDescriptor); @@ -782,7 +771,7 @@ RPC_STATUS WINAPI RpcServerUseProtseqA(unsigned char *Protseq, unsigned int MaxC /*********************************************************************** * RpcServerUseProtseqW (RPCRT4.@) */ -RPC_STATUS WINAPI RpcServerUseProtseqW(LPWSTR Protseq, unsigned int MaxCalls, void *SecurityDescriptor) +RPC_STATUS WINAPI RpcServerUseProtseqW(RPC_WSTR Protseq, unsigned int MaxCalls, void *SecurityDescriptor) { TRACE("Protseq == %s, MaxCalls == %d, SecurityDescriptor == ^%p)\n", debugstr_w(Protseq), MaxCalls, SecurityDescriptor); return RpcServerUseProtseqEpW(Protseq, MaxCalls, NULL, SecurityDescriptor); @@ -852,17 +841,11 @@ RPC_STATUS WINAPI RpcServerRegisterIf2( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, sif->IfCallbackFn = IfCallbackFn; EnterCriticalSection(&server_cs); - sif->Next = ifs; - ifs = sif; + list_add_head(&server_interfaces, &sif->entry); LeaveCriticalSection(&server_cs); - if (sif->Flags & RPC_IF_AUTOLISTEN) { - RPCRT4_start_listen(TRUE); - - /* make sure server is actually listening on the interface before - * returning */ - RPCRT4_sync_with_server_thread(); - } + if (sif->Flags & RPC_IF_AUTOLISTEN) + RPCRT4_start_listen(TRUE); return RPC_S_OK; } @@ -872,8 +855,45 @@ RPC_STATUS WINAPI RpcServerRegisterIf2( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, */ RPC_STATUS WINAPI RpcServerUnregisterIf( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, UINT WaitForCallsToComplete ) { - FIXME("(IfSpec == (RPC_IF_HANDLE)^%p, MgrTypeUuid == %s, WaitForCallsToComplete == %u): stub\n", - IfSpec, debugstr_guid(MgrTypeUuid), WaitForCallsToComplete); + PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec; + HANDLE event = NULL; + BOOL found = FALSE; + BOOL completed = TRUE; + RpcServerInterface *cif; + RPC_STATUS status; + + TRACE("(IfSpec == (RPC_IF_HANDLE)^%p (%s), MgrTypeUuid == %s, WaitForCallsToComplete == %u)\n", + IfSpec, debugstr_guid(&If->InterfaceId.SyntaxGUID), debugstr_guid(MgrTypeUuid), WaitForCallsToComplete); + + EnterCriticalSection(&server_cs); + LIST_FOR_EACH_ENTRY(cif, &server_interfaces, RpcServerInterface, entry) { + if ((!IfSpec || !memcmp(&If->InterfaceId, &cif->If->InterfaceId, sizeof(RPC_SYNTAX_IDENTIFIER))) && + UuidEqual(MgrTypeUuid, &cif->MgrTypeUuid, &status)) { + list_remove(&cif->entry); + if (cif->CurrentCalls) { + completed = FALSE; + if (WaitForCallsToComplete) + cif->CallsCompletedEvent = event = CreateEventW(NULL, FALSE, FALSE, NULL); + } + found = TRUE; + break; + } + } + LeaveCriticalSection(&server_cs); + + if (!found) { + ERR("not found for object %s\n", debugstr_guid(MgrTypeUuid)); + return RPC_S_UNKNOWN_IF; + } + + if (completed) + HeapFree(GetProcessHeap(), 0, cif); + else if (event) { + /* sif will be freed when the last call is completed, so be careful not to + * touch that memory here as that could happen before we get here */ + WaitForSingleObject(event, INFINITE); + CloseHandle(event); + } return RPC_S_OK; } @@ -929,7 +949,7 @@ RPC_STATUS WINAPI RpcObjectSetType( UUID* ObjUuid, UUID* TypeUuid ) if ((! TypeUuid) || UuidIsNil(TypeUuid, &dummy)) { /* ... and drop it from the list */ if (map) { - if (prev) + if (prev) prev->next = map->next; else RpcObjTypeMaps = map->next; @@ -956,22 +976,22 @@ RPC_STATUS WINAPI RpcObjectSetType( UUID* ObjUuid, UUID* TypeUuid ) /*********************************************************************** * RpcServerRegisterAuthInfoA (RPCRT4.@) */ -RPC_STATUS WINAPI RpcServerRegisterAuthInfoA( unsigned char *ServerPrincName, unsigned long AuthnSvc, RPC_AUTH_KEY_RETRIEVAL_FN GetKeyFn, +RPC_STATUS WINAPI RpcServerRegisterAuthInfoA( RPC_CSTR ServerPrincName, ULONG AuthnSvc, RPC_AUTH_KEY_RETRIEVAL_FN GetKeyFn, LPVOID Arg ) { - FIXME( "(%s,%lu,%p,%p): stub\n", ServerPrincName, AuthnSvc, GetKeyFn, Arg ); - + FIXME( "(%s,%u,%p,%p): stub\n", ServerPrincName, AuthnSvc, GetKeyFn, Arg ); + return RPC_S_UNKNOWN_AUTHN_SERVICE; /* We don't know any authentication services */ } /*********************************************************************** * RpcServerRegisterAuthInfoW (RPCRT4.@) */ -RPC_STATUS WINAPI RpcServerRegisterAuthInfoW( LPWSTR ServerPrincName, unsigned long AuthnSvc, RPC_AUTH_KEY_RETRIEVAL_FN GetKeyFn, +RPC_STATUS WINAPI RpcServerRegisterAuthInfoW( RPC_WSTR ServerPrincName, ULONG AuthnSvc, RPC_AUTH_KEY_RETRIEVAL_FN GetKeyFn, LPVOID Arg ) { - FIXME( "(%s,%lu,%p,%p): stub\n", debugstr_w( ServerPrincName ), AuthnSvc, GetKeyFn, Arg ); - + FIXME( "(%s,%u,%p,%p): stub\n", debugstr_w( ServerPrincName ), AuthnSvc, GetKeyFn, Arg ); + return RPC_S_UNKNOWN_AUTHN_SERVICE; /* We don't know any authentication services */ } @@ -980,18 +1000,15 @@ RPC_STATUS WINAPI RpcServerRegisterAuthInfoW( LPWSTR ServerPrincName, unsigned l */ RPC_STATUS WINAPI RpcServerListen( UINT MinimumCallThreads, UINT MaxCalls, UINT DontWait ) { - RPC_STATUS status; + RPC_STATUS status = RPC_S_OK; TRACE("(%u,%u,%u)\n", MinimumCallThreads, MaxCalls, DontWait); - if (!protseqs) + if (list_empty(&protseqs)) return RPC_S_NO_PROTSEQS_REGISTERED; status = RPCRT4_start_listen(FALSE); - if (status == RPC_S_OK) - RPCRT4_sync_with_server_thread(); - if (DontWait || (status != RPC_S_OK)) return status; return RpcMgmtWaitServerListen(); @@ -1010,9 +1027,11 @@ RPC_STATUS WINAPI RpcMgmtWaitServerListen( void ) LeaveCriticalSection(&listen_cs); return RPC_S_NOT_LISTENING; } - + LeaveCriticalSection(&listen_cs); + FIXME("not waiting for server calls to finish\n"); + return RPC_S_OK; } @@ -1027,12 +1046,21 @@ RPC_STATUS WINAPI RpcMgmtStopServerListening ( RPC_BINDING_HANDLE Binding ) FIXME("client-side invocation not implemented.\n"); return RPC_S_WRONG_KIND_OF_BINDING; } - + RPCRT4_stop_listen(FALSE); return RPC_S_OK; } +/*********************************************************************** + * RpcMgmtEnableIdleCleanup (RPCRT4.@) + */ +RPC_STATUS WINAPI RpcMgmtEnableIdleCleanup(void) +{ + FIXME("(): stub\n"); + return RPC_S_OK; +} + /*********************************************************************** * I_RpcServerStartListening (RPCRT4.@) */ @@ -1058,7 +1086,54 @@ RPC_STATUS WINAPI I_RpcServerStopListening( void ) */ UINT WINAPI I_RpcWindowProc( void *hWnd, UINT Message, UINT wParam, ULONG lParam ) { - FIXME( "(%p,%08x,%08x,%08lx): stub\n", hWnd, Message, wParam, lParam ); + FIXME( "(%p,%08x,%08x,%08x): stub\n", hWnd, Message, wParam, lParam ); return 0; } + +/*********************************************************************** + * RpcMgmtInqIfIds (RPCRT4.@) + */ +RPC_STATUS WINAPI RpcMgmtInqIfIds(RPC_BINDING_HANDLE Binding, RPC_IF_ID_VECTOR **IfIdVector) +{ + FIXME("(%p,%p): stub\n", Binding, IfIdVector); + return RPC_S_INVALID_BINDING; +} + +/*********************************************************************** + * RpcMgmtEpEltInqBegin (RPCRT4.@) + */ +RPC_STATUS WINAPI RpcMgmtEpEltInqBegin(RPC_BINDING_HANDLE Binding, ULONG InquiryType, + RPC_IF_ID *IfId, ULONG VersOption, UUID *ObjectUuid, RPC_EP_INQ_HANDLE* InquiryContext) +{ + FIXME("(%p,%u,%p,%u,%p,%p): stub\n", + Binding, InquiryType, IfId, VersOption, ObjectUuid, InquiryContext); + return RPC_S_INVALID_BINDING; +} + +/*********************************************************************** + * RpcMgmtIsServerListening (RPCRT4.@) + */ +RPC_STATUS WINAPI RpcMgmtIsServerListening(RPC_BINDING_HANDLE Binding) +{ + FIXME("(%p): stub\n", Binding); + return RPC_S_INVALID_BINDING; +} + +/*********************************************************************** + * RpcMgmtSetServerStackSize (RPCRT4.@) + */ +RPC_STATUS WINAPI RpcMgmtSetServerStackSize(ULONG ThreadStackSize) +{ + FIXME("(0x%x): stub\n", ThreadStackSize); + return RPC_S_OK; +} + +/*********************************************************************** + * I_RpcGetCurrentCallHandle (RPCRT4.@) + */ +RPC_BINDING_HANDLE WINAPI I_RpcGetCurrentCallHandle(void) +{ + TRACE("\n"); + return RPCRT4_GetThreadCurrentCallHandle(); +} diff --git a/reactos/dll/win32/rpcrt4/rpc_server.h b/reactos/dll/win32/rpcrt4/rpc_server.h index 1f43de8d024..eb32be6afc9 100644 --- a/reactos/dll/win32/rpcrt4/rpc_server.h +++ b/reactos/dll/win32/rpcrt4/rpc_server.h @@ -15,26 +15,53 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __WINE_RPC_SERVER_H #define __WINE_RPC_SERVER_H #include "rpc_binding.h" +#include "wine/list.h" + +struct protseq_ops; typedef struct _RpcServerProtseq { - struct _RpcServerProtseq* Next; - LPSTR Protseq; - LPSTR Endpoint; - UINT MaxCalls; - RpcConnection* conn; + const struct protseq_ops *ops; /* RO */ + struct list entry; /* CS ::server_cs */ + LPSTR Protseq; /* RO */ + UINT MaxCalls; /* RO */ + /* list of listening connections */ + RpcConnection* conn; /* CS cs */ + CRITICAL_SECTION cs; + + /* is the server currently listening? */ + BOOL is_listening; /* CS ::listen_cs */ + /* mutex for ensuring only one thread can change state at a time */ + HANDLE mgr_mutex; + /* set when server thread has finished opening connections */ + HANDLE server_ready_event; } RpcServerProtseq; +struct protseq_ops +{ + const char *name; + RpcServerProtseq *(*alloc)(void); + void (*signal_state_changed)(RpcServerProtseq *protseq); + /* previous array is passed in to allow reuse of memory */ + void *(*get_wait_array)(RpcServerProtseq *protseq, void *prev_array, unsigned int *count); + void (*free_wait_array)(RpcServerProtseq *protseq, void *array); + /* returns -1 for failure, 0 for server state changed and 1 to indicate a + * new connection was established */ + int (*wait_for_new_connection)(RpcServerProtseq *protseq, unsigned int count, void *wait_array); + /* opens the endpoint and optionally begins listening */ + RPC_STATUS (*open_endpoint)(RpcServerProtseq *protseq, LPSTR endpoint); +}; + typedef struct _RpcServerInterface { - struct _RpcServerInterface* Next; + struct list entry; RPC_SERVER_INTERFACE* If; UUID MgrTypeUuid; RPC_MGR_EPV* MgrEpv; @@ -42,6 +69,13 @@ typedef struct _RpcServerInterface UINT MaxCalls; UINT MaxRpcSize; RPC_IF_CALLBACK_FN* IfCallbackFn; + LONG CurrentCalls; /* number of calls currently executing */ + /* set when unregistering interface to let the caller of + * RpcServerUnregisterIf* know that all calls have finished */ + HANDLE CallsCompletedEvent; } RpcServerInterface; +void RPCRT4_new_client(RpcConnection* conn); +const struct protseq_ops *rpcrt4_get_protseq_ops(const char *protseq); + #endif /* __WINE_RPC_SERVER_H */ diff --git a/reactos/dll/win32/rpcrt4_new/rpc_transport.c b/reactos/dll/win32/rpcrt4/rpc_transport.c similarity index 99% rename from reactos/dll/win32/rpcrt4_new/rpc_transport.c rename to reactos/dll/win32/rpcrt4/rpc_transport.c index 7665ef79358..b8e4ee91388 100644 --- a/reactos/dll/win32/rpcrt4_new/rpc_transport.c +++ b/reactos/dll/win32/rpcrt4/rpc_transport.c @@ -375,7 +375,7 @@ static int rpcrt4_conn_np_read(RpcConnection *Connection, break; ret = GetOverlappedResult(npc->pipe, &npc->ovl[0], &bytes_read, TRUE); - if (!ret && GetLastError() != ERROR_MORE_DATA) + if (!ret /*&& GetLastError() != ERROR_MORE_DATA*/) break; bytes_left -= bytes_read; @@ -400,7 +400,7 @@ static int rpcrt4_conn_np_write(RpcConnection *Connection, break; ret = GetOverlappedResult(npc->pipe, &npc->ovl[1], &bytes_written, TRUE); - if (!ret && GetLastError() != ERROR_MORE_DATA) + if (!ret /*&& GetLastError() != ERROR_MORE_DATA*/) break; bytes_left -= bytes_written; diff --git a/reactos/dll/win32/rpcrt4/rpcrt4.rbuild b/reactos/dll/win32/rpcrt4/rpcrt4.rbuild index 67b08e7af54..fa6f46b15eb 100644 --- a/reactos/dll/win32/rpcrt4/rpcrt4.rbuild +++ b/reactos/dll/win32/rpcrt4/rpcrt4.rbuild @@ -17,28 +17,27 @@ ntdll kernel32 advapi32 + secur32 iphlpapi - pseh - - - + ws2_32 cproxy.c cpsf.c cstub.c + ndr_contexthandle.c + ndr_clientserver.c + ndr_fullpointer.c ndr_marshall.c - ndr_midl.c ndr_ole.c ndr_stubless.c + rpc_assoc.c rpc_binding.c rpc_epmap.c rpc_message.c rpc_server.c - ndr_contexth.c + rpc_transport.c rpcrt4_main.c rpcss_np_client.c + unix_func.c rpcrt4.rc rpcrt4.spec diff --git a/reactos/dll/win32/rpcrt4/rpcrt4.spec b/reactos/dll/win32/rpcrt4/rpcrt4.spec index de4df2eb758..93f6d318e46 100644 --- a/reactos/dll/win32/rpcrt4/rpcrt4.spec +++ b/reactos/dll/win32/rpcrt4/rpcrt4.spec @@ -19,7 +19,7 @@ @ stdcall IUnknown_QueryInterface_Proxy(ptr ptr ptr) @ stdcall IUnknown_Release_Proxy(ptr) @ stub I_RpcAbortAsyncCall -@ stub I_RpcAllocate +@ stdcall I_RpcAllocate(long) @ stub I_RpcAsyncAbortCall @ stub I_RpcAsyncSendReceive # NT4 @ stub I_RpcAsyncSetHandle @@ -45,13 +45,13 @@ @ stub I_RpcDeleteMutex @ stub I_RpcEnableWmiTrace # wxp @ stub I_RpcExceptionFilter # wxp -@ stub I_RpcFree +@ stdcall I_RpcFree(ptr) @ stdcall I_RpcFreeBuffer(ptr) @ stub I_RpcFreePipeBuffer @ stub I_RpcGetAssociationContext @ stdcall I_RpcGetBuffer(ptr) @ stub I_RpcGetBufferWithObject -@ stub I_RpcGetCurrentCallHandle +@ stdcall I_RpcGetCurrentCallHandle() @ stub I_RpcGetExtendedError @ stub I_RpcGetServerContextList @ stub I_RpcGetThreadEvent # win9x @@ -59,7 +59,7 @@ @ stub I_RpcIfInqTransferSyntaxes @ stub I_RpcLaunchDatagramReceiveThread # win9x @ stub I_RpcLogEvent -@ stub I_RpcMapWin32Status +@ stdcall I_RpcMapWin32Status(long) @ stub I_RpcMonitorAssociation @ stub I_RpcNegotiateTransferSyntax # wxp @ stub I_RpcNsBindingSetEntryName @@ -140,12 +140,12 @@ @ stdcall NDRCContextBinding(ptr) @ stdcall NDRCContextMarshall(ptr ptr) @ stdcall NDRCContextUnmarshall(ptr ptr ptr long) -@ stub NDRSContextMarshall2 +@ stdcall NDRSContextMarshall2(ptr ptr ptr ptr ptr long) @ stdcall NDRSContextMarshall(ptr ptr ptr) @ stdcall NDRSContextMarshallEx(ptr ptr ptr ptr) -@ stub NDRSContextUnmarshall2 -@ stdcall NDRSContextUnmarshall(ptr long) -@ stdcall NDRSContextUnmarshallEx(ptr ptr long) +@ stdcall NDRSContextUnmarshall2(ptr ptr ptr ptr long) +@ stdcall NDRSContextUnmarshall(ptr ptr) +@ stdcall NDRSContextUnmarshallEx(ptr ptr ptr) @ stub NDRcopy @ stdcall NdrAllocate(ptr long) @ stub NdrAsyncClientCall @@ -158,7 +158,7 @@ @ stdcall NdrCStdStubBuffer_Release(ptr ptr) @ stdcall NdrClearOutParameters(ptr ptr ptr) @ varargs NdrClientCall2(ptr ptr) -@ stub NdrClientCall +@ varargs NdrClientCall(ptr ptr) NdrClientCall2 @ stdcall NdrClientContextMarshall(ptr ptr long) @ stdcall NdrClientContextUnmarshall(ptr ptr ptr) @ stub NdrClientInitialize @@ -221,12 +221,12 @@ @ stdcall NdrFixedArrayMemorySize(ptr ptr) @ stdcall NdrFixedArrayUnmarshall(ptr ptr ptr long) @ stdcall NdrFreeBuffer(ptr) -@ stub NdrFullPointerFree -@ stub NdrFullPointerInsertRefId -@ stub NdrFullPointerQueryPointer -@ stub NdrFullPointerQueryRefId -@ stub NdrFullPointerXlatFree -@ stub NdrFullPointerXlatInit +@ stdcall NdrFullPointerFree(ptr ptr) +@ stdcall NdrFullPointerInsertRefId(ptr long ptr) +@ stdcall NdrFullPointerQueryPointer(ptr ptr long ptr) +@ stdcall NdrFullPointerQueryRefId(ptr long long ptr) +@ stdcall NdrFullPointerXlatFree(ptr) +@ stdcall NdrFullPointerXlatInit(long long) @ stdcall NdrGetBuffer(ptr long ptr) @ stub NdrGetDcomProtocolVersion @ stub NdrGetPartialBuffer @@ -294,7 +294,7 @@ @ stdcall NdrProxyGetBuffer(ptr ptr) @ stdcall NdrProxyInitialize(ptr ptr ptr ptr long) @ stdcall NdrProxySendReceive(ptr ptr) -@ stub NdrRangeUnmarshall +@ stdcall NdrRangeUnmarshall(ptr ptr ptr long) @ stub NdrRpcSmClientAllocate @ stub NdrRpcSmClientFree @ stub NdrRpcSmSetClientToOsf @@ -377,25 +377,25 @@ @ stub RpcBindingInqAuthClientExA @ stub RpcBindingInqAuthClientExW @ stub RpcBindingInqAuthClientW -@ stub RpcBindingInqAuthInfoA -@ stub RpcBindingInqAuthInfoExA -@ stub RpcBindingInqAuthInfoExW -@ stub RpcBindingInqAuthInfoW +@ stdcall RpcBindingInqAuthInfoA(ptr ptr ptr ptr ptr ptr) +@ stdcall RpcBindingInqAuthInfoExA(ptr ptr ptr ptr ptr ptr long ptr) +@ stdcall RpcBindingInqAuthInfoExW(ptr ptr ptr ptr ptr ptr long ptr) +@ stdcall RpcBindingInqAuthInfoW(ptr ptr ptr ptr ptr ptr) @ stdcall RpcBindingInqObject(ptr ptr) @ stub RpcBindingInqOption @ stub RpcBindingReset @ stub RpcBindingServerFromClient -@ stub RpcBindingSetAuthInfoA -@ stub RpcBindingSetAuthInfoExA -@ stub RpcBindingSetAuthInfoExW -@ stub RpcBindingSetAuthInfoW +@ stdcall RpcBindingSetAuthInfoA(ptr str long long ptr long) +@ stdcall RpcBindingSetAuthInfoExA(ptr str long long ptr long ptr) +@ stdcall RpcBindingSetAuthInfoExW(ptr wstr long long ptr long ptr) +@ stdcall RpcBindingSetAuthInfoW(ptr wstr long long ptr long) @ stdcall RpcBindingSetObject(ptr ptr) -@ stub RpcBindingSetOption +@ stdcall RpcBindingSetOption(ptr long long) @ stdcall RpcBindingToStringBindingA(ptr ptr) @ stdcall RpcBindingToStringBindingW(ptr ptr) @ stdcall RpcBindingVectorFree(ptr) @ stub RpcCancelAsyncCall -@ stub RpcCancelThread +@ stdcall RpcCancelThread(ptr) @ stub RpcCancelThreadEx @ stub RpcCertGeneratePrincipalNameA @ stub RpcCertGeneratePrincipalNameW @@ -414,7 +414,7 @@ @ stub RpcErrorNumberOfRecords # wxp @ stub RpcErrorResetEnumeration # wxp @ stub RpcErrorSaveErrorInfo # wxp -@ stub RpcErrorStartEnumeration # wxp +@ stdcall RpcErrorStartEnumeration(ptr) @ stub RpcFreeAuthorizationContext # wxp @ stub RpcGetAsyncCallStatus @ stub RpcIfIdVectorFree @@ -423,25 +423,25 @@ @ stub RpcInitializeAsyncHandle @ stub RpcMgmtBindingInqParameter # win9x @ stub RpcMgmtBindingSetParameter # win9x -@ stub RpcMgmtEnableIdleCleanup -@ stub RpcMgmtEpEltInqBegin +@ stdcall RpcMgmtEnableIdleCleanup() +@ stdcall RpcMgmtEpEltInqBegin(ptr long ptr long ptr ptr) @ stub RpcMgmtEpEltInqDone @ stub RpcMgmtEpEltInqNextA @ stub RpcMgmtEpEltInqNextW @ stub RpcMgmtEpUnregister @ stub RpcMgmtInqComTimeout @ stub RpcMgmtInqDefaultProtectLevel -@ stub RpcMgmtInqIfIds +@ stdcall RpcMgmtInqIfIds(ptr ptr) @ stub RpcMgmtInqParameter # win9x @ stub RpcMgmtInqServerPrincNameA @ stub RpcMgmtInqServerPrincNameW @ stub RpcMgmtInqStats -@ stub RpcMgmtIsServerListening +@ stdcall RpcMgmtIsServerListening(ptr) @ stub RpcMgmtSetAuthorizationFn -@ stub RpcMgmtSetCancelTimeout -@ stub RpcMgmtSetComTimeout +@ stdcall RpcMgmtSetCancelTimeout(long) +@ stdcall RpcMgmtSetComTimeout(ptr long) @ stub RpcMgmtSetParameter # win9x -@ stub RpcMgmtSetServerStackSize +@ stdcall RpcMgmtSetServerStackSize(long) @ stub RpcMgmtStatsVectorFree @ stdcall RpcMgmtStopServerListening(ptr) @ stdcall RpcMgmtWaitServerListen() @@ -494,7 +494,7 @@ @ stub RpcServerYield @ stub RpcSmAllocate @ stub RpcSmClientFree -@ stdcall RpcSmDestroyClientContext (ptr) +@ stdcall RpcSmDestroyClientContext(ptr) @ stub RpcSmDisableAllocate @ stub RpcSmEnableAllocate @ stub RpcSmFree @@ -505,7 +505,7 @@ @ stub RpcSsAllocate @ stub RpcSsContextLockExclusive # wxp @ stub RpcSsContextLockShared # wxp -@ stdcall RpcSsDestroyClientContext (ptr) +@ stdcall RpcSsDestroyClientContext(ptr) @ stub RpcSsDisableAllocate @ stub RpcSsDontSerializeContext @ stub RpcSsEnableAllocate @@ -527,8 +527,8 @@ @ stub SimpleTypeBufferSize # wxp @ stub SimpleTypeMemorySize # wxp @ stub StartServiceIfNecessary # win9x -@ stub TowerConstruct -@ stub TowerExplode +@ stdcall TowerConstruct(ptr ptr ptr ptr ptr ptr) +@ stdcall TowerExplode(ptr ptr ptr ptr ptr ptr) @ stdcall UuidCompare(ptr ptr ptr) @ stdcall UuidCreate(ptr) @ stdcall UuidCreateNil(ptr) diff --git a/reactos/dll/win32/rpcrt4/rpcrt4_main.c b/reactos/dll/win32/rpcrt4/rpcrt4_main.c index 4e534d93e12..e48cf586988 100644 --- a/reactos/dll/win32/rpcrt4/rpcrt4_main.c +++ b/reactos/dll/win32/rpcrt4/rpcrt4_main.c @@ -15,8 +15,8 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * * WINE RPC TODO's (and a few TODONT's) * * - Ove's decreasingly incomplete widl is an IDL compiler for wine. For widl @@ -45,11 +45,11 @@ * * - Some transports are not yet implemented. The existing transport implementations * are incomplete and may be bug-infested. - * + * * - The various transports that we do support ought to be supported in a more * object-oriented manner, as in DCE's RPC implementation, instead of cluttering * up the code with conditionals like we do now. - * + * * - Data marshalling: So far, only the beginnings of a full implementation * exist in wine. NDR protocol itself is documented, but the MS API's to * convert data-types in memory into NDR are not. This is challenging work, @@ -59,7 +59,7 @@ * use it to implement out-of-process OLE client/server communications. * ATM there is maybe a disconnect between the marshalling in the OLE DLLs * and the marshalling going on here [TODO: well, is there or not?] - * + * * - In-source API Documentation, at least for those functions which we have * implemented, but preferably for everything we can document, would be nice, * since some of this stuff is quite obscure. @@ -100,6 +100,8 @@ #include "winerror.h" #include "winbase.h" #include "winuser.h" +#include "winnt.h" +#include "winternl.h" #include "iptypes.h" #include "iphlpapi.h" #include "wine/unicode.h" @@ -133,6 +135,33 @@ static CRITICAL_SECTION_DEBUG critsect_debug = }; static CRITICAL_SECTION uuid_cs = { &critsect_debug, -1, 0, 0, 0, 0 }; +static CRITICAL_SECTION threaddata_cs; +static CRITICAL_SECTION_DEBUG threaddata_cs_debug = +{ + 0, 0, &threaddata_cs, + { &threaddata_cs_debug.ProcessLocksList, &threaddata_cs_debug.ProcessLocksList }, + 0, 0, { (DWORD_PTR)(__FILE__ ": threaddata_cs") } +}; +static CRITICAL_SECTION threaddata_cs = { &threaddata_cs_debug, -1, 0, 0, 0, 0 }; + +struct list threaddata_list = LIST_INIT(threaddata_list); + +struct context_handle_list +{ + struct context_handle_list *next; + NDR_SCONTEXT context_handle; +}; + +struct threaddata +{ + struct list entry; + CRITICAL_SECTION cs; + DWORD thread_id; + RpcConnection *connection; + RpcBinding *server_binding; + struct context_handle_list *context_handle_list; +}; + /*********************************************************************** * DllMain * @@ -148,10 +177,30 @@ static CRITICAL_SECTION uuid_cs = { &critsect_debug, -1, 0, 0, 0, 0 }; BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { + struct threaddata *tdata; + switch (fdwReason) { case DLL_PROCESS_ATTACH: - DisableThreadLibraryCalls(hinstDLL); master_mutex = CreateMutexA( NULL, FALSE, RPCSS_MASTER_MUTEX_NAME); + if (!master_mutex) + ERR("Failed to create master mutex\n"); + break; + + case DLL_THREAD_DETACH: + tdata = NtCurrentTeb()->ReservedForNtRpc; + if (tdata) + { + EnterCriticalSection(&threaddata_cs); + list_remove(&tdata->entry); + LeaveCriticalSection(&threaddata_cs); + + DeleteCriticalSection(&tdata->cs); + if (tdata->connection) + ERR("tdata->connection should be NULL but is still set to %p\n", tdata->connection); + if (tdata->server_binding) + ERR("tdata->server_binding should be NULL but is still set to %p\n", tdata->server_binding); + HeapFree(GetProcessHeap(), 0, tdata); + } break; case DLL_PROCESS_DETACH: @@ -172,7 +221,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) * * S_OK if successful. */ -RPC_STATUS WINAPI RpcStringFreeA(unsigned char** String) +RPC_STATUS WINAPI RpcStringFreeA(RPC_CSTR* String) { HeapFree( GetProcessHeap(), 0, *String); @@ -188,7 +237,7 @@ RPC_STATUS WINAPI RpcStringFreeA(unsigned char** String) * * S_OK if successful. */ -RPC_STATUS WINAPI RpcStringFreeW(unsigned short** String) +RPC_STATUS WINAPI RpcStringFreeW(RPC_WSTR* String) { HeapFree( GetProcessHeap(), 0, *String); @@ -200,10 +249,12 @@ RPC_STATUS WINAPI RpcStringFreeW(unsigned short** String) * * Raises an exception. */ -void WINAPI RpcRaiseException(RPC_STATUS exception) +void DECLSPEC_NORETURN WINAPI RpcRaiseException(RPC_STATUS exception) { - /* FIXME: translate exception? */ + /* shouldn't return */ RaiseException(exception, 0, 0, NULL); + ERR("handler continued execution\n"); + ExitProcess(1); } /************************************************************************* @@ -213,7 +264,7 @@ void WINAPI RpcRaiseException(RPC_STATUS exception) * UUID *Uuid1 [I] Uuid to compare * UUID *Uuid2 [I] Uuid to compare * RPC_STATUS *Status [O] returns RPC_S_OK - * + * * RETURNS * -1 if Uuid1 is less than Uuid2 * 0 if Uuid1 and Uuid2 are equal @@ -319,9 +370,7 @@ static void RPC_UuidGetSystemTime(ULONGLONG *time) *time += TICKS_15_OCT_1582_TO_1601; } -typedef DWORD WINAPI (*LPGETADAPTERSINFO)(PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen); - -/* Assume that a hardware address is at least 6 bytes long */ +/* Assume that a hardware address is at least 6 bytes long */ #define ADDRESS_BYTES_NEEDED 6 static RPC_STATUS RPC_UuidGetNodeAddress(BYTE *address) @@ -331,46 +380,28 @@ static RPC_STATUS RPC_UuidGetNodeAddress(BYTE *address) ULONG buflen = sizeof(IP_ADAPTER_INFO); PIP_ADAPTER_INFO adapter = HeapAlloc(GetProcessHeap(), 0, buflen); - HANDLE hIpHlpApi; - LPGETADAPTERSINFO pGetAdaptersInfo; - hIpHlpApi = LoadLibrary("iphlpapi.dll"); - if (hIpHlpApi) - { - pGetAdaptersInfo = (LPGETADAPTERSINFO)GetProcAddress(hIpHlpApi, "GetAdaptersInfo"); - if (pGetAdaptersInfo) - { - if (pGetAdaptersInfo(adapter, &buflen) == ERROR_BUFFER_OVERFLOW) { - HeapFree(GetProcessHeap(), 0, adapter); - adapter = HeapAlloc(GetProcessHeap(), 0, buflen); - } + if (GetAdaptersInfo(adapter, &buflen) == ERROR_BUFFER_OVERFLOW) { + HeapFree(GetProcessHeap(), 0, adapter); + adapter = HeapAlloc(GetProcessHeap(), 0, buflen); + } - if (pGetAdaptersInfo(adapter, &buflen) == NO_ERROR) { - for (i = 0; i < ADDRESS_BYTES_NEEDED; i++) { - address[i] = adapter->Address[i]; - } - } - else - { - goto local; - } + if (GetAdaptersInfo(adapter, &buflen) == NO_ERROR) { + for (i = 0; i < ADDRESS_BYTES_NEEDED; i++) { + address[i] = adapter->Address[i]; + } + } + /* We can't get a hardware address, just use random numbers. + Set the multicast bit to prevent conflicts with real cards. */ + else { + for (i = 0; i < ADDRESS_BYTES_NEEDED; i++) { + address[i] = rand() & 0xff; } - /* Free the Library */ - FreeLibrary(hIpHlpApi); - goto exit; + address[0] |= 0x01; + status = RPC_S_UUID_LOCAL_ONLY; } -local: - /* We can't get a hardware address, just use random numbers. - Set the multicast bit to prevent conflicts with real cards. */ - for (i = 0; i < ADDRESS_BYTES_NEEDED; i++) { - address[i] = rand() & 0xff; - } - address[0] |= 0x01; - status = RPC_S_UUID_LOCAL_ONLY; - -exit: HeapFree(GetProcessHeap(), 0, adapter); return status; } @@ -386,9 +417,9 @@ exit: * RPC_S_UUID_LOCAL_ONLY if UUID is only locally unique. * * FIXME: No compensation for changes across reloading - * this dll or across reboots (e.g. clock going + * this dll or across reboots (e.g. clock going * backwards and swapped network cards). The RFC - * suggests using NVRAM for storing persistent + * suggests using NVRAM for storing persistent * values. */ RPC_STATUS WINAPI UuidCreate(UUID *Uuid) @@ -525,9 +556,9 @@ unsigned short WINAPI UuidHash(UUID *uuid, RPC_STATUS *Status) * RETURNS * * S_OK if successful. - * S_OUT_OF_MEMORY if unsucessful. + * S_OUT_OF_MEMORY if unsuccessful. */ -RPC_STATUS WINAPI UuidToStringA(UUID *Uuid, unsigned char** StringUuid) +RPC_STATUS WINAPI UuidToStringA(UUID *Uuid, RPC_CSTR* StringUuid) { *StringUuid = HeapAlloc( GetProcessHeap(), 0, sizeof(char) * 37); @@ -536,7 +567,7 @@ RPC_STATUS WINAPI UuidToStringA(UUID *Uuid, unsigned char** StringUuid) if (!Uuid) Uuid = &uuid_nil; - sprintf( (char*)*StringUuid, "%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", + sprintf( (char*)*StringUuid, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", Uuid->Data1, Uuid->Data2, Uuid->Data3, Uuid->Data4[0], Uuid->Data4[1], Uuid->Data4[2], Uuid->Data4[3], Uuid->Data4[4], Uuid->Data4[5], @@ -551,15 +582,15 @@ RPC_STATUS WINAPI UuidToStringA(UUID *Uuid, unsigned char** StringUuid) * Converts a UUID to a string. * * S_OK if successful. - * S_OUT_OF_MEMORY if unsucessful. + * S_OUT_OF_MEMORY if unsuccessful. */ -RPC_STATUS WINAPI UuidToStringW(UUID *Uuid, unsigned short** StringUuid) +RPC_STATUS WINAPI UuidToStringW(UUID *Uuid, RPC_WSTR* StringUuid) { char buf[37]; if (!Uuid) Uuid = &uuid_nil; - sprintf(buf, "%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", + sprintf(buf, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", Uuid->Data1, Uuid->Data2, Uuid->Data3, Uuid->Data4[0], Uuid->Data4[1], Uuid->Data4[2], Uuid->Data4[3], Uuid->Data4[4], Uuid->Data4[5], @@ -587,7 +618,7 @@ static const BYTE hex2bin[] = /*********************************************************************** * UuidFromStringA (RPCRT4.@) */ -RPC_STATUS WINAPI UuidFromStringA(unsigned char* s, UUID *uuid) +RPC_STATUS WINAPI UuidFromStringA(RPC_CSTR s, UUID *uuid) { int i; @@ -627,7 +658,7 @@ RPC_STATUS WINAPI UuidFromStringA(unsigned char* s, UUID *uuid) /*********************************************************************** * UuidFromStringW (RPCRT4.@) */ -RPC_STATUS WINAPI UuidFromStringW(unsigned short* s, UUID *uuid) +RPC_STATUS WINAPI UuidFromStringW(RPC_WSTR s, UUID *uuid) { int i; @@ -673,7 +704,7 @@ HRESULT WINAPI DllRegisterServer( void ) return S_OK; } -BOOL RPCRT4_StartRPCSS(void) +static BOOL RPCRT4_StartRPCSS(void) { PROCESS_INFORMATION pi; STARTUPINFOA si; @@ -711,11 +742,11 @@ BOOL RPCRT4_StartRPCSS(void) /*********************************************************************** * RPCRT4_RPCSSOnDemandCall (internal) - * + * * Attempts to send a message to the RPCSS process * on the local machine, invoking it if necessary. * For remote RPCSS calls, use.... your imagination. - * + * * PARAMS * msg [I] pointer to the RPCSS message * vardata_payload [I] pointer vardata portion of the RPCSS message @@ -728,13 +759,14 @@ BOOL RPCRT4_StartRPCSS(void) BOOL RPCRT4_RPCSSOnDemandCall(PRPCSS_NP_MESSAGE msg, char *vardata_payload, PRPCSS_NP_REPLY reply) { HANDLE client_handle; + BOOL ret; int i, j = 0; TRACE("(msg == %p, vardata_payload == %p, reply == %p)\n", msg, vardata_payload, reply); client_handle = RPCRT4_RpcssNPConnect(); - while (!client_handle) { + while (INVALID_HANDLE_VALUE == client_handle) { /* start the RPCSS process */ if (!RPCRT4_StartRPCSS()) { ERR("Unable to start RPCSS process.\n"); @@ -744,13 +776,13 @@ BOOL RPCRT4_RPCSSOnDemandCall(PRPCSS_NP_MESSAGE msg, char *vardata_payload, PRPC for (i = 0; i < 60; i++) { Sleep(200); client_handle = RPCRT4_RpcssNPConnect(); - if (client_handle) break; - } + if (INVALID_HANDLE_VALUE != client_handle) break; + } /* we are only willing to try twice */ if (j++ >= 1) break; } - if (!client_handle) { + if (INVALID_HANDLE_VALUE == client_handle) { /* no dice! */ ERR("Unable to connect to RPCSS process!\n"); SetLastError(RPC_E_SERVER_DIED_DNE); @@ -758,12 +790,14 @@ BOOL RPCRT4_RPCSSOnDemandCall(PRPCSS_NP_MESSAGE msg, char *vardata_payload, PRPC } /* great, we're connected. now send the message */ + ret = TRUE; if (!RPCRT4_SendReceiveNPMsg(client_handle, msg, vardata_payload, reply)) { ERR("Something is amiss: RPC_SendReceive failed.\n"); - return FALSE; + ret = FALSE; } + CloseHandle(client_handle); - return TRUE; + return ret; } #define MAX_RPC_ERROR_TEXT 256 @@ -780,7 +814,7 @@ BOOL RPCRT4_RPCSSOnDemandCall(PRPCSS_NP_MESSAGE msg, char *vardata_payload, PRPC * 4. The MSDN documentation currently declares that the second argument is * unsigned char *, even for the W version. I don't believe it. */ -RPC_STATUS RPC_ENTRY DceErrorInqTextW (RPC_STATUS e, unsigned short *buffer) +RPC_STATUS RPC_ENTRY DceErrorInqTextW (RPC_STATUS e, RPC_WSTR buffer) { DWORD count; count = FormatMessageW (FORMAT_MESSAGE_FROM_SYSTEM | @@ -793,7 +827,7 @@ RPC_STATUS RPC_ENTRY DceErrorInqTextW (RPC_STATUS e, unsigned short *buffer) NULL, RPC_S_NOT_RPC_ERROR, 0, buffer, MAX_RPC_ERROR_TEXT, NULL); if (!count) { - ERR ("Failed to translate error"); + ERR ("Failed to translate error\n"); return RPC_S_INVALID_ARG; } } @@ -803,7 +837,7 @@ RPC_STATUS RPC_ENTRY DceErrorInqTextW (RPC_STATUS e, unsigned short *buffer) /****************************************************************************** * DceErrorInqTextA (rpcrt4.@) */ -RPC_STATUS RPC_ENTRY DceErrorInqTextA (RPC_STATUS e, unsigned char *buffer) +RPC_STATUS RPC_ENTRY DceErrorInqTextA (RPC_STATUS e, RPC_CSTR buffer) { RPC_STATUS status; WCHAR bufferW [MAX_RPC_ERROR_TEXT]; @@ -812,9 +846,180 @@ RPC_STATUS RPC_ENTRY DceErrorInqTextA (RPC_STATUS e, unsigned char *buffer) if (!WideCharToMultiByte(CP_ACP, 0, bufferW, -1, (LPSTR)buffer, MAX_RPC_ERROR_TEXT, NULL, NULL)) { - ERR ("Failed to translate error"); + ERR ("Failed to translate error\n"); status = RPC_S_INVALID_ARG; } } return status; } + +/****************************************************************************** + * I_RpcAllocate (rpcrt4.@) + */ +void * WINAPI I_RpcAllocate(unsigned int Size) +{ + return HeapAlloc(GetProcessHeap(), 0, Size); +} + +/****************************************************************************** + * I_RpcFree (rpcrt4.@) + */ +void WINAPI I_RpcFree(void *Object) +{ + HeapFree(GetProcessHeap(), 0, Object); +} + +/****************************************************************************** + * I_RpcMapWin32Status (rpcrt4.@) + */ +LONG WINAPI I_RpcMapWin32Status(RPC_STATUS status) +{ + FIXME("(%ld): stub\n", status); + return 0; +} + +/****************************************************************************** + * RpcErrorStartEnumeration (rpcrt4.@) + */ +RPC_STATUS RPC_ENTRY RpcErrorStartEnumeration(RPC_ERROR_ENUM_HANDLE* EnumHandle) +{ + FIXME("(%p): stub\n", EnumHandle); + return RPC_S_ENTRY_NOT_FOUND; +} + +/****************************************************************************** + * RpcMgmtSetCancelTimeout (rpcrt4.@) + */ +RPC_STATUS RPC_ENTRY RpcMgmtSetCancelTimeout(LONG Timeout) +{ + FIXME("(%d): stub\n", Timeout); + return RPC_S_OK; +} + +static struct threaddata *get_or_create_threaddata(void) +{ + struct threaddata *tdata = NtCurrentTeb()->ReservedForNtRpc; + if (!tdata) + { + tdata = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*tdata)); + if (!tdata) return NULL; + + InitializeCriticalSection(&tdata->cs); + tdata->thread_id = GetCurrentThreadId(); + + EnterCriticalSection(&threaddata_cs); + list_add_tail(&threaddata_list, &tdata->entry); + LeaveCriticalSection(&threaddata_cs); + + NtCurrentTeb()->ReservedForNtRpc = tdata; + return tdata; + } + return tdata; +} + +void RPCRT4_SetThreadCurrentConnection(RpcConnection *Connection) +{ + struct threaddata *tdata = get_or_create_threaddata(); + if (!tdata) return; + + EnterCriticalSection(&tdata->cs); + tdata->connection = Connection; + LeaveCriticalSection(&tdata->cs); +} + +void RPCRT4_SetThreadCurrentCallHandle(RpcBinding *Binding) +{ + struct threaddata *tdata = get_or_create_threaddata(); + if (!tdata) return; + + tdata->server_binding = Binding; +} + +RpcBinding *RPCRT4_GetThreadCurrentCallHandle(void) +{ + struct threaddata *tdata = get_or_create_threaddata(); + if (!tdata) return NULL; + + return tdata->server_binding; +} + +void RPCRT4_PushThreadContextHandle(NDR_SCONTEXT SContext) +{ + struct threaddata *tdata = get_or_create_threaddata(); + struct context_handle_list *context_handle_list; + + if (!tdata) return; + + context_handle_list = HeapAlloc(GetProcessHeap(), 0, sizeof(*context_handle_list)); + if (!context_handle_list) return; + + context_handle_list->context_handle = SContext; + context_handle_list->next = tdata->context_handle_list; + tdata->context_handle_list = context_handle_list; +} + +void RPCRT4_RemoveThreadContextHandle(NDR_SCONTEXT SContext) +{ + struct threaddata *tdata = get_or_create_threaddata(); + struct context_handle_list *current, *prev; + + if (!tdata) return; + + for (current = tdata->context_handle_list, prev = NULL; current; prev = current, current = current->next) + { + if (current->context_handle == SContext) + { + if (prev) + prev->next = current->next; + else + tdata->context_handle_list = current->next; + HeapFree(GetProcessHeap(), 0, current); + return; + } + } +} + +NDR_SCONTEXT RPCRT4_PopThreadContextHandle(void) +{ + struct threaddata *tdata = get_or_create_threaddata(); + struct context_handle_list *context_handle_list; + NDR_SCONTEXT context_handle; + + if (!tdata) return NULL; + + context_handle_list = tdata->context_handle_list; + if (!context_handle_list) return NULL; + tdata->context_handle_list = context_handle_list->next; + + context_handle = context_handle_list->context_handle; + HeapFree(GetProcessHeap(), 0, context_handle_list); + return context_handle; +} + +/****************************************************************************** + * RpcCancelThread (rpcrt4.@) + */ +RPC_STATUS RPC_ENTRY RpcCancelThread(void* ThreadHandle) +{ + DWORD target_tid; + struct threaddata *tdata; + + TRACE("(%p)\n", ThreadHandle); + + target_tid = GetThreadId(ThreadHandle); + if (!target_tid) + return RPC_S_INVALID_ARG; + + EnterCriticalSection(&threaddata_cs); + LIST_FOR_EACH_ENTRY(tdata, &threaddata_list, struct threaddata, entry) + if (tdata->thread_id == target_tid) + { + EnterCriticalSection(&tdata->cs); + if (tdata->connection) rpcrt4_conn_cancel_call(tdata->connection); + LeaveCriticalSection(&tdata->cs); + break; + } + LeaveCriticalSection(&threaddata_cs); + + return RPC_S_OK; +} diff --git a/reactos/dll/win32/rpcrt4_new/rpcrt4_ros.diff b/reactos/dll/win32/rpcrt4/rpcrt4_ros.diff similarity index 89% rename from reactos/dll/win32/rpcrt4_new/rpcrt4_ros.diff rename to reactos/dll/win32/rpcrt4/rpcrt4_ros.diff index c6b3943bd4a..2a76e462b92 100644 --- a/reactos/dll/win32/rpcrt4_new/rpcrt4_ros.diff +++ b/reactos/dll/win32/rpcrt4/rpcrt4_ros.diff @@ -1,40 +1,5 @@ ---- rpc_server.c Tue Jan 01 13:09:34 2008 -+++ rpc_server.c Fri Jan 11 15:58:57 2008 -@@ -1017,22 +1017,30 @@ - /*********************************************************************** - * RpcMgmtServerWaitListen (RPCRT4.@) - */ - RPC_STATUS WINAPI RpcMgmtWaitServerListen( void ) - { -- TRACE("()\n"); -+ RpcServerProtseq *cps; - - EnterCriticalSection(&listen_cs); - - if (!std_listen) { - LeaveCriticalSection(&listen_cs); - return RPC_S_NOT_LISTENING; - } - -+ do -+ { - LeaveCriticalSection(&listen_cs); - -- FIXME("not waiting for server calls to finish\n"); -+ LIST_FOR_EACH_ENTRY(cps, &protseqs, RpcServerProtseq, entry) -+ WaitForSingleObject(cps->server_ready_event, INFINITE); -+ -+ EnterCriticalSection(&listen_cs); -+ } while (!std_listen); -+ -+ LeaveCriticalSection(&listen_cs); - - return RPC_S_OK; - } - - /*********************************************************************** ---- rpc_transport.c Sun Jan 06 19:27:38 2008 -+++ rpc_transport.c Fri Jan 11 15:59:32 2008 +--- H:\Working Copies\wine\dlls\rpcrt4\rpc_transport.c Sun Jan 06 19:27:38 2008 ++++ H:\Working Copies\ReactOS\trunk\reactos\dll\win32\rpcrt4\rpc_transport.c Mon Jan 07 16:02:15 2008 @@ -54,10 +54,13 @@ #endif #ifdef HAVE_SYS_POLL_H @@ -162,7 +127,7 @@ break; + + ret = GetOverlappedResult(npc->pipe, &npc->ovl[0], &bytes_read, TRUE); -+ if (!ret && GetLastError() != ERROR_MORE_DATA) ++ if (!ret /*&& GetLastError() != ERROR_MORE_DATA*/) + break; + bytes_left -= bytes_read; @@ -183,7 +148,7 @@ break; + + ret = GetOverlappedResult(npc->pipe, &npc->ovl[1], &bytes_written, TRUE); -+ if (!ret && GetLastError() != ERROR_MORE_DATA) ++ if (!ret /*&& GetLastError() != ERROR_MORE_DATA*/) + break; + bytes_left -= bytes_written; diff --git a/reactos/dll/win32/rpcrt4/rpcss_np_client.c b/reactos/dll/win32/rpcrt4/rpcss_np_client.c index c454f95d25c..016f77f5f15 100644 --- a/reactos/dll/win32/rpcrt4/rpcss_np_client.c +++ b/reactos/dll/win32/rpcrt4/rpcss_np_client.c @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include @@ -32,22 +32,22 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole); HANDLE RPCRT4_RpcssNPConnect(void) { - HANDLE the_pipe = NULL; + HANDLE the_pipe; DWORD dwmode, wait_result; HANDLE master_mutex = RPCRT4_GetMasterMutex(); - + TRACE("\n"); while (TRUE) { wait_result = WaitForSingleObject(master_mutex, MASTER_MUTEX_TIMEOUT); switch (wait_result) { - case WAIT_ABANDONED: + case WAIT_ABANDONED: case WAIT_OBJECT_0: break; case WAIT_FAILED: case WAIT_TIMEOUT: - default: + default: ERR("This should never happen: couldn't enter mutex.\n"); return NULL; } @@ -67,29 +67,27 @@ HANDLE RPCRT4_RpcssNPConnect(void) break; if (GetLastError() != ERROR_PIPE_BUSY) { - WARN("Unable to open named pipe %s (assuming unavailable).\n", + WARN("Unable to open named pipe %s (assuming unavailable).\n", debugstr_a(NAME_RPCSS_NAMED_PIPE)); - the_pipe = NULL; break; } WARN("Named pipe busy (will wait)\n"); - + if (!ReleaseMutex(master_mutex)) ERR("Failed to release master mutex. Expect deadlock.\n"); - /* wait for the named pipe. We are only - willing to wait only 5 seconds. It should be available /very/ soon. */ + /* wait for the named pipe. We are only willing to wait for 5 seconds. + It should be available /very/ soon. */ if (! WaitNamedPipeA(NAME_RPCSS_NAMED_PIPE, MASTER_MUTEX_WAITNAMEDPIPE_TIMEOUT)) { ERR("Named pipe unavailable after waiting. Something is probably wrong.\n"); - the_pipe = NULL; break; } } - if (the_pipe) { + if (the_pipe != INVALID_HANDLE_VALUE) { dwmode = PIPE_READMODE_MESSAGE; /* SetNamedPipeHandleState not implemented ATM, but still seems to work somehow. */ if (! SetNamedPipeHandleState(the_pipe, &dwmode, NULL, NULL)) @@ -124,7 +122,7 @@ BOOL RPCRT4_SendReceiveNPMsg(HANDLE np, PRPCSS_NP_MESSAGE msg, char *vardata, PR /* process the vardata payload if necessary */ vardata_payload_msg.message_type = RPCSS_NP_MESSAGE_TYPEID_VARDATAPAYLOADMSG; vardata_payload_msg.vardata_payload_size = 0; /* meaningless */ - for ( payload_offset = 0; payload_offset < msg->vardata_payload_size; + for ( payload_offset = 0; payload_offset < msg->vardata_payload_size; payload_offset += VARDATA_PAYLOAD_BYTES ) { TRACE("sending vardata payload. vd=%p, po=%d, ps=%d\n", vardata, payload_offset, msg->vardata_payload_size); @@ -138,14 +136,14 @@ BOOL RPCRT4_SendReceiveNPMsg(HANDLE np, PRPCSS_NP_MESSAGE msg, char *vardata, PR return FALSE; } } - + if (! ReadFile(np, reply, sizeof(RPCSS_NP_REPLY), &count, NULL)) { ERR("read failed.\n"); return FALSE; } if (count != sizeof(RPCSS_NP_REPLY)) { - ERR("read count mismatch. got %ld, expected %u.\n", count, sizeof(RPCSS_NP_REPLY)); + ERR("read count mismatch. got %d.\n", count); return FALSE; } diff --git a/reactos/dll/win32/rpcrt4/rpcss_np_client.h b/reactos/dll/win32/rpcrt4/rpcss_np_client.h index c50e8ada80f..db65d432bca 100644 --- a/reactos/dll/win32/rpcrt4/rpcss_np_client.h +++ b/reactos/dll/win32/rpcrt4/rpcss_np_client.h @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef __WINE_RPCSS_NP_CLIENT_H diff --git a/reactos/dll/win32/rpcrt4_new/unix_func.c b/reactos/dll/win32/rpcrt4/unix_func.c similarity index 100% rename from reactos/dll/win32/rpcrt4_new/unix_func.c rename to reactos/dll/win32/rpcrt4/unix_func.c diff --git a/reactos/dll/win32/rpcrt4_new/unix_func.h b/reactos/dll/win32/rpcrt4/unix_func.h similarity index 100% rename from reactos/dll/win32/rpcrt4_new/unix_func.h rename to reactos/dll/win32/rpcrt4/unix_func.h diff --git a/reactos/dll/win32/rpcrt4_new/cproxy.c b/reactos/dll/win32/rpcrt4_new/cproxy.c deleted file mode 100644 index 6580bcf143c..00000000000 --- a/reactos/dll/win32/rpcrt4_new/cproxy.c +++ /dev/null @@ -1,450 +0,0 @@ -/* - * COM proxy implementation - * - * Copyright 2001 Ove Kåven, TransGaming Technologies - * - * 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 - * - * TODO: Handle non-i386 architectures - */ - -#include - -#define COBJMACROS - -#include "windef.h" -#include "winbase.h" -#include "winerror.h" - -#include "objbase.h" -#include "rpcproxy.h" - -#include "cpsf.h" -#include "ndr_misc.h" -#include "wine/debug.h" - -WINE_DEFAULT_DEBUG_CHANNEL(ole); - -struct StublessThunk; - -/* I don't know what MS's std proxy structure looks like, - so this probably doesn't match, but that shouldn't matter */ -typedef struct { - const IRpcProxyBufferVtbl *lpVtbl; - LPVOID *PVtbl; - LONG RefCount; - const MIDL_STUBLESS_PROXY_INFO *stubless; - const IID* piid; - LPUNKNOWN pUnkOuter; - PCInterfaceName name; - LPPSFACTORYBUFFER pPSFactory; - LPRPCCHANNELBUFFER pChannel; - struct StublessThunk *thunks; -} StdProxyImpl; - -static const IRpcProxyBufferVtbl StdProxy_Vtbl; - -#define ICOM_THIS_MULTI(impl,field,iface) impl* const This=(impl*)((char*)(iface) - offsetof(impl,field)) - -/* How the Windows stubless proxy thunks work is explained at - * http://msdn.microsoft.com/library/en-us/dnmsj99/html/com0199.asp, - * but I'll use a slightly different method, to make life easier */ - -#if defined(__i386__) - -#include "pshpack1.h" - -struct StublessThunk { - BYTE push; - DWORD index; - BYTE call; - LONG handler; - BYTE ret; - WORD bytes; - BYTE pad[3]; -}; - -#include "poppack.h" - -/* adjust the stack size since we don't use Windows's method */ -#define STACK_ADJUST sizeof(DWORD) - -#define FILL_STUBLESS(x,idx,stk) \ - x->push = 0x68; /* pushl [immediate] */ \ - x->index = (idx); \ - x->call = 0xe8; /* call [near] */ \ - x->handler = (char*)ObjectStubless - (char*)&x->ret; \ - x->ret = 0xc2; /* ret [immediate] */ \ - x->bytes = stk; \ - x->pad[0] = 0x8d; /* leal (%esi),%esi */ \ - x->pad[1] = 0x76; \ - x->pad[2] = 0x00; - -static HRESULT WINAPI ObjectStubless(DWORD index) -{ - char *args = (char*)(&index + 2); - LPVOID iface = *(LPVOID*)args; - - ICOM_THIS_MULTI(StdProxyImpl,PVtbl,iface); - - PFORMAT_STRING fs = This->stubless->ProcFormatString + This->stubless->FormatStringOffset[index]; - unsigned bytes = *(const WORD*)(fs+8) - STACK_ADJUST; - TRACE("(%p)->(%d)([%d bytes]) ret=%08x\n", iface, index, bytes, *(DWORD*)(args+bytes)); - - return NdrClientCall2(This->stubless->pStubDesc, fs, args); -} - -#else /* __i386__ */ - -/* can't do that on this arch */ -struct StublessThunk { int dummy; }; -#define FILL_STUBLESS(x,idx,stk) \ - ERR("stubless proxies are not supported on this architecture\n"); -#define STACK_ADJUST 0 - -#endif /* __i386__ */ - -HRESULT WINAPI StdProxy_Construct(REFIID riid, - LPUNKNOWN pUnkOuter, - const ProxyFileInfo *ProxyInfo, - int Index, - LPPSFACTORYBUFFER pPSFactory, - LPRPCPROXYBUFFER *ppProxy, - LPVOID *ppvObj) -{ - StdProxyImpl *This; - const MIDL_STUBLESS_PROXY_INFO *stubless = NULL; - PCInterfaceName name = ProxyInfo->pNamesArray[Index]; - CInterfaceProxyVtbl *vtbl = ProxyInfo->pProxyVtblList[Index]; - - TRACE("(%p,%p,%p,%p,%p) %s\n", pUnkOuter, vtbl, pPSFactory, ppProxy, ppvObj, name); - - /* TableVersion = 2 means it is the stubless version of CInterfaceProxyVtbl */ - if (ProxyInfo->TableVersion > 1) { - stubless = *(const void **)vtbl; - vtbl = (CInterfaceProxyVtbl *)((const void **)vtbl + 1); - TRACE("stubless=%p\n", stubless); - } - - TRACE("iid=%s\n", debugstr_guid(vtbl->header.piid)); - TRACE("vtbl=%p\n", vtbl->Vtbl); - - if (!IsEqualGUID(vtbl->header.piid, riid)) { - ERR("IID mismatch during proxy creation\n"); - return RPC_E_UNEXPECTED; - } - - This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(StdProxyImpl)); - if (!This) return E_OUTOFMEMORY; - - if (stubless) { - CInterfaceStubVtbl *svtbl = ProxyInfo->pStubVtblList[Index]; - unsigned long i, count = svtbl->header.DispatchTableCount; - /* Maybe the original vtbl is just modified directly to point at - * ObjectStublessClientXXX thunks in real Windows, but I don't like it - */ - TRACE("stubless thunks: count=%ld\n", count); - This->thunks = HeapAlloc(GetProcessHeap(),0,sizeof(struct StublessThunk)*count); - This->PVtbl = HeapAlloc(GetProcessHeap(),0,sizeof(LPVOID)*count); - for (i=0; ithunks[i]; - if (vtbl->Vtbl[i] == (LPVOID)-1) { - PFORMAT_STRING fs = stubless->ProcFormatString + stubless->FormatStringOffset[i]; - unsigned bytes = *(const WORD*)(fs+8) - STACK_ADJUST; - TRACE("method %ld: stacksize=%d\n", i, bytes); - FILL_STUBLESS(thunk, i, bytes) - This->PVtbl[i] = thunk; - } - else { - memset(thunk, 0, sizeof(struct StublessThunk)); - This->PVtbl[i] = vtbl->Vtbl[i]; - } - } - } - else - This->PVtbl = vtbl->Vtbl; - - This->lpVtbl = &StdProxy_Vtbl; - /* one reference for the proxy */ - This->RefCount = 1; - This->stubless = stubless; - This->piid = vtbl->header.piid; - This->pUnkOuter = pUnkOuter; - This->name = name; - This->pPSFactory = pPSFactory; - This->pChannel = NULL; - *ppProxy = (LPRPCPROXYBUFFER)&This->lpVtbl; - *ppvObj = &This->PVtbl; - /* if there is no outer unknown then the caller will control the lifetime - * of the proxy object through the proxy buffer, so no need to increment the - * ref count of the proxy object */ - if (pUnkOuter) - IUnknown_AddRef((IUnknown *)*ppvObj); - IPSFactoryBuffer_AddRef(pPSFactory); - - return S_OK; -} - -static void WINAPI StdProxy_Destruct(LPRPCPROXYBUFFER iface) -{ - ICOM_THIS_MULTI(StdProxyImpl,lpVtbl,iface); - - if (This->pChannel) - IRpcProxyBuffer_Disconnect(iface); - - IPSFactoryBuffer_Release(This->pPSFactory); - if (This->thunks) { - HeapFree(GetProcessHeap(),0,This->PVtbl); - HeapFree(GetProcessHeap(),0,This->thunks); - } - HeapFree(GetProcessHeap(),0,This); -} - -static HRESULT WINAPI StdProxy_QueryInterface(LPRPCPROXYBUFFER iface, - REFIID riid, - LPVOID *obj) -{ - ICOM_THIS_MULTI(StdProxyImpl,lpVtbl,iface); - TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(riid),obj); - - if (IsEqualGUID(&IID_IUnknown,riid) || - IsEqualGUID(This->piid,riid)) { - *obj = &This->PVtbl; - InterlockedIncrement(&This->RefCount); - return S_OK; - } - - if (IsEqualGUID(&IID_IRpcProxyBuffer,riid)) { - *obj = &This->lpVtbl; - InterlockedIncrement(&This->RefCount); - return S_OK; - } - - return E_NOINTERFACE; -} - -static ULONG WINAPI StdProxy_AddRef(LPRPCPROXYBUFFER iface) -{ - ICOM_THIS_MULTI(StdProxyImpl,lpVtbl,iface); - TRACE("(%p)->AddRef()\n",This); - - return InterlockedIncrement(&This->RefCount); -} - -static ULONG WINAPI StdProxy_Release(LPRPCPROXYBUFFER iface) -{ - ULONG refs; - ICOM_THIS_MULTI(StdProxyImpl,lpVtbl,iface); - TRACE("(%p)->Release()\n",This); - - refs = InterlockedDecrement(&This->RefCount); - if (!refs) - StdProxy_Destruct((LPRPCPROXYBUFFER)&This->lpVtbl); - return refs; -} - -static HRESULT WINAPI StdProxy_Connect(LPRPCPROXYBUFFER iface, - LPRPCCHANNELBUFFER pChannel) -{ - ICOM_THIS_MULTI(StdProxyImpl,lpVtbl,iface); - TRACE("(%p)->Connect(%p)\n",This,pChannel); - - This->pChannel = pChannel; - IRpcChannelBuffer_AddRef(pChannel); - return S_OK; -} - -static VOID WINAPI StdProxy_Disconnect(LPRPCPROXYBUFFER iface) -{ - ICOM_THIS_MULTI(StdProxyImpl,lpVtbl,iface); - TRACE("(%p)->Disconnect()\n",This); - - IRpcChannelBuffer_Release(This->pChannel); - This->pChannel = NULL; -} - -static const IRpcProxyBufferVtbl StdProxy_Vtbl = -{ - StdProxy_QueryInterface, - StdProxy_AddRef, - StdProxy_Release, - StdProxy_Connect, - StdProxy_Disconnect -}; - -static void StdProxy_GetChannel(LPVOID iface, - LPRPCCHANNELBUFFER *ppChannel) -{ - ICOM_THIS_MULTI(StdProxyImpl,PVtbl,iface); - TRACE("(%p)->GetChannel(%p) %s\n",This,ppChannel,This->name); - - *ppChannel = This->pChannel; -} - -static void StdProxy_GetIID(LPVOID iface, - const IID **ppiid) -{ - ICOM_THIS_MULTI(StdProxyImpl,PVtbl,iface); - TRACE("(%p)->GetIID(%p) %s\n",This,ppiid,This->name); - - *ppiid = This->piid; -} - -HRESULT WINAPI IUnknown_QueryInterface_Proxy(LPUNKNOWN iface, - REFIID riid, - LPVOID *ppvObj) -{ - ICOM_THIS_MULTI(StdProxyImpl,PVtbl,iface); - TRACE("(%p)->QueryInterface(%s,%p) %s\n",This,debugstr_guid(riid),ppvObj,This->name); - return IUnknown_QueryInterface(This->pUnkOuter,riid,ppvObj); -} - -ULONG WINAPI IUnknown_AddRef_Proxy(LPUNKNOWN iface) -{ - ICOM_THIS_MULTI(StdProxyImpl,PVtbl,iface); - TRACE("(%p)->AddRef() %s\n",This,This->name); - return IUnknown_AddRef(This->pUnkOuter); -} - -ULONG WINAPI IUnknown_Release_Proxy(LPUNKNOWN iface) -{ - ICOM_THIS_MULTI(StdProxyImpl,PVtbl,iface); - TRACE("(%p)->Release() %s\n",This,This->name); - return IUnknown_Release(This->pUnkOuter); -} - -/*********************************************************************** - * NdrProxyInitialize [RPCRT4.@] - */ -void WINAPI NdrProxyInitialize(void *This, - PRPC_MESSAGE pRpcMsg, - PMIDL_STUB_MESSAGE pStubMsg, - PMIDL_STUB_DESC pStubDescriptor, - unsigned int ProcNum) -{ - TRACE("(%p,%p,%p,%p,%d)\n", This, pRpcMsg, pStubMsg, pStubDescriptor, ProcNum); - NdrClientInitializeNew(pRpcMsg, pStubMsg, pStubDescriptor, ProcNum); - StdProxy_GetChannel(This, &pStubMsg->pRpcChannelBuffer); - IRpcChannelBuffer_GetDestCtx(pStubMsg->pRpcChannelBuffer, - &pStubMsg->dwDestContext, - &pStubMsg->pvDestContext); - TRACE("channel=%p\n", pStubMsg->pRpcChannelBuffer); -} - -/*********************************************************************** - * NdrProxyGetBuffer [RPCRT4.@] - */ -void WINAPI NdrProxyGetBuffer(void *This, - PMIDL_STUB_MESSAGE pStubMsg) -{ - HRESULT hr; - const IID *riid = NULL; - - TRACE("(%p,%p)\n", This, pStubMsg); - pStubMsg->RpcMsg->BufferLength = pStubMsg->BufferLength; - pStubMsg->dwStubPhase = PROXY_GETBUFFER; - StdProxy_GetIID(This, &riid); - hr = IRpcChannelBuffer_GetBuffer(pStubMsg->pRpcChannelBuffer, - (RPCOLEMESSAGE*)pStubMsg->RpcMsg, - riid); - if (FAILED(hr)) - { - RpcRaiseException(hr); - return; - } - pStubMsg->BufferStart = pStubMsg->RpcMsg->Buffer; - pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->BufferLength; - pStubMsg->Buffer = pStubMsg->BufferStart; - pStubMsg->dwStubPhase = PROXY_MARSHAL; -} - -/*********************************************************************** - * NdrProxySendReceive [RPCRT4.@] - */ -void WINAPI NdrProxySendReceive(void *This, - PMIDL_STUB_MESSAGE pStubMsg) -{ - ULONG Status = 0; - HRESULT hr; - - TRACE("(%p,%p)\n", This, pStubMsg); - - if (!pStubMsg->pRpcChannelBuffer) - { - WARN("Trying to use disconnected proxy %p\n", This); - RpcRaiseException(RPC_E_DISCONNECTED); - } - - pStubMsg->dwStubPhase = PROXY_SENDRECEIVE; - hr = IRpcChannelBuffer_SendReceive(pStubMsg->pRpcChannelBuffer, - (RPCOLEMESSAGE*)pStubMsg->RpcMsg, - &Status); - pStubMsg->dwStubPhase = PROXY_UNMARSHAL; - pStubMsg->BufferLength = pStubMsg->RpcMsg->BufferLength; - pStubMsg->BufferStart = pStubMsg->RpcMsg->Buffer; - pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->BufferLength; - pStubMsg->Buffer = pStubMsg->BufferStart; - - /* raise exception if call failed */ - if (hr == RPC_S_CALL_FAILED) RpcRaiseException(*(DWORD*)pStubMsg->Buffer); - else if (FAILED(hr)) RpcRaiseException(hr); -} - -/*********************************************************************** - * NdrProxyFreeBuffer [RPCRT4.@] - */ -void WINAPI NdrProxyFreeBuffer(void *This, - PMIDL_STUB_MESSAGE pStubMsg) -{ - HRESULT hr; - - TRACE("(%p,%p)\n", This, pStubMsg); - hr = IRpcChannelBuffer_FreeBuffer(pStubMsg->pRpcChannelBuffer, - (RPCOLEMESSAGE*)pStubMsg->RpcMsg); -} - -/*********************************************************************** - * NdrProxyErrorHandler [RPCRT4.@] - */ -HRESULT WINAPI NdrProxyErrorHandler(DWORD dwExceptionCode) -{ - WARN("(0x%08x): a proxy call failed\n", dwExceptionCode); - - if (FAILED(dwExceptionCode)) - return dwExceptionCode; - else - return HRESULT_FROM_WIN32(dwExceptionCode); -} - -HRESULT WINAPI -CreateProxyFromTypeInfo( LPTYPEINFO pTypeInfo, LPUNKNOWN pUnkOuter, REFIID riid, - LPRPCPROXYBUFFER *ppProxy, LPVOID *ppv ) -{ - typedef INT (WINAPI *MessageBoxA)(HWND,LPCSTR,LPCSTR,UINT); - HMODULE hUser32 = LoadLibraryA("user32"); - MessageBoxA pMessageBoxA = (void *)GetProcAddress(hUser32, "MessageBoxA"); - - FIXME("%p %p %s %p %p\n", pTypeInfo, pUnkOuter, debugstr_guid(riid), ppProxy, ppv); - if (pMessageBoxA) - { - pMessageBoxA(NULL, - "The native implementation of OLEAUT32.DLL cannot be used " - "with Wine's RPCRT4.DLL. Remove OLEAUT32.DLL and try again.\n", - "Wine: Unimplemented CreateProxyFromTypeInfo", - 0x10); - ExitProcess(1); - } - return E_NOTIMPL; -} diff --git a/reactos/dll/win32/rpcrt4_new/cpsf.c b/reactos/dll/win32/rpcrt4_new/cpsf.c deleted file mode 100644 index dcf37219195..00000000000 --- a/reactos/dll/win32/rpcrt4_new/cpsf.c +++ /dev/null @@ -1,307 +0,0 @@ -/* - * COM proxy/stub factory (CStdPSFactory) implementation - * - * Copyright 2001 Ove Kåven, TransGaming Technologies - * - * 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 -#include -#include - -#define COBJMACROS - -#include "windef.h" -#include "winbase.h" -#include "winerror.h" -#include "winreg.h" - -#include "objbase.h" - -#include "rpcproxy.h" - -#include "wine/debug.h" - -#include "cpsf.h" - -WINE_DEFAULT_DEBUG_CHANNEL(ole); - -static BOOL FindProxyInfo(const ProxyFileInfo **pProxyFileList, REFIID riid, const ProxyFileInfo **pProxyInfo, int *pIndex) -{ - while (*pProxyFileList) { - if ((*pProxyFileList)->pIIDLookupRtn(riid, pIndex)) { - *pProxyInfo = *pProxyFileList; - TRACE("found: ProxyInfo %p Index %d\n", *pProxyInfo, *pIndex); - return TRUE; - } - pProxyFileList++; - } - TRACE("not found\n"); - return FALSE; -} - -static HRESULT WINAPI CStdPSFactory_QueryInterface(LPPSFACTORYBUFFER iface, - REFIID riid, - LPVOID *obj) -{ - CStdPSFactoryBuffer *This = (CStdPSFactoryBuffer *)iface; - TRACE("(%p)->QueryInterface(%s,%p)\n",iface,debugstr_guid(riid),obj); - if (IsEqualGUID(&IID_IUnknown,riid) || - IsEqualGUID(&IID_IPSFactoryBuffer,riid)) { - *obj = This; - This->RefCount++; - return S_OK; - } - return E_NOINTERFACE; -} - -static ULONG WINAPI CStdPSFactory_AddRef(LPPSFACTORYBUFFER iface) -{ - CStdPSFactoryBuffer *This = (CStdPSFactoryBuffer *)iface; - TRACE("(%p)->AddRef()\n",iface); - return ++(This->RefCount); -} - -static ULONG WINAPI CStdPSFactory_Release(LPPSFACTORYBUFFER iface) -{ - CStdPSFactoryBuffer *This = (CStdPSFactoryBuffer *)iface; - TRACE("(%p)->Release()\n",iface); - return --(This->RefCount); -} - -static HRESULT WINAPI CStdPSFactory_CreateProxy(LPPSFACTORYBUFFER iface, - LPUNKNOWN pUnkOuter, - REFIID riid, - LPRPCPROXYBUFFER *ppProxy, - LPVOID *ppv) -{ - CStdPSFactoryBuffer *This = (CStdPSFactoryBuffer *)iface; - const ProxyFileInfo *ProxyInfo; - int Index; - TRACE("(%p)->CreateProxy(%p,%s,%p,%p)\n",iface,pUnkOuter, - debugstr_guid(riid),ppProxy,ppv); - if (!FindProxyInfo(This->pProxyFileList,riid,&ProxyInfo,&Index)) - return E_NOINTERFACE; - return StdProxy_Construct(riid, pUnkOuter, ProxyInfo, Index, iface, ppProxy, ppv); -} - -static HRESULT WINAPI CStdPSFactory_CreateStub(LPPSFACTORYBUFFER iface, - REFIID riid, - LPUNKNOWN pUnkServer, - LPRPCSTUBBUFFER *ppStub) -{ - CStdPSFactoryBuffer *This = (CStdPSFactoryBuffer *)iface; - const ProxyFileInfo *ProxyInfo; - int Index; - TRACE("(%p)->CreateStub(%s,%p,%p)\n",iface,debugstr_guid(riid), - pUnkServer,ppStub); - if (!FindProxyInfo(This->pProxyFileList,riid,&ProxyInfo,&Index)) - return E_NOINTERFACE; - - if(ProxyInfo->pDelegatedIIDs && ProxyInfo->pDelegatedIIDs[Index]) - return CStdStubBuffer_Delegating_Construct(riid, pUnkServer, ProxyInfo->pNamesArray[Index], - ProxyInfo->pStubVtblList[Index], ProxyInfo->pDelegatedIIDs[Index], - iface, ppStub); - - return CStdStubBuffer_Construct(riid, pUnkServer, ProxyInfo->pNamesArray[Index], - ProxyInfo->pStubVtblList[Index], iface, ppStub); -} - -static const IPSFactoryBufferVtbl CStdPSFactory_Vtbl = -{ - CStdPSFactory_QueryInterface, - CStdPSFactory_AddRef, - CStdPSFactory_Release, - CStdPSFactory_CreateProxy, - CStdPSFactory_CreateStub -}; - -/*********************************************************************** - * NdrDllGetClassObject [RPCRT4.@] - */ -HRESULT WINAPI NdrDllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv, - const ProxyFileInfo **pProxyFileList, - const CLSID *pclsid, - CStdPSFactoryBuffer *pPSFactoryBuffer) -{ - TRACE("(%s, %s, %p, %p, %s, %p)\n", debugstr_guid(rclsid), - debugstr_guid(iid), ppv, pProxyFileList, debugstr_guid(pclsid), - pPSFactoryBuffer); - - *ppv = NULL; - if (!pPSFactoryBuffer->lpVtbl) { - const ProxyFileInfo **pProxyFileList2; - int max_delegating_vtbl_size = 0; - pPSFactoryBuffer->lpVtbl = &CStdPSFactory_Vtbl; - pPSFactoryBuffer->RefCount = 0; - pPSFactoryBuffer->pProxyFileList = pProxyFileList; - for (pProxyFileList2 = pProxyFileList; *pProxyFileList2; pProxyFileList2++) { - int i; - for (i = 0; i < (*pProxyFileList2)->TableSize; i++) { - /* FIXME: i think that different vtables should be copied for - * async interfaces */ - void * const *pSrcRpcStubVtbl = (void * const *)&CStdStubBuffer_Vtbl; - void **pRpcStubVtbl = (void **)&(*pProxyFileList2)->pStubVtblList[i]->Vtbl; - int j; - - if ((*pProxyFileList2)->pDelegatedIIDs && (*pProxyFileList2)->pDelegatedIIDs[i]) { - pSrcRpcStubVtbl = (void * const *)&CStdStubBuffer_Delegating_Vtbl; - if ((*pProxyFileList2)->pStubVtblList[i]->header.DispatchTableCount > max_delegating_vtbl_size) - max_delegating_vtbl_size = (*pProxyFileList2)->pStubVtblList[i]->header.DispatchTableCount; - } - - for (j = 0; j < sizeof(IRpcStubBufferVtbl)/sizeof(void *); j++) - if (!pRpcStubVtbl[j]) - pRpcStubVtbl[j] = pSrcRpcStubVtbl[j]; - } - } - if(max_delegating_vtbl_size > 0) - create_delegating_vtbl(max_delegating_vtbl_size); - } - if (IsEqualGUID(rclsid, pclsid)) - return IPSFactoryBuffer_QueryInterface((LPPSFACTORYBUFFER)pPSFactoryBuffer, iid, ppv); - else { - const ProxyFileInfo *info; - int index; - /* otherwise, the dll may be using the iid as the clsid, so - * search for it in the proxy file list */ - if (FindProxyInfo(pProxyFileList, rclsid, &info, &index)) - return IPSFactoryBuffer_QueryInterface((LPPSFACTORYBUFFER)pPSFactoryBuffer, iid, ppv); - - WARN("class %s not available\n", debugstr_guid(rclsid)); - return CLASS_E_CLASSNOTAVAILABLE; - } -} - -/*********************************************************************** - * NdrDllCanUnloadNow [RPCRT4.@] - */ -HRESULT WINAPI NdrDllCanUnloadNow(CStdPSFactoryBuffer *pPSFactoryBuffer) -{ - return !(pPSFactoryBuffer->RefCount); -} - -/*********************************************************************** - * NdrDllRegisterProxy [RPCRT4.@] - */ -HRESULT WINAPI NdrDllRegisterProxy(HMODULE hDll, - const ProxyFileInfo **pProxyFileList, - const CLSID *pclsid) -{ - LPSTR clsid; - char keyname[120], module[MAX_PATH]; - HKEY key, subkey; - DWORD len; - - TRACE("(%p,%p,%s)\n", hDll, pProxyFileList, debugstr_guid(pclsid)); - UuidToStringA((UUID*)pclsid, (unsigned char**)&clsid); - - /* register interfaces to point to clsid */ - while (*pProxyFileList) { - unsigned u; - for (u=0; u<(*pProxyFileList)->TableSize; u++) { - CInterfaceStubVtbl *proxy = (*pProxyFileList)->pStubVtblList[u]; - PCInterfaceName name = (*pProxyFileList)->pNamesArray[u]; - LPSTR iid; - - TRACE("registering %s %s => %s\n", name, debugstr_guid(proxy->header.piid), clsid); - - UuidToStringA((UUID*)proxy->header.piid, (unsigned char**)&iid); - snprintf(keyname, sizeof(keyname), "Interface\\{%s}", iid); - RpcStringFreeA((unsigned char**)&iid); - if (RegCreateKeyExA(HKEY_CLASSES_ROOT, keyname, 0, NULL, 0, - KEY_WRITE, NULL, &key, NULL) == ERROR_SUCCESS) { - if (name) - RegSetValueExA(key, NULL, 0, REG_SZ, (const BYTE *)name, strlen(name)); - if (RegCreateKeyExA(key, "ProxyStubClsid32", 0, NULL, 0, - KEY_WRITE, NULL, &subkey, NULL) == ERROR_SUCCESS) { - snprintf(module, sizeof(module), "{%s}", clsid); - RegSetValueExA(subkey, NULL, 0, REG_SZ, (LPBYTE)module, strlen(module)); - RegCloseKey(subkey); - } - RegCloseKey(key); - } - } - pProxyFileList++; - } - - /* register clsid to point to module */ - snprintf(keyname, sizeof(keyname), "CLSID\\{%s}", clsid); - len = GetModuleFileNameA(hDll, module, sizeof(module)); - if (len && len < sizeof(module)) { - TRACE("registering CLSID %s => %s\n", clsid, module); - if (RegCreateKeyExA(HKEY_CLASSES_ROOT, keyname, 0, NULL, 0, - KEY_WRITE, NULL, &key, NULL) == ERROR_SUCCESS) { - RegSetValueExA(subkey, NULL, 0, REG_SZ, (const BYTE *)"PSFactoryBuffer", strlen("PSFactoryBuffer")); - if (RegCreateKeyExA(key, "InProcServer32", 0, NULL, 0, - KEY_WRITE, NULL, &subkey, NULL) == ERROR_SUCCESS) { - RegSetValueExA(subkey, NULL, 0, REG_SZ, (LPBYTE)module, strlen(module)); - RegSetValueExA(subkey, "ThreadingModel", 0, REG_SZ, (const BYTE *)"Both", strlen("Both")); - RegCloseKey(subkey); - } - RegCloseKey(key); - } - } - - /* done */ - RpcStringFreeA((unsigned char**)&clsid); - return S_OK; -} - -/*********************************************************************** - * NdrDllUnregisterProxy [RPCRT4.@] - */ -HRESULT WINAPI NdrDllUnregisterProxy(HMODULE hDll, - const ProxyFileInfo **pProxyFileList, - const CLSID *pclsid) -{ - LPSTR clsid; - char keyname[120], module[MAX_PATH]; - DWORD len; - - TRACE("(%p,%p,%s)\n", hDll, pProxyFileList, debugstr_guid(pclsid)); - UuidToStringA((UUID*)pclsid, (unsigned char**)&clsid); - - /* unregister interfaces */ - while (*pProxyFileList) { - unsigned u; - for (u=0; u<(*pProxyFileList)->TableSize; u++) { - CInterfaceStubVtbl *proxy = (*pProxyFileList)->pStubVtblList[u]; - PCInterfaceName name = (*pProxyFileList)->pNamesArray[u]; - LPSTR iid; - - TRACE("unregistering %s %s <= %s\n", name, debugstr_guid(proxy->header.piid), clsid); - - UuidToStringA((UUID*)proxy->header.piid, (unsigned char**)&iid); - snprintf(keyname, sizeof(keyname), "Interface\\{%s}", iid); - RpcStringFreeA((unsigned char**)&iid); - RegDeleteKeyA(HKEY_CLASSES_ROOT, keyname); - } - pProxyFileList++; - } - - /* unregister clsid */ - snprintf(keyname, sizeof(keyname), "CLSID\\{%s}", clsid); - len = GetModuleFileNameA(hDll, module, sizeof(module)); - if (len && len < sizeof(module)) { - TRACE("unregistering CLSID %s <= %s\n", clsid, module); - RegDeleteKeyA(HKEY_CLASSES_ROOT, keyname); - } - - /* done */ - RpcStringFreeA((unsigned char**)&clsid); - return S_OK; -} diff --git a/reactos/dll/win32/rpcrt4_new/cpsf.h b/reactos/dll/win32/rpcrt4_new/cpsf.h deleted file mode 100644 index 5ce8fe6575e..00000000000 --- a/reactos/dll/win32/rpcrt4_new/cpsf.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * COM proxy definitions - * - * Copyright 2001 Ove Kåven, TransGaming Technologies - * - * 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 - */ - -#ifndef __WINE_CPSF_H -#define __WINE_CPSF_H - -HRESULT WINAPI StdProxy_Construct(REFIID riid, - LPUNKNOWN pUnkOuter, - const ProxyFileInfo *ProxyInfo, - int Index, - LPPSFACTORYBUFFER pPSFactory, - LPRPCPROXYBUFFER *ppProxy, - LPVOID *ppvObj); - -HRESULT WINAPI CStdStubBuffer_Construct(REFIID riid, - LPUNKNOWN pUnkServer, - PCInterfaceName name, - CInterfaceStubVtbl *vtbl, - LPPSFACTORYBUFFER pPSFactory, - LPRPCSTUBBUFFER *ppStub); - -HRESULT WINAPI CStdStubBuffer_Delegating_Construct(REFIID riid, - LPUNKNOWN pUnkServer, - PCInterfaceName name, - CInterfaceStubVtbl *vtbl, - REFIID delegating_iid, - LPPSFACTORYBUFFER pPSFactory, - LPRPCSTUBBUFFER *ppStub); - -const MIDL_SERVER_INFO *CStdStubBuffer_GetServerInfo(IRpcStubBuffer *iface); - -const IRpcStubBufferVtbl CStdStubBuffer_Vtbl; -const IRpcStubBufferVtbl CStdStubBuffer_Delegating_Vtbl; - -void create_delegating_vtbl(DWORD num_methods); - -HRESULT create_stub(REFIID iid, IUnknown *pUnk, IRpcStubBuffer **ppstub); - -#endif /* __WINE_CPSF_H */ diff --git a/reactos/dll/win32/rpcrt4_new/cstub.c b/reactos/dll/win32/rpcrt4_new/cstub.c deleted file mode 100644 index cd07c297390..00000000000 --- a/reactos/dll/win32/rpcrt4_new/cstub.c +++ /dev/null @@ -1,599 +0,0 @@ -/* - * COM stub (CStdStubBuffer) implementation - * - * Copyright 2001 Ove Kåven, TransGaming Technologies - * - * 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 - -#define COBJMACROS - -#include "windef.h" -#include "winbase.h" -#include "winerror.h" -#include "excpt.h" - -#include "objbase.h" -#include "rpcproxy.h" - -#include "wine/debug.h" -#include "wine/exception.h" - -#include "cpsf.h" - -WINE_DEFAULT_DEBUG_CHANNEL(ole); - -#define STUB_HEADER(This) (((const CInterfaceStubHeader*)((This)->lpVtbl))[-1]) - -static WINE_EXCEPTION_FILTER(stub_filter) -{ - if (GetExceptionInformation()->ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE) - return EXCEPTION_CONTINUE_SEARCH; - return EXCEPTION_EXECUTE_HANDLER; -} - -typedef struct -{ - IUnknownVtbl *base_obj; - IRpcStubBuffer *base_stub; - CStdStubBuffer stub_buffer; -} cstdstubbuffer_delegating_t; - -static inline cstdstubbuffer_delegating_t *impl_from_delegating( IRpcStubBuffer *iface ) -{ - return (cstdstubbuffer_delegating_t*)((char *)iface - FIELD_OFFSET(cstdstubbuffer_delegating_t, stub_buffer)); -} - -HRESULT WINAPI CStdStubBuffer_Construct(REFIID riid, - LPUNKNOWN pUnkServer, - PCInterfaceName name, - CInterfaceStubVtbl *vtbl, - LPPSFACTORYBUFFER pPSFactory, - LPRPCSTUBBUFFER *ppStub) -{ - CStdStubBuffer *This; - IUnknown *pvServer; - HRESULT r; - TRACE("(%p,%p,%p,%p) %s\n", pUnkServer, vtbl, pPSFactory, ppStub, name); - TRACE("iid=%s\n", debugstr_guid(vtbl->header.piid)); - TRACE("vtbl=%p\n", &vtbl->Vtbl); - - if (!IsEqualGUID(vtbl->header.piid, riid)) { - ERR("IID mismatch during stub creation\n"); - return RPC_E_UNEXPECTED; - } - - r = IUnknown_QueryInterface(pUnkServer, riid, (void**)&pvServer); - if(FAILED(r)) - return r; - - This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(CStdStubBuffer)); - if (!This) { - IUnknown_Release(pvServer); - return E_OUTOFMEMORY; - } - - This->lpVtbl = &vtbl->Vtbl; - This->RefCount = 1; - This->pvServerObject = pvServer; - This->pPSFactory = pPSFactory; - *ppStub = (LPRPCSTUBBUFFER)This; - - IPSFactoryBuffer_AddRef(pPSFactory); - return S_OK; -} - -static CRITICAL_SECTION delegating_vtbl_section; -static CRITICAL_SECTION_DEBUG critsect_debug = -{ - 0, 0, &delegating_vtbl_section, - { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList }, - 0, 0, { (DWORD_PTR)(__FILE__ ": delegating_vtbl_section") } -}; -static CRITICAL_SECTION delegating_vtbl_section = { &critsect_debug, -1, 0, 0, 0, 0 }; - -typedef struct -{ - DWORD ref; - DWORD size; - void **methods; - IUnknownVtbl vtbl; - /* remaining entries in vtbl */ -} ref_counted_vtbl; - -static struct -{ - ref_counted_vtbl *table; -} current_vtbl; - - -static HRESULT WINAPI delegating_QueryInterface(IUnknown *pUnk, REFIID iid, void **ppv) -{ - *ppv = (void *)pUnk; - return S_OK; -} - -static ULONG WINAPI delegating_AddRef(IUnknown *pUnk) -{ - return 1; -} - -static ULONG WINAPI delegating_Release(IUnknown *pUnk) -{ - return 1; -} - -#if defined(__i386__) - -/* The idea here is to replace the first param on the stack - ie. This (which will point to cstdstubbuffer_delegating_t) - with This->stub_buffer.pvServerObject and then jump to the - relevant offset in This->stub_buffer.pvServerObject's vtbl. -*/ -#include "pshpack1.h" -typedef struct { - DWORD mov1; /* mov 0x4(%esp), %eax 8b 44 24 04 */ - WORD mov2; /* mov 0x10(%eax), %eax 8b 40 */ - BYTE sixteen; /* 10 */ - DWORD mov3; /* mov %eax, 0x4(%esp) 89 44 24 04 */ - WORD mov4; /* mov (%eax), %eax 8b 00 */ - WORD mov5; /* mov offset(%eax), %eax 8b 80 */ - DWORD offset; /* xx xx xx xx */ - WORD jmp; /* jmp *%eax ff e0 */ - BYTE pad[3]; /* lea 0x0(%esi), %esi 8d 76 00 */ -} vtbl_method_t; -#include "poppack.h" - -static void fill_table(IUnknownVtbl *vtbl, void **methods, DWORD num) -{ - vtbl_method_t *method; - void **entry; - DWORD i; - - vtbl->QueryInterface = delegating_QueryInterface; - vtbl->AddRef = delegating_AddRef; - vtbl->Release = delegating_Release; - - method = (vtbl_method_t*)methods; - entry = (void**)(vtbl + 1); - - for(i = 3; i < num; i++) - { - *entry = method; - method->mov1 = 0x0424448b; - method->mov2 = 0x408b; - method->sixteen = 0x10; - method->mov3 = 0x04244489; - method->mov4 = 0x008b; - method->mov5 = 0x808b; - method->offset = i << 2; - method->jmp = 0xe0ff; - method->pad[0] = 0x8d; - method->pad[1] = 0x76; - method->pad[2] = 0x00; - - method++; - entry++; - } -} - -#else /* __i386__ */ - -typedef struct {int dummy;} vtbl_method_t; -static void fill_table(IUnknownVtbl *vtbl, DWORD num) -{ - ERR("delegated stubs are not supported on this architecture\n"); -} - -#endif /* __i386__ */ - -void create_delegating_vtbl(DWORD num_methods) -{ - TRACE("%d\n", num_methods); - if(num_methods <= 3) - { - ERR("should have more than %d methods\n", num_methods); - return; - } - - EnterCriticalSection(&delegating_vtbl_section); - if(!current_vtbl.table || num_methods > current_vtbl.table->size) - { - DWORD size; - DWORD old_protect; - if(current_vtbl.table && current_vtbl.table->ref == 0) - { - TRACE("freeing old table\n"); - VirtualFree(current_vtbl.table->methods, - (current_vtbl.table->size - 3) * sizeof(vtbl_method_t), - MEM_RELEASE); - HeapFree(GetProcessHeap(), 0, current_vtbl.table); - } - size = (num_methods - 3) * sizeof(vtbl_method_t); - current_vtbl.table = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(ref_counted_vtbl, vtbl) + num_methods * sizeof(void*)); - current_vtbl.table->ref = 0; - current_vtbl.table->size = num_methods; - current_vtbl.table->methods = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); - fill_table(¤t_vtbl.table->vtbl, current_vtbl.table->methods, num_methods); - VirtualProtect(current_vtbl.table->methods, size, PAGE_EXECUTE_READ, &old_protect); - } - LeaveCriticalSection(&delegating_vtbl_section); -} - -static IUnknownVtbl *get_delegating_vtbl(void) -{ - IUnknownVtbl *ret; - - EnterCriticalSection(&delegating_vtbl_section); - current_vtbl.table->ref++; - ret = ¤t_vtbl.table->vtbl; - LeaveCriticalSection(&delegating_vtbl_section); - return ret; -} - -static void release_delegating_vtbl(IUnknownVtbl *vtbl) -{ - ref_counted_vtbl *table = (ref_counted_vtbl*)((DWORD *)vtbl - 1); - - EnterCriticalSection(&delegating_vtbl_section); - table->ref--; - TRACE("ref now %d\n", table->ref); - if(table->ref == 0 && table != current_vtbl.table) - { - TRACE("... and we're not current so free'ing\n"); - VirtualFree(current_vtbl.table->methods, - (current_vtbl.table->size - 3) * sizeof(vtbl_method_t), - MEM_RELEASE); - HeapFree(GetProcessHeap(), 0, table); - } - LeaveCriticalSection(&delegating_vtbl_section); -} - -HRESULT WINAPI CStdStubBuffer_Delegating_Construct(REFIID riid, - LPUNKNOWN pUnkServer, - PCInterfaceName name, - CInterfaceStubVtbl *vtbl, - REFIID delegating_iid, - LPPSFACTORYBUFFER pPSFactory, - LPRPCSTUBBUFFER *ppStub) -{ - cstdstubbuffer_delegating_t *This; - IUnknown *pvServer; - HRESULT r; - - TRACE("(%p,%p,%p,%p) %s\n", pUnkServer, vtbl, pPSFactory, ppStub, name); - TRACE("iid=%s delegating to %s\n", debugstr_guid(vtbl->header.piid), debugstr_guid(delegating_iid)); - TRACE("vtbl=%p\n", &vtbl->Vtbl); - - if (!IsEqualGUID(vtbl->header.piid, riid)) - { - ERR("IID mismatch during stub creation\n"); - return RPC_E_UNEXPECTED; - } - - r = IUnknown_QueryInterface(pUnkServer, riid, (void**)&pvServer); - if(FAILED(r)) return r; - - This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*This)); - if (!This) - { - IUnknown_Release(pvServer); - return E_OUTOFMEMORY; - } - - This->base_obj = get_delegating_vtbl(); - r = create_stub(delegating_iid, (IUnknown*)&This->base_obj, &This->base_stub); - if(FAILED(r)) - { - release_delegating_vtbl(This->base_obj); - HeapFree(GetProcessHeap(), 0, This); - IUnknown_Release(pvServer); - return r; - } - - This->stub_buffer.lpVtbl = &vtbl->Vtbl; - This->stub_buffer.RefCount = 1; - This->stub_buffer.pvServerObject = pvServer; - This->stub_buffer.pPSFactory = pPSFactory; - *ppStub = (LPRPCSTUBBUFFER)&This->stub_buffer; - - IPSFactoryBuffer_AddRef(pPSFactory); - return S_OK; -} - -HRESULT WINAPI CStdStubBuffer_QueryInterface(LPRPCSTUBBUFFER iface, - REFIID riid, - LPVOID *obj) -{ - CStdStubBuffer *This = (CStdStubBuffer *)iface; - TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(riid),obj); - - if (IsEqualIID(&IID_IUnknown, riid) || - IsEqualIID(&IID_IRpcStubBuffer, riid)) - { - IUnknown_AddRef(iface); - *obj = iface; - return S_OK; - } - *obj = NULL; - return E_NOINTERFACE; -} - -ULONG WINAPI CStdStubBuffer_AddRef(LPRPCSTUBBUFFER iface) -{ - CStdStubBuffer *This = (CStdStubBuffer *)iface; - TRACE("(%p)->AddRef()\n",This); - return InterlockedIncrement(&This->RefCount); -} - -ULONG WINAPI NdrCStdStubBuffer_Release(LPRPCSTUBBUFFER iface, - LPPSFACTORYBUFFER pPSF) -{ - CStdStubBuffer *This = (CStdStubBuffer *)iface; - ULONG refs; - - TRACE("(%p)->Release()\n",This); - - refs = InterlockedDecrement(&This->RefCount); - if (!refs) - { - /* test_Release shows that native doesn't call Disconnect here. - We'll leave it in for the time being. */ - IRpcStubBuffer_Disconnect(iface); - - IPSFactoryBuffer_Release(pPSF); - HeapFree(GetProcessHeap(),0,This); - } - return refs; -} - -ULONG WINAPI NdrCStdStubBuffer2_Release(LPRPCSTUBBUFFER iface, - LPPSFACTORYBUFFER pPSF) -{ - cstdstubbuffer_delegating_t *This = impl_from_delegating( iface ); - ULONG refs; - - TRACE("(%p)->Release()\n", This); - - refs = InterlockedDecrement(&This->stub_buffer.RefCount); - if (!refs) - { - /* Just like NdrCStdStubBuffer_Release, we shouldn't call - Disconnect here */ - IRpcStubBuffer_Disconnect((IRpcStubBuffer *)&This->stub_buffer); - - IRpcStubBuffer_Release(This->base_stub); - release_delegating_vtbl(This->base_obj); - - IPSFactoryBuffer_Release(pPSF); - HeapFree(GetProcessHeap(), 0, This); - } - - return refs; -} - -HRESULT WINAPI CStdStubBuffer_Connect(LPRPCSTUBBUFFER iface, - LPUNKNOWN lpUnkServer) -{ - CStdStubBuffer *This = (CStdStubBuffer *)iface; - HRESULT r; - IUnknown *new = NULL; - - TRACE("(%p)->Connect(%p)\n",This,lpUnkServer); - - r = IUnknown_QueryInterface(lpUnkServer, STUB_HEADER(This).piid, (void**)&new); - new = InterlockedExchangePointer((void**)&This->pvServerObject, new); - if(new) - IUnknown_Release(new); - return r; -} - -void WINAPI CStdStubBuffer_Disconnect(LPRPCSTUBBUFFER iface) -{ - CStdStubBuffer *This = (CStdStubBuffer *)iface; - IUnknown *old; - TRACE("(%p)->Disconnect()\n",This); - - old = InterlockedExchangePointer((void**)&This->pvServerObject, NULL); - - if(old) - IUnknown_Release(old); -} - -HRESULT WINAPI CStdStubBuffer_Invoke(LPRPCSTUBBUFFER iface, - PRPCOLEMESSAGE pMsg, - LPRPCCHANNELBUFFER pChannel) -{ - CStdStubBuffer *This = (CStdStubBuffer *)iface; - DWORD dwPhase = STUB_UNMARSHAL; - HRESULT hr = S_OK; - - TRACE("(%p)->Invoke(%p,%p)\n",This,pMsg,pChannel); - - __TRY - { - if (STUB_HEADER(This).pDispatchTable) - STUB_HEADER(This).pDispatchTable[pMsg->iMethod](iface, pChannel, (PRPC_MESSAGE)pMsg, &dwPhase); - else /* pure interpreted */ - NdrStubCall2(iface, pChannel, (PRPC_MESSAGE)pMsg, &dwPhase); - } - __EXCEPT(stub_filter) - { - DWORD dwExceptionCode = GetExceptionCode(); - WARN("a stub call failed with exception 0x%08x (%d)\n", dwExceptionCode, dwExceptionCode); - if (FAILED(dwExceptionCode)) - hr = dwExceptionCode; - else - hr = HRESULT_FROM_WIN32(dwExceptionCode); - } - __ENDTRY - - return hr; -} - -LPRPCSTUBBUFFER WINAPI CStdStubBuffer_IsIIDSupported(LPRPCSTUBBUFFER iface, - REFIID riid) -{ - CStdStubBuffer *This = (CStdStubBuffer *)iface; - TRACE("(%p)->IsIIDSupported(%s)\n",This,debugstr_guid(riid)); - return IsEqualGUID(STUB_HEADER(This).piid, riid) ? iface : NULL; -} - -ULONG WINAPI CStdStubBuffer_CountRefs(LPRPCSTUBBUFFER iface) -{ - CStdStubBuffer *This = (CStdStubBuffer *)iface; - TRACE("(%p)->CountRefs()\n",This); - return This->RefCount; -} - -HRESULT WINAPI CStdStubBuffer_DebugServerQueryInterface(LPRPCSTUBBUFFER iface, - LPVOID *ppv) -{ - CStdStubBuffer *This = (CStdStubBuffer *)iface; - TRACE("(%p)->DebugServerQueryInterface(%p)\n",This,ppv); - return S_OK; -} - -void WINAPI CStdStubBuffer_DebugServerRelease(LPRPCSTUBBUFFER iface, - LPVOID pv) -{ - CStdStubBuffer *This = (CStdStubBuffer *)iface; - TRACE("(%p)->DebugServerRelease(%p)\n",This,pv); -} - -const IRpcStubBufferVtbl CStdStubBuffer_Vtbl = -{ - CStdStubBuffer_QueryInterface, - CStdStubBuffer_AddRef, - NULL, - CStdStubBuffer_Connect, - CStdStubBuffer_Disconnect, - CStdStubBuffer_Invoke, - CStdStubBuffer_IsIIDSupported, - CStdStubBuffer_CountRefs, - CStdStubBuffer_DebugServerQueryInterface, - CStdStubBuffer_DebugServerRelease -}; - -static HRESULT WINAPI CStdStubBuffer_Delegating_Connect(LPRPCSTUBBUFFER iface, - LPUNKNOWN lpUnkServer) -{ - cstdstubbuffer_delegating_t *This = impl_from_delegating(iface); - HRESULT r; - TRACE("(%p)->Connect(%p)\n", This, lpUnkServer); - - r = CStdStubBuffer_Connect(iface, lpUnkServer); - if(SUCCEEDED(r)) - r = IRpcStubBuffer_Connect(This->base_stub, (IUnknown*)&This->base_obj); - - return r; -} - -static void WINAPI CStdStubBuffer_Delegating_Disconnect(LPRPCSTUBBUFFER iface) -{ - cstdstubbuffer_delegating_t *This = impl_from_delegating(iface); - TRACE("(%p)->Disconnect()\n", This); - - IRpcStubBuffer_Disconnect(This->base_stub); - CStdStubBuffer_Disconnect(iface); -} - -static ULONG WINAPI CStdStubBuffer_Delegating_CountRefs(LPRPCSTUBBUFFER iface) -{ - cstdstubbuffer_delegating_t *This = impl_from_delegating(iface); - ULONG ret; - TRACE("(%p)->CountRefs()\n", This); - - ret = CStdStubBuffer_CountRefs(iface); - ret += IRpcStubBuffer_CountRefs(This->base_stub); - - return ret; -} - -const IRpcStubBufferVtbl CStdStubBuffer_Delegating_Vtbl = -{ - CStdStubBuffer_QueryInterface, - CStdStubBuffer_AddRef, - NULL, - CStdStubBuffer_Delegating_Connect, - CStdStubBuffer_Delegating_Disconnect, - CStdStubBuffer_Invoke, - CStdStubBuffer_IsIIDSupported, - CStdStubBuffer_Delegating_CountRefs, - CStdStubBuffer_DebugServerQueryInterface, - CStdStubBuffer_DebugServerRelease -}; - -const MIDL_SERVER_INFO *CStdStubBuffer_GetServerInfo(IRpcStubBuffer *iface) -{ - CStdStubBuffer *This = (CStdStubBuffer *)iface; - return STUB_HEADER(This).pServerInfo; -} - -/************************************************************************ - * NdrStubForwardingFunction [RPCRT4.@] - */ -void __RPC_STUB NdrStubForwardingFunction( IRpcStubBuffer *iface, IRpcChannelBuffer *pChannel, - PRPC_MESSAGE pMsg, DWORD *pdwStubPhase ) -{ - /* Note pMsg is passed intact since RPCOLEMESSAGE is basically a RPC_MESSAGE. */ - - cstdstubbuffer_delegating_t *This = impl_from_delegating(iface); - HRESULT r = IRpcStubBuffer_Invoke(This->base_stub, (RPCOLEMESSAGE*)pMsg, pChannel); - if(FAILED(r)) RpcRaiseException(r); - return; -} - -/*********************************************************************** - * NdrStubInitialize [RPCRT4.@] - */ -void WINAPI NdrStubInitialize(PRPC_MESSAGE pRpcMsg, - PMIDL_STUB_MESSAGE pStubMsg, - PMIDL_STUB_DESC pStubDescriptor, - LPRPCCHANNELBUFFER pRpcChannelBuffer) -{ - TRACE("(%p,%p,%p,%p)\n", pRpcMsg, pStubMsg, pStubDescriptor, pRpcChannelBuffer); - NdrServerInitializeNew(pRpcMsg, pStubMsg, pStubDescriptor); - pStubMsg->pRpcChannelBuffer = pRpcChannelBuffer; - IRpcChannelBuffer_GetDestCtx(pStubMsg->pRpcChannelBuffer, - &pStubMsg->dwDestContext, - &pStubMsg->pvDestContext); -} - -/*********************************************************************** - * NdrStubGetBuffer [RPCRT4.@] - */ -void WINAPI NdrStubGetBuffer(LPRPCSTUBBUFFER iface, - LPRPCCHANNELBUFFER pRpcChannelBuffer, - PMIDL_STUB_MESSAGE pStubMsg) -{ - CStdStubBuffer *This = (CStdStubBuffer *)iface; - HRESULT hr; - - TRACE("(%p, %p, %p)\n", This, pRpcChannelBuffer, pStubMsg); - - pStubMsg->RpcMsg->BufferLength = pStubMsg->BufferLength; - hr = IRpcChannelBuffer_GetBuffer(pRpcChannelBuffer, - (RPCOLEMESSAGE *)pStubMsg->RpcMsg, STUB_HEADER(This).piid); - if (FAILED(hr)) - { - RpcRaiseException(hr); - return; - } - - pStubMsg->Buffer = pStubMsg->RpcMsg->Buffer; -} diff --git a/reactos/dll/win32/rpcrt4_new/ndr_marshall.c b/reactos/dll/win32/rpcrt4_new/ndr_marshall.c deleted file mode 100644 index 3b6106fe7c5..00000000000 --- a/reactos/dll/win32/rpcrt4_new/ndr_marshall.c +++ /dev/null @@ -1,6334 +0,0 @@ -/* - * NDR data marshalling - * - * Copyright 2002 Greg Turner - * Copyright 2003-2006 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 - * - * TODO: - * - Non-conformant strings - * - String structs - * - Byte count pointers - * - transmit_as/represent as - * - Multi-dimensional arrays - * - Conversion functions (NdrConvert) - * - Checks for integer addition overflow in base type and user marshall functions - */ - -#include -#include -#include -#include -#include - -#include "windef.h" -#include "winbase.h" -#include "winerror.h" - -#include "ndr_misc.h" -#include "rpcndr.h" - -#include "wine/unicode.h" -#include "wine/rpcfc.h" - -#include "wine/debug.h" - -WINE_DEFAULT_DEBUG_CHANNEL(ole); - -#if defined(__i386__) -# define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \ - (*((UINT32 *)(pchar)) = (uint32)) - -# define LITTLE_ENDIAN_UINT32_READ(pchar) \ - (*((UINT32 *)(pchar))) -#else - /* these would work for i386 too, but less efficient */ -# define LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) \ - (*(pchar) = LOBYTE(LOWORD(uint32)), \ - *((pchar)+1) = HIBYTE(LOWORD(uint32)), \ - *((pchar)+2) = LOBYTE(HIWORD(uint32)), \ - *((pchar)+3) = HIBYTE(HIWORD(uint32)), \ - (uint32)) /* allow as r-value */ - -# define LITTLE_ENDIAN_UINT32_READ(pchar) \ - (MAKELONG( \ - MAKEWORD(*(pchar), *((pchar)+1)), \ - MAKEWORD(*((pchar)+2), *((pchar)+3)))) -#endif - -#define BIG_ENDIAN_UINT32_WRITE(pchar, uint32) \ - (*((pchar)+3) = LOBYTE(LOWORD(uint32)), \ - *((pchar)+2) = HIBYTE(LOWORD(uint32)), \ - *((pchar)+1) = LOBYTE(HIWORD(uint32)), \ - *(pchar) = HIBYTE(HIWORD(uint32)), \ - (uint32)) /* allow as r-value */ - -#define BIG_ENDIAN_UINT32_READ(pchar) \ - (MAKELONG( \ - MAKEWORD(*((pchar)+3), *((pchar)+2)), \ - MAKEWORD(*((pchar)+1), *(pchar)))) - -#ifdef NDR_LOCAL_IS_BIG_ENDIAN -# define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \ - BIG_ENDIAN_UINT32_WRITE(pchar, uint32) -# define NDR_LOCAL_UINT32_READ(pchar) \ - BIG_ENDIAN_UINT32_READ(pchar) -#else -# define NDR_LOCAL_UINT32_WRITE(pchar, uint32) \ - LITTLE_ENDIAN_UINT32_WRITE(pchar, uint32) -# define NDR_LOCAL_UINT32_READ(pchar) \ - LITTLE_ENDIAN_UINT32_READ(pchar) -#endif - -/* _Align must be the desired alignment, - * e.g. ALIGN_LENGTH(len, 4) to align on a dword boundary. */ -#define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align)-1)&~((_Align)-1)) -#define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align)) -#define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align) -#define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align) -#define ALIGN_POINTER_CLEAR(_Ptr, _Align) \ - do { \ - memset((_Ptr), 0, ((_Align) - (ULONG_PTR)(_Ptr)) & ((_Align) - 1)); \ - ALIGN_POINTER(_Ptr, _Align); \ - } while(0) - -#define STD_OVERFLOW_CHECK(_Msg) do { \ - TRACE("buffer=%d/%d\n", _Msg->Buffer - (unsigned char *)_Msg->RpcMsg->Buffer, _Msg->BufferLength); \ - if (_Msg->Buffer > (unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength) \ - ERR("buffer overflow %d bytes\n", _Msg->Buffer - ((unsigned char *)_Msg->RpcMsg->Buffer + _Msg->BufferLength)); \ - } while (0) - -#define NDR_TABLE_SIZE 128 -#define NDR_TABLE_MASK 127 - -static unsigned char *WINAPI NdrBaseTypeMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING); -static unsigned char *WINAPI NdrBaseTypeUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char); -static void WINAPI NdrBaseTypeBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING); -static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING); -static ULONG WINAPI NdrBaseTypeMemorySize(PMIDL_STUB_MESSAGE, PFORMAT_STRING); - -static unsigned char *WINAPI NdrContextHandleMarshall(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING); -static void WINAPI NdrContextHandleBufferSize(PMIDL_STUB_MESSAGE, unsigned char *, PFORMAT_STRING); -static unsigned char *WINAPI NdrContextHandleUnmarshall(PMIDL_STUB_MESSAGE, unsigned char **, PFORMAT_STRING, unsigned char); - -const NDR_MARSHALL NdrMarshaller[NDR_TABLE_SIZE] = { - 0, - NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, - NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, - NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, - NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, NdrBaseTypeMarshall, - /* 0x10 */ - NdrBaseTypeMarshall, - /* 0x11 */ - NdrPointerMarshall, NdrPointerMarshall, - NdrPointerMarshall, NdrPointerMarshall, - /* 0x15 */ - NdrSimpleStructMarshall, NdrSimpleStructMarshall, - NdrConformantStructMarshall, NdrConformantStructMarshall, - NdrConformantVaryingStructMarshall, - NdrComplexStructMarshall, - /* 0x1b */ - NdrConformantArrayMarshall, - NdrConformantVaryingArrayMarshall, - NdrFixedArrayMarshall, NdrFixedArrayMarshall, - NdrVaryingArrayMarshall, NdrVaryingArrayMarshall, - NdrComplexArrayMarshall, - /* 0x22 */ - NdrConformantStringMarshall, 0, 0, - NdrConformantStringMarshall, - NdrNonConformantStringMarshall, 0, 0, 0, - /* 0x2a */ - NdrEncapsulatedUnionMarshall, - NdrNonEncapsulatedUnionMarshall, - NdrByteCountPointerMarshall, - NdrXmitOrRepAsMarshall, NdrXmitOrRepAsMarshall, - /* 0x2f */ - NdrInterfacePointerMarshall, - /* 0x30 */ - NdrContextHandleMarshall, - /* 0xb1 */ - 0, 0, 0, - NdrUserMarshalMarshall, - 0, 0, - /* 0xb7 */ - NdrRangeMarshall -}; -const NDR_UNMARSHALL NdrUnmarshaller[NDR_TABLE_SIZE] = { - 0, - NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, - NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, - NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, - NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, NdrBaseTypeUnmarshall, - /* 0x10 */ - NdrBaseTypeUnmarshall, - /* 0x11 */ - NdrPointerUnmarshall, NdrPointerUnmarshall, - NdrPointerUnmarshall, NdrPointerUnmarshall, - /* 0x15 */ - NdrSimpleStructUnmarshall, NdrSimpleStructUnmarshall, - NdrConformantStructUnmarshall, NdrConformantStructUnmarshall, - NdrConformantVaryingStructUnmarshall, - NdrComplexStructUnmarshall, - /* 0x1b */ - NdrConformantArrayUnmarshall, - NdrConformantVaryingArrayUnmarshall, - NdrFixedArrayUnmarshall, NdrFixedArrayUnmarshall, - NdrVaryingArrayUnmarshall, NdrVaryingArrayUnmarshall, - NdrComplexArrayUnmarshall, - /* 0x22 */ - NdrConformantStringUnmarshall, 0, 0, - NdrConformantStringUnmarshall, - NdrNonConformantStringUnmarshall, 0, 0, 0, - /* 0x2a */ - NdrEncapsulatedUnionUnmarshall, - NdrNonEncapsulatedUnionUnmarshall, - NdrByteCountPointerUnmarshall, - NdrXmitOrRepAsUnmarshall, NdrXmitOrRepAsUnmarshall, - /* 0x2f */ - NdrInterfacePointerUnmarshall, - /* 0x30 */ - NdrContextHandleUnmarshall, - /* 0xb1 */ - 0, 0, 0, - NdrUserMarshalUnmarshall, - 0, 0, - /* 0xb7 */ - NdrRangeUnmarshall -}; -const NDR_BUFFERSIZE NdrBufferSizer[NDR_TABLE_SIZE] = { - 0, - NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, - NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, - NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, - NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, NdrBaseTypeBufferSize, - /* 0x10 */ - NdrBaseTypeBufferSize, - /* 0x11 */ - NdrPointerBufferSize, NdrPointerBufferSize, - NdrPointerBufferSize, NdrPointerBufferSize, - /* 0x15 */ - NdrSimpleStructBufferSize, NdrSimpleStructBufferSize, - NdrConformantStructBufferSize, NdrConformantStructBufferSize, - NdrConformantVaryingStructBufferSize, - NdrComplexStructBufferSize, - /* 0x1b */ - NdrConformantArrayBufferSize, - NdrConformantVaryingArrayBufferSize, - NdrFixedArrayBufferSize, NdrFixedArrayBufferSize, - NdrVaryingArrayBufferSize, NdrVaryingArrayBufferSize, - NdrComplexArrayBufferSize, - /* 0x22 */ - NdrConformantStringBufferSize, 0, 0, - NdrConformantStringBufferSize, - NdrNonConformantStringBufferSize, 0, 0, 0, - /* 0x2a */ - NdrEncapsulatedUnionBufferSize, - NdrNonEncapsulatedUnionBufferSize, - NdrByteCountPointerBufferSize, - NdrXmitOrRepAsBufferSize, NdrXmitOrRepAsBufferSize, - /* 0x2f */ - NdrInterfacePointerBufferSize, - /* 0x30 */ - NdrContextHandleBufferSize, - /* 0xb1 */ - 0, 0, 0, - NdrUserMarshalBufferSize, - 0, 0, - /* 0xb7 */ - NdrRangeBufferSize -}; -const NDR_MEMORYSIZE NdrMemorySizer[NDR_TABLE_SIZE] = { - 0, - NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, - NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, - NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, - NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, NdrBaseTypeMemorySize, - /* 0x10 */ - NdrBaseTypeMemorySize, - /* 0x11 */ - NdrPointerMemorySize, NdrPointerMemorySize, - NdrPointerMemorySize, NdrPointerMemorySize, - /* 0x15 */ - NdrSimpleStructMemorySize, NdrSimpleStructMemorySize, - NdrConformantStructMemorySize, NdrConformantStructMemorySize, - NdrConformantVaryingStructMemorySize, - NdrComplexStructMemorySize, - /* 0x1b */ - NdrConformantArrayMemorySize, - NdrConformantVaryingArrayMemorySize, - NdrFixedArrayMemorySize, NdrFixedArrayMemorySize, - NdrVaryingArrayMemorySize, NdrVaryingArrayMemorySize, - NdrComplexArrayMemorySize, - /* 0x22 */ - NdrConformantStringMemorySize, 0, 0, - NdrConformantStringMemorySize, - NdrNonConformantStringMemorySize, 0, 0, 0, - /* 0x2a */ - NdrEncapsulatedUnionMemorySize, - NdrNonEncapsulatedUnionMemorySize, - NdrByteCountPointerMemorySize, - NdrXmitOrRepAsMemorySize, NdrXmitOrRepAsMemorySize, - /* 0x2f */ - NdrInterfacePointerMemorySize, - /* 0x30 */ - 0, - /* 0xb1 */ - 0, 0, 0, - NdrUserMarshalMemorySize, - 0, 0, - /* 0xb7 */ - NdrRangeMemorySize -}; -const NDR_FREE NdrFreer[NDR_TABLE_SIZE] = { - 0, - NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, - NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, - NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, - NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, NdrBaseTypeFree, - /* 0x10 */ - NdrBaseTypeFree, - /* 0x11 */ - NdrPointerFree, NdrPointerFree, - NdrPointerFree, NdrPointerFree, - /* 0x15 */ - NdrSimpleStructFree, NdrSimpleStructFree, - NdrConformantStructFree, NdrConformantStructFree, - NdrConformantVaryingStructFree, - NdrComplexStructFree, - /* 0x1b */ - NdrConformantArrayFree, - NdrConformantVaryingArrayFree, - NdrFixedArrayFree, NdrFixedArrayFree, - NdrVaryingArrayFree, NdrVaryingArrayFree, - NdrComplexArrayFree, - /* 0x22 */ - 0, 0, 0, - 0, 0, 0, 0, 0, - /* 0x2a */ - NdrEncapsulatedUnionFree, - NdrNonEncapsulatedUnionFree, - 0, - NdrXmitOrRepAsFree, NdrXmitOrRepAsFree, - /* 0x2f */ - NdrInterfacePointerFree, - /* 0x30 */ - 0, - /* 0xb1 */ - 0, 0, 0, - NdrUserMarshalFree, - 0, 0, - /* 0xb7 */ - NdrRangeFree -}; - -typedef struct _NDR_MEMORY_LIST -{ - ULONG magic; - ULONG size; - ULONG reserved; - struct _NDR_MEMORY_LIST *next; -} NDR_MEMORY_LIST; - -#define MEML_MAGIC ('M' << 24 | 'E' << 16 | 'M' << 8 | 'L') - -/*********************************************************************** - * NdrAllocate [RPCRT4.@] - * - * Allocates a block of memory using pStubMsg->pfnAllocate. - * - * PARAMS - * pStubMsg [I/O] MIDL_STUB_MESSAGE structure. - * len [I] Size of memory block to allocate. - * - * RETURNS - * The memory block of size len that was allocated. - * - * NOTES - * The memory block is always 8-byte aligned. - * If the function is unable to allocate memory an ERROR_OUTOFMEMORY - * exception is raised. - */ -void * WINAPI NdrAllocate(MIDL_STUB_MESSAGE *pStubMsg, size_t len) -{ - size_t aligned_len; - size_t adjusted_len; - void *p; - NDR_MEMORY_LIST *mem_list; - - aligned_len = ALIGNED_LENGTH(len, 8); - adjusted_len = aligned_len + sizeof(NDR_MEMORY_LIST); - /* check for overflow */ - if (adjusted_len < len) - { - ERR("overflow of adjusted_len %d, len %d\n", adjusted_len, len); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - } - - p = pStubMsg->pfnAllocate(adjusted_len); - if (!p) RpcRaiseException(ERROR_OUTOFMEMORY); - - mem_list = (NDR_MEMORY_LIST *)((char *)p + aligned_len); - mem_list->magic = MEML_MAGIC; - mem_list->size = aligned_len; - mem_list->reserved = 0; - mem_list->next = pStubMsg->pMemoryList; - pStubMsg->pMemoryList = mem_list; - - TRACE("-- %p\n", p); - return p; -} - -static void WINAPI NdrFree(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *Pointer) -{ - TRACE("(%p, %p)\n", pStubMsg, Pointer); - - pStubMsg->pfnFree(Pointer); -} - -static inline BOOL IsConformanceOrVariancePresent(PFORMAT_STRING pFormat) -{ - return (*(const ULONG *)pFormat != -1); -} - -static PFORMAT_STRING ReadConformance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat) -{ - ALIGN_POINTER(pStubMsg->Buffer, 4); - if (pStubMsg->Buffer + 4 > pStubMsg->BufferEnd) - RpcRaiseException(RPC_X_BAD_STUB_DATA); - pStubMsg->MaxCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); - pStubMsg->Buffer += 4; - TRACE("unmarshalled conformance is %ld\n", pStubMsg->MaxCount); - if (pStubMsg->fHasNewCorrDesc) - return pFormat+6; - else - return pFormat+4; -} - -static inline PFORMAT_STRING ReadVariance(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat, ULONG MaxValue) -{ - if (pFormat && !IsConformanceOrVariancePresent(pFormat)) - { - pStubMsg->Offset = 0; - pStubMsg->ActualCount = pStubMsg->MaxCount; - goto done; - } - - ALIGN_POINTER(pStubMsg->Buffer, 4); - if (pStubMsg->Buffer + 8 > pStubMsg->BufferEnd) - RpcRaiseException(RPC_X_BAD_STUB_DATA); - pStubMsg->Offset = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); - pStubMsg->Buffer += 4; - TRACE("offset is %d\n", pStubMsg->Offset); - pStubMsg->ActualCount = NDR_LOCAL_UINT32_READ(pStubMsg->Buffer); - pStubMsg->Buffer += 4; - TRACE("variance is %d\n", pStubMsg->ActualCount); - - if ((pStubMsg->ActualCount > MaxValue) || - (pStubMsg->ActualCount + pStubMsg->Offset > MaxValue)) - { - ERR("invalid array bound(s): ActualCount = %d, Offset = %d, MaxValue = %d\n", - pStubMsg->ActualCount, pStubMsg->Offset, MaxValue); - RpcRaiseException(RPC_S_INVALID_BOUND); - return NULL; - } - -done: - if (pStubMsg->fHasNewCorrDesc) - return pFormat+6; - else - return pFormat+4; -} - -/* writes the conformance value to the buffer */ -static inline void WriteConformance(MIDL_STUB_MESSAGE *pStubMsg) -{ - ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4); - if (pStubMsg->Buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) - RpcRaiseException(RPC_X_BAD_STUB_DATA); - NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->MaxCount); - pStubMsg->Buffer += 4; -} - -/* writes the variance values to the buffer */ -static inline void WriteVariance(MIDL_STUB_MESSAGE *pStubMsg) -{ - ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4); - if (pStubMsg->Buffer + 8 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) - RpcRaiseException(RPC_X_BAD_STUB_DATA); - NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->Offset); - pStubMsg->Buffer += 4; - NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, pStubMsg->ActualCount); - pStubMsg->Buffer += 4; -} - -/* requests buffer space for the conformance value */ -static inline void SizeConformance(MIDL_STUB_MESSAGE *pStubMsg) -{ - ALIGN_LENGTH(pStubMsg->BufferLength, 4); - if (pStubMsg->BufferLength + 4 < pStubMsg->BufferLength) - RpcRaiseException(RPC_X_BAD_STUB_DATA); - pStubMsg->BufferLength += 4; -} - -/* requests buffer space for the variance values */ -static inline void SizeVariance(MIDL_STUB_MESSAGE *pStubMsg) -{ - ALIGN_LENGTH(pStubMsg->BufferLength, 4); - if (pStubMsg->BufferLength + 8 < pStubMsg->BufferLength) - RpcRaiseException(RPC_X_BAD_STUB_DATA); - pStubMsg->BufferLength += 8; -} - -PFORMAT_STRING ComputeConformanceOrVariance( - MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory, - PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount) -{ - BYTE dtype = pFormat[0] & 0xf; - short ofs = *(const short *)&pFormat[2]; - LPVOID ptr = NULL; - DWORD data = 0; - - if (!IsConformanceOrVariancePresent(pFormat)) { - /* null descriptor */ - *pCount = def; - goto finish_conf; - } - - switch (pFormat[0] & 0xf0) { - case RPC_FC_NORMAL_CONFORMANCE: - TRACE("normal conformance, ofs=%d\n", ofs); - ptr = pMemory; - break; - case RPC_FC_POINTER_CONFORMANCE: - TRACE("pointer conformance, ofs=%d\n", ofs); - ptr = pStubMsg->Memory; - break; - case RPC_FC_TOP_LEVEL_CONFORMANCE: - TRACE("toplevel conformance, ofs=%d\n", ofs); - if (pStubMsg->StackTop) { - ptr = pStubMsg->StackTop; - } - else { - /* -Os mode, *pCount is already set */ - goto finish_conf; - } - break; - case RPC_FC_CONSTANT_CONFORMANCE: - data = ofs | ((DWORD)pFormat[1] << 16); - TRACE("constant conformance, val=%d\n", data); - *pCount = data; - goto finish_conf; - case RPC_FC_TOP_LEVEL_MULTID_CONFORMANCE: - FIXME("toplevel multidimensional conformance, ofs=%d\n", ofs); - if (pStubMsg->StackTop) { - ptr = pStubMsg->StackTop; - } - else { - /* ? */ - goto done_conf_grab; - } - break; - default: - FIXME("unknown conformance type %x\n", pFormat[0] & 0xf0); - } - - switch (pFormat[1]) { - case RPC_FC_DEREFERENCE: - ptr = *(LPVOID*)((char *)ptr + ofs); - break; - case RPC_FC_CALLBACK: - { - unsigned char *old_stack_top = pStubMsg->StackTop; - pStubMsg->StackTop = ptr; - - /* ofs is index into StubDesc->apfnExprEval */ - TRACE("callback conformance into apfnExprEval[%d]\n", ofs); - pStubMsg->StubDesc->apfnExprEval[ofs](pStubMsg); - - pStubMsg->StackTop = old_stack_top; - - /* the callback function always stores the computed value in MaxCount */ - *pCount = pStubMsg->MaxCount; - goto finish_conf; - } - default: - ptr = (char *)ptr + ofs; - break; - } - - switch (dtype) { - case RPC_FC_LONG: - case RPC_FC_ULONG: - data = *(DWORD*)ptr; - break; - case RPC_FC_SHORT: - data = *(SHORT*)ptr; - break; - case RPC_FC_USHORT: - data = *(USHORT*)ptr; - break; - case RPC_FC_CHAR: - case RPC_FC_SMALL: - data = *(CHAR*)ptr; - break; - case RPC_FC_BYTE: - case RPC_FC_USMALL: - data = *(UCHAR*)ptr; - break; - default: - FIXME("unknown conformance data type %x\n", dtype); - goto done_conf_grab; - } - TRACE("dereferenced data type %x at %p, got %d\n", dtype, ptr, data); - -done_conf_grab: - switch (pFormat[1]) { - case RPC_FC_DEREFERENCE: /* already handled */ - case 0: /* no op */ - *pCount = data; - break; - case RPC_FC_ADD_1: - *pCount = data + 1; - break; - case RPC_FC_SUB_1: - *pCount = data - 1; - break; - case RPC_FC_MULT_2: - *pCount = data * 2; - break; - case RPC_FC_DIV_2: - *pCount = data / 2; - break; - default: - FIXME("unknown conformance op %d\n", pFormat[1]); - goto finish_conf; - } - -finish_conf: - TRACE("resulting conformance is %ld\n", *pCount); - if (pStubMsg->fHasNewCorrDesc) - return pFormat+6; - else - return pFormat+4; -} - -/* multiply two numbers together, raising an RPC_S_INVALID_BOUND exception if - * the result overflows 32-bits */ -static inline ULONG safe_multiply(ULONG a, ULONG b) -{ - ULONGLONG ret = (ULONGLONG)a * b; - if (ret > 0xffffffff) - { - RpcRaiseException(RPC_S_INVALID_BOUND); - return 0; - } - return ret; -} - -static inline void safe_buffer_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size) -{ - if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */ - (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)) - RpcRaiseException(RPC_X_BAD_STUB_DATA); - pStubMsg->Buffer += size; -} - -static inline void safe_buffer_length_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size) -{ - if (pStubMsg->BufferLength + size < pStubMsg->BufferLength) /* integer overflow of pStubMsg->BufferSize */ - { - ERR("buffer length overflow - BufferLength = %u, size = %u\n", - pStubMsg->BufferLength, size); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - } - pStubMsg->BufferLength += size; -} - -/* copies data from the buffer, checking that there is enough data in the buffer - * to do so */ -static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE *pStubMsg, void *p, ULONG size) -{ - if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */ - (pStubMsg->Buffer + size > pStubMsg->BufferEnd)) - { - ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n", - pStubMsg->Buffer, pStubMsg->BufferEnd, size); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - } - if (p == pStubMsg->Buffer) - ERR("pointer is the same as the buffer\n"); - memcpy(p, pStubMsg->Buffer, size); - pStubMsg->Buffer += size; -} - -/* copies data to the buffer, checking that there is enough space to do so */ -static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE *pStubMsg, const void *p, ULONG size) -{ - if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */ - (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)) - { - ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n", - pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength, - size); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - } - memcpy(pStubMsg->Buffer, p, size); - pStubMsg->Buffer += size; -} - -/* - * NdrConformantString: - * - * What MS calls a ConformantString is, in DCE terminology, - * a Varying-Conformant String. - * [ - * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0') - * offset: DWORD (actual string data begins at (offset) CHARTYPE's - * into unmarshalled string) - * length: DWORD (# of CHARTYPE characters, inclusive of '\0') - * [ - * data: CHARTYPE[maxlen] - * ] - * ], where CHARTYPE is the appropriate character type (specified externally) - * - */ - -/*********************************************************************** - * NdrConformantStringMarshall [RPCRT4.@] - */ -unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg, - unsigned char *pszMessage, PFORMAT_STRING pFormat) -{ - ULONG esize, size; - - TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat); - - if (*pFormat == RPC_FC_C_CSTRING) { - TRACE("string=%s\n", debugstr_a((char*)pszMessage)); - pStubMsg->ActualCount = strlen((char*)pszMessage)+1; - esize = 1; - } - else if (*pFormat == RPC_FC_C_WSTRING) { - TRACE("string=%s\n", debugstr_w((LPWSTR)pszMessage)); - pStubMsg->ActualCount = strlenW((LPWSTR)pszMessage)+1; - esize = 2; - } - else { - ERR("Unhandled string type: %#x\n", *pFormat); - /* FIXME: raise an exception. */ - return NULL; - } - - if (pFormat[1] == RPC_FC_STRING_SIZED) - pFormat = ComputeConformance(pStubMsg, pszMessage, pFormat + 2, 0); - else - pStubMsg->MaxCount = pStubMsg->ActualCount; - pStubMsg->Offset = 0; - WriteConformance(pStubMsg); - WriteVariance(pStubMsg); - - size = safe_multiply(esize, pStubMsg->ActualCount); - safe_copy_to_buffer(pStubMsg, pszMessage, size); /* the string itself */ - - /* success */ - return NULL; /* is this always right? */ -} - -/*********************************************************************** - * NdrConformantStringBufferSize [RPCRT4.@] - */ -void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char* pMemory, PFORMAT_STRING pFormat) -{ - ULONG esize; - - TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat); - - SizeConformance(pStubMsg); - SizeVariance(pStubMsg); - - if (*pFormat == RPC_FC_C_CSTRING) { - TRACE("string=%s\n", debugstr_a((char*)pMemory)); - pStubMsg->ActualCount = strlen((char*)pMemory)+1; - esize = 1; - } - else if (*pFormat == RPC_FC_C_WSTRING) { - TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory)); - pStubMsg->ActualCount = strlenW((LPWSTR)pMemory)+1; - esize = 2; - } - else { - ERR("Unhandled string type: %#x\n", *pFormat); - /* FIXME: raise an exception */ - return; - } - - if (pFormat[1] == RPC_FC_STRING_SIZED) - pFormat = ComputeConformance(pStubMsg, pMemory, pFormat + 2, 0); - else - pStubMsg->MaxCount = pStubMsg->ActualCount; - - safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount)); -} - -/************************************************************************ - * NdrConformantStringMemorySize [RPCRT4.@] - */ -ULONG WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg, - PFORMAT_STRING pFormat ) -{ - ULONG bufsize, memsize, esize, i; - - TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat); - - ReadConformance(pStubMsg, NULL); - ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount); - - if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount)) - { - ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n", - pStubMsg->ActualCount, pStubMsg->MaxCount); - RpcRaiseException(RPC_S_INVALID_BOUND); - } - if (pStubMsg->Offset) - { - ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset); - RpcRaiseException(RPC_S_INVALID_BOUND); - } - - if (*pFormat == RPC_FC_C_CSTRING) esize = 1; - else if (*pFormat == RPC_FC_C_WSTRING) esize = 2; - else { - ERR("Unhandled string type: %#x\n", *pFormat); - /* FIXME: raise an exception */ - esize = 0; - } - - memsize = safe_multiply(esize, pStubMsg->MaxCount); - bufsize = safe_multiply(esize, pStubMsg->ActualCount); - - /* strings must always have null terminating bytes */ - if (bufsize < esize) - { - ERR("invalid string length of %d\n", pStubMsg->ActualCount); - RpcRaiseException(RPC_S_INVALID_BOUND); - } - - /* verify the buffer is safe to access */ - if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) || - (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd)) - { - ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize, - pStubMsg->BufferEnd, pStubMsg->Buffer); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - } - - for (i = bufsize - esize; i < bufsize; i++) - if (pStubMsg->Buffer[i] != 0) - { - ERR("string not null-terminated at byte position %d, data is 0x%x\n", - i, pStubMsg->Buffer[i]); - RpcRaiseException(RPC_S_INVALID_BOUND); - } - - safe_buffer_increment(pStubMsg, bufsize); - pStubMsg->MemorySize += memsize; - - return pStubMsg->MemorySize; -} - -/************************************************************************ - * NdrConformantStringUnmarshall [RPCRT4.@] - */ -unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, - unsigned char** ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc ) -{ - ULONG bufsize, memsize, esize, i; - - TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n", - pStubMsg, *ppMemory, pFormat, fMustAlloc); - - assert(pFormat && ppMemory && pStubMsg); - - ReadConformance(pStubMsg, NULL); - ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount); - - if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount)) - { - ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n", - pStubMsg->ActualCount, pStubMsg->MaxCount); - RpcRaiseException(RPC_S_INVALID_BOUND); - return NULL; - } - if (pStubMsg->Offset) - { - ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset); - RpcRaiseException(RPC_S_INVALID_BOUND); - return NULL; - } - - if (*pFormat == RPC_FC_C_CSTRING) esize = 1; - else if (*pFormat == RPC_FC_C_WSTRING) esize = 2; - else { - ERR("Unhandled string type: %#x\n", *pFormat); - /* FIXME: raise an exception */ - esize = 0; - } - - memsize = safe_multiply(esize, pStubMsg->MaxCount); - bufsize = safe_multiply(esize, pStubMsg->ActualCount); - - /* strings must always have null terminating bytes */ - if (bufsize < esize) - { - ERR("invalid string length of %d\n", pStubMsg->ActualCount); - RpcRaiseException(RPC_S_INVALID_BOUND); - return NULL; - } - - /* verify the buffer is safe to access */ - if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) || - (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd)) - { - ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize, - pStubMsg->BufferEnd, pStubMsg->Buffer); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - return NULL; - } - - for (i = bufsize - esize; i < bufsize; i++) - if (pStubMsg->Buffer[i] != 0) - { - ERR("string not null-terminated at byte position %d, data is 0x%x\n", - i, pStubMsg->Buffer[i]); - RpcRaiseException(RPC_S_INVALID_BOUND); - return NULL; - } - - if (fMustAlloc) - *ppMemory = NdrAllocate(pStubMsg, memsize); - else - { - if (!pStubMsg->IsClient && !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount)) - /* if the data in the RPC buffer is big enough, we just point straight - * into it */ - *ppMemory = pStubMsg->Buffer; - else if (!*ppMemory) - *ppMemory = NdrAllocate(pStubMsg, memsize); - } - - if (*ppMemory == pStubMsg->Buffer) - safe_buffer_increment(pStubMsg, bufsize); - else - safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize); - - if (*pFormat == RPC_FC_C_CSTRING) { - TRACE("string=%s\n", debugstr_a((char*)*ppMemory)); - } - else if (*pFormat == RPC_FC_C_WSTRING) { - TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory)); - } - - return NULL; /* FIXME: is this always right? */ -} - -/*********************************************************************** - * NdrNonConformantStringMarshall [RPCRT4.@] - */ -unsigned char * WINAPI NdrNonConformantStringMarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - ULONG esize, size, maxsize; - - TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat); - - maxsize = *(USHORT *)&pFormat[2]; - - if (*pFormat == RPC_FC_CSTRING) - { - ULONG i; - const char *str = (const char *)pMemory; - for (i = 0; i < maxsize && *str; i++, str++) - ; - TRACE("string=%s\n", debugstr_an(str, i)); - pStubMsg->ActualCount = i + 1; - esize = 1; - } - else if (*pFormat == RPC_FC_WSTRING) - { - ULONG i; - const WCHAR *str = (const WCHAR *)pMemory; - for (i = 0; i < maxsize && *str; i++, str++) - ; - TRACE("string=%s\n", debugstr_wn(str, i)); - pStubMsg->ActualCount = i + 1; - esize = 2; - } - else - { - ERR("Unhandled string type: %#x\n", *pFormat); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - } - - pStubMsg->Offset = 0; - WriteVariance(pStubMsg); - - size = safe_multiply(esize, pStubMsg->ActualCount); - safe_copy_to_buffer(pStubMsg, pMemory, size); /* the string itself */ - - return NULL; -} - -/*********************************************************************** - * NdrNonConformantStringUnmarshall [RPCRT4.@] - */ -unsigned char * WINAPI NdrNonConformantStringUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char **ppMemory, - PFORMAT_STRING pFormat, - unsigned char fMustAlloc) -{ - ULONG bufsize, memsize, esize, i, maxsize; - - TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n", - pStubMsg, *ppMemory, pFormat, fMustAlloc); - - maxsize = *(USHORT *)&pFormat[2]; - - ReadVariance(pStubMsg, NULL, maxsize); - if (pStubMsg->Offset) - { - ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset); - RpcRaiseException(RPC_S_INVALID_BOUND); - } - - if (*pFormat == RPC_FC_CSTRING) esize = 1; - else if (*pFormat == RPC_FC_WSTRING) esize = 2; - else - { - ERR("Unhandled string type: %#x\n", *pFormat); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - } - - memsize = esize * maxsize; - bufsize = safe_multiply(esize, pStubMsg->ActualCount); - - if (bufsize < esize) - { - ERR("invalid string length of %d\n", pStubMsg->ActualCount); - RpcRaiseException(RPC_S_INVALID_BOUND); - return NULL; - } - - /* verify the buffer is safe to access */ - if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) || - (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd)) - { - ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize, - pStubMsg->BufferEnd, pStubMsg->Buffer); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - return NULL; - } - - /* strings must always have null terminating bytes */ - for (i = bufsize - esize; i < bufsize; i++) - if (pStubMsg->Buffer[i] != 0) - { - ERR("string not null-terminated at byte position %d, data is 0x%x\n", - i, pStubMsg->Buffer[i]); - RpcRaiseException(RPC_S_INVALID_BOUND); - } - - if (fMustAlloc || !*ppMemory) - *ppMemory = NdrAllocate(pStubMsg, memsize); - - safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize); - - if (*pFormat == RPC_FC_CSTRING) { - TRACE("string=%s\n", debugstr_an((char*)*ppMemory, pStubMsg->ActualCount)); - } - else if (*pFormat == RPC_FC_WSTRING) { - TRACE("string=%s\n", debugstr_wn((LPWSTR)*ppMemory, pStubMsg->ActualCount)); - } - - return NULL; -} - -/*********************************************************************** - * NdrNonConformantStringBufferSize [RPCRT4.@] - */ -void WINAPI NdrNonConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - ULONG esize, maxsize; - - TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat); - - maxsize = *(USHORT *)&pFormat[2]; - - SizeVariance(pStubMsg); - - if (*pFormat == RPC_FC_CSTRING) - { - ULONG i; - const char *str = (const char *)pMemory; - for (i = 0; i < maxsize && *str; i++, str++) - ; - TRACE("string=%s\n", debugstr_an(str, i)); - pStubMsg->ActualCount = i + 1; - esize = 1; - } - else if (*pFormat == RPC_FC_WSTRING) - { - ULONG i; - const WCHAR *str = (const WCHAR *)pMemory; - for (i = 0; i < maxsize && *str; i++, str++) - ; - TRACE("string=%s\n", debugstr_wn(str, i)); - pStubMsg->ActualCount = i + 1; - esize = 2; - } - else - { - ERR("Unhandled string type: %#x\n", *pFormat); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - } - - safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount)); -} - -/*********************************************************************** - * NdrNonConformantStringMemorySize [RPCRT4.@] - */ -ULONG WINAPI NdrNonConformantStringMemorySize(PMIDL_STUB_MESSAGE pStubMsg, - PFORMAT_STRING pFormat) -{ - ULONG bufsize, memsize, esize, i, maxsize; - - TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg, pFormat); - - maxsize = *(USHORT *)&pFormat[2]; - - ReadVariance(pStubMsg, NULL, maxsize); - - if (pStubMsg->Offset) - { - ERR("non-conformant strings can't have Offset (%d)\n", pStubMsg->Offset); - RpcRaiseException(RPC_S_INVALID_BOUND); - } - - if (*pFormat == RPC_FC_CSTRING) esize = 1; - else if (*pFormat == RPC_FC_WSTRING) esize = 2; - else - { - ERR("Unhandled string type: %#x\n", *pFormat); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - } - - memsize = esize * maxsize; - bufsize = safe_multiply(esize, pStubMsg->ActualCount); - - /* strings must always have null terminating bytes */ - if (bufsize < esize) - { - ERR("invalid string length of %d\n", pStubMsg->ActualCount); - RpcRaiseException(RPC_S_INVALID_BOUND); - } - - /* verify the buffer is safe to access */ - if ((pStubMsg->Buffer + bufsize < pStubMsg->Buffer) || - (pStubMsg->Buffer + bufsize > pStubMsg->BufferEnd)) - { - ERR("bufsize 0x%x exceeded buffer end %p of buffer %p\n", bufsize, - pStubMsg->BufferEnd, pStubMsg->Buffer); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - } - - for (i = bufsize - esize; i < bufsize; i++) - if (pStubMsg->Buffer[i] != 0) - { - ERR("string not null-terminated at byte position %d, data is 0x%x\n", - i, pStubMsg->Buffer[i]); - RpcRaiseException(RPC_S_INVALID_BOUND); - } - - safe_buffer_increment(pStubMsg, bufsize); - pStubMsg->MemorySize += memsize; - - return pStubMsg->MemorySize; -} - -static inline void dump_pointer_attr(unsigned char attr) -{ - if (attr & RPC_FC_P_ALLOCALLNODES) - TRACE(" RPC_FC_P_ALLOCALLNODES"); - if (attr & RPC_FC_P_DONTFREE) - TRACE(" RPC_FC_P_DONTFREE"); - if (attr & RPC_FC_P_ONSTACK) - TRACE(" RPC_FC_P_ONSTACK"); - if (attr & RPC_FC_P_SIMPLEPOINTER) - TRACE(" RPC_FC_P_SIMPLEPOINTER"); - if (attr & RPC_FC_P_DEREF) - TRACE(" RPC_FC_P_DEREF"); - TRACE("\n"); -} - -/*********************************************************************** - * PointerMarshall [internal] - */ -static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *Buffer, - unsigned char *Pointer, - PFORMAT_STRING pFormat) -{ - unsigned type = pFormat[0], attr = pFormat[1]; - PFORMAT_STRING desc; - NDR_MARSHALL m; - ULONG pointer_id; - int pointer_needs_marshaling; - - TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat); - TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr); - pFormat += 2; - if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat; - else desc = pFormat + *(const SHORT*)pFormat; - - switch (type) { - case RPC_FC_RP: /* ref pointer (always non-null) */ - if (!Pointer) - { - ERR("NULL ref pointer is not allowed\n"); - RpcRaiseException(RPC_X_NULL_REF_POINTER); - } - pointer_needs_marshaling = 1; - break; - case RPC_FC_UP: /* unique pointer */ - case RPC_FC_OP: /* object pointer - same as unique here */ - if (Pointer) - pointer_needs_marshaling = 1; - else - pointer_needs_marshaling = 0; - pointer_id = (ULONG)Pointer; - TRACE("writing 0x%08x to buffer\n", pointer_id); - NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id); - break; - case RPC_FC_FP: - pointer_needs_marshaling = !NdrFullPointerQueryPointer( - pStubMsg->FullPtrXlatTables, Pointer, 1, &pointer_id); - TRACE("writing 0x%08x to buffer\n", pointer_id); - NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id); - break; - default: - FIXME("unhandled ptr type=%02x\n", type); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - return; - } - - TRACE("calling marshaller for type 0x%x\n", (int)*desc); - - if (pointer_needs_marshaling) { - if (attr & RPC_FC_P_DEREF) { - Pointer = *(unsigned char**)Pointer; - TRACE("deref => %p\n", Pointer); - } - m = NdrMarshaller[*desc & NDR_TABLE_MASK]; - if (m) m(pStubMsg, Pointer, desc); - else FIXME("no marshaller for data type=%02x\n", *desc); - } - - STD_OVERFLOW_CHECK(pStubMsg); -} - -/*********************************************************************** - * PointerUnmarshall [internal] - */ -static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *Buffer, - unsigned char **pPointer, - unsigned char *pSrcPointer, - PFORMAT_STRING pFormat, - unsigned char fMustAlloc) -{ - unsigned type = pFormat[0], attr = pFormat[1]; - PFORMAT_STRING desc; - NDR_UNMARSHALL m; - DWORD pointer_id = 0; - int pointer_needs_unmarshaling; - - TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pSrcPointer, pFormat, fMustAlloc); - TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr); - pFormat += 2; - if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat; - else desc = pFormat + *(const SHORT*)pFormat; - - switch (type) { - case RPC_FC_RP: /* ref pointer (always non-null) */ - pointer_needs_unmarshaling = 1; - break; - case RPC_FC_UP: /* unique pointer */ - pointer_id = NDR_LOCAL_UINT32_READ(Buffer); - TRACE("pointer_id is 0x%08x\n", pointer_id); - if (pointer_id) - pointer_needs_unmarshaling = 1; - else { - *pPointer = NULL; - pointer_needs_unmarshaling = 0; - } - break; - case RPC_FC_OP: /* object pointer - we must free data before overwriting it */ - pointer_id = NDR_LOCAL_UINT32_READ(Buffer); - TRACE("pointer_id is 0x%08x\n", pointer_id); - if (!fMustAlloc && pSrcPointer) - { - FIXME("free object pointer %p\n", pSrcPointer); - fMustAlloc = TRUE; - } - if (pointer_id) - pointer_needs_unmarshaling = 1; - else - pointer_needs_unmarshaling = 0; - break; - case RPC_FC_FP: - pointer_id = NDR_LOCAL_UINT32_READ(Buffer); - TRACE("pointer_id is 0x%08x\n", pointer_id); - pointer_needs_unmarshaling = !NdrFullPointerQueryRefId( - pStubMsg->FullPtrXlatTables, pointer_id, 1, (void **)pPointer); - break; - default: - FIXME("unhandled ptr type=%02x\n", type); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - return; - } - - if (pointer_needs_unmarshaling) { - unsigned char *base_ptr_val = *pPointer; - unsigned char **current_ptr = pPointer; - if (pStubMsg->IsClient) { - TRACE("client\n"); - /* if we aren't forcing allocation of memory then try to use the existing - * (source) pointer to unmarshall the data into so that [in,out] - * parameters behave correctly. it doesn't matter if the parameter is - * [out] only since in that case the pointer will be NULL. we force - * allocation when the source pointer is NULL here instead of in the type - * unmarshalling routine for the benefit of the deref code below */ - if (!fMustAlloc) { - if (pSrcPointer) { - TRACE("setting *pPointer to %p\n", pSrcPointer); - *pPointer = base_ptr_val = pSrcPointer; - } else - fMustAlloc = TRUE; - } - } else { - TRACE("server\n"); - /* the memory in a stub is never initialised, so we have to work out here - * whether we have to initialise it so we can use the optimisation of - * setting the pointer to the buffer, if possible, or set fMustAlloc to - * TRUE. */ - if (attr & RPC_FC_P_DEREF) { - fMustAlloc = TRUE; - } else { - base_ptr_val = NULL; - *current_ptr = NULL; - } - } - - if (attr & RPC_FC_P_ALLOCALLNODES) - FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n"); - - if (attr & RPC_FC_P_DEREF) { - if (fMustAlloc) { - base_ptr_val = NdrAllocate(pStubMsg, sizeof(void *)); - *pPointer = base_ptr_val; - current_ptr = (unsigned char **)base_ptr_val; - } else - current_ptr = *(unsigned char***)current_ptr; - TRACE("deref => %p\n", current_ptr); - if (!fMustAlloc && !*current_ptr) fMustAlloc = TRUE; - } - m = NdrUnmarshaller[*desc & NDR_TABLE_MASK]; - if (m) m(pStubMsg, current_ptr, desc, fMustAlloc); - else FIXME("no unmarshaller for data type=%02x\n", *desc); - - if (type == RPC_FC_FP) - NdrFullPointerInsertRefId(pStubMsg->FullPtrXlatTables, pointer_id, - base_ptr_val); - } - - TRACE("pointer=%p\n", *pPointer); -} - -/*********************************************************************** - * PointerBufferSize [internal] - */ -static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *Pointer, - PFORMAT_STRING pFormat) -{ - unsigned type = pFormat[0], attr = pFormat[1]; - PFORMAT_STRING desc; - NDR_BUFFERSIZE m; - int pointer_needs_sizing; - ULONG pointer_id; - - TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat); - TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr); - pFormat += 2; - if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat; - else desc = pFormat + *(const SHORT*)pFormat; - - switch (type) { - case RPC_FC_RP: /* ref pointer (always non-null) */ - if (!Pointer) - { - ERR("NULL ref pointer is not allowed\n"); - RpcRaiseException(RPC_X_NULL_REF_POINTER); - } - break; - case RPC_FC_OP: - case RPC_FC_UP: - /* NULL pointer has no further representation */ - if (!Pointer) - return; - break; - case RPC_FC_FP: - pointer_needs_sizing = !NdrFullPointerQueryPointer( - pStubMsg->FullPtrXlatTables, Pointer, 0, &pointer_id); - if (!pointer_needs_sizing) - return; - break; - default: - FIXME("unhandled ptr type=%02x\n", type); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - return; - } - - if (attr & RPC_FC_P_DEREF) { - Pointer = *(unsigned char**)Pointer; - TRACE("deref => %p\n", Pointer); - } - - m = NdrBufferSizer[*desc & NDR_TABLE_MASK]; - if (m) m(pStubMsg, Pointer, desc); - else FIXME("no buffersizer for data type=%02x\n", *desc); -} - -/*********************************************************************** - * PointerMemorySize [internal] - */ -static unsigned long PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *Buffer, - PFORMAT_STRING pFormat) -{ - unsigned type = pFormat[0], attr = pFormat[1]; - PFORMAT_STRING desc; - NDR_MEMORYSIZE m; - DWORD pointer_id = 0; - int pointer_needs_sizing; - - TRACE("(%p,%p,%p)\n", pStubMsg, Buffer, pFormat); - TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr); - pFormat += 2; - if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat; - else desc = pFormat + *(const SHORT*)pFormat; - - switch (type) { - case RPC_FC_RP: /* ref pointer (always non-null) */ - pointer_needs_sizing = 1; - break; - case RPC_FC_UP: /* unique pointer */ - case RPC_FC_OP: /* object pointer - we must free data before overwriting it */ - pointer_id = NDR_LOCAL_UINT32_READ(Buffer); - TRACE("pointer_id is 0x%08x\n", pointer_id); - if (pointer_id) - pointer_needs_sizing = 1; - else - pointer_needs_sizing = 0; - break; - case RPC_FC_FP: - { - void *pointer; - pointer_id = NDR_LOCAL_UINT32_READ(Buffer); - TRACE("pointer_id is 0x%08x\n", pointer_id); - pointer_needs_sizing = !NdrFullPointerQueryRefId( - pStubMsg->FullPtrXlatTables, pointer_id, 1, &pointer); - break; - } - default: - FIXME("unhandled ptr type=%02x\n", type); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - return 0; - } - - if (attr & RPC_FC_P_DEREF) { - TRACE("deref\n"); - } - - if (pointer_needs_sizing) { - m = NdrMemorySizer[*desc & NDR_TABLE_MASK]; - if (m) m(pStubMsg, desc); - else FIXME("no memorysizer for data type=%02x\n", *desc); - } - - return pStubMsg->MemorySize; -} - -/*********************************************************************** - * PointerFree [internal] - */ -static void PointerFree(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *Pointer, - PFORMAT_STRING pFormat) -{ - unsigned type = pFormat[0], attr = pFormat[1]; - PFORMAT_STRING desc; - NDR_FREE m; - unsigned char *current_pointer = Pointer; - - TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat); - TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr); - if (attr & RPC_FC_P_DONTFREE) return; - pFormat += 2; - if (attr & RPC_FC_P_SIMPLEPOINTER) desc = pFormat; - else desc = pFormat + *(const SHORT*)pFormat; - - if (!Pointer) return; - - if (type == RPC_FC_FP) { - int pointer_needs_freeing = NdrFullPointerFree( - pStubMsg->FullPtrXlatTables, Pointer); - if (!pointer_needs_freeing) - return; - } - - if (attr & RPC_FC_P_DEREF) { - current_pointer = *(unsigned char**)Pointer; - TRACE("deref => %p\n", current_pointer); - } - - m = NdrFreer[*desc & NDR_TABLE_MASK]; - if (m) m(pStubMsg, current_pointer, desc); - - /* this check stops us from trying to free buffer memory. we don't have to - * worry about clients, since they won't call this function. - * we don't have to check for the buffer being reallocated because - * BufferStart and BufferEnd won't be reset when allocating memory for - * sending the response. we don't have to check for the new buffer here as - * it won't be used a type memory, only for buffer memory */ - if (Pointer >= (unsigned char *)pStubMsg->BufferStart && - Pointer < (unsigned char *)pStubMsg->BufferEnd) - goto notfree; - - if (attr & RPC_FC_P_ONSTACK) { - TRACE("not freeing stack ptr %p\n", Pointer); - return; - } - TRACE("freeing %p\n", Pointer); - NdrFree(pStubMsg, Pointer); - return; -notfree: - TRACE("not freeing %p\n", Pointer); -} - -/*********************************************************************** - * EmbeddedPointerMarshall - */ -static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - unsigned char *Mark = pStubMsg->BufferMark; - unsigned rep, count, stride; - unsigned i; - unsigned char *saved_buffer = NULL; - - TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); - - if (*pFormat != RPC_FC_PP) return NULL; - pFormat += 2; - - if (pStubMsg->PointerBufferMark) - { - saved_buffer = pStubMsg->Buffer; - pStubMsg->Buffer = pStubMsg->PointerBufferMark; - pStubMsg->PointerBufferMark = NULL; - } - - while (pFormat[0] != RPC_FC_END) { - switch (pFormat[0]) { - default: - FIXME("unknown repeat type %d\n", pFormat[0]); - case RPC_FC_NO_REPEAT: - rep = 1; - stride = 0; - count = 1; - pFormat += 2; - break; - case RPC_FC_FIXED_REPEAT: - rep = *(const WORD*)&pFormat[2]; - stride = *(const WORD*)&pFormat[4]; - count = *(const WORD*)&pFormat[8]; - pFormat += 10; - break; - case RPC_FC_VARIABLE_REPEAT: - rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount; - stride = *(const WORD*)&pFormat[2]; - count = *(const WORD*)&pFormat[6]; - pFormat += 8; - break; - } - for (i = 0; i < rep; i++) { - PFORMAT_STRING info = pFormat; - unsigned char *membase = pMemory + (i * stride); - unsigned char *bufbase = Mark + (i * stride); - unsigned u; - - for (u=0; uMemory; - - pStubMsg->Memory = pMemory; - PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4); - pStubMsg->Memory = saved_memory; - } - } - pFormat += 8 * count; - } - - if (saved_buffer) - { - pStubMsg->PointerBufferMark = pStubMsg->Buffer; - pStubMsg->Buffer = saved_buffer; - } - - STD_OVERFLOW_CHECK(pStubMsg); - - return NULL; -} - -/*********************************************************************** - * EmbeddedPointerUnmarshall - */ -static unsigned char * EmbeddedPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pDstMemoryPtrs, - unsigned char *pSrcMemoryPtrs, - PFORMAT_STRING pFormat, - unsigned char fMustAlloc) -{ - unsigned char *Mark = pStubMsg->BufferMark; - unsigned rep, count, stride; - unsigned i; - unsigned char *saved_buffer = NULL; - - TRACE("(%p,%p,%p,%p,%d)\n", pStubMsg, pDstMemoryPtrs, pSrcMemoryPtrs, pFormat, fMustAlloc); - - if (*pFormat != RPC_FC_PP) return NULL; - pFormat += 2; - - if (pStubMsg->PointerBufferMark) - { - saved_buffer = pStubMsg->Buffer; - pStubMsg->Buffer = pStubMsg->PointerBufferMark; - pStubMsg->PointerBufferMark = NULL; - } - - while (pFormat[0] != RPC_FC_END) { - TRACE("pFormat[0] = 0x%x\n", pFormat[0]); - switch (pFormat[0]) { - default: - FIXME("unknown repeat type %d\n", pFormat[0]); - case RPC_FC_NO_REPEAT: - rep = 1; - stride = 0; - count = 1; - pFormat += 2; - break; - case RPC_FC_FIXED_REPEAT: - rep = *(const WORD*)&pFormat[2]; - stride = *(const WORD*)&pFormat[4]; - count = *(const WORD*)&pFormat[8]; - pFormat += 10; - break; - case RPC_FC_VARIABLE_REPEAT: - rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount; - stride = *(const WORD*)&pFormat[2]; - count = *(const WORD*)&pFormat[6]; - pFormat += 8; - break; - } - for (i = 0; i < rep; i++) { - PFORMAT_STRING info = pFormat; - unsigned char *memdstbase = pDstMemoryPtrs + (i * stride); - unsigned char *memsrcbase = pSrcMemoryPtrs + (i * stride); - unsigned char *bufbase = Mark + (i * stride); - unsigned u; - - for (u=0; uPointerBufferMark = pStubMsg->Buffer; - pStubMsg->Buffer = saved_buffer; - } - - return NULL; -} - -/*********************************************************************** - * EmbeddedPointerBufferSize - */ -static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - unsigned rep, count, stride; - unsigned i; - ULONG saved_buffer_length = 0; - - TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); - - if (pStubMsg->IgnoreEmbeddedPointers) return; - - if (*pFormat != RPC_FC_PP) return; - pFormat += 2; - - if (pStubMsg->PointerLength) - { - saved_buffer_length = pStubMsg->BufferLength; - pStubMsg->BufferLength = pStubMsg->PointerLength; - pStubMsg->PointerLength = 0; - } - - while (pFormat[0] != RPC_FC_END) { - switch (pFormat[0]) { - default: - FIXME("unknown repeat type %d\n", pFormat[0]); - case RPC_FC_NO_REPEAT: - rep = 1; - stride = 0; - count = 1; - pFormat += 2; - break; - case RPC_FC_FIXED_REPEAT: - rep = *(const WORD*)&pFormat[2]; - stride = *(const WORD*)&pFormat[4]; - count = *(const WORD*)&pFormat[8]; - pFormat += 10; - break; - case RPC_FC_VARIABLE_REPEAT: - rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount; - stride = *(const WORD*)&pFormat[2]; - count = *(const WORD*)&pFormat[6]; - pFormat += 8; - break; - } - for (i = 0; i < rep; i++) { - PFORMAT_STRING info = pFormat; - unsigned char *membase = pMemory + (i * stride); - unsigned u; - - for (u=0; uMemory; - - pStubMsg->Memory = pMemory; - PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4); - pStubMsg->Memory = saved_memory; - } - } - pFormat += 8 * count; - } - - if (saved_buffer_length) - { - pStubMsg->PointerLength = pStubMsg->BufferLength; - pStubMsg->BufferLength = saved_buffer_length; - } -} - -/*********************************************************************** - * EmbeddedPointerMemorySize [internal] - */ -static unsigned long EmbeddedPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg, - PFORMAT_STRING pFormat) -{ - unsigned char *Mark = pStubMsg->BufferMark; - unsigned rep, count, stride; - unsigned i; - unsigned char *saved_buffer = NULL; - - TRACE("(%p,%p)\n", pStubMsg, pFormat); - - if (pStubMsg->IgnoreEmbeddedPointers) return 0; - - if (pStubMsg->PointerBufferMark) - { - saved_buffer = pStubMsg->Buffer; - pStubMsg->Buffer = pStubMsg->PointerBufferMark; - pStubMsg->PointerBufferMark = NULL; - } - - if (*pFormat != RPC_FC_PP) return 0; - pFormat += 2; - - while (pFormat[0] != RPC_FC_END) { - switch (pFormat[0]) { - default: - FIXME("unknown repeat type %d\n", pFormat[0]); - case RPC_FC_NO_REPEAT: - rep = 1; - stride = 0; - count = 1; - pFormat += 2; - break; - case RPC_FC_FIXED_REPEAT: - rep = *(const WORD*)&pFormat[2]; - stride = *(const WORD*)&pFormat[4]; - count = *(const WORD*)&pFormat[8]; - pFormat += 10; - break; - case RPC_FC_VARIABLE_REPEAT: - rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount; - stride = *(const WORD*)&pFormat[2]; - count = *(const WORD*)&pFormat[6]; - pFormat += 8; - break; - } - for (i = 0; i < rep; i++) { - PFORMAT_STRING info = pFormat; - unsigned char *bufbase = Mark + (i * stride); - unsigned u; - for (u=0; uPointerBufferMark = pStubMsg->Buffer; - pStubMsg->Buffer = saved_buffer; - } - - return 0; -} - -/*********************************************************************** - * EmbeddedPointerFree [internal] - */ -static void EmbeddedPointerFree(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - unsigned rep, count, stride; - unsigned i; - - TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); - if (*pFormat != RPC_FC_PP) return; - pFormat += 2; - - while (pFormat[0] != RPC_FC_END) { - switch (pFormat[0]) { - default: - FIXME("unknown repeat type %d\n", pFormat[0]); - case RPC_FC_NO_REPEAT: - rep = 1; - stride = 0; - count = 1; - pFormat += 2; - break; - case RPC_FC_FIXED_REPEAT: - rep = *(const WORD*)&pFormat[2]; - stride = *(const WORD*)&pFormat[4]; - count = *(const WORD*)&pFormat[8]; - pFormat += 10; - break; - case RPC_FC_VARIABLE_REPEAT: - rep = (pFormat[1] == RPC_FC_VARIABLE_OFFSET) ? pStubMsg->ActualCount : pStubMsg->MaxCount; - stride = *(const WORD*)&pFormat[2]; - count = *(const WORD*)&pFormat[6]; - pFormat += 8; - break; - } - for (i = 0; i < rep; i++) { - PFORMAT_STRING info = pFormat; - unsigned char *membase = pMemory + (i * stride); - unsigned u; - - for (u=0; uMemory; - - pStubMsg->Memory = pMemory; - PointerFree(pStubMsg, *(unsigned char**)memptr, info+4); - pStubMsg->Memory = saved_memory; - } - } - pFormat += 8 * count; - } -} - -/*********************************************************************** - * NdrPointerMarshall [RPCRT4.@] - */ -unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - unsigned char *Buffer; - - TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); - - /* incremement the buffer here instead of in PointerMarshall, - * as that is used by embedded pointers which already handle the incrementing - * the buffer, and shouldn't write any additional pointer data to the wire */ - if (*pFormat != RPC_FC_RP) - { - ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4); - Buffer = pStubMsg->Buffer; - safe_buffer_increment(pStubMsg, 4); - } - else - Buffer = pStubMsg->Buffer; - - PointerMarshall(pStubMsg, Buffer, pMemory, pFormat); - - return NULL; -} - -/*********************************************************************** - * NdrPointerUnmarshall [RPCRT4.@] - */ -unsigned char * WINAPI NdrPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char **ppMemory, - PFORMAT_STRING pFormat, - unsigned char fMustAlloc) -{ - unsigned char *Buffer; - - TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); - - /* incremement the buffer here instead of in PointerUnmarshall, - * as that is used by embedded pointers which already handle the incrementing - * the buffer, and shouldn't read any additional pointer data from the - * buffer */ - if (*pFormat != RPC_FC_RP) - { - ALIGN_POINTER(pStubMsg->Buffer, 4); - Buffer = pStubMsg->Buffer; - safe_buffer_increment(pStubMsg, 4); - } - else - Buffer = pStubMsg->Buffer; - - PointerUnmarshall(pStubMsg, Buffer, ppMemory, *ppMemory, pFormat, fMustAlloc); - - return NULL; -} - -/*********************************************************************** - * NdrPointerBufferSize [RPCRT4.@] - */ -void WINAPI NdrPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); - - /* incremement the buffer length here instead of in PointerBufferSize, - * as that is used by embedded pointers which already handle the buffer - * length, and shouldn't write anything more to the wire */ - if (*pFormat != RPC_FC_RP) - { - ALIGN_LENGTH(pStubMsg->BufferLength, 4); - safe_buffer_length_increment(pStubMsg, 4); - } - - PointerBufferSize(pStubMsg, pMemory, pFormat); -} - -/*********************************************************************** - * NdrPointerMemorySize [RPCRT4.@] - */ -ULONG WINAPI NdrPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg, - PFORMAT_STRING pFormat) -{ - /* unsigned size = *(LPWORD)(pFormat+2); */ - FIXME("(%p,%p): stub\n", pStubMsg, pFormat); - PointerMemorySize(pStubMsg, pStubMsg->Buffer, pFormat); - return 0; -} - -/*********************************************************************** - * NdrPointerFree [RPCRT4.@] - */ -void WINAPI NdrPointerFree(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); - PointerFree(pStubMsg, pMemory, pFormat); -} - -/*********************************************************************** - * NdrSimpleTypeMarshall [RPCRT4.@] - */ -void WINAPI NdrSimpleTypeMarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, - unsigned char FormatChar ) -{ - NdrBaseTypeMarshall(pStubMsg, pMemory, &FormatChar); -} - -/*********************************************************************** - * NdrSimpleTypeUnmarshall [RPCRT4.@] - */ -void WINAPI NdrSimpleTypeUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, - unsigned char FormatChar ) -{ - NdrBaseTypeUnmarshall(pStubMsg, &pMemory, &FormatChar, 0); -} - -/*********************************************************************** - * NdrSimpleStructMarshall [RPCRT4.@] - */ -unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - unsigned size = *(const WORD*)(pFormat+2); - TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); - - ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1); - - pStubMsg->BufferMark = pStubMsg->Buffer; - safe_copy_to_buffer(pStubMsg, pMemory, size); - - if (pFormat[0] != RPC_FC_STRUCT) - EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4); - - return NULL; -} - -/*********************************************************************** - * NdrSimpleStructUnmarshall [RPCRT4.@] - */ -unsigned char * WINAPI NdrSimpleStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char **ppMemory, - PFORMAT_STRING pFormat, - unsigned char fMustAlloc) -{ - unsigned size = *(const WORD*)(pFormat+2); - unsigned char *saved_buffer; - TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); - - ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1); - - if (fMustAlloc) - *ppMemory = NdrAllocate(pStubMsg, size); - else - { - if (!pStubMsg->IsClient && !*ppMemory) - /* for servers, we just point straight into the RPC buffer */ - *ppMemory = pStubMsg->Buffer; - } - - saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer; - safe_buffer_increment(pStubMsg, size); - if (pFormat[0] == RPC_FC_PSTRUCT) - EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat+4, fMustAlloc); - - TRACE("copying %p to %p\n", saved_buffer, *ppMemory); - if (*ppMemory != saved_buffer) - memcpy(*ppMemory, saved_buffer, size); - - return NULL; -} - -/*********************************************************************** - * NdrSimpleStructBufferSize [RPCRT4.@] - */ -void WINAPI NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - unsigned size = *(const WORD*)(pFormat+2); - TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); - - ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1); - - safe_buffer_length_increment(pStubMsg, size); - if (pFormat[0] != RPC_FC_STRUCT) - EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat+4); -} - -/*********************************************************************** - * NdrSimpleStructMemorySize [RPCRT4.@] - */ -ULONG WINAPI NdrSimpleStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg, - PFORMAT_STRING pFormat) -{ - unsigned short size = *(const WORD *)(pFormat+2); - - TRACE("(%p,%p)\n", pStubMsg, pFormat); - - ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1); - pStubMsg->MemorySize += size; - safe_buffer_increment(pStubMsg, size); - - if (pFormat[0] != RPC_FC_STRUCT) - EmbeddedPointerMemorySize(pStubMsg, pFormat+4); - return pStubMsg->MemorySize; -} - -/*********************************************************************** - * NdrSimpleStructFree [RPCRT4.@] - */ -void WINAPI NdrSimpleStructFree(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); - if (pFormat[0] != RPC_FC_STRUCT) - EmbeddedPointerFree(pStubMsg, pMemory, pFormat+4); -} - - -static unsigned long EmbeddedComplexSize(const MIDL_STUB_MESSAGE *pStubMsg, - PFORMAT_STRING pFormat) -{ - switch (*pFormat) { - case RPC_FC_STRUCT: - case RPC_FC_PSTRUCT: - case RPC_FC_CSTRUCT: - case RPC_FC_BOGUS_STRUCT: - case RPC_FC_SMFARRAY: - case RPC_FC_SMVARRAY: - return *(const WORD*)&pFormat[2]; - case RPC_FC_USER_MARSHAL: - return *(const WORD*)&pFormat[4]; - case RPC_FC_NON_ENCAPSULATED_UNION: - pFormat += 2; - if (pStubMsg->fHasNewCorrDesc) - pFormat += 6; - else - pFormat += 4; - - pFormat += *(const SHORT*)pFormat; - return *(const SHORT*)pFormat; - case RPC_FC_IP: - return sizeof(void *); - default: - FIXME("unhandled embedded type %02x\n", *pFormat); - } - return 0; -} - - -static unsigned long EmbeddedComplexMemorySize(PMIDL_STUB_MESSAGE pStubMsg, - PFORMAT_STRING pFormat) -{ - NDR_MEMORYSIZE m = NdrMemorySizer[*pFormat & NDR_TABLE_MASK]; - - if (!m) - { - FIXME("no memorysizer for data type=%02x\n", *pFormat); - return 0; - } - - return m(pStubMsg, pFormat); -} - - -static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat, - PFORMAT_STRING pPointer) -{ - PFORMAT_STRING desc; - NDR_MARSHALL m; - unsigned long size; - - while (*pFormat != RPC_FC_END) { - switch (*pFormat) { - case RPC_FC_BYTE: - case RPC_FC_CHAR: - case RPC_FC_SMALL: - case RPC_FC_USMALL: - TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory); - safe_copy_to_buffer(pStubMsg, pMemory, 1); - pMemory += 1; - break; - case RPC_FC_WCHAR: - case RPC_FC_SHORT: - case RPC_FC_USHORT: - TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory); - safe_copy_to_buffer(pStubMsg, pMemory, 2); - pMemory += 2; - break; - case RPC_FC_LONG: - case RPC_FC_ULONG: - case RPC_FC_ENUM32: - TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory); - safe_copy_to_buffer(pStubMsg, pMemory, 4); - pMemory += 4; - break; - case RPC_FC_HYPER: - TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory); - safe_copy_to_buffer(pStubMsg, pMemory, 8); - pMemory += 8; - break; - case RPC_FC_POINTER: - { - unsigned char *saved_buffer; - int pointer_buffer_mark_set = 0; - TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory); - ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4); - saved_buffer = pStubMsg->Buffer; - if (pStubMsg->PointerBufferMark) - { - pStubMsg->Buffer = pStubMsg->PointerBufferMark; - pStubMsg->PointerBufferMark = NULL; - pointer_buffer_mark_set = 1; - } - else - safe_buffer_increment(pStubMsg, 4); /* for pointer ID */ - PointerMarshall(pStubMsg, saved_buffer, *(unsigned char**)pMemory, pPointer); - if (pointer_buffer_mark_set) - { - STD_OVERFLOW_CHECK(pStubMsg); - pStubMsg->PointerBufferMark = pStubMsg->Buffer; - if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) - { - ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n", - saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - } - pStubMsg->Buffer = saved_buffer + 4; - } - pPointer += 4; - pMemory += 4; - break; - } - case RPC_FC_ALIGNM4: - ALIGN_POINTER(pMemory, 4); - break; - case RPC_FC_ALIGNM8: - ALIGN_POINTER(pMemory, 8); - break; - case RPC_FC_STRUCTPAD1: - case RPC_FC_STRUCTPAD2: - case RPC_FC_STRUCTPAD3: - case RPC_FC_STRUCTPAD4: - case RPC_FC_STRUCTPAD5: - case RPC_FC_STRUCTPAD6: - case RPC_FC_STRUCTPAD7: - pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1; - break; - case RPC_FC_EMBEDDED_COMPLEX: - pMemory += pFormat[1]; - pFormat += 2; - desc = pFormat + *(const SHORT*)pFormat; - size = EmbeddedComplexSize(pStubMsg, desc); - TRACE("embedded complex (size=%ld) <= %p\n", size, pMemory); - m = NdrMarshaller[*desc & NDR_TABLE_MASK]; - if (m) - { - /* for some reason interface pointers aren't generated as - * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet - * they still need the derefencing treatment that pointers are - * given */ - if (*desc == RPC_FC_IP) - m(pStubMsg, *(unsigned char **)pMemory, desc); - else - m(pStubMsg, pMemory, desc); - } - else FIXME("no marshaller for embedded type %02x\n", *desc); - pMemory += size; - pFormat += 2; - continue; - case RPC_FC_PAD: - break; - default: - FIXME("unhandled format 0x%02x\n", *pFormat); - } - pFormat++; - } - - return pMemory; -} - -static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat, - PFORMAT_STRING pPointer) -{ - PFORMAT_STRING desc; - NDR_UNMARSHALL m; - unsigned long size; - - while (*pFormat != RPC_FC_END) { - switch (*pFormat) { - case RPC_FC_BYTE: - case RPC_FC_CHAR: - case RPC_FC_SMALL: - case RPC_FC_USMALL: - safe_copy_from_buffer(pStubMsg, pMemory, 1); - TRACE("byte=%d => %p\n", *(WORD*)pMemory, pMemory); - pMemory += 1; - break; - case RPC_FC_WCHAR: - case RPC_FC_SHORT: - case RPC_FC_USHORT: - safe_copy_from_buffer(pStubMsg, pMemory, 2); - TRACE("short=%d => %p\n", *(WORD*)pMemory, pMemory); - pMemory += 2; - break; - case RPC_FC_LONG: - case RPC_FC_ULONG: - case RPC_FC_ENUM32: - safe_copy_from_buffer(pStubMsg, pMemory, 4); - TRACE("long=%d => %p\n", *(DWORD*)pMemory, pMemory); - pMemory += 4; - break; - case RPC_FC_HYPER: - safe_copy_from_buffer(pStubMsg, pMemory, 8); - TRACE("longlong=%s => %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory); - pMemory += 8; - break; - case RPC_FC_POINTER: - { - unsigned char *saved_buffer; - int pointer_buffer_mark_set = 0; - TRACE("pointer => %p\n", pMemory); - ALIGN_POINTER(pStubMsg->Buffer, 4); - saved_buffer = pStubMsg->Buffer; - if (pStubMsg->PointerBufferMark) - { - pStubMsg->Buffer = pStubMsg->PointerBufferMark; - pStubMsg->PointerBufferMark = NULL; - pointer_buffer_mark_set = 1; - } - else - safe_buffer_increment(pStubMsg, 4); /* for pointer ID */ - - PointerUnmarshall(pStubMsg, saved_buffer, (unsigned char**)pMemory, *(unsigned char**)pMemory, pPointer, TRUE); - if (pointer_buffer_mark_set) - { - STD_OVERFLOW_CHECK(pStubMsg); - pStubMsg->PointerBufferMark = pStubMsg->Buffer; - if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) - { - ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n", - saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - } - pStubMsg->Buffer = saved_buffer + 4; - } - pPointer += 4; - pMemory += 4; - break; - } - case RPC_FC_ALIGNM4: - ALIGN_POINTER_CLEAR(pMemory, 4); - break; - case RPC_FC_ALIGNM8: - ALIGN_POINTER_CLEAR(pMemory, 8); - break; - case RPC_FC_STRUCTPAD1: - case RPC_FC_STRUCTPAD2: - case RPC_FC_STRUCTPAD3: - case RPC_FC_STRUCTPAD4: - case RPC_FC_STRUCTPAD5: - case RPC_FC_STRUCTPAD6: - case RPC_FC_STRUCTPAD7: - memset(pMemory, 0, *pFormat - RPC_FC_STRUCTPAD1 + 1); - pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1; - break; - case RPC_FC_EMBEDDED_COMPLEX: - pMemory += pFormat[1]; - pFormat += 2; - desc = pFormat + *(const SHORT*)pFormat; - size = EmbeddedComplexSize(pStubMsg, desc); - TRACE("embedded complex (size=%ld) => %p\n", size, pMemory); - m = NdrUnmarshaller[*desc & NDR_TABLE_MASK]; - memset(pMemory, 0, size); /* just in case */ - if (m) - { - /* for some reason interface pointers aren't generated as - * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet - * they still need the derefencing treatment that pointers are - * given */ - if (*desc == RPC_FC_IP) - m(pStubMsg, (unsigned char **)pMemory, desc, FALSE); - else - m(pStubMsg, &pMemory, desc, FALSE); - } - else FIXME("no unmarshaller for embedded type %02x\n", *desc); - pMemory += size; - pFormat += 2; - continue; - case RPC_FC_PAD: - break; - default: - FIXME("unhandled format %d\n", *pFormat); - } - pFormat++; - } - - return pMemory; -} - -static unsigned char * ComplexBufferSize(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat, - PFORMAT_STRING pPointer) -{ - PFORMAT_STRING desc; - NDR_BUFFERSIZE m; - unsigned long size; - - while (*pFormat != RPC_FC_END) { - switch (*pFormat) { - case RPC_FC_BYTE: - case RPC_FC_CHAR: - case RPC_FC_SMALL: - case RPC_FC_USMALL: - safe_buffer_length_increment(pStubMsg, 1); - pMemory += 1; - break; - case RPC_FC_WCHAR: - case RPC_FC_SHORT: - case RPC_FC_USHORT: - safe_buffer_length_increment(pStubMsg, 2); - pMemory += 2; - break; - case RPC_FC_LONG: - case RPC_FC_ULONG: - case RPC_FC_ENUM32: - safe_buffer_length_increment(pStubMsg, 4); - pMemory += 4; - break; - case RPC_FC_HYPER: - safe_buffer_length_increment(pStubMsg, 8); - pMemory += 8; - break; - case RPC_FC_POINTER: - if (!pStubMsg->IgnoreEmbeddedPointers) - { - int saved_buffer_length = pStubMsg->BufferLength; - pStubMsg->BufferLength = pStubMsg->PointerLength; - pStubMsg->PointerLength = 0; - if(!pStubMsg->BufferLength) - ERR("BufferLength == 0??\n"); - PointerBufferSize(pStubMsg, *(unsigned char**)pMemory, pPointer); - pStubMsg->PointerLength = pStubMsg->BufferLength; - pStubMsg->BufferLength = saved_buffer_length; - } - safe_buffer_length_increment(pStubMsg, 4); - pPointer += 4; - pMemory += 4; - break; - case RPC_FC_ALIGNM4: - ALIGN_POINTER(pMemory, 4); - break; - case RPC_FC_ALIGNM8: - ALIGN_POINTER(pMemory, 8); - break; - case RPC_FC_STRUCTPAD1: - case RPC_FC_STRUCTPAD2: - case RPC_FC_STRUCTPAD3: - case RPC_FC_STRUCTPAD4: - case RPC_FC_STRUCTPAD5: - case RPC_FC_STRUCTPAD6: - case RPC_FC_STRUCTPAD7: - pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1; - break; - case RPC_FC_EMBEDDED_COMPLEX: - pMemory += pFormat[1]; - pFormat += 2; - desc = pFormat + *(const SHORT*)pFormat; - size = EmbeddedComplexSize(pStubMsg, desc); - m = NdrBufferSizer[*desc & NDR_TABLE_MASK]; - if (m) - { - /* for some reason interface pointers aren't generated as - * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet - * they still need the derefencing treatment that pointers are - * given */ - if (*desc == RPC_FC_IP) - m(pStubMsg, *(unsigned char **)pMemory, desc); - else - m(pStubMsg, pMemory, desc); - } - else FIXME("no buffersizer for embedded type %02x\n", *desc); - pMemory += size; - pFormat += 2; - continue; - case RPC_FC_PAD: - break; - default: - FIXME("unhandled format 0x%02x\n", *pFormat); - } - pFormat++; - } - - return pMemory; -} - -static unsigned char * ComplexFree(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat, - PFORMAT_STRING pPointer) -{ - PFORMAT_STRING desc; - NDR_FREE m; - unsigned long size; - - while (*pFormat != RPC_FC_END) { - switch (*pFormat) { - case RPC_FC_BYTE: - case RPC_FC_CHAR: - case RPC_FC_SMALL: - case RPC_FC_USMALL: - pMemory += 1; - break; - case RPC_FC_WCHAR: - case RPC_FC_SHORT: - case RPC_FC_USHORT: - pMemory += 2; - break; - case RPC_FC_LONG: - case RPC_FC_ULONG: - case RPC_FC_ENUM32: - pMemory += 4; - break; - case RPC_FC_HYPER: - pMemory += 8; - break; - case RPC_FC_POINTER: - NdrPointerFree(pStubMsg, *(unsigned char**)pMemory, pPointer); - pPointer += 4; - pMemory += 4; - break; - case RPC_FC_ALIGNM4: - ALIGN_POINTER(pMemory, 4); - break; - case RPC_FC_ALIGNM8: - ALIGN_POINTER(pMemory, 8); - break; - case RPC_FC_STRUCTPAD1: - case RPC_FC_STRUCTPAD2: - case RPC_FC_STRUCTPAD3: - case RPC_FC_STRUCTPAD4: - case RPC_FC_STRUCTPAD5: - case RPC_FC_STRUCTPAD6: - case RPC_FC_STRUCTPAD7: - pMemory += *pFormat - RPC_FC_STRUCTPAD1 + 1; - break; - case RPC_FC_EMBEDDED_COMPLEX: - pMemory += pFormat[1]; - pFormat += 2; - desc = pFormat + *(const SHORT*)pFormat; - size = EmbeddedComplexSize(pStubMsg, desc); - m = NdrFreer[*desc & NDR_TABLE_MASK]; - if (m) - { - /* for some reason interface pointers aren't generated as - * RPC_FC_POINTER, but instead as RPC_FC_EMBEDDED_COMPLEX, yet - * they still need the derefencing treatment that pointers are - * given */ - if (*desc == RPC_FC_IP) - m(pStubMsg, *(unsigned char **)pMemory, desc); - else - m(pStubMsg, pMemory, desc); - } - else FIXME("no freer for embedded type %02x\n", *desc); - pMemory += size; - pFormat += 2; - continue; - case RPC_FC_PAD: - break; - default: - FIXME("unhandled format 0x%02x\n", *pFormat); - } - pFormat++; - } - - return pMemory; -} - -static unsigned long ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg, - PFORMAT_STRING pFormat) -{ - PFORMAT_STRING desc; - unsigned long size = 0; - - while (*pFormat != RPC_FC_END) { - switch (*pFormat) { - case RPC_FC_BYTE: - case RPC_FC_CHAR: - case RPC_FC_SMALL: - case RPC_FC_USMALL: - size += 1; - safe_buffer_increment(pStubMsg, 1); - break; - case RPC_FC_WCHAR: - case RPC_FC_SHORT: - case RPC_FC_USHORT: - size += 2; - safe_buffer_increment(pStubMsg, 2); - break; - case RPC_FC_LONG: - case RPC_FC_ULONG: - case RPC_FC_ENUM32: - size += 4; - safe_buffer_increment(pStubMsg, 4); - break; - case RPC_FC_HYPER: - size += 8; - safe_buffer_increment(pStubMsg, 8); - break; - case RPC_FC_POINTER: - size += 4; - safe_buffer_increment(pStubMsg, 4); - if (!pStubMsg->IgnoreEmbeddedPointers) - FIXME("embedded pointers\n"); - break; - case RPC_FC_ALIGNM4: - ALIGN_LENGTH(size, 4); - ALIGN_POINTER(pStubMsg->Buffer, 4); - break; - case RPC_FC_ALIGNM8: - ALIGN_LENGTH(size, 8); - ALIGN_POINTER(pStubMsg->Buffer, 8); - break; - case RPC_FC_STRUCTPAD1: - case RPC_FC_STRUCTPAD2: - case RPC_FC_STRUCTPAD3: - case RPC_FC_STRUCTPAD4: - case RPC_FC_STRUCTPAD5: - case RPC_FC_STRUCTPAD6: - case RPC_FC_STRUCTPAD7: - size += *pFormat - RPC_FC_STRUCTPAD1 + 1; - break; - case RPC_FC_EMBEDDED_COMPLEX: - size += pFormat[1]; - pFormat += 2; - desc = pFormat + *(const SHORT*)pFormat; - size += EmbeddedComplexMemorySize(pStubMsg, desc); - pFormat += 2; - continue; - case RPC_FC_PAD: - break; - default: - FIXME("unhandled format 0x%02x\n", *pFormat); - } - pFormat++; - } - - return size; -} - -/*********************************************************************** - * NdrComplexStructMarshall [RPCRT4.@] - */ -unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - PFORMAT_STRING conf_array = NULL; - PFORMAT_STRING pointer_desc = NULL; - unsigned char *OldMemory = pStubMsg->Memory; - int pointer_buffer_mark_set = 0; - - TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); - - if (!pStubMsg->PointerBufferMark) - { - int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers; - /* save buffer length */ - unsigned long saved_buffer_length = pStubMsg->BufferLength; - - /* get the buffer pointer after complex array data, but before - * pointer data */ - pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart; - pStubMsg->IgnoreEmbeddedPointers = 1; - NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat); - pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded; - - /* save it for use by embedded pointer code later */ - pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength; - TRACE("difference = 0x%x\n", pStubMsg->PointerBufferMark - pStubMsg->Buffer); - pointer_buffer_mark_set = 1; - - /* restore the original buffer length */ - pStubMsg->BufferLength = saved_buffer_length; - } - - ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pFormat[1] + 1); - - pFormat += 4; - if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat; - pFormat += 2; - if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat; - pFormat += 2; - - pStubMsg->Memory = pMemory; - - ComplexMarshall(pStubMsg, pMemory, pFormat, pointer_desc); - - if (conf_array) - NdrConformantArrayMarshall(pStubMsg, pMemory, conf_array); - - pStubMsg->Memory = OldMemory; - - if (pointer_buffer_mark_set) - { - pStubMsg->Buffer = pStubMsg->PointerBufferMark; - pStubMsg->PointerBufferMark = NULL; - } - - STD_OVERFLOW_CHECK(pStubMsg); - - return NULL; -} - -/*********************************************************************** - * NdrComplexStructUnmarshall [RPCRT4.@] - */ -unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char **ppMemory, - PFORMAT_STRING pFormat, - unsigned char fMustAlloc) -{ - unsigned size = *(const WORD*)(pFormat+2); - PFORMAT_STRING conf_array = NULL; - PFORMAT_STRING pointer_desc = NULL; - unsigned char *pMemory; - int pointer_buffer_mark_set = 0; - - TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); - - if (!pStubMsg->PointerBufferMark) - { - int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers; - /* save buffer pointer */ - unsigned char *saved_buffer = pStubMsg->Buffer; - - /* get the buffer pointer after complex array data, but before - * pointer data */ - pStubMsg->IgnoreEmbeddedPointers = 1; - NdrComplexStructMemorySize(pStubMsg, pFormat); - pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded; - - /* save it for use by embedded pointer code later */ - pStubMsg->PointerBufferMark = pStubMsg->Buffer; - TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->PointerBufferMark - saved_buffer)); - pointer_buffer_mark_set = 1; - - /* restore the original buffer */ - pStubMsg->Buffer = saved_buffer; - } - - ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1); - - if (fMustAlloc || !*ppMemory) - { - *ppMemory = NdrAllocate(pStubMsg, size); - memset(*ppMemory, 0, size); - } - - pFormat += 4; - if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat; - pFormat += 2; - if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat; - pFormat += 2; - - pMemory = ComplexUnmarshall(pStubMsg, *ppMemory, pFormat, pointer_desc); - - if (conf_array) - NdrConformantArrayUnmarshall(pStubMsg, &pMemory, conf_array, fMustAlloc); - - if (pointer_buffer_mark_set) - { - pStubMsg->Buffer = pStubMsg->PointerBufferMark; - pStubMsg->PointerBufferMark = NULL; - } - - return NULL; -} - -/*********************************************************************** - * NdrComplexStructBufferSize [RPCRT4.@] - */ -void WINAPI NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - PFORMAT_STRING conf_array = NULL; - PFORMAT_STRING pointer_desc = NULL; - unsigned char *OldMemory = pStubMsg->Memory; - int pointer_length_set = 0; - - TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); - - ALIGN_LENGTH(pStubMsg->BufferLength, pFormat[1] + 1); - - if(!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength) - { - int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers; - unsigned long saved_buffer_length = pStubMsg->BufferLength; - - /* get the buffer length after complex struct data, but before - * pointer data */ - pStubMsg->IgnoreEmbeddedPointers = 1; - NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat); - pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded; - - /* save it for use by embedded pointer code later */ - pStubMsg->PointerLength = pStubMsg->BufferLength; - pointer_length_set = 1; - TRACE("difference = 0x%lx\n", pStubMsg->PointerLength - saved_buffer_length); - - /* restore the original buffer length */ - pStubMsg->BufferLength = saved_buffer_length; - } - - pFormat += 4; - if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat; - pFormat += 2; - if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat; - pFormat += 2; - - pStubMsg->Memory = pMemory; - - pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, pointer_desc); - - if (conf_array) - NdrConformantArrayBufferSize(pStubMsg, pMemory, conf_array); - - pStubMsg->Memory = OldMemory; - - if(pointer_length_set) - { - pStubMsg->BufferLength = pStubMsg->PointerLength; - pStubMsg->PointerLength = 0; - } - -} - -/*********************************************************************** - * NdrComplexStructMemorySize [RPCRT4.@] - */ -ULONG WINAPI NdrComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg, - PFORMAT_STRING pFormat) -{ - unsigned size = *(const WORD*)(pFormat+2); - PFORMAT_STRING conf_array = NULL; - PFORMAT_STRING pointer_desc = NULL; - - TRACE("(%p,%p)\n", pStubMsg, pFormat); - - ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1); - - pFormat += 4; - if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat; - pFormat += 2; - if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat; - pFormat += 2; - - ComplexStructMemorySize(pStubMsg, pFormat); - - if (conf_array) - NdrConformantArrayMemorySize(pStubMsg, conf_array); - - return size; -} - -/*********************************************************************** - * NdrComplexStructFree [RPCRT4.@] - */ -void WINAPI NdrComplexStructFree(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - PFORMAT_STRING conf_array = NULL; - PFORMAT_STRING pointer_desc = NULL; - unsigned char *OldMemory = pStubMsg->Memory; - - TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); - - pFormat += 4; - if (*(const WORD*)pFormat) conf_array = pFormat + *(const WORD*)pFormat; - pFormat += 2; - if (*(const WORD*)pFormat) pointer_desc = pFormat + *(const WORD*)pFormat; - pFormat += 2; - - pStubMsg->Memory = pMemory; - - pMemory = ComplexFree(pStubMsg, pMemory, pFormat, pointer_desc); - - if (conf_array) - NdrConformantArrayFree(pStubMsg, pMemory, conf_array); - - pStubMsg->Memory = OldMemory; -} - -/*********************************************************************** - * NdrConformantArrayMarshall [RPCRT4.@] - */ -unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - DWORD size = 0, esize = *(const WORD*)(pFormat+2); - unsigned char alignment = pFormat[1] + 1; - - TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); - if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]); - - pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0); - - WriteConformance(pStubMsg); - - ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment); - - size = safe_multiply(esize, pStubMsg->MaxCount); - pStubMsg->BufferMark = pStubMsg->Buffer; - safe_copy_to_buffer(pStubMsg, pMemory, size); - - EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat); - - return NULL; -} - -/*********************************************************************** - * NdrConformantArrayUnmarshall [RPCRT4.@] - */ -unsigned char * WINAPI NdrConformantArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char **ppMemory, - PFORMAT_STRING pFormat, - unsigned char fMustAlloc) -{ - DWORD size, esize = *(const WORD*)(pFormat+2); - unsigned char alignment = pFormat[1] + 1; - unsigned char *saved_buffer; - - TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); - if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]); - - pFormat = ReadConformance(pStubMsg, pFormat+4); - - size = safe_multiply(esize, pStubMsg->MaxCount); - ALIGN_POINTER(pStubMsg->Buffer, alignment); - - if (fMustAlloc) - *ppMemory = NdrAllocate(pStubMsg, size); - else - { - if (!pStubMsg->IsClient && !*ppMemory) - /* for servers, we just point straight into the RPC buffer */ - *ppMemory = pStubMsg->Buffer; - } - - saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer; - safe_buffer_increment(pStubMsg, size); - EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc); - - TRACE("copying %p to %p\n", saved_buffer, *ppMemory); - if (*ppMemory != saved_buffer) - memcpy(*ppMemory, saved_buffer, size); - - return NULL; -} - -/*********************************************************************** - * NdrConformantArrayBufferSize [RPCRT4.@] - */ -void WINAPI NdrConformantArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - DWORD size, esize = *(const WORD*)(pFormat+2); - unsigned char alignment = pFormat[1] + 1; - - TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); - if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]); - - pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0); - - SizeConformance(pStubMsg); - - ALIGN_LENGTH(pStubMsg->BufferLength, alignment); - - size = safe_multiply(esize, pStubMsg->MaxCount); - /* conformance value plus array */ - safe_buffer_length_increment(pStubMsg, size); - - EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat); -} - -/*********************************************************************** - * NdrConformantArrayMemorySize [RPCRT4.@] - */ -ULONG WINAPI NdrConformantArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg, - PFORMAT_STRING pFormat) -{ - DWORD size = 0, esize = *(const WORD*)(pFormat+2); - unsigned char alignment = pFormat[1] + 1; - - TRACE("(%p,%p)\n", pStubMsg, pFormat); - if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]); - - pFormat = ReadConformance(pStubMsg, pFormat+4); - size = safe_multiply(esize, pStubMsg->MaxCount); - pStubMsg->MemorySize += size; - - ALIGN_POINTER(pStubMsg->Buffer, alignment); - pStubMsg->BufferMark = pStubMsg->Buffer; - safe_buffer_increment(pStubMsg, size); - - EmbeddedPointerMemorySize(pStubMsg, pFormat); - - return pStubMsg->MemorySize; -} - -/*********************************************************************** - * NdrConformantArrayFree [RPCRT4.@] - */ -void WINAPI NdrConformantArrayFree(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); - if (pFormat[0] != RPC_FC_CARRAY) FIXME("format=%d\n", pFormat[0]); - - pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0); - - EmbeddedPointerFree(pStubMsg, pMemory, pFormat); -} - - -/*********************************************************************** - * NdrConformantVaryingArrayMarshall [RPCRT4.@] - */ -unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStubMsg, - unsigned char* pMemory, - PFORMAT_STRING pFormat ) -{ - ULONG bufsize; - unsigned char alignment = pFormat[1] + 1; - DWORD esize = *(const WORD*)(pFormat+2); - - TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); - - if (pFormat[0] != RPC_FC_CVARRAY) - { - ERR("invalid format type %x\n", pFormat[0]); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return NULL; - } - - pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0); - pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0); - - WriteConformance(pStubMsg); - WriteVariance(pStubMsg); - - ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment); - - bufsize = safe_multiply(esize, pStubMsg->ActualCount); - - pStubMsg->BufferMark = pStubMsg->Buffer; - safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize); - - EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat); - - return NULL; -} - - -/*********************************************************************** - * NdrConformantVaryingArrayUnmarshall [RPCRT4.@] - */ -unsigned char* WINAPI NdrConformantVaryingArrayUnmarshall( PMIDL_STUB_MESSAGE pStubMsg, - unsigned char** ppMemory, - PFORMAT_STRING pFormat, - unsigned char fMustAlloc ) -{ - 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); - - if (pFormat[0] != RPC_FC_CVARRAY) - { - ERR("invalid format type %x\n", pFormat[0]); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return NULL; - } - - pFormat = ReadConformance(pStubMsg, pFormat+4); - pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount); - - ALIGN_POINTER(pStubMsg->Buffer, alignment); - - bufsize = safe_multiply(esize, pStubMsg->ActualCount); - memsize = safe_multiply(esize, pStubMsg->MaxCount); - offset = pStubMsg->Offset; - - if (!*ppMemory || fMustAlloc) - *ppMemory = NdrAllocate(pStubMsg, memsize); - saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer; - safe_buffer_increment(pStubMsg, bufsize); - - EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc); - - memcpy(*ppMemory + offset, saved_buffer, bufsize); - - return NULL; -} - - -/*********************************************************************** - * NdrConformantVaryingArrayFree [RPCRT4.@] - */ -void WINAPI NdrConformantVaryingArrayFree( PMIDL_STUB_MESSAGE pStubMsg, - unsigned char* pMemory, - PFORMAT_STRING pFormat ) -{ - TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); - - if (pFormat[0] != RPC_FC_CVARRAY) - { - ERR("invalid format type %x\n", pFormat[0]); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return; - } - - pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0); - pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0); - - EmbeddedPointerFree(pStubMsg, pMemory, pFormat); -} - - -/*********************************************************************** - * NdrConformantVaryingArrayBufferSize [RPCRT4.@] - */ -void WINAPI NdrConformantVaryingArrayBufferSize( PMIDL_STUB_MESSAGE pStubMsg, - unsigned char* pMemory, PFORMAT_STRING pFormat ) -{ - unsigned char alignment = pFormat[1] + 1; - DWORD esize = *(const WORD*)(pFormat+2); - - TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); - - if (pFormat[0] != RPC_FC_CVARRAY) - { - ERR("invalid format type %x\n", pFormat[0]); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return; - } - - /* compute size */ - pFormat = ComputeConformance(pStubMsg, pMemory, pFormat+4, 0); - /* compute length */ - pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0); - - SizeConformance(pStubMsg); - SizeVariance(pStubMsg); - - ALIGN_LENGTH(pStubMsg->BufferLength, alignment); - - safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount)); - - EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat); -} - - -/*********************************************************************** - * NdrConformantVaryingArrayMemorySize [RPCRT4.@] - */ -ULONG WINAPI NdrConformantVaryingArrayMemorySize( PMIDL_STUB_MESSAGE pStubMsg, - PFORMAT_STRING pFormat ) -{ - ULONG bufsize, memsize; - unsigned char alignment = pFormat[1] + 1; - DWORD esize = *(const WORD*)(pFormat+2); - - TRACE("(%p, %p)\n", pStubMsg, pFormat); - - if (pFormat[0] != RPC_FC_CVARRAY) - { - ERR("invalid format type %x\n", pFormat[0]); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return pStubMsg->MemorySize; - } - - pFormat = ReadConformance(pStubMsg, pFormat+4); - pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount); - - ALIGN_POINTER(pStubMsg->Buffer, alignment); - - bufsize = safe_multiply(esize, pStubMsg->ActualCount); - memsize = safe_multiply(esize, pStubMsg->MaxCount); - - safe_buffer_increment(pStubMsg, bufsize); - pStubMsg->MemorySize += memsize; - - EmbeddedPointerMemorySize(pStubMsg, pFormat); - - return pStubMsg->MemorySize; -} - - -/*********************************************************************** - * NdrComplexArrayMarshall [RPCRT4.@] - */ -unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - ULONG i, count, def; - BOOL variance_present; - unsigned char alignment; - int pointer_buffer_mark_set = 0; - - TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); - - if (pFormat[0] != RPC_FC_BOGUS_ARRAY) - { - ERR("invalid format type %x\n", pFormat[0]); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return NULL; - } - - alignment = pFormat[1] + 1; - - if (!pStubMsg->PointerBufferMark) - { - /* save buffer fields that may be changed by buffer sizer functions - * and that may be needed later on */ - int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers; - unsigned long saved_buffer_length = pStubMsg->BufferLength; - unsigned long saved_max_count = pStubMsg->MaxCount; - unsigned long saved_offset = pStubMsg->Offset; - unsigned long saved_actual_count = pStubMsg->ActualCount; - - /* get the buffer pointer after complex array data, but before - * pointer data */ - pStubMsg->BufferLength = pStubMsg->Buffer - pStubMsg->BufferStart; - pStubMsg->IgnoreEmbeddedPointers = 1; - NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat); - pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded; - - /* save it for use by embedded pointer code later */ - pStubMsg->PointerBufferMark = pStubMsg->BufferStart + pStubMsg->BufferLength; - TRACE("difference = 0x%x\n", pStubMsg->Buffer - pStubMsg->BufferStart); - pointer_buffer_mark_set = 1; - - /* restore fields */ - pStubMsg->ActualCount = saved_actual_count; - pStubMsg->Offset = saved_offset; - pStubMsg->MaxCount = saved_max_count; - pStubMsg->BufferLength = saved_buffer_length; - } - - def = *(const WORD*)&pFormat[2]; - pFormat += 4; - - pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def); - TRACE("conformance = %ld\n", pStubMsg->MaxCount); - - variance_present = IsConformanceOrVariancePresent(pFormat); - pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount); - TRACE("variance = %d\n", pStubMsg->ActualCount); - - WriteConformance(pStubMsg); - if (variance_present) - WriteVariance(pStubMsg); - - ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment); - - count = pStubMsg->ActualCount; - for (i = 0; i < count; i++) - pMemory = ComplexMarshall(pStubMsg, pMemory, pFormat, NULL); - - STD_OVERFLOW_CHECK(pStubMsg); - - if (pointer_buffer_mark_set) - { - pStubMsg->Buffer = pStubMsg->PointerBufferMark; - pStubMsg->PointerBufferMark = NULL; - } - - return NULL; -} - -/*********************************************************************** - * NdrComplexArrayUnmarshall [RPCRT4.@] - */ -unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char **ppMemory, - PFORMAT_STRING pFormat, - unsigned char fMustAlloc) -{ - ULONG i, count, size; - unsigned char alignment; - unsigned char *pMemory; - unsigned char *saved_buffer; - int pointer_buffer_mark_set = 0; - int saved_ignore_embedded; - - TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); - - if (pFormat[0] != RPC_FC_BOGUS_ARRAY) - { - ERR("invalid format type %x\n", pFormat[0]); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return NULL; - } - - alignment = pFormat[1] + 1; - - saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers; - /* save buffer pointer */ - saved_buffer = pStubMsg->Buffer; - /* get the buffer pointer after complex array data, but before - * pointer data */ - pStubMsg->IgnoreEmbeddedPointers = 1; - pStubMsg->MemorySize = 0; - NdrComplexArrayMemorySize(pStubMsg, pFormat); - size = pStubMsg->MemorySize; - pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded; - - TRACE("difference = 0x%lx\n", (unsigned long)(pStubMsg->Buffer - saved_buffer)); - if (!pStubMsg->PointerBufferMark) - { - /* save it for use by embedded pointer code later */ - pStubMsg->PointerBufferMark = pStubMsg->Buffer; - pointer_buffer_mark_set = 1; - } - /* restore the original buffer */ - pStubMsg->Buffer = saved_buffer; - - pFormat += 4; - - pFormat = ReadConformance(pStubMsg, pFormat); - pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount); - - if (fMustAlloc || !*ppMemory) - { - *ppMemory = NdrAllocate(pStubMsg, size); - memset(*ppMemory, 0, size); - } - - ALIGN_POINTER(pStubMsg->Buffer, alignment); - - pMemory = *ppMemory; - count = pStubMsg->ActualCount; - for (i = 0; i < count; i++) - pMemory = ComplexUnmarshall(pStubMsg, pMemory, pFormat, NULL); - - if (pointer_buffer_mark_set) - { - pStubMsg->Buffer = pStubMsg->PointerBufferMark; - pStubMsg->PointerBufferMark = NULL; - } - - return NULL; -} - -/*********************************************************************** - * NdrComplexArrayBufferSize [RPCRT4.@] - */ -void WINAPI NdrComplexArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - ULONG i, count, def; - unsigned char alignment; - BOOL variance_present; - int pointer_length_set = 0; - - TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); - - if (pFormat[0] != RPC_FC_BOGUS_ARRAY) - { - ERR("invalid format type %x\n", pFormat[0]); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return; - } - - alignment = pFormat[1] + 1; - - if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength) - { - /* save buffer fields that may be changed by buffer sizer functions - * and that may be needed later on */ - int saved_ignore_embedded = pStubMsg->IgnoreEmbeddedPointers; - unsigned long saved_buffer_length = pStubMsg->BufferLength; - unsigned long saved_max_count = pStubMsg->MaxCount; - unsigned long saved_offset = pStubMsg->Offset; - unsigned long saved_actual_count = pStubMsg->ActualCount; - - /* get the buffer pointer after complex array data, but before - * pointer data */ - pStubMsg->IgnoreEmbeddedPointers = 1; - NdrComplexArrayBufferSize(pStubMsg, pMemory, pFormat); - pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded; - - /* save it for use by embedded pointer code later */ - pStubMsg->PointerLength = pStubMsg->BufferLength; - pointer_length_set = 1; - - /* restore fields */ - pStubMsg->ActualCount = saved_actual_count; - pStubMsg->Offset = saved_offset; - pStubMsg->MaxCount = saved_max_count; - pStubMsg->BufferLength = saved_buffer_length; - } - def = *(const WORD*)&pFormat[2]; - pFormat += 4; - - pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def); - TRACE("conformance = %ld\n", pStubMsg->MaxCount); - SizeConformance(pStubMsg); - - variance_present = IsConformanceOrVariancePresent(pFormat); - pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount); - TRACE("variance = %d\n", pStubMsg->ActualCount); - - if (variance_present) - SizeVariance(pStubMsg); - - ALIGN_LENGTH(pStubMsg->BufferLength, alignment); - - count = pStubMsg->ActualCount; - for (i = 0; i < count; i++) - pMemory = ComplexBufferSize(pStubMsg, pMemory, pFormat, NULL); - - if(pointer_length_set) - { - pStubMsg->BufferLength = pStubMsg->PointerLength; - pStubMsg->PointerLength = 0; - } -} - -/*********************************************************************** - * NdrComplexArrayMemorySize [RPCRT4.@] - */ -ULONG WINAPI NdrComplexArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg, - PFORMAT_STRING pFormat) -{ - ULONG i, count, esize, SavedMemorySize, MemorySize; - unsigned char alignment; - unsigned char *Buffer; - - TRACE("(%p,%p)\n", pStubMsg, pFormat); - - if (pFormat[0] != RPC_FC_BOGUS_ARRAY) - { - ERR("invalid format type %x\n", pFormat[0]); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return 0; - } - - alignment = pFormat[1] + 1; - - pFormat += 4; - - pFormat = ReadConformance(pStubMsg, pFormat); - pFormat = ReadVariance(pStubMsg, pFormat, pStubMsg->MaxCount); - - ALIGN_POINTER(pStubMsg->Buffer, alignment); - - SavedMemorySize = pStubMsg->MemorySize; - - Buffer = pStubMsg->Buffer; - pStubMsg->MemorySize = 0; - esize = ComplexStructMemorySize(pStubMsg, pFormat); - pStubMsg->Buffer = Buffer; - - MemorySize = safe_multiply(pStubMsg->MaxCount, esize); - - count = pStubMsg->ActualCount; - for (i = 0; i < count; i++) - ComplexStructMemorySize(pStubMsg, pFormat); - - pStubMsg->MemorySize = SavedMemorySize; - - pStubMsg->MemorySize += MemorySize; - return MemorySize; -} - -/*********************************************************************** - * NdrComplexArrayFree [RPCRT4.@] - */ -void WINAPI NdrComplexArrayFree(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - ULONG i, count, def; - - TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); - - if (pFormat[0] != RPC_FC_BOGUS_ARRAY) - { - ERR("invalid format type %x\n", pFormat[0]); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return; - } - - def = *(const WORD*)&pFormat[2]; - pFormat += 4; - - pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, def); - TRACE("conformance = %ld\n", pStubMsg->MaxCount); - - pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, pStubMsg->MaxCount); - TRACE("variance = %d\n", pStubMsg->ActualCount); - - count = pStubMsg->ActualCount; - for (i = 0; i < count; i++) - pMemory = ComplexFree(pStubMsg, pMemory, pFormat, NULL); -} - -static void UserMarshalCB(PMIDL_STUB_MESSAGE pStubMsg, - USER_MARSHAL_CB_TYPE cbtype, PFORMAT_STRING pFormat, - USER_MARSHAL_CB *umcb) -{ - umcb->Flags = MAKELONG(pStubMsg->dwDestContext, - pStubMsg->RpcMsg->DataRepresentation); - umcb->pStubMsg = pStubMsg; - umcb->pReserve = NULL; - umcb->Signature = USER_MARSHAL_CB_SIGNATURE; - umcb->CBType = cbtype; - umcb->pFormat = pFormat; - umcb->pTypeFormat = NULL /* FIXME */; -} - -#define USER_MARSHAL_PTR_PREFIX \ - ( (DWORD)'U' | ( (DWORD)'s' << 8 ) | \ - ( (DWORD)'e' << 16 ) | ( (DWORD)'r' << 24 ) ) - -/*********************************************************************** - * NdrUserMarshalMarshall [RPCRT4.@] - */ -unsigned char * WINAPI NdrUserMarshalMarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - unsigned flags = pFormat[1]; - unsigned index = *(const WORD*)&pFormat[2]; - unsigned char *saved_buffer = NULL; - USER_MARSHAL_CB umcb; - - TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); - TRACE("index=%d\n", index); - - UserMarshalCB(pStubMsg, USER_MARSHAL_CB_MARSHALL, pFormat, &umcb); - - if (flags & USER_MARSHAL_POINTER) - { - ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4); - NDR_LOCAL_UINT32_WRITE(pStubMsg->Buffer, USER_MARSHAL_PTR_PREFIX); - pStubMsg->Buffer += 4; - if (pStubMsg->PointerBufferMark) - { - saved_buffer = pStubMsg->Buffer; - pStubMsg->Buffer = pStubMsg->PointerBufferMark; - pStubMsg->PointerBufferMark = NULL; - } - ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 8); - } - else - ALIGN_POINTER_CLEAR(pStubMsg->Buffer, (flags & 0xf) + 1); - - pStubMsg->Buffer = - pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnMarshall( - &umcb.Flags, pStubMsg->Buffer, pMemory); - - if (saved_buffer) - { - STD_OVERFLOW_CHECK(pStubMsg); - pStubMsg->PointerBufferMark = pStubMsg->Buffer; - pStubMsg->Buffer = saved_buffer; - } - - STD_OVERFLOW_CHECK(pStubMsg); - - return NULL; -} - -/*********************************************************************** - * NdrUserMarshalUnmarshall [RPCRT4.@] - */ -unsigned char * WINAPI NdrUserMarshalUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char **ppMemory, - PFORMAT_STRING pFormat, - unsigned char fMustAlloc) -{ - unsigned flags = pFormat[1]; - unsigned index = *(const WORD*)&pFormat[2]; - DWORD memsize = *(const WORD*)&pFormat[4]; - unsigned char *saved_buffer = NULL; - USER_MARSHAL_CB umcb; - - TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); - TRACE("index=%d\n", index); - - UserMarshalCB(pStubMsg, USER_MARSHAL_CB_UNMARSHALL, pFormat, &umcb); - - if (flags & USER_MARSHAL_POINTER) - { - ALIGN_POINTER(pStubMsg->Buffer, 4); - /* skip pointer prefix */ - pStubMsg->Buffer += 4; - if (pStubMsg->PointerBufferMark) - { - saved_buffer = pStubMsg->Buffer; - pStubMsg->Buffer = pStubMsg->PointerBufferMark; - pStubMsg->PointerBufferMark = NULL; - } - ALIGN_POINTER(pStubMsg->Buffer, 8); - } - else - ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1); - - if (fMustAlloc || !*ppMemory) - *ppMemory = NdrAllocate(pStubMsg, memsize); - - pStubMsg->Buffer = - pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnUnmarshall( - &umcb.Flags, pStubMsg->Buffer, *ppMemory); - - if (saved_buffer) - { - STD_OVERFLOW_CHECK(pStubMsg); - pStubMsg->PointerBufferMark = pStubMsg->Buffer; - pStubMsg->Buffer = saved_buffer; - } - - return NULL; -} - -/*********************************************************************** - * NdrUserMarshalBufferSize [RPCRT4.@] - */ -void WINAPI NdrUserMarshalBufferSize(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - unsigned flags = pFormat[1]; - unsigned index = *(const WORD*)&pFormat[2]; - DWORD bufsize = *(const WORD*)&pFormat[6]; - USER_MARSHAL_CB umcb; - unsigned long saved_buffer_length = 0; - - TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); - TRACE("index=%d\n", index); - - UserMarshalCB(pStubMsg, USER_MARSHAL_CB_BUFFER_SIZE, pFormat, &umcb); - - if (flags & USER_MARSHAL_POINTER) - { - ALIGN_LENGTH(pStubMsg->BufferLength, 4); - /* skip pointer prefix */ - safe_buffer_length_increment(pStubMsg, 4); - if (pStubMsg->IgnoreEmbeddedPointers) - return; - if (pStubMsg->PointerLength) - { - saved_buffer_length = pStubMsg->BufferLength; - pStubMsg->BufferLength = pStubMsg->PointerLength; - pStubMsg->PointerLength = 0; - } - ALIGN_LENGTH(pStubMsg->BufferLength, 8); - } - else - ALIGN_LENGTH(pStubMsg->BufferLength, (flags & 0xf) + 1); - - if (bufsize) { - TRACE("size=%d\n", bufsize); - safe_buffer_length_increment(pStubMsg, bufsize); - } - else - pStubMsg->BufferLength = - pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnBufferSize( - &umcb.Flags, pStubMsg->BufferLength, pMemory); - - if (saved_buffer_length) - { - pStubMsg->PointerLength = pStubMsg->BufferLength; - pStubMsg->BufferLength = saved_buffer_length; - } - -} - -/*********************************************************************** - * NdrUserMarshalMemorySize [RPCRT4.@] - */ -ULONG WINAPI NdrUserMarshalMemorySize(PMIDL_STUB_MESSAGE pStubMsg, - PFORMAT_STRING pFormat) -{ - unsigned flags = pFormat[1]; - unsigned index = *(const WORD*)&pFormat[2]; - DWORD memsize = *(const WORD*)&pFormat[4]; - DWORD bufsize = *(const WORD*)&pFormat[6]; - - TRACE("(%p,%p)\n", pStubMsg, pFormat); - TRACE("index=%d\n", index); - - pStubMsg->MemorySize += memsize; - - if (flags & USER_MARSHAL_POINTER) - { - ALIGN_POINTER(pStubMsg->Buffer, 4); - /* skip pointer prefix */ - pStubMsg->Buffer += 4; - if (pStubMsg->IgnoreEmbeddedPointers) - return pStubMsg->MemorySize; - ALIGN_POINTER(pStubMsg->Buffer, 8); - } - else - ALIGN_POINTER(pStubMsg->Buffer, (flags & 0xf) + 1); - - if (!bufsize) - FIXME("not implemented for varying buffer size\n"); - - pStubMsg->Buffer += bufsize; - - return pStubMsg->MemorySize; -} - -/*********************************************************************** - * NdrUserMarshalFree [RPCRT4.@] - */ -void WINAPI NdrUserMarshalFree(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ -/* unsigned flags = pFormat[1]; */ - unsigned index = *(const WORD*)&pFormat[2]; - USER_MARSHAL_CB umcb; - - TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); - TRACE("index=%d\n", index); - - UserMarshalCB(pStubMsg, USER_MARSHAL_CB_FREE, pFormat, &umcb); - - pStubMsg->StubDesc->aUserMarshalQuadruple[index].pfnFree( - &umcb.Flags, pMemory); -} - -/*********************************************************************** - * NdrClearOutParameters [RPCRT4.@] - */ -void WINAPI NdrClearOutParameters(PMIDL_STUB_MESSAGE pStubMsg, - PFORMAT_STRING pFormat, - void *ArgAddr) -{ - FIXME("(%p,%p,%p): stub\n", pStubMsg, pFormat, ArgAddr); -} - -/*********************************************************************** - * NdrConvert [RPCRT4.@] - */ -void WINAPI NdrConvert( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat ) -{ - FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat); - /* FIXME: since this stub doesn't do any converting, the proper behavior - is to raise an exception */ -} - -/*********************************************************************** - * NdrConvert2 [RPCRT4.@] - */ -void WINAPI NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, LONG NumberParams ) -{ - FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %d): stub.\n", - pStubMsg, pFormat, NumberParams); - /* FIXME: since this stub doesn't do any converting, the proper behavior - is to raise an exception */ -} - -#include "pshpack1.h" -typedef struct _NDR_CSTRUCT_FORMAT -{ - unsigned char type; - unsigned char alignment; - unsigned short memory_size; - short offset_to_array_description; -} NDR_CSTRUCT_FORMAT, NDR_CVSTRUCT_FORMAT; -#include "poppack.h" - -/*********************************************************************** - * NdrConformantStructMarshall [RPCRT4.@] - */ -unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat; - PFORMAT_STRING pCArrayFormat; - ULONG esize, bufsize; - - TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); - - pFormat += sizeof(NDR_CSTRUCT_FORMAT); - if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT)) - { - ERR("invalid format type %x\n", pCStructFormat->type); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return NULL; - } - - pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description + - pCStructFormat->offset_to_array_description; - if (*pCArrayFormat != RPC_FC_CARRAY) - { - ERR("invalid array format type %x\n", pCStructFormat->type); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return NULL; - } - esize = *(const WORD*)(pCArrayFormat+2); - - ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, - pCArrayFormat + 4, 0); - - WriteConformance(pStubMsg); - - ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCStructFormat->alignment + 1); - - TRACE("memory_size = %d\n", pCStructFormat->memory_size); - - bufsize = safe_multiply(esize, pStubMsg->MaxCount); - if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */ - { - ERR("integer overflow of memory_size %u with bufsize %u\n", - pCStructFormat->memory_size, bufsize); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - } - /* copy constant sized part of struct */ - pStubMsg->BufferMark = pStubMsg->Buffer; - safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize); - - if (pCStructFormat->type == RPC_FC_CPSTRUCT) - EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat); - - return NULL; -} - -/*********************************************************************** - * NdrConformantStructUnmarshall [RPCRT4.@] - */ -unsigned char * WINAPI NdrConformantStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char **ppMemory, - PFORMAT_STRING pFormat, - unsigned char fMustAlloc) -{ - const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat; - PFORMAT_STRING pCArrayFormat; - ULONG esize, bufsize; - unsigned char *saved_buffer; - - TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); - - pFormat += sizeof(NDR_CSTRUCT_FORMAT); - if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT)) - { - ERR("invalid format type %x\n", pCStructFormat->type); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return NULL; - } - pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description + - pCStructFormat->offset_to_array_description; - if (*pCArrayFormat != RPC_FC_CARRAY) - { - ERR("invalid array format type %x\n", pCStructFormat->type); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return NULL; - } - esize = *(const WORD*)(pCArrayFormat+2); - - pCArrayFormat = ReadConformance(pStubMsg, pCArrayFormat + 4); - - ALIGN_POINTER(pStubMsg->Buffer, pCStructFormat->alignment + 1); - - TRACE("memory_size = %d\n", pCStructFormat->memory_size); - - bufsize = safe_multiply(esize, pStubMsg->MaxCount); - if (pCStructFormat->memory_size + bufsize < pCStructFormat->memory_size) /* integer overflow */ - { - ERR("integer overflow of memory_size %u with bufsize %u\n", - pCStructFormat->memory_size, bufsize); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - } - - if (fMustAlloc) - { - SIZE_T size = pCStructFormat->memory_size + bufsize; - *ppMemory = NdrAllocate(pStubMsg, size); - } - else - { - if (!pStubMsg->IsClient && !*ppMemory) - /* for servers, we just point straight into the RPC buffer */ - *ppMemory = pStubMsg->Buffer; - } - - saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer; - safe_buffer_increment(pStubMsg, pCStructFormat->memory_size + bufsize); - if (pCStructFormat->type == RPC_FC_CPSTRUCT) - EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc); - - TRACE("copying %p to %p\n", saved_buffer, *ppMemory); - if (*ppMemory != saved_buffer) - memcpy(*ppMemory, saved_buffer, pCStructFormat->memory_size + bufsize); - - return NULL; -} - -/*********************************************************************** - * NdrConformantStructBufferSize [RPCRT4.@] - */ -void WINAPI NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - const NDR_CSTRUCT_FORMAT * pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat; - PFORMAT_STRING pCArrayFormat; - ULONG esize; - - TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); - - pFormat += sizeof(NDR_CSTRUCT_FORMAT); - if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT)) - { - ERR("invalid format type %x\n", pCStructFormat->type); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return; - } - pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description + - pCStructFormat->offset_to_array_description; - if (*pCArrayFormat != RPC_FC_CARRAY) - { - ERR("invalid array format type %x\n", pCStructFormat->type); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return; - } - esize = *(const WORD*)(pCArrayFormat+2); - - pCArrayFormat = ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, pCArrayFormat+4, 0); - SizeConformance(pStubMsg); - - ALIGN_LENGTH(pStubMsg->BufferLength, pCStructFormat->alignment + 1); - - TRACE("memory_size = %d\n", pCStructFormat->memory_size); - - safe_buffer_length_increment(pStubMsg, pCStructFormat->memory_size); - safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize)); - - if (pCStructFormat->type == RPC_FC_CPSTRUCT) - EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat); -} - -/*********************************************************************** - * NdrConformantStructMemorySize [RPCRT4.@] - */ -ULONG WINAPI NdrConformantStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg, - PFORMAT_STRING pFormat) -{ - FIXME("stub\n"); - return 0; -} - -/*********************************************************************** - * NdrConformantStructFree [RPCRT4.@] - */ -void WINAPI NdrConformantStructFree(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - const NDR_CSTRUCT_FORMAT *pCStructFormat = (const NDR_CSTRUCT_FORMAT *)pFormat; - PFORMAT_STRING pCArrayFormat; - ULONG esize; - - TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); - - pFormat += sizeof(NDR_CSTRUCT_FORMAT); - if ((pCStructFormat->type != RPC_FC_CPSTRUCT) && (pCStructFormat->type != RPC_FC_CSTRUCT)) - { - ERR("invalid format type %x\n", pCStructFormat->type); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return; - } - - pCArrayFormat = (const unsigned char *)&pCStructFormat->offset_to_array_description + - pCStructFormat->offset_to_array_description; - if (*pCArrayFormat != RPC_FC_CARRAY) - { - ERR("invalid array format type %x\n", pCStructFormat->type); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return; - } - esize = *(const WORD*)(pCArrayFormat+2); - - ComputeConformance(pStubMsg, pMemory + pCStructFormat->memory_size, - pCArrayFormat + 4, 0); - - TRACE("memory_size = %d\n", pCStructFormat->memory_size); - - /* copy constant sized part of struct */ - pStubMsg->BufferMark = pStubMsg->Buffer; - - if (pCStructFormat->type == RPC_FC_CPSTRUCT) - EmbeddedPointerFree(pStubMsg, pMemory, pFormat); -} - -/*********************************************************************** - * NdrConformantVaryingStructMarshall [RPCRT4.@] - */ -unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat; - PFORMAT_STRING pCVArrayFormat; - ULONG esize, bufsize; - - TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); - - pFormat += sizeof(NDR_CVSTRUCT_FORMAT); - if (pCVStructFormat->type != RPC_FC_CVSTRUCT) - { - ERR("invalid format type %x\n", pCVStructFormat->type); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return NULL; - } - - pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description + - pCVStructFormat->offset_to_array_description; - switch (*pCVArrayFormat) - { - case RPC_FC_CVARRAY: - esize = *(const WORD*)(pCVArrayFormat+2); - - pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size, - pCVArrayFormat + 4, 0); - pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size, - pCVArrayFormat, 0); - break; - case RPC_FC_C_CSTRING: - TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size)); - pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1; - esize = sizeof(char); - if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED) - pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size, - pCVArrayFormat + 2, 0); - else - pStubMsg->MaxCount = pStubMsg->ActualCount; - break; - case RPC_FC_C_WSTRING: - TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size)); - pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1; - esize = sizeof(WCHAR); - if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED) - pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size, - pCVArrayFormat + 2, 0); - else - pStubMsg->MaxCount = pStubMsg->ActualCount; - break; - default: - ERR("invalid array format type %x\n", *pCVArrayFormat); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return NULL; - } - - WriteConformance(pStubMsg); - - ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pCVStructFormat->alignment + 1); - - TRACE("memory_size = %d\n", pCVStructFormat->memory_size); - - /* write constant sized part */ - pStubMsg->BufferMark = pStubMsg->Buffer; - safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size); - - WriteVariance(pStubMsg); - - bufsize = safe_multiply(esize, pStubMsg->ActualCount); - - /* write array part */ - safe_copy_to_buffer(pStubMsg, pMemory + pCVStructFormat->memory_size, bufsize); - - EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat); - - return NULL; -} - -/*********************************************************************** - * NdrConformantVaryingStructUnmarshall [RPCRT4.@] - */ -unsigned char * WINAPI NdrConformantVaryingStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char **ppMemory, - PFORMAT_STRING pFormat, - unsigned char fMustAlloc) -{ - const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat; - PFORMAT_STRING pCVArrayFormat; - ULONG esize, bufsize; - unsigned char cvarray_type; - - TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); - - pFormat += sizeof(NDR_CVSTRUCT_FORMAT); - if (pCVStructFormat->type != RPC_FC_CVSTRUCT) - { - ERR("invalid format type %x\n", pCVStructFormat->type); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return NULL; - } - - pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description + - pCVStructFormat->offset_to_array_description; - cvarray_type = *pCVArrayFormat; - switch (cvarray_type) - { - case RPC_FC_CVARRAY: - esize = *(const WORD*)(pCVArrayFormat+2); - pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4); - break; - case RPC_FC_C_CSTRING: - esize = sizeof(char); - if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED) - pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2); - else - pCVArrayFormat = ReadConformance(pStubMsg, NULL); - break; - case RPC_FC_C_WSTRING: - esize = sizeof(WCHAR); - if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED) - pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2); - else - pCVArrayFormat = ReadConformance(pStubMsg, NULL); - break; - default: - ERR("invalid array format type %x\n", *pCVArrayFormat); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return NULL; - } - - ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1); - - TRACE("memory_size = %d\n", pCVStructFormat->memory_size); - - /* work out how much memory to allocate if we need to do so */ - if (!*ppMemory || fMustAlloc) - { - SIZE_T size = pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount); - *ppMemory = NdrAllocate(pStubMsg, size); - } - - /* copy the constant data */ - pStubMsg->BufferMark = pStubMsg->Buffer; - safe_copy_from_buffer(pStubMsg, *ppMemory, pCVStructFormat->memory_size); - - pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount); - - bufsize = safe_multiply(esize, pStubMsg->ActualCount); - - if ((cvarray_type == RPC_FC_C_CSTRING) || - (cvarray_type == RPC_FC_C_WSTRING)) - { - ULONG i; - /* strings must always have null terminating bytes */ - if (bufsize < esize) - { - ERR("invalid string length of %d\n", pStubMsg->ActualCount); - RpcRaiseException(RPC_S_INVALID_BOUND); - return NULL; - } - for (i = bufsize - esize; i < bufsize; i++) - if (pStubMsg->Buffer[i] != 0) - { - ERR("string not null-terminated at byte position %d, data is 0x%x\n", - i, pStubMsg->Buffer[i]); - RpcRaiseException(RPC_S_INVALID_BOUND); - return NULL; - } - } - - /* copy the array data */ - safe_copy_from_buffer(pStubMsg, *ppMemory + pCVStructFormat->memory_size, bufsize); - - if (cvarray_type == RPC_FC_C_CSTRING) - TRACE("string=%s\n", debugstr_a((char *)(*ppMemory + pCVStructFormat->memory_size))); - else if (cvarray_type == RPC_FC_C_WSTRING) - TRACE("string=%s\n", debugstr_w((WCHAR *)(*ppMemory + pCVStructFormat->memory_size))); - - EmbeddedPointerUnmarshall(pStubMsg, *ppMemory, *ppMemory, pFormat, TRUE /* FIXME */); - - return NULL; -} - -/*********************************************************************** - * NdrConformantVaryingStructBufferSize [RPCRT4.@] - */ -void WINAPI NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat; - PFORMAT_STRING pCVArrayFormat; - ULONG esize; - - TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); - - pFormat += sizeof(NDR_CVSTRUCT_FORMAT); - if (pCVStructFormat->type != RPC_FC_CVSTRUCT) - { - ERR("invalid format type %x\n", pCVStructFormat->type); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return; - } - - pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description + - pCVStructFormat->offset_to_array_description; - switch (*pCVArrayFormat) - { - case RPC_FC_CVARRAY: - esize = *(const WORD*)(pCVArrayFormat+2); - - pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size, - pCVArrayFormat + 4, 0); - pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size, - pCVArrayFormat, 0); - break; - case RPC_FC_C_CSTRING: - TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size)); - pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1; - esize = sizeof(char); - if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED) - pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size, - pCVArrayFormat + 2, 0); - else - pStubMsg->MaxCount = pStubMsg->ActualCount; - break; - case RPC_FC_C_WSTRING: - TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size)); - pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1; - esize = sizeof(WCHAR); - if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED) - pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size, - pCVArrayFormat + 2, 0); - else - pStubMsg->MaxCount = pStubMsg->ActualCount; - break; - default: - ERR("invalid array format type %x\n", *pCVArrayFormat); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return; - } - - SizeConformance(pStubMsg); - - ALIGN_LENGTH(pStubMsg->BufferLength, pCVStructFormat->alignment + 1); - - TRACE("memory_size = %d\n", pCVStructFormat->memory_size); - - safe_buffer_length_increment(pStubMsg, pCVStructFormat->memory_size); - SizeVariance(pStubMsg); - safe_buffer_length_increment(pStubMsg, safe_multiply(pStubMsg->MaxCount, esize)); - - EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat); -} - -/*********************************************************************** - * NdrConformantVaryingStructMemorySize [RPCRT4.@] - */ -ULONG WINAPI NdrConformantVaryingStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg, - PFORMAT_STRING pFormat) -{ - const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat; - PFORMAT_STRING pCVArrayFormat; - ULONG esize; - unsigned char cvarray_type; - - TRACE("(%p, %p)\n", pStubMsg, pFormat); - - pFormat += sizeof(NDR_CVSTRUCT_FORMAT); - if (pCVStructFormat->type != RPC_FC_CVSTRUCT) - { - ERR("invalid format type %x\n", pCVStructFormat->type); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return 0; - } - - pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description + - pCVStructFormat->offset_to_array_description; - cvarray_type = *pCVArrayFormat; - switch (cvarray_type) - { - case RPC_FC_CVARRAY: - esize = *(const WORD*)(pCVArrayFormat+2); - pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 4); - break; - case RPC_FC_C_CSTRING: - esize = sizeof(char); - if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED) - pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2); - else - pCVArrayFormat = ReadConformance(pStubMsg, NULL); - break; - case RPC_FC_C_WSTRING: - esize = sizeof(WCHAR); - if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED) - pCVArrayFormat = ReadConformance(pStubMsg, pCVArrayFormat + 2); - else - pCVArrayFormat = ReadConformance(pStubMsg, NULL); - break; - default: - ERR("invalid array format type %x\n", *pCVArrayFormat); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return 0; - } - - ALIGN_POINTER(pStubMsg->Buffer, pCVStructFormat->alignment + 1); - - TRACE("memory_size = %d\n", pCVStructFormat->memory_size); - - safe_buffer_increment(pStubMsg, pCVStructFormat->memory_size); - pCVArrayFormat = ReadVariance(pStubMsg, pCVArrayFormat, pStubMsg->MaxCount); - safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount)); - - pStubMsg->MemorySize += pCVStructFormat->memory_size + safe_multiply(esize, pStubMsg->MaxCount); - - EmbeddedPointerMemorySize(pStubMsg, pFormat); - - return pCVStructFormat->memory_size + pStubMsg->MaxCount * esize; -} - -/*********************************************************************** - * NdrConformantVaryingStructFree [RPCRT4.@] - */ -void WINAPI NdrConformantVaryingStructFree(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - const NDR_CVSTRUCT_FORMAT *pCVStructFormat = (const NDR_CVSTRUCT_FORMAT *)pFormat; - PFORMAT_STRING pCVArrayFormat; - ULONG esize; - - TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); - - pFormat += sizeof(NDR_CVSTRUCT_FORMAT); - if (pCVStructFormat->type != RPC_FC_CVSTRUCT) - { - ERR("invalid format type %x\n", pCVStructFormat->type); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return; - } - - pCVArrayFormat = (const unsigned char *)&pCVStructFormat->offset_to_array_description + - pCVStructFormat->offset_to_array_description; - switch (*pCVArrayFormat) - { - case RPC_FC_CVARRAY: - esize = *(const WORD*)(pCVArrayFormat+2); - - pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size, - pCVArrayFormat + 4, 0); - pCVArrayFormat = ComputeVariance(pStubMsg, pMemory + pCVStructFormat->memory_size, - pCVArrayFormat, 0); - break; - case RPC_FC_C_CSTRING: - TRACE("string=%s\n", debugstr_a((char*)pMemory + pCVStructFormat->memory_size)); - pStubMsg->ActualCount = strlen((char*)pMemory + pCVStructFormat->memory_size)+1; - esize = sizeof(char); - if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED) - pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size, - pCVArrayFormat + 2, 0); - else - pStubMsg->MaxCount = pStubMsg->ActualCount; - break; - case RPC_FC_C_WSTRING: - TRACE("string=%s\n", debugstr_w((LPWSTR)pMemory + pCVStructFormat->memory_size)); - pStubMsg->ActualCount = strlenW((LPWSTR)pMemory + pCVStructFormat->memory_size)+1; - esize = sizeof(WCHAR); - if (pCVArrayFormat[1] == RPC_FC_STRING_SIZED) - pCVArrayFormat = ComputeConformance(pStubMsg, pMemory + pCVStructFormat->memory_size, - pCVArrayFormat + 2, 0); - else - pStubMsg->MaxCount = pStubMsg->ActualCount; - break; - default: - ERR("invalid array format type %x\n", *pCVArrayFormat); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return; - } - - TRACE("memory_size = %d\n", pCVStructFormat->memory_size); - - EmbeddedPointerFree(pStubMsg, pMemory, pFormat); -} - -#include "pshpack1.h" -typedef struct -{ - unsigned char type; - unsigned char alignment; - unsigned short total_size; -} NDR_SMFARRAY_FORMAT; - -typedef struct -{ - unsigned char type; - unsigned char alignment; - unsigned long total_size; -} NDR_LGFARRAY_FORMAT; -#include "poppack.h" - -/*********************************************************************** - * NdrFixedArrayMarshall [RPCRT4.@] - */ -unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat; - unsigned long total_size; - - TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); - - if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) && - (pSmFArrayFormat->type != RPC_FC_LGFARRAY)) - { - ERR("invalid format type %x\n", pSmFArrayFormat->type); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return NULL; - } - - ALIGN_POINTER_CLEAR(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1); - - if (pSmFArrayFormat->type == RPC_FC_SMFARRAY) - { - total_size = pSmFArrayFormat->total_size; - pFormat = (const unsigned char *)(pSmFArrayFormat + 1); - } - else - { - const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat; - total_size = pLgFArrayFormat->total_size; - pFormat = (const unsigned char *)(pLgFArrayFormat + 1); - } - - pStubMsg->BufferMark = pStubMsg->Buffer; - safe_copy_to_buffer(pStubMsg, pMemory, total_size); - - pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat); - - return NULL; -} - -/*********************************************************************** - * NdrFixedArrayUnmarshall [RPCRT4.@] - */ -unsigned char * WINAPI NdrFixedArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char **ppMemory, - PFORMAT_STRING pFormat, - unsigned char fMustAlloc) -{ - const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat; - unsigned long total_size; - unsigned char *saved_buffer; - - TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); - - if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) && - (pSmFArrayFormat->type != RPC_FC_LGFARRAY)) - { - ERR("invalid format type %x\n", pSmFArrayFormat->type); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return NULL; - } - - ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1); - - if (pSmFArrayFormat->type == RPC_FC_SMFARRAY) - { - total_size = pSmFArrayFormat->total_size; - pFormat = (const unsigned char *)(pSmFArrayFormat + 1); - } - else - { - const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat; - total_size = pLgFArrayFormat->total_size; - pFormat = (const unsigned char *)(pLgFArrayFormat + 1); - } - - if (fMustAlloc) - *ppMemory = NdrAllocate(pStubMsg, total_size); - else - { - if (!pStubMsg->IsClient && !*ppMemory) - /* for servers, we just point straight into the RPC buffer */ - *ppMemory = pStubMsg->Buffer; - } - - saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer; - safe_buffer_increment(pStubMsg, total_size); - pFormat = EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc); - - TRACE("copying %p to %p\n", saved_buffer, *ppMemory); - if (*ppMemory != saved_buffer) - memcpy(*ppMemory, saved_buffer, total_size); - - return NULL; -} - -/*********************************************************************** - * NdrFixedArrayBufferSize [RPCRT4.@] - */ -void WINAPI NdrFixedArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat; - unsigned long total_size; - - TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); - - if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) && - (pSmFArrayFormat->type != RPC_FC_LGFARRAY)) - { - ERR("invalid format type %x\n", pSmFArrayFormat->type); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return; - } - - ALIGN_LENGTH(pStubMsg->BufferLength, pSmFArrayFormat->alignment + 1); - - if (pSmFArrayFormat->type == RPC_FC_SMFARRAY) - { - total_size = pSmFArrayFormat->total_size; - pFormat = (const unsigned char *)(pSmFArrayFormat + 1); - } - else - { - const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat; - total_size = pLgFArrayFormat->total_size; - pFormat = (const unsigned char *)(pLgFArrayFormat + 1); - } - safe_buffer_length_increment(pStubMsg, total_size); - - EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat); -} - -/*********************************************************************** - * NdrFixedArrayMemorySize [RPCRT4.@] - */ -ULONG WINAPI NdrFixedArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg, - PFORMAT_STRING pFormat) -{ - const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat; - ULONG total_size; - - TRACE("(%p, %p)\n", pStubMsg, pFormat); - - if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) && - (pSmFArrayFormat->type != RPC_FC_LGFARRAY)) - { - ERR("invalid format type %x\n", pSmFArrayFormat->type); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return 0; - } - - ALIGN_POINTER(pStubMsg->Buffer, pSmFArrayFormat->alignment + 1); - - if (pSmFArrayFormat->type == RPC_FC_SMFARRAY) - { - total_size = pSmFArrayFormat->total_size; - pFormat = (const unsigned char *)(pSmFArrayFormat + 1); - } - else - { - const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat; - total_size = pLgFArrayFormat->total_size; - pFormat = (const unsigned char *)(pLgFArrayFormat + 1); - } - pStubMsg->BufferMark = pStubMsg->Buffer; - safe_buffer_increment(pStubMsg, total_size); - pStubMsg->MemorySize += total_size; - - EmbeddedPointerMemorySize(pStubMsg, pFormat); - - return total_size; -} - -/*********************************************************************** - * NdrFixedArrayFree [RPCRT4.@] - */ -void WINAPI NdrFixedArrayFree(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - const NDR_SMFARRAY_FORMAT *pSmFArrayFormat = (const NDR_SMFARRAY_FORMAT *)pFormat; - - TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); - - if ((pSmFArrayFormat->type != RPC_FC_SMFARRAY) && - (pSmFArrayFormat->type != RPC_FC_LGFARRAY)) - { - ERR("invalid format type %x\n", pSmFArrayFormat->type); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return; - } - - if (pSmFArrayFormat->type == RPC_FC_SMFARRAY) - pFormat = (const unsigned char *)(pSmFArrayFormat + 1); - else - { - const NDR_LGFARRAY_FORMAT *pLgFArrayFormat = (const NDR_LGFARRAY_FORMAT *)pFormat; - pFormat = (const unsigned char *)(pLgFArrayFormat + 1); - } - - EmbeddedPointerFree(pStubMsg, pMemory, pFormat); -} - -/*********************************************************************** - * NdrVaryingArrayMarshall [RPCRT4.@] - */ -unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - unsigned char alignment; - DWORD elements, esize; - ULONG bufsize; - - TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); - - if ((pFormat[0] != RPC_FC_SMVARRAY) && - (pFormat[0] != RPC_FC_LGVARRAY)) - { - ERR("invalid format type %x\n", pFormat[0]); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return NULL; - } - - alignment = pFormat[1] + 1; - - if (pFormat[0] == RPC_FC_SMVARRAY) - { - pFormat += 2; - pFormat += sizeof(WORD); - elements = *(const WORD*)pFormat; - pFormat += sizeof(WORD); - } - else - { - pFormat += 2; - pFormat += sizeof(DWORD); - elements = *(const DWORD*)pFormat; - pFormat += sizeof(DWORD); - } - - esize = *(const WORD*)pFormat; - pFormat += sizeof(WORD); - - pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0); - if ((pStubMsg->ActualCount > elements) || - (pStubMsg->ActualCount + pStubMsg->Offset > elements)) - { - RpcRaiseException(RPC_S_INVALID_BOUND); - return NULL; - } - - WriteVariance(pStubMsg); - - ALIGN_POINTER_CLEAR(pStubMsg->Buffer, alignment); - - bufsize = safe_multiply(esize, pStubMsg->ActualCount); - pStubMsg->BufferMark = pStubMsg->Buffer; - safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize); - - EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat); - - return NULL; -} - -/*********************************************************************** - * NdrVaryingArrayUnmarshall [RPCRT4.@] - */ -unsigned char * WINAPI NdrVaryingArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char **ppMemory, - PFORMAT_STRING pFormat, - unsigned char fMustAlloc) -{ - 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); - - if ((pFormat[0] != RPC_FC_SMVARRAY) && - (pFormat[0] != RPC_FC_LGVARRAY)) - { - ERR("invalid format type %x\n", pFormat[0]); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return NULL; - } - - alignment = pFormat[1] + 1; - - if (pFormat[0] == RPC_FC_SMVARRAY) - { - pFormat += 2; - size = *(const WORD*)pFormat; - pFormat += sizeof(WORD); - elements = *(const WORD*)pFormat; - pFormat += sizeof(WORD); - } - else - { - pFormat += 2; - size = *(const DWORD*)pFormat; - pFormat += sizeof(DWORD); - elements = *(const DWORD*)pFormat; - pFormat += sizeof(DWORD); - } - - esize = *(const WORD*)pFormat; - pFormat += sizeof(WORD); - - pFormat = ReadVariance(pStubMsg, pFormat, elements); - - ALIGN_POINTER(pStubMsg->Buffer, alignment); - - bufsize = safe_multiply(esize, pStubMsg->ActualCount); - offset = pStubMsg->Offset; - - if (!*ppMemory || fMustAlloc) - *ppMemory = NdrAllocate(pStubMsg, size); - saved_buffer = pStubMsg->BufferMark = pStubMsg->Buffer; - safe_buffer_increment(pStubMsg, bufsize); - - EmbeddedPointerUnmarshall(pStubMsg, saved_buffer, *ppMemory, pFormat, fMustAlloc); - - memcpy(*ppMemory + offset, saved_buffer, bufsize); - - return NULL; -} - -/*********************************************************************** - * NdrVaryingArrayBufferSize [RPCRT4.@] - */ -void WINAPI NdrVaryingArrayBufferSize(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - unsigned char alignment; - DWORD elements, esize; - - TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); - - if ((pFormat[0] != RPC_FC_SMVARRAY) && - (pFormat[0] != RPC_FC_LGVARRAY)) - { - ERR("invalid format type %x\n", pFormat[0]); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return; - } - - alignment = pFormat[1] + 1; - - if (pFormat[0] == RPC_FC_SMVARRAY) - { - pFormat += 2; - pFormat += sizeof(WORD); - elements = *(const WORD*)pFormat; - pFormat += sizeof(WORD); - } - else - { - pFormat += 2; - pFormat += sizeof(DWORD); - elements = *(const DWORD*)pFormat; - pFormat += sizeof(DWORD); - } - - esize = *(const WORD*)pFormat; - pFormat += sizeof(WORD); - - pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0); - if ((pStubMsg->ActualCount > elements) || - (pStubMsg->ActualCount + pStubMsg->Offset > elements)) - { - RpcRaiseException(RPC_S_INVALID_BOUND); - return; - } - - SizeVariance(pStubMsg); - - ALIGN_LENGTH(pStubMsg->BufferLength, alignment); - - safe_buffer_length_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount)); - - EmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat); -} - -/*********************************************************************** - * NdrVaryingArrayMemorySize [RPCRT4.@] - */ -ULONG WINAPI NdrVaryingArrayMemorySize(PMIDL_STUB_MESSAGE pStubMsg, - PFORMAT_STRING pFormat) -{ - unsigned char alignment; - DWORD size, elements, esize; - - TRACE("(%p, %p)\n", pStubMsg, pFormat); - - if ((pFormat[0] != RPC_FC_SMVARRAY) && - (pFormat[0] != RPC_FC_LGVARRAY)) - { - ERR("invalid format type %x\n", pFormat[0]); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return 0; - } - - alignment = pFormat[1] + 1; - - if (pFormat[0] == RPC_FC_SMVARRAY) - { - pFormat += 2; - size = *(const WORD*)pFormat; - pFormat += sizeof(WORD); - elements = *(const WORD*)pFormat; - pFormat += sizeof(WORD); - } - else - { - pFormat += 2; - size = *(const DWORD*)pFormat; - pFormat += sizeof(DWORD); - elements = *(const DWORD*)pFormat; - pFormat += sizeof(DWORD); - } - - esize = *(const WORD*)pFormat; - pFormat += sizeof(WORD); - - pFormat = ReadVariance(pStubMsg, pFormat, elements); - - ALIGN_POINTER(pStubMsg->Buffer, alignment); - - safe_buffer_increment(pStubMsg, safe_multiply(esize, pStubMsg->ActualCount)); - pStubMsg->MemorySize += size; - - EmbeddedPointerMemorySize(pStubMsg, pFormat); - - return pStubMsg->MemorySize; -} - -/*********************************************************************** - * NdrVaryingArrayFree [RPCRT4.@] - */ -void WINAPI NdrVaryingArrayFree(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - unsigned char alignment; - DWORD elements; - - TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); - - if ((pFormat[0] != RPC_FC_SMVARRAY) && - (pFormat[0] != RPC_FC_LGVARRAY)) - { - ERR("invalid format type %x\n", pFormat[0]); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return; - } - - alignment = pFormat[1] + 1; - - if (pFormat[0] == RPC_FC_SMVARRAY) - { - pFormat += 2; - pFormat += sizeof(WORD); - elements = *(const WORD*)pFormat; - pFormat += sizeof(WORD); - } - else - { - pFormat += 2; - pFormat += sizeof(DWORD); - elements = *(const DWORD*)pFormat; - pFormat += sizeof(DWORD); - } - - pFormat += sizeof(WORD); - - pFormat = ComputeVariance(pStubMsg, pMemory, pFormat, 0); - if ((pStubMsg->ActualCount > elements) || - (pStubMsg->ActualCount + pStubMsg->Offset > elements)) - { - RpcRaiseException(RPC_S_INVALID_BOUND); - return; - } - - EmbeddedPointerFree(pStubMsg, pMemory, pFormat); -} - -static ULONG get_discriminant(unsigned char fc, const unsigned char *pMemory) -{ - switch (fc) - { - case RPC_FC_BYTE: - case RPC_FC_CHAR: - case RPC_FC_SMALL: - case RPC_FC_USMALL: - return *(const UCHAR *)pMemory; - case RPC_FC_WCHAR: - case RPC_FC_SHORT: - case RPC_FC_USHORT: - case RPC_FC_ENUM16: - return *(const USHORT *)pMemory; - case RPC_FC_LONG: - case RPC_FC_ULONG: - case RPC_FC_ENUM32: - return *(const ULONG *)pMemory; - default: - FIXME("Unhandled base type: 0x%02x\n", fc); - return 0; - } -} - -static PFORMAT_STRING get_arm_offset_from_union_arm_selector(PMIDL_STUB_MESSAGE pStubMsg, - unsigned long discriminant, - PFORMAT_STRING pFormat) -{ - unsigned short num_arms, arm, type; - - num_arms = *(const SHORT*)pFormat & 0x0fff; - pFormat += 2; - for(arm = 0; arm < num_arms; arm++) - { - if(discriminant == *(const ULONG*)pFormat) - { - pFormat += 4; - break; - } - pFormat += 6; - } - - type = *(const unsigned short*)pFormat; - TRACE("type %04x\n", type); - if(arm == num_arms) /* default arm extras */ - { - if(type == 0xffff) - { - ERR("no arm for 0x%lx and no default case\n", discriminant); - RpcRaiseException(RPC_S_INVALID_TAG); - return NULL; - } - if(type == 0) - { - TRACE("falling back to empty default case for 0x%lx\n", discriminant); - return NULL; - } - } - return pFormat; -} - -static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, ULONG discriminant, PFORMAT_STRING pFormat) -{ - unsigned short type; - - pFormat += 2; - - pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat); - if(!pFormat) - return NULL; - - type = *(const unsigned short*)pFormat; - if((type & 0xff00) == 0x8000) - { - unsigned char basetype = LOBYTE(type); - return NdrBaseTypeMarshall(pStubMsg, pMemory, &basetype); - } - else - { - PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat; - NDR_MARSHALL m = NdrMarshaller[*desc & NDR_TABLE_MASK]; - if (m) - { - unsigned char *saved_buffer = NULL; - int pointer_buffer_mark_set = 0; - switch(*desc) - { - case RPC_FC_RP: - case RPC_FC_UP: - case RPC_FC_OP: - case RPC_FC_FP: - ALIGN_POINTER_CLEAR(pStubMsg->Buffer, 4); - saved_buffer = pStubMsg->Buffer; - if (pStubMsg->PointerBufferMark) - { - pStubMsg->Buffer = pStubMsg->PointerBufferMark; - pStubMsg->PointerBufferMark = NULL; - pointer_buffer_mark_set = 1; - } - else - safe_buffer_increment(pStubMsg, 4); /* for pointer ID */ - - PointerMarshall(pStubMsg, saved_buffer, *(unsigned char **)pMemory, desc); - if (pointer_buffer_mark_set) - { - STD_OVERFLOW_CHECK(pStubMsg); - pStubMsg->PointerBufferMark = pStubMsg->Buffer; - if (saved_buffer + 4 > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) - { - ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n", - saved_buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - } - pStubMsg->Buffer = saved_buffer + 4; - } - break; - default: - m(pStubMsg, pMemory, desc); - } - } - else FIXME("no marshaller for embedded type %02x\n", *desc); - } - return NULL; -} - -static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char **ppMemory, - ULONG discriminant, - PFORMAT_STRING pFormat, - unsigned char fMustAlloc) -{ - unsigned short type; - - pFormat += 2; - - pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat); - if(!pFormat) - return NULL; - - type = *(const unsigned short*)pFormat; - if((type & 0xff00) == 0x8000) - { - unsigned char basetype = LOBYTE(type); - return NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &basetype, FALSE); - } - else - { - PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat; - NDR_UNMARSHALL m = NdrUnmarshaller[*desc & NDR_TABLE_MASK]; - if (m) - { - unsigned char *saved_buffer = NULL; - int pointer_buffer_mark_set = 0; - switch(*desc) - { - case RPC_FC_RP: - case RPC_FC_UP: - case RPC_FC_OP: - case RPC_FC_FP: - **(void***)ppMemory = NULL; - ALIGN_POINTER(pStubMsg->Buffer, 4); - saved_buffer = pStubMsg->Buffer; - if (pStubMsg->PointerBufferMark) - { - pStubMsg->Buffer = pStubMsg->PointerBufferMark; - pStubMsg->PointerBufferMark = NULL; - pointer_buffer_mark_set = 1; - } - else - pStubMsg->Buffer += 4; /* for pointer ID */ - - if (saved_buffer + 4 > pStubMsg->BufferEnd) - { - ERR("buffer overflow - saved_buffer = %p, BufferEnd = %p\n", - saved_buffer, pStubMsg->BufferEnd); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - } - - PointerUnmarshall(pStubMsg, saved_buffer, *(unsigned char ***)ppMemory, **(unsigned char ***)ppMemory, desc, fMustAlloc); - if (pointer_buffer_mark_set) - { - STD_OVERFLOW_CHECK(pStubMsg); - pStubMsg->PointerBufferMark = pStubMsg->Buffer; - pStubMsg->Buffer = saved_buffer + 4; - } - break; - default: - m(pStubMsg, ppMemory, desc, fMustAlloc); - } - } - else FIXME("no marshaller for embedded type %02x\n", *desc); - } - return NULL; -} - -static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - ULONG discriminant, - PFORMAT_STRING pFormat) -{ - unsigned short type; - - pFormat += 2; - - pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat); - if(!pFormat) - return; - - type = *(const unsigned short*)pFormat; - if((type & 0xff00) == 0x8000) - { - unsigned char basetype = LOBYTE(type); - NdrBaseTypeBufferSize(pStubMsg, pMemory, &basetype); - } - else - { - PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat; - NDR_BUFFERSIZE m = NdrBufferSizer[*desc & NDR_TABLE_MASK]; - if (m) - { - switch(*desc) - { - case RPC_FC_RP: - case RPC_FC_UP: - case RPC_FC_OP: - case RPC_FC_FP: - ALIGN_LENGTH(pStubMsg->BufferLength, 4); - safe_buffer_length_increment(pStubMsg, 4); /* for pointer ID */ - if (!pStubMsg->IgnoreEmbeddedPointers) - { - int saved_buffer_length = pStubMsg->BufferLength; - pStubMsg->BufferLength = pStubMsg->PointerLength; - pStubMsg->PointerLength = 0; - if(!pStubMsg->BufferLength) - ERR("BufferLength == 0??\n"); - PointerBufferSize(pStubMsg, *(unsigned char **)pMemory, desc); - pStubMsg->PointerLength = pStubMsg->BufferLength; - pStubMsg->BufferLength = saved_buffer_length; - } - break; - default: - m(pStubMsg, pMemory, desc); - } - } - else FIXME("no buffersizer for embedded type %02x\n", *desc); - } -} - -static ULONG union_arm_memory_size(PMIDL_STUB_MESSAGE pStubMsg, - ULONG discriminant, - PFORMAT_STRING pFormat) -{ - unsigned short type, size; - - size = *(const unsigned short*)pFormat; - pStubMsg->Memory += size; - pFormat += 2; - - pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat); - if(!pFormat) - return 0; - - type = *(const unsigned short*)pFormat; - if((type & 0xff00) == 0x8000) - { - return NdrBaseTypeMemorySize(pStubMsg, pFormat); - } - else - { - PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat; - NDR_MEMORYSIZE m = NdrMemorySizer[*desc & NDR_TABLE_MASK]; - unsigned char *saved_buffer; - if (m) - { - switch(*desc) - { - case RPC_FC_RP: - case RPC_FC_UP: - case RPC_FC_OP: - case RPC_FC_FP: - ALIGN_POINTER(pStubMsg->Buffer, 4); - saved_buffer = pStubMsg->Buffer; - safe_buffer_increment(pStubMsg, 4); - ALIGN_LENGTH(pStubMsg->MemorySize, 4); - pStubMsg->MemorySize += 4; - if (!pStubMsg->IgnoreEmbeddedPointers) - PointerMemorySize(pStubMsg, saved_buffer, pFormat); - break; - default: - return m(pStubMsg, desc); - } - } - else FIXME("no marshaller for embedded type %02x\n", *desc); - } - - TRACE("size %d\n", size); - return size; -} - -static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - ULONG discriminant, - PFORMAT_STRING pFormat) -{ - unsigned short type; - - pFormat += 2; - - pFormat = get_arm_offset_from_union_arm_selector(pStubMsg, discriminant, pFormat); - if(!pFormat) - return; - - type = *(const unsigned short*)pFormat; - if((type & 0xff00) != 0x8000) - { - PFORMAT_STRING desc = pFormat + *(const SHORT*)pFormat; - NDR_FREE m = NdrFreer[*desc & NDR_TABLE_MASK]; - if (m) - { - switch(*desc) - { - case RPC_FC_RP: - case RPC_FC_UP: - case RPC_FC_OP: - case RPC_FC_FP: - PointerFree(pStubMsg, *(unsigned char **)pMemory, desc); - break; - default: - m(pStubMsg, pMemory, desc); - } - } - else FIXME("no freer for embedded type %02x\n", *desc); - } -} - -/*********************************************************************** - * NdrEncapsulatedUnionMarshall [RPCRT4.@] - */ -unsigned char * WINAPI NdrEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - unsigned char switch_type; - unsigned char increment; - ULONG switch_value; - - TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); - pFormat++; - - switch_type = *pFormat & 0xf; - increment = (*pFormat & 0xf0) >> 4; - pFormat++; - - ALIGN_POINTER_CLEAR(pStubMsg->Buffer, increment); - - switch_value = get_discriminant(switch_type, pMemory); - TRACE("got switch value 0x%x\n", switch_value); - - NdrBaseTypeMarshall(pStubMsg, pMemory, &switch_type); - pMemory += increment; - - return union_arm_marshall(pStubMsg, pMemory, switch_value, pFormat); -} - -/*********************************************************************** - * NdrEncapsulatedUnionUnmarshall [RPCRT4.@] - */ -unsigned char * WINAPI NdrEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char **ppMemory, - PFORMAT_STRING pFormat, - unsigned char fMustAlloc) -{ - unsigned char switch_type; - unsigned char increment; - ULONG switch_value; - unsigned short size; - unsigned char *pMemoryArm; - - TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); - pFormat++; - - switch_type = *pFormat & 0xf; - increment = (*pFormat & 0xf0) >> 4; - pFormat++; - - ALIGN_POINTER(pStubMsg->Buffer, increment); - switch_value = get_discriminant(switch_type, pStubMsg->Buffer); - TRACE("got switch value 0x%x\n", switch_value); - - size = *(const unsigned short*)pFormat + increment; - if(!*ppMemory || fMustAlloc) - *ppMemory = NdrAllocate(pStubMsg, size); - - NdrBaseTypeUnmarshall(pStubMsg, ppMemory, &switch_type, FALSE); - pMemoryArm = *ppMemory + increment; - - return union_arm_unmarshall(pStubMsg, &pMemoryArm, switch_value, pFormat, fMustAlloc); -} - -/*********************************************************************** - * NdrEncapsulatedUnionBufferSize [RPCRT4.@] - */ -void WINAPI NdrEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - unsigned char switch_type; - unsigned char increment; - ULONG switch_value; - - TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); - pFormat++; - - switch_type = *pFormat & 0xf; - increment = (*pFormat & 0xf0) >> 4; - pFormat++; - - ALIGN_LENGTH(pStubMsg->BufferLength, increment); - switch_value = get_discriminant(switch_type, pMemory); - TRACE("got switch value 0x%x\n", switch_value); - - /* Add discriminant size */ - NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&switch_value, &switch_type); - pMemory += increment; - - union_arm_buffer_size(pStubMsg, pMemory, switch_value, pFormat); -} - -/*********************************************************************** - * NdrEncapsulatedUnionMemorySize [RPCRT4.@] - */ -ULONG WINAPI NdrEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg, - PFORMAT_STRING pFormat) -{ - unsigned char switch_type; - unsigned char increment; - ULONG switch_value; - - switch_type = *pFormat & 0xf; - increment = (*pFormat & 0xf0) >> 4; - pFormat++; - - ALIGN_POINTER(pStubMsg->Buffer, increment); - switch_value = get_discriminant(switch_type, pStubMsg->Buffer); - TRACE("got switch value 0x%x\n", switch_value); - - pStubMsg->Memory += increment; - - return increment + union_arm_memory_size(pStubMsg, switch_value, pFormat + *(const SHORT*)pFormat); -} - -/*********************************************************************** - * NdrEncapsulatedUnionFree [RPCRT4.@] - */ -void WINAPI NdrEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - unsigned char switch_type; - unsigned char increment; - ULONG switch_value; - - TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); - pFormat++; - - switch_type = *pFormat & 0xf; - increment = (*pFormat & 0xf0) >> 4; - pFormat++; - - switch_value = get_discriminant(switch_type, pMemory); - TRACE("got switch value 0x%x\n", switch_value); - - pMemory += increment; - - return union_arm_free(pStubMsg, pMemory, switch_value, pFormat); -} - -/*********************************************************************** - * NdrNonEncapsulatedUnionMarshall [RPCRT4.@] - */ -unsigned char * WINAPI NdrNonEncapsulatedUnionMarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - unsigned char switch_type; - - TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); - pFormat++; - - switch_type = *pFormat; - pFormat++; - - pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0); - TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount); - /* Marshall discriminant */ - NdrBaseTypeMarshall(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type); - - return union_arm_marshall(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat); -} - -static long unmarshall_discriminant(PMIDL_STUB_MESSAGE pStubMsg, - PFORMAT_STRING *ppFormat) -{ - long discriminant = 0; - - switch(**ppFormat) - { - case RPC_FC_BYTE: - case RPC_FC_CHAR: - case RPC_FC_SMALL: - case RPC_FC_USMALL: - { - UCHAR d; - safe_copy_from_buffer(pStubMsg, &d, sizeof(d)); - discriminant = d; - break; - } - case RPC_FC_WCHAR: - case RPC_FC_SHORT: - case RPC_FC_USHORT: - { - USHORT d; - ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT)); - safe_copy_from_buffer(pStubMsg, &d, sizeof(d)); - discriminant = d; - break; - } - case RPC_FC_LONG: - case RPC_FC_ULONG: - { - ULONG d; - ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG)); - safe_copy_from_buffer(pStubMsg, &d, sizeof(d)); - discriminant = d; - break; - } - default: - FIXME("Unhandled base type: 0x%02x\n", **ppFormat); - } - (*ppFormat)++; - - if (pStubMsg->fHasNewCorrDesc) - *ppFormat += 6; - else - *ppFormat += 4; - return discriminant; -} - -/********************************************************************** - * NdrNonEncapsulatedUnionUnmarshall [RPCRT4.@] - */ -unsigned char * WINAPI NdrNonEncapsulatedUnionUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char **ppMemory, - PFORMAT_STRING pFormat, - unsigned char fMustAlloc) -{ - long discriminant; - unsigned short size; - - TRACE("(%p, %p, %p, %d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); - pFormat++; - - /* Unmarshall discriminant */ - discriminant = unmarshall_discriminant(pStubMsg, &pFormat); - TRACE("unmarshalled discriminant %lx\n", discriminant); - - pFormat += *(const SHORT*)pFormat; - - size = *(const unsigned short*)pFormat; - - if(!*ppMemory || fMustAlloc) - *ppMemory = NdrAllocate(pStubMsg, size); - - return union_arm_unmarshall(pStubMsg, ppMemory, discriminant, pFormat, fMustAlloc); -} - -/*********************************************************************** - * NdrNonEncapsulatedUnionBufferSize [RPCRT4.@] - */ -void WINAPI NdrNonEncapsulatedUnionBufferSize(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - unsigned char switch_type; - - TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); - pFormat++; - - switch_type = *pFormat; - pFormat++; - - pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0); - TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount); - /* Add discriminant size */ - NdrBaseTypeBufferSize(pStubMsg, (unsigned char *)&pStubMsg->MaxCount, &switch_type); - - union_arm_buffer_size(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat); -} - -/*********************************************************************** - * NdrNonEncapsulatedUnionMemorySize [RPCRT4.@] - */ -ULONG WINAPI NdrNonEncapsulatedUnionMemorySize(PMIDL_STUB_MESSAGE pStubMsg, - PFORMAT_STRING pFormat) -{ - ULONG discriminant; - - pFormat++; - /* Unmarshall discriminant */ - discriminant = unmarshall_discriminant(pStubMsg, &pFormat); - TRACE("unmarshalled discriminant 0x%x\n", discriminant); - - return union_arm_memory_size(pStubMsg, discriminant, pFormat + *(const SHORT*)pFormat); -} - -/*********************************************************************** - * NdrNonEncapsulatedUnionFree [RPCRT4.@] - */ -void WINAPI NdrNonEncapsulatedUnionFree(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - TRACE("(%p, %p, %p)\n", pStubMsg, pMemory, pFormat); - pFormat++; - pFormat++; - - pFormat = ComputeConformance(pStubMsg, pMemory, pFormat, 0); - TRACE("got switch value 0x%lx\n", pStubMsg->MaxCount); - - return union_arm_free(pStubMsg, pMemory, pStubMsg->MaxCount, pFormat + *(const SHORT*)pFormat); -} - -/*********************************************************************** - * NdrByteCountPointerMarshall [RPCRT4.@] - */ -unsigned char * WINAPI NdrByteCountPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - FIXME("stub\n"); - return NULL; -} - -/*********************************************************************** - * NdrByteCountPointerUnmarshall [RPCRT4.@] - */ -unsigned char * WINAPI NdrByteCountPointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char **ppMemory, - PFORMAT_STRING pFormat, - unsigned char fMustAlloc) -{ - FIXME("stub\n"); - return NULL; -} - -/*********************************************************************** - * NdrByteCountPointerBufferSize [RPCRT4.@] - */ -void WINAPI NdrByteCountPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - FIXME("stub\n"); -} - -/*********************************************************************** - * NdrByteCountPointerMemorySize [RPCRT4.@] - */ -ULONG WINAPI NdrByteCountPointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg, - PFORMAT_STRING pFormat) -{ - FIXME("stub\n"); - return 0; -} - -/*********************************************************************** - * NdrByteCountPointerFree [RPCRT4.@] - */ -void WINAPI NdrByteCountPointerFree(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - FIXME("stub\n"); -} - -/*********************************************************************** - * NdrXmitOrRepAsMarshall [RPCRT4.@] - */ -unsigned char * WINAPI NdrXmitOrRepAsMarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - FIXME("stub\n"); - return NULL; -} - -/*********************************************************************** - * NdrXmitOrRepAsUnmarshall [RPCRT4.@] - */ -unsigned char * WINAPI NdrXmitOrRepAsUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char **ppMemory, - PFORMAT_STRING pFormat, - unsigned char fMustAlloc) -{ - FIXME("stub\n"); - return NULL; -} - -/*********************************************************************** - * NdrXmitOrRepAsBufferSize [RPCRT4.@] - */ -void WINAPI NdrXmitOrRepAsBufferSize(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - FIXME("stub\n"); -} - -/*********************************************************************** - * NdrXmitOrRepAsMemorySize [RPCRT4.@] - */ -ULONG WINAPI NdrXmitOrRepAsMemorySize(PMIDL_STUB_MESSAGE pStubMsg, - PFORMAT_STRING pFormat) -{ - FIXME("stub\n"); - return 0; -} - -/*********************************************************************** - * NdrXmitOrRepAsFree [RPCRT4.@] - */ -void WINAPI NdrXmitOrRepAsFree(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - FIXME("stub\n"); -} - -#include "pshpack1.h" -typedef struct -{ - unsigned char type; - unsigned char flags_type; /* flags in upper nibble, type in lower nibble */ - ULONG low_value; - ULONG high_value; -} NDR_RANGE; -#include "poppack.h" - -/*********************************************************************** - * NdrRangeMarshall [internal] - */ -unsigned char *WINAPI NdrRangeMarshall( - PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - NDR_RANGE *pRange = (NDR_RANGE *)pFormat; - unsigned char base_type; - - TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat); - - if (pRange->type != RPC_FC_RANGE) - { - ERR("invalid format type %x\n", pRange->type); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return NULL; - } - - base_type = pRange->flags_type & 0xf; - - return NdrBaseTypeMarshall(pStubMsg, pMemory, &base_type); -} - -/*********************************************************************** - * NdrRangeUnmarshall - */ -unsigned char *WINAPI NdrRangeUnmarshall( - PMIDL_STUB_MESSAGE pStubMsg, - unsigned char **ppMemory, - PFORMAT_STRING pFormat, - unsigned char fMustAlloc) -{ - NDR_RANGE *pRange = (NDR_RANGE *)pFormat; - unsigned char base_type; - - TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false"); - - if (pRange->type != RPC_FC_RANGE) - { - ERR("invalid format type %x\n", pRange->type); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return NULL; - } - base_type = pRange->flags_type & 0xf; - - TRACE("base_type = 0x%02x, low_value = %d, high_value = %d\n", - base_type, pRange->low_value, pRange->high_value); - -#define RANGE_UNMARSHALL(type, format_spec) \ - do \ - { \ - ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \ - if (fMustAlloc || !*ppMemory) \ - *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \ - if (pStubMsg->Buffer + sizeof(type) > pStubMsg->BufferEnd) \ - { \ - ERR("buffer overflow - Buffer = %p, BufferEnd = %p\n", \ - pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength); \ - RpcRaiseException(RPC_X_BAD_STUB_DATA); \ - } \ - if ((*(type *)pStubMsg->Buffer < (type)pRange->low_value) || \ - (*(type *)pStubMsg->Buffer > (type)pRange->high_value)) \ - { \ - ERR("value exceeded bounds: " format_spec ", low: " format_spec ", high: " format_spec "\n", \ - *(type *)pStubMsg->Buffer, (type)pRange->low_value, \ - (type)pRange->high_value); \ - RpcRaiseException(RPC_S_INVALID_BOUND); \ - return NULL; \ - } \ - TRACE("*ppMemory: %p\n", *ppMemory); \ - **(type **)ppMemory = *(type *)pStubMsg->Buffer; \ - pStubMsg->Buffer += sizeof(type); \ - } while (0) - - switch(base_type) - { - case RPC_FC_CHAR: - case RPC_FC_SMALL: - RANGE_UNMARSHALL(UCHAR, "%d"); - TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory); - break; - case RPC_FC_BYTE: - case RPC_FC_USMALL: - RANGE_UNMARSHALL(CHAR, "%u"); - TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory); - break; - case RPC_FC_WCHAR: /* FIXME: valid? */ - case RPC_FC_USHORT: - RANGE_UNMARSHALL(USHORT, "%u"); - TRACE("value: 0x%04x\n", **(USHORT **)ppMemory); - break; - case RPC_FC_SHORT: - RANGE_UNMARSHALL(SHORT, "%d"); - TRACE("value: 0x%04x\n", **(USHORT **)ppMemory); - break; - case RPC_FC_LONG: - RANGE_UNMARSHALL(LONG, "%d"); - TRACE("value: 0x%08x\n", **(ULONG **)ppMemory); - break; - case RPC_FC_ULONG: - RANGE_UNMARSHALL(ULONG, "%u"); - TRACE("value: 0x%08x\n", **(ULONG **)ppMemory); - break; - case RPC_FC_ENUM16: - case RPC_FC_ENUM32: - FIXME("Unhandled enum type\n"); - break; - case RPC_FC_ERROR_STATUS_T: /* FIXME: valid? */ - case RPC_FC_FLOAT: - case RPC_FC_DOUBLE: - case RPC_FC_HYPER: - default: - ERR("invalid range base type: 0x%02x\n", base_type); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - } - - return NULL; -} - -/*********************************************************************** - * NdrRangeBufferSize [internal] - */ -void WINAPI NdrRangeBufferSize( - PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - NDR_RANGE *pRange = (NDR_RANGE *)pFormat; - unsigned char base_type; - - TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat); - - if (pRange->type != RPC_FC_RANGE) - { - ERR("invalid format type %x\n", pRange->type); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - } - base_type = pRange->flags_type & 0xf; - - NdrBaseTypeBufferSize(pStubMsg, pMemory, &base_type); -} - -/*********************************************************************** - * NdrRangeMemorySize [internal] - */ -ULONG WINAPI NdrRangeMemorySize( - PMIDL_STUB_MESSAGE pStubMsg, - PFORMAT_STRING pFormat) -{ - NDR_RANGE *pRange = (NDR_RANGE *)pFormat; - unsigned char base_type; - - if (pRange->type != RPC_FC_RANGE) - { - ERR("invalid format type %x\n", pRange->type); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - return 0; - } - base_type = pRange->flags_type & 0xf; - - return NdrBaseTypeMemorySize(pStubMsg, &base_type); -} - -/*********************************************************************** - * NdrRangeFree [internal] - */ -void WINAPI NdrRangeFree(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat); - - /* nothing to do */ -} - -/*********************************************************************** - * NdrBaseTypeMarshall [internal] - */ -static unsigned char *WINAPI NdrBaseTypeMarshall( - PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat); - - switch(*pFormat) - { - case RPC_FC_BYTE: - case RPC_FC_CHAR: - case RPC_FC_SMALL: - case RPC_FC_USMALL: - safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR)); - TRACE("value: 0x%02x\n", *(UCHAR *)pMemory); - break; - case RPC_FC_WCHAR: - case RPC_FC_SHORT: - case RPC_FC_USHORT: - ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT)); - safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT)); - TRACE("value: 0x%04x\n", *(USHORT *)pMemory); - break; - case RPC_FC_LONG: - case RPC_FC_ULONG: - case RPC_FC_ERROR_STATUS_T: - case RPC_FC_ENUM32: - ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONG)); - safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG)); - TRACE("value: 0x%08x\n", *(ULONG *)pMemory); - break; - case RPC_FC_FLOAT: - ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(float)); - safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float)); - break; - case RPC_FC_DOUBLE: - ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(double)); - safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double)); - break; - case RPC_FC_HYPER: - ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(ULONGLONG)); - safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG)); - TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory)); - break; - case RPC_FC_ENUM16: - /* only 16-bits on the wire, so do a sanity check */ - if (*(UINT *)pMemory > SHRT_MAX) - RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE); - ALIGN_POINTER_CLEAR(pStubMsg->Buffer, sizeof(USHORT)); - if (pStubMsg->Buffer + sizeof(USHORT) > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) - RpcRaiseException(RPC_X_BAD_STUB_DATA); - *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory; - pStubMsg->Buffer += sizeof(USHORT); - TRACE("value: 0x%04x\n", *(UINT *)pMemory); - break; - case RPC_FC_IGNORE: - break; - default: - FIXME("Unhandled base type: 0x%02x\n", *pFormat); - } - - /* FIXME: what is the correct return value? */ - return NULL; -} - -/*********************************************************************** - * NdrBaseTypeUnmarshall [internal] - */ -static unsigned char *WINAPI NdrBaseTypeUnmarshall( - PMIDL_STUB_MESSAGE pStubMsg, - unsigned char **ppMemory, - PFORMAT_STRING pFormat, - unsigned char fMustAlloc) -{ - TRACE("pStubMsg: %p, ppMemory: %p, type: 0x%02x, fMustAlloc: %s\n", pStubMsg, ppMemory, *pFormat, fMustAlloc ? "true" : "false"); - -#define BASE_TYPE_UNMARSHALL(type) \ - ALIGN_POINTER(pStubMsg->Buffer, sizeof(type)); \ - if (!fMustAlloc && !pStubMsg->IsClient && !*ppMemory) \ - { \ - *ppMemory = pStubMsg->Buffer; \ - TRACE("*ppMemory: %p\n", *ppMemory); \ - } \ - else \ - { \ - if (fMustAlloc) \ - *ppMemory = NdrAllocate(pStubMsg, sizeof(type)); \ - TRACE("*ppMemory: %p\n", *ppMemory); \ - **(type **)ppMemory = *(type *)pStubMsg->Buffer; \ - } \ - pStubMsg->Buffer += sizeof(type); - - switch(*pFormat) - { - case RPC_FC_BYTE: - case RPC_FC_CHAR: - case RPC_FC_SMALL: - case RPC_FC_USMALL: - BASE_TYPE_UNMARSHALL(UCHAR); - TRACE("value: 0x%02x\n", **(UCHAR **)ppMemory); - break; - case RPC_FC_WCHAR: - case RPC_FC_SHORT: - case RPC_FC_USHORT: - BASE_TYPE_UNMARSHALL(USHORT); - TRACE("value: 0x%04x\n", **(USHORT **)ppMemory); - break; - case RPC_FC_LONG: - case RPC_FC_ULONG: - case RPC_FC_ERROR_STATUS_T: - case RPC_FC_ENUM32: - BASE_TYPE_UNMARSHALL(ULONG); - TRACE("value: 0x%08x\n", **(ULONG **)ppMemory); - break; - case RPC_FC_FLOAT: - BASE_TYPE_UNMARSHALL(float); - TRACE("value: %f\n", **(float **)ppMemory); - break; - case RPC_FC_DOUBLE: - BASE_TYPE_UNMARSHALL(double); - TRACE("value: %f\n", **(double **)ppMemory); - break; - case RPC_FC_HYPER: - BASE_TYPE_UNMARSHALL(ULONGLONG); - TRACE("value: %s\n", wine_dbgstr_longlong(**(ULONGLONG **)ppMemory)); - break; - case RPC_FC_ENUM16: - ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT)); - if (fMustAlloc || !*ppMemory) - *ppMemory = NdrAllocate(pStubMsg, sizeof(UINT)); - if (pStubMsg->Buffer + sizeof(USHORT) > pStubMsg->BufferEnd) - RpcRaiseException(RPC_X_BAD_STUB_DATA); - TRACE("*ppMemory: %p\n", *ppMemory); - /* 16-bits on the wire, but int in memory */ - **(UINT **)ppMemory = *(USHORT *)pStubMsg->Buffer; - pStubMsg->Buffer += sizeof(USHORT); - TRACE("value: 0x%08x\n", **(UINT **)ppMemory); - break; - case RPC_FC_IGNORE: - break; - default: - FIXME("Unhandled base type: 0x%02x\n", *pFormat); - } -#undef BASE_TYPE_UNMARSHALL - - /* FIXME: what is the correct return value? */ - - return NULL; -} - -/*********************************************************************** - * NdrBaseTypeBufferSize [internal] - */ -static void WINAPI NdrBaseTypeBufferSize( - PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat); - - switch(*pFormat) - { - case RPC_FC_BYTE: - case RPC_FC_CHAR: - case RPC_FC_SMALL: - case RPC_FC_USMALL: - safe_buffer_length_increment(pStubMsg, sizeof(UCHAR)); - break; - case RPC_FC_WCHAR: - case RPC_FC_SHORT: - case RPC_FC_USHORT: - case RPC_FC_ENUM16: - ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(USHORT)); - safe_buffer_length_increment(pStubMsg, sizeof(USHORT)); - break; - case RPC_FC_LONG: - case RPC_FC_ULONG: - case RPC_FC_ENUM32: - ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONG)); - safe_buffer_length_increment(pStubMsg, sizeof(ULONG)); - break; - case RPC_FC_FLOAT: - ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(float)); - safe_buffer_length_increment(pStubMsg, sizeof(float)); - break; - case RPC_FC_DOUBLE: - ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(double)); - safe_buffer_length_increment(pStubMsg, sizeof(double)); - break; - case RPC_FC_HYPER: - ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(ULONGLONG)); - safe_buffer_length_increment(pStubMsg, sizeof(ULONGLONG)); - break; - case RPC_FC_ERROR_STATUS_T: - ALIGN_LENGTH(pStubMsg->BufferLength, sizeof(error_status_t)); - safe_buffer_length_increment(pStubMsg, sizeof(error_status_t)); - break; - case RPC_FC_IGNORE: - break; - default: - FIXME("Unhandled base type: 0x%02x\n", *pFormat); - } -} - -/*********************************************************************** - * NdrBaseTypeMemorySize [internal] - */ -static ULONG WINAPI NdrBaseTypeMemorySize( - PMIDL_STUB_MESSAGE pStubMsg, - PFORMAT_STRING pFormat) -{ - TRACE("pStubMsg %p, type 0x%02x\n", pStubMsg, *pFormat); - - switch(*pFormat) - { - case RPC_FC_BYTE: - case RPC_FC_CHAR: - case RPC_FC_SMALL: - case RPC_FC_USMALL: - safe_buffer_increment(pStubMsg, sizeof(UCHAR)); - pStubMsg->MemorySize += sizeof(UCHAR); - return sizeof(UCHAR); - case RPC_FC_WCHAR: - case RPC_FC_SHORT: - case RPC_FC_USHORT: - safe_buffer_increment(pStubMsg, sizeof(USHORT)); - pStubMsg->MemorySize += sizeof(USHORT); - return sizeof(USHORT); - case RPC_FC_LONG: - case RPC_FC_ULONG: - case RPC_FC_ENUM32: - safe_buffer_increment(pStubMsg, sizeof(ULONG)); - pStubMsg->MemorySize += sizeof(ULONG); - return sizeof(ULONG); - case RPC_FC_FLOAT: - safe_buffer_increment(pStubMsg, sizeof(float)); - pStubMsg->MemorySize += sizeof(float); - return sizeof(float); - case RPC_FC_DOUBLE: - safe_buffer_increment(pStubMsg, sizeof(double)); - pStubMsg->MemorySize += sizeof(double); - return sizeof(double); - case RPC_FC_HYPER: - safe_buffer_increment(pStubMsg, sizeof(ULONGLONG)); - pStubMsg->MemorySize += sizeof(ULONGLONG); - return sizeof(ULONGLONG); - case RPC_FC_ERROR_STATUS_T: - safe_buffer_increment(pStubMsg, sizeof(error_status_t)); - pStubMsg->MemorySize += sizeof(error_status_t); - return sizeof(error_status_t); - case RPC_FC_ENUM16: - safe_buffer_increment(pStubMsg, sizeof(USHORT)); - pStubMsg->MemorySize += sizeof(UINT); - return sizeof(UINT); - case RPC_FC_IGNORE: - pStubMsg->MemorySize += sizeof(void *); - return sizeof(void *); - default: - FIXME("Unhandled base type: 0x%02x\n", *pFormat); - return 0; - } -} - -/*********************************************************************** - * NdrBaseTypeFree [internal] - */ -static void WINAPI NdrBaseTypeFree(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - TRACE("pStubMsg %p pMemory %p type 0x%02x\n", pStubMsg, pMemory, *pFormat); - - /* nothing to do */ -} - -/*********************************************************************** - * NdrContextHandleBufferSize [internal] - */ -static void WINAPI NdrContextHandleBufferSize( - PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat); - - if (*pFormat != RPC_FC_BIND_CONTEXT) - { - ERR("invalid format type %x\n", *pFormat); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - } - ALIGN_LENGTH(pStubMsg->BufferLength, 4); - safe_buffer_length_increment(pStubMsg, cbNDRContext); -} - -/*********************************************************************** - * NdrContextHandleMarshall [internal] - */ -static unsigned char *WINAPI NdrContextHandleMarshall( - PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - TRACE("pStubMsg %p, pMemory %p, type 0x%02x\n", pStubMsg, pMemory, *pFormat); - - if (*pFormat != RPC_FC_BIND_CONTEXT) - { - ERR("invalid format type %x\n", *pFormat); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - } - - if (pFormat[1] & 0x80) - NdrClientContextMarshall(pStubMsg, *(NDR_CCONTEXT **)pMemory, FALSE); - else - NdrClientContextMarshall(pStubMsg, (NDR_CCONTEXT *)pMemory, FALSE); - - return NULL; -} - -/*********************************************************************** - * NdrContextHandleUnmarshall [internal] - */ -static unsigned char *WINAPI NdrContextHandleUnmarshall( - PMIDL_STUB_MESSAGE pStubMsg, - unsigned char **ppMemory, - PFORMAT_STRING pFormat, - unsigned char fMustAlloc) -{ - if (*pFormat != RPC_FC_BIND_CONTEXT) - { - ERR("invalid format type %x\n", *pFormat); - RpcRaiseException(RPC_S_INTERNAL_ERROR); - } - - **(NDR_CCONTEXT **)ppMemory = NULL; - NdrClientContextUnmarshall(pStubMsg, *(NDR_CCONTEXT **)ppMemory, pStubMsg->RpcMsg->Handle); - - return NULL; -} - -/*********************************************************************** - * NdrClientContextMarshall [RPCRT4.@] - */ -void WINAPI NdrClientContextMarshall(PMIDL_STUB_MESSAGE pStubMsg, - NDR_CCONTEXT ContextHandle, - int fCheck) -{ - TRACE("(%p, %p, %d)\n", pStubMsg, ContextHandle, fCheck); - - ALIGN_POINTER_CLEAR(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); - } - - /* FIXME: what does fCheck do? */ - NDRCContextMarshall(ContextHandle, - pStubMsg->Buffer); - - pStubMsg->Buffer += cbNDRContext; -} - -/*********************************************************************** - * NdrClientContextUnmarshall [RPCRT4.@] - */ -void WINAPI NdrClientContextUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, - NDR_CCONTEXT * pContextHandle, - RPC_BINDING_HANDLE BindHandle) -{ - TRACE("(%p, %p, %p)\n", pStubMsg, pContextHandle, BindHandle); - - ALIGN_POINTER(pStubMsg->Buffer, 4); - - if (pStubMsg->Buffer + cbNDRContext > pStubMsg->BufferEnd) - RpcRaiseException(RPC_X_BAD_STUB_DATA); - - NDRCContextUnmarshall(pContextHandle, - BindHandle, - pStubMsg->Buffer, - pStubMsg->RpcMsg->DataRepresentation); - - pStubMsg->Buffer += cbNDRContext; -} - -void WINAPI NdrServerContextMarshall(PMIDL_STUB_MESSAGE pStubMsg, - NDR_SCONTEXT ContextHandle, - NDR_RUNDOWN 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) -{ - 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, - unsigned char* pMemory, - PFORMAT_STRING pFormat) -{ - FIXME("(%p, %p, %p): stub\n", pStubMsg, pMemory, pFormat); -} - -NDR_SCONTEXT WINAPI NdrContextHandleInitialize(PMIDL_STUB_MESSAGE pStubMsg, - PFORMAT_STRING pFormat) -{ - TRACE("(%p, %p)\n", pStubMsg, pFormat); - return NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, NULL, - pStubMsg->RpcMsg->DataRepresentation, NULL, 0); -} - -void WINAPI NdrServerContextNewMarshall(PMIDL_STUB_MESSAGE pStubMsg, - NDR_SCONTEXT ContextHandle, - NDR_RUNDOWN RundownRoutine, - PFORMAT_STRING pFormat) -{ - TRACE("(%p, %p, %p, %p)\n", pStubMsg, ContextHandle, RundownRoutine, pFormat); - - 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); - } - - /* FIXME: do something with pFormat */ - NDRSContextMarshall2(pStubMsg->RpcMsg->Handle, ContextHandle, - pStubMsg->Buffer, RundownRoutine, NULL, 0); - pStubMsg->Buffer += cbNDRContext; -} - -NDR_SCONTEXT WINAPI NdrServerContextNewUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, - PFORMAT_STRING pFormat) -{ - NDR_SCONTEXT ContextHandle; - - TRACE("(%p, %p)\n", pStubMsg, pFormat); - - 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); - } - - /* FIXME: do something with pFormat */ - ContextHandle = NDRSContextUnmarshall2(pStubMsg->RpcMsg->Handle, - pStubMsg->Buffer, - pStubMsg->RpcMsg->DataRepresentation, - NULL, 0); - pStubMsg->Buffer += cbNDRContext; - - return ContextHandle; -} diff --git a/reactos/dll/win32/rpcrt4_new/ndr_misc.h b/reactos/dll/win32/rpcrt4_new/ndr_misc.h deleted file mode 100644 index ebd70b8d826..00000000000 --- a/reactos/dll/win32/rpcrt4_new/ndr_misc.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * NDR definitions - * - * Copyright 2001 Ove Kåven, TransGaming Technologies - * - * 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 - */ - -#ifndef __WINE_NDR_MISC_H -#define __WINE_NDR_MISC_H - -#include - -#include "windef.h" -#include "winbase.h" -#include "rpc.h" -#include "rpcndr.h" - -struct IPSFactoryBuffer; - -PFORMAT_STRING ComputeConformanceOrVariance( - MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pMemory, - PFORMAT_STRING pFormat, ULONG_PTR def, ULONG_PTR *pCount); - -static inline PFORMAT_STRING ComputeConformance(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat, ULONG def) -{ - return ComputeConformanceOrVariance(pStubMsg, pMemory, pFormat, def, &pStubMsg->MaxCount); -} - -static inline PFORMAT_STRING ComputeVariance(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat, ULONG def) -{ - PFORMAT_STRING ret; - ULONG_PTR ActualCount = pStubMsg->ActualCount; - - pStubMsg->Offset = 0; - ret = ComputeConformanceOrVariance(pStubMsg, pMemory, pFormat, def, &ActualCount); - pStubMsg->ActualCount = (ULONG)ActualCount; - return ret; -} - -typedef unsigned char* (WINAPI *NDR_MARSHALL) (PMIDL_STUB_MESSAGE, unsigned char*, PFORMAT_STRING); -typedef unsigned char* (WINAPI *NDR_UNMARSHALL)(PMIDL_STUB_MESSAGE, unsigned char**,PFORMAT_STRING, unsigned char); -typedef void (WINAPI *NDR_BUFFERSIZE)(PMIDL_STUB_MESSAGE, unsigned char*, PFORMAT_STRING); -typedef ULONG (WINAPI *NDR_MEMORYSIZE)(PMIDL_STUB_MESSAGE, PFORMAT_STRING); -typedef void (WINAPI *NDR_FREE) (PMIDL_STUB_MESSAGE, unsigned char*, PFORMAT_STRING); - -extern const NDR_MARSHALL NdrMarshaller[]; -extern const NDR_UNMARSHALL NdrUnmarshaller[]; -extern const NDR_BUFFERSIZE NdrBufferSizer[]; -extern const NDR_MEMORYSIZE NdrMemorySizer[]; -extern const NDR_FREE NdrFreer[]; - -#endif /* __WINE_NDR_MISC_H */ diff --git a/reactos/dll/win32/rpcrt4_new/ndr_ole.c b/reactos/dll/win32/rpcrt4_new/ndr_ole.c deleted file mode 100644 index 5c1845a2e1d..00000000000 --- a/reactos/dll/win32/rpcrt4_new/ndr_ole.c +++ /dev/null @@ -1,393 +0,0 @@ -/* - * OLE32 callouts, COM interface marshalling - * - * Copyright 2001 Ove Kåven, TransGaming Technologies - * - * 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 - * - * TODO: - * - fix the wire-protocol to match MS/RPC - * - finish RpcStream_Vtbl - */ - -#include -#include -#include - -#define COBJMACROS -#define NONAMELESSUNION -#define NONAMELESSSTRUCT - -#include "windef.h" -#include "winbase.h" -#include "winerror.h" - -#include "objbase.h" - -#include "ndr_misc.h" -#include "rpcndr.h" -#include "rpcproxy.h" -#include "wine/rpcfc.h" -#include "cpsf.h" - -#include "wine/debug.h" - -WINE_DEFAULT_DEBUG_CHANNEL(ole); - -static HMODULE hOLE; - -static HRESULT (WINAPI *COM_GetMarshalSizeMax)(ULONG *,REFIID,LPUNKNOWN,DWORD,LPVOID,DWORD); -static HRESULT (WINAPI *COM_MarshalInterface)(LPSTREAM,REFIID,LPUNKNOWN,DWORD,LPVOID,DWORD); -static HRESULT (WINAPI *COM_UnmarshalInterface)(LPSTREAM,REFIID,LPVOID*); -static HRESULT (WINAPI *COM_ReleaseMarshalData)(LPSTREAM); -static HRESULT (WINAPI *COM_GetClassObject)(REFCLSID,DWORD,COSERVERINFO *,REFIID,LPVOID *); -static HRESULT (WINAPI *COM_GetPSClsid)(REFIID,CLSID *); -static LPVOID (WINAPI *COM_MemAlloc)(ULONG); -static void (WINAPI *COM_MemFree)(LPVOID); - -static HMODULE LoadCOM(void) -{ - if (hOLE) return hOLE; - hOLE = LoadLibraryA("OLE32.DLL"); - if (!hOLE) return 0; - COM_GetMarshalSizeMax = (LPVOID)GetProcAddress(hOLE, "CoGetMarshalSizeMax"); - COM_MarshalInterface = (LPVOID)GetProcAddress(hOLE, "CoMarshalInterface"); - COM_UnmarshalInterface = (LPVOID)GetProcAddress(hOLE, "CoUnmarshalInterface"); - COM_ReleaseMarshalData = (LPVOID)GetProcAddress(hOLE, "CoReleaseMarshalData"); - COM_GetClassObject = (LPVOID)GetProcAddress(hOLE, "CoGetClassObject"); - COM_GetPSClsid = (LPVOID)GetProcAddress(hOLE, "CoGetPSClsid"); - COM_MemAlloc = (LPVOID)GetProcAddress(hOLE, "CoTaskMemAlloc"); - COM_MemFree = (LPVOID)GetProcAddress(hOLE, "CoTaskMemFree"); - return hOLE; -} - -/* CoMarshalInterface/CoUnmarshalInterface works on streams, - * so implement a simple stream on top of the RPC buffer - * (which also implements the MInterfacePointer structure) */ -typedef struct RpcStreamImpl -{ - const IStreamVtbl *lpVtbl; - DWORD RefCount; - PMIDL_STUB_MESSAGE pMsg; - LPDWORD size; - unsigned char *data; - DWORD pos; -} RpcStreamImpl; - -static HRESULT WINAPI RpcStream_QueryInterface(LPSTREAM iface, - REFIID riid, - LPVOID *obj) -{ - RpcStreamImpl *This = (RpcStreamImpl *)iface; - if (IsEqualGUID(&IID_IUnknown, riid) || - IsEqualGUID(&IID_ISequentialStream, riid) || - IsEqualGUID(&IID_IStream, riid)) { - *obj = This; - This->RefCount++; - return S_OK; - } - return E_NOINTERFACE; -} - -static ULONG WINAPI RpcStream_AddRef(LPSTREAM iface) -{ - RpcStreamImpl *This = (RpcStreamImpl *)iface; - return ++(This->RefCount); -} - -static ULONG WINAPI RpcStream_Release(LPSTREAM iface) -{ - RpcStreamImpl *This = (RpcStreamImpl *)iface; - if (!--(This->RefCount)) { - TRACE("size=%d\n", *This->size); - This->pMsg->Buffer = (unsigned char*)This->data + *This->size; - HeapFree(GetProcessHeap(),0,This); - return 0; - } - return This->RefCount; -} - -static HRESULT WINAPI RpcStream_Read(LPSTREAM iface, - void *pv, - ULONG cb, - ULONG *pcbRead) -{ - RpcStreamImpl *This = (RpcStreamImpl *)iface; - HRESULT hr = S_OK; - if (This->pos + cb > *This->size) - { - cb = *This->size - This->pos; - hr = S_FALSE; - } - if (cb) { - memcpy(pv, This->data + This->pos, cb); - This->pos += cb; - } - if (pcbRead) *pcbRead = cb; - return hr; -} - -static HRESULT WINAPI RpcStream_Write(LPSTREAM iface, - const void *pv, - ULONG cb, - ULONG *pcbWritten) -{ - RpcStreamImpl *This = (RpcStreamImpl *)iface; - if (This->data + cb > (unsigned char *)This->pMsg->RpcMsg->Buffer + This->pMsg->BufferLength) - return STG_E_MEDIUMFULL; - memcpy(This->data + This->pos, pv, cb); - This->pos += cb; - if (This->pos > *This->size) *This->size = This->pos; - if (pcbWritten) *pcbWritten = cb; - return S_OK; -} - -static HRESULT WINAPI RpcStream_Seek(LPSTREAM iface, - LARGE_INTEGER move, - DWORD origin, - ULARGE_INTEGER *newPos) -{ - RpcStreamImpl *This = (RpcStreamImpl *)iface; - switch (origin) { - case STREAM_SEEK_SET: - This->pos = move.u.LowPart; - break; - case STREAM_SEEK_CUR: - This->pos = This->pos + move.u.LowPart; - break; - case STREAM_SEEK_END: - This->pos = *This->size + move.u.LowPart; - break; - default: - return STG_E_INVALIDFUNCTION; - } - if (newPos) { - newPos->u.LowPart = This->pos; - newPos->u.HighPart = 0; - } - return S_OK; -} - -static HRESULT WINAPI RpcStream_SetSize(LPSTREAM iface, - ULARGE_INTEGER newSize) -{ - RpcStreamImpl *This = (RpcStreamImpl *)iface; - *This->size = newSize.u.LowPart; - return S_OK; -} - -static const IStreamVtbl RpcStream_Vtbl = -{ - RpcStream_QueryInterface, - RpcStream_AddRef, - RpcStream_Release, - RpcStream_Read, - RpcStream_Write, - RpcStream_Seek, - RpcStream_SetSize, - NULL, /* CopyTo */ - NULL, /* Commit */ - NULL, /* Revert */ - NULL, /* LockRegion */ - NULL, /* UnlockRegion */ - NULL, /* Stat */ - NULL /* Clone */ -}; - -static LPSTREAM RpcStream_Create(PMIDL_STUB_MESSAGE pStubMsg, BOOL init) -{ - RpcStreamImpl *This; - This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(RpcStreamImpl)); - if (!This) return NULL; - This->lpVtbl = &RpcStream_Vtbl; - This->RefCount = 1; - This->pMsg = pStubMsg; - This->size = (LPDWORD)pStubMsg->Buffer; - This->data = (unsigned char*)(This->size + 1); - This->pos = 0; - if (init) *This->size = 0; - TRACE("init size=%d\n", *This->size); - return (LPSTREAM)This; -} - -static const IID* get_ip_iid(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat) -{ - const IID *riid; - if (!pFormat) return &IID_IUnknown; - TRACE("format=%02x %02x\n", pFormat[0], pFormat[1]); - if (pFormat[0] != RPC_FC_IP) FIXME("format=%d\n", pFormat[0]); - if (pFormat[1] == RPC_FC_CONSTANT_IID) { - riid = (const IID *)&pFormat[2]; - } else { - ComputeConformance(pStubMsg, pMemory, pFormat+2, 0); - riid = (const IID *)pStubMsg->MaxCount; - } - if (!riid) riid = &IID_IUnknown; - TRACE("got %s\n", debugstr_guid(riid)); - return riid; -} - -/*********************************************************************** - * NdrInterfacePointerMarshall [RPCRT4.@] - */ -unsigned char * WINAPI NdrInterfacePointerMarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - const IID *riid = get_ip_iid(pStubMsg, pMemory, pFormat); - LPSTREAM stream; - HRESULT hr; - - TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); - pStubMsg->MaxCount = 0; - if (!LoadCOM()) return NULL; - if (pStubMsg->Buffer + sizeof(DWORD) <= (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) { - stream = RpcStream_Create(pStubMsg, TRUE); - if (stream) { - if (pMemory) - hr = COM_MarshalInterface(stream, riid, (LPUNKNOWN)pMemory, - pStubMsg->dwDestContext, pStubMsg->pvDestContext, - MSHLFLAGS_NORMAL); - else - hr = S_OK; - - IStream_Release(stream); - if (FAILED(hr)) - RpcRaiseException(hr); - } - } - return NULL; -} - -/*********************************************************************** - * NdrInterfacePointerUnmarshall [RPCRT4.@] - */ -unsigned char * WINAPI NdrInterfacePointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char **ppMemory, - PFORMAT_STRING pFormat, - unsigned char fMustAlloc) -{ - LPSTREAM stream; - HRESULT hr; - - TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); - if (!LoadCOM()) return NULL; - *(LPVOID*)ppMemory = NULL; - if (pStubMsg->Buffer + sizeof(DWORD) < (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) { - stream = RpcStream_Create(pStubMsg, FALSE); - if (!stream) RpcRaiseException(E_OUTOFMEMORY); - if (*((RpcStreamImpl *)stream)->size != 0) - hr = COM_UnmarshalInterface(stream, &IID_NULL, (LPVOID*)ppMemory); - else - hr = S_OK; - IStream_Release(stream); - if (FAILED(hr)) - RpcRaiseException(hr); - } - return NULL; -} - -/*********************************************************************** - * NdrInterfacePointerBufferSize [RPCRT4.@] - */ -void WINAPI NdrInterfacePointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - const IID *riid = get_ip_iid(pStubMsg, pMemory, pFormat); - ULONG size = 0; - HRESULT hr; - - TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); - if (!LoadCOM()) return; - hr = COM_GetMarshalSizeMax(&size, riid, (LPUNKNOWN)pMemory, - pStubMsg->dwDestContext, pStubMsg->pvDestContext, - MSHLFLAGS_NORMAL); - TRACE("size=%d\n", size); - pStubMsg->BufferLength += sizeof(DWORD) + size; -} - -/*********************************************************************** - * NdrInterfacePointerMemorySize [RPCRT4.@] - */ -ULONG WINAPI NdrInterfacePointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg, - PFORMAT_STRING pFormat) -{ - ULONG size; - - TRACE("(%p,%p)\n", pStubMsg, pFormat); - - size = *(ULONG *)pStubMsg->Buffer; - pStubMsg->Buffer += 4; - pStubMsg->MemorySize += 4; - - pStubMsg->Buffer += size; - - return pStubMsg->MemorySize; -} - -/*********************************************************************** - * NdrInterfacePointerFree [RPCRT4.@] - */ -void WINAPI NdrInterfacePointerFree(PMIDL_STUB_MESSAGE pStubMsg, - unsigned char *pMemory, - PFORMAT_STRING pFormat) -{ - LPUNKNOWN pUnk = (LPUNKNOWN)pMemory; - TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); - if (pUnk) IUnknown_Release(pUnk); -} - -/*********************************************************************** - * NdrOleAllocate [RPCRT4.@] - */ -void * WINAPI NdrOleAllocate(size_t Size) -{ - if (!LoadCOM()) return NULL; - return COM_MemAlloc(Size); -} - -/*********************************************************************** - * NdrOleFree [RPCRT4.@] - */ -void WINAPI NdrOleFree(void *NodeToFree) -{ - if (!LoadCOM()) return; - COM_MemFree(NodeToFree); -} - -/*********************************************************************** - * Helper function to create a stub. - * This probably looks very much like NdrpCreateStub. - */ -HRESULT create_stub(REFIID iid, IUnknown *pUnk, IRpcStubBuffer **ppstub) -{ - CLSID clsid; - IPSFactoryBuffer *psfac; - HRESULT r; - - if(!LoadCOM()) return E_FAIL; - - r = COM_GetPSClsid( iid, &clsid ); - if(FAILED(r)) return r; - - r = COM_GetClassObject( &clsid, CLSCTX_INPROC_SERVER, NULL, &IID_IPSFactoryBuffer, (void**)&psfac ); - if(FAILED(r)) return r; - - r = IPSFactoryBuffer_CreateStub(psfac, iid, pUnk, ppstub); - - IPSFactoryBuffer_Release(psfac); - return r; -} diff --git a/reactos/dll/win32/rpcrt4_new/ndr_stubless.c b/reactos/dll/win32/rpcrt4_new/ndr_stubless.c deleted file mode 100644 index c21b8098198..00000000000 --- a/reactos/dll/win32/rpcrt4_new/ndr_stubless.c +++ /dev/null @@ -1,1452 +0,0 @@ -/* - * NDR -Oi,-Oif,-Oicf Interpreter - * - * Copyright 2001 Ove Kåven, TransGaming Technologies - * Copyright 2003-5 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 - * - * TODO: - * - Pipes - * - Some types of binding handles - */ - -#include "config.h" -#include "wine/port.h" - -#include -#include -#include - -#include "windef.h" -#include "winbase.h" -#include "winerror.h" - -#include "objbase.h" -#include "rpc.h" -#include "rpcproxy.h" -#include "ndrtypes.h" - -#include "wine/debug.h" -#include "wine/rpcfc.h" - -#include "cpsf.h" -#include "ndr_misc.h" -#include "ndr_stubless.h" - -WINE_DEFAULT_DEBUG_CHANNEL(rpc); - -#define NDR_TABLE_MASK 127 - -static inline void call_buffer_sizer(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat) -{ - NDR_BUFFERSIZE m = NdrBufferSizer[pFormat[0] & NDR_TABLE_MASK]; - if (m) m(pStubMsg, pMemory, pFormat); - else - { - FIXME("format type 0x%x not implemented\n", pFormat[0]); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - } -} - -static inline unsigned char *call_marshaller(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat) -{ - NDR_MARSHALL m = NdrMarshaller[pFormat[0] & NDR_TABLE_MASK]; - if (m) return m(pStubMsg, pMemory, pFormat); - else - { - FIXME("format type 0x%x not implemented\n", pFormat[0]); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - return NULL; - } -} - -static inline unsigned char *call_unmarshaller(PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc) -{ - NDR_UNMARSHALL m = NdrUnmarshaller[pFormat[0] & NDR_TABLE_MASK]; - if (m) return m(pStubMsg, ppMemory, pFormat, fMustAlloc); - else - { - FIXME("format type 0x%x not implemented\n", pFormat[0]); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - return NULL; - } -} - -static inline void call_freer(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat) -{ - NDR_FREE m = NdrFreer[pFormat[0] & NDR_TABLE_MASK]; - if (m) m(pStubMsg, pMemory, pFormat); -} - -static inline unsigned long call_memory_sizer(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat) -{ - NDR_MEMORYSIZE m = NdrMemorySizer[pFormat[0] & NDR_TABLE_MASK]; - if (m) - { - unsigned char *saved_buffer = pStubMsg->Buffer; - unsigned long ret; - int saved_ignore_embedded_pointers = pStubMsg->IgnoreEmbeddedPointers; - pStubMsg->MemorySize = 0; - pStubMsg->IgnoreEmbeddedPointers = 1; - ret = m(pStubMsg, pFormat); - pStubMsg->IgnoreEmbeddedPointers = saved_ignore_embedded_pointers; - pStubMsg->Buffer = saved_buffer; - return ret; - } - else - { - FIXME("format type 0x%x not implemented\n", pFormat[0]); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - return 0; - } -} - -#define STUBLESS_UNMARSHAL 1 -#define STUBLESS_CALLSERVER 2 -#define STUBLESS_CALCSIZE 3 -#define STUBLESS_GETBUFFER 4 -#define STUBLESS_MARSHAL 5 -#define STUBLESS_FREE 6 - -void WINAPI NdrRpcSmSetClientToOsf(PMIDL_STUB_MESSAGE pMessage) -{ -#if 0 /* these functions are not defined yet */ - pMessage->pfnAllocate = NdrRpcSmClientAllocate; - pMessage->pfnFree = NdrRpcSmClientFree; -#endif -} - -static void WINAPI dump_RPC_FC_PROC_PF(PARAM_ATTRIBUTES param_attributes) -{ - if (param_attributes.MustSize) TRACE(" MustSize"); - if (param_attributes.MustFree) TRACE(" MustFree"); - if (param_attributes.IsPipe) TRACE(" IsPipe"); - if (param_attributes.IsIn) TRACE(" IsIn"); - if (param_attributes.IsOut) TRACE(" IsOut"); - if (param_attributes.IsReturn) TRACE(" IsReturn"); - if (param_attributes.IsBasetype) TRACE(" IsBasetype"); - if (param_attributes.IsByValue) TRACE(" IsByValue"); - if (param_attributes.IsSimpleRef) TRACE(" IsSimpleRef"); - if (param_attributes.IsDontCallFreeInst) TRACE(" IsDontCallFreeInst"); - if (param_attributes.SaveForAsyncFinish) TRACE(" SaveForAsyncFinish"); - if (param_attributes.ServerAllocSize) TRACE(" ServerAllocSize = %d", param_attributes.ServerAllocSize * 8); -} - -static void WINAPI dump_INTERPRETER_OPT_FLAGS(INTERPRETER_OPT_FLAGS Oi2Flags) -{ - if (Oi2Flags.ServerMustSize) TRACE(" ServerMustSize"); - if (Oi2Flags.ClientMustSize) TRACE(" ClientMustSize"); - if (Oi2Flags.HasReturn) TRACE(" HasReturn"); - if (Oi2Flags.HasPipes) TRACE(" HasPipes"); - if (Oi2Flags.Unused) TRACE(" Unused"); - if (Oi2Flags.HasAsyncUuid) TRACE(" HasAsyncUuid"); - if (Oi2Flags.HasExtensions) TRACE(" HasExtensions"); - if (Oi2Flags.HasAsyncHandle) TRACE(" HasAsyncHandle"); - TRACE("\n"); -} - -#define ARG_FROM_OFFSET(stubMsg, offset) ((stubMsg).StackTop + (offset)) - -static PFORMAT_STRING client_get_handle( - PMIDL_STUB_MESSAGE pStubMsg, const NDR_PROC_HEADER *pProcHeader, - PFORMAT_STRING pFormat, handle_t *phBinding) -{ - /* binding */ - switch (pProcHeader->handle_type) - { - /* explicit binding: parse additional section */ - case RPC_FC_BIND_EXPLICIT: - switch (*pFormat) /* handle_type */ - { - case RPC_FC_BIND_PRIMITIVE: /* explicit primitive */ - { - const NDR_EHD_PRIMITIVE *pDesc = (const NDR_EHD_PRIMITIVE *)pFormat; - - TRACE("Explicit primitive handle @ %d\n", pDesc->offset); - - if (pDesc->flag) /* pointer to binding */ - *phBinding = **(handle_t **)ARG_FROM_OFFSET(*pStubMsg, pDesc->offset); - else - *phBinding = *(handle_t *)ARG_FROM_OFFSET(*pStubMsg, pDesc->offset); - return pFormat + sizeof(NDR_EHD_PRIMITIVE); - } - case RPC_FC_BIND_GENERIC: /* explicit generic */ - { - const NDR_EHD_GENERIC *pDesc = (const NDR_EHD_GENERIC *)pFormat; - void *pObject = NULL; - void *pArg; - const GENERIC_BINDING_ROUTINE_PAIR *pGenPair; - - TRACE("Explicit generic binding handle #%d\n", pDesc->binding_routine_pair_index); - - if (pDesc->flag_and_size & HANDLE_PARAM_IS_VIA_PTR) - pArg = *(void **)ARG_FROM_OFFSET(*pStubMsg, pDesc->offset); - else - pArg = (void *)ARG_FROM_OFFSET(*pStubMsg, pDesc->offset); - memcpy(&pObject, pArg, pDesc->flag_and_size & 0xf); - pGenPair = &pStubMsg->StubDesc->aGenericBindingRoutinePairs[pDesc->binding_routine_pair_index]; - *phBinding = pGenPair->pfnBind(pObject); - return pFormat + sizeof(NDR_EHD_GENERIC); - } - case RPC_FC_BIND_CONTEXT: /* explicit context */ - { - const NDR_EHD_CONTEXT *pDesc = (const NDR_EHD_CONTEXT *)pFormat; - NDR_CCONTEXT context_handle; - TRACE("Explicit bind context\n"); - if (pDesc->flags & HANDLE_PARAM_IS_VIA_PTR) - { - TRACE("\tHANDLE_PARAM_IS_VIA_PTR\n"); - context_handle = **(NDR_CCONTEXT **)ARG_FROM_OFFSET(*pStubMsg, pDesc->offset); - } - else - context_handle = *(NDR_CCONTEXT *)ARG_FROM_OFFSET(*pStubMsg, pDesc->offset); - if ((pDesc->flags & NDR_CONTEXT_HANDLE_CANNOT_BE_NULL) && - !context_handle) - { - ERR("null context handle isn't allowed\n"); - RpcRaiseException(RPC_X_SS_IN_NULL_CONTEXT); - return NULL; - } - *phBinding = NDRCContextBinding(context_handle); - /* FIXME: should we store this structure in stubMsg.pContext? */ - return pFormat + sizeof(NDR_EHD_CONTEXT); - } - default: - ERR("bad explicit binding handle type (0x%02x)\n", pProcHeader->handle_type); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - } - break; - case RPC_FC_BIND_GENERIC: /* implicit generic */ - FIXME("RPC_FC_BIND_GENERIC\n"); - RpcRaiseException(RPC_X_BAD_STUB_DATA); /* FIXME: remove when implemented */ - break; - case RPC_FC_BIND_PRIMITIVE: /* implicit primitive */ - TRACE("Implicit primitive handle\n"); - *phBinding = *pStubMsg->StubDesc->IMPLICIT_HANDLE_INFO.pPrimitiveHandle; - break; - case RPC_FC_CALLBACK_HANDLE: /* implicit callback */ - FIXME("RPC_FC_CALLBACK_HANDLE\n"); - break; - case RPC_FC_AUTO_HANDLE: /* implicit auto handle */ - /* strictly speaking, it isn't necessary to set hBinding here - * since it isn't actually used (hence the automatic in its name), - * but then why does MIDL generate a valid entry in the - * MIDL_STUB_DESC for it? */ - TRACE("Implicit auto handle\n"); - *phBinding = *pStubMsg->StubDesc->IMPLICIT_HANDLE_INFO.pAutoHandle; - break; - default: - ERR("bad implicit binding handle type (0x%02x)\n", pProcHeader->handle_type); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - } - return pFormat; -} - -static void client_free_handle( - PMIDL_STUB_MESSAGE pStubMsg, const NDR_PROC_HEADER *pProcHeader, - PFORMAT_STRING pFormat, handle_t hBinding) -{ - /* binding */ - switch (pProcHeader->handle_type) - { - /* explicit binding: parse additional section */ - case RPC_FC_BIND_EXPLICIT: - switch (*pFormat) /* handle_type */ - { - case RPC_FC_BIND_GENERIC: /* explicit generic */ - { - const NDR_EHD_GENERIC *pDesc = (const NDR_EHD_GENERIC *)pFormat; - void *pObject = NULL; - void *pArg; - const GENERIC_BINDING_ROUTINE_PAIR *pGenPair; - - TRACE("Explicit generic binding handle #%d\n", pDesc->binding_routine_pair_index); - - if (pDesc->flag_and_size & HANDLE_PARAM_IS_VIA_PTR) - pArg = *(void **)ARG_FROM_OFFSET(*pStubMsg, pDesc->offset); - else - pArg = (void *)ARG_FROM_OFFSET(*pStubMsg, pDesc->offset); - memcpy(&pObject, pArg, pDesc->flag_and_size & 0xf); - pGenPair = &pStubMsg->StubDesc->aGenericBindingRoutinePairs[pDesc->binding_routine_pair_index]; - pGenPair->pfnUnbind(pObject, hBinding); - break; - } - case RPC_FC_BIND_CONTEXT: /* explicit context */ - case RPC_FC_BIND_PRIMITIVE: /* explicit primitive */ - break; - default: - ERR("bad explicit binding handle type (0x%02x)\n", pProcHeader->handle_type); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - } - break; - case RPC_FC_BIND_GENERIC: /* implicit generic */ - FIXME("RPC_FC_BIND_GENERIC\n"); - RpcRaiseException(RPC_X_BAD_STUB_DATA); /* FIXME: remove when implemented */ - break; - case RPC_FC_CALLBACK_HANDLE: /* implicit callback */ - case RPC_FC_BIND_PRIMITIVE: /* implicit primitive */ - case RPC_FC_AUTO_HANDLE: /* implicit auto handle */ - break; - default: - ERR("bad implicit binding handle type (0x%02x)\n", pProcHeader->handle_type); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - } -} - -static void client_do_args(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, - int phase, unsigned short number_of_params, unsigned char *pRetVal) -{ - /* current format string offset */ - int current_offset = 0; - /* current stack offset */ - unsigned short current_stack_offset = 0; - /* counter */ - unsigned short i; - - for (i = 0; i < number_of_params; i++) - { - const NDR_PARAM_OIF_BASETYPE *pParam = - (const NDR_PARAM_OIF_BASETYPE *)&pFormat[current_offset]; - unsigned char * pArg; - - current_stack_offset = pParam->stack_offset; - pArg = ARG_FROM_OFFSET(*pStubMsg, current_stack_offset); - - TRACE("param[%d]: new format\n", i); - TRACE("\tparam_attributes:"); dump_RPC_FC_PROC_PF(pParam->param_attributes); TRACE("\n"); - TRACE("\tstack_offset: 0x%x\n", current_stack_offset); - TRACE("\tmemory addr (before): %p\n", pArg); - - if (pParam->param_attributes.IsBasetype) - { - const unsigned char * pTypeFormat = - &pParam->type_format_char; - - if (pParam->param_attributes.IsSimpleRef) - pArg = *(unsigned char **)pArg; - - TRACE("\tbase type: 0x%02x\n", *pTypeFormat); - - switch (phase) - { - case PROXY_CALCSIZE: - if (pParam->param_attributes.IsIn) - call_buffer_sizer(pStubMsg, pArg, pTypeFormat); - break; - case PROXY_MARSHAL: - if (pParam->param_attributes.IsIn) - call_marshaller(pStubMsg, pArg, pTypeFormat); - break; - case PROXY_UNMARSHAL: - if (pParam->param_attributes.IsOut) - { - if (pParam->param_attributes.IsReturn) - call_unmarshaller(pStubMsg, &pRetVal, pTypeFormat, 0); - else - call_unmarshaller(pStubMsg, &pArg, pTypeFormat, 0); - TRACE("pRetVal = %p\n", pRetVal); - } - break; - default: - RpcRaiseException(RPC_S_INTERNAL_ERROR); - } - - current_offset += sizeof(NDR_PARAM_OIF_BASETYPE); - } - else - { - const NDR_PARAM_OIF_OTHER *pParamOther = - (const NDR_PARAM_OIF_OTHER *)&pFormat[current_offset]; - - const unsigned char * pTypeFormat = - &(pStubMsg->StubDesc->pFormatTypes[pParamOther->type_offset]); - - /* if a simple ref pointer then we have to do the - * check for the pointer being non-NULL. */ - if (pParam->param_attributes.IsSimpleRef) - { - if (!*(unsigned char **)pArg) - RpcRaiseException(RPC_X_NULL_REF_POINTER); - } - - TRACE("\tcomplex type: 0x%02x\n", *pTypeFormat); - - switch (phase) - { - case PROXY_CALCSIZE: - if (pParam->param_attributes.IsIn) - { - if (pParam->param_attributes.IsByValue) - call_buffer_sizer(pStubMsg, pArg, pTypeFormat); - else - call_buffer_sizer(pStubMsg, *(unsigned char **)pArg, pTypeFormat); - } - break; - case PROXY_MARSHAL: - if (pParam->param_attributes.IsIn) - { - if (pParam->param_attributes.IsByValue) - call_marshaller(pStubMsg, pArg, pTypeFormat); - else - call_marshaller(pStubMsg, *(unsigned char **)pArg, pTypeFormat); - } - break; - case PROXY_UNMARSHAL: - if (pParam->param_attributes.IsOut) - { - if (pParam->param_attributes.IsReturn) - call_unmarshaller(pStubMsg, &pRetVal, pTypeFormat, 0); - else if (pParam->param_attributes.IsByValue) - call_unmarshaller(pStubMsg, &pArg, pTypeFormat, 0); - else - call_unmarshaller(pStubMsg, (unsigned char **)pArg, pTypeFormat, 0); - } - break; - default: - RpcRaiseException(RPC_S_INTERNAL_ERROR); - } - - current_offset += sizeof(NDR_PARAM_OIF_OTHER); - } - TRACE("\tmemory addr (after): %p\n", pArg); - } -} - -static void client_do_args_old_format(PMIDL_STUB_MESSAGE pStubMsg, - PFORMAT_STRING pFormat, int phase, unsigned short stack_size, - unsigned char *pRetVal, BOOL object_proc) -{ - /* current format string offset */ - int current_offset = 0; - /* current stack offset */ - unsigned short current_stack_offset = 0; - /* counter */ - unsigned short i; - - /* NOTE: V1 style format does't terminate on the number_of_params - * condition as it doesn't have this attribute. Instead it - * terminates when the stack size given in the header is exceeded. - */ - for (i = 0; TRUE; i++) - { - const NDR_PARAM_OI_BASETYPE *pParam = - (const NDR_PARAM_OI_BASETYPE *)&pFormat[current_offset]; - /* note: current_stack_offset starts after the This pointer - * if present, so adjust this */ - unsigned short current_stack_offset_adjusted = current_stack_offset + - (object_proc ? sizeof(void *) : 0); - unsigned char * pArg = ARG_FROM_OFFSET(*pStubMsg, current_stack_offset_adjusted); - - /* no more parameters; exit loop */ - if (current_stack_offset_adjusted >= stack_size) - break; - - TRACE("param[%d]: old format\n", i); - TRACE("\tparam_direction: 0x%x\n", pParam->param_direction); - TRACE("\tstack_offset: 0x%x\n", current_stack_offset_adjusted); - TRACE("\tmemory addr (before): %p\n", pArg); - - if (pParam->param_direction == RPC_FC_IN_PARAM_BASETYPE || - pParam->param_direction == RPC_FC_RETURN_PARAM_BASETYPE) - { - const unsigned char * pTypeFormat = - &pParam->type_format_char; - - TRACE("\tbase type 0x%02x\n", *pTypeFormat); - - switch (phase) - { - case PROXY_CALCSIZE: - if (pParam->param_direction == RPC_FC_IN_PARAM_BASETYPE) - call_buffer_sizer(pStubMsg, pArg, pTypeFormat); - break; - case PROXY_MARSHAL: - if (pParam->param_direction == RPC_FC_IN_PARAM_BASETYPE) - call_marshaller(pStubMsg, pArg, pTypeFormat); - break; - case PROXY_UNMARSHAL: - if (pParam->param_direction == RPC_FC_RETURN_PARAM_BASETYPE) - { - if (pParam->param_direction & RPC_FC_RETURN_PARAM) - call_unmarshaller(pStubMsg, (unsigned char **)pRetVal, pTypeFormat, 0); - else - call_unmarshaller(pStubMsg, &pArg, pTypeFormat, 0); - } - break; - default: - RpcRaiseException(RPC_S_INTERNAL_ERROR); - } - - current_stack_offset += call_memory_sizer(pStubMsg, pTypeFormat); - current_offset += sizeof(NDR_PARAM_OI_BASETYPE); - } - else - { - const NDR_PARAM_OI_OTHER *pParamOther = - (const NDR_PARAM_OI_OTHER *)&pFormat[current_offset]; - - const unsigned char *pTypeFormat = - &pStubMsg->StubDesc->pFormatTypes[pParamOther->type_offset]; - - TRACE("\tcomplex type 0x%02x\n", *pTypeFormat); - - switch (phase) - { - case PROXY_CALCSIZE: - if (pParam->param_direction == RPC_FC_IN_PARAM || - pParam->param_direction & RPC_FC_IN_OUT_PARAM) - call_buffer_sizer(pStubMsg, *(unsigned char **)pArg, pTypeFormat); - break; - case PROXY_MARSHAL: - if (pParam->param_direction == RPC_FC_IN_PARAM || - pParam->param_direction & RPC_FC_IN_OUT_PARAM) - call_marshaller(pStubMsg, *(unsigned char **)pArg, pTypeFormat); - break; - case PROXY_UNMARSHAL: - if (pParam->param_direction == RPC_FC_IN_OUT_PARAM || - pParam->param_direction == RPC_FC_OUT_PARAM) - call_unmarshaller(pStubMsg, (unsigned char **)pArg, pTypeFormat, 0); - else if (pParam->param_direction == RPC_FC_RETURN_PARAM) - call_unmarshaller(pStubMsg, (unsigned char **)pRetVal, pTypeFormat, 0); - break; - default: - RpcRaiseException(RPC_S_INTERNAL_ERROR); - } - - current_stack_offset += pParamOther->stack_size * sizeof(INT); - current_offset += sizeof(NDR_PARAM_OI_OTHER); - } - TRACE("\tmemory addr (after): %p\n", pArg); - } -} - -/* the return type should be CLIENT_CALL_RETURN, but this is incompatible - * with the way gcc returns structures. "void *" should be the largest type - * that MIDL should allow you to return anyway */ -LONG_PTR WINAPIV NdrClientCall2(PMIDL_STUB_DESC pStubDesc, PFORMAT_STRING pFormat, ...) -{ - /* pointer to start of stack where arguments start */ - RPC_MESSAGE rpcMsg; - MIDL_STUB_MESSAGE stubMsg; - handle_t hBinding = NULL; - /* procedure number */ - unsigned short procedure_number; - /* size of stack */ - unsigned short stack_size; - /* number of parameters. optional for client to give it to us */ - unsigned char number_of_params = ~0; - /* cache of Oif_flags from v2 procedure header */ - INTERPRETER_OPT_FLAGS Oif_flags = { 0 }; - /* cache of extension flags from NDR_PROC_HEADER_EXTS */ - INTERPRETER_OPT_FLAGS2 ext_flags = { 0 }; - /* the type of pass we are currently doing */ - int phase; - /* header for procedure string */ - const NDR_PROC_HEADER * pProcHeader = (const NDR_PROC_HEADER *)&pFormat[0]; - /* -Oif or -Oicf generated format */ - BOOL bV2Format = FALSE; - /* the value to return to the client from the remote procedure */ - LONG_PTR RetVal = 0; - /* the pointer to the object when in OLE mode */ - void * This = NULL; - PFORMAT_STRING pHandleFormat; - - TRACE("pStubDesc %p, pFormat %p, ...\n", pStubDesc, pFormat); - - /* Later NDR language versions probably won't be backwards compatible */ - if (pStubDesc->Version > 0x50002) - { - FIXME("Incompatible stub description version: 0x%x\n", pStubDesc->Version); - RpcRaiseException(RPC_X_WRONG_STUB_VERSION); - } - - if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCFLAGS) - { - const NDR_PROC_HEADER_RPC *pProcHeader = (const NDR_PROC_HEADER_RPC *)&pFormat[0]; - stack_size = pProcHeader->stack_size; - procedure_number = pProcHeader->proc_num; - pFormat += sizeof(NDR_PROC_HEADER_RPC); - } - else - { - stack_size = pProcHeader->stack_size; - procedure_number = pProcHeader->proc_num; - pFormat += sizeof(NDR_PROC_HEADER); - } - TRACE("stack size: 0x%x\n", stack_size); - TRACE("proc num: %d\n", procedure_number); - - /* create the full pointer translation tables, if requested */ - if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_FULLPTR) - stubMsg.FullPtrXlatTables = NdrFullPointerXlatInit(0,XLAT_CLIENT); - - if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT) - { - /* object is always the first argument */ - This = **(void *const **)(&pFormat+1); - NdrProxyInitialize(This, &rpcMsg, &stubMsg, pStubDesc, procedure_number); - } - else - NdrClientInitializeNew(&rpcMsg, &stubMsg, pStubDesc, procedure_number); - - TRACE("Oi_flags = 0x%02x\n", pProcHeader->Oi_flags); - TRACE("MIDL stub version = 0x%x\n", pStubDesc->MIDLVersion); - - /* needed for conformance of top-level objects */ -#ifdef __i386__ - stubMsg.StackTop = *(unsigned char **)(&pFormat+1); -#else -# warning Stack not retrieved for your CPU architecture -#endif - - pHandleFormat = pFormat; - - /* we only need a handle if this isn't an object method */ - if (!(pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT)) - { - pFormat = client_get_handle(&stubMsg, pProcHeader, pHandleFormat, &hBinding); - if (!pFormat) return 0; - } - - bV2Format = (pStubDesc->Version >= 0x20000); - - if (bV2Format) - { - const NDR_PROC_PARTIAL_OIF_HEADER *pOIFHeader = - (const NDR_PROC_PARTIAL_OIF_HEADER *)pFormat; - - Oif_flags = pOIFHeader->Oi2Flags; - number_of_params = pOIFHeader->number_of_params; - - pFormat += sizeof(NDR_PROC_PARTIAL_OIF_HEADER); - } - - TRACE("Oif_flags = "); dump_INTERPRETER_OPT_FLAGS(Oif_flags); - - if (Oif_flags.HasExtensions) - { - const NDR_PROC_HEADER_EXTS *pExtensions = - (const NDR_PROC_HEADER_EXTS *)pFormat; - ext_flags = pExtensions->Flags2; - pFormat += pExtensions->Size; - } - - stubMsg.BufferLength = 0; - - /* store the RPC flags away */ - if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCFLAGS) - rpcMsg.RpcFlags = ((const NDR_PROC_HEADER_RPC *)pProcHeader)->rpc_flags; - - /* use alternate memory allocation routines */ - if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCSSALLOC) - NdrRpcSmSetClientToOsf(&stubMsg); - - if (Oif_flags.HasPipes) - { - FIXME("pipes not supported yet\n"); - RpcRaiseException(RPC_X_WRONG_STUB_VERSION); /* FIXME: remove when implemented */ - /* init pipes package */ - /* NdrPipesInitialize(...) */ - } - if (ext_flags.HasNewCorrDesc) - { - /* initialize extra correlation package */ - FIXME("new correlation description not implemented\n"); - stubMsg.fHasNewCorrDesc = TRUE; - } - - /* order of phases: - * 1. PROXY_CALCSIZE - calculate the buffer size - * 2. PROXY_GETBUFFER - allocate the buffer - * 3. PROXY_MARHSAL - marshal [in] params into the buffer - * 4. PROXY_SENDRECEIVE - send/receive buffer - * 5. PROXY_UNMARHSAL - unmarshal [out] params from buffer - */ - for (phase = PROXY_CALCSIZE; phase <= PROXY_UNMARSHAL; phase++) - { - TRACE("phase = %d\n", phase); - switch (phase) - { - case PROXY_GETBUFFER: - /* allocate the buffer */ - if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT) - NdrProxyGetBuffer(This, &stubMsg); - else if (Oif_flags.HasPipes) - /* NdrGetPipeBuffer(...) */ - FIXME("pipes not supported yet\n"); - else - { - if (pProcHeader->handle_type == RPC_FC_AUTO_HANDLE) -#if 0 - NdrNsGetBuffer(&stubMsg, stubMsg.BufferLength, hBinding); -#else - FIXME("using auto handle - call NdrNsGetBuffer when it gets implemented\n"); -#endif - else - NdrGetBuffer(&stubMsg, stubMsg.BufferLength, hBinding); - } - break; - case PROXY_SENDRECEIVE: - /* send the [in] params and receive the [out] and [retval] - * params */ - if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT) - NdrProxySendReceive(This, &stubMsg); - else if (Oif_flags.HasPipes) - /* NdrPipesSendReceive(...) */ - FIXME("pipes not supported yet\n"); - else - { - if (pProcHeader->handle_type == RPC_FC_AUTO_HANDLE) -#if 0 - NdrNsSendReceive(&stubMsg, stubMsg.Buffer, pStubDesc->IMPLICIT_HANDLE_INFO.pAutoHandle); -#else - FIXME("using auto handle - call NdrNsSendReceive when it gets implemented\n"); -#endif - else - NdrSendReceive(&stubMsg, stubMsg.Buffer); - } - - /* convert strings, floating point values and endianess into our - * preferred format */ - if ((rpcMsg.DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION) - NdrConvert(&stubMsg, pFormat); - - break; - case PROXY_CALCSIZE: - case PROXY_MARSHAL: - case PROXY_UNMARSHAL: - if (bV2Format) - client_do_args(&stubMsg, pFormat, phase, number_of_params, - (unsigned char *)&RetVal); - else - client_do_args_old_format(&stubMsg, pFormat, phase, stack_size, - (unsigned char *)&RetVal, - (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT)); - break; - default: - ERR("shouldn't reach here. phase %d\n", phase); - break; - } - } - - if (ext_flags.HasNewCorrDesc) - { - /* free extra correlation package */ - /* NdrCorrelationFree(&stubMsg); */ - } - - if (Oif_flags.HasPipes) - { - /* NdrPipesDone(...) */ - } - - /* free the full pointer translation tables */ - if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_FULLPTR) - NdrFullPointerXlatFree(stubMsg.FullPtrXlatTables); - - /* free marshalling buffer */ - if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT) - NdrProxyFreeBuffer(This, &stubMsg); - else - { - NdrFreeBuffer(&stubMsg); - client_free_handle(&stubMsg, pProcHeader, pHandleFormat, hBinding); - } - - TRACE("RetVal = 0x%lx\n", RetVal); - - return RetVal; -} - -/* calls a function with the specificed arguments, restoring the stack - * properly afterwards as we don't know the calling convention of the - * function */ -#if defined __i386__ && defined _MSC_VER -__declspec(naked) LONG_PTR __cdecl call_server_func(SERVER_ROUTINE func, unsigned char * args, unsigned int stack_size) -{ - __asm - { - push ebp - push edi ; Save registers - push esi - mov ebp, esp - mov eax, [ebp+16] ; Get stack size - sub esp, eax ; Make room in stack for arguments - mov edi, esp - mov ecx, eax - mov esi, [ebp+12] - shr ecx, 2 - cld - rep movsd ; Copy dword blocks - call [ebp+8] ; Call function - lea esp, [ebp-8] ; Restore stack - pop esi ; Restore registers - pop edi - pop ebp - ret - } -} -#elif defined __i386__ && defined __GNUC__ -LONG_PTR __cdecl call_server_func(SERVER_ROUTINE func, unsigned char * args, unsigned int stack_size); -__ASM_GLOBAL_FUNC(call_server_func, - "pushl %ebp\n\t" - "movl %esp, %ebp\n\t" - "pushl %edi\n\t" /* Save registers */ - "pushl %esi\n\t" - "movl 16(%ebp), %eax\n\t" /* Get stack size */ - "subl %eax, %esp\n\t" /* Make room in stack for arguments */ - "andl $~15, %esp\n\t" /* Make sure stack has 16-byte alignment for Mac OS X */ - "movl %esp, %edi\n\t" - "movl %eax, %ecx\n\t" - "movl 12(%ebp), %esi\n\t" - "shrl $2, %ecx\n\t" /* divide by 4 */ - "cld\n\t" - "rep; movsl\n\t" /* Copy dword blocks */ - "call *8(%ebp)\n\t" /* Call function */ - "leal -8(%ebp), %esp\n\t" /* Restore stack */ - "popl %esi\n\t" /* Restore registers */ - "popl %edi\n\t" - "popl %ebp\n\t" - "ret\n" ) -#else -#warning call_server_func not implemented for your architecture -LONG_PTR __cdecl call_server_func(SERVER_ROUTINE func, unsigned char * args, unsigned short stack_size) -{ - FIXME("Not implemented for your architecture\n"); - return 0; -} -#endif - -static DWORD calc_arg_size(MIDL_STUB_MESSAGE *pStubMsg, PFORMAT_STRING pFormat) -{ - DWORD size; - switch(*pFormat) - { - case RPC_FC_STRUCT: - size = *(const WORD*)(pFormat + 2); - break; - case RPC_FC_CARRAY: - size = *(const WORD*)(pFormat + 2); - ComputeConformance(pStubMsg, NULL, pFormat + 4, 0); - size *= pStubMsg->MaxCount; - break; - case RPC_FC_SMFARRAY: - size = *(const WORD*)(pFormat + 2); - break; - case RPC_FC_LGFARRAY: - size = *(const DWORD*)(pFormat + 2); - break; - default: - FIXME("Unhandled type %02x\n", *pFormat); - /* fallthrough */ - case RPC_FC_RP: - size = sizeof(void *); - break; - } - return size; -} - -static LONG_PTR *stub_do_args(MIDL_STUB_MESSAGE *pStubMsg, - PFORMAT_STRING pFormat, int phase, - unsigned char *args, - unsigned short number_of_params) -{ - /* counter */ - unsigned short i; - /* current format string offset */ - int current_offset = 0; - /* current stack offset */ - unsigned short current_stack_offset = 0; - /* location to put retval into */ - LONG_PTR *retval_ptr = NULL; - - for (i = 0; i < number_of_params; i++) - { - const NDR_PARAM_OIF_BASETYPE *pParam = - (const NDR_PARAM_OIF_BASETYPE *)&pFormat[current_offset]; - unsigned char *pArg; - - current_stack_offset = pParam->stack_offset; - pArg = (unsigned char *)(args+current_stack_offset); - - TRACE("param[%d]: new format\n", i); - TRACE("\tparam_attributes:"); dump_RPC_FC_PROC_PF(pParam->param_attributes); TRACE("\n"); - TRACE("\tstack_offset: 0x%x\n", current_stack_offset); - TRACE("\tmemory addr (before): %p -> %p\n", pArg, *(unsigned char **)pArg); - - if (pParam->param_attributes.IsBasetype) - { - const unsigned char *pTypeFormat = - &pParam->type_format_char; - - TRACE("\tbase type: 0x%02x\n", *pTypeFormat); - - switch (phase) - { - case STUBLESS_MARSHAL: - if (pParam->param_attributes.IsOut || pParam->param_attributes.IsReturn) - { - if (pParam->param_attributes.IsSimpleRef) - call_marshaller(pStubMsg, *(unsigned char **)pArg, pTypeFormat); - else - call_marshaller(pStubMsg, pArg, pTypeFormat); - } - break; - case STUBLESS_FREE: - if (pParam->param_attributes.ServerAllocSize) - HeapFree(GetProcessHeap(), 0, *(void **)pArg); - break; - case STUBLESS_UNMARSHAL: - if (pParam->param_attributes.ServerAllocSize) - *(void **)pArg = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - pParam->param_attributes.ServerAllocSize * 8); - - if (pParam->param_attributes.IsIn) - { - if (pParam->param_attributes.IsSimpleRef) - call_unmarshaller(pStubMsg, (unsigned char **)pArg, pTypeFormat, 0); - else - call_unmarshaller(pStubMsg, &pArg, pTypeFormat, 0); - } - - /* make a note of the address of the return value parameter for later */ - if (pParam->param_attributes.IsReturn) - retval_ptr = (LONG_PTR *)pArg; - - break; - case STUBLESS_CALCSIZE: - if (pParam->param_attributes.IsOut || pParam->param_attributes.IsReturn) - { - if (pParam->param_attributes.IsSimpleRef) - call_buffer_sizer(pStubMsg, *(unsigned char **)pArg, pTypeFormat); - else - call_buffer_sizer(pStubMsg, pArg, pTypeFormat); - } - break; - default: - RpcRaiseException(RPC_S_INTERNAL_ERROR); - } - - current_offset += sizeof(NDR_PARAM_OIF_BASETYPE); - } - else - { - const NDR_PARAM_OIF_OTHER *pParamOther = - (const NDR_PARAM_OIF_OTHER *)&pFormat[current_offset]; - - const unsigned char * pTypeFormat = - &(pStubMsg->StubDesc->pFormatTypes[pParamOther->type_offset]); - - TRACE("\tcomplex type 0x%02x\n", *pTypeFormat); - - switch (phase) - { - case STUBLESS_MARSHAL: - if (pParam->param_attributes.IsOut || pParam->param_attributes.IsReturn) - { - if (pParam->param_attributes.IsByValue) - call_marshaller(pStubMsg, pArg, pTypeFormat); - else - call_marshaller(pStubMsg, *(unsigned char **)pArg, pTypeFormat); - } - break; - case STUBLESS_FREE: - if (pParam->param_attributes.MustFree) - { - if (pParam->param_attributes.IsByValue) - call_freer(pStubMsg, pArg, pTypeFormat); - else - call_freer(pStubMsg, *(unsigned char **)pArg, pTypeFormat); - } - - if (pParam->param_attributes.IsOut && - !pParam->param_attributes.IsIn && - !pParam->param_attributes.IsByValue && - !pParam->param_attributes.ServerAllocSize) - { - pStubMsg->pfnFree(*(void **)pArg); - } - - if (pParam->param_attributes.ServerAllocSize) - HeapFree(GetProcessHeap(), 0, *(void **)pArg); - /* FIXME: call call_freer here for IN types with MustFree set */ - break; - case STUBLESS_UNMARSHAL: - if (pParam->param_attributes.ServerAllocSize) - *(void **)pArg = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - pParam->param_attributes.ServerAllocSize * 8); - - if (pParam->param_attributes.IsIn) - { - if (pParam->param_attributes.IsByValue) - call_unmarshaller(pStubMsg, &pArg, pTypeFormat, 0); - else - call_unmarshaller(pStubMsg, (unsigned char **)pArg, pTypeFormat, 0); - } - else if (pParam->param_attributes.IsOut && - !pParam->param_attributes.ServerAllocSize && - !pParam->param_attributes.IsByValue) - { - DWORD size = calc_arg_size(pStubMsg, pTypeFormat); - - if(size) - { - *(void **)pArg = NdrAllocate(pStubMsg, size); - memset(*(void **)pArg, 0, size); - } - } - break; - case STUBLESS_CALCSIZE: - if (pParam->param_attributes.IsOut || pParam->param_attributes.IsReturn) - { - if (pParam->param_attributes.IsByValue) - call_buffer_sizer(pStubMsg, pArg, pTypeFormat); - else - call_buffer_sizer(pStubMsg, *(unsigned char **)pArg, pTypeFormat); - } - break; - default: - RpcRaiseException(RPC_S_INTERNAL_ERROR); - } - - current_offset += sizeof(NDR_PARAM_OIF_OTHER); - } - TRACE("\tmemory addr (after): %p -> %p\n", pArg, *(unsigned char **)pArg); - } - - return retval_ptr; -} - -static LONG_PTR *stub_do_old_args(MIDL_STUB_MESSAGE *pStubMsg, - PFORMAT_STRING pFormat, int phase, - unsigned char *args, - unsigned short stack_size, BOOL object) -{ - /* counter */ - unsigned short i; - /* current format string offset */ - int current_offset = 0; - /* current stack offset */ - unsigned short current_stack_offset = 0; - /* location to put retval into */ - LONG_PTR *retval_ptr = NULL; - - for (i = 0; TRUE; i++) - { - const NDR_PARAM_OI_BASETYPE *pParam = - (const NDR_PARAM_OI_BASETYPE *)&pFormat[current_offset]; - /* note: current_stack_offset starts after the This pointer - * if present, so adjust this */ - unsigned short current_stack_offset_adjusted = current_stack_offset + - (object ? sizeof(void *) : 0); - unsigned char *pArg = (unsigned char *)(args+current_stack_offset_adjusted); - - /* no more parameters; exit loop */ - if (current_stack_offset_adjusted >= stack_size) - break; - - TRACE("param[%d]: old format\n", i); - TRACE("\tparam_direction: 0x%x\n", pParam->param_direction); - TRACE("\tstack_offset: 0x%x\n", current_stack_offset_adjusted); - - if (pParam->param_direction == RPC_FC_IN_PARAM_BASETYPE || - pParam->param_direction == RPC_FC_RETURN_PARAM_BASETYPE) - { - const unsigned char *pTypeFormat = - &pParam->type_format_char; - - TRACE("\tbase type 0x%02x\n", *pTypeFormat); - - switch (phase) - { - case STUBLESS_MARSHAL: - if (pParam->param_direction == RPC_FC_RETURN_PARAM_BASETYPE) - call_marshaller(pStubMsg, pArg, pTypeFormat); - break; - case STUBLESS_FREE: - if (pParam->param_direction == RPC_FC_IN_PARAM_BASETYPE) - call_freer(pStubMsg, pArg, pTypeFormat); - break; - case STUBLESS_UNMARSHAL: - if (pParam->param_direction == RPC_FC_IN_PARAM_BASETYPE) - call_unmarshaller(pStubMsg, &pArg, pTypeFormat, 0); - else if (pParam->param_direction == RPC_FC_RETURN_PARAM_BASETYPE) - retval_ptr = (LONG_PTR *)pArg; - break; - case STUBLESS_CALCSIZE: - if (pParam->param_direction == RPC_FC_RETURN_PARAM_BASETYPE) - call_buffer_sizer(pStubMsg, pArg, pTypeFormat); - break; - default: - RpcRaiseException(RPC_S_INTERNAL_ERROR); - } - - current_stack_offset += call_memory_sizer(pStubMsg, pTypeFormat); - current_offset += sizeof(NDR_PARAM_OI_BASETYPE); - } - else - { - const NDR_PARAM_OI_OTHER *pParamOther = - (const NDR_PARAM_OI_OTHER *)&pFormat[current_offset]; - - const unsigned char * pTypeFormat = - &pStubMsg->StubDesc->pFormatTypes[pParamOther->type_offset]; - - TRACE("\tcomplex type 0x%02x\n", *pTypeFormat); - - switch (phase) - { - case STUBLESS_MARSHAL: - if (pParam->param_direction == RPC_FC_OUT_PARAM || - pParam->param_direction == RPC_FC_IN_OUT_PARAM || - pParam->param_direction == RPC_FC_RETURN_PARAM) - call_marshaller(pStubMsg, *(unsigned char **)pArg, pTypeFormat); - break; - case STUBLESS_FREE: - if (pParam->param_direction == RPC_FC_IN_OUT_PARAM || - pParam->param_direction == RPC_FC_IN_PARAM) - call_freer(pStubMsg, *(unsigned char **)pArg, pTypeFormat); - else if (pParam->param_direction == RPC_FC_OUT_PARAM) - pStubMsg->pfnFree(*(void **)pArg); - break; - case STUBLESS_UNMARSHAL: - if (pParam->param_direction == RPC_FC_IN_OUT_PARAM || - pParam->param_direction == RPC_FC_IN_PARAM) - call_unmarshaller(pStubMsg, (unsigned char **)pArg, pTypeFormat, 0); - else if (pParam->param_direction == RPC_FC_RETURN_PARAM) - retval_ptr = (LONG_PTR *)pArg; - else if (pParam->param_direction == RPC_FC_OUT_PARAM) - { - DWORD size = calc_arg_size(pStubMsg, pTypeFormat); - - if(size) - { - *(void **)pArg = NdrAllocate(pStubMsg, size); - memset(*(void **)pArg, 0, size); - } - } - break; - case STUBLESS_CALCSIZE: - if (pParam->param_direction == RPC_FC_OUT_PARAM || - pParam->param_direction == RPC_FC_IN_OUT_PARAM || - pParam->param_direction == RPC_FC_RETURN_PARAM) - call_buffer_sizer(pStubMsg, *(unsigned char **)pArg, pTypeFormat); - break; - default: - RpcRaiseException(RPC_S_INTERNAL_ERROR); - } - - current_stack_offset += pParamOther->stack_size * sizeof(INT); - current_offset += sizeof(NDR_PARAM_OI_OTHER); - } - } - - return retval_ptr; -} - -/*********************************************************************** - * NdrStubCall2 [RPCRT4.@] - * - * Unmarshals [in] parameters, calls either a method in an object or a server - * function, marshals any [out] parameters and frees any allocated data. - * - * NOTES - * Used by stubless MIDL-generated code. - */ -LONG WINAPI NdrStubCall2( - struct IRpcStubBuffer * pThis, - struct IRpcChannelBuffer * pChannel, - PRPC_MESSAGE pRpcMsg, - DWORD * pdwStubPhase) -{ - const MIDL_SERVER_INFO *pServerInfo; - const MIDL_STUB_DESC *pStubDesc; - PFORMAT_STRING pFormat; - MIDL_STUB_MESSAGE stubMsg; - /* pointer to start of stack to pass into stub implementation */ - unsigned char * args; - /* size of stack */ - unsigned short stack_size; - /* number of parameters. optional for client to give it to us */ - unsigned char number_of_params = ~0; - /* cache of Oif_flags from v2 procedure header */ - INTERPRETER_OPT_FLAGS Oif_flags = { 0 }; - /* cache of extension flags from NDR_PROC_HEADER_EXTS */ - INTERPRETER_OPT_FLAGS2 ext_flags = { 0 }; - /* the type of pass we are currently doing */ - int phase; - /* header for procedure string */ - const NDR_PROC_HEADER *pProcHeader; - /* offset in format string for start of params */ - int parameter_start_offset; - /* current format string offset */ - int current_offset; - /* -Oif or -Oicf generated format */ - BOOL bV2Format = FALSE; - /* location to put retval into */ - LONG_PTR *retval_ptr = NULL; - - TRACE("pThis %p, pChannel %p, pRpcMsg %p, pdwStubPhase %p\n", pThis, pChannel, pRpcMsg, pdwStubPhase); - - if (pThis) - pServerInfo = CStdStubBuffer_GetServerInfo(pThis); - else - pServerInfo = ((RPC_SERVER_INTERFACE *)pRpcMsg->RpcInterfaceInformation)->InterpreterInfo; - - pStubDesc = pServerInfo->pStubDesc; - pFormat = pServerInfo->ProcString + pServerInfo->FmtStringOffset[pRpcMsg->ProcNum]; - pProcHeader = (const NDR_PROC_HEADER *)&pFormat[0]; - - /* Later NDR language versions probably won't be backwards compatible */ - if (pStubDesc->Version > 0x50002) - { - FIXME("Incompatible stub description version: 0x%x\n", pStubDesc->Version); - RpcRaiseException(RPC_X_WRONG_STUB_VERSION); - } - - /* create the full pointer translation tables, if requested */ - if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_FULLPTR) - stubMsg.FullPtrXlatTables = NdrFullPointerXlatInit(0,XLAT_SERVER); - - if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCFLAGS) - { - const NDR_PROC_HEADER_RPC *pProcHeader = (const NDR_PROC_HEADER_RPC *)&pFormat[0]; - stack_size = pProcHeader->stack_size; - current_offset = sizeof(NDR_PROC_HEADER_RPC); - - } - else - { - stack_size = pProcHeader->stack_size; - current_offset = sizeof(NDR_PROC_HEADER); - } - - TRACE("Oi_flags = 0x%02x\n", pProcHeader->Oi_flags); - - /* binding */ - switch (pProcHeader->handle_type) - { - /* explicit binding: parse additional section */ - case RPC_FC_BIND_EXPLICIT: - switch (pFormat[current_offset]) /* handle_type */ - { - case RPC_FC_BIND_PRIMITIVE: /* explicit primitive */ - current_offset += sizeof(NDR_EHD_PRIMITIVE); - break; - case RPC_FC_BIND_GENERIC: /* explicit generic */ - current_offset += sizeof(NDR_EHD_GENERIC); - break; - case RPC_FC_BIND_CONTEXT: /* explicit context */ - current_offset += sizeof(NDR_EHD_CONTEXT); - break; - default: - ERR("bad explicit binding handle type (0x%02x)\n", pProcHeader->handle_type); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - } - break; - case RPC_FC_BIND_GENERIC: /* implicit generic */ - case RPC_FC_BIND_PRIMITIVE: /* implicit primitive */ - case RPC_FC_CALLBACK_HANDLE: /* implicit callback */ - case RPC_FC_AUTO_HANDLE: /* implicit auto handle */ - break; - default: - ERR("bad implicit binding handle type (0x%02x)\n", pProcHeader->handle_type); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - } - - bV2Format = (pStubDesc->Version >= 0x20000); - - if (bV2Format) - { - const NDR_PROC_PARTIAL_OIF_HEADER *pOIFHeader = - (const NDR_PROC_PARTIAL_OIF_HEADER *)&pFormat[current_offset]; - - Oif_flags = pOIFHeader->Oi2Flags; - number_of_params = pOIFHeader->number_of_params; - - current_offset += sizeof(NDR_PROC_PARTIAL_OIF_HEADER); - } - - TRACE("Oif_flags = "); dump_INTERPRETER_OPT_FLAGS(Oif_flags); - - if (Oif_flags.HasExtensions) - { - const NDR_PROC_HEADER_EXTS *pExtensions = - (const NDR_PROC_HEADER_EXTS *)&pFormat[current_offset]; - ext_flags = pExtensions->Flags2; - current_offset += pExtensions->Size; - } - - if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT) - NdrStubInitialize(pRpcMsg, &stubMsg, pStubDesc, pChannel); - else - NdrServerInitializeNew(pRpcMsg, &stubMsg, pStubDesc); - - /* store the RPC flags away */ - if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCFLAGS) - pRpcMsg->RpcFlags = ((const NDR_PROC_HEADER_RPC *)pProcHeader)->rpc_flags; - - /* use alternate memory allocation routines */ - if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCSSALLOC) -#if 0 - NdrRpcSsEnableAllocate(&stubMsg); -#else - FIXME("Set RPCSS memory allocation routines\n"); -#endif - - if (Oif_flags.HasPipes) - { - FIXME("pipes not supported yet\n"); - RpcRaiseException(RPC_X_WRONG_STUB_VERSION); /* FIXME: remove when implemented */ - /* init pipes package */ - /* NdrPipesInitialize(...) */ - } - if (ext_flags.HasNewCorrDesc) - { - /* initialize extra correlation package */ - FIXME("new correlation description not implemented\n"); - stubMsg.fHasNewCorrDesc = TRUE; - } - - /* convert strings, floating point values and endianess into our - * preferred format */ - if ((pRpcMsg->DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION) - NdrConvert(&stubMsg, pFormat); - - parameter_start_offset = current_offset; - - TRACE("allocating memory for stack of size %x\n", stack_size); - - args = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, stack_size); - stubMsg.StackTop = args; /* used by conformance of top-level objects */ - - /* add the implicit This pointer as the first arg to the function if we - * are calling an object method */ - if (pThis) - *(void **)args = ((CStdStubBuffer *)pThis)->pvServerObject; - - /* order of phases: - * 1. STUBLESS_UNMARHSAL - unmarshal [in] params from buffer - * 2. STUBLESS_CALLSERVER - send/receive buffer - * 3. STUBLESS_CALCSIZE - get [out] buffer size - * 4. STUBLESS_GETBUFFER - allocate [out] buffer - * 5. STUBLESS_MARHSAL - marshal [out] params to buffer - */ - for (phase = STUBLESS_UNMARSHAL; phase <= STUBLESS_FREE; phase++) - { - TRACE("phase = %d\n", phase); - switch (phase) - { - case STUBLESS_CALLSERVER: - /* call the server function */ - if (pServerInfo->ThunkTable && pServerInfo->ThunkTable[pRpcMsg->ProcNum]) - pServerInfo->ThunkTable[pRpcMsg->ProcNum](&stubMsg); - else - { - SERVER_ROUTINE func; - LONG_PTR retval; - - if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT) - { - SERVER_ROUTINE *vtbl = *(SERVER_ROUTINE **)((CStdStubBuffer *)pThis)->pvServerObject; - func = vtbl[pRpcMsg->ProcNum]; - } - else - func = pServerInfo->DispatchTable[pRpcMsg->ProcNum]; - - /* FIXME: what happens with return values that don't fit into a single register on x86? */ - retval = call_server_func(func, args, stack_size); - - if (retval_ptr) - { - TRACE("stub implementation returned 0x%lx\n", retval); - *retval_ptr = retval; - } - else - TRACE("void stub implementation\n"); - } - - stubMsg.Buffer = NULL; - stubMsg.BufferLength = 0; - - break; - case STUBLESS_GETBUFFER: - if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT) - NdrStubGetBuffer(pThis, pChannel, &stubMsg); - else - { - RPC_STATUS Status; - - pRpcMsg->BufferLength = stubMsg.BufferLength; - /* allocate buffer for [out] and [ret] params */ - Status = I_RpcGetBuffer(pRpcMsg); - if (Status) - RpcRaiseException(Status); - stubMsg.BufferStart = pRpcMsg->Buffer; - stubMsg.BufferEnd = stubMsg.BufferStart + stubMsg.BufferLength; - stubMsg.Buffer = stubMsg.BufferStart; - } - break; - case STUBLESS_MARSHAL: - case STUBLESS_UNMARSHAL: - case STUBLESS_CALCSIZE: - case STUBLESS_FREE: - if (bV2Format) - retval_ptr = stub_do_args(&stubMsg, &pFormat[parameter_start_offset], - phase, args, number_of_params); - else - retval_ptr = stub_do_old_args(&stubMsg, &pFormat[parameter_start_offset], - phase, args, stack_size, - (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT)); - - break; - default: - ERR("shouldn't reach here. phase %d\n", phase); - break; - } - } - - pRpcMsg->BufferLength = (unsigned int)(stubMsg.Buffer - (unsigned char *)pRpcMsg->Buffer); - - if (ext_flags.HasNewCorrDesc) - { - /* free extra correlation package */ - /* NdrCorrelationFree(&stubMsg); */ - } - - if (Oif_flags.HasPipes) - { - /* NdrPipesDone(...) */ - } - - /* free the full pointer translation tables */ - if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_FULLPTR) - NdrFullPointerXlatFree(stubMsg.FullPtrXlatTables); - - /* free server function stack */ - HeapFree(GetProcessHeap(), 0, args); - - return S_OK; -} - -/*********************************************************************** - * NdrServerCall2 [RPCRT4.@] - */ -void WINAPI NdrServerCall2(PRPC_MESSAGE pRpcMsg) -{ - DWORD dwPhase; - NdrStubCall2(NULL, NULL, pRpcMsg, &dwPhase); -} diff --git a/reactos/dll/win32/rpcrt4_new/rpc_binding.c b/reactos/dll/win32/rpcrt4_new/rpc_binding.c deleted file mode 100644 index 24769e2ce60..00000000000 --- a/reactos/dll/win32/rpcrt4_new/rpc_binding.c +++ /dev/null @@ -1,1586 +0,0 @@ -/* - * RPC binding API - * - * Copyright 2001 Ove Kåven, TransGaming Technologies - * Copyright 2003 Mike Hearn - * Copyright 2004 Filip Navara - * Copyright 2006 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 -#include -#include -#include - -#include "windef.h" -#include "winbase.h" -#include "winnls.h" -#include "winerror.h" -#include "winternl.h" -#include "wine/unicode.h" - -#include "rpc.h" -#include "rpcndr.h" - -#include "wine/debug.h" - -#include "rpc_binding.h" -#include "rpc_assoc.h" - -WINE_DEFAULT_DEBUG_CHANNEL(rpc); - -LPSTR RPCRT4_strndupA(LPCSTR src, INT slen) -{ - DWORD len; - LPSTR s; - if (!src) return NULL; - if (slen == -1) slen = strlen(src); - len = slen; - s = HeapAlloc(GetProcessHeap(), 0, len+1); - memcpy(s, src, len); - s[len] = 0; - return s; -} - -LPSTR RPCRT4_strdupWtoA(LPCWSTR src) -{ - DWORD len; - LPSTR s; - if (!src) return NULL; - len = WideCharToMultiByte(CP_ACP, 0, src, -1, NULL, 0, NULL, NULL); - s = HeapAlloc(GetProcessHeap(), 0, len); - WideCharToMultiByte(CP_ACP, 0, src, -1, s, len, NULL, NULL); - return s; -} - -LPWSTR RPCRT4_strdupAtoW(LPCSTR src) -{ - DWORD len; - LPWSTR s; - if (!src) return NULL; - len = MultiByteToWideChar(CP_ACP, 0, src, -1, NULL, 0); - s = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR)); - MultiByteToWideChar(CP_ACP, 0, src, -1, s, len); - return s; -} - -static LPWSTR RPCRT4_strndupAtoW(LPCSTR src, INT slen) -{ - DWORD len; - LPWSTR s; - if (!src) return NULL; - len = MultiByteToWideChar(CP_ACP, 0, src, slen, NULL, 0); - s = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR)); - MultiByteToWideChar(CP_ACP, 0, src, slen, s, len); - return s; -} - -LPWSTR RPCRT4_strndupW(LPCWSTR src, INT slen) -{ - DWORD len; - LPWSTR s; - if (!src) return NULL; - if (slen == -1) slen = strlenW(src); - len = slen; - s = HeapAlloc(GetProcessHeap(), 0, (len+1)*sizeof(WCHAR)); - memcpy(s, src, len*sizeof(WCHAR)); - s[len] = 0; - return s; -} - -void RPCRT4_strfree(LPSTR src) -{ - HeapFree(GetProcessHeap(), 0, src); -} - -static RPC_STATUS RPCRT4_AllocBinding(RpcBinding** Binding, BOOL server) -{ - RpcBinding* NewBinding; - - NewBinding = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RpcBinding)); - NewBinding->refs = 1; - NewBinding->server = server; - - *Binding = NewBinding; - - return RPC_S_OK; -} - -static RPC_STATUS RPCRT4_CreateBindingA(RpcBinding** Binding, BOOL server, LPCSTR Protseq) -{ - RpcBinding* NewBinding; - - RPCRT4_AllocBinding(&NewBinding, server); - NewBinding->Protseq = RPCRT4_strdupA(Protseq); - - TRACE("binding: %p\n", NewBinding); - *Binding = NewBinding; - - return RPC_S_OK; -} - -static RPC_STATUS RPCRT4_CreateBindingW(RpcBinding** Binding, BOOL server, LPCWSTR Protseq) -{ - RpcBinding* NewBinding; - - RPCRT4_AllocBinding(&NewBinding, server); - NewBinding->Protseq = RPCRT4_strdupWtoA(Protseq); - - TRACE("binding: %p\n", NewBinding); - *Binding = NewBinding; - - return RPC_S_OK; -} - -static RPC_STATUS RPCRT4_CompleteBindingA(RpcBinding* Binding, LPCSTR NetworkAddr, - LPCSTR Endpoint, LPCSTR NetworkOptions) -{ - RPC_STATUS status; - - TRACE("(RpcBinding == ^%p, NetworkAddr == %s, EndPoint == %s, NetworkOptions == %s)\n", Binding, - debugstr_a(NetworkAddr), debugstr_a(Endpoint), debugstr_a(NetworkOptions)); - - RPCRT4_strfree(Binding->NetworkAddr); - Binding->NetworkAddr = RPCRT4_strdupA(NetworkAddr); - RPCRT4_strfree(Binding->Endpoint); - if (Endpoint) { - Binding->Endpoint = RPCRT4_strdupA(Endpoint); - } else { - Binding->Endpoint = RPCRT4_strdupA(""); - } - HeapFree(GetProcessHeap(), 0, Binding->NetworkOptions); - Binding->NetworkOptions = RPCRT4_strdupAtoW(NetworkOptions); - if (!Binding->Endpoint) ERR("out of memory?\n"); - - status = RPCRT4_GetAssociation(Binding->Protseq, Binding->NetworkAddr, - Binding->Endpoint, Binding->NetworkOptions, - &Binding->Assoc); - if (status != RPC_S_OK) - return status; - - return RPC_S_OK; -} - -static RPC_STATUS RPCRT4_CompleteBindingW(RpcBinding* Binding, LPCWSTR NetworkAddr, - LPCWSTR Endpoint, LPCWSTR NetworkOptions) -{ - RPC_STATUS status; - - TRACE("(RpcBinding == ^%p, NetworkAddr == %s, EndPoint == %s, NetworkOptions == %s)\n", Binding, - debugstr_w(NetworkAddr), debugstr_w(Endpoint), debugstr_w(NetworkOptions)); - - RPCRT4_strfree(Binding->NetworkAddr); - Binding->NetworkAddr = RPCRT4_strdupWtoA(NetworkAddr); - RPCRT4_strfree(Binding->Endpoint); - if (Endpoint) { - Binding->Endpoint = RPCRT4_strdupWtoA(Endpoint); - } else { - Binding->Endpoint = RPCRT4_strdupA(""); - } - if (!Binding->Endpoint) ERR("out of memory?\n"); - HeapFree(GetProcessHeap(), 0, Binding->NetworkOptions); - Binding->NetworkOptions = RPCRT4_strdupW(NetworkOptions); - - status = RPCRT4_GetAssociation(Binding->Protseq, Binding->NetworkAddr, - Binding->Endpoint, Binding->NetworkOptions, - &Binding->Assoc); - if (status != RPC_S_OK) - return status; - - return RPC_S_OK; -} - -RPC_STATUS RPCRT4_ResolveBinding(RpcBinding* Binding, LPCSTR Endpoint) -{ - RPC_STATUS status; - - TRACE("(RpcBinding == ^%p, EndPoint == \"%s\"\n", Binding, Endpoint); - - RPCRT4_strfree(Binding->Endpoint); - Binding->Endpoint = RPCRT4_strdupA(Endpoint); - - RpcAssoc_Release(Binding->Assoc); - Binding->Assoc = NULL; - status = RPCRT4_GetAssociation(Binding->Protseq, Binding->NetworkAddr, - Binding->Endpoint, Binding->NetworkOptions, - &Binding->Assoc); - if (status != RPC_S_OK) - return status; - - return RPC_S_OK; -} - -RPC_STATUS RPCRT4_SetBindingObject(RpcBinding* Binding, const UUID* ObjectUuid) -{ - TRACE("(*RpcBinding == ^%p, UUID == %s)\n", Binding, debugstr_guid(ObjectUuid)); - if (ObjectUuid) memcpy(&Binding->ObjectUuid, ObjectUuid, sizeof(UUID)); - else UuidCreateNil(&Binding->ObjectUuid); - return RPC_S_OK; -} - -RPC_STATUS RPCRT4_MakeBinding(RpcBinding** Binding, RpcConnection* Connection) -{ - RpcBinding* NewBinding; - TRACE("(RpcBinding == ^%p, Connection == ^%p)\n", Binding, Connection); - - RPCRT4_AllocBinding(&NewBinding, Connection->server); - NewBinding->Protseq = RPCRT4_strdupA(rpcrt4_conn_get_name(Connection)); - NewBinding->NetworkAddr = RPCRT4_strdupA(Connection->NetworkAddr); - NewBinding->Endpoint = RPCRT4_strdupA(Connection->Endpoint); - NewBinding->FromConn = Connection; - - TRACE("binding: %p\n", NewBinding); - *Binding = NewBinding; - - return RPC_S_OK; -} - -RPC_STATUS RPCRT4_ExportBinding(RpcBinding** Binding, RpcBinding* OldBinding) -{ - InterlockedIncrement(&OldBinding->refs); - *Binding = OldBinding; - return RPC_S_OK; -} - -RPC_STATUS RPCRT4_DestroyBinding(RpcBinding* Binding) -{ - if (InterlockedDecrement(&Binding->refs)) - return RPC_S_OK; - - TRACE("binding: %p\n", Binding); - if (Binding->Assoc) RpcAssoc_Release(Binding->Assoc); - RPCRT4_strfree(Binding->Endpoint); - RPCRT4_strfree(Binding->NetworkAddr); - RPCRT4_strfree(Binding->Protseq); - HeapFree(GetProcessHeap(), 0, Binding->NetworkOptions); - if (Binding->AuthInfo) RpcAuthInfo_Release(Binding->AuthInfo); - if (Binding->QOS) RpcQualityOfService_Release(Binding->QOS); - HeapFree(GetProcessHeap(), 0, Binding); - return RPC_S_OK; -} - -RPC_STATUS RPCRT4_OpenBinding(RpcBinding* Binding, RpcConnection** Connection, - const RPC_SYNTAX_IDENTIFIER *TransferSyntax, - const RPC_SYNTAX_IDENTIFIER *InterfaceId) -{ - TRACE("(Binding == ^%p)\n", Binding); - - if (!Binding->server) { - return RpcAssoc_GetClientConnection(Binding->Assoc, InterfaceId, - TransferSyntax, Binding->AuthInfo, Binding->QOS, Connection); - } else { - /* we already have a connection with acceptable binding, so use it */ - if (Binding->FromConn) { - *Connection = Binding->FromConn; - return RPC_S_OK; - } else { - ERR("no connection in binding\n"); - return RPC_S_INTERNAL_ERROR; - } - } -} - -RPC_STATUS RPCRT4_CloseBinding(RpcBinding* Binding, RpcConnection* Connection) -{ - TRACE("(Binding == ^%p)\n", Binding); - if (!Connection) return RPC_S_OK; - if (Binding->server) { - /* don't destroy a connection that is cached in the binding */ - if (Binding->FromConn == Connection) - return RPC_S_OK; - return RPCRT4_DestroyConnection(Connection); - } - else { - RpcAssoc_ReleaseIdleConnection(Binding->Assoc, Connection); - return RPC_S_OK; - } -} - -/* utility functions for string composing and parsing */ -static unsigned RPCRT4_strcopyA(LPSTR data, LPCSTR src) -{ - unsigned len = strlen(src); - memcpy(data, src, len*sizeof(CHAR)); - return len; -} - -static unsigned RPCRT4_strcopyW(LPWSTR data, LPCWSTR src) -{ - unsigned len = strlenW(src); - memcpy(data, src, len*sizeof(WCHAR)); - return len; -} - -static LPSTR RPCRT4_strconcatA(LPSTR dst, LPCSTR src) -{ - DWORD len = strlen(dst), slen = strlen(src); - LPSTR ndst = HeapReAlloc(GetProcessHeap(), 0, dst, (len+slen+2)*sizeof(CHAR)); - if (!ndst) - { - HeapFree(GetProcessHeap(), 0, dst); - return NULL; - } - ndst[len] = ','; - memcpy(ndst+len+1, src, slen+1); - return ndst; -} - -static LPWSTR RPCRT4_strconcatW(LPWSTR dst, LPCWSTR src) -{ - DWORD len = strlenW(dst), slen = strlenW(src); - LPWSTR ndst = HeapReAlloc(GetProcessHeap(), 0, dst, (len+slen+2)*sizeof(WCHAR)); - if (!ndst) - { - HeapFree(GetProcessHeap(), 0, dst); - return NULL; - } - ndst[len] = ','; - memcpy(ndst+len+1, src, (slen+1)*sizeof(WCHAR)); - return ndst; -} - - -/*********************************************************************** - * RpcStringBindingComposeA (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcStringBindingComposeA(RPC_CSTR ObjUuid, RPC_CSTR Protseq, - RPC_CSTR NetworkAddr, RPC_CSTR Endpoint, - RPC_CSTR Options, RPC_CSTR *StringBinding ) -{ - DWORD len = 1; - LPSTR data; - - TRACE( "(%s,%s,%s,%s,%s,%p)\n", - debugstr_a( (char*)ObjUuid ), debugstr_a( (char*)Protseq ), - debugstr_a( (char*)NetworkAddr ), debugstr_a( (char*)Endpoint ), - debugstr_a( (char*)Options ), StringBinding ); - - if (ObjUuid && *ObjUuid) len += strlen((char*)ObjUuid) + 1; - if (Protseq && *Protseq) len += strlen((char*)Protseq) + 1; - if (NetworkAddr && *NetworkAddr) len += strlen((char*)NetworkAddr); - if (Endpoint && *Endpoint) len += strlen((char*)Endpoint) + 2; - if (Options && *Options) len += strlen((char*)Options) + 2; - - data = HeapAlloc(GetProcessHeap(), 0, len); - *StringBinding = (unsigned char*)data; - - if (ObjUuid && *ObjUuid) { - data += RPCRT4_strcopyA(data, (char*)ObjUuid); - *data++ = '@'; - } - if (Protseq && *Protseq) { - data += RPCRT4_strcopyA(data, (char*)Protseq); - *data++ = ':'; - } - if (NetworkAddr && *NetworkAddr) - data += RPCRT4_strcopyA(data, (char*)NetworkAddr); - - if ((Endpoint && *Endpoint) || - (Options && *Options)) { - *data++ = '['; - if (Endpoint && *Endpoint) { - data += RPCRT4_strcopyA(data, (char*)Endpoint); - if (Options && *Options) *data++ = ','; - } - if (Options && *Options) { - data += RPCRT4_strcopyA(data, (char*)Options); - } - *data++ = ']'; - } - *data = 0; - - return RPC_S_OK; -} - -/*********************************************************************** - * RpcStringBindingComposeW (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcStringBindingComposeW( RPC_WSTR ObjUuid, RPC_WSTR Protseq, - RPC_WSTR NetworkAddr, RPC_WSTR Endpoint, - RPC_WSTR Options, RPC_WSTR* StringBinding ) -{ - DWORD len = 1; - RPC_WSTR data; - - TRACE("(%s,%s,%s,%s,%s,%p)\n", - debugstr_w( ObjUuid ), debugstr_w( Protseq ), - debugstr_w( NetworkAddr ), debugstr_w( Endpoint ), - debugstr_w( Options ), StringBinding); - - if (ObjUuid && *ObjUuid) len += strlenW(ObjUuid) + 1; - if (Protseq && *Protseq) len += strlenW(Protseq) + 1; - if (NetworkAddr && *NetworkAddr) len += strlenW(NetworkAddr); - if (Endpoint && *Endpoint) len += strlenW(Endpoint) + 2; - if (Options && *Options) len += strlenW(Options) + 2; - - data = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR)); - *StringBinding = data; - - if (ObjUuid && *ObjUuid) { - data += RPCRT4_strcopyW(data, ObjUuid); - *data++ = '@'; - } - if (Protseq && *Protseq) { - data += RPCRT4_strcopyW(data, Protseq); - *data++ = ':'; - } - if (NetworkAddr && *NetworkAddr) { - data += RPCRT4_strcopyW(data, NetworkAddr); - } - if ((Endpoint && *Endpoint) || - (Options && *Options)) { - *data++ = '['; - if (Endpoint && *Endpoint) { - data += RPCRT4_strcopyW(data, Endpoint); - if (Options && *Options) *data++ = ','; - } - if (Options && *Options) { - data += RPCRT4_strcopyW(data, Options); - } - *data++ = ']'; - } - *data = 0; - - return RPC_S_OK; -} - - -/*********************************************************************** - * RpcStringBindingParseA (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcStringBindingParseA( RPC_CSTR StringBinding, RPC_CSTR *ObjUuid, - RPC_CSTR *Protseq, RPC_CSTR *NetworkAddr, - RPC_CSTR *Endpoint, RPC_CSTR *Options) -{ - CHAR *data, *next; - static const char ep_opt[] = "endpoint="; - - TRACE("(%s,%p,%p,%p,%p,%p)\n", debugstr_a((char*)StringBinding), - ObjUuid, Protseq, NetworkAddr, Endpoint, Options); - - if (ObjUuid) *ObjUuid = NULL; - if (Protseq) *Protseq = NULL; - if (NetworkAddr) *NetworkAddr = NULL; - if (Endpoint) *Endpoint = NULL; - if (Options) *Options = NULL; - - data = (char*) StringBinding; - - next = strchr(data, '@'); - if (next) { - if (ObjUuid) *ObjUuid = (unsigned char*)RPCRT4_strndupA(data, next - data); - data = next+1; - } - - next = strchr(data, ':'); - if (next) { - if (Protseq) *Protseq = (unsigned char*)RPCRT4_strndupA(data, next - data); - data = next+1; - } - - next = strchr(data, '['); - if (next) { - CHAR *close, *opt; - - if (NetworkAddr) *NetworkAddr = (unsigned char*)RPCRT4_strndupA(data, next - data); - data = next+1; - close = strchr(data, ']'); - if (!close) goto fail; - - /* tokenize options */ - while (data < close) { - next = strchr(data, ','); - if (!next || next > close) next = close; - /* FIXME: this is kind of inefficient */ - opt = RPCRT4_strndupA(data, next - data); - data = next+1; - - /* parse option */ - next = strchr(opt, '='); - if (!next) { - /* not an option, must be an endpoint */ - if (*Endpoint) goto fail; - *Endpoint = (unsigned char*) opt; - } else { - if (strncmp(opt, ep_opt, strlen(ep_opt)) == 0) { - /* endpoint option */ - if (*Endpoint) goto fail; - *Endpoint = (unsigned char*) RPCRT4_strdupA(next+1); - HeapFree(GetProcessHeap(), 0, opt); - } else { - /* network option */ - if (*Options) { - /* FIXME: this is kind of inefficient */ - *Options = (unsigned char*) RPCRT4_strconcatA( (char*)*Options, opt); - HeapFree(GetProcessHeap(), 0, opt); - } else - *Options = (unsigned char*) opt; - } - } - } - - data = close+1; - if (*data) goto fail; - } - else if (NetworkAddr) - *NetworkAddr = (unsigned char*)RPCRT4_strdupA(data); - - return RPC_S_OK; - -fail: - if (ObjUuid) RpcStringFreeA((unsigned char**)ObjUuid); - if (Protseq) RpcStringFreeA((unsigned char**)Protseq); - if (NetworkAddr) RpcStringFreeA((unsigned char**)NetworkAddr); - if (Endpoint) RpcStringFreeA((unsigned char**)Endpoint); - if (Options) RpcStringFreeA((unsigned char**)Options); - return RPC_S_INVALID_STRING_BINDING; -} - -/*********************************************************************** - * RpcStringBindingParseW (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcStringBindingParseW( RPC_WSTR StringBinding, RPC_WSTR *ObjUuid, - RPC_WSTR *Protseq, RPC_WSTR *NetworkAddr, - RPC_WSTR *Endpoint, RPC_WSTR *Options) -{ - WCHAR *data, *next; - static const WCHAR ep_opt[] = {'e','n','d','p','o','i','n','t','=',0}; - - TRACE("(%s,%p,%p,%p,%p,%p)\n", debugstr_w(StringBinding), - ObjUuid, Protseq, NetworkAddr, Endpoint, Options); - - if (ObjUuid) *ObjUuid = NULL; - if (Protseq) *Protseq = NULL; - if (NetworkAddr) *NetworkAddr = NULL; - if (Endpoint) *Endpoint = NULL; - if (Options) *Options = NULL; - - data = StringBinding; - - next = strchrW(data, '@'); - if (next) { - if (ObjUuid) *ObjUuid = RPCRT4_strndupW(data, next - data); - data = next+1; - } - - next = strchrW(data, ':'); - if (next) { - if (Protseq) *Protseq = RPCRT4_strndupW(data, next - data); - data = next+1; - } - - next = strchrW(data, '['); - if (next) { - WCHAR *close, *opt; - - if (NetworkAddr) *NetworkAddr = RPCRT4_strndupW(data, next - data); - data = next+1; - close = strchrW(data, ']'); - if (!close) goto fail; - - /* tokenize options */ - while (data < close) { - next = strchrW(data, ','); - if (!next || next > close) next = close; - /* FIXME: this is kind of inefficient */ - opt = RPCRT4_strndupW(data, next - data); - data = next+1; - - /* parse option */ - next = strchrW(opt, '='); - if (!next) { - /* not an option, must be an endpoint */ - if (*Endpoint) goto fail; - *Endpoint = opt; - } else { - if (strncmpW(opt, ep_opt, strlenW(ep_opt)) == 0) { - /* endpoint option */ - if (*Endpoint) goto fail; - *Endpoint = RPCRT4_strdupW(next+1); - HeapFree(GetProcessHeap(), 0, opt); - } else { - /* network option */ - if (*Options) { - /* FIXME: this is kind of inefficient */ - *Options = RPCRT4_strconcatW(*Options, opt); - HeapFree(GetProcessHeap(), 0, opt); - } else - *Options = opt; - } - } - } - - data = close+1; - if (*data) goto fail; - } else if (NetworkAddr) - *NetworkAddr = RPCRT4_strdupW(data); - - return RPC_S_OK; - -fail: - if (ObjUuid) RpcStringFreeW(ObjUuid); - if (Protseq) RpcStringFreeW(Protseq); - if (NetworkAddr) RpcStringFreeW(NetworkAddr); - if (Endpoint) RpcStringFreeW(Endpoint); - if (Options) RpcStringFreeW(Options); - return RPC_S_INVALID_STRING_BINDING; -} - -/*********************************************************************** - * RpcBindingFree (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcBindingFree( RPC_BINDING_HANDLE* Binding ) -{ - RPC_STATUS status; - TRACE("(%p) = %p\n", Binding, *Binding); - status = RPCRT4_DestroyBinding(*Binding); - if (status == RPC_S_OK) *Binding = 0; - return status; -} - -/*********************************************************************** - * RpcBindingVectorFree (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcBindingVectorFree( RPC_BINDING_VECTOR** BindingVector ) -{ - RPC_STATUS status; - unsigned long c; - - TRACE("(%p)\n", BindingVector); - for (c=0; c<(*BindingVector)->Count; c++) { - status = RpcBindingFree(&(*BindingVector)->BindingH[c]); - } - HeapFree(GetProcessHeap(), 0, *BindingVector); - *BindingVector = NULL; - return RPC_S_OK; -} - -/*********************************************************************** - * RpcBindingInqObject (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcBindingInqObject( RPC_BINDING_HANDLE Binding, UUID* ObjectUuid ) -{ - RpcBinding* bind = (RpcBinding*)Binding; - - TRACE("(%p,%p) = %s\n", Binding, ObjectUuid, debugstr_guid(&bind->ObjectUuid)); - memcpy(ObjectUuid, &bind->ObjectUuid, sizeof(UUID)); - return RPC_S_OK; -} - -/*********************************************************************** - * RpcBindingSetObject (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcBindingSetObject( RPC_BINDING_HANDLE Binding, UUID* ObjectUuid ) -{ - RpcBinding* bind = (RpcBinding*)Binding; - - TRACE("(%p,%s)\n", Binding, debugstr_guid(ObjectUuid)); - if (bind->server) return RPC_S_WRONG_KIND_OF_BINDING; - return RPCRT4_SetBindingObject(Binding, ObjectUuid); -} - -/*********************************************************************** - * RpcBindingFromStringBindingA (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcBindingFromStringBindingA( RPC_CSTR StringBinding, RPC_BINDING_HANDLE* Binding ) -{ - RPC_STATUS ret; - RpcBinding* bind = NULL; - RPC_CSTR ObjectUuid, Protseq, NetworkAddr, Endpoint, Options; - UUID Uuid; - - TRACE("(%s,%p)\n", debugstr_a((char*)StringBinding), Binding); - - ret = RpcStringBindingParseA(StringBinding, &ObjectUuid, &Protseq, - &NetworkAddr, &Endpoint, &Options); - if (ret != RPC_S_OK) return ret; - - ret = UuidFromStringA(ObjectUuid, &Uuid); - - if (ret == RPC_S_OK) - ret = RPCRT4_CreateBindingA(&bind, FALSE, (char*)Protseq); - if (ret == RPC_S_OK) - ret = RPCRT4_SetBindingObject(bind, &Uuid); - if (ret == RPC_S_OK) - ret = RPCRT4_CompleteBindingA(bind, (char*)NetworkAddr, (char*)Endpoint, (char*)Options); - - RpcStringFreeA((unsigned char**)&Options); - RpcStringFreeA((unsigned char**)&Endpoint); - RpcStringFreeA((unsigned char**)&NetworkAddr); - RpcStringFreeA((unsigned char**)&Protseq); - RpcStringFreeA((unsigned char**)&ObjectUuid); - - if (ret == RPC_S_OK) - *Binding = (RPC_BINDING_HANDLE)bind; - else - RPCRT4_DestroyBinding(bind); - - return ret; -} - -/*********************************************************************** - * RpcBindingFromStringBindingW (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcBindingFromStringBindingW( RPC_WSTR StringBinding, RPC_BINDING_HANDLE* Binding ) -{ - RPC_STATUS ret; - RpcBinding* bind = NULL; - RPC_WSTR ObjectUuid, Protseq, NetworkAddr, Endpoint, Options; - UUID Uuid; - - TRACE("(%s,%p)\n", debugstr_w(StringBinding), Binding); - - ret = RpcStringBindingParseW(StringBinding, &ObjectUuid, &Protseq, - &NetworkAddr, &Endpoint, &Options); - if (ret != RPC_S_OK) return ret; - - ret = UuidFromStringW(ObjectUuid, &Uuid); - - if (ret == RPC_S_OK) - ret = RPCRT4_CreateBindingW(&bind, FALSE, Protseq); - if (ret == RPC_S_OK) - ret = RPCRT4_SetBindingObject(bind, &Uuid); - if (ret == RPC_S_OK) - ret = RPCRT4_CompleteBindingW(bind, NetworkAddr, Endpoint, Options); - - RpcStringFreeW(&Options); - RpcStringFreeW(&Endpoint); - RpcStringFreeW(&NetworkAddr); - RpcStringFreeW(&Protseq); - RpcStringFreeW(&ObjectUuid); - - if (ret == RPC_S_OK) - *Binding = (RPC_BINDING_HANDLE)bind; - else - RPCRT4_DestroyBinding(bind); - - return ret; -} - -/*********************************************************************** - * RpcBindingToStringBindingA (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcBindingToStringBindingA( RPC_BINDING_HANDLE Binding, RPC_CSTR *StringBinding ) -{ - RPC_STATUS ret; - RpcBinding* bind = (RpcBinding*)Binding; - RPC_CSTR ObjectUuid; - - TRACE("(%p,%p)\n", Binding, StringBinding); - - ret = UuidToStringA(&bind->ObjectUuid, &ObjectUuid); - if (ret != RPC_S_OK) return ret; - - ret = RpcStringBindingComposeA(ObjectUuid, (unsigned char*)bind->Protseq, (unsigned char*) bind->NetworkAddr, - (unsigned char*) bind->Endpoint, NULL, StringBinding); - - RpcStringFreeA(&ObjectUuid); - - return ret; -} - -/*********************************************************************** - * RpcBindingToStringBindingW (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcBindingToStringBindingW( RPC_BINDING_HANDLE Binding, RPC_WSTR *StringBinding ) -{ - RPC_STATUS ret; - unsigned char *str = NULL; - TRACE("(%p,%p)\n", Binding, StringBinding); - ret = RpcBindingToStringBindingA(Binding, &str); - *StringBinding = RPCRT4_strdupAtoW((char*)str); - RpcStringFreeA((unsigned char**)&str); - return ret; -} - -/*********************************************************************** - * I_RpcBindingSetAsync (RPCRT4.@) - * NOTES - * Exists in win9x and winNT, but with different number of arguments - * (9x version has 3 arguments, NT has 2). - */ -RPC_STATUS WINAPI I_RpcBindingSetAsync( RPC_BINDING_HANDLE Binding, RPC_BLOCKING_FN BlockingFn) -{ - RpcBinding* bind = (RpcBinding*)Binding; - - TRACE( "(%p,%p): stub\n", Binding, BlockingFn ); - - bind->BlockingFn = BlockingFn; - - return RPC_S_OK; -} - -/*********************************************************************** - * RpcBindingCopy (RPCRT4.@) - */ -RPC_STATUS RPC_ENTRY RpcBindingCopy( - RPC_BINDING_HANDLE SourceBinding, - RPC_BINDING_HANDLE* DestinationBinding) -{ - RpcBinding *DestBinding; - RpcBinding *SrcBinding = (RpcBinding*)SourceBinding; - RPC_STATUS status; - - TRACE("(%p, %p)\n", SourceBinding, DestinationBinding); - - status = RPCRT4_AllocBinding(&DestBinding, SrcBinding->server); - if (status != RPC_S_OK) return status; - - DestBinding->ObjectUuid = SrcBinding->ObjectUuid; - DestBinding->BlockingFn = SrcBinding->BlockingFn; - DestBinding->Protseq = RPCRT4_strndupA(SrcBinding->Protseq, -1); - DestBinding->NetworkAddr = RPCRT4_strndupA(SrcBinding->NetworkAddr, -1); - DestBinding->Endpoint = RPCRT4_strndupA(SrcBinding->Endpoint, -1); - DestBinding->NetworkOptions = RPCRT4_strdupW(SrcBinding->NetworkOptions); - if (SrcBinding->Assoc) SrcBinding->Assoc->refs++; - DestBinding->Assoc = SrcBinding->Assoc; - - if (SrcBinding->AuthInfo) RpcAuthInfo_AddRef(SrcBinding->AuthInfo); - DestBinding->AuthInfo = SrcBinding->AuthInfo; - if (SrcBinding->QOS) RpcQualityOfService_AddRef(SrcBinding->QOS); - DestBinding->QOS = SrcBinding->QOS; - - *DestinationBinding = DestBinding; - return RPC_S_OK; -} - -/*********************************************************************** - * RpcImpersonateClient (RPCRT4.@) - * - * Impersonates the client connected via a binding handle so that security - * checks are done in the context of the client. - * - * PARAMS - * BindingHandle [I] Handle to the binding to the client. - * - * RETURNS - * Success: RPS_S_OK. - * Failure: RPC_STATUS value. - * - * NOTES - * - * If BindingHandle is NULL then the function impersonates the client - * connected to the binding handle of the current thread. - */ -RPC_STATUS WINAPI RpcImpersonateClient(RPC_BINDING_HANDLE BindingHandle) -{ - FIXME("(%p): stub\n", BindingHandle); - ImpersonateSelf(SecurityImpersonation); - return RPC_S_OK; -} - -/*********************************************************************** - * RpcRevertToSelfEx (RPCRT4.@) - * - * Stops impersonating the client connected to the binding handle so that security - * checks are no longer done in the context of the client. - * - * PARAMS - * BindingHandle [I] Handle to the binding to the client. - * - * RETURNS - * Success: RPS_S_OK. - * Failure: RPC_STATUS value. - * - * NOTES - * - * If BindingHandle is NULL then the function stops impersonating the client - * connected to the binding handle of the current thread. - */ -RPC_STATUS WINAPI RpcRevertToSelfEx(RPC_BINDING_HANDLE BindingHandle) -{ - FIXME("(%p): stub\n", BindingHandle); - return RPC_S_OK; -} - -static inline BOOL has_nt_auth_identity(ULONG AuthnLevel) -{ - switch (AuthnLevel) - { - case RPC_C_AUTHN_GSS_NEGOTIATE: - case RPC_C_AUTHN_WINNT: - case RPC_C_AUTHN_GSS_KERBEROS: - return TRUE; - default: - return FALSE; - } -} - -static RPC_STATUS RpcAuthInfo_Create(ULONG AuthnLevel, ULONG AuthnSvc, - CredHandle cred, TimeStamp exp, - ULONG cbMaxToken, - RPC_AUTH_IDENTITY_HANDLE identity, - RpcAuthInfo **ret) -{ - RpcAuthInfo *AuthInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(*AuthInfo)); - if (!AuthInfo) - return ERROR_OUTOFMEMORY; - - AuthInfo->refs = 1; - AuthInfo->AuthnLevel = AuthnLevel; - AuthInfo->AuthnSvc = AuthnSvc; - AuthInfo->cred = cred; - AuthInfo->exp = exp; - AuthInfo->cbMaxToken = cbMaxToken; - AuthInfo->identity = identity; - - /* duplicate the SEC_WINNT_AUTH_IDENTITY structure, if applicable, to - * enable better matching in RpcAuthInfo_IsEqual */ - if (identity && has_nt_auth_identity(AuthnSvc)) - { - const SEC_WINNT_AUTH_IDENTITY_W *nt_identity = identity; - AuthInfo->nt_identity = HeapAlloc(GetProcessHeap(), 0, sizeof(*AuthInfo->nt_identity)); - if (!AuthInfo->nt_identity) - { - HeapFree(GetProcessHeap(), 0, AuthInfo); - return ERROR_OUTOFMEMORY; - } - - AuthInfo->nt_identity->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE; - if (nt_identity->Flags & SEC_WINNT_AUTH_IDENTITY_UNICODE) - AuthInfo->nt_identity->User = RPCRT4_strndupW(nt_identity->User, nt_identity->UserLength); - else - AuthInfo->nt_identity->User = RPCRT4_strndupAtoW((const char *)nt_identity->User, nt_identity->UserLength); - AuthInfo->nt_identity->UserLength = nt_identity->UserLength; - if (nt_identity->Flags & SEC_WINNT_AUTH_IDENTITY_UNICODE) - AuthInfo->nt_identity->Domain = RPCRT4_strndupW(nt_identity->Domain, nt_identity->DomainLength); - else - AuthInfo->nt_identity->Domain = RPCRT4_strndupAtoW((const char *)nt_identity->Domain, nt_identity->DomainLength); - AuthInfo->nt_identity->DomainLength = nt_identity->DomainLength; - if (nt_identity->Flags & SEC_WINNT_AUTH_IDENTITY_UNICODE) - AuthInfo->nt_identity->Password = RPCRT4_strndupW(nt_identity->Password, nt_identity->PasswordLength); - else - AuthInfo->nt_identity->Password = RPCRT4_strndupAtoW((const char *)nt_identity->Password, nt_identity->PasswordLength); - AuthInfo->nt_identity->PasswordLength = nt_identity->PasswordLength; - - if (!AuthInfo->nt_identity->User || - !AuthInfo->nt_identity->Domain || - !AuthInfo->nt_identity->Password) - { - HeapFree(GetProcessHeap(), 0, AuthInfo->nt_identity->User); - HeapFree(GetProcessHeap(), 0, AuthInfo->nt_identity->Domain); - HeapFree(GetProcessHeap(), 0, AuthInfo->nt_identity->Password); - HeapFree(GetProcessHeap(), 0, AuthInfo->nt_identity); - HeapFree(GetProcessHeap(), 0, AuthInfo); - return ERROR_OUTOFMEMORY; - } - } - else - AuthInfo->nt_identity = NULL; - *ret = AuthInfo; - return RPC_S_OK; -} - -ULONG RpcAuthInfo_AddRef(RpcAuthInfo *AuthInfo) -{ - return InterlockedIncrement(&AuthInfo->refs); -} - -ULONG RpcAuthInfo_Release(RpcAuthInfo *AuthInfo) -{ - ULONG refs = InterlockedDecrement(&AuthInfo->refs); - - if (!refs) - { - FreeCredentialsHandle(&AuthInfo->cred); - if (AuthInfo->nt_identity) - { - HeapFree(GetProcessHeap(), 0, AuthInfo->nt_identity->User); - HeapFree(GetProcessHeap(), 0, AuthInfo->nt_identity->Domain); - HeapFree(GetProcessHeap(), 0, AuthInfo->nt_identity->Password); - HeapFree(GetProcessHeap(), 0, AuthInfo->nt_identity); - } - HeapFree(GetProcessHeap(), 0, AuthInfo); - } - - return refs; -} - -BOOL RpcAuthInfo_IsEqual(const RpcAuthInfo *AuthInfo1, const RpcAuthInfo *AuthInfo2) -{ - if (AuthInfo1 == AuthInfo2) - return TRUE; - - if (!AuthInfo1 || !AuthInfo2) - return FALSE; - - if ((AuthInfo1->AuthnLevel != AuthInfo2->AuthnLevel) || - (AuthInfo1->AuthnSvc != AuthInfo2->AuthnSvc)) - return FALSE; - - if (AuthInfo1->identity == AuthInfo2->identity) - return TRUE; - - if (!AuthInfo1->identity || !AuthInfo2->identity) - return FALSE; - - if (has_nt_auth_identity(AuthInfo1->AuthnSvc)) - { - const SEC_WINNT_AUTH_IDENTITY_W *identity1 = AuthInfo1->nt_identity; - const SEC_WINNT_AUTH_IDENTITY_W *identity2 = AuthInfo2->nt_identity; - /* compare user names */ - if (identity1->UserLength != identity2->UserLength || - memcmp(identity1->User, identity2->User, identity1->UserLength)) - return FALSE; - /* compare domain names */ - if (identity1->DomainLength != identity2->DomainLength || - memcmp(identity1->Domain, identity2->Domain, identity1->DomainLength)) - return FALSE; - /* compare passwords */ - if (identity1->PasswordLength != identity2->PasswordLength || - memcmp(identity1->Password, identity2->Password, identity1->PasswordLength)) - return FALSE; - } - else - return FALSE; - - return TRUE; -} - -static RPC_STATUS RpcQualityOfService_Create(const RPC_SECURITY_QOS *qos_src, BOOL unicode, RpcQualityOfService **qos_dst) -{ - RpcQualityOfService *qos = HeapAlloc(GetProcessHeap(), 0, sizeof(*qos)); - - if (!qos) - return RPC_S_OUT_OF_RESOURCES; - - qos->refs = 1; - qos->qos = HeapAlloc(GetProcessHeap(), 0, sizeof(*qos->qos)); - if (!qos->qos) goto error; - qos->qos->Version = qos_src->Version; - qos->qos->Capabilities = qos_src->Capabilities; - qos->qos->IdentityTracking = qos_src->IdentityTracking; - qos->qos->ImpersonationType = qos_src->ImpersonationType; - qos->qos->AdditionalSecurityInfoType = 0; - - if (qos_src->Version >= 2) - { - const RPC_SECURITY_QOS_V2_W *qos_src2 = (const RPC_SECURITY_QOS_V2_W *)qos_src; - qos->qos->AdditionalSecurityInfoType = qos_src2->AdditionalSecurityInfoType; - if (qos_src2->AdditionalSecurityInfoType == RPC_C_AUTHN_INFO_TYPE_HTTP) - { - const RPC_HTTP_TRANSPORT_CREDENTIALS_W *http_credentials_src = qos_src2->u.HttpCredentials; - RPC_HTTP_TRANSPORT_CREDENTIALS_W *http_credentials_dst; - - http_credentials_dst = HeapAlloc(GetProcessHeap(), 0, sizeof(*http_credentials_dst)); - qos->qos->u.HttpCredentials = http_credentials_dst; - if (!http_credentials_dst) goto error; - http_credentials_dst->TransportCredentials = NULL; - http_credentials_dst->Flags = http_credentials_src->Flags; - http_credentials_dst->AuthenticationTarget = http_credentials_src->AuthenticationTarget; - http_credentials_dst->NumberOfAuthnSchemes = http_credentials_src->NumberOfAuthnSchemes; - http_credentials_dst->AuthnSchemes = NULL; - http_credentials_dst->ServerCertificateSubject = NULL; - if (http_credentials_src->TransportCredentials) - { - SEC_WINNT_AUTH_IDENTITY_W *cred_dst; - cred_dst = http_credentials_dst->TransportCredentials = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*cred_dst)); - if (!cred_dst) goto error; - cred_dst->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE; - if (unicode) - { - const SEC_WINNT_AUTH_IDENTITY_W *cred_src = http_credentials_src->TransportCredentials; - cred_dst->UserLength = cred_src->UserLength; - cred_dst->PasswordLength = cred_src->PasswordLength; - cred_dst->DomainLength = cred_src->DomainLength; - cred_dst->User = RPCRT4_strndupW(cred_src->User, cred_src->UserLength); - cred_dst->Password = RPCRT4_strndupW(cred_src->Password, cred_src->PasswordLength); - cred_dst->Domain = RPCRT4_strndupW(cred_src->Domain, cred_src->DomainLength); - } - else - { - const SEC_WINNT_AUTH_IDENTITY_A *cred_src = (const SEC_WINNT_AUTH_IDENTITY_A *)http_credentials_src->TransportCredentials; - cred_dst->UserLength = MultiByteToWideChar(CP_ACP, 0, (char *)cred_src->User, cred_src->UserLength, NULL, 0); - cred_dst->DomainLength = MultiByteToWideChar(CP_ACP, 0, (char *)cred_src->Domain, cred_src->DomainLength, NULL, 0); - cred_dst->PasswordLength = MultiByteToWideChar(CP_ACP, 0, (char *)cred_src->Password, cred_src->PasswordLength, NULL, 0); - cred_dst->User = HeapAlloc(GetProcessHeap(), 0, cred_dst->UserLength * sizeof(WCHAR)); - cred_dst->Password = HeapAlloc(GetProcessHeap(), 0, cred_dst->PasswordLength * sizeof(WCHAR)); - cred_dst->Domain = HeapAlloc(GetProcessHeap(), 0, cred_dst->DomainLength * sizeof(WCHAR)); - if (!cred_dst || !cred_dst->Password || !cred_dst->Domain) goto error; - MultiByteToWideChar(CP_ACP, 0, (char *)cred_src->User, cred_src->UserLength, cred_dst->User, cred_dst->UserLength); - MultiByteToWideChar(CP_ACP, 0, (char *)cred_src->Domain, cred_src->DomainLength, cred_dst->Domain, cred_dst->DomainLength); - MultiByteToWideChar(CP_ACP, 0, (char *)cred_src->Password, cred_src->PasswordLength, cred_dst->Password, cred_dst->PasswordLength); - } - } - if (http_credentials_src->NumberOfAuthnSchemes) - { - http_credentials_dst->AuthnSchemes = HeapAlloc(GetProcessHeap(), 0, http_credentials_src->NumberOfAuthnSchemes * sizeof(*http_credentials_dst->AuthnSchemes)); - if (!http_credentials_dst->AuthnSchemes) goto error; - memcpy(http_credentials_dst->AuthnSchemes, http_credentials_src->AuthnSchemes, http_credentials_src->NumberOfAuthnSchemes * sizeof(*http_credentials_dst->AuthnSchemes)); - } - if (http_credentials_src->ServerCertificateSubject) - { - if (unicode) - http_credentials_dst->ServerCertificateSubject = - RPCRT4_strndupW(http_credentials_src->ServerCertificateSubject, - strlenW(http_credentials_src->ServerCertificateSubject)); - else - http_credentials_dst->ServerCertificateSubject = - RPCRT4_strdupAtoW((char *)http_credentials_src->ServerCertificateSubject); - if (!http_credentials_dst->ServerCertificateSubject) goto error; - } - } - } - *qos_dst = qos; - return RPC_S_OK; - -error: - if (qos->qos) - { - if (qos->qos->AdditionalSecurityInfoType == RPC_C_AUTHN_INFO_TYPE_HTTP && - qos->qos->u.HttpCredentials) - { - if (qos->qos->u.HttpCredentials->TransportCredentials) - { - HeapFree(GetProcessHeap(), 0, qos->qos->u.HttpCredentials->TransportCredentials->User); - HeapFree(GetProcessHeap(), 0, qos->qos->u.HttpCredentials->TransportCredentials->Domain); - HeapFree(GetProcessHeap(), 0, qos->qos->u.HttpCredentials->TransportCredentials->Password); - HeapFree(GetProcessHeap(), 0, qos->qos->u.HttpCredentials->TransportCredentials); - } - HeapFree(GetProcessHeap(), 0, qos->qos->u.HttpCredentials->AuthnSchemes); - HeapFree(GetProcessHeap(), 0, qos->qos->u.HttpCredentials->ServerCertificateSubject); - HeapFree(GetProcessHeap(), 0, qos->qos->u.HttpCredentials); - } - HeapFree(GetProcessHeap(), 0, qos->qos); - } - HeapFree(GetProcessHeap(), 0, qos); - return RPC_S_OUT_OF_RESOURCES; -} - -ULONG RpcQualityOfService_AddRef(RpcQualityOfService *qos) -{ - return InterlockedIncrement(&qos->refs); -} - -ULONG RpcQualityOfService_Release(RpcQualityOfService *qos) -{ - ULONG refs = InterlockedDecrement(&qos->refs); - - if (!refs) - { - if (qos->qos->AdditionalSecurityInfoType == RPC_C_AUTHN_INFO_TYPE_HTTP) - { - if (qos->qos->u.HttpCredentials->TransportCredentials) - { - HeapFree(GetProcessHeap(), 0, qos->qos->u.HttpCredentials->TransportCredentials->User); - HeapFree(GetProcessHeap(), 0, qos->qos->u.HttpCredentials->TransportCredentials->Domain); - HeapFree(GetProcessHeap(), 0, qos->qos->u.HttpCredentials->TransportCredentials->Password); - HeapFree(GetProcessHeap(), 0, qos->qos->u.HttpCredentials->TransportCredentials); - } - HeapFree(GetProcessHeap(), 0, qos->qos->u.HttpCredentials->AuthnSchemes); - HeapFree(GetProcessHeap(), 0, qos->qos->u.HttpCredentials->ServerCertificateSubject); - HeapFree(GetProcessHeap(), 0, qos->qos->u.HttpCredentials); - } - HeapFree(GetProcessHeap(), 0, qos->qos); - HeapFree(GetProcessHeap(), 0, qos); - } - return refs; -} - -BOOL RpcQualityOfService_IsEqual(const RpcQualityOfService *qos1, const RpcQualityOfService *qos2) -{ - if (qos1 == qos2) - return TRUE; - - if (!qos1 || !qos2) - return FALSE; - - TRACE("qos1 = { %ld %ld %ld %ld }, qos2 = { %ld %ld %ld %ld }\n", - qos1->qos->Capabilities, qos1->qos->IdentityTracking, - qos1->qos->ImpersonationType, qos1->qos->AdditionalSecurityInfoType, - qos2->qos->Capabilities, qos2->qos->IdentityTracking, - qos2->qos->ImpersonationType, qos2->qos->AdditionalSecurityInfoType); - - if ((qos1->qos->Capabilities != qos2->qos->Capabilities) || - (qos1->qos->IdentityTracking != qos2->qos->IdentityTracking) || - (qos1->qos->ImpersonationType != qos2->qos->ImpersonationType) || - (qos1->qos->AdditionalSecurityInfoType != qos2->qos->AdditionalSecurityInfoType)) - return FALSE; - - if (qos1->qos->AdditionalSecurityInfoType == RPC_C_AUTHN_INFO_TYPE_HTTP) - { - const RPC_HTTP_TRANSPORT_CREDENTIALS_W *http_credentials1 = qos1->qos->u.HttpCredentials; - const RPC_HTTP_TRANSPORT_CREDENTIALS_W *http_credentials2 = qos2->qos->u.HttpCredentials; - - if (http_credentials1->Flags != http_credentials2->Flags) - return FALSE; - - if (http_credentials1->AuthenticationTarget != http_credentials2->AuthenticationTarget) - return FALSE; - - /* authentication schemes and server certificate subject not currently used */ - - if (http_credentials1->TransportCredentials != http_credentials2->TransportCredentials) - { - const SEC_WINNT_AUTH_IDENTITY_W *identity1 = http_credentials1->TransportCredentials; - const SEC_WINNT_AUTH_IDENTITY_W *identity2 = http_credentials2->TransportCredentials; - - if (!identity1 || !identity2) - return FALSE; - - /* compare user names */ - if (identity1->UserLength != identity2->UserLength || - memcmp(identity1->User, identity2->User, identity1->UserLength)) - return FALSE; - /* compare domain names */ - if (identity1->DomainLength != identity2->DomainLength || - memcmp(identity1->Domain, identity2->Domain, identity1->DomainLength)) - return FALSE; - /* compare passwords */ - if (identity1->PasswordLength != identity2->PasswordLength || - memcmp(identity1->Password, identity2->Password, identity1->PasswordLength)) - return FALSE; - } - } - - return TRUE; -} - -/*********************************************************************** - * RpcRevertToSelf (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcRevertToSelf(void) -{ - FIXME("stub\n"); - RevertToSelf(); - return RPC_S_OK; -} - -/*********************************************************************** - * RpcMgmtSetComTimeout (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcMgmtSetComTimeout(RPC_BINDING_HANDLE BindingHandle, unsigned int Timeout) -{ - FIXME("(%p, %d): stub\n", BindingHandle, Timeout); - return RPC_S_OK; -} - -/*********************************************************************** - * RpcBindingInqAuthInfoExA (RPCRT4.@) - */ -RPCRTAPI RPC_STATUS RPC_ENTRY -RpcBindingInqAuthInfoExA( RPC_BINDING_HANDLE Binding, RPC_CSTR *ServerPrincName, ULONG *AuthnLevel, - ULONG *AuthnSvc, RPC_AUTH_IDENTITY_HANDLE *AuthIdentity, ULONG *AuthzSvc, - ULONG RpcQosVersion, RPC_SECURITY_QOS *SecurityQOS ) -{ - FIXME("%p %p %p %p %p %p %u %p\n", Binding, ServerPrincName, AuthnLevel, - AuthnSvc, AuthIdentity, AuthzSvc, RpcQosVersion, SecurityQOS); - return RPC_S_INVALID_BINDING; -} - -/*********************************************************************** - * RpcBindingInqAuthInfoExW (RPCRT4.@) - */ -RPCRTAPI RPC_STATUS RPC_ENTRY -RpcBindingInqAuthInfoExW( RPC_BINDING_HANDLE Binding, RPC_WSTR *ServerPrincName, ULONG *AuthnLevel, - ULONG *AuthnSvc, RPC_AUTH_IDENTITY_HANDLE *AuthIdentity, ULONG *AuthzSvc, - ULONG RpcQosVersion, RPC_SECURITY_QOS *SecurityQOS ) -{ - FIXME("%p %p %p %p %p %p %u %p\n", Binding, ServerPrincName, AuthnLevel, - AuthnSvc, AuthIdentity, AuthzSvc, RpcQosVersion, SecurityQOS); - return RPC_S_INVALID_BINDING; -} - -/*********************************************************************** - * RpcBindingInqAuthInfoA (RPCRT4.@) - */ -RPCRTAPI RPC_STATUS RPC_ENTRY -RpcBindingInqAuthInfoA( RPC_BINDING_HANDLE Binding, RPC_CSTR *ServerPrincName, ULONG *AuthnLevel, - ULONG *AuthnSvc, RPC_AUTH_IDENTITY_HANDLE *AuthIdentity, ULONG *AuthzSvc ) -{ - FIXME("%p %p %p %p %p %p\n", Binding, ServerPrincName, AuthnLevel, - AuthnSvc, AuthIdentity, AuthzSvc); - return RPC_S_INVALID_BINDING; -} - -/*********************************************************************** - * RpcBindingInqAuthInfoW (RPCRT4.@) - */ -RPCRTAPI RPC_STATUS RPC_ENTRY -RpcBindingInqAuthInfoW( RPC_BINDING_HANDLE Binding, RPC_WSTR *ServerPrincName, ULONG *AuthnLevel, - ULONG *AuthnSvc, RPC_AUTH_IDENTITY_HANDLE *AuthIdentity, ULONG *AuthzSvc ) -{ - FIXME("%p %p %p %p %p %p\n", Binding, ServerPrincName, AuthnLevel, - AuthnSvc, AuthIdentity, AuthzSvc); - return RPC_S_INVALID_BINDING; -} - -/*********************************************************************** - * RpcBindingSetAuthInfoExA (RPCRT4.@) - */ -RPCRTAPI RPC_STATUS RPC_ENTRY -RpcBindingSetAuthInfoExA( RPC_BINDING_HANDLE Binding, RPC_CSTR ServerPrincName, - ULONG AuthnLevel, ULONG AuthnSvc, - RPC_AUTH_IDENTITY_HANDLE AuthIdentity, ULONG AuthzSvr, - RPC_SECURITY_QOS *SecurityQos ) -{ - RpcBinding* bind = (RpcBinding*)Binding; - SECURITY_STATUS r; - CredHandle cred; - TimeStamp exp; - ULONG package_count; - ULONG i; - PSecPkgInfoA packages; - ULONG cbMaxToken; - - TRACE("%p %s %u %u %p %u %p\n", Binding, debugstr_a((const char*)ServerPrincName), - AuthnLevel, AuthnSvc, AuthIdentity, AuthzSvr, SecurityQos); - - if (SecurityQos) - { - RPC_STATUS status; - - TRACE("SecurityQos { Version=%ld, Capabilties=0x%lx, IdentityTracking=%ld, ImpersonationLevel=%ld", - SecurityQos->Version, SecurityQos->Capabilities, SecurityQos->IdentityTracking, SecurityQos->ImpersonationType); - if (SecurityQos->Version >= 2) - { - const RPC_SECURITY_QOS_V2_A *SecurityQos2 = (const RPC_SECURITY_QOS_V2_A *)SecurityQos; - TRACE(", AdditionalSecurityInfoType=%ld", SecurityQos2->AdditionalSecurityInfoType); - if (SecurityQos2->AdditionalSecurityInfoType == RPC_C_AUTHN_INFO_TYPE_HTTP) - TRACE(", { %p, 0x%lx, %ld, %ld, %p, %s }", - SecurityQos2->u.HttpCredentials->TransportCredentials, - SecurityQos2->u.HttpCredentials->Flags, - SecurityQos2->u.HttpCredentials->AuthenticationTarget, - SecurityQos2->u.HttpCredentials->NumberOfAuthnSchemes, - SecurityQos2->u.HttpCredentials->AuthnSchemes, - SecurityQos2->u.HttpCredentials->ServerCertificateSubject); - } - TRACE("}\n"); - status = RpcQualityOfService_Create(SecurityQos, FALSE, &bind->QOS); - if (status != RPC_S_OK) - return status; - } - else - { - if (bind->QOS) RpcQualityOfService_Release(bind->QOS); - bind->QOS = NULL; - } - - if (AuthnSvc == RPC_C_AUTHN_DEFAULT) - AuthnSvc = RPC_C_AUTHN_WINNT; - - /* FIXME: the mapping should probably be retrieved using SSPI somehow */ - if (AuthnLevel == RPC_C_AUTHN_LEVEL_DEFAULT) - AuthnLevel = RPC_C_AUTHN_LEVEL_NONE; - - if ((AuthnLevel == RPC_C_AUTHN_LEVEL_NONE) || (AuthnSvc == RPC_C_AUTHN_NONE)) - { - if (bind->AuthInfo) RpcAuthInfo_Release(bind->AuthInfo); - bind->AuthInfo = NULL; - return RPC_S_OK; - } - - if (AuthnLevel > RPC_C_AUTHN_LEVEL_PKT_PRIVACY) - { - FIXME("unknown AuthnLevel %u\n", AuthnLevel); - return RPC_S_UNKNOWN_AUTHN_LEVEL; - } - - if (AuthzSvr) - { - FIXME("unsupported AuthzSvr %u\n", AuthzSvr); - return RPC_S_UNKNOWN_AUTHZ_SERVICE; - } - - r = EnumerateSecurityPackagesA(&package_count, &packages); - if (r != SEC_E_OK) - { - ERR("EnumerateSecurityPackagesA failed with error 0x%08x\n", r); - return RPC_S_SEC_PKG_ERROR; - } - - for (i = 0; i < package_count; i++) - if (packages[i].wRPCID == AuthnSvc) - break; - - if (i == package_count) - { - FIXME("unsupported AuthnSvc %u\n", AuthnSvc); - FreeContextBuffer(packages); - return RPC_S_UNKNOWN_AUTHN_SERVICE; - } - - TRACE("found package %s for service %u\n", packages[i].Name, AuthnSvc); - r = AcquireCredentialsHandleA((SEC_CHAR *)ServerPrincName, packages[i].Name, SECPKG_CRED_OUTBOUND, NULL, - AuthIdentity, NULL, NULL, &cred, &exp); - cbMaxToken = packages[i].cbMaxToken; - FreeContextBuffer(packages); - if (r == ERROR_SUCCESS) - { - if (bind->AuthInfo) RpcAuthInfo_Release(bind->AuthInfo); - bind->AuthInfo = NULL; - r = RpcAuthInfo_Create(AuthnLevel, AuthnSvc, cred, exp, cbMaxToken, - AuthIdentity, &bind->AuthInfo); - if (r != RPC_S_OK) - FreeCredentialsHandle(&cred); - return RPC_S_OK; - } - else - { - ERR("AcquireCredentialsHandleA failed with error 0x%08x\n", r); - return RPC_S_SEC_PKG_ERROR; - } -} - -/*********************************************************************** - * RpcBindingSetAuthInfoExW (RPCRT4.@) - */ -RPCRTAPI RPC_STATUS RPC_ENTRY -RpcBindingSetAuthInfoExW( RPC_BINDING_HANDLE Binding, RPC_WSTR ServerPrincName, ULONG AuthnLevel, - ULONG AuthnSvc, RPC_AUTH_IDENTITY_HANDLE AuthIdentity, ULONG AuthzSvr, - RPC_SECURITY_QOS *SecurityQos ) -{ - RpcBinding* bind = (RpcBinding*)Binding; - SECURITY_STATUS r; - CredHandle cred; - TimeStamp exp; - ULONG package_count; - ULONG i; - PSecPkgInfoW packages; - ULONG cbMaxToken; - - TRACE("%p %s %u %u %p %u %p\n", Binding, debugstr_w((const WCHAR*)ServerPrincName), - AuthnLevel, AuthnSvc, AuthIdentity, AuthzSvr, SecurityQos); - - if (SecurityQos) - { - RPC_STATUS status; - - TRACE("SecurityQos { Version=%ld, Capabilties=0x%lx, IdentityTracking=%ld, ImpersonationLevel=%ld", - SecurityQos->Version, SecurityQos->Capabilities, SecurityQos->IdentityTracking, SecurityQos->ImpersonationType); - if (SecurityQos->Version >= 2) - { - const RPC_SECURITY_QOS_V2_W *SecurityQos2 = (const RPC_SECURITY_QOS_V2_W *)SecurityQos; - TRACE(", AdditionalSecurityInfoType=%ld", SecurityQos2->AdditionalSecurityInfoType); - if (SecurityQos2->AdditionalSecurityInfoType == RPC_C_AUTHN_INFO_TYPE_HTTP) - TRACE(", { %p, 0x%lx, %ld, %ld, %p, %s }", - SecurityQos2->u.HttpCredentials->TransportCredentials, - SecurityQos2->u.HttpCredentials->Flags, - SecurityQos2->u.HttpCredentials->AuthenticationTarget, - SecurityQos2->u.HttpCredentials->NumberOfAuthnSchemes, - SecurityQos2->u.HttpCredentials->AuthnSchemes, - debugstr_w(SecurityQos2->u.HttpCredentials->ServerCertificateSubject)); - } - TRACE("}\n"); - status = RpcQualityOfService_Create(SecurityQos, TRUE, &bind->QOS); - if (status != RPC_S_OK) - return status; - } - else - { - if (bind->QOS) RpcQualityOfService_Release(bind->QOS); - bind->QOS = NULL; - } - - if (AuthnSvc == RPC_C_AUTHN_DEFAULT) - AuthnSvc = RPC_C_AUTHN_WINNT; - - /* FIXME: the mapping should probably be retrieved using SSPI somehow */ - if (AuthnLevel == RPC_C_AUTHN_LEVEL_DEFAULT) - AuthnLevel = RPC_C_AUTHN_LEVEL_NONE; - - if ((AuthnLevel == RPC_C_AUTHN_LEVEL_NONE) || (AuthnSvc == RPC_C_AUTHN_NONE)) - { - if (bind->AuthInfo) RpcAuthInfo_Release(bind->AuthInfo); - bind->AuthInfo = NULL; - return RPC_S_OK; - } - - if (AuthnLevel > RPC_C_AUTHN_LEVEL_PKT_PRIVACY) - { - FIXME("unknown AuthnLevel %u\n", AuthnLevel); - return RPC_S_UNKNOWN_AUTHN_LEVEL; - } - - if (AuthzSvr) - { - FIXME("unsupported AuthzSvr %u\n", AuthzSvr); - return RPC_S_UNKNOWN_AUTHZ_SERVICE; - } - - r = EnumerateSecurityPackagesW(&package_count, &packages); - if (r != SEC_E_OK) - { - ERR("EnumerateSecurityPackagesA failed with error 0x%08x\n", r); - return RPC_S_SEC_PKG_ERROR; - } - - for (i = 0; i < package_count; i++) - if (packages[i].wRPCID == AuthnSvc) - break; - - if (i == package_count) - { - FIXME("unsupported AuthnSvc %u\n", AuthnSvc); - FreeContextBuffer(packages); - return RPC_S_UNKNOWN_AUTHN_SERVICE; - } - - TRACE("found package %s for service %u\n", debugstr_w(packages[i].Name), AuthnSvc); - r = AcquireCredentialsHandleW((SEC_WCHAR *)ServerPrincName, packages[i].Name, SECPKG_CRED_OUTBOUND, NULL, - AuthIdentity, NULL, NULL, &cred, &exp); - cbMaxToken = packages[i].cbMaxToken; - FreeContextBuffer(packages); - if (r == ERROR_SUCCESS) - { - if (bind->AuthInfo) RpcAuthInfo_Release(bind->AuthInfo); - bind->AuthInfo = NULL; - r = RpcAuthInfo_Create(AuthnLevel, AuthnSvc, cred, exp, cbMaxToken, - AuthIdentity, &bind->AuthInfo); - if (r != RPC_S_OK) - FreeCredentialsHandle(&cred); - return RPC_S_OK; - } - else - { - ERR("AcquireCredentialsHandleA failed with error 0x%08x\n", r); - return RPC_S_SEC_PKG_ERROR; - } -} - -/*********************************************************************** - * RpcBindingSetAuthInfoA (RPCRT4.@) - */ -RPCRTAPI RPC_STATUS RPC_ENTRY -RpcBindingSetAuthInfoA( RPC_BINDING_HANDLE Binding, RPC_CSTR ServerPrincName, ULONG AuthnLevel, - ULONG AuthnSvc, RPC_AUTH_IDENTITY_HANDLE AuthIdentity, ULONG AuthzSvr ) -{ - TRACE("%p %s %u %u %p %u\n", Binding, debugstr_a((const char*)ServerPrincName), - AuthnLevel, AuthnSvc, AuthIdentity, AuthzSvr); - return RpcBindingSetAuthInfoExA(Binding, ServerPrincName, AuthnLevel, AuthnSvc, AuthIdentity, AuthzSvr, NULL); -} - -/*********************************************************************** - * RpcBindingSetAuthInfoW (RPCRT4.@) - */ -RPCRTAPI RPC_STATUS RPC_ENTRY -RpcBindingSetAuthInfoW( RPC_BINDING_HANDLE Binding, RPC_WSTR ServerPrincName, ULONG AuthnLevel, - ULONG AuthnSvc, RPC_AUTH_IDENTITY_HANDLE AuthIdentity, ULONG AuthzSvr ) -{ - TRACE("%p %s %u %u %p %u\n", Binding, debugstr_w((const WCHAR*)ServerPrincName), - AuthnLevel, AuthnSvc, AuthIdentity, AuthzSvr); - return RpcBindingSetAuthInfoExW(Binding, ServerPrincName, AuthnLevel, AuthnSvc, AuthIdentity, AuthzSvr, NULL); -} - -/*********************************************************************** - * RpcBindingSetOption (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcBindingSetOption(RPC_BINDING_HANDLE BindingHandle, ULONG Option, ULONG OptionValue) -{ - FIXME("(%p, %d, %d): stub\n", BindingHandle, Option, OptionValue); - return RPC_S_OK; -} diff --git a/reactos/dll/win32/rpcrt4_new/rpc_binding.h b/reactos/dll/win32/rpcrt4_new/rpc_binding.h deleted file mode 100644 index ed8d4ea062d..00000000000 --- a/reactos/dll/win32/rpcrt4_new/rpc_binding.h +++ /dev/null @@ -1,197 +0,0 @@ -/* - * RPC binding API - * - * Copyright 2001 Ove Kåven, TransGaming Technologies - * - * 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 - */ - -#ifndef __WINE_RPC_BINDING_H -#define __WINE_RPC_BINDING_H - -#include "wine/rpcss_shared.h" -#include "rpcndr.h" -#include "security.h" -#include "wine/list.h" - - -typedef struct _RpcAuthInfo -{ - LONG refs; - - ULONG AuthnLevel; - ULONG AuthnSvc; - CredHandle cred; - TimeStamp exp; - ULONG cbMaxToken; - /* the auth identity pointer that the application passed us (freed by application) */ - RPC_AUTH_IDENTITY_HANDLE *identity; - /* our copy of NT auth identity structure, if the authentication service - * takes an NT auth identity */ - SEC_WINNT_AUTH_IDENTITY_W *nt_identity; -} RpcAuthInfo; - -typedef struct _RpcQualityOfService -{ - LONG refs; - - RPC_SECURITY_QOS_V2_W *qos; -} RpcQualityOfService; - -struct connection_ops; - -typedef struct _RpcConnection -{ - BOOL server; - LPSTR NetworkAddr; - LPSTR Endpoint; - LPWSTR NetworkOptions; - const struct connection_ops *ops; - USHORT MaxTransmissionSize; - - /* authentication */ - CtxtHandle ctx; - TimeStamp exp; - ULONG attr; - RpcAuthInfo *AuthInfo; - ULONG encryption_auth_len; - ULONG signature_auth_len; - RpcQualityOfService *QOS; - - /* client-only */ - struct list conn_pool_entry; - ULONG assoc_group_id; /* association group returned during binding */ - - /* server-only */ - /* The active interface bound to server. */ - RPC_SYNTAX_IDENTIFIER ActiveInterface; - USHORT NextCallId; - struct _RpcConnection* Next; - struct _RpcBinding *server_binding; -} RpcConnection; - -struct connection_ops { - const char *name; - unsigned char epm_protocols[2]; /* only floors 3 and 4. see http://www.opengroup.org/onlinepubs/9629399/apdxl.htm */ - RpcConnection *(*alloc)(void); - RPC_STATUS (*open_connection_client)(RpcConnection *conn); - RPC_STATUS (*handoff)(RpcConnection *old_conn, RpcConnection *new_conn); - int (*read)(RpcConnection *conn, void *buffer, unsigned int len); - int (*write)(RpcConnection *conn, const void *buffer, unsigned int len); - int (*close)(RpcConnection *conn); - void (*cancel_call)(RpcConnection *conn); - size_t (*get_top_of_tower)(unsigned char *tower_data, const char *networkaddr, const char *endpoint); - RPC_STATUS (*parse_top_of_tower)(const unsigned char *tower_data, size_t tower_size, char **networkaddr, char **endpoint); -}; - -/* don't know what MS's structure looks like */ -typedef struct _RpcBinding -{ - LONG refs; - struct _RpcBinding* Next; - BOOL server; - UUID ObjectUuid; - LPSTR Protseq; - LPSTR NetworkAddr; - LPSTR Endpoint; - LPWSTR NetworkOptions; - RPC_BLOCKING_FN BlockingFn; - ULONG ServerTid; - RpcConnection* FromConn; - struct _RpcAssoc *Assoc; - - /* authentication */ - RpcAuthInfo *AuthInfo; - RpcQualityOfService *QOS; -} RpcBinding; - -LPSTR RPCRT4_strndupA(LPCSTR src, INT len); -LPWSTR RPCRT4_strndupW(LPCWSTR src, INT len); -LPSTR RPCRT4_strdupWtoA(LPCWSTR src); -LPWSTR RPCRT4_strdupAtoW(LPCSTR src); -void RPCRT4_strfree(LPSTR src); - -#define RPCRT4_strdupA(x) RPCRT4_strndupA((x),-1) -#define RPCRT4_strdupW(x) RPCRT4_strndupW((x),-1) - -ULONG RpcAuthInfo_AddRef(RpcAuthInfo *AuthInfo); -ULONG RpcAuthInfo_Release(RpcAuthInfo *AuthInfo); -BOOL RpcAuthInfo_IsEqual(const RpcAuthInfo *AuthInfo1, const RpcAuthInfo *AuthInfo2); -ULONG RpcQualityOfService_AddRef(RpcQualityOfService *qos); -ULONG RpcQualityOfService_Release(RpcQualityOfService *qos); -BOOL RpcQualityOfService_IsEqual(const RpcQualityOfService *qos1, const RpcQualityOfService *qos2); - -RPC_STATUS RPCRT4_CreateConnection(RpcConnection** Connection, BOOL server, LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint, LPCWSTR NetworkOptions, RpcAuthInfo* AuthInfo, RpcQualityOfService *QOS); -RPC_STATUS RPCRT4_DestroyConnection(RpcConnection* Connection); -RPC_STATUS RPCRT4_OpenClientConnection(RpcConnection* Connection); -RPC_STATUS RPCRT4_CloseConnection(RpcConnection* Connection); -RPC_STATUS RPCRT4_SpawnConnection(RpcConnection** Connection, RpcConnection* OldConnection); - -RPC_STATUS RPCRT4_ResolveBinding(RpcBinding* Binding, LPCSTR Endpoint); -RPC_STATUS RPCRT4_SetBindingObject(RpcBinding* Binding, const UUID* ObjectUuid); -RPC_STATUS RPCRT4_MakeBinding(RpcBinding** Binding, RpcConnection* Connection); -RPC_STATUS RPCRT4_ExportBinding(RpcBinding** Binding, RpcBinding* OldBinding); -RPC_STATUS RPCRT4_DestroyBinding(RpcBinding* Binding); -RPC_STATUS RPCRT4_OpenBinding(RpcBinding* Binding, RpcConnection** Connection, - const RPC_SYNTAX_IDENTIFIER *TransferSyntax, const RPC_SYNTAX_IDENTIFIER *InterfaceId); -RPC_STATUS RPCRT4_CloseBinding(RpcBinding* Binding, RpcConnection* Connection); -BOOL RPCRT4_RPCSSOnDemandCall(PRPCSS_NP_MESSAGE msg, char *vardata_payload, PRPCSS_NP_REPLY reply); -HANDLE RPCRT4_GetMasterMutex(void); -HANDLE RPCRT4_RpcssNPConnect(void); - -static inline const char *rpcrt4_conn_get_name(const RpcConnection *Connection) -{ - return Connection->ops->name; -} - -static inline int rpcrt4_conn_read(RpcConnection *Connection, - void *buffer, unsigned int len) -{ - return Connection->ops->read(Connection, buffer, len); -} - -static inline int rpcrt4_conn_write(RpcConnection *Connection, - const void *buffer, unsigned int len) -{ - return Connection->ops->write(Connection, buffer, len); -} - -static inline int rpcrt4_conn_close(RpcConnection *Connection) -{ - return Connection->ops->close(Connection); -} - -static inline void rpcrt4_conn_cancel_call(RpcConnection *Connection) -{ - Connection->ops->cancel_call(Connection); -} - -static inline RPC_STATUS rpcrt4_conn_handoff(RpcConnection *old_conn, RpcConnection *new_conn) -{ - return old_conn->ops->handoff(old_conn, new_conn); -} - -/* floors 3 and up */ -RPC_STATUS RpcTransport_GetTopOfTower(unsigned char *tower_data, size_t *tower_size, const char *protseq, const char *networkaddr, const char *endpoint); -RPC_STATUS RpcTransport_ParseTopOfTower(const unsigned char *tower_data, size_t tower_size, char **protseq, char **networkaddr, char **endpoint); - -void RPCRT4_SetThreadCurrentConnection(RpcConnection *Connection); -void RPCRT4_SetThreadCurrentCallHandle(RpcBinding *Binding); -RpcBinding *RPCRT4_GetThreadCurrentCallHandle(void); -void RPCRT4_PushThreadContextHandle(NDR_SCONTEXT SContext); -void RPCRT4_RemoveThreadContextHandle(NDR_SCONTEXT SContext); -NDR_SCONTEXT RPCRT4_PopThreadContextHandle(void); - -#endif diff --git a/reactos/dll/win32/rpcrt4_new/rpc_defs.h b/reactos/dll/win32/rpcrt4_new/rpc_defs.h deleted file mode 100644 index c0c3609f1cc..00000000000 --- a/reactos/dll/win32/rpcrt4_new/rpc_defs.h +++ /dev/null @@ -1,212 +0,0 @@ -/* - * RPC definitions - * - * Copyright 2001-2002 Ove Kåven, TransGaming Technologies - * Copyright 2004 Filip Navara - * - * 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 - */ - -#ifndef __WINE_RPC_DEFS_H -#define __WINE_RPC_DEFS_H - -/* info from http://www.microsoft.com/msj/0398/dcomtextfigs.htm */ - -typedef struct -{ - unsigned char rpc_ver; /* RPC major version (5) */ - unsigned char rpc_ver_minor; /* RPC minor version (0) */ - unsigned char ptype; /* Packet type (PKT_*) */ - unsigned char flags; - unsigned char drep[4]; /* Data representation */ - unsigned short frag_len; /* Data size in bytes including header and tail. */ - unsigned short auth_len; /* Authentication length */ - unsigned long call_id; /* Call identifier. */ -} RpcPktCommonHdr; - -typedef struct -{ - RpcPktCommonHdr common; - unsigned long alloc_hint; /* Data size in bytes excluding header and tail. */ - unsigned short context_id; /* Presentation context identifier */ - unsigned short opnum; -} RpcPktRequestHdr; - -typedef struct -{ - RpcPktCommonHdr common; - unsigned long alloc_hint; /* Data size in bytes excluding header and tail. */ - unsigned short context_id; /* Presentation context identifier */ - unsigned char cancel_count; - unsigned char reserved; -} RpcPktResponseHdr; - -typedef struct -{ - RpcPktCommonHdr common; - unsigned long alloc_hint; /* Data size in bytes excluding header and tail. */ - unsigned short context_id; /* Presentation context identifier */ - unsigned char cancel_count; /* Received cancel count */ - unsigned char reserved; /* Force alignment! */ - unsigned long status; /* Runtime fault code (RPC_STATUS) */ - unsigned long reserved2; -} RpcPktFaultHdr; - -typedef struct -{ - RpcPktCommonHdr common; - unsigned short max_tsize; /* Maximum transmission fragment size */ - unsigned short max_rsize; /* Maximum receive fragment size */ - unsigned long assoc_gid; /* Associated group id */ - unsigned char num_elements; /* Number of elements */ - unsigned char padding[3]; /* Force alignment! */ - unsigned short context_id; /* Presentation context identifier */ - unsigned char num_syntaxes; /* Number of syntaxes */ - RPC_SYNTAX_IDENTIFIER abstract; - RPC_SYNTAX_IDENTIFIER transfer; -} RpcPktBindHdr; - -#include "pshpack1.h" -typedef struct -{ - unsigned short length; /* Length of the string including null terminator */ - char string[1]; /* String data in single byte, null terminated form */ -} RpcAddressString; -#include "poppack.h" - -typedef struct -{ - unsigned char num_results; /* Number of results */ - unsigned char reserved[3]; /* Force alignment! */ - struct { - unsigned short result; - unsigned short reason; - } results[1]; -} RpcResults; - -typedef struct -{ - RpcPktCommonHdr common; - unsigned short max_tsize; /* Maximum transmission fragment size */ - unsigned short max_rsize; /* Maximum receive fragment size */ - unsigned long assoc_gid; /* Associated group id */ - /* - * Following this header are these fields: - * RpcAddressString server_address; - * [0 - 3 bytes of padding so that results is 4-byte aligned] - * RpcResults results; - * RPC_SYNTAX_IDENTIFIER transfer; - */ -} RpcPktBindAckHdr; - -typedef struct -{ - RpcPktCommonHdr common; - unsigned short reject_reason; - unsigned char protocols_count; - struct { - unsigned char rpc_ver; - unsigned char rpc_ver_minor; - } protocols[1]; -} RpcPktBindNAckHdr; - -/* Union representing all possible packet headers */ -typedef union -{ - RpcPktCommonHdr common; - RpcPktRequestHdr request; - RpcPktResponseHdr response; - RpcPktFaultHdr fault; - RpcPktBindHdr bind; - RpcPktBindAckHdr bind_ack; - RpcPktBindNAckHdr bind_nack; -} RpcPktHdr; - -typedef struct -{ - unsigned char auth_type; /* authentication scheme in use */ - unsigned char auth_level; /* RPC_C_AUTHN_LEVEL* */ - unsigned char auth_pad_length; /* length of padding to restore n % 4 alignment */ - unsigned char auth_reserved; /* reserved, must be zero */ - unsigned long auth_context_id; /* unique value for the authenticated connection */ -} RpcAuthVerifier; - -#define RPC_AUTH_VERIFIER_LEN(common_hdr) \ - ((common_hdr)->auth_len ? (common_hdr)->auth_len + sizeof(RpcAuthVerifier) : 0) - -#define RPC_VER_MAJOR 5 -#define RPC_VER_MINOR 0 - -#define RPC_FLG_FIRST 1 -#define RPC_FLG_LAST 2 -#define RPC_FLG_OBJECT_UUID 0x80 - -#define RPC_MIN_PACKET_SIZE 0x1000 -#define RPC_MAX_PACKET_SIZE 0x16D0 - -#define PKT_REQUEST 0 -#define PKT_PING 1 -#define PKT_RESPONSE 2 -#define PKT_FAULT 3 -#define PKT_WORKING 4 -#define PKT_NOCALL 5 -#define PKT_REJECT 6 -#define PKT_ACK 7 -#define PKT_CL_CANCEL 8 -#define PKT_FACK 9 -#define PKT_CANCEL_ACK 10 -#define PKT_BIND 11 -#define PKT_BIND_ACK 12 -#define PKT_BIND_NACK 13 -#define PKT_ALTER_CONTEXT 14 -#define PKT_ALTER_CONTEXT_RESP 15 -#define PKT_AUTH3 16 -#define PKT_SHUTDOWN 17 -#define PKT_CO_CANCEL 18 -#define PKT_ORPHANED 19 - -#define RESULT_ACCEPT 0 -#define RESULT_USER_REJECTION 1 -#define RESULT_PROVIDER_REJECTION 2 - -#define REASON_NONE 0 -#define REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED 1 -#define REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED 2 -#define REASON_LOCAL_LIMIT_EXCEEDED 3 - -#define REJECT_REASON_NOT_SPECIFIED 0 -#define REJECT_TEMPORARY_CONGESTION 1 -#define REJECT_LOCAL_LIMIT_EXCEEDED 2 -#define REJECT_CALLED_PADDR_UNKNOWN 3 /* not used */ -#define REJECT_PROTOCOL_VERSION_NOT_SUPPORTED 4 -#define REJECT_DEFAULT_CONTEXT_NOT_SUPPORTED 5 /* not used */ -#define REJECT_USER_DATA_NOT_READABLE 6 /* not used */ -#define REJECT_NO_PSAP_AVAILABLE 7 /* not used */ -#define REJECT_UNKNOWN_AUTHN_SERVICE 8 -#define REJECT_INVALID_CHECKSUM 9 - -#define NCADG_IP_UDP 0x08 -#define NCACN_IP_TCP 0x07 -#define NCADG_IPX 0x0E -#define NCACN_SPX 0x0C -#define NCACN_NB_NB 0x12 -#define NCACN_NB_IPX 0x0D -#define NCACN_DNET_NSP 0x04 -#define NCACN_HTTP 0x1F - -/* FreeDCE: TWR_C_FLR_PROT_ID_IP */ -#define TWR_IP 0x09 - -#endif /* __WINE_RPC_DEFS_H */ diff --git a/reactos/dll/win32/rpcrt4_new/rpc_epmap.c b/reactos/dll/win32/rpcrt4_new/rpc_epmap.c deleted file mode 100644 index cac3f626c1a..00000000000 --- a/reactos/dll/win32/rpcrt4_new/rpc_epmap.c +++ /dev/null @@ -1,384 +0,0 @@ -/* - * RPC endpoint mapper - * - * Copyright 2002 Greg Turner - * Copyright 2001 Ove Kåven, TransGaming Technologies - * - * 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 - * - * TODO: - * - actually do things right - */ - -#include -#include -#include - -#include "windef.h" -#include "winbase.h" -#include "winerror.h" - -#include "rpc.h" - -#include "wine/debug.h" - -#include "rpc_binding.h" -#include "epm_towers.h" - -WINE_DEFAULT_DEBUG_CHANNEL(ole); - -/* The "real" RPC portmapper endpoints that I know of are: - * - * ncadg_ip_udp: 135 - * ncacn_ip_tcp: 135 - * ncacn_np: \\pipe\epmapper (?) - * ncalrpc: epmapper - * - * If the user's machine ran a DCE RPC daemon, it would - * probably be possible to connect to it, but there are many - * reasons not to, like: - * - the user probably does *not* run one, and probably - * shouldn't be forced to run one just for local COM - * - very few Unix systems use DCE RPC... if they run a RPC - * daemon at all, it's usually Sun RPC - * - DCE RPC registrations are persistent and saved on disk, - * while MS-RPC registrations are documented as non-persistent - * and stored only in RAM, and auto-destroyed when the process - * dies (something DCE RPC can't do) - * - * Of course, if the user *did* want to run a DCE RPC daemon anyway, - * there would be interoperability advantages, like the possibility - * of running a fully functional DCOM server using Wine... - */ - -/*********************************************************************** - * RpcEpRegisterA (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcEpRegisterA( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *BindingVector, - UUID_VECTOR *UuidVector, RPC_CSTR Annotation ) -{ - RPCSS_NP_MESSAGE msg; - RPCSS_NP_REPLY reply; - char *vardata_payload, *vp; - PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec; - unsigned long c; - RPC_STATUS rslt = RPC_S_OK; - - TRACE("(%p,%p,%p,%s)\n", IfSpec, BindingVector, UuidVector, debugstr_a((char*)Annotation)); - TRACE(" ifid=%s\n", debugstr_guid(&If->InterfaceId.SyntaxGUID)); - for (c=0; cCount; c++) { - RpcBinding* bind = (RpcBinding*)(BindingVector->BindingH[c]); - TRACE(" protseq[%ld]=%s\n", c, debugstr_a(bind->Protseq)); - TRACE(" endpoint[%ld]=%s\n", c, debugstr_a(bind->Endpoint)); - } - if (UuidVector) { - for (c=0; cCount; c++) - TRACE(" obj[%ld]=%s\n", c, debugstr_guid(UuidVector->Uuid[c])); - } - - /* FIXME: Do something with annotation. */ - - /* construct the message to rpcss */ - msg.message_type = RPCSS_NP_MESSAGE_TYPEID_REGISTEREPMSG; - msg.message.registerepmsg.iface = If->InterfaceId; - msg.message.registerepmsg.no_replace = 0; - - msg.message.registerepmsg.object_count = (UuidVector) ? UuidVector->Count : 0; - msg.message.registerepmsg.binding_count = BindingVector->Count; - - /* calculate vardata payload size */ - msg.vardata_payload_size = msg.message.registerepmsg.object_count * sizeof(UUID); - for (c=0; c < msg.message.registerepmsg.binding_count; c++) { - RpcBinding *bind = (RpcBinding *)(BindingVector->BindingH[c]); - msg.vardata_payload_size += strlen(bind->Protseq) + 1; - msg.vardata_payload_size += strlen(bind->Endpoint) + 1; - } - - /* allocate the payload buffer */ - vp = vardata_payload = LocalAlloc(LPTR, msg.vardata_payload_size); - if (!vardata_payload) - return RPC_S_OUT_OF_MEMORY; - - /* populate the payload data */ - for (c=0; c < msg.message.registerepmsg.object_count; c++) { - CopyMemory(vp, UuidVector->Uuid[c], sizeof(UUID)); - vp += sizeof(UUID); - } - - for (c=0; c < msg.message.registerepmsg.binding_count; c++) { - RpcBinding *bind = (RpcBinding*)(BindingVector->BindingH[c]); - unsigned long pslen = strlen(bind->Protseq) + 1, eplen = strlen(bind->Endpoint) + 1; - CopyMemory(vp, bind->Protseq, pslen); - vp += pslen; - CopyMemory(vp, bind->Endpoint, eplen); - vp += eplen; - } - - /* send our request */ - if (!RPCRT4_RPCSSOnDemandCall(&msg, vardata_payload, &reply)) - rslt = RPC_S_OUT_OF_MEMORY; - - /* free the payload buffer */ - LocalFree(vardata_payload); - - return rslt; -} - -/*********************************************************************** - * RpcEpUnregister (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcEpUnregister( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *BindingVector, - UUID_VECTOR *UuidVector ) -{ - RPCSS_NP_MESSAGE msg; - RPCSS_NP_REPLY reply; - char *vardata_payload, *vp; - PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec; - unsigned long c; - RPC_STATUS rslt = RPC_S_OK; - - TRACE("(%p,%p,%p)\n", IfSpec, BindingVector, UuidVector); - TRACE(" ifid=%s\n", debugstr_guid(&If->InterfaceId.SyntaxGUID)); - for (c=0; cCount; c++) { - RpcBinding* bind = (RpcBinding*)(BindingVector->BindingH[c]); - TRACE(" protseq[%ld]=%s\n", c, debugstr_a(bind->Protseq)); - TRACE(" endpoint[%ld]=%s\n", c, debugstr_a(bind->Endpoint)); - } - if (UuidVector) { - for (c=0; cCount; c++) - TRACE(" obj[%ld]=%s\n", c, debugstr_guid(UuidVector->Uuid[c])); - } - - /* construct the message to rpcss */ - msg.message_type = RPCSS_NP_MESSAGE_TYPEID_UNREGISTEREPMSG; - msg.message.unregisterepmsg.iface = If->InterfaceId; - - msg.message.unregisterepmsg.object_count = (UuidVector) ? UuidVector->Count : 0; - msg.message.unregisterepmsg.binding_count = BindingVector->Count; - - /* calculate vardata payload size */ - msg.vardata_payload_size = msg.message.unregisterepmsg.object_count * sizeof(UUID); - for (c=0; c < msg.message.unregisterepmsg.binding_count; c++) { - RpcBinding *bind = (RpcBinding *)(BindingVector->BindingH[c]); - msg.vardata_payload_size += strlen(bind->Protseq) + 1; - msg.vardata_payload_size += strlen(bind->Endpoint) + 1; - } - - /* allocate the payload buffer */ - vp = vardata_payload = LocalAlloc(LPTR, msg.vardata_payload_size); - if (!vardata_payload) - return RPC_S_OUT_OF_MEMORY; - - /* populate the payload data */ - for (c=0; c < msg.message.unregisterepmsg.object_count; c++) { - CopyMemory(vp, UuidVector->Uuid[c], sizeof(UUID)); - vp += sizeof(UUID); - } - - for (c=0; c < msg.message.unregisterepmsg.binding_count; c++) { - RpcBinding *bind = (RpcBinding*)(BindingVector->BindingH[c]); - unsigned long pslen = strlen(bind->Protseq) + 1, eplen = strlen(bind->Endpoint) + 1; - CopyMemory(vp, bind->Protseq, pslen); - vp += pslen; - CopyMemory(vp, bind->Endpoint, eplen); - vp += eplen; - } - - /* send our request */ - if (!RPCRT4_RPCSSOnDemandCall(&msg, vardata_payload, &reply)) - rslt = RPC_S_OUT_OF_MEMORY; - - /* free the payload buffer */ - LocalFree(vardata_payload); - - return rslt; -} - -/*********************************************************************** - * RpcEpResolveBinding (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcEpResolveBinding( RPC_BINDING_HANDLE Binding, RPC_IF_HANDLE IfSpec ) -{ - RPCSS_NP_MESSAGE msg; - RPCSS_NP_REPLY reply; - PRPC_CLIENT_INTERFACE If = (PRPC_CLIENT_INTERFACE)IfSpec; - RpcBinding* bind = (RpcBinding*)Binding; - - TRACE("(%p,%p)\n", Binding, IfSpec); - TRACE(" protseq=%s\n", debugstr_a(bind->Protseq)); - TRACE(" obj=%s\n", debugstr_guid(&bind->ObjectUuid)); - TRACE(" ifid=%s\n", debugstr_guid(&If->InterfaceId.SyntaxGUID)); - - /* FIXME: totally untested */ - - /* just return for fully bound handles */ - if (bind->Endpoint && (bind->Endpoint[0] != '\0')) - return RPC_S_OK; - - /* construct the message to rpcss */ - msg.message_type = RPCSS_NP_MESSAGE_TYPEID_RESOLVEEPMSG; - msg.message.resolveepmsg.iface = If->InterfaceId; - msg.message.resolveepmsg.object = bind->ObjectUuid; - - msg.vardata_payload_size = strlen(bind->Protseq) + 1; - - /* send the message */ - if (!RPCRT4_RPCSSOnDemandCall(&msg, bind->Protseq, &reply)) - return RPC_S_OUT_OF_MEMORY; - - /* empty-string result means not registered */ - if (reply.as_string[0] == '\0') - return EPT_S_NOT_REGISTERED; - - /* otherwise we fully bind the handle & return RPC_S_OK */ - return RPCRT4_ResolveBinding(Binding, reply.as_string); -} - -typedef unsigned int unsigned32; -typedef struct twr_t - { - unsigned32 tower_length; - /* [size_is] */ BYTE tower_octet_string[ 1 ]; - } twr_t; - -/*********************************************************************** - * TowerExplode (RPCRT4.@) - */ -RPC_STATUS WINAPI TowerExplode( - const twr_t *tower, PRPC_SYNTAX_IDENTIFIER object, PRPC_SYNTAX_IDENTIFIER syntax, - char **protseq, char **endpoint, char **address) -{ - size_t tower_size; - RPC_STATUS status; - const unsigned char *p; - u_int16 floor_count; - const twr_uuid_floor_t *object_floor; - const twr_uuid_floor_t *syntax_floor; - - if (protseq) - *protseq = NULL; - if (endpoint) - *endpoint = NULL; - if (address) - *address = NULL; - - tower_size = tower->tower_length; - - if (tower_size < sizeof(u_int16)) - return EPT_S_NOT_REGISTERED; - - p = &tower->tower_octet_string[0]; - - floor_count = *(const u_int16 *)p; - p += sizeof(u_int16); - tower_size -= sizeof(u_int16); - TRACE("floor_count: %d\n", floor_count); - /* FIXME: should we do something with the floor count? at the moment we don't */ - - if (tower_size < sizeof(*object_floor) + sizeof(*syntax_floor)) - return EPT_S_NOT_REGISTERED; - - object_floor = (const twr_uuid_floor_t *)p; - p += sizeof(*object_floor); - tower_size -= sizeof(*object_floor); - syntax_floor = (const twr_uuid_floor_t *)p; - p += sizeof(*syntax_floor); - tower_size -= sizeof(*syntax_floor); - - if ((object_floor->count_lhs != sizeof(object_floor->protid) + - sizeof(object_floor->uuid) + sizeof(object_floor->major_version)) || - (object_floor->protid != EPM_PROTOCOL_UUID) || - (object_floor->count_rhs != sizeof(object_floor->minor_version))) - return EPT_S_NOT_REGISTERED; - - if ((syntax_floor->count_lhs != sizeof(syntax_floor->protid) + - sizeof(syntax_floor->uuid) + sizeof(syntax_floor->major_version)) || - (syntax_floor->protid != EPM_PROTOCOL_UUID) || - (syntax_floor->count_rhs != sizeof(syntax_floor->minor_version))) - return EPT_S_NOT_REGISTERED; - - status = RpcTransport_ParseTopOfTower(p, tower_size, protseq, address, endpoint); - if ((status == RPC_S_OK) && syntax && object) - { - syntax->SyntaxGUID = syntax_floor->uuid; - syntax->SyntaxVersion.MajorVersion = syntax_floor->major_version; - syntax->SyntaxVersion.MinorVersion = syntax_floor->minor_version; - object->SyntaxGUID = object_floor->uuid; - object->SyntaxVersion.MajorVersion = object_floor->major_version; - object->SyntaxVersion.MinorVersion = object_floor->minor_version; - } - return status; -} - -/*********************************************************************** - * TowerConstruct (RPCRT4.@) - */ -RPC_STATUS WINAPI TowerConstruct( - const RPC_SYNTAX_IDENTIFIER *object, const RPC_SYNTAX_IDENTIFIER *syntax, - const char *protseq, const char *endpoint, const char *address, - twr_t **tower) -{ - size_t tower_size; - RPC_STATUS status; - unsigned char *p; - twr_uuid_floor_t *object_floor; - twr_uuid_floor_t *syntax_floor; - - *tower = NULL; - - status = RpcTransport_GetTopOfTower(NULL, &tower_size, protseq, address, endpoint); - - if (status != RPC_S_OK) - return status; - - tower_size += sizeof(u_int16) + sizeof(*object_floor) + sizeof(*syntax_floor); - *tower = I_RpcAllocate(FIELD_OFFSET(twr_t, tower_octet_string[tower_size])); - if (!*tower) - return RPC_S_OUT_OF_RESOURCES; - - (*tower)->tower_length = tower_size; - p = &(*tower)->tower_octet_string[0]; - *(u_int16 *)p = 5; /* number of floors */ - p += sizeof(u_int16); - object_floor = (twr_uuid_floor_t *)p; - p += sizeof(*object_floor); - syntax_floor = (twr_uuid_floor_t *)p; - p += sizeof(*syntax_floor); - - object_floor->count_lhs = sizeof(object_floor->protid) + sizeof(object_floor->uuid) + - sizeof(object_floor->major_version); - object_floor->protid = EPM_PROTOCOL_UUID; - object_floor->count_rhs = sizeof(object_floor->minor_version); - object_floor->uuid = object->SyntaxGUID; - object_floor->major_version = object->SyntaxVersion.MajorVersion; - object_floor->minor_version = object->SyntaxVersion.MinorVersion; - - syntax_floor->count_lhs = sizeof(syntax_floor->protid) + sizeof(syntax_floor->uuid) + - sizeof(syntax_floor->major_version); - syntax_floor->protid = EPM_PROTOCOL_UUID; - syntax_floor->count_rhs = sizeof(syntax_floor->minor_version); - syntax_floor->uuid = syntax->SyntaxGUID; - syntax_floor->major_version = syntax->SyntaxVersion.MajorVersion; - syntax_floor->minor_version = syntax->SyntaxVersion.MinorVersion; - - status = RpcTransport_GetTopOfTower(p, &tower_size, protseq, address, endpoint); - if (status != RPC_S_OK) - { - I_RpcFree(*tower); - *tower = NULL; - return status; - } - return RPC_S_OK; -} diff --git a/reactos/dll/win32/rpcrt4_new/rpc_message.c b/reactos/dll/win32/rpcrt4_new/rpc_message.c deleted file mode 100644 index 1248e4605fa..00000000000 --- a/reactos/dll/win32/rpcrt4_new/rpc_message.c +++ /dev/null @@ -1,1159 +0,0 @@ -/* - * RPC messages - * - * Copyright 2001-2002 Ove Kåven, TransGaming Technologies - * Copyright 2004 Filip Navara - * Copyright 2006 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 -#include -#include - -#include "windef.h" -#include "winbase.h" -#include "winerror.h" - -#include "rpc.h" -#include "rpcndr.h" -#include "rpcdcep.h" - -#include "wine/debug.h" - -#include "rpc_binding.h" -#include "rpc_defs.h" -#include "rpc_message.h" -#include "ncastatus.h" - -WINE_DEFAULT_DEBUG_CHANNEL(rpc); - -/* note: the DCE/RPC spec says the alignment amount should be 4, but - * MS/RPC servers seem to always use 16 */ -#define AUTH_ALIGNMENT 16 - -/* gets the amount needed to round a value up to the specified alignment */ -#define ROUND_UP_AMOUNT(value, alignment) \ - (((alignment) - (((value) % (alignment)))) % (alignment)) -#define ROUND_UP(value, alignment) (((value) + ((alignment) - 1)) & ~((alignment)-1)) - -enum secure_packet_direction -{ - SECURE_PACKET_SEND, - SECURE_PACKET_RECEIVE -}; - -static RPC_STATUS I_RpcReAllocateBuffer(PRPC_MESSAGE pMsg); - -static DWORD RPCRT4_GetHeaderSize(const RpcPktHdr *Header) -{ - static const DWORD header_sizes[] = { - sizeof(Header->request), 0, sizeof(Header->response), - sizeof(Header->fault), 0, 0, 0, 0, 0, 0, 0, sizeof(Header->bind), - sizeof(Header->bind_ack), sizeof(Header->bind_nack), - 0, 0, 0, 0, 0 - }; - ULONG ret = 0; - - if (Header->common.ptype < sizeof(header_sizes) / sizeof(header_sizes[0])) { - ret = header_sizes[Header->common.ptype]; - if (ret == 0) - FIXME("unhandled packet type\n"); - if (Header->common.flags & RPC_FLG_OBJECT_UUID) - ret += sizeof(UUID); - } else { - TRACE("invalid packet type\n"); - } - - return ret; -} - -static int packet_has_body(const RpcPktHdr *Header) -{ - return (Header->common.ptype == PKT_FAULT) || - (Header->common.ptype == PKT_REQUEST) || - (Header->common.ptype == PKT_RESPONSE); -} - -static int packet_has_auth_verifier(const RpcPktHdr *Header) -{ - return !(Header->common.ptype == PKT_BIND_NACK) && - !(Header->common.ptype == PKT_SHUTDOWN); -} - -static VOID RPCRT4_BuildCommonHeader(RpcPktHdr *Header, unsigned char PacketType, - unsigned long DataRepresentation) -{ - Header->common.rpc_ver = RPC_VER_MAJOR; - Header->common.rpc_ver_minor = RPC_VER_MINOR; - Header->common.ptype = PacketType; - Header->common.drep[0] = LOBYTE(LOWORD(DataRepresentation)); - Header->common.drep[1] = HIBYTE(LOWORD(DataRepresentation)); - Header->common.drep[2] = LOBYTE(HIWORD(DataRepresentation)); - Header->common.drep[3] = HIBYTE(HIWORD(DataRepresentation)); - Header->common.auth_len = 0; - Header->common.call_id = 1; - Header->common.flags = 0; - /* Flags and fragment length are computed in RPCRT4_Send. */ -} - -static RpcPktHdr *RPCRT4_BuildRequestHeader(unsigned long DataRepresentation, - unsigned long BufferLength, - unsigned short ProcNum, - UUID *ObjectUuid) -{ - RpcPktHdr *header; - BOOL has_object; - RPC_STATUS status; - - has_object = (ObjectUuid != NULL && !UuidIsNil(ObjectUuid, &status)); - header = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(header->request) + (has_object ? sizeof(UUID) : 0)); - if (header == NULL) { - return NULL; - } - - RPCRT4_BuildCommonHeader(header, PKT_REQUEST, DataRepresentation); - header->common.frag_len = sizeof(header->request); - header->request.alloc_hint = BufferLength; - header->request.context_id = 0; - header->request.opnum = ProcNum; - if (has_object) { - header->common.flags |= RPC_FLG_OBJECT_UUID; - header->common.frag_len += sizeof(UUID); - memcpy(&header->request + 1, ObjectUuid, sizeof(UUID)); - } - - return header; -} - -RpcPktHdr *RPCRT4_BuildResponseHeader(unsigned long DataRepresentation, - unsigned long BufferLength) -{ - RpcPktHdr *header; - - header = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(header->response)); - if (header == NULL) { - return NULL; - } - - RPCRT4_BuildCommonHeader(header, PKT_RESPONSE, DataRepresentation); - header->common.frag_len = sizeof(header->response); - header->response.alloc_hint = BufferLength; - - return header; -} - -RpcPktHdr *RPCRT4_BuildFaultHeader(unsigned long DataRepresentation, - RPC_STATUS Status) -{ - RpcPktHdr *header; - - header = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(header->fault)); - if (header == NULL) { - return NULL; - } - - RPCRT4_BuildCommonHeader(header, PKT_FAULT, DataRepresentation); - header->common.frag_len = sizeof(header->fault); - header->fault.status = Status; - - return header; -} - -RpcPktHdr *RPCRT4_BuildBindHeader(unsigned long DataRepresentation, - unsigned short MaxTransmissionSize, - unsigned short MaxReceiveSize, - unsigned long AssocGroupId, - const RPC_SYNTAX_IDENTIFIER *AbstractId, - const RPC_SYNTAX_IDENTIFIER *TransferId) -{ - RpcPktHdr *header; - - header = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(header->bind)); - if (header == NULL) { - return NULL; - } - - RPCRT4_BuildCommonHeader(header, PKT_BIND, DataRepresentation); - header->common.frag_len = sizeof(header->bind); - header->bind.max_tsize = MaxTransmissionSize; - header->bind.max_rsize = MaxReceiveSize; - header->bind.assoc_gid = AssocGroupId; - header->bind.num_elements = 1; - header->bind.num_syntaxes = 1; - memcpy(&header->bind.abstract, AbstractId, sizeof(RPC_SYNTAX_IDENTIFIER)); - memcpy(&header->bind.transfer, TransferId, sizeof(RPC_SYNTAX_IDENTIFIER)); - - return header; -} - -static RpcPktHdr *RPCRT4_BuildAuthHeader(unsigned long DataRepresentation) -{ - RpcPktHdr *header; - - header = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(header->common) + 12); - if (header == NULL) - return NULL; - - RPCRT4_BuildCommonHeader(header, PKT_AUTH3, DataRepresentation); - header->common.frag_len = 0x14; - header->common.auth_len = 0; - - return header; -} - -RpcPktHdr *RPCRT4_BuildBindNackHeader(unsigned long DataRepresentation, - unsigned char RpcVersion, - unsigned char RpcVersionMinor) -{ - RpcPktHdr *header; - - header = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(header->bind_nack)); - if (header == NULL) { - return NULL; - } - - RPCRT4_BuildCommonHeader(header, PKT_BIND_NACK, DataRepresentation); - header->common.frag_len = sizeof(header->bind_nack); - header->bind_nack.reject_reason = REJECT_REASON_NOT_SPECIFIED; - header->bind_nack.protocols_count = 1; - header->bind_nack.protocols[0].rpc_ver = RpcVersion; - header->bind_nack.protocols[0].rpc_ver_minor = RpcVersionMinor; - - return header; -} - -RpcPktHdr *RPCRT4_BuildBindAckHeader(unsigned long DataRepresentation, - unsigned short MaxTransmissionSize, - unsigned short MaxReceiveSize, - unsigned long AssocGroupId, - LPCSTR ServerAddress, - unsigned long Result, - unsigned long Reason, - const RPC_SYNTAX_IDENTIFIER *TransferId) -{ - RpcPktHdr *header; - unsigned long header_size; - RpcAddressString *server_address; - RpcResults *results; - RPC_SYNTAX_IDENTIFIER *transfer_id; - - header_size = sizeof(header->bind_ack) + - ROUND_UP(FIELD_OFFSET(RpcAddressString, string[strlen(ServerAddress) + 1]), 4) + - sizeof(RpcResults) + - sizeof(RPC_SYNTAX_IDENTIFIER); - - header = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, header_size); - if (header == NULL) { - return NULL; - } - - RPCRT4_BuildCommonHeader(header, PKT_BIND_ACK, DataRepresentation); - header->common.frag_len = header_size; - header->bind_ack.max_tsize = MaxTransmissionSize; - header->bind_ack.max_rsize = MaxReceiveSize; - header->bind_ack.assoc_gid = AssocGroupId; - server_address = (RpcAddressString*)(&header->bind_ack + 1); - server_address->length = strlen(ServerAddress) + 1; - strcpy(server_address->string, ServerAddress); - /* results is 4-byte aligned */ - results = (RpcResults*)((ULONG_PTR)server_address + ROUND_UP(FIELD_OFFSET(RpcAddressString, string[server_address->length]), 4)); - results->num_results = 1; - results->results[0].result = Result; - results->results[0].reason = Reason; - transfer_id = (RPC_SYNTAX_IDENTIFIER*)(results + 1); - memcpy(transfer_id, TransferId, sizeof(RPC_SYNTAX_IDENTIFIER)); - - return header; -} - -VOID RPCRT4_FreeHeader(RpcPktHdr *Header) -{ - HeapFree(GetProcessHeap(), 0, Header); -} - -NCA_STATUS RPC2NCA_STATUS(RPC_STATUS status) -{ - switch (status) - { - case ERROR_INVALID_HANDLE: return NCA_S_FAULT_CONTEXT_MISMATCH; - case ERROR_OUTOFMEMORY: return NCA_S_FAULT_REMOTE_NO_MEMORY; - case RPC_S_NOT_LISTENING: return NCA_S_SERVER_TOO_BUSY; - case RPC_S_UNKNOWN_IF: return NCA_S_UNK_IF; - case RPC_S_SERVER_TOO_BUSY: return NCA_S_SERVER_TOO_BUSY; - case RPC_S_CALL_FAILED: return NCA_S_FAULT_UNSPEC; - case RPC_S_CALL_FAILED_DNE: return NCA_S_MANAGER_NOT_ENTERED; - case RPC_S_PROTOCOL_ERROR: return NCA_S_PROTO_ERROR; - case RPC_S_UNSUPPORTED_TYPE: return NCA_S_UNSUPPORTED_TYPE; - case RPC_S_INVALID_TAG: return NCA_S_FAULT_INVALID_TAG; - case RPC_S_INVALID_BOUND: return NCA_S_FAULT_INVALID_BOUND; - case RPC_S_PROCNUM_OUT_OF_RANGE: return NCA_S_OP_RNG_ERROR; - case RPC_X_SS_HANDLES_MISMATCH: return NCA_S_FAULT_CONTEXT_MISMATCH; - case RPC_S_CALL_CANCELLED: return NCA_S_FAULT_CANCEL; - case RPC_S_COMM_FAILURE: return NCA_S_COMM_FAILURE; - case RPC_X_WRONG_PIPE_ORDER: return NCA_S_FAULT_PIPE_ORDER; - case RPC_X_PIPE_CLOSED: return NCA_S_FAULT_PIPE_CLOSED; - case RPC_X_PIPE_DISCIPLINE_ERROR: return NCA_S_FAULT_PIPE_DISCIPLINE; - case RPC_X_PIPE_EMPTY: return NCA_S_FAULT_PIPE_EMPTY; - case STATUS_FLOAT_DIVIDE_BY_ZERO: return NCA_S_FAULT_FP_DIV_ZERO; - case STATUS_FLOAT_INVALID_OPERATION: return NCA_S_FAULT_FP_ERROR; - case STATUS_FLOAT_OVERFLOW: return NCA_S_FAULT_FP_OVERFLOW; - case STATUS_FLOAT_UNDERFLOW: return NCA_S_FAULT_FP_UNDERFLOW; - case STATUS_INTEGER_DIVIDE_BY_ZERO: return NCA_S_FAULT_INT_DIV_BY_ZERO; - case STATUS_INTEGER_OVERFLOW: return NCA_S_FAULT_INT_OVERFLOW; - default: return status; - } -} - -RPC_STATUS NCA2RPC_STATUS(NCA_STATUS status) -{ - switch (status) - { - case NCA_S_COMM_FAILURE: return RPC_S_COMM_FAILURE; - case NCA_S_OP_RNG_ERROR: return RPC_S_PROCNUM_OUT_OF_RANGE; - case NCA_S_UNK_IF: return RPC_S_UNKNOWN_IF; - case NCA_S_YOU_CRASHED: return RPC_S_CALL_FAILED; - case NCA_S_PROTO_ERROR: return RPC_S_PROTOCOL_ERROR; - case NCA_S_OUT_ARGS_TOO_BIG: return ERROR_NOT_ENOUGH_SERVER_MEMORY; - case NCA_S_SERVER_TOO_BUSY: return RPC_S_SERVER_TOO_BUSY; - case NCA_S_UNSUPPORTED_TYPE: return RPC_S_UNSUPPORTED_TYPE; - case NCA_S_FAULT_INT_DIV_BY_ZERO: return RPC_S_ZERO_DIVIDE; - case NCA_S_FAULT_ADDR_ERROR: return RPC_S_ADDRESS_ERROR; - case NCA_S_FAULT_FP_DIV_ZERO: return RPC_S_FP_DIV_ZERO; - case NCA_S_FAULT_FP_UNDERFLOW: return RPC_S_FP_UNDERFLOW; - case NCA_S_FAULT_FP_OVERFLOW: return RPC_S_FP_OVERFLOW; - case NCA_S_FAULT_INVALID_TAG: return RPC_S_INVALID_TAG; - case NCA_S_FAULT_INVALID_BOUND: return RPC_S_INVALID_BOUND; - case NCA_S_RPC_VERSION_MISMATCH: return RPC_S_PROTOCOL_ERROR; - case NCA_S_UNSPEC_REJECT: return RPC_S_CALL_FAILED_DNE; - case NCA_S_BAD_ACTID: return RPC_S_CALL_FAILED_DNE; - case NCA_S_WHO_ARE_YOU_FAILED: return RPC_S_CALL_FAILED; - case NCA_S_MANAGER_NOT_ENTERED: return RPC_S_CALL_FAILED_DNE; - case NCA_S_FAULT_CANCEL: return RPC_S_CALL_CANCELLED; - case NCA_S_FAULT_ILL_INST: return RPC_S_ADDRESS_ERROR; - case NCA_S_FAULT_FP_ERROR: return RPC_S_FP_OVERFLOW; - case NCA_S_FAULT_INT_OVERFLOW: return RPC_S_ADDRESS_ERROR; - case NCA_S_FAULT_UNSPEC: return RPC_S_CALL_FAILED; - case NCA_S_FAULT_PIPE_EMPTY: return RPC_X_PIPE_EMPTY; - case NCA_S_FAULT_PIPE_CLOSED: return RPC_X_PIPE_CLOSED; - case NCA_S_FAULT_PIPE_ORDER: return RPC_X_WRONG_PIPE_ORDER; - case NCA_S_FAULT_PIPE_DISCIPLINE: return RPC_X_PIPE_DISCIPLINE_ERROR; - case NCA_S_FAULT_PIPE_COMM_ERROR: return RPC_S_COMM_FAILURE; - case NCA_S_FAULT_PIPE_MEMORY: return ERROR_OUTOFMEMORY; - case NCA_S_FAULT_CONTEXT_MISMATCH: return ERROR_INVALID_HANDLE; - case NCA_S_FAULT_REMOTE_NO_MEMORY: return ERROR_NOT_ENOUGH_SERVER_MEMORY; - default: return status; - } -} - -static RPC_STATUS RPCRT4_SecurePacket(RpcConnection *Connection, - enum secure_packet_direction dir, - RpcPktHdr *hdr, unsigned int hdr_size, - unsigned char *stub_data, unsigned int stub_data_size, - RpcAuthVerifier *auth_hdr, - unsigned char *auth_value, unsigned int auth_value_size) -{ - SecBufferDesc message; - SecBuffer buffers[4]; - SECURITY_STATUS sec_status; - - message.ulVersion = SECBUFFER_VERSION; - message.cBuffers = sizeof(buffers)/sizeof(buffers[0]); - message.pBuffers = buffers; - - buffers[0].cbBuffer = hdr_size; - buffers[0].BufferType = SECBUFFER_DATA|SECBUFFER_READONLY_WITH_CHECKSUM; - buffers[0].pvBuffer = hdr; - buffers[1].cbBuffer = stub_data_size; - buffers[1].BufferType = SECBUFFER_DATA; - buffers[1].pvBuffer = stub_data; - buffers[2].cbBuffer = sizeof(*auth_hdr); - buffers[2].BufferType = SECBUFFER_DATA|SECBUFFER_READONLY_WITH_CHECKSUM; - buffers[2].pvBuffer = auth_hdr; - buffers[3].cbBuffer = auth_value_size; - buffers[3].BufferType = SECBUFFER_TOKEN; - buffers[3].pvBuffer = auth_value; - - if (dir == SECURE_PACKET_SEND) - { - if ((auth_hdr->auth_level == RPC_C_AUTHN_LEVEL_PKT_PRIVACY) && packet_has_body(hdr)) - { - sec_status = EncryptMessage(&Connection->ctx, 0, &message, 0 /* FIXME */); - if (sec_status != SEC_E_OK) - { - ERR("EncryptMessage failed with 0x%08x\n", sec_status); - return RPC_S_SEC_PKG_ERROR; - } - } - else if (auth_hdr->auth_level != RPC_C_AUTHN_LEVEL_NONE) - { - sec_status = MakeSignature(&Connection->ctx, 0, &message, 0 /* FIXME */); - if (sec_status != SEC_E_OK) - { - ERR("MakeSignature failed with 0x%08x\n", sec_status); - return RPC_S_SEC_PKG_ERROR; - } - } - } - else if (dir == SECURE_PACKET_RECEIVE) - { - if ((auth_hdr->auth_level == RPC_C_AUTHN_LEVEL_PKT_PRIVACY) && packet_has_body(hdr)) - { - sec_status = DecryptMessage(&Connection->ctx, &message, 0 /* FIXME */, 0); - if (sec_status != SEC_E_OK) - { - ERR("DecryptMessage failed with 0x%08x\n", sec_status); - return RPC_S_SEC_PKG_ERROR; - } - } - else if (auth_hdr->auth_level != RPC_C_AUTHN_LEVEL_NONE) - { - sec_status = VerifySignature(&Connection->ctx, &message, 0 /* FIXME */, NULL); - if (sec_status != SEC_E_OK) - { - ERR("VerifySignature failed with 0x%08x\n", sec_status); - return RPC_S_SEC_PKG_ERROR; - } - } - } - - return RPC_S_OK; -} - -/*********************************************************************** - * RPCRT4_SendAuth (internal) - * - * Transmit a packet with authorization data over connection in acceptable fragments. - */ -static RPC_STATUS RPCRT4_SendAuth(RpcConnection *Connection, RpcPktHdr *Header, - void *Buffer, unsigned int BufferLength, - const void *Auth, unsigned int AuthLength) -{ - PUCHAR buffer_pos; - DWORD hdr_size; - LONG count; - unsigned char *pkt; - LONG alen; - RPC_STATUS status; - - RPCRT4_SetThreadCurrentConnection(Connection); - - buffer_pos = Buffer; - /* The packet building functions save the packet header size, so we can use it. */ - hdr_size = Header->common.frag_len; - if (AuthLength) - Header->common.auth_len = AuthLength; - else if (Connection->AuthInfo && packet_has_auth_verifier(Header)) - { - if ((Connection->AuthInfo->AuthnLevel == RPC_C_AUTHN_LEVEL_PKT_PRIVACY) && packet_has_body(Header)) - Header->common.auth_len = Connection->encryption_auth_len; - else - Header->common.auth_len = Connection->signature_auth_len; - } - else - Header->common.auth_len = 0; - Header->common.flags |= RPC_FLG_FIRST; - Header->common.flags &= ~RPC_FLG_LAST; - - alen = RPC_AUTH_VERIFIER_LEN(&Header->common); - - while (!(Header->common.flags & RPC_FLG_LAST)) { - unsigned char auth_pad_len = Header->common.auth_len ? ROUND_UP_AMOUNT(BufferLength, AUTH_ALIGNMENT) : 0; - unsigned int pkt_size = BufferLength + hdr_size + alen + auth_pad_len; - - /* decide if we need to split the packet into fragments */ - if (pkt_size <= Connection->MaxTransmissionSize) { - Header->common.flags |= RPC_FLG_LAST; - Header->common.frag_len = pkt_size; - } else { - auth_pad_len = 0; - /* make sure packet payload will be a multiple of 16 */ - Header->common.frag_len = - ((Connection->MaxTransmissionSize - hdr_size - alen) & ~(AUTH_ALIGNMENT-1)) + - hdr_size + alen; - } - - pkt = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Header->common.frag_len); - - memcpy(pkt, Header, hdr_size); - - /* fragment consisted of header only and is the last one */ - if (hdr_size == Header->common.frag_len) - goto write; - - memcpy(pkt + hdr_size, buffer_pos, Header->common.frag_len - hdr_size - auth_pad_len - alen); - - /* add the authorization info */ - if (Connection->AuthInfo && packet_has_auth_verifier(Header)) - { - RpcAuthVerifier *auth_hdr = (RpcAuthVerifier *)&pkt[Header->common.frag_len - alen]; - - auth_hdr->auth_type = Connection->AuthInfo->AuthnSvc; - auth_hdr->auth_level = Connection->AuthInfo->AuthnLevel; - auth_hdr->auth_pad_length = auth_pad_len; - auth_hdr->auth_reserved = 0; - /* a unique number... */ - auth_hdr->auth_context_id = (unsigned long)Connection; - - if (AuthLength) - memcpy(auth_hdr + 1, Auth, AuthLength); - else - { - status = RPCRT4_SecurePacket(Connection, SECURE_PACKET_SEND, - (RpcPktHdr *)pkt, hdr_size, - pkt + hdr_size, Header->common.frag_len - hdr_size - alen, - auth_hdr, - (unsigned char *)(auth_hdr + 1), Header->common.auth_len); - if (status != RPC_S_OK) - { - HeapFree(GetProcessHeap(), 0, pkt); - RPCRT4_SetThreadCurrentConnection(NULL); - return status; - } - } - } - -write: - count = rpcrt4_conn_write(Connection, pkt, Header->common.frag_len); - HeapFree(GetProcessHeap(), 0, pkt); - if (count<0) { - WARN("rpcrt4_conn_write failed (auth)\n"); - RPCRT4_SetThreadCurrentConnection(NULL); - return RPC_S_CALL_FAILED; - } - - buffer_pos += Header->common.frag_len - hdr_size - alen - auth_pad_len; - BufferLength -= Header->common.frag_len - hdr_size - alen - auth_pad_len; - Header->common.flags &= ~RPC_FLG_FIRST; - } - - RPCRT4_SetThreadCurrentConnection(NULL); - return RPC_S_OK; -} - -/*********************************************************************** - * RPCRT4_ClientAuthorize (internal) - * - * Authorize a client connection. A NULL in param signifies a new connection. - */ -static RPC_STATUS RPCRT4_ClientAuthorize(RpcConnection *conn, SecBuffer *in, - SecBuffer *out) -{ - SECURITY_STATUS r; - SecBufferDesc out_desc; - SecBufferDesc inp_desc; - SecPkgContext_Sizes secctx_sizes; - BOOL continue_needed; - ULONG context_req = ISC_REQ_CONNECTION | ISC_REQ_USE_DCE_STYLE | - ISC_REQ_MUTUAL_AUTH | ISC_REQ_DELEGATE; - - if (conn->AuthInfo->AuthnLevel == RPC_C_AUTHN_LEVEL_PKT_INTEGRITY) - context_req |= ISC_REQ_INTEGRITY; - else if (conn->AuthInfo->AuthnLevel == RPC_C_AUTHN_LEVEL_PKT_PRIVACY) - context_req |= ISC_REQ_CONFIDENTIALITY | ISC_REQ_INTEGRITY; - - out->BufferType = SECBUFFER_TOKEN; - out->cbBuffer = conn->AuthInfo->cbMaxToken; - out->pvBuffer = HeapAlloc(GetProcessHeap(), 0, out->cbBuffer); - if (!out->pvBuffer) return ERROR_OUTOFMEMORY; - - out_desc.ulVersion = 0; - out_desc.cBuffers = 1; - out_desc.pBuffers = out; - - inp_desc.cBuffers = 1; - inp_desc.pBuffers = in; - inp_desc.ulVersion = 0; - - r = InitializeSecurityContextA(&conn->AuthInfo->cred, in ? &conn->ctx : NULL, - NULL, context_req, 0, SECURITY_NETWORK_DREP, - in ? &inp_desc : NULL, 0, &conn->ctx, &out_desc, &conn->attr, - &conn->exp); - if (FAILED(r)) - { - WARN("InitializeSecurityContext failed with error 0x%08x\n", r); - goto failed; - } - - TRACE("r = 0x%08x, attr = 0x%08x\n", r, conn->attr); - continue_needed = ((r == SEC_I_CONTINUE_NEEDED) || - (r == SEC_I_COMPLETE_AND_CONTINUE)); - - if ((r == SEC_I_COMPLETE_NEEDED) || (r == SEC_I_COMPLETE_AND_CONTINUE)) - { - TRACE("complete needed\n"); - r = CompleteAuthToken(&conn->ctx, &out_desc); - if (FAILED(r)) - { - WARN("CompleteAuthToken failed with error 0x%08x\n", r); - goto failed; - } - } - - TRACE("cbBuffer = %ld\n", out->cbBuffer); - - if (!continue_needed) - { - r = QueryContextAttributesA(&conn->ctx, SECPKG_ATTR_SIZES, &secctx_sizes); - if (FAILED(r)) - { - WARN("QueryContextAttributes failed with error 0x%08x\n", r); - goto failed; - } - conn->signature_auth_len = secctx_sizes.cbMaxSignature; - conn->encryption_auth_len = secctx_sizes.cbSecurityTrailer; - } - - return RPC_S_OK; - -failed: - HeapFree(GetProcessHeap(), 0, out->pvBuffer); - out->pvBuffer = NULL; - return ERROR_ACCESS_DENIED; /* FIXME: is this correct? */ -} - -/*********************************************************************** - * RPCRT4_AuthorizeBinding (internal) - */ -static RPC_STATUS RPCRT_AuthorizeConnection(RpcConnection* conn, - BYTE *challenge, ULONG count) -{ - SecBuffer inp, out; - RpcPktHdr *resp_hdr; - RPC_STATUS status; - - TRACE("challenge %s, %d bytes\n", challenge, count); - - inp.BufferType = SECBUFFER_TOKEN; - inp.pvBuffer = challenge; - inp.cbBuffer = count; - - status = RPCRT4_ClientAuthorize(conn, &inp, &out); - if (status) return status; - - resp_hdr = RPCRT4_BuildAuthHeader(NDR_LOCAL_DATA_REPRESENTATION); - if (!resp_hdr) - return E_OUTOFMEMORY; - - status = RPCRT4_SendAuth(conn, resp_hdr, NULL, 0, out.pvBuffer, out.cbBuffer); - - HeapFree(GetProcessHeap(), 0, out.pvBuffer); - RPCRT4_FreeHeader(resp_hdr); - - return status; -} - -/*********************************************************************** - * RPCRT4_Send (internal) - * - * Transmit a packet over connection in acceptable fragments. - */ -RPC_STATUS RPCRT4_Send(RpcConnection *Connection, RpcPktHdr *Header, - void *Buffer, unsigned int BufferLength) -{ - RPC_STATUS r; - SecBuffer out; - - if (!Connection->AuthInfo || SecIsValidHandle(&Connection->ctx)) - { - return RPCRT4_SendAuth(Connection, Header, Buffer, BufferLength, NULL, 0); - } - - /* tack on a negotiate packet */ - RPCRT4_ClientAuthorize(Connection, NULL, &out); - r = RPCRT4_SendAuth(Connection, Header, Buffer, BufferLength, out.pvBuffer, out.cbBuffer); - HeapFree(GetProcessHeap(), 0, out.pvBuffer); - - return r; -} - -/*********************************************************************** - * RPCRT4_Receive (internal) - * - * Receive a packet from connection and merge the fragments. - */ -RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header, - PRPC_MESSAGE pMsg) -{ - RPC_STATUS status; - DWORD hdr_length; - LONG dwRead; - unsigned short first_flag; - unsigned long data_length; - unsigned long buffer_length; - unsigned long auth_length; - unsigned char *auth_data = NULL; - RpcPktCommonHdr common_hdr; - - *Header = NULL; - - TRACE("(%p, %p, %p)\n", Connection, Header, pMsg); - - RPCRT4_SetThreadCurrentConnection(Connection); - - /* read packet common header */ - dwRead = rpcrt4_conn_read(Connection, &common_hdr, sizeof(common_hdr)); - if (dwRead != sizeof(common_hdr)) { - WARN("Short read of header, %d bytes\n", dwRead); - status = RPC_S_CALL_FAILED; - goto fail; - } - - /* verify if the header really makes sense */ - if (common_hdr.rpc_ver != RPC_VER_MAJOR || - common_hdr.rpc_ver_minor != RPC_VER_MINOR) { - WARN("unhandled packet version\n"); - status = RPC_S_PROTOCOL_ERROR; - goto fail; - } - - hdr_length = RPCRT4_GetHeaderSize((RpcPktHdr*)&common_hdr); - if (hdr_length == 0) { - WARN("header length == 0\n"); - status = RPC_S_PROTOCOL_ERROR; - goto fail; - } - - *Header = HeapAlloc(GetProcessHeap(), 0, hdr_length); - memcpy(*Header, &common_hdr, sizeof(common_hdr)); - - /* read the rest of packet header */ - dwRead = rpcrt4_conn_read(Connection, &(*Header)->common + 1, hdr_length - sizeof(common_hdr)); - if (dwRead != hdr_length - sizeof(common_hdr)) { - WARN("bad header length, %d bytes, hdr_length %d\n", dwRead, hdr_length); - status = RPC_S_CALL_FAILED; - goto fail; - } - - /* read packet body */ - switch (common_hdr.ptype) { - case PKT_RESPONSE: - pMsg->BufferLength = (*Header)->response.alloc_hint; - break; - case PKT_REQUEST: - pMsg->BufferLength = (*Header)->request.alloc_hint; - break; - default: - pMsg->BufferLength = common_hdr.frag_len - hdr_length - RPC_AUTH_VERIFIER_LEN(&common_hdr); - } - - TRACE("buffer length = %u\n", pMsg->BufferLength); - - status = I_RpcGetBuffer(pMsg); - if (status != RPC_S_OK) goto fail; - - first_flag = RPC_FLG_FIRST; - auth_length = common_hdr.auth_len; - if (auth_length) { - auth_data = HeapAlloc(GetProcessHeap(), 0, RPC_AUTH_VERIFIER_LEN(&common_hdr)); - if (!auth_data) { - status = RPC_S_OUT_OF_RESOURCES; - goto fail; - } - } - buffer_length = 0; - while (TRUE) - { - unsigned int header_auth_len = RPC_AUTH_VERIFIER_LEN(&(*Header)->common); - - /* verify header fields */ - - if (((*Header)->common.frag_len < hdr_length) || - ((*Header)->common.frag_len - hdr_length < header_auth_len)) { - WARN("frag_len %d too small for hdr_length %d and auth_len %d\n", - (*Header)->common.frag_len, hdr_length, header_auth_len); - status = RPC_S_PROTOCOL_ERROR; - goto fail; - } - - if ((*Header)->common.auth_len != auth_length) { - WARN("auth_len header field changed from %ld to %d\n", - auth_length, (*Header)->common.auth_len); - status = RPC_S_PROTOCOL_ERROR; - goto fail; - } - - if (((*Header)->common.flags & RPC_FLG_FIRST) != first_flag) { - TRACE("invalid packet flags\n"); - status = RPC_S_PROTOCOL_ERROR; - goto fail; - } - - data_length = (*Header)->common.frag_len - hdr_length - header_auth_len; - if (data_length + buffer_length > pMsg->BufferLength) { - TRACE("allocation hint exceeded, new buffer length = %ld\n", - data_length + buffer_length); - pMsg->BufferLength = data_length + buffer_length; - status = I_RpcReAllocateBuffer(pMsg); - if (status != RPC_S_OK) goto fail; - } - - if (data_length == 0) dwRead = 0; else - dwRead = rpcrt4_conn_read(Connection, - (unsigned char *)pMsg->Buffer + buffer_length, data_length); - if (dwRead != data_length) { - WARN("bad data length, %d/%ld\n", dwRead, data_length); - status = RPC_S_CALL_FAILED; - goto fail; - } - - if (header_auth_len) { - if (header_auth_len < sizeof(RpcAuthVerifier)) { - WARN("bad auth verifier length %d\n", header_auth_len); - status = RPC_S_PROTOCOL_ERROR; - goto fail; - } - - /* FIXME: we should accumulate authentication data for the bind, - * bind_ack, alter_context and alter_context_response if necessary. - * however, the details of how this is done is very sketchy in the - * DCE/RPC spec. for all other packet types that have authentication - * verifier data then it is just duplicated in all the fragments */ - dwRead = rpcrt4_conn_read(Connection, auth_data, header_auth_len); - if (dwRead != header_auth_len) { - WARN("bad authentication data length, %d/%d\n", dwRead, - header_auth_len); - status = RPC_S_CALL_FAILED; - goto fail; - } - - /* these packets are handled specially, not by the generic SecurePacket - * function */ - if ((common_hdr.ptype != PKT_BIND) && - (common_hdr.ptype != PKT_BIND_ACK) && - (common_hdr.ptype != PKT_AUTH3)) - { - status = RPCRT4_SecurePacket(Connection, SECURE_PACKET_RECEIVE, - *Header, hdr_length, - (unsigned char *)pMsg->Buffer + buffer_length, data_length, - (RpcAuthVerifier *)auth_data, - (unsigned char *)auth_data + sizeof(RpcAuthVerifier), - header_auth_len - sizeof(RpcAuthVerifier)); - if (status != RPC_S_OK) goto fail; - } - } - - buffer_length += data_length; - if (!((*Header)->common.flags & RPC_FLG_LAST)) { - TRACE("next header\n"); - - /* read the header of next packet */ - dwRead = rpcrt4_conn_read(Connection, *Header, hdr_length); - if (dwRead != hdr_length) { - WARN("invalid packet header size (%d)\n", dwRead); - status = RPC_S_CALL_FAILED; - goto fail; - } - - first_flag = 0; - } else { - break; - } - } - pMsg->BufferLength = buffer_length; - - /* respond to authorization request */ - if (common_hdr.ptype == PKT_BIND_ACK && auth_length > sizeof(RpcAuthVerifier)) - { - status = RPCRT_AuthorizeConnection(Connection, - auth_data + sizeof(RpcAuthVerifier), - auth_length); - if (status) - goto fail; - } - - /* success */ - status = RPC_S_OK; - -fail: - RPCRT4_SetThreadCurrentConnection(NULL); - if (status != RPC_S_OK) { - RPCRT4_FreeHeader(*Header); - *Header = NULL; - } - HeapFree(GetProcessHeap(), 0, auth_data); - return status; -} - -/*********************************************************************** - * I_RpcGetBuffer [RPCRT4.@] - * - * Allocates a buffer for use by I_RpcSend or I_RpcSendReceive and binds to the - * server interface. - * - * PARAMS - * pMsg [I/O] RPC message information. - * - * RETURNS - * Success: RPC_S_OK. - * Failure: RPC_S_INVALID_BINDING if pMsg->Handle is invalid. - * RPC_S_SERVER_UNAVAILABLE if unable to connect to server. - * ERROR_OUTOFMEMORY if buffer allocation failed. - * - * NOTES - * The pMsg->BufferLength field determines the size of the buffer to allocate, - * in bytes. - * - * Use I_RpcFreeBuffer() to unbind from the server and free the message buffer. - * - * SEE ALSO - * I_RpcFreeBuffer(), I_RpcSend(), I_RpcReceive(), I_RpcSendReceive(). - */ -RPC_STATUS WINAPI I_RpcGetBuffer(PRPC_MESSAGE pMsg) -{ - TRACE("(%p): BufferLength=%d\n", pMsg, pMsg->BufferLength); - /* FIXME: pfnAllocate? */ - pMsg->Buffer = HeapAlloc(GetProcessHeap(), 0, pMsg->BufferLength); - - TRACE("Buffer=%p\n", pMsg->Buffer); - /* FIXME: which errors to return? */ - return pMsg->Buffer ? S_OK : E_OUTOFMEMORY; -} - -/*********************************************************************** - * I_RpcReAllocateBuffer (internal) - */ -static RPC_STATUS I_RpcReAllocateBuffer(PRPC_MESSAGE pMsg) -{ - TRACE("(%p): BufferLength=%d\n", pMsg, pMsg->BufferLength); - pMsg->Buffer = HeapReAlloc(GetProcessHeap(), 0, pMsg->Buffer, pMsg->BufferLength); - - TRACE("Buffer=%p\n", pMsg->Buffer); - return pMsg->Buffer ? RPC_S_OK : RPC_S_OUT_OF_RESOURCES; -} - -/*********************************************************************** - * I_RpcFreeBuffer [RPCRT4.@] - * - * Frees a buffer allocated by I_RpcGetBuffer or I_RpcReceive and unbinds from - * the server interface. - * - * PARAMS - * pMsg [I/O] RPC message information. - * - * RETURNS - * RPC_S_OK. - * - * SEE ALSO - * I_RpcGetBuffer(), I_RpcReceive(). - */ -RPC_STATUS WINAPI I_RpcFreeBuffer(PRPC_MESSAGE pMsg) -{ - TRACE("(%p) Buffer=%p\n", pMsg, pMsg->Buffer); - /* FIXME: pfnFree? */ - HeapFree(GetProcessHeap(), 0, pMsg->Buffer); - pMsg->Buffer = NULL; - return S_OK; -} - -/*********************************************************************** - * I_RpcSend [RPCRT4.@] - * - * Sends a message to the server. - * - * PARAMS - * pMsg [I/O] RPC message information. - * - * RETURNS - * Unknown. - * - * NOTES - * The buffer must have been allocated with I_RpcGetBuffer(). - * - * SEE ALSO - * I_RpcGetBuffer(), I_RpcReceive(), I_RpcSendReceive(). - */ -RPC_STATUS WINAPI I_RpcSend(PRPC_MESSAGE pMsg) -{ - RpcBinding* bind = (RpcBinding*)pMsg->Handle; - RpcConnection* conn; - RPC_CLIENT_INTERFACE* cif = NULL; - RPC_STATUS status; - RpcPktHdr *hdr; - - TRACE("(%p)\n", pMsg); - if (!bind || bind->server) return RPC_S_INVALID_BINDING; - - cif = pMsg->RpcInterfaceInformation; - if (!cif) return RPC_S_INTERFACE_NOT_FOUND; /* ? */ - - if (!bind->Endpoint || !bind->Endpoint[0]) - { - TRACE("automatically resolving partially bound binding\n"); - status = RpcEpResolveBinding(bind, cif); - if (status != RPC_S_OK) return status; - } - - status = RPCRT4_OpenBinding(bind, &conn, &cif->TransferSyntax, - &cif->InterfaceId); - if (status != RPC_S_OK) return status; - - hdr = RPCRT4_BuildRequestHeader(pMsg->DataRepresentation, - pMsg->BufferLength, pMsg->ProcNum, - &bind->ObjectUuid); - if (!hdr) - { - RPCRT4_CloseBinding(bind, conn); - return ERROR_OUTOFMEMORY; - } - hdr->common.call_id = conn->NextCallId++; - - status = RPCRT4_Send(conn, hdr, pMsg->Buffer, pMsg->BufferLength); - - RPCRT4_FreeHeader(hdr); - - /* save the connection, so the response can be read from it */ - pMsg->ReservedForRuntime = conn; - return status; -} - -/* is this status something that the server can't recover from? */ -static inline BOOL is_hard_error(RPC_STATUS status) -{ - switch (status) - { - case 0: /* user-defined fault */ - case ERROR_ACCESS_DENIED: - case ERROR_INVALID_PARAMETER: - case RPC_S_PROTOCOL_ERROR: - case RPC_S_CALL_FAILED: - case RPC_S_CALL_FAILED_DNE: - case RPC_S_SEC_PKG_ERROR: - return TRUE; - default: - return FALSE; - } -} - -/*********************************************************************** - * I_RpcReceive [RPCRT4.@] - */ -RPC_STATUS WINAPI I_RpcReceive(PRPC_MESSAGE pMsg) -{ - RpcBinding* bind = (RpcBinding*)pMsg->Handle; - RpcConnection* conn; - RPC_CLIENT_INTERFACE* cif = NULL; - RPC_SERVER_INTERFACE* sif = NULL; - RPC_STATUS status; - RpcPktHdr *hdr = NULL; - - TRACE("(%p)\n", pMsg); - if (!bind) return RPC_S_INVALID_BINDING; - - if (pMsg->ReservedForRuntime) { - conn = pMsg->ReservedForRuntime; - pMsg->ReservedForRuntime = NULL; - } else { - if (bind->server) { - sif = pMsg->RpcInterfaceInformation; - if (!sif) return RPC_S_INTERFACE_NOT_FOUND; /* ? */ - status = RPCRT4_OpenBinding(bind, &conn, &sif->TransferSyntax, - &sif->InterfaceId); - } else { - cif = pMsg->RpcInterfaceInformation; - if (!cif) return RPC_S_INTERFACE_NOT_FOUND; /* ? */ - - if (!bind->Endpoint || !bind->Endpoint[0]) - { - TRACE("automatically resolving partially bound binding\n"); - status = RpcEpResolveBinding(bind, cif); - if (status != RPC_S_OK) return status; - } - - status = RPCRT4_OpenBinding(bind, &conn, &cif->TransferSyntax, - &cif->InterfaceId); - } - if (status != RPC_S_OK) return status; - } - - status = RPCRT4_Receive(conn, &hdr, pMsg); - if (status != RPC_S_OK) { - WARN("receive failed with error %lx\n", status); - goto fail; - } - - switch (hdr->common.ptype) { - case PKT_RESPONSE: - if (bind->server) { - status = RPC_S_PROTOCOL_ERROR; - goto fail; - } - break; - case PKT_REQUEST: - if (!bind->server) { - status = RPC_S_PROTOCOL_ERROR; - goto fail; - } - break; - case PKT_FAULT: - ERR ("we got fault packet with status 0x%lx\n", hdr->fault.status); - status = NCA2RPC_STATUS(hdr->fault.status); - if (is_hard_error(status)) - goto fail; - break; - default: - WARN("bad packet type %d\n", hdr->common.ptype); - status = RPC_S_PROTOCOL_ERROR; - goto fail; - } - - /* success */ - RPCRT4_CloseBinding(bind, conn); - RPCRT4_FreeHeader(hdr); - return status; - -fail: - RPCRT4_FreeHeader(hdr); - RPCRT4_DestroyConnection(conn); - return status; -} - -/*********************************************************************** - * I_RpcSendReceive [RPCRT4.@] - * - * Sends a message to the server and receives the response. - * - * PARAMS - * pMsg [I/O] RPC message information. - * - * RETURNS - * Success: RPC_S_OK. - * Failure: Any error code. - * - * NOTES - * The buffer must have been allocated with I_RpcGetBuffer(). - * - * SEE ALSO - * I_RpcGetBuffer(), I_RpcSend(), I_RpcReceive(). - */ -RPC_STATUS WINAPI I_RpcSendReceive(PRPC_MESSAGE pMsg) -{ - RPC_STATUS status; - RPC_MESSAGE original_message; - - TRACE("(%p)\n", pMsg); - - original_message = *pMsg; - status = I_RpcSend(pMsg); - if (status == RPC_S_OK) - status = I_RpcReceive(pMsg); - /* free the buffer replaced by a new buffer in I_RpcReceive */ - if (status == RPC_S_OK) - I_RpcFreeBuffer(&original_message); - return status; -} diff --git a/reactos/dll/win32/rpcrt4_new/rpc_message.h b/reactos/dll/win32/rpcrt4_new/rpc_message.h deleted file mode 100644 index cbf83d30ce0..00000000000 --- a/reactos/dll/win32/rpcrt4_new/rpc_message.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * RPC message API - * - * Copyright 2004 Filip Navara - * - * 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 - */ - -#ifndef __WINE_RPC_MESSAGE_H -#define __WINE_RPC_MESSAGE_H - -#include "wine/rpcss_shared.h" -#include "rpc_defs.h" - -typedef unsigned int NCA_STATUS; - -RpcPktHdr *RPCRT4_BuildFaultHeader(unsigned long DataRepresentation, RPC_STATUS Status); -RpcPktHdr *RPCRT4_BuildResponseHeader(unsigned long DataRepresentation, unsigned long BufferLength); -RpcPktHdr *RPCRT4_BuildBindHeader(unsigned long DataRepresentation, unsigned short MaxTransmissionSize, unsigned short MaxReceiveSize, unsigned long AssocGroupId, const RPC_SYNTAX_IDENTIFIER *AbstractId, const RPC_SYNTAX_IDENTIFIER *TransferId); -RpcPktHdr *RPCRT4_BuildBindNackHeader(unsigned long DataRepresentation, unsigned char RpcVersion, unsigned char RpcVersionMinor); -RpcPktHdr *RPCRT4_BuildBindAckHeader(unsigned long DataRepresentation, unsigned short MaxTransmissionSize, unsigned short MaxReceiveSize, unsigned long AssocGroupId, LPCSTR ServerAddress, unsigned long Result, unsigned long Reason, const RPC_SYNTAX_IDENTIFIER *TransferId); -VOID RPCRT4_FreeHeader(RpcPktHdr *Header); -RPC_STATUS RPCRT4_Send(RpcConnection *Connection, RpcPktHdr *Header, void *Buffer, unsigned int BufferLength); -RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header, PRPC_MESSAGE pMsg); -NCA_STATUS RPC2NCA_STATUS(RPC_STATUS status); -RPC_STATUS NCA2RPC_STATUS(NCA_STATUS status); - -#endif diff --git a/reactos/dll/win32/rpcrt4_new/rpc_server.c b/reactos/dll/win32/rpcrt4_new/rpc_server.c deleted file mode 100644 index 02d13988e24..00000000000 --- a/reactos/dll/win32/rpcrt4_new/rpc_server.c +++ /dev/null @@ -1,1147 +0,0 @@ -/* - * RPC server API - * - * Copyright 2001 Ove Kåven, TransGaming Technologies - * Copyright 2004 Filip Navara - * - * 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 - * - * TODO: - * - a whole lot - */ - -#include "config.h" -#include "wine/port.h" - -#include -#include -#include -#include - -#include "windef.h" -#include "winbase.h" -#include "winerror.h" - -#include "rpc.h" -#include "rpcndr.h" -#include "excpt.h" - -#include "wine/debug.h" -#include "wine/exception.h" - -#include "rpc_server.h" -#include "rpc_assoc.h" -#include "rpc_message.h" -#include "rpc_defs.h" -#include "ncastatus.h" - -WINE_DEFAULT_DEBUG_CHANNEL(rpc); - -typedef struct _RpcPacket -{ - struct _RpcConnection* conn; - RpcPktHdr* hdr; - RPC_MESSAGE* msg; -} RpcPacket; - -typedef struct _RpcObjTypeMap -{ - /* FIXME: a hash table would be better. */ - struct _RpcObjTypeMap *next; - UUID Object; - UUID Type; -} RpcObjTypeMap; - -static RpcObjTypeMap *RpcObjTypeMaps; - -/* list of type RpcServerProtseq */ -static struct list protseqs = LIST_INIT(protseqs); -static struct list server_interfaces = LIST_INIT(server_interfaces); - -static CRITICAL_SECTION server_cs; -static CRITICAL_SECTION_DEBUG server_cs_debug = -{ - 0, 0, &server_cs, - { &server_cs_debug.ProcessLocksList, &server_cs_debug.ProcessLocksList }, - 0, 0, { (DWORD_PTR)(__FILE__ ": server_cs") } -}; -static CRITICAL_SECTION server_cs = { &server_cs_debug, -1, 0, 0, 0, 0 }; - -static CRITICAL_SECTION listen_cs; -static CRITICAL_SECTION_DEBUG listen_cs_debug = -{ - 0, 0, &listen_cs, - { &listen_cs_debug.ProcessLocksList, &listen_cs_debug.ProcessLocksList }, - 0, 0, { (DWORD_PTR)(__FILE__ ": listen_cs") } -}; -static CRITICAL_SECTION listen_cs = { &listen_cs_debug, -1, 0, 0, 0, 0 }; - -/* whether the server is currently listening */ -static BOOL std_listen; -/* number of manual listeners (calls to RpcServerListen) */ -static LONG manual_listen_count; -/* total listeners including auto listeners */ -static LONG listen_count; - -static UUID uuid_nil; - -static inline RpcObjTypeMap *LookupObjTypeMap(UUID *ObjUuid) -{ - RpcObjTypeMap *rslt = RpcObjTypeMaps; - RPC_STATUS dummy; - - while (rslt) { - if (! UuidCompare(ObjUuid, &rslt->Object, &dummy)) break; - rslt = rslt->next; - } - - return rslt; -} - -static inline UUID *LookupObjType(UUID *ObjUuid) -{ - RpcObjTypeMap *map = LookupObjTypeMap(ObjUuid); - if (map) - return &map->Type; - else - return &uuid_nil; -} - -static RpcServerInterface* RPCRT4_find_interface(UUID* object, - const RPC_SYNTAX_IDENTIFIER* if_id, - BOOL check_object) -{ - UUID* MgrType = NULL; - RpcServerInterface* cif; - RPC_STATUS status; - - if (check_object) - MgrType = LookupObjType(object); - EnterCriticalSection(&server_cs); - LIST_FOR_EACH_ENTRY(cif, &server_interfaces, RpcServerInterface, entry) { - if (!memcmp(if_id, &cif->If->InterfaceId, sizeof(RPC_SYNTAX_IDENTIFIER)) && - (check_object == FALSE || UuidEqual(MgrType, &cif->MgrTypeUuid, &status)) && - std_listen) { - InterlockedIncrement(&cif->CurrentCalls); - break; - } - } - LeaveCriticalSection(&server_cs); - if (&cif->entry == &server_interfaces) cif = NULL; - TRACE("returning %p for %s\n", cif, debugstr_guid(object)); - return cif; -} - -static void RPCRT4_release_server_interface(RpcServerInterface *sif) -{ - if (!InterlockedDecrement(&sif->CurrentCalls) && - sif->CallsCompletedEvent) { - /* sif must have been removed from server_interfaces before - * CallsCompletedEvent is set */ - SetEvent(sif->CallsCompletedEvent); - HeapFree(GetProcessHeap(), 0, sif); - } -} - -static WINE_EXCEPTION_FILTER(rpc_filter) -{ - WARN("exception caught with code 0x%08x = %d\n", GetExceptionCode(), GetExceptionCode()); - TRACE("returning failure packet\n"); - /* catch every exception */ - return EXCEPTION_EXECUTE_HANDLER; -} - -static void RPCRT4_process_packet(RpcConnection* conn, RpcPktHdr* hdr, RPC_MESSAGE* msg) -{ - RpcServerInterface* sif; - RPC_DISPATCH_FUNCTION func; - UUID *object_uuid; - RpcPktHdr *response = NULL; - void *buf = msg->Buffer; - RPC_STATUS status; - BOOL exception; - NDR_SCONTEXT context_handle; - - msg->Handle = (RPC_BINDING_HANDLE)conn->server_binding; - - switch (hdr->common.ptype) { - case PKT_BIND: - TRACE("got bind packet\n"); - - /* FIXME: do more checks! */ - if (hdr->bind.max_tsize < RPC_MIN_PACKET_SIZE || - !UuidIsNil(&conn->ActiveInterface.SyntaxGUID, &status) || - conn->server_binding) { - TRACE("packet size less than min size, or active interface syntax guid non-null\n"); - sif = NULL; - } else { - /* create temporary binding */ - if (RPCRT4_MakeBinding(&conn->server_binding, conn) == RPC_S_OK && - RpcServerAssoc_GetAssociation(rpcrt4_conn_get_name(conn), - conn->NetworkAddr, conn->Endpoint, - conn->NetworkOptions, - hdr->bind.assoc_gid, - &conn->server_binding->Assoc) == RPC_S_OK) - sif = RPCRT4_find_interface(NULL, &hdr->bind.abstract, FALSE); - else - sif = NULL; - } - if (sif == NULL) { - TRACE("rejecting bind request on connection %p\n", conn); - /* Report failure to client. */ - response = RPCRT4_BuildBindNackHeader(NDR_LOCAL_DATA_REPRESENTATION, - RPC_VER_MAJOR, RPC_VER_MINOR); - } else { - TRACE("accepting bind request on connection %p for %s\n", conn, - debugstr_guid(&hdr->bind.abstract.SyntaxGUID)); - - /* accept. */ - response = RPCRT4_BuildBindAckHeader(NDR_LOCAL_DATA_REPRESENTATION, - RPC_MAX_PACKET_SIZE, - RPC_MAX_PACKET_SIZE, - conn->server_binding->Assoc->assoc_group_id, - conn->Endpoint, - RESULT_ACCEPT, REASON_NONE, - &sif->If->TransferSyntax); - - /* save the interface for later use */ - conn->ActiveInterface = hdr->bind.abstract; - conn->MaxTransmissionSize = hdr->bind.max_tsize; - - RPCRT4_release_server_interface(sif); - } - - status = RPCRT4_Send(conn, response, NULL, 0); - RPCRT4_FreeHeader(response); - if (status != RPC_S_OK) - goto fail; - - break; - - case PKT_REQUEST: - TRACE("got request packet\n"); - - /* fail if the connection isn't bound with an interface */ - if (UuidIsNil(&conn->ActiveInterface.SyntaxGUID, &status)) { - /* FIXME: should send BindNack instead */ - response = RPCRT4_BuildFaultHeader(NDR_LOCAL_DATA_REPRESENTATION, - status); - - RPCRT4_Send(conn, response, NULL, 0); - RPCRT4_FreeHeader(response); - break; - } - - if (hdr->common.flags & RPC_FLG_OBJECT_UUID) { - object_uuid = (UUID*)(&hdr->request + 1); - } else { - object_uuid = NULL; - } - - sif = RPCRT4_find_interface(object_uuid, &conn->ActiveInterface, TRUE); - if (!sif) { - WARN("interface %s no longer registered, returning fault packet\n", debugstr_guid(&conn->ActiveInterface.SyntaxGUID)); - response = RPCRT4_BuildFaultHeader(NDR_LOCAL_DATA_REPRESENTATION, - NCA_S_UNK_IF); - - RPCRT4_Send(conn, response, NULL, 0); - RPCRT4_FreeHeader(response); - break; - } - msg->RpcInterfaceInformation = sif->If; - /* copy the endpoint vector from sif to msg so that midl-generated code will use it */ - msg->ManagerEpv = sif->MgrEpv; - if (object_uuid != NULL) { - RPCRT4_SetBindingObject(msg->Handle, object_uuid); - } - - /* find dispatch function */ - msg->ProcNum = hdr->request.opnum; - if (sif->Flags & RPC_IF_OLE) { - /* native ole32 always gives us a dispatch table with a single entry - * (I assume that's a wrapper for IRpcStubBuffer::Invoke) */ - func = *sif->If->DispatchTable->DispatchTable; - } else { - if (msg->ProcNum >= sif->If->DispatchTable->DispatchTableCount) { - WARN("invalid procnum (%d/%d)\n", msg->ProcNum, sif->If->DispatchTable->DispatchTableCount); - response = RPCRT4_BuildFaultHeader(NDR_LOCAL_DATA_REPRESENTATION, - NCA_S_OP_RNG_ERROR); - - RPCRT4_Send(conn, response, NULL, 0); - RPCRT4_FreeHeader(response); - } - func = sif->If->DispatchTable->DispatchTable[msg->ProcNum]; - } - - /* put in the drep. FIXME: is this more universally applicable? - perhaps we should move this outward... */ - msg->DataRepresentation = - MAKELONG( MAKEWORD(hdr->common.drep[0], hdr->common.drep[1]), - MAKEWORD(hdr->common.drep[2], hdr->common.drep[3])); - - exception = FALSE; - - /* dispatch */ - RPCRT4_SetThreadCurrentCallHandle(msg->Handle); - __TRY { - if (func) func(msg); - } __EXCEPT(rpc_filter) { - exception = TRUE; - if (GetExceptionCode() == STATUS_ACCESS_VIOLATION) - status = ERROR_NOACCESS; - else - status = GetExceptionCode(); - response = RPCRT4_BuildFaultHeader(msg->DataRepresentation, - RPC2NCA_STATUS(status)); - } __ENDTRY - RPCRT4_SetThreadCurrentCallHandle(NULL); - - /* release any unmarshalled context handles */ - while ((context_handle = RPCRT4_PopThreadContextHandle()) != NULL) - RpcServerAssoc_ReleaseContextHandle(conn->server_binding->Assoc, context_handle, TRUE); - - if (!exception) - response = RPCRT4_BuildResponseHeader(msg->DataRepresentation, - msg->BufferLength); - - /* send response packet */ - if (response) { - status = RPCRT4_Send(conn, response, exception ? NULL : msg->Buffer, - exception ? 0 : msg->BufferLength); - RPCRT4_FreeHeader(response); - } else - ERR("out of memory\n"); - - msg->RpcInterfaceInformation = NULL; - RPCRT4_release_server_interface(sif); - - break; - - default: - FIXME("unhandled packet type %u\n", hdr->common.ptype); - break; - } - -fail: - /* clean up */ - if (msg->Buffer == buf) msg->Buffer = NULL; - TRACE("freeing Buffer=%p\n", buf); - HeapFree(GetProcessHeap(), 0, buf); - msg->Handle = 0; - I_RpcFreeBuffer(msg); - msg->Buffer = NULL; - RPCRT4_FreeHeader(hdr); - HeapFree(GetProcessHeap(), 0, msg); -} - -static DWORD CALLBACK RPCRT4_worker_thread(LPVOID the_arg) -{ - RpcPacket *pkt = the_arg; - RPCRT4_process_packet(pkt->conn, pkt->hdr, pkt->msg); - HeapFree(GetProcessHeap(), 0, pkt); - return 0; -} - -static DWORD CALLBACK RPCRT4_io_thread(LPVOID the_arg) -{ - RpcConnection* conn = (RpcConnection*)the_arg; - RpcPktHdr *hdr; - RPC_MESSAGE *msg; - RPC_STATUS status; - RpcPacket *packet; - - TRACE("(%p)\n", conn); - - for (;;) { - msg = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RPC_MESSAGE)); - - status = RPCRT4_Receive(conn, &hdr, msg); - if (status != RPC_S_OK) { - WARN("receive failed with error %lx\n", status); - HeapFree(GetProcessHeap(), 0, msg); - break; - } - -#if 0 - RPCRT4_process_packet(conn, hdr, msg); -#else - packet = HeapAlloc(GetProcessHeap(), 0, sizeof(RpcPacket)); - packet->conn = conn; - packet->hdr = hdr; - packet->msg = msg; - QueueUserWorkItem(RPCRT4_worker_thread, packet, WT_EXECUTELONGFUNCTION); -#endif - msg = NULL; - } - RPCRT4_DestroyConnection(conn); - return 0; -} - -void RPCRT4_new_client(RpcConnection* conn) -{ - HANDLE thread = CreateThread(NULL, 0, RPCRT4_io_thread, conn, 0, NULL); - if (!thread) { - DWORD err = GetLastError(); - ERR("failed to create thread, error=%08x\n", err); - RPCRT4_DestroyConnection(conn); - } - /* we could set conn->thread, but then we'd have to make the io_thread wait - * for that, otherwise the thread might finish, destroy the connection, and - * free the memory we'd write to before we did, causing crashes and stuff - - * so let's implement that later, when we really need conn->thread */ - - CloseHandle( thread ); -} - -static DWORD CALLBACK RPCRT4_server_thread(LPVOID the_arg) -{ - int res; - unsigned int count; - void *objs = NULL; - RpcServerProtseq* cps = the_arg; - RpcConnection* conn; - BOOL set_ready_event = FALSE; - - TRACE("(the_arg == ^%p)\n", the_arg); - - for (;;) { - objs = cps->ops->get_wait_array(cps, objs, &count); - - if (set_ready_event) - { - /* signal to function that changed state that we are now sync'ed */ - SetEvent(cps->server_ready_event); - set_ready_event = FALSE; - } - - /* start waiting */ - res = cps->ops->wait_for_new_connection(cps, count, objs); - if (res == -1) - break; - else if (res == 0) - { - if (!std_listen) - { - SetEvent(cps->server_ready_event); - break; - } - set_ready_event = TRUE; - } - } - cps->ops->free_wait_array(cps, objs); - EnterCriticalSection(&cps->cs); - /* close connections */ - conn = cps->conn; - while (conn) { - RPCRT4_CloseConnection(conn); - conn = conn->Next; - } - LeaveCriticalSection(&cps->cs); - return 0; -} - -/* tells the server thread that the state has changed and waits for it to - * make the changes */ -static void RPCRT4_sync_with_server_thread(RpcServerProtseq *ps) -{ - /* make sure we are the only thread sync'ing the server state, otherwise - * there is a race with the server thread setting an older state and setting - * the server_ready_event when the new state hasn't yet been applied */ - WaitForSingleObject(ps->mgr_mutex, INFINITE); - - ps->ops->signal_state_changed(ps); - - /* wait for server thread to make the requested changes before returning */ - WaitForSingleObject(ps->server_ready_event, INFINITE); - - ReleaseMutex(ps->mgr_mutex); -} - -static RPC_STATUS RPCRT4_start_listen_protseq(RpcServerProtseq *ps, BOOL auto_listen) -{ - RPC_STATUS status = RPC_S_OK; - HANDLE server_thread; - - EnterCriticalSection(&listen_cs); - if (ps->is_listening) goto done; - - if (!ps->mgr_mutex) ps->mgr_mutex = CreateMutexW(NULL, FALSE, NULL); - if (!ps->server_ready_event) ps->server_ready_event = CreateEventW(NULL, FALSE, FALSE, NULL); - server_thread = CreateThread(NULL, 0, RPCRT4_server_thread, ps, 0, NULL); - if (!server_thread) - { - status = RPC_S_OUT_OF_RESOURCES; - goto done; - } - ps->is_listening = TRUE; - CloseHandle(server_thread); - -done: - LeaveCriticalSection(&listen_cs); - return status; -} - -static RPC_STATUS RPCRT4_start_listen(BOOL auto_listen) -{ - RPC_STATUS status = RPC_S_ALREADY_LISTENING; - RpcServerProtseq *cps; - - TRACE("\n"); - - EnterCriticalSection(&listen_cs); - if (auto_listen || (manual_listen_count++ == 0)) - { - status = RPC_S_OK; - if (++listen_count == 1) - std_listen = TRUE; - } - LeaveCriticalSection(&listen_cs); - - if (std_listen) - { - EnterCriticalSection(&server_cs); - LIST_FOR_EACH_ENTRY(cps, &protseqs, RpcServerProtseq, entry) - { - status = RPCRT4_start_listen_protseq(cps, TRUE); - if (status != RPC_S_OK) - break; - - /* make sure server is actually listening on the interface before - * returning */ - RPCRT4_sync_with_server_thread(cps); - } - LeaveCriticalSection(&server_cs); - } - - return status; -} - -static void RPCRT4_stop_listen(BOOL auto_listen) -{ - EnterCriticalSection(&listen_cs); - if (auto_listen || (--manual_listen_count == 0)) - { - if (listen_count != 0 && --listen_count == 0) { - RpcServerProtseq *cps; - - std_listen = FALSE; - LeaveCriticalSection(&listen_cs); - - LIST_FOR_EACH_ENTRY(cps, &protseqs, RpcServerProtseq, entry) - RPCRT4_sync_with_server_thread(cps); - - return; - } - assert(listen_count >= 0); - } - LeaveCriticalSection(&listen_cs); -} - -static RPC_STATUS RPCRT4_use_protseq(RpcServerProtseq* ps, LPSTR endpoint) -{ - RPC_STATUS status; - - status = ps->ops->open_endpoint(ps, endpoint); - if (status != RPC_S_OK) - return status; - - if (std_listen) - { - status = RPCRT4_start_listen_protseq(ps, FALSE); - if (status == RPC_S_OK) - RPCRT4_sync_with_server_thread(ps); - } - - return status; -} - -/*********************************************************************** - * RpcServerInqBindings (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcServerInqBindings( RPC_BINDING_VECTOR** BindingVector ) -{ - RPC_STATUS status; - DWORD count; - RpcServerProtseq* ps; - RpcConnection* conn; - - if (BindingVector) - TRACE("(*BindingVector == ^%p)\n", *BindingVector); - else - ERR("(BindingVector == NULL!!?)\n"); - - EnterCriticalSection(&server_cs); - /* count connections */ - count = 0; - LIST_FOR_EACH_ENTRY(ps, &protseqs, RpcServerProtseq, entry) { - EnterCriticalSection(&ps->cs); - conn = ps->conn; - while (conn) { - count++; - conn = conn->Next; - } - LeaveCriticalSection(&ps->cs); - } - if (count) { - /* export bindings */ - *BindingVector = HeapAlloc(GetProcessHeap(), 0, - sizeof(RPC_BINDING_VECTOR) + - sizeof(RPC_BINDING_HANDLE)*(count-1)); - (*BindingVector)->Count = count; - count = 0; - LIST_FOR_EACH_ENTRY(ps, &protseqs, RpcServerProtseq, entry) { - EnterCriticalSection(&ps->cs); - conn = ps->conn; - while (conn) { - RPCRT4_MakeBinding((RpcBinding**)&(*BindingVector)->BindingH[count], - conn); - count++; - conn = conn->Next; - } - LeaveCriticalSection(&ps->cs); - } - status = RPC_S_OK; - } else { - *BindingVector = NULL; - status = RPC_S_NO_BINDINGS; - } - LeaveCriticalSection(&server_cs); - return status; -} - -/*********************************************************************** - * RpcServerUseProtseqEpA (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcServerUseProtseqEpA( RPC_CSTR Protseq, UINT MaxCalls, RPC_CSTR Endpoint, LPVOID SecurityDescriptor ) -{ - RPC_POLICY policy; - - TRACE( "(%s,%u,%s,%p)\n", Protseq, MaxCalls, Endpoint, SecurityDescriptor ); - - /* This should provide the default behaviour */ - policy.Length = sizeof( policy ); - policy.EndpointFlags = 0; - policy.NICFlags = 0; - - return RpcServerUseProtseqEpExA( Protseq, MaxCalls, Endpoint, SecurityDescriptor, &policy ); -} - -/*********************************************************************** - * RpcServerUseProtseqEpW (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcServerUseProtseqEpW( RPC_WSTR Protseq, UINT MaxCalls, RPC_WSTR Endpoint, LPVOID SecurityDescriptor ) -{ - RPC_POLICY policy; - - TRACE( "(%s,%u,%s,%p)\n", debugstr_w( Protseq ), MaxCalls, debugstr_w( Endpoint ), SecurityDescriptor ); - - /* This should provide the default behaviour */ - policy.Length = sizeof( policy ); - policy.EndpointFlags = 0; - policy.NICFlags = 0; - - return RpcServerUseProtseqEpExW( Protseq, MaxCalls, Endpoint, SecurityDescriptor, &policy ); -} - -/*********************************************************************** - * alloc_serverprotoseq (internal) - * - * Must be called with server_cs held. - */ -static RPC_STATUS alloc_serverprotoseq(UINT MaxCalls, char *Protseq, RpcServerProtseq **ps) -{ - const struct protseq_ops *ops = rpcrt4_get_protseq_ops(Protseq); - - if (!ops) - { - FIXME("protseq %s not supported\n", debugstr_a(Protseq)); - return RPC_S_PROTSEQ_NOT_SUPPORTED; - } - - *ps = ops->alloc(); - if (!*ps) - return RPC_S_OUT_OF_RESOURCES; - (*ps)->MaxCalls = MaxCalls; - (*ps)->Protseq = Protseq; - (*ps)->ops = ops; - (*ps)->MaxCalls = 0; - (*ps)->conn = NULL; - InitializeCriticalSection(&(*ps)->cs); - (*ps)->is_listening = FALSE; - (*ps)->mgr_mutex = NULL; - (*ps)->server_ready_event = NULL; - - list_add_head(&protseqs, &(*ps)->entry); - - TRACE("new protseq %p created for %s\n", *ps, Protseq); - - return RPC_S_OK; -} - -/* Finds a given protseq or creates a new one if one doesn't already exist */ -static RPC_STATUS RPCRT4_get_or_create_serverprotseq(UINT MaxCalls, char *Protseq, RpcServerProtseq **ps) -{ - RPC_STATUS status; - RpcServerProtseq *cps; - - EnterCriticalSection(&server_cs); - - LIST_FOR_EACH_ENTRY(cps, &protseqs, RpcServerProtseq, entry) - if (!strcmp(cps->Protseq, Protseq)) - { - TRACE("found existing protseq object for %s\n", Protseq); - *ps = cps; - LeaveCriticalSection(&server_cs); - return S_OK; - } - - status = alloc_serverprotoseq(MaxCalls, Protseq, ps); - - LeaveCriticalSection(&server_cs); - - return status; -} - -/*********************************************************************** - * RpcServerUseProtseqEpExA (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcServerUseProtseqEpExA( RPC_CSTR Protseq, UINT MaxCalls, RPC_CSTR Endpoint, LPVOID SecurityDescriptor, - PRPC_POLICY lpPolicy ) -{ - char *szps = (char*)Protseq, *szep = (char*)Endpoint; - RpcServerProtseq* ps; - RPC_STATUS status; - - TRACE("(%s,%u,%s,%p,{%u,%lu,%lu})\n", debugstr_a(szps), MaxCalls, - debugstr_a(szep), SecurityDescriptor, - lpPolicy->Length, lpPolicy->EndpointFlags, lpPolicy->NICFlags ); - - status = RPCRT4_get_or_create_serverprotseq(MaxCalls, RPCRT4_strdupA(szps), &ps); - if (status != RPC_S_OK) - return status; - - return RPCRT4_use_protseq(ps, szep); -} - -/*********************************************************************** - * RpcServerUseProtseqEpExW (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcServerUseProtseqEpExW( RPC_WSTR Protseq, UINT MaxCalls, RPC_WSTR Endpoint, LPVOID SecurityDescriptor, - PRPC_POLICY lpPolicy ) -{ - RpcServerProtseq* ps; - RPC_STATUS status; - LPSTR EndpointA; - - TRACE("(%s,%u,%s,%p,{%u,%lu,%lu})\n", debugstr_w( Protseq ), MaxCalls, - debugstr_w( Endpoint ), SecurityDescriptor, - lpPolicy->Length, lpPolicy->EndpointFlags, lpPolicy->NICFlags ); - - status = RPCRT4_get_or_create_serverprotseq(MaxCalls, RPCRT4_strdupWtoA(Protseq), &ps); - if (status != RPC_S_OK) - return status; - - EndpointA = RPCRT4_strdupWtoA(Endpoint); - status = RPCRT4_use_protseq(ps, EndpointA); - RPCRT4_strfree(EndpointA); - return status; -} - -/*********************************************************************** - * RpcServerUseProtseqA (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcServerUseProtseqA(RPC_CSTR Protseq, unsigned int MaxCalls, void *SecurityDescriptor) -{ - TRACE("(Protseq == %s, MaxCalls == %d, SecurityDescriptor == ^%p)\n", debugstr_a((char*)Protseq), MaxCalls, SecurityDescriptor); - return RpcServerUseProtseqEpA(Protseq, MaxCalls, NULL, SecurityDescriptor); -} - -/*********************************************************************** - * RpcServerUseProtseqW (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcServerUseProtseqW(RPC_WSTR Protseq, unsigned int MaxCalls, void *SecurityDescriptor) -{ - TRACE("Protseq == %s, MaxCalls == %d, SecurityDescriptor == ^%p)\n", debugstr_w(Protseq), MaxCalls, SecurityDescriptor); - return RpcServerUseProtseqEpW(Protseq, MaxCalls, NULL, SecurityDescriptor); -} - -/*********************************************************************** - * RpcServerRegisterIf (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcServerRegisterIf( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, RPC_MGR_EPV* MgrEpv ) -{ - TRACE("(%p,%s,%p)\n", IfSpec, debugstr_guid(MgrTypeUuid), MgrEpv); - return RpcServerRegisterIf2( IfSpec, MgrTypeUuid, MgrEpv, 0, RPC_C_LISTEN_MAX_CALLS_DEFAULT, (UINT)-1, NULL ); -} - -/*********************************************************************** - * RpcServerRegisterIfEx (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcServerRegisterIfEx( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, RPC_MGR_EPV* MgrEpv, - UINT Flags, UINT MaxCalls, RPC_IF_CALLBACK_FN* IfCallbackFn ) -{ - TRACE("(%p,%s,%p,%u,%u,%p)\n", IfSpec, debugstr_guid(MgrTypeUuid), MgrEpv, Flags, MaxCalls, IfCallbackFn); - return RpcServerRegisterIf2( IfSpec, MgrTypeUuid, MgrEpv, Flags, MaxCalls, (UINT)-1, IfCallbackFn ); -} - -/*********************************************************************** - * RpcServerRegisterIf2 (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcServerRegisterIf2( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, RPC_MGR_EPV* MgrEpv, - UINT Flags, UINT MaxCalls, UINT MaxRpcSize, RPC_IF_CALLBACK_FN* IfCallbackFn ) -{ - PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec; - RpcServerInterface* sif; - unsigned int i; - - TRACE("(%p,%s,%p,%u,%u,%u,%p)\n", IfSpec, debugstr_guid(MgrTypeUuid), MgrEpv, Flags, MaxCalls, - MaxRpcSize, IfCallbackFn); - TRACE(" interface id: %s %d.%d\n", debugstr_guid(&If->InterfaceId.SyntaxGUID), - If->InterfaceId.SyntaxVersion.MajorVersion, - If->InterfaceId.SyntaxVersion.MinorVersion); - TRACE(" transfer syntax: %s %d.%d\n", debugstr_guid(&If->TransferSyntax.SyntaxGUID), - If->TransferSyntax.SyntaxVersion.MajorVersion, - If->TransferSyntax.SyntaxVersion.MinorVersion); - TRACE(" dispatch table: %p\n", If->DispatchTable); - if (If->DispatchTable) { - TRACE(" dispatch table count: %d\n", If->DispatchTable->DispatchTableCount); - for (i=0; iDispatchTable->DispatchTableCount; i++) { - TRACE(" entry %d: %p\n", i, If->DispatchTable->DispatchTable[i]); - } - TRACE(" reserved: %ld\n", If->DispatchTable->Reserved); - } - TRACE(" protseq endpoint count: %d\n", If->RpcProtseqEndpointCount); - TRACE(" default manager epv: %p\n", If->DefaultManagerEpv); - TRACE(" interpreter info: %p\n", If->InterpreterInfo); - - sif = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RpcServerInterface)); - sif->If = If; - if (MgrTypeUuid) { - memcpy(&sif->MgrTypeUuid, MgrTypeUuid, sizeof(UUID)); - sif->MgrEpv = MgrEpv; - } else { - memset(&sif->MgrTypeUuid, 0, sizeof(UUID)); - sif->MgrEpv = If->DefaultManagerEpv; - } - sif->Flags = Flags; - sif->MaxCalls = MaxCalls; - sif->MaxRpcSize = MaxRpcSize; - sif->IfCallbackFn = IfCallbackFn; - - EnterCriticalSection(&server_cs); - list_add_head(&server_interfaces, &sif->entry); - LeaveCriticalSection(&server_cs); - - if (sif->Flags & RPC_IF_AUTOLISTEN) - RPCRT4_start_listen(TRUE); - - return RPC_S_OK; -} - -/*********************************************************************** - * RpcServerUnregisterIf (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcServerUnregisterIf( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, UINT WaitForCallsToComplete ) -{ - PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec; - HANDLE event = NULL; - BOOL found = FALSE; - BOOL completed = TRUE; - RpcServerInterface *cif; - RPC_STATUS status; - - TRACE("(IfSpec == (RPC_IF_HANDLE)^%p (%s), MgrTypeUuid == %s, WaitForCallsToComplete == %u)\n", - IfSpec, debugstr_guid(&If->InterfaceId.SyntaxGUID), debugstr_guid(MgrTypeUuid), WaitForCallsToComplete); - - EnterCriticalSection(&server_cs); - LIST_FOR_EACH_ENTRY(cif, &server_interfaces, RpcServerInterface, entry) { - if ((!IfSpec || !memcmp(&If->InterfaceId, &cif->If->InterfaceId, sizeof(RPC_SYNTAX_IDENTIFIER))) && - UuidEqual(MgrTypeUuid, &cif->MgrTypeUuid, &status)) { - list_remove(&cif->entry); - if (cif->CurrentCalls) { - completed = FALSE; - if (WaitForCallsToComplete) - cif->CallsCompletedEvent = event = CreateEventW(NULL, FALSE, FALSE, NULL); - } - found = TRUE; - break; - } - } - LeaveCriticalSection(&server_cs); - - if (!found) { - ERR("not found for object %s\n", debugstr_guid(MgrTypeUuid)); - return RPC_S_UNKNOWN_IF; - } - - if (completed) - HeapFree(GetProcessHeap(), 0, cif); - else if (event) { - /* sif will be freed when the last call is completed, so be careful not to - * touch that memory here as that could happen before we get here */ - WaitForSingleObject(event, INFINITE); - CloseHandle(event); - } - - return RPC_S_OK; -} - -/*********************************************************************** - * RpcServerUnregisterIfEx (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcServerUnregisterIfEx( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, int RundownContextHandles ) -{ - FIXME("(IfSpec == (RPC_IF_HANDLE)^%p, MgrTypeUuid == %s, RundownContextHandles == %d): stub\n", - IfSpec, debugstr_guid(MgrTypeUuid), RundownContextHandles); - - return RPC_S_OK; -} - -/*********************************************************************** - * RpcObjectSetType (RPCRT4.@) - * - * PARAMS - * ObjUuid [I] "Object" UUID - * TypeUuid [I] "Type" UUID - * - * RETURNS - * RPC_S_OK The call succeeded - * RPC_S_INVALID_OBJECT The provided object (nil) is not valid - * RPC_S_ALREADY_REGISTERED The provided object is already registered - * - * Maps "Object" UUIDs to "Type" UUID's. Passing the nil UUID as the type - * resets the mapping for the specified object UUID to nil (the default). - * The nil object is always associated with the nil type and cannot be - * reassigned. Servers can support multiple implementations on the same - * interface by registering different end-point vectors for the different - * types. There's no need to call this if a server only supports the nil - * type, as is typical. - */ -RPC_STATUS WINAPI RpcObjectSetType( UUID* ObjUuid, UUID* TypeUuid ) -{ - RpcObjTypeMap *map = RpcObjTypeMaps, *prev = NULL; - RPC_STATUS dummy; - - TRACE("(ObjUUID == %s, TypeUuid == %s).\n", debugstr_guid(ObjUuid), debugstr_guid(TypeUuid)); - if ((! ObjUuid) || UuidIsNil(ObjUuid, &dummy)) { - /* nil uuid cannot be remapped */ - return RPC_S_INVALID_OBJECT; - } - - /* find the mapping for this object if there is one ... */ - while (map) { - if (! UuidCompare(ObjUuid, &map->Object, &dummy)) break; - prev = map; - map = map->next; - } - if ((! TypeUuid) || UuidIsNil(TypeUuid, &dummy)) { - /* ... and drop it from the list */ - if (map) { - if (prev) - prev->next = map->next; - else - RpcObjTypeMaps = map->next; - HeapFree(GetProcessHeap(), 0, map); - } - } else { - /* ... , fail if we found it ... */ - if (map) - return RPC_S_ALREADY_REGISTERED; - /* ... otherwise create a new one and add it in. */ - map = HeapAlloc(GetProcessHeap(), 0, sizeof(RpcObjTypeMap)); - memcpy(&map->Object, ObjUuid, sizeof(UUID)); - memcpy(&map->Type, TypeUuid, sizeof(UUID)); - map->next = NULL; - if (prev) - prev->next = map; /* prev is the last map in the linklist */ - else - RpcObjTypeMaps = map; - } - - return RPC_S_OK; -} - -/*********************************************************************** - * RpcServerRegisterAuthInfoA (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcServerRegisterAuthInfoA( RPC_CSTR ServerPrincName, ULONG AuthnSvc, RPC_AUTH_KEY_RETRIEVAL_FN GetKeyFn, - LPVOID Arg ) -{ - FIXME( "(%s,%u,%p,%p): stub\n", ServerPrincName, AuthnSvc, GetKeyFn, Arg ); - - return RPC_S_UNKNOWN_AUTHN_SERVICE; /* We don't know any authentication services */ -} - -/*********************************************************************** - * RpcServerRegisterAuthInfoW (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcServerRegisterAuthInfoW( RPC_WSTR ServerPrincName, ULONG AuthnSvc, RPC_AUTH_KEY_RETRIEVAL_FN GetKeyFn, - LPVOID Arg ) -{ - FIXME( "(%s,%u,%p,%p): stub\n", debugstr_w( ServerPrincName ), AuthnSvc, GetKeyFn, Arg ); - - return RPC_S_UNKNOWN_AUTHN_SERVICE; /* We don't know any authentication services */ -} - -/*********************************************************************** - * RpcServerListen (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcServerListen( UINT MinimumCallThreads, UINT MaxCalls, UINT DontWait ) -{ - RPC_STATUS status = RPC_S_OK; - - TRACE("(%u,%u,%u)\n", MinimumCallThreads, MaxCalls, DontWait); - - if (list_empty(&protseqs)) - return RPC_S_NO_PROTSEQS_REGISTERED; - - status = RPCRT4_start_listen(FALSE); - - if (DontWait || (status != RPC_S_OK)) return status; - - return RpcMgmtWaitServerListen(); -} - -/*********************************************************************** - * RpcMgmtServerWaitListen (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcMgmtWaitServerListen( void ) -{ - RpcServerProtseq *cps; - - EnterCriticalSection(&listen_cs); - - if (!std_listen) { - LeaveCriticalSection(&listen_cs); - return RPC_S_NOT_LISTENING; - } - - do - { - LeaveCriticalSection(&listen_cs); - - LIST_FOR_EACH_ENTRY(cps, &protseqs, RpcServerProtseq, entry) - WaitForSingleObject(cps->server_ready_event, INFINITE); - - EnterCriticalSection(&listen_cs); - } while (!std_listen); - - LeaveCriticalSection(&listen_cs); - - return RPC_S_OK; -} - -/*********************************************************************** - * RpcMgmtStopServerListening (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcMgmtStopServerListening ( RPC_BINDING_HANDLE Binding ) -{ - TRACE("(Binding == (RPC_BINDING_HANDLE)^%p)\n", Binding); - - if (Binding) { - FIXME("client-side invocation not implemented.\n"); - return RPC_S_WRONG_KIND_OF_BINDING; - } - - RPCRT4_stop_listen(FALSE); - - return RPC_S_OK; -} - -/*********************************************************************** - * RpcMgmtEnableIdleCleanup (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcMgmtEnableIdleCleanup(void) -{ - FIXME("(): stub\n"); - return RPC_S_OK; -} - -/*********************************************************************** - * I_RpcServerStartListening (RPCRT4.@) - */ -RPC_STATUS WINAPI I_RpcServerStartListening( HWND hWnd ) -{ - FIXME( "(%p): stub\n", hWnd ); - - return RPC_S_OK; -} - -/*********************************************************************** - * I_RpcServerStopListening (RPCRT4.@) - */ -RPC_STATUS WINAPI I_RpcServerStopListening( void ) -{ - FIXME( "(): stub\n" ); - - return RPC_S_OK; -} - -/*********************************************************************** - * I_RpcWindowProc (RPCRT4.@) - */ -UINT WINAPI I_RpcWindowProc( void *hWnd, UINT Message, UINT wParam, ULONG lParam ) -{ - FIXME( "(%p,%08x,%08x,%08x): stub\n", hWnd, Message, wParam, lParam ); - - return 0; -} - -/*********************************************************************** - * RpcMgmtInqIfIds (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcMgmtInqIfIds(RPC_BINDING_HANDLE Binding, RPC_IF_ID_VECTOR **IfIdVector) -{ - FIXME("(%p,%p): stub\n", Binding, IfIdVector); - return RPC_S_INVALID_BINDING; -} - -/*********************************************************************** - * RpcMgmtEpEltInqBegin (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcMgmtEpEltInqBegin(RPC_BINDING_HANDLE Binding, ULONG InquiryType, - RPC_IF_ID *IfId, ULONG VersOption, UUID *ObjectUuid, RPC_EP_INQ_HANDLE* InquiryContext) -{ - FIXME("(%p,%u,%p,%u,%p,%p): stub\n", - Binding, InquiryType, IfId, VersOption, ObjectUuid, InquiryContext); - return RPC_S_INVALID_BINDING; -} - -/*********************************************************************** - * RpcMgmtIsServerListening (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcMgmtIsServerListening(RPC_BINDING_HANDLE Binding) -{ - FIXME("(%p): stub\n", Binding); - return RPC_S_INVALID_BINDING; -} - -/*********************************************************************** - * RpcMgmtSetServerStackSize (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcMgmtSetServerStackSize(ULONG ThreadStackSize) -{ - FIXME("(0x%x): stub\n", ThreadStackSize); - return RPC_S_OK; -} - -/*********************************************************************** - * I_RpcGetCurrentCallHandle (RPCRT4.@) - */ -RPC_BINDING_HANDLE WINAPI I_RpcGetCurrentCallHandle(void) -{ - TRACE("\n"); - return RPCRT4_GetThreadCurrentCallHandle(); -} diff --git a/reactos/dll/win32/rpcrt4_new/rpc_server.h b/reactos/dll/win32/rpcrt4_new/rpc_server.h deleted file mode 100644 index eb32be6afc9..00000000000 --- a/reactos/dll/win32/rpcrt4_new/rpc_server.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * RPC server API - * - * Copyright 2001 Ove Kåven, TransGaming Technologies - * - * 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 - */ - -#ifndef __WINE_RPC_SERVER_H -#define __WINE_RPC_SERVER_H - -#include "rpc_binding.h" -#include "wine/list.h" - -struct protseq_ops; - -typedef struct _RpcServerProtseq -{ - const struct protseq_ops *ops; /* RO */ - struct list entry; /* CS ::server_cs */ - LPSTR Protseq; /* RO */ - UINT MaxCalls; /* RO */ - /* list of listening connections */ - RpcConnection* conn; /* CS cs */ - CRITICAL_SECTION cs; - - /* is the server currently listening? */ - BOOL is_listening; /* CS ::listen_cs */ - /* mutex for ensuring only one thread can change state at a time */ - HANDLE mgr_mutex; - /* set when server thread has finished opening connections */ - HANDLE server_ready_event; -} RpcServerProtseq; - -struct protseq_ops -{ - const char *name; - RpcServerProtseq *(*alloc)(void); - void (*signal_state_changed)(RpcServerProtseq *protseq); - /* previous array is passed in to allow reuse of memory */ - void *(*get_wait_array)(RpcServerProtseq *protseq, void *prev_array, unsigned int *count); - void (*free_wait_array)(RpcServerProtseq *protseq, void *array); - /* returns -1 for failure, 0 for server state changed and 1 to indicate a - * new connection was established */ - int (*wait_for_new_connection)(RpcServerProtseq *protseq, unsigned int count, void *wait_array); - /* opens the endpoint and optionally begins listening */ - RPC_STATUS (*open_endpoint)(RpcServerProtseq *protseq, LPSTR endpoint); -}; - -typedef struct _RpcServerInterface -{ - struct list entry; - RPC_SERVER_INTERFACE* If; - UUID MgrTypeUuid; - RPC_MGR_EPV* MgrEpv; - UINT Flags; - UINT MaxCalls; - UINT MaxRpcSize; - RPC_IF_CALLBACK_FN* IfCallbackFn; - LONG CurrentCalls; /* number of calls currently executing */ - /* set when unregistering interface to let the caller of - * RpcServerUnregisterIf* know that all calls have finished */ - HANDLE CallsCompletedEvent; -} RpcServerInterface; - -void RPCRT4_new_client(RpcConnection* conn); -const struct protseq_ops *rpcrt4_get_protseq_ops(const char *protseq); - -#endif /* __WINE_RPC_SERVER_H */ diff --git a/reactos/dll/win32/rpcrt4_new/rpcrt4.rbuild b/reactos/dll/win32/rpcrt4_new/rpcrt4.rbuild deleted file mode 100644 index fa6f46b15eb..00000000000 --- a/reactos/dll/win32/rpcrt4_new/rpcrt4.rbuild +++ /dev/null @@ -1,43 +0,0 @@ - - - - . - include/reactos/wine - - - 0x600 - 0x501 - 0x501 - - - - - wine - uuid - ntdll - kernel32 - advapi32 - secur32 - iphlpapi - ws2_32 - cproxy.c - cpsf.c - cstub.c - ndr_contexthandle.c - ndr_clientserver.c - ndr_fullpointer.c - ndr_marshall.c - ndr_ole.c - ndr_stubless.c - rpc_assoc.c - rpc_binding.c - rpc_epmap.c - rpc_message.c - rpc_server.c - rpc_transport.c - rpcrt4_main.c - rpcss_np_client.c - unix_func.c - rpcrt4.rc - rpcrt4.spec - diff --git a/reactos/dll/win32/rpcrt4_new/rpcrt4.rc b/reactos/dll/win32/rpcrt4_new/rpcrt4.rc deleted file mode 100644 index 446318060a7..00000000000 --- a/reactos/dll/win32/rpcrt4_new/rpcrt4.rc +++ /dev/null @@ -1,7 +0,0 @@ -#include - -#define REACTOS_VERSION_DLL -#define REACTOS_STR_FILE_DESCRIPTION "ReactOS RPC server API\0" -#define REACTOS_STR_INTERNAL_NAME "rpcrt4\0" -#define REACTOS_STR_ORIGINAL_FILENAME "rpcrt4.dll\0" -#include diff --git a/reactos/dll/win32/rpcrt4_new/rpcrt4.spec b/reactos/dll/win32/rpcrt4_new/rpcrt4.spec deleted file mode 100644 index 93f6d318e46..00000000000 --- a/reactos/dll/win32/rpcrt4_new/rpcrt4.spec +++ /dev/null @@ -1,565 +0,0 @@ -@ stdcall CreateProxyFromTypeInfo(ptr ptr ptr ptr ptr) -@ stub CreateStubFromTypeInfo -@ stdcall CStdStubBuffer_AddRef(ptr) -@ stdcall CStdStubBuffer_Connect(ptr ptr) -@ stdcall CStdStubBuffer_CountRefs(ptr) -@ stdcall CStdStubBuffer_DebugServerQueryInterface(ptr ptr) -@ stdcall CStdStubBuffer_DebugServerRelease(ptr ptr) -@ stdcall CStdStubBuffer_Disconnect(ptr) -@ stdcall CStdStubBuffer_Invoke(ptr ptr ptr) -@ stdcall CStdStubBuffer_IsIIDSupported(ptr ptr) -@ stdcall CStdStubBuffer_QueryInterface(ptr ptr ptr) -@ stub CreateServerInterfaceFromStub # wxp -@ stdcall DceErrorInqTextA (long ptr) -@ stdcall DceErrorInqTextW (long ptr) -@ stdcall -private DllRegisterServer() -@ stub GlobalMutexClearExternal -@ stub GlobalMutexRequestExternal -@ stdcall IUnknown_AddRef_Proxy(ptr) -@ stdcall IUnknown_QueryInterface_Proxy(ptr ptr ptr) -@ stdcall IUnknown_Release_Proxy(ptr) -@ stub I_RpcAbortAsyncCall -@ stdcall I_RpcAllocate(long) -@ stub I_RpcAsyncAbortCall -@ stub I_RpcAsyncSendReceive # NT4 -@ stub I_RpcAsyncSetHandle -@ stub I_RpcBCacheAllocate -@ stub I_RpcBCacheFree -@ stub I_RpcBindingCopy -@ stub I_RpcBindingInqConnId -@ stub I_RpcBindingInqDynamicEndPoint -@ stub I_RpcBindingInqDynamicEndPointA -@ stub I_RpcBindingInqDynamicEndPointW -@ stub I_RpcBindingInqLocalClientPID # wxp -@ stub I_RpcBindingInqSecurityContext -@ stub I_RpcBindingInqTransportType -@ stub I_RpcBindingInqWireIdForSnego -@ stub I_RpcBindingIsClientLocal -# 9x version of I_RpcBindingSetAsync has 3 arguments, not 2 -@ stdcall I_RpcBindingSetAsync(ptr ptr) -@ stub I_RpcBindingToStaticStringBindingW -@ stub I_RpcClearMutex -@ stub I_RpcConnectionInqSockBuffSize2 -@ stub I_RpcConnectionInqSockBuffSize -@ stub I_RpcConnectionSetSockBuffSize -@ stub I_RpcDeleteMutex -@ stub I_RpcEnableWmiTrace # wxp -@ stub I_RpcExceptionFilter # wxp -@ stdcall I_RpcFree(ptr) -@ stdcall I_RpcFreeBuffer(ptr) -@ stub I_RpcFreePipeBuffer -@ stub I_RpcGetAssociationContext -@ stdcall I_RpcGetBuffer(ptr) -@ stub I_RpcGetBufferWithObject -@ stdcall I_RpcGetCurrentCallHandle() -@ stub I_RpcGetExtendedError -@ stub I_RpcGetServerContextList -@ stub I_RpcGetThreadEvent # win9x -@ stub I_RpcGetThreadWindowHandle # win9x -@ stub I_RpcIfInqTransferSyntaxes -@ stub I_RpcLaunchDatagramReceiveThread # win9x -@ stub I_RpcLogEvent -@ stdcall I_RpcMapWin32Status(long) -@ stub I_RpcMonitorAssociation -@ stub I_RpcNegotiateTransferSyntax # wxp -@ stub I_RpcNsBindingSetEntryName -@ stub I_RpcNsBindingSetEntryNameA -@ stub I_RpcNsBindingSetEntryNameW -@ stub I_RpcNsInterfaceExported -@ stub I_RpcNsInterfaceUnexported -@ stub I_RpcParseSecurity -@ stub I_RpcPauseExecution -@ stub I_RpcProxyNewConnection # wxp -@ stub I_RpcReallocPipeBuffer -@ stdcall I_RpcReceive(ptr) -@ stub I_RpcRequestMutex -@ stdcall I_RpcSend(ptr) -@ stdcall I_RpcSendReceive(ptr) -@ stub I_RpcServerAllocateIpPort -@ stub I_RpcServerInqAddressChangeFn -@ stub I_RpcServerInqLocalConnAddress # wxp -@ stub I_RpcServerInqTransportType -@ stub I_RpcServerRegisterForwardFunction -@ stub I_RpcServerSetAddressChangeFn -@ stdcall I_RpcServerStartListening(ptr) # win9x -@ stdcall I_RpcServerStopListening() # win9x -@ stub I_RpcServerUnregisterEndpointA # win9x -@ stub I_RpcServerUnregisterEndpointW # win9x -@ stub I_RpcServerUseProtseq2A -@ stub I_RpcServerUseProtseq2W -@ stub I_RpcServerUseProtseqEp2A -@ stub I_RpcServerUseProtseqEp2W -@ stub I_RpcSetAssociationContext # win9x -@ stub I_RpcSetAsyncHandle -@ stub I_RpcSetServerContextList -@ stub I_RpcSetThreadParams # win9x -@ stub I_RpcSetWMsgEndpoint # NT4 -@ stub I_RpcSsDontSerializeContext -@ stub I_RpcStopMonitorAssociation -@ stub I_RpcSystemFunction001 # wxp (oh, brother!) -@ stub I_RpcTransCancelMigration # win9x -@ stub I_RpcTransClientMaxFrag # win9x -@ stub I_RpcTransClientReallocBuffer # win9x -@ stub I_RpcTransConnectionAllocatePacket -@ stub I_RpcTransConnectionFreePacket -@ stub I_RpcTransConnectionReallocPacket -@ stub I_RpcTransDatagramAllocate2 -@ stub I_RpcTransDatagramAllocate -@ stub I_RpcTransDatagramFree -@ stub I_RpcTransGetAddressList -@ stub I_RpcTransGetThreadEvent -@ stub I_RpcTransIoCancelled -@ stub I_RpcTransMaybeMakeReceiveAny # win9x -@ stub I_RpcTransMaybeMakeReceiveDirect # win9x -@ stub I_RpcTransPingServer # win9x -@ stub I_RpcTransServerFindConnection # win9x -@ stub I_RpcTransServerFreeBuffer # win9x -@ stub I_RpcTransServerMaxFrag # win9x -@ stub I_RpcTransServerNewConnection -@ stub I_RpcTransServerProtectThread # win9x -@ stub I_RpcTransServerReallocBuffer # win9x -@ stub I_RpcTransServerReceiveDirectReady # win9x -@ stub I_RpcTransServerUnprotectThread # win9x -@ stub I_RpcTurnOnEEInfoPropagation # wxp -@ stdcall I_RpcWindowProc(ptr long long long) # win9x -@ stub I_RpcltDebugSetPDUFilter -@ stub I_UuidCreate -@ stub MIDL_wchar_strcpy -@ stub MIDL_wchar_strlen -@ stub MesBufferHandleReset -@ stub MesDecodeBufferHandleCreate -@ stub MesDecodeIncrementalHandleCreate -@ stub MesEncodeDynBufferHandleCreate -@ stub MesEncodeFixedBufferHandleCreate -@ stub MesEncodeIncrementalHandleCreate -@ stub MesHandleFree -@ stub MesIncrementalHandleReset -@ stub MesInqProcEncodingId -@ stub MqGetContext # win9x -@ stub MqRegisterQueue # win9x -@ stdcall NDRCContextBinding(ptr) -@ stdcall NDRCContextMarshall(ptr ptr) -@ stdcall NDRCContextUnmarshall(ptr ptr ptr long) -@ stdcall NDRSContextMarshall2(ptr ptr ptr ptr ptr long) -@ stdcall NDRSContextMarshall(ptr ptr ptr) -@ stdcall NDRSContextMarshallEx(ptr ptr ptr ptr) -@ stdcall NDRSContextUnmarshall2(ptr ptr ptr ptr long) -@ stdcall NDRSContextUnmarshall(ptr ptr) -@ stdcall NDRSContextUnmarshallEx(ptr ptr ptr) -@ stub NDRcopy -@ stdcall NdrAllocate(ptr long) -@ stub NdrAsyncClientCall -@ stub NdrAsyncServerCall -@ stdcall NdrByteCountPointerBufferSize(ptr ptr ptr) -@ stdcall NdrByteCountPointerFree(ptr ptr ptr) -@ stdcall NdrByteCountPointerMarshall(ptr ptr ptr) -@ stdcall NdrByteCountPointerUnmarshall(ptr ptr ptr long) -@ stdcall NdrCStdStubBuffer2_Release(ptr ptr) -@ stdcall NdrCStdStubBuffer_Release(ptr ptr) -@ stdcall NdrClearOutParameters(ptr ptr ptr) -@ varargs NdrClientCall2(ptr ptr) -@ varargs NdrClientCall(ptr ptr) NdrClientCall2 -@ stdcall NdrClientContextMarshall(ptr ptr long) -@ stdcall NdrClientContextUnmarshall(ptr ptr ptr) -@ stub NdrClientInitialize -@ stdcall NdrClientInitializeNew(ptr ptr ptr long) -@ stdcall NdrComplexArrayBufferSize(ptr ptr ptr) -@ stdcall NdrComplexArrayFree(ptr ptr ptr) -@ stdcall NdrComplexArrayMarshall(ptr ptr ptr) -@ stdcall NdrComplexArrayMemorySize(ptr ptr) -@ stdcall NdrComplexArrayUnmarshall(ptr ptr ptr long) -@ stdcall NdrComplexStructBufferSize(ptr ptr ptr) -@ stdcall NdrComplexStructFree(ptr ptr ptr) -@ stdcall NdrComplexStructMarshall(ptr ptr ptr) -@ stdcall NdrComplexStructMemorySize(ptr ptr) -@ stdcall NdrComplexStructUnmarshall(ptr ptr ptr long) -@ stdcall NdrConformantArrayBufferSize(ptr ptr ptr) -@ stdcall NdrConformantArrayFree(ptr ptr ptr) -@ stdcall NdrConformantArrayMarshall(ptr ptr ptr) -@ stdcall NdrConformantArrayMemorySize(ptr ptr) -@ stdcall NdrConformantArrayUnmarshall(ptr ptr ptr long) -@ stdcall NdrConformantStringBufferSize(ptr ptr ptr) -@ stdcall NdrConformantStringMarshall(ptr ptr ptr) -@ stdcall NdrConformantStringMemorySize(ptr ptr) -@ stdcall NdrConformantStringUnmarshall(ptr ptr ptr long) -@ stdcall NdrConformantStructBufferSize(ptr ptr ptr) -@ stdcall NdrConformantStructFree(ptr ptr ptr) -@ stdcall NdrConformantStructMarshall(ptr ptr ptr) -@ stdcall NdrConformantStructMemorySize(ptr ptr) -@ stdcall NdrConformantStructUnmarshall(ptr ptr ptr long) -@ stdcall NdrConformantVaryingArrayBufferSize(ptr ptr ptr) -@ stdcall NdrConformantVaryingArrayFree(ptr ptr ptr) -@ stdcall NdrConformantVaryingArrayMarshall(ptr ptr ptr) -@ stdcall NdrConformantVaryingArrayMemorySize(ptr ptr) -@ stdcall NdrConformantVaryingArrayUnmarshall(ptr ptr ptr long) -@ stdcall NdrConformantVaryingStructBufferSize(ptr ptr ptr) -@ stdcall NdrConformantVaryingStructFree(ptr ptr ptr) -@ stdcall NdrConformantVaryingStructMarshall(ptr ptr ptr) -@ stdcall NdrConformantVaryingStructMemorySize(ptr ptr) -@ stdcall NdrConformantVaryingStructUnmarshall(ptr ptr ptr long) -@ stdcall NdrContextHandleInitialize(ptr ptr) -@ stdcall NdrContextHandleSize(ptr ptr ptr) -@ stdcall NdrConvert2(ptr ptr long) -@ stdcall NdrConvert(ptr ptr) -@ stub NdrCorrelationFree -@ stub NdrCorrelationInitialize -@ stub NdrCorrelationPass -@ stub NdrDcomAsyncClientCall -@ stub NdrDcomAsyncStubCall -@ stdcall NdrDllCanUnloadNow(ptr) -@ stdcall NdrDllGetClassObject(ptr ptr ptr ptr ptr ptr) -@ stdcall NdrDllRegisterProxy(long ptr ptr) -@ stdcall NdrDllUnregisterProxy(long ptr ptr) -@ stdcall NdrEncapsulatedUnionBufferSize(ptr ptr ptr) -@ stdcall NdrEncapsulatedUnionFree(ptr ptr ptr) -@ stdcall NdrEncapsulatedUnionMarshall(ptr ptr ptr) -@ stdcall NdrEncapsulatedUnionMemorySize(ptr ptr) -@ stdcall NdrEncapsulatedUnionUnmarshall(ptr ptr ptr long) -@ stdcall NdrFixedArrayBufferSize(ptr ptr ptr) -@ stdcall NdrFixedArrayFree(ptr ptr ptr) -@ stdcall NdrFixedArrayMarshall(ptr ptr ptr) -@ stdcall NdrFixedArrayMemorySize(ptr ptr) -@ stdcall NdrFixedArrayUnmarshall(ptr ptr ptr long) -@ stdcall NdrFreeBuffer(ptr) -@ stdcall NdrFullPointerFree(ptr ptr) -@ stdcall NdrFullPointerInsertRefId(ptr long ptr) -@ stdcall NdrFullPointerQueryPointer(ptr ptr long ptr) -@ stdcall NdrFullPointerQueryRefId(ptr long long ptr) -@ stdcall NdrFullPointerXlatFree(ptr) -@ stdcall NdrFullPointerXlatInit(long long) -@ stdcall NdrGetBuffer(ptr long ptr) -@ stub NdrGetDcomProtocolVersion -@ stub NdrGetPartialBuffer -@ stub NdrGetPipeBuffer -@ stub NdrGetSimpleTypeBufferAlignment # wxp -@ stub NdrGetSimpleTypeBufferSize # wxp -@ stub NdrGetSimpleTypeMemorySize # wxp -@ stub NdrGetTypeFlags # wxp -@ stub NdrGetUserMarshallInfo -@ stub NdrHardStructBufferSize #(ptr ptr ptr) -@ stub NdrHardStructFree #(ptr ptr ptr) -@ stub NdrHardStructMarshall #(ptr ptr ptr) -@ stub NdrHardStructMemorySize #(ptr ptr) -@ stub NdrHardStructUnmarshall #(ptr ptr ptr long) -@ stdcall NdrInterfacePointerBufferSize(ptr ptr ptr) -@ stdcall NdrInterfacePointerFree(ptr ptr ptr) -@ stdcall NdrInterfacePointerMarshall(ptr ptr ptr) -@ stdcall NdrInterfacePointerMemorySize(ptr ptr) -@ stdcall NdrInterfacePointerUnmarshall(ptr ptr ptr long) -@ stub NdrIsAppDoneWithPipes -@ stdcall NdrMapCommAndFaultStatus(ptr ptr ptr long) -@ stub NdrMarkNextActivePipe -@ stub NdrMesProcEncodeDecode2 -@ stub NdrMesProcEncodeDecode -@ stub NdrMesSimpleTypeAlignSize -@ stub NdrMesSimpleTypeDecode -@ stub NdrMesSimpleTypeEncode -@ stub NdrMesTypeAlignSize2 -@ stub NdrMesTypeAlignSize -@ stub NdrMesTypeDecode2 -@ stub NdrMesTypeDecode -@ stub NdrMesTypeEncode2 -@ stub NdrMesTypeEncode -@ stub NdrMesTypeFree2 -@ stdcall NdrNonConformantStringBufferSize(ptr ptr ptr) -@ stdcall NdrNonConformantStringMarshall(ptr ptr ptr) -@ stdcall NdrNonConformantStringMemorySize(ptr ptr) -@ stdcall NdrNonConformantStringUnmarshall(ptr ptr ptr long) -@ stdcall NdrNonEncapsulatedUnionBufferSize(ptr ptr ptr) -@ stdcall NdrNonEncapsulatedUnionFree(ptr ptr ptr) -@ stdcall NdrNonEncapsulatedUnionMarshall(ptr ptr ptr) -@ stdcall NdrNonEncapsulatedUnionMemorySize(ptr ptr) -@ stdcall NdrNonEncapsulatedUnionUnmarshall(ptr ptr ptr long) -@ stub NdrNsGetBuffer -@ stub NdrNsSendReceive -@ stdcall NdrOleAllocate(long) -@ stdcall NdrOleFree(ptr) -@ stub NdrOutInit # wxp -@ stub NdrPartialIgnoreClientBufferSize # wxp -@ stub NdrPartialIgnoreClientMarshall # wxp -@ stub NdrPartialIgnoreServerInitialize # wxp -@ stub NdrPartialIgnoreServerUnmarshall # wxp -@ stub NdrPipePull -@ stub NdrPipePush -@ stub NdrPipeSendReceive -@ stub NdrPipesDone -@ stub NdrPipesInitialize -@ stdcall NdrPointerBufferSize(ptr ptr ptr) -@ stdcall NdrPointerFree(ptr ptr ptr) -@ stdcall NdrPointerMarshall(ptr ptr ptr) -@ stdcall NdrPointerMemorySize(ptr ptr) -@ stdcall NdrPointerUnmarshall(ptr ptr ptr long) -@ stdcall NdrProxyErrorHandler(long) -@ stdcall NdrProxyFreeBuffer(ptr ptr) -@ stdcall NdrProxyGetBuffer(ptr ptr) -@ stdcall NdrProxyInitialize(ptr ptr ptr ptr long) -@ stdcall NdrProxySendReceive(ptr ptr) -@ stdcall NdrRangeUnmarshall(ptr ptr ptr long) -@ stub NdrRpcSmClientAllocate -@ stub NdrRpcSmClientFree -@ stub NdrRpcSmSetClientToOsf -@ stub NdrRpcSsDefaultAllocate -@ stub NdrRpcSsDefaultFree -@ stub NdrRpcSsDisableAllocate -@ stub NdrRpcSsEnableAllocate -@ stdcall NdrSendReceive(ptr ptr) -@ stdcall NdrServerCall2(ptr) -@ stub NdrServerCall -@ stdcall NdrServerContextMarshall(ptr ptr long) -@ stdcall NdrServerContextNewMarshall(ptr ptr ptr ptr) # wxp -@ stdcall NdrServerContextNewUnmarshall(ptr ptr) # wxp -@ stdcall NdrServerContextUnmarshall(ptr) -@ stub NdrServerInitialize -@ stub NdrServerInitializeMarshall -@ stdcall NdrServerInitializeNew(ptr ptr ptr) -@ stub NdrServerInitializePartial # wxp -@ stub NdrServerInitializeUnmarshall -@ stub NdrServerMarshall -@ stub NdrServerUnmarshall -@ stdcall NdrSimpleStructBufferSize(ptr ptr ptr) -@ stdcall NdrSimpleStructFree(ptr ptr ptr) -@ stdcall NdrSimpleStructMarshall(ptr ptr ptr) -@ stdcall NdrSimpleStructMemorySize(ptr ptr) -@ stdcall NdrSimpleStructUnmarshall(ptr ptr ptr long) -@ stdcall NdrSimpleTypeMarshall(ptr ptr long) -@ stdcall NdrSimpleTypeUnmarshall(ptr ptr long) -@ stdcall NdrStubCall2(ptr ptr ptr ptr) -@ stub NdrStubCall -@ stdcall NdrStubForwardingFunction(ptr ptr ptr ptr) -@ stdcall NdrStubGetBuffer(ptr ptr ptr) -@ stdcall NdrStubInitialize(ptr ptr ptr ptr) -@ stub NdrStubInitializeMarshall -@ stub NdrTypeFlags # wxp -@ stub NdrTypeFree # wxp -@ stub NdrTypeMarshall # wxp -@ stub NdrTypeSize # wxp -@ stub NdrTypeUnmarshall # wxp -@ stub NdrUnmarshallBasetypeInline # wxp -@ stdcall NdrUserMarshalBufferSize(ptr ptr ptr) -@ stdcall NdrUserMarshalFree(ptr ptr ptr) -@ stdcall NdrUserMarshalMarshall(ptr ptr ptr) -@ stdcall NdrUserMarshalMemorySize(ptr ptr) -@ stub NdrUserMarshalSimpleTypeConvert -@ stdcall NdrUserMarshalUnmarshall(ptr ptr ptr long) -@ stdcall NdrVaryingArrayBufferSize(ptr ptr ptr) -@ stdcall NdrVaryingArrayFree(ptr ptr ptr) -@ stdcall NdrVaryingArrayMarshall(ptr ptr ptr) -@ stdcall NdrVaryingArrayMemorySize(ptr ptr) -@ stdcall NdrVaryingArrayUnmarshall(ptr ptr ptr long) -@ stdcall NdrXmitOrRepAsBufferSize(ptr ptr ptr) -@ stdcall NdrXmitOrRepAsFree(ptr ptr ptr) -@ stdcall NdrXmitOrRepAsMarshall(ptr ptr ptr) -@ stdcall NdrXmitOrRepAsMemorySize(ptr ptr) -@ stdcall NdrXmitOrRepAsUnmarshall(ptr ptr ptr long) -@ stub NdrpCreateProxy # wxp -@ stub NdrpCreateStub # wxp -@ stub NdrpGetProcFormatString # wxp -@ stub NdrpGetTypeFormatString # wxp -@ stub NdrpGetTypeGenCookie # wxp -@ stub NdrpMemoryIncrement # wxp -@ stub NdrpReleaseTypeFormatString # wxp -@ stub NdrpReleaseTypeGenCookie # wxp -@ stub NdrpSetRpcSsDefaults -@ stub NdrpVarVtOfTypeDesc # wxp -@ stub PerformRpcInitialization -@ stub RpcAbortAsyncCall -@ stub RpcAsyncAbortCall -@ stub RpcAsyncCancelCall -@ stub RpcAsyncCompleteCall -@ stub RpcAsyncGetCallStatus -@ stub RpcAsyncInitializeHandle -@ stub RpcAsyncRegisterInfo -@ stdcall RpcBindingCopy(ptr ptr) -@ stdcall RpcBindingFree(ptr) -@ stdcall RpcBindingFromStringBindingA(str ptr) -@ stdcall RpcBindingFromStringBindingW(wstr ptr) -@ stub RpcBindingInqAuthClientA -@ stub RpcBindingInqAuthClientExA -@ stub RpcBindingInqAuthClientExW -@ stub RpcBindingInqAuthClientW -@ stdcall RpcBindingInqAuthInfoA(ptr ptr ptr ptr ptr ptr) -@ stdcall RpcBindingInqAuthInfoExA(ptr ptr ptr ptr ptr ptr long ptr) -@ stdcall RpcBindingInqAuthInfoExW(ptr ptr ptr ptr ptr ptr long ptr) -@ stdcall RpcBindingInqAuthInfoW(ptr ptr ptr ptr ptr ptr) -@ stdcall RpcBindingInqObject(ptr ptr) -@ stub RpcBindingInqOption -@ stub RpcBindingReset -@ stub RpcBindingServerFromClient -@ stdcall RpcBindingSetAuthInfoA(ptr str long long ptr long) -@ stdcall RpcBindingSetAuthInfoExA(ptr str long long ptr long ptr) -@ stdcall RpcBindingSetAuthInfoExW(ptr wstr long long ptr long ptr) -@ stdcall RpcBindingSetAuthInfoW(ptr wstr long long ptr long) -@ stdcall RpcBindingSetObject(ptr ptr) -@ stdcall RpcBindingSetOption(ptr long long) -@ stdcall RpcBindingToStringBindingA(ptr ptr) -@ stdcall RpcBindingToStringBindingW(ptr ptr) -@ stdcall RpcBindingVectorFree(ptr) -@ stub RpcCancelAsyncCall -@ stdcall RpcCancelThread(ptr) -@ stub RpcCancelThreadEx -@ stub RpcCertGeneratePrincipalNameA -@ stub RpcCertGeneratePrincipalNameW -@ stub RpcCompleteAsyncCall -@ stdcall RpcEpRegisterA(ptr ptr ptr str) -@ stub RpcEpRegisterNoReplaceA -@ stub RpcEpRegisterNoReplaceW -@ stub RpcEpRegisterW -@ stdcall RpcEpResolveBinding(ptr ptr) -@ stdcall RpcEpUnregister(ptr ptr ptr) -@ stub RpcErrorAddRecord # wxp -@ stub RpcErrorClearInformation # wxp -@ stub RpcErrorEndEnumeration # wxp -@ stub RpcErrorGetNextRecord # wxp -@ stub RpcErrorLoadErrorInfo # wxp -@ stub RpcErrorNumberOfRecords # wxp -@ stub RpcErrorResetEnumeration # wxp -@ stub RpcErrorSaveErrorInfo # wxp -@ stdcall RpcErrorStartEnumeration(ptr) -@ stub RpcFreeAuthorizationContext # wxp -@ stub RpcGetAsyncCallStatus -@ stub RpcIfIdVectorFree -@ stub RpcIfInqId -@ stdcall RpcImpersonateClient(ptr) -@ stub RpcInitializeAsyncHandle -@ stub RpcMgmtBindingInqParameter # win9x -@ stub RpcMgmtBindingSetParameter # win9x -@ stdcall RpcMgmtEnableIdleCleanup() -@ stdcall RpcMgmtEpEltInqBegin(ptr long ptr long ptr ptr) -@ stub RpcMgmtEpEltInqDone -@ stub RpcMgmtEpEltInqNextA -@ stub RpcMgmtEpEltInqNextW -@ stub RpcMgmtEpUnregister -@ stub RpcMgmtInqComTimeout -@ stub RpcMgmtInqDefaultProtectLevel -@ stdcall RpcMgmtInqIfIds(ptr ptr) -@ stub RpcMgmtInqParameter # win9x -@ stub RpcMgmtInqServerPrincNameA -@ stub RpcMgmtInqServerPrincNameW -@ stub RpcMgmtInqStats -@ stdcall RpcMgmtIsServerListening(ptr) -@ stub RpcMgmtSetAuthorizationFn -@ stdcall RpcMgmtSetCancelTimeout(long) -@ stdcall RpcMgmtSetComTimeout(ptr long) -@ stub RpcMgmtSetParameter # win9x -@ stdcall RpcMgmtSetServerStackSize(long) -@ stub RpcMgmtStatsVectorFree -@ stdcall RpcMgmtStopServerListening(ptr) -@ stdcall RpcMgmtWaitServerListen() -@ stub RpcNetworkInqProtseqsA -@ stub RpcNetworkInqProtseqsW -@ stdcall RpcNetworkIsProtseqValidA(ptr) -@ stdcall RpcNetworkIsProtseqValidW(ptr) -@ stub RpcNsBindingInqEntryNameA -@ stub RpcNsBindingInqEntryNameW -@ stub RpcObjectInqType -@ stub RpcObjectSetInqFn -@ stdcall RpcObjectSetType(ptr ptr) -@ stub RpcProtseqVectorFreeA -@ stub RpcProtseqVectorFreeW -@ stdcall RpcRaiseException(long) -@ stub RpcRegisterAsyncInfo -@ stdcall RpcRevertToSelf() -@ stdcall RpcRevertToSelfEx(ptr) -@ stdcall RpcServerInqBindings(ptr) -@ stub RpcServerInqCallAttributesA # wxp -@ stub RpcServerInqCallAttributesW # wxp -@ stub RpcServerInqDefaultPrincNameA -@ stub RpcServerInqDefaultPrincNameW -@ stub RpcServerInqIf -@ stdcall RpcServerListen(long long long) -@ stdcall RpcServerRegisterAuthInfoA(str long ptr ptr) -@ stdcall RpcServerRegisterAuthInfoW(wstr long ptr ptr) -@ stdcall RpcServerRegisterIf2(ptr ptr ptr long long long ptr) -@ stdcall RpcServerRegisterIf(ptr ptr ptr) -@ stdcall RpcServerRegisterIfEx(ptr ptr ptr long long ptr) -@ stub RpcServerTestCancel -@ stdcall RpcServerUnregisterIf(ptr ptr long) -@ stdcall RpcServerUnregisterIfEx(ptr ptr long) -@ stub RpcServerUseAllProtseqs -@ stub RpcServerUseAllProtseqsEx -@ stub RpcServerUseAllProtseqsIf -@ stub RpcServerUseAllProtseqsIfEx -@ stdcall RpcServerUseProtseqA(str long ptr) -@ stdcall RpcServerUseProtseqEpA(str long str ptr) -@ stdcall RpcServerUseProtseqEpExA(str long str ptr ptr) -@ stdcall RpcServerUseProtseqEpExW(wstr long wstr ptr ptr) -@ stdcall RpcServerUseProtseqEpW(wstr long wstr ptr) -@ stub RpcServerUseProtseqExA -@ stub RpcServerUseProtseqExW -@ stub RpcServerUseProtseqIfA -@ stub RpcServerUseProtseqIfExA -@ stub RpcServerUseProtseqIfExW -@ stub RpcServerUseProtseqIfW -@ stdcall RpcServerUseProtseqW(wstr long ptr) -@ stub RpcServerYield -@ stub RpcSmAllocate -@ stub RpcSmClientFree -@ stdcall RpcSmDestroyClientContext(ptr) -@ stub RpcSmDisableAllocate -@ stub RpcSmEnableAllocate -@ stub RpcSmFree -@ stub RpcSmGetThreadHandle -@ stub RpcSmSetClientAllocFree -@ stub RpcSmSetThreadHandle -@ stub RpcSmSwapClientAllocFree -@ stub RpcSsAllocate -@ stub RpcSsContextLockExclusive # wxp -@ stub RpcSsContextLockShared # wxp -@ stdcall RpcSsDestroyClientContext(ptr) -@ stub RpcSsDisableAllocate -@ stub RpcSsDontSerializeContext -@ stub RpcSsEnableAllocate -@ stub RpcSsFree -@ stub RpcSsGetContextBinding -@ stub RpcSsGetThreadHandle -@ stub RpcSsSetClientAllocFree -@ stub RpcSsSetThreadHandle -@ stub RpcSsSwapClientAllocFree -@ stdcall RpcStringBindingComposeA(str str str str str ptr) -@ stdcall RpcStringBindingComposeW(wstr wstr wstr wstr wstr ptr) -@ stdcall RpcStringBindingParseA(str ptr ptr ptr ptr ptr) -@ stdcall RpcStringBindingParseW(wstr ptr ptr ptr ptr ptr) -@ stdcall RpcStringFreeA(ptr) -@ stdcall RpcStringFreeW(ptr) -@ stub RpcTestCancel -@ stub RpcUserFree # wxp -@ stub SimpleTypeAlignment # wxp -@ stub SimpleTypeBufferSize # wxp -@ stub SimpleTypeMemorySize # wxp -@ stub StartServiceIfNecessary # win9x -@ stdcall TowerConstruct(ptr ptr ptr ptr ptr ptr) -@ stdcall TowerExplode(ptr ptr ptr ptr ptr ptr) -@ stdcall UuidCompare(ptr ptr ptr) -@ stdcall UuidCreate(ptr) -@ stdcall UuidCreateNil(ptr) -@ stdcall UuidCreateSequential(ptr) # win 2000 -@ stdcall UuidEqual(ptr ptr ptr) -@ stdcall UuidFromStringA(str ptr) -@ stdcall UuidFromStringW(wstr ptr) -@ stdcall UuidHash(ptr ptr) -@ stdcall UuidIsNil(ptr ptr) -@ stdcall UuidToStringA(ptr ptr) -@ stdcall UuidToStringW(ptr ptr) -@ stub char_array_from_ndr -@ stub char_from_ndr -@ stub data_from_ndr -@ stub data_into_ndr -@ stub data_size_ndr -@ stub double_array_from_ndr -@ stub double_from_ndr -@ stub enum_from_ndr -@ stub float_array_from_ndr -@ stub float_from_ndr -@ stub long_array_from_ndr -@ stub long_from_ndr -@ stub long_from_ndr_temp -@ stub pfnFreeRoutines # wxp -@ stub pfnMarshallRouteines # wxp -@ stub pfnSizeRoutines # wxp -@ stub pfnUnmarshallRouteines # wxp -@ stub short_array_from_ndr -@ stub short_from_ndr -@ stub short_from_ndr_temp -@ stub tree_into_ndr -@ stub tree_peek_ndr -@ stub tree_size_ndr diff --git a/reactos/dll/win32/rpcrt4_new/rpcrt4_main.c b/reactos/dll/win32/rpcrt4_new/rpcrt4_main.c deleted file mode 100644 index e48cf586988..00000000000 --- a/reactos/dll/win32/rpcrt4_new/rpcrt4_main.c +++ /dev/null @@ -1,1025 +0,0 @@ -/* - * RPCRT4 - * - * Copyright 2000 Huw D M Davies 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 - * - * WINE RPC TODO's (and a few TODONT's) - * - * - Ove's decreasingly incomplete widl is an IDL compiler for wine. For widl - * to be wine's only IDL compiler, a fair bit of work remains to be done. - * until then we have used some midl-generated stuff. (What?) - * widl currently doesn't generate stub/proxy files required by wine's (O)RPC - * capabilities -- nor does it make those lovely format strings :( - * The MS MIDL compiler does some really esoteric stuff. Of course Ove has - * started with the less esoteric stuff. There are also lots of nice - * comments in there if you want to flex your bison and help build this monster. - * - * - RPC has a quite featureful error handling mechanism; basically none of this is - * implemented right now. We also have deficiencies on the compiler side, where - * wine's __TRY / __EXCEPT / __FINALLY macros are not even used for RpcTryExcept & co, - * due to syntactic differences! (we can fix it with widl by using __TRY) - * - * - There are several different memory allocation schemes for MSRPC. - * I don't even understand what they all are yet, much less have them - * properly implemented. Surely we are supposed to be doing something with - * the user-provided allocation/deallocation functions, but so far, - * I don't think we are doing this... - * - * - MSRPC provides impersonation capabilities which currently are not possible - * to implement in wine. At the very least we should implement the authorization - * API's & gracefully ignore the irrelevant stuff (to an extent we already do). - * - * - Some transports are not yet implemented. The existing transport implementations - * are incomplete and may be bug-infested. - * - * - The various transports that we do support ought to be supported in a more - * object-oriented manner, as in DCE's RPC implementation, instead of cluttering - * up the code with conditionals like we do now. - * - * - Data marshalling: So far, only the beginnings of a full implementation - * exist in wine. NDR protocol itself is documented, but the MS API's to - * convert data-types in memory into NDR are not. This is challenging work, - * and has supposedly been "at the top of Greg's queue" for several months now. - * - * - ORPC is RPC for OLE; once we have a working RPC framework, we can - * use it to implement out-of-process OLE client/server communications. - * ATM there is maybe a disconnect between the marshalling in the OLE DLLs - * and the marshalling going on here [TODO: well, is there or not?] - * - * - In-source API Documentation, at least for those functions which we have - * implemented, but preferably for everything we can document, would be nice, - * since some of this stuff is quite obscure. - * - * - Name services... [TODO: what about them] - * - * - Protocol Towers: Totally unimplemented.... I think. - * - * - Context Handle Rundown: whatever that is. - * - * - Nested RPC's: Totally unimplemented. - * - * - Statistics: we are supposed to be keeping various counters. we aren't. - * - * - Async RPC: Unimplemented. - * - * - XML/http RPC: Somewhere there's an XML fiend that wants to do this! Betcha - * we could use these as a transport for RPC's across computers without a - * permissions and/or licensing crisis. - * - * - The NT "ports" API, aka LPC. Greg claims this is on his radar. Might (or - * might not) enable users to get some kind of meaningful result out of - * NT-based native rpcrt4's. Commonly-used transport for self-to-self RPC's. - * - * - ...? More stuff I haven't thought of. If you think of more RPC todo's - * drop me an e-mail or send a patch to the - * wine-patches mailing list. - */ - -#include "config.h" - -#include -#include -#include -#include - -#include "windef.h" -#include "winerror.h" -#include "winbase.h" -#include "winuser.h" -#include "winnt.h" -#include "winternl.h" -#include "iptypes.h" -#include "iphlpapi.h" -#include "wine/unicode.h" -#include "rpc.h" - -#include "ole2.h" -#include "rpcndr.h" -#include "rpcproxy.h" - -#include "rpc_binding.h" -#include "rpcss_np_client.h" - -#include "wine/debug.h" - -WINE_DEFAULT_DEBUG_CHANNEL(rpc); - -static UUID uuid_nil; -static HANDLE master_mutex; - -HANDLE RPCRT4_GetMasterMutex(void) -{ - return master_mutex; -} - -static CRITICAL_SECTION uuid_cs; -static CRITICAL_SECTION_DEBUG critsect_debug = -{ - 0, 0, &uuid_cs, - { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList }, - 0, 0, { (DWORD_PTR)(__FILE__ ": uuid_cs") } -}; -static CRITICAL_SECTION uuid_cs = { &critsect_debug, -1, 0, 0, 0, 0 }; - -static CRITICAL_SECTION threaddata_cs; -static CRITICAL_SECTION_DEBUG threaddata_cs_debug = -{ - 0, 0, &threaddata_cs, - { &threaddata_cs_debug.ProcessLocksList, &threaddata_cs_debug.ProcessLocksList }, - 0, 0, { (DWORD_PTR)(__FILE__ ": threaddata_cs") } -}; -static CRITICAL_SECTION threaddata_cs = { &threaddata_cs_debug, -1, 0, 0, 0, 0 }; - -struct list threaddata_list = LIST_INIT(threaddata_list); - -struct context_handle_list -{ - struct context_handle_list *next; - NDR_SCONTEXT context_handle; -}; - -struct threaddata -{ - struct list entry; - CRITICAL_SECTION cs; - DWORD thread_id; - RpcConnection *connection; - RpcBinding *server_binding; - struct context_handle_list *context_handle_list; -}; - -/*********************************************************************** - * DllMain - * - * PARAMS - * hinstDLL [I] handle to the DLL's instance - * fdwReason [I] - * lpvReserved [I] reserved, must be NULL - * - * RETURNS - * Success: TRUE - * Failure: FALSE - */ - -BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) -{ - struct threaddata *tdata; - - switch (fdwReason) { - case DLL_PROCESS_ATTACH: - master_mutex = CreateMutexA( NULL, FALSE, RPCSS_MASTER_MUTEX_NAME); - if (!master_mutex) - ERR("Failed to create master mutex\n"); - break; - - case DLL_THREAD_DETACH: - tdata = NtCurrentTeb()->ReservedForNtRpc; - if (tdata) - { - EnterCriticalSection(&threaddata_cs); - list_remove(&tdata->entry); - LeaveCriticalSection(&threaddata_cs); - - DeleteCriticalSection(&tdata->cs); - if (tdata->connection) - ERR("tdata->connection should be NULL but is still set to %p\n", tdata->connection); - if (tdata->server_binding) - ERR("tdata->server_binding should be NULL but is still set to %p\n", tdata->server_binding); - HeapFree(GetProcessHeap(), 0, tdata); - } - break; - - case DLL_PROCESS_DETACH: - CloseHandle(master_mutex); - master_mutex = NULL; - break; - } - - return TRUE; -} - -/************************************************************************* - * RpcStringFreeA [RPCRT4.@] - * - * Frees a character string allocated by the RPC run-time library. - * - * RETURNS - * - * S_OK if successful. - */ -RPC_STATUS WINAPI RpcStringFreeA(RPC_CSTR* String) -{ - HeapFree( GetProcessHeap(), 0, *String); - - return RPC_S_OK; -} - -/************************************************************************* - * RpcStringFreeW [RPCRT4.@] - * - * Frees a character string allocated by the RPC run-time library. - * - * RETURNS - * - * S_OK if successful. - */ -RPC_STATUS WINAPI RpcStringFreeW(RPC_WSTR* String) -{ - HeapFree( GetProcessHeap(), 0, *String); - - return RPC_S_OK; -} - -/************************************************************************* - * RpcRaiseException [RPCRT4.@] - * - * Raises an exception. - */ -void DECLSPEC_NORETURN WINAPI RpcRaiseException(RPC_STATUS exception) -{ - /* shouldn't return */ - RaiseException(exception, 0, 0, NULL); - ERR("handler continued execution\n"); - ExitProcess(1); -} - -/************************************************************************* - * UuidCompare [RPCRT4.@] - * - * PARAMS - * UUID *Uuid1 [I] Uuid to compare - * UUID *Uuid2 [I] Uuid to compare - * RPC_STATUS *Status [O] returns RPC_S_OK - * - * RETURNS - * -1 if Uuid1 is less than Uuid2 - * 0 if Uuid1 and Uuid2 are equal - * 1 if Uuid1 is greater than Uuid2 - */ -int WINAPI UuidCompare(UUID *Uuid1, UUID *Uuid2, RPC_STATUS *Status) -{ - int i; - - TRACE("(%s,%s)\n", debugstr_guid(Uuid1), debugstr_guid(Uuid2)); - - *Status = RPC_S_OK; - - if (!Uuid1) Uuid1 = &uuid_nil; - if (!Uuid2) Uuid2 = &uuid_nil; - - if (Uuid1 == Uuid2) return 0; - - if (Uuid1->Data1 != Uuid2->Data1) - return Uuid1->Data1 < Uuid2->Data1 ? -1 : 1; - - if (Uuid1->Data2 != Uuid2->Data2) - return Uuid1->Data2 < Uuid2->Data2 ? -1 : 1; - - if (Uuid1->Data3 != Uuid2->Data3) - return Uuid1->Data3 < Uuid2->Data3 ? -1 : 1; - - for (i = 0; i < 8; i++) { - if (Uuid1->Data4[i] < Uuid2->Data4[i]) - return -1; - if (Uuid1->Data4[i] > Uuid2->Data4[i]) - return 1; - } - - return 0; -} - -/************************************************************************* - * UuidEqual [RPCRT4.@] - * - * PARAMS - * UUID *Uuid1 [I] Uuid to compare - * UUID *Uuid2 [I] Uuid to compare - * RPC_STATUS *Status [O] returns RPC_S_OK - * - * RETURNS - * TRUE/FALSE - */ -int WINAPI UuidEqual(UUID *Uuid1, UUID *Uuid2, RPC_STATUS *Status) -{ - TRACE("(%s,%s)\n", debugstr_guid(Uuid1), debugstr_guid(Uuid2)); - return !UuidCompare(Uuid1, Uuid2, Status); -} - -/************************************************************************* - * UuidIsNil [RPCRT4.@] - * - * PARAMS - * UUID *Uuid [I] Uuid to compare - * RPC_STATUS *Status [O] retuns RPC_S_OK - * - * RETURNS - * TRUE/FALSE - */ -int WINAPI UuidIsNil(UUID *Uuid, RPC_STATUS *Status) -{ - TRACE("(%s)\n", debugstr_guid(Uuid)); - if (!Uuid) return TRUE; - return !UuidCompare(Uuid, &uuid_nil, Status); -} - - /************************************************************************* - * UuidCreateNil [RPCRT4.@] - * - * PARAMS - * UUID *Uuid [O] returns a nil UUID - * - * RETURNS - * RPC_S_OK - */ -RPC_STATUS WINAPI UuidCreateNil(UUID *Uuid) -{ - *Uuid = uuid_nil; - return RPC_S_OK; -} - -/* Number of 100ns ticks per clock tick. To be safe, assume that the clock - resolution is at least 1000 * 100 * (1/1000000) = 1/10 of a second */ -#define TICKS_PER_CLOCK_TICK 1000 -#define SECSPERDAY 86400 -#define TICKSPERSEC 10000000 -/* UUID system time starts at October 15, 1582 */ -#define SECS_15_OCT_1582_TO_1601 ((17 + 30 + 31 + 365 * 18 + 5) * SECSPERDAY) -#define TICKS_15_OCT_1582_TO_1601 ((ULONGLONG)SECS_15_OCT_1582_TO_1601 * TICKSPERSEC) - -static void RPC_UuidGetSystemTime(ULONGLONG *time) -{ - FILETIME ft; - - GetSystemTimeAsFileTime(&ft); - - *time = ((ULONGLONG)ft.dwHighDateTime << 32) | ft.dwLowDateTime; - *time += TICKS_15_OCT_1582_TO_1601; -} - -/* Assume that a hardware address is at least 6 bytes long */ -#define ADDRESS_BYTES_NEEDED 6 - -static RPC_STATUS RPC_UuidGetNodeAddress(BYTE *address) -{ - int i; - DWORD status = RPC_S_OK; - - ULONG buflen = sizeof(IP_ADAPTER_INFO); - PIP_ADAPTER_INFO adapter = HeapAlloc(GetProcessHeap(), 0, buflen); - - if (GetAdaptersInfo(adapter, &buflen) == ERROR_BUFFER_OVERFLOW) { - HeapFree(GetProcessHeap(), 0, adapter); - adapter = HeapAlloc(GetProcessHeap(), 0, buflen); - } - - if (GetAdaptersInfo(adapter, &buflen) == NO_ERROR) { - for (i = 0; i < ADDRESS_BYTES_NEEDED; i++) { - address[i] = adapter->Address[i]; - } - } - /* We can't get a hardware address, just use random numbers. - Set the multicast bit to prevent conflicts with real cards. */ - else { - for (i = 0; i < ADDRESS_BYTES_NEEDED; i++) { - address[i] = rand() & 0xff; - } - - address[0] |= 0x01; - status = RPC_S_UUID_LOCAL_ONLY; - } - - HeapFree(GetProcessHeap(), 0, adapter); - return status; -} - -/************************************************************************* - * UuidCreate [RPCRT4.@] - * - * Creates a 128bit UUID. - * - * RETURNS - * - * RPC_S_OK if successful. - * RPC_S_UUID_LOCAL_ONLY if UUID is only locally unique. - * - * FIXME: No compensation for changes across reloading - * this dll or across reboots (e.g. clock going - * backwards and swapped network cards). The RFC - * suggests using NVRAM for storing persistent - * values. - */ -RPC_STATUS WINAPI UuidCreate(UUID *Uuid) -{ - static int initialised, count; - - ULONGLONG time; - static ULONGLONG timelast; - static WORD sequence; - - static DWORD status; - static BYTE address[MAX_ADAPTER_ADDRESS_LENGTH]; - - EnterCriticalSection(&uuid_cs); - - if (!initialised) { - RPC_UuidGetSystemTime(&timelast); - count = TICKS_PER_CLOCK_TICK; - - sequence = ((rand() & 0xff) << 8) + (rand() & 0xff); - sequence &= 0x1fff; - - status = RPC_UuidGetNodeAddress(address); - initialised = 1; - } - - /* Generate time element of the UUID. Account for going faster - than our clock as well as the clock going backwards. */ - while (1) { - RPC_UuidGetSystemTime(&time); - if (time > timelast) { - count = 0; - break; - } - if (time < timelast) { - sequence = (sequence + 1) & 0x1fff; - count = 0; - break; - } - if (count < TICKS_PER_CLOCK_TICK) { - count++; - break; - } - } - - timelast = time; - time += count; - - /* Pack the information into the UUID structure. */ - - Uuid->Data1 = (unsigned long)(time & 0xffffffff); - Uuid->Data2 = (unsigned short)((time >> 32) & 0xffff); - Uuid->Data3 = (unsigned short)((time >> 48) & 0x0fff); - - /* This is a version 1 UUID */ - Uuid->Data3 |= (1 << 12); - - Uuid->Data4[0] = sequence & 0xff; - Uuid->Data4[1] = (sequence & 0x3f00) >> 8; - Uuid->Data4[1] |= 0x80; - - Uuid->Data4[2] = address[0]; - Uuid->Data4[3] = address[1]; - Uuid->Data4[4] = address[2]; - Uuid->Data4[5] = address[3]; - Uuid->Data4[6] = address[4]; - Uuid->Data4[7] = address[5]; - - LeaveCriticalSection(&uuid_cs); - - TRACE("%s\n", debugstr_guid(Uuid)); - - return status; -} - -/************************************************************************* - * UuidCreateSequential [RPCRT4.@] - * - * Creates a 128bit UUID. - * - * RETURNS - * - * RPC_S_OK if successful. - * RPC_S_UUID_LOCAL_ONLY if UUID is only locally unique. - * - */ -RPC_STATUS WINAPI UuidCreateSequential(UUID *Uuid) -{ - return UuidCreate(Uuid); -} - - -/************************************************************************* - * UuidHash [RPCRT4.@] - * - * Generates a hash value for a given UUID - * - * Code based on FreeDCE implementation - * - */ -unsigned short WINAPI UuidHash(UUID *uuid, RPC_STATUS *Status) -{ - BYTE *data = (BYTE*)uuid; - short c0 = 0, c1 = 0, x, y; - unsigned int i; - - if (!uuid) data = (BYTE*)(uuid = &uuid_nil); - - TRACE("(%s)\n", debugstr_guid(uuid)); - - for (i=0; iData1, Uuid->Data2, Uuid->Data3, - Uuid->Data4[0], Uuid->Data4[1], Uuid->Data4[2], - Uuid->Data4[3], Uuid->Data4[4], Uuid->Data4[5], - Uuid->Data4[6], Uuid->Data4[7] ); - - return RPC_S_OK; -} - -/************************************************************************* - * UuidToStringW [RPCRT4.@] - * - * Converts a UUID to a string. - * - * S_OK if successful. - * S_OUT_OF_MEMORY if unsuccessful. - */ -RPC_STATUS WINAPI UuidToStringW(UUID *Uuid, RPC_WSTR* StringUuid) -{ - char buf[37]; - - if (!Uuid) Uuid = &uuid_nil; - - sprintf(buf, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", - Uuid->Data1, Uuid->Data2, Uuid->Data3, - Uuid->Data4[0], Uuid->Data4[1], Uuid->Data4[2], - Uuid->Data4[3], Uuid->Data4[4], Uuid->Data4[5], - Uuid->Data4[6], Uuid->Data4[7] ); - - *StringUuid = RPCRT4_strdupAtoW(buf); - - if(!(*StringUuid)) - return RPC_S_OUT_OF_MEMORY; - - return RPC_S_OK; -} - -static const BYTE hex2bin[] = -{ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x00 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x10 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x20 */ - 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, /* 0x30 */ - 0,10,11,12,13,14,15,0,0,0,0,0,0,0,0,0, /* 0x40 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x50 */ - 0,10,11,12,13,14,15 /* 0x60 */ -}; - -/*********************************************************************** - * UuidFromStringA (RPCRT4.@) - */ -RPC_STATUS WINAPI UuidFromStringA(RPC_CSTR s, UUID *uuid) -{ - int i; - - if (!s) return UuidCreateNil( uuid ); - - if (strlen((char*)s) != 36) return RPC_S_INVALID_STRING_UUID; - - if ((s[8]!='-') || (s[13]!='-') || (s[18]!='-') || (s[23]!='-')) - return RPC_S_INVALID_STRING_UUID; - - for (i=0; i<36; i++) - { - if ((i == 8)||(i == 13)||(i == 18)||(i == 23)) continue; - if (s[i] > 'f' || (!hex2bin[s[i]] && s[i] != '0')) return RPC_S_INVALID_STRING_UUID; - } - - /* in form XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX */ - - uuid->Data1 = (hex2bin[s[0]] << 28 | hex2bin[s[1]] << 24 | hex2bin[s[2]] << 20 | hex2bin[s[3]] << 16 | - hex2bin[s[4]] << 12 | hex2bin[s[5]] << 8 | hex2bin[s[6]] << 4 | hex2bin[s[7]]); - uuid->Data2 = hex2bin[s[9]] << 12 | hex2bin[s[10]] << 8 | hex2bin[s[11]] << 4 | hex2bin[s[12]]; - uuid->Data3 = hex2bin[s[14]] << 12 | hex2bin[s[15]] << 8 | hex2bin[s[16]] << 4 | hex2bin[s[17]]; - - /* these are just sequential bytes */ - uuid->Data4[0] = hex2bin[s[19]] << 4 | hex2bin[s[20]]; - uuid->Data4[1] = hex2bin[s[21]] << 4 | hex2bin[s[22]]; - uuid->Data4[2] = hex2bin[s[24]] << 4 | hex2bin[s[25]]; - uuid->Data4[3] = hex2bin[s[26]] << 4 | hex2bin[s[27]]; - uuid->Data4[4] = hex2bin[s[28]] << 4 | hex2bin[s[29]]; - uuid->Data4[5] = hex2bin[s[30]] << 4 | hex2bin[s[31]]; - uuid->Data4[6] = hex2bin[s[32]] << 4 | hex2bin[s[33]]; - uuid->Data4[7] = hex2bin[s[34]] << 4 | hex2bin[s[35]]; - return RPC_S_OK; -} - - -/*********************************************************************** - * UuidFromStringW (RPCRT4.@) - */ -RPC_STATUS WINAPI UuidFromStringW(RPC_WSTR s, UUID *uuid) -{ - int i; - - if (!s) return UuidCreateNil( uuid ); - - if (strlenW(s) != 36) return RPC_S_INVALID_STRING_UUID; - - if ((s[8]!='-') || (s[13]!='-') || (s[18]!='-') || (s[23]!='-')) - return RPC_S_INVALID_STRING_UUID; - - for (i=0; i<36; i++) - { - if ((i == 8)||(i == 13)||(i == 18)||(i == 23)) continue; - if (s[i] > 'f' || (!hex2bin[s[i]] && s[i] != '0')) return RPC_S_INVALID_STRING_UUID; - } - - /* in form XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX */ - - uuid->Data1 = (hex2bin[s[0]] << 28 | hex2bin[s[1]] << 24 | hex2bin[s[2]] << 20 | hex2bin[s[3]] << 16 | - hex2bin[s[4]] << 12 | hex2bin[s[5]] << 8 | hex2bin[s[6]] << 4 | hex2bin[s[7]]); - uuid->Data2 = hex2bin[s[9]] << 12 | hex2bin[s[10]] << 8 | hex2bin[s[11]] << 4 | hex2bin[s[12]]; - uuid->Data3 = hex2bin[s[14]] << 12 | hex2bin[s[15]] << 8 | hex2bin[s[16]] << 4 | hex2bin[s[17]]; - - /* these are just sequential bytes */ - uuid->Data4[0] = hex2bin[s[19]] << 4 | hex2bin[s[20]]; - uuid->Data4[1] = hex2bin[s[21]] << 4 | hex2bin[s[22]]; - uuid->Data4[2] = hex2bin[s[24]] << 4 | hex2bin[s[25]]; - uuid->Data4[3] = hex2bin[s[26]] << 4 | hex2bin[s[27]]; - uuid->Data4[4] = hex2bin[s[28]] << 4 | hex2bin[s[29]]; - uuid->Data4[5] = hex2bin[s[30]] << 4 | hex2bin[s[31]]; - uuid->Data4[6] = hex2bin[s[32]] << 4 | hex2bin[s[33]]; - uuid->Data4[7] = hex2bin[s[34]] << 4 | hex2bin[s[35]]; - return RPC_S_OK; -} - -/*********************************************************************** - * DllRegisterServer (RPCRT4.@) - */ - -HRESULT WINAPI DllRegisterServer( void ) -{ - FIXME( "(): stub\n" ); - return S_OK; -} - -static BOOL RPCRT4_StartRPCSS(void) -{ - PROCESS_INFORMATION pi; - STARTUPINFOA si; - static char cmd[6]; - BOOL rslt; - - ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); - ZeroMemory(&si, sizeof(STARTUPINFOA)); - si.cb = sizeof(STARTUPINFOA); - - /* apparently it's not OK to use a constant string below */ - CopyMemory(cmd, "rpcss", 6); - - /* FIXME: will this do the right thing when run as a test? */ - rslt = CreateProcessA( - NULL, /* executable */ - cmd, /* command line */ - NULL, /* process security attributes */ - NULL, /* primary thread security attributes */ - FALSE, /* inherit handles */ - 0, /* creation flags */ - NULL, /* use parent's environment */ - NULL, /* use parent's current directory */ - &si, /* STARTUPINFO pointer */ - &pi /* PROCESS_INFORMATION */ - ); - - if (rslt) { - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); - } - - return rslt; -} - -/*********************************************************************** - * RPCRT4_RPCSSOnDemandCall (internal) - * - * Attempts to send a message to the RPCSS process - * on the local machine, invoking it if necessary. - * For remote RPCSS calls, use.... your imagination. - * - * PARAMS - * msg [I] pointer to the RPCSS message - * vardata_payload [I] pointer vardata portion of the RPCSS message - * reply [O] pointer to reply structure - * - * RETURNS - * TRUE if successful - * FALSE otherwise - */ -BOOL RPCRT4_RPCSSOnDemandCall(PRPCSS_NP_MESSAGE msg, char *vardata_payload, PRPCSS_NP_REPLY reply) -{ - HANDLE client_handle; - BOOL ret; - int i, j = 0; - - TRACE("(msg == %p, vardata_payload == %p, reply == %p)\n", msg, vardata_payload, reply); - - client_handle = RPCRT4_RpcssNPConnect(); - - while (INVALID_HANDLE_VALUE == client_handle) { - /* start the RPCSS process */ - if (!RPCRT4_StartRPCSS()) { - ERR("Unable to start RPCSS process.\n"); - return FALSE; - } - /* wait for a connection (w/ periodic polling) */ - for (i = 0; i < 60; i++) { - Sleep(200); - client_handle = RPCRT4_RpcssNPConnect(); - if (INVALID_HANDLE_VALUE != client_handle) break; - } - /* we are only willing to try twice */ - if (j++ >= 1) break; - } - - if (INVALID_HANDLE_VALUE == client_handle) { - /* no dice! */ - ERR("Unable to connect to RPCSS process!\n"); - SetLastError(RPC_E_SERVER_DIED_DNE); - return FALSE; - } - - /* great, we're connected. now send the message */ - ret = TRUE; - if (!RPCRT4_SendReceiveNPMsg(client_handle, msg, vardata_payload, reply)) { - ERR("Something is amiss: RPC_SendReceive failed.\n"); - ret = FALSE; - } - CloseHandle(client_handle); - - return ret; -} - -#define MAX_RPC_ERROR_TEXT 256 - -/****************************************************************************** - * DceErrorInqTextW (rpcrt4.@) - * - * Notes - * 1. On passing a NULL pointer the code does bomb out. - * 2. The size of the required buffer is not defined in the documentation. - * It appears to be 256. - * 3. The function is defined to return RPC_S_INVALID_ARG but I don't know - * of any value for which it does. - * 4. The MSDN documentation currently declares that the second argument is - * unsigned char *, even for the W version. I don't believe it. - */ -RPC_STATUS RPC_ENTRY DceErrorInqTextW (RPC_STATUS e, RPC_WSTR buffer) -{ - DWORD count; - count = FormatMessageW (FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, e, 0, buffer, MAX_RPC_ERROR_TEXT, NULL); - if (!count) - { - count = FormatMessageW (FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, RPC_S_NOT_RPC_ERROR, 0, buffer, MAX_RPC_ERROR_TEXT, NULL); - if (!count) - { - ERR ("Failed to translate error\n"); - return RPC_S_INVALID_ARG; - } - } - return RPC_S_OK; -} - -/****************************************************************************** - * DceErrorInqTextA (rpcrt4.@) - */ -RPC_STATUS RPC_ENTRY DceErrorInqTextA (RPC_STATUS e, RPC_CSTR buffer) -{ - RPC_STATUS status; - WCHAR bufferW [MAX_RPC_ERROR_TEXT]; - if ((status = DceErrorInqTextW (e, bufferW)) == RPC_S_OK) - { - if (!WideCharToMultiByte(CP_ACP, 0, bufferW, -1, (LPSTR)buffer, MAX_RPC_ERROR_TEXT, - NULL, NULL)) - { - ERR ("Failed to translate error\n"); - status = RPC_S_INVALID_ARG; - } - } - return status; -} - -/****************************************************************************** - * I_RpcAllocate (rpcrt4.@) - */ -void * WINAPI I_RpcAllocate(unsigned int Size) -{ - return HeapAlloc(GetProcessHeap(), 0, Size); -} - -/****************************************************************************** - * I_RpcFree (rpcrt4.@) - */ -void WINAPI I_RpcFree(void *Object) -{ - HeapFree(GetProcessHeap(), 0, Object); -} - -/****************************************************************************** - * I_RpcMapWin32Status (rpcrt4.@) - */ -LONG WINAPI I_RpcMapWin32Status(RPC_STATUS status) -{ - FIXME("(%ld): stub\n", status); - return 0; -} - -/****************************************************************************** - * RpcErrorStartEnumeration (rpcrt4.@) - */ -RPC_STATUS RPC_ENTRY RpcErrorStartEnumeration(RPC_ERROR_ENUM_HANDLE* EnumHandle) -{ - FIXME("(%p): stub\n", EnumHandle); - return RPC_S_ENTRY_NOT_FOUND; -} - -/****************************************************************************** - * RpcMgmtSetCancelTimeout (rpcrt4.@) - */ -RPC_STATUS RPC_ENTRY RpcMgmtSetCancelTimeout(LONG Timeout) -{ - FIXME("(%d): stub\n", Timeout); - return RPC_S_OK; -} - -static struct threaddata *get_or_create_threaddata(void) -{ - struct threaddata *tdata = NtCurrentTeb()->ReservedForNtRpc; - if (!tdata) - { - tdata = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*tdata)); - if (!tdata) return NULL; - - InitializeCriticalSection(&tdata->cs); - tdata->thread_id = GetCurrentThreadId(); - - EnterCriticalSection(&threaddata_cs); - list_add_tail(&threaddata_list, &tdata->entry); - LeaveCriticalSection(&threaddata_cs); - - NtCurrentTeb()->ReservedForNtRpc = tdata; - return tdata; - } - return tdata; -} - -void RPCRT4_SetThreadCurrentConnection(RpcConnection *Connection) -{ - struct threaddata *tdata = get_or_create_threaddata(); - if (!tdata) return; - - EnterCriticalSection(&tdata->cs); - tdata->connection = Connection; - LeaveCriticalSection(&tdata->cs); -} - -void RPCRT4_SetThreadCurrentCallHandle(RpcBinding *Binding) -{ - struct threaddata *tdata = get_or_create_threaddata(); - if (!tdata) return; - - tdata->server_binding = Binding; -} - -RpcBinding *RPCRT4_GetThreadCurrentCallHandle(void) -{ - struct threaddata *tdata = get_or_create_threaddata(); - if (!tdata) return NULL; - - return tdata->server_binding; -} - -void RPCRT4_PushThreadContextHandle(NDR_SCONTEXT SContext) -{ - struct threaddata *tdata = get_or_create_threaddata(); - struct context_handle_list *context_handle_list; - - if (!tdata) return; - - context_handle_list = HeapAlloc(GetProcessHeap(), 0, sizeof(*context_handle_list)); - if (!context_handle_list) return; - - context_handle_list->context_handle = SContext; - context_handle_list->next = tdata->context_handle_list; - tdata->context_handle_list = context_handle_list; -} - -void RPCRT4_RemoveThreadContextHandle(NDR_SCONTEXT SContext) -{ - struct threaddata *tdata = get_or_create_threaddata(); - struct context_handle_list *current, *prev; - - if (!tdata) return; - - for (current = tdata->context_handle_list, prev = NULL; current; prev = current, current = current->next) - { - if (current->context_handle == SContext) - { - if (prev) - prev->next = current->next; - else - tdata->context_handle_list = current->next; - HeapFree(GetProcessHeap(), 0, current); - return; - } - } -} - -NDR_SCONTEXT RPCRT4_PopThreadContextHandle(void) -{ - struct threaddata *tdata = get_or_create_threaddata(); - struct context_handle_list *context_handle_list; - NDR_SCONTEXT context_handle; - - if (!tdata) return NULL; - - context_handle_list = tdata->context_handle_list; - if (!context_handle_list) return NULL; - tdata->context_handle_list = context_handle_list->next; - - context_handle = context_handle_list->context_handle; - HeapFree(GetProcessHeap(), 0, context_handle_list); - return context_handle; -} - -/****************************************************************************** - * RpcCancelThread (rpcrt4.@) - */ -RPC_STATUS RPC_ENTRY RpcCancelThread(void* ThreadHandle) -{ - DWORD target_tid; - struct threaddata *tdata; - - TRACE("(%p)\n", ThreadHandle); - - target_tid = GetThreadId(ThreadHandle); - if (!target_tid) - return RPC_S_INVALID_ARG; - - EnterCriticalSection(&threaddata_cs); - LIST_FOR_EACH_ENTRY(tdata, &threaddata_list, struct threaddata, entry) - if (tdata->thread_id == target_tid) - { - EnterCriticalSection(&tdata->cs); - if (tdata->connection) rpcrt4_conn_cancel_call(tdata->connection); - LeaveCriticalSection(&tdata->cs); - break; - } - LeaveCriticalSection(&threaddata_cs); - - return RPC_S_OK; -} diff --git a/reactos/dll/win32/rpcrt4_new/rpcss_np_client.c b/reactos/dll/win32/rpcrt4_new/rpcss_np_client.c deleted file mode 100644 index 016f77f5f15..00000000000 --- a/reactos/dll/win32/rpcrt4_new/rpcss_np_client.c +++ /dev/null @@ -1,152 +0,0 @@ -/* - * RPCSS named pipe client implementation - * - * Copyright (C) 2002 Greg Turner - * - * 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 -#include - -#include "windef.h" -#include "winbase.h" -#include "wine/rpcss_shared.h" -#include "wine/debug.h" - -#include "rpc_binding.h" - -WINE_DEFAULT_DEBUG_CHANNEL(ole); - -HANDLE RPCRT4_RpcssNPConnect(void) -{ - HANDLE the_pipe; - DWORD dwmode, wait_result; - HANDLE master_mutex = RPCRT4_GetMasterMutex(); - - TRACE("\n"); - - while (TRUE) { - - wait_result = WaitForSingleObject(master_mutex, MASTER_MUTEX_TIMEOUT); - switch (wait_result) { - case WAIT_ABANDONED: - case WAIT_OBJECT_0: - break; - case WAIT_FAILED: - case WAIT_TIMEOUT: - default: - ERR("This should never happen: couldn't enter mutex.\n"); - return NULL; - } - - /* try to open the client side of the named pipe. */ - the_pipe = CreateFileA( - NAME_RPCSS_NAMED_PIPE, /* pipe name */ - GENERIC_READ | GENERIC_WRITE, /* r/w access */ - 0, /* no sharing */ - NULL, /* no security attributes */ - OPEN_EXISTING, /* open an existing pipe */ - 0, /* default attributes */ - NULL /* no template file */ - ); - - if (the_pipe != INVALID_HANDLE_VALUE) - break; - - if (GetLastError() != ERROR_PIPE_BUSY) { - WARN("Unable to open named pipe %s (assuming unavailable).\n", - debugstr_a(NAME_RPCSS_NAMED_PIPE)); - break; - } - - WARN("Named pipe busy (will wait)\n"); - - if (!ReleaseMutex(master_mutex)) - ERR("Failed to release master mutex. Expect deadlock.\n"); - - /* wait for the named pipe. We are only willing to wait for 5 seconds. - It should be available /very/ soon. */ - if (! WaitNamedPipeA(NAME_RPCSS_NAMED_PIPE, MASTER_MUTEX_WAITNAMEDPIPE_TIMEOUT)) - { - ERR("Named pipe unavailable after waiting. Something is probably wrong.\n"); - break; - } - - } - - if (the_pipe != INVALID_HANDLE_VALUE) { - dwmode = PIPE_READMODE_MESSAGE; - /* SetNamedPipeHandleState not implemented ATM, but still seems to work somehow. */ - if (! SetNamedPipeHandleState(the_pipe, &dwmode, NULL, NULL)) - WARN("Failed to set pipe handle state\n"); - } - - if (!ReleaseMutex(master_mutex)) - ERR("Uh oh, failed to leave the RPC Master Mutex!\n"); - - return the_pipe; -} - -BOOL RPCRT4_SendReceiveNPMsg(HANDLE np, PRPCSS_NP_MESSAGE msg, char *vardata, PRPCSS_NP_REPLY reply) -{ - DWORD count; - UINT32 payload_offset; - RPCSS_NP_MESSAGE vardata_payload_msg; - - TRACE("(np == %p, msg == %p, vardata == %p, reply == %p)\n", - np, msg, vardata, reply); - - if (! WriteFile(np, msg, sizeof(RPCSS_NP_MESSAGE), &count, NULL)) { - ERR("write failed.\n"); - return FALSE; - } - - if (count != sizeof(RPCSS_NP_MESSAGE)) { - ERR("write count mismatch.\n"); - return FALSE; - } - - /* process the vardata payload if necessary */ - vardata_payload_msg.message_type = RPCSS_NP_MESSAGE_TYPEID_VARDATAPAYLOADMSG; - vardata_payload_msg.vardata_payload_size = 0; /* meaningless */ - for ( payload_offset = 0; payload_offset < msg->vardata_payload_size; - payload_offset += VARDATA_PAYLOAD_BYTES ) { - TRACE("sending vardata payload. vd=%p, po=%d, ps=%d\n", vardata, - payload_offset, msg->vardata_payload_size); - ZeroMemory(vardata_payload_msg.message.vardatapayloadmsg.payload, VARDATA_PAYLOAD_BYTES); - CopyMemory(vardata_payload_msg.message.vardatapayloadmsg.payload, - vardata, - min( VARDATA_PAYLOAD_BYTES, msg->vardata_payload_size - payload_offset )); - vardata += VARDATA_PAYLOAD_BYTES; - if (! WriteFile(np, &vardata_payload_msg, sizeof(RPCSS_NP_MESSAGE), &count, NULL)) { - ERR("vardata write failed at %u bytes.\n", payload_offset); - return FALSE; - } - } - - if (! ReadFile(np, reply, sizeof(RPCSS_NP_REPLY), &count, NULL)) { - ERR("read failed.\n"); - return FALSE; - } - - if (count != sizeof(RPCSS_NP_REPLY)) { - ERR("read count mismatch. got %d.\n", count); - return FALSE; - } - - /* message execution was successful */ - return TRUE; -} diff --git a/reactos/dll/win32/rpcrt4_new/rpcss_np_client.h b/reactos/dll/win32/rpcrt4_new/rpcss_np_client.h deleted file mode 100644 index db65d432bca..00000000000 --- a/reactos/dll/win32/rpcrt4_new/rpcss_np_client.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2002 Greg Turner - * - * 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 - */ - -#ifndef __WINE_RPCSS_NP_CLIENT_H -#define __WINE_RPCSS_NP_CLIENT_H - -/* rpcss_np_client.c */ -HANDLE RPC_RpcssNPConnect(void); -BOOL RPCRT4_SendReceiveNPMsg(HANDLE, PRPCSS_NP_MESSAGE, char *, PRPCSS_NP_REPLY); - -#endif /* __RPCSS_NP_CLINET_H */ diff --git a/reactos/dll/win32/shdocvw/shdocvw.h b/reactos/dll/win32/shdocvw/shdocvw.h index 5b8eb507663..93e3f90e2ca 100644 --- a/reactos/dll/win32/shdocvw/shdocvw.h +++ b/reactos/dll/win32/shdocvw/shdocvw.h @@ -61,7 +61,7 @@ extern HRESULT SHDOCVW_GetShellInstanceObjectClassObject(REFCLSID rclsid, typedef struct ConnectionPoint ConnectionPoint; -typedef struct { +struct WebBrowser { /* Interfaces available via WebBrowser object */ const IWebBrowser2Vtbl *lpWebBrowser2Vtbl; @@ -115,7 +115,7 @@ typedef struct { ConnectionPoint *cp_wbe2; ConnectionPoint *cp_wbe; ConnectionPoint *cp_pns; -} WebBrowser; +}; #define WEBBROWSER(x) ((IWebBrowser*) &(x)->lpWebBrowser2Vtbl) #define WEBBROWSER2(x) ((IWebBrowser2*) &(x)->lpWebBrowser2Vtbl) diff --git a/reactos/tools/widl/ChangeLog b/reactos/tools/widl/ChangeLog deleted file mode 100644 index 40c0dcb94e6..00000000000 --- a/reactos/tools/widl/ChangeLog +++ /dev/null @@ -1,298 +0,0 @@ -ChangeLog - -2007-05-17 ekohl - - tools/widl/lex.yy.c - tools/widl/parser.l - tools/widl/typelib.c - -- Update wpp and fix the wpp_find_include issue! - - -2006-07-30 ekohl - -- Synchronized with WINE widl 20060729. - - The only difference is one call to wpp_find_include in parser.l. - We'll need to fix this issue! - - -2006-02-27 ekohl - - tools/widl/client.c - tools/widl/server.c - -- Dereference type declarations properly. - -2006-02-27 ekohl - - tools/widl/client.c - tools/widl/server.c - -- Move proc string offset calculation to a separate function. -- Replace all __FUNCTION__ by __FILE__. - -2006-01-01 ekohl - - tools/widl/client.c - tools/widl/server.c - -- Generate static MIDL_PROC_FORMAT_STRING, MIDL_TYPE_FORMAT_STRING and - MIDL_STUB_DESC variables. - -2005-12-05 ekohl - - tools/widl/widl.c - tools/widl/widl.man - -- Change oldnames option from '-o' to '--oldnames'. - -2005-11-26 ekohl - - tools/widl/client.c - tools/widl/server.c - -- Allocate another 4 bytes for unique pointers to simple types. - -2005-10-16 ekohl - - tools/widl/client.c - tools/widl/server.c - -- Fix [out, size_is, unique] parameter issues. - -2005-10-09 ekohl - - tools/widl/client.c - tools/widl/server.c - -- Support [out, unique] base type parameters. - -2005-08-07 ekohl - - tools/widl/server.c - -- Support size_is(*Length) attributes for strings. - -2005-07-30 ekohl - - tools/widl/client.c - tools/widl/server.c - -- Support conformant arrays as in and out parameters. -- Fix message buffer size calculation for client and server. - -2005-07-25 ekohl - - tools/widl/client.c - tools/widl/lex.yy.c - tools/widl/parser.y - tools/widl/proxy.c - tools/widl/server.c - tools/widl/y.tab.c - tools/widl/y.tab.h - -- Fix grammar of the size_is attribute so that size_is(*Length) gets accepted. - -2005-07-23 ekohl - - tools/widl/client.c - tools/widl/server.c - -- Fix offset calculation bug in the ProcFormatString. -- Fix offset calculation bug in the marshalling and unmarshalling code. -- Fix typos in the TypeFormatString. -This makes the [string, out, size_is()] parameters work properly. - -2005-07-17 ekohl - - tools/widl/client.c - tools/widl/server.c - -Fix bugs for in-string parameters. -Implement out-string parameters (untested). - -2005-05-08 weiden - - tools/widl/server.c - -Don't generate lvalue assignment code. - -2005-05-08 weiden - - tools/widl/client.c - tools/widl/proxy.c - tools/widl/server.c - -Generate code GCC4.x accepts. - -2005-04-18 navaraf - - tools/widl/parser.y - -Don't use pointer to freed memory. - -2005-04-17 ekohl - - tools/widl/server.c - -Support out-pointers to structs. - -2005-04-15 ekohl - - tools/widl/client.c - tools/widl/parser.y - tools/widl/server.c - -Support in-pointers to structs. - -2005-04-03 ekohl - - tools/widl/client.c - tools/widl/parser.l - tools/widl/parser.y - tools/widl/server.c - tools/widl/widltypes.h - -Support 'ref' and 'unique' attributes for pointers. - -2005-03-27 Jacek Caban (from WINE) - - tools/widl/parser.y - tools/widl/y.tab.c - -Added handling of unsigned type - -2005-03-25 ekohl - - tools/widl/client.c - tools/widl/server.c - -Generate code without L-value casts. Fix remaining issues. - -2005-03-21 navaraf - - tools/widl/client.c - -Fix a typo in write_function_stubs. - -2005-03-20 navaraf - - tools/widl/client.c - tools/widl/server.c - -Generate code without L-value casts. - -2005-03-20 ekohl - - tools/widl/client.c - tools/widl/server.c - -Improve error messages. -Don't start counting the type_offset for each new fuction. It is a global offset. -Use only basic types in type- and proc-strings (e.g. unsigned long -> long). - - -2005-03-13 ekohl - - tools/widl/server.c - -Remove debug printf(). - - -2005-03-13 jimtabor - - tools/widl/write_msft.c - -Fixup *nix port, added include fcntl.h and unistd.h. - - -2005-03-13 royce3 - - tools/widl/hash.c - tools/widl/Makefile - tools/widl/write_msft.c - --Wall -Werror and fix warnings - - -2005-03-13 ekohl - - tools/widl/client.c - tools/widl/server.c - -Implement [string] attribute for pointers to char and wchar_t. - - -2005-03-12 ekohl - - tools/widl/client.c - tools/widl/server.c - -Implement [in], [out] and [in, out] support for pointers to basic types. - - -2005-03-10 ekohl - - tools/widl/client.c - tools/widl/header.c - tools/widl/server.c - tools/widl/widl.c - tools/widl/widl.h - -Implement '-o' option. This is equivalent to MIDLs '/oldnames' option. - - -2005-03-06 ekohl - - tools/widl/client.c - tools/widl/header.c - tools/widl/header.h - tools/widl/server.c - -Support pointers to simple types as input arguments. - - -2005-02-27 sedwards - - tools/widl/y.tab.c - tools/widl/parser.y - tools/widl/widl.c - tools/widl/widl.h - tools/widl/server.c - tools/widl/typelib.c - -Merge in Winehq changes to reduce noise. - - tools/widl/server.h - tools/widl/client.h - tools/widl/proxy.h - -Deleted unneeded headers. - -2005-02-26 ekohl - tools/widl/server.c - -Server stubs are void functions. -Fix a warning in the server stub descriptor. - - -2005-02-25 ekohl - tools/widl/client.c - tools/widl/header.c - tools/widl/header.h - tools/widl/server.c - -Support multiple interfaces per idl file. -Support explicit binding handles. - - -2005-02-24 ekohl - include/wine/rpcfc.h - tools/widl/client.c - tools/widl/header.c - tools/widl/parser.l - tools/widl/parser.y - tools/widl/server.c - -Support remaining basic types (float, double, small, wchar_t and handle_t). diff --git a/reactos/tools/widl/Makefile.in b/reactos/tools/widl/Makefile.in deleted file mode 100644 index e2bd0cc887f..00000000000 --- a/reactos/tools/widl/Makefile.in +++ /dev/null @@ -1,53 +0,0 @@ -TOPSRCDIR = @top_srcdir@ -TOPOBJDIR = ../.. -SRCDIR = @srcdir@ -VPATH = @srcdir@ -EXEEXT = @EXEEXT@ - -PROGRAMS = widl$(EXEEXT) -MANPAGES = widl.man -MODULE = none - -C_SRCS = \ - client.c \ - hash.c \ - header.c \ - proxy.c \ - server.c \ - typegen.c \ - typelib.c \ - utils.c \ - widl.c \ - write_msft.c - -EXTRA_SRCS = parser.y parser.l -EXTRA_OBJS = parser.tab.o @LEX_OUTPUT_ROOT@.o - -all: $(PROGRAMS) $(MANPAGES) - -@MAKE_RULES@ - -widl$(EXEEXT): $(OBJS) $(LIBWPP) - $(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBWPP) $(LIBPORT) $(LEXLIB) $(LDFLAGS) - -parser.tab.c parser.tab.h: parser.y - $(BISON) -d -t $(SRCDIR)/parser.y -o parser.tab.c - -# hack to allow parallel make -parser.tab.h: parser.tab.c -parser.tab.o: parser.tab.h - -@LEX_OUTPUT_ROOT@.c: parser.l - $(LEX) $(SRCDIR)/parser.l - -@LEX_OUTPUT_ROOT@.o: parser.tab.h - -install:: $(PROGRAMS) $(MANPAGES) - $(MKINSTALLDIRS) $(DESTDIR)$(bindir) $(DESTDIR)$(mandir)/man$(prog_manext) - $(INSTALL_PROGRAM) widl$(EXEEXT) $(DESTDIR)$(bindir)/widl$(EXEEXT) - $(INSTALL_DATA) widl.man $(DESTDIR)$(mandir)/man$(prog_manext)/widl.$(prog_manext) - -uninstall:: - $(RM) $(DESTDIR)$(bindir)/widl$(EXEEXT) $(DESTDIR)$(mandir)/man$(prog_manext)/widl.$(prog_manext) - -### Dependencies: diff --git a/reactos/tools/widl/client.c b/reactos/tools/widl/client.c index 24c086b54db..5cd2a81800b 100644 --- a/reactos/tools/widl/client.c +++ b/reactos/tools/widl/client.c @@ -20,7 +20,7 @@ #include "config.h" #include "wine/port.h" - + #include #include #include @@ -34,98 +34,57 @@ #include "parser.h" #include "header.h" -#include - #include "widltypes.h" -#include "typelib.h" -#include "typelib_struct.h" #include "typegen.h" static FILE* client; static int indent = 0; -static int print_client( const char *format, ... ) +static void print_client( const char *format, ... ) { va_list va; - int i, r; - va_start(va, format); - for (i = 0; i < indent; i++) - fprintf(client, " "); - r = vfprintf(client, format, va); + print(client, indent, format, va); va_end(va); - return r; } -static void print_message_buffer_size(const func_t *func) -{ - unsigned int total_size = 0; - - if (func->args) - { - const var_t *var = func->args; - while (NEXT_LINK(var)) var = NEXT_LINK(var); - while (var) - { - unsigned int alignment; - - total_size += get_required_buffer_size(var, &alignment, PASS_IN); - total_size += alignment; - - var = PREV_LINK(var); - } - } - fprintf(client, " %u", total_size); -} - static void check_pointers(const func_t *func) { - var_t *var; - int pointer_type; + const var_t *var; if (!func->args) return; - var = func->args; - while (NEXT_LINK(var)) var = NEXT_LINK(var); - while (var) + LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) { - pointer_type = get_attrv(var->attrs, ATTR_POINTERTYPE); - if (!pointer_type) - pointer_type = RPC_FC_RP; - - if (pointer_type == RPC_FC_RP) + if (is_var_ptr(var) && cant_be_null(var)) { - if (var->ptr_level >= 1) - { - print_client("if (!%s)\n", var->name); - print_client("{\n"); - indent++; - print_client("RpcRaiseException(RPC_X_NULL_REF_POINTER);\n"); - indent--; - print_client("}\n\n"); - } + print_client("if (!%s)\n", var->name); + print_client("{\n"); + indent++; + print_client("RpcRaiseException(RPC_X_NULL_REF_POINTER);\n"); + indent--; + print_client("}\n\n"); } - - var = PREV_LINK(var); } } -static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsigned int *type_offset) +static void write_function_stubs(type_t *iface, unsigned int *proc_offset) { - const func_t *func = iface->funcs; + const func_t *func; const char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE); int explicit_handle = is_attr(iface->attrs, ATTR_EXPLICIT_HANDLE); - var_t *var; + const var_t *var; int method_count = 0; - while (NEXT_LINK(func)) func = NEXT_LINK(func); - while (func) + if (!implicit_handle) + print_client("static RPC_BINDING_HANDLE %s__MIDL_AutoBindHandle;\n\n", iface->name); + + if (iface->funcs) LIST_FOR_EACH_ENTRY( func, iface->funcs, const func_t, entry ) { const var_t *def = func->def; const var_t* explicit_handle_var; - unsigned int type_offset_func; /* check for a defined binding handle */ explicit_handle_var = get_explicit_handle_var(func); @@ -146,9 +105,10 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig } } - write_type(client, def->type, def, def->tname); - fprintf(client, " "); - write_name(client, def); + write_type_decl_left(client, def->type); + if (needs_space_after(def->type)) + fprintf(client, " "); + write_prefix_name(client, prefix_client, def); fprintf(client, "(\n"); indent++; if (func->args) @@ -163,10 +123,10 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig indent++; /* declare return value '_RetVal' */ - if (!is_void(def->type, NULL)) + if (!is_void(def->type)) { print_client(""); - write_type(client, def->type, def, def->tname); + write_type_decl_left(client, def->type); fprintf(client, " _RetVal;\n"); } @@ -175,6 +135,11 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig print_client("RPC_MESSAGE _RpcMessage;\n"); print_client("MIDL_STUB_MESSAGE _StubMsg;\n"); + if (!is_void(def->type) && decl_indirect(def->type)) + { + print_client("void *_p_%s = &%s;\n", + "_RetVal", "_RetVal"); + } fprintf(client, "\n"); /* check pointers */ @@ -204,13 +169,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig fprintf(client, "\n"); } - /* emit the message buffer size */ - print_client("_StubMsg.BufferLength ="); - print_message_buffer_size(func); - fprintf(client, ";\n"); - - type_offset_func = *type_offset; - write_remoting_arguments(client, indent, func, &type_offset_func, PASS_IN, PHASE_BUFFERSIZE); + write_remoting_arguments(client, indent, func, PASS_IN, PHASE_BUFFERSIZE); print_client("NdrGetBuffer(\n"); indent++; @@ -223,12 +182,8 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig indent--; fprintf(client, "\n"); - - /* make a copy so we don't increment the type offset twice */ - type_offset_func = *type_offset; - /* marshal arguments */ - write_remoting_arguments(client, indent, func, &type_offset_func, PASS_IN, PHASE_MARSHAL); + write_remoting_arguments(client, indent, func, PASS_IN, PHASE_MARSHAL); /* send/receive message */ /* print_client("NdrNsSendReceive(\n"); */ @@ -258,24 +213,25 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig /* unmarshall arguments */ fprintf(client, "\n"); - write_remoting_arguments(client, indent, func, type_offset, PASS_OUT, PHASE_UNMARSHAL); + write_remoting_arguments(client, indent, func, PASS_OUT, PHASE_UNMARSHAL); /* unmarshal return value */ - if (!is_void(def->type, NULL)) - print_phase_basetype(client, indent, PHASE_UNMARSHAL, PASS_RETURN, def, "_RetVal"); + if (!is_void(def->type)) + { + if (decl_indirect(def->type)) + print_client("MIDL_memset(&%s, 0, sizeof(%s));\n", "_RetVal", "_RetVal"); + else if (is_ptr(def->type) || is_array(def->type)) + print_client("%s = 0;\n", "_RetVal"); + write_remoting_arguments(client, indent, func, PASS_RETURN, PHASE_UNMARSHAL); + } /* update proc_offset */ if (func->args) { - var = func->args; - while (NEXT_LINK(var)) var = NEXT_LINK(var); - while (var) - { + LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) *proc_offset += get_size_procformatstring_var(var); - var = PREV_LINK(var); - } } - if (!is_void(def->type, NULL)) + if (!is_void(def->type)) *proc_offset += get_size_procformatstring_var(def); else *proc_offset += 2; /* FC_END and FC_PAD */ @@ -297,7 +253,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig /* emit return code */ - if (!is_void(def->type, NULL)) + if (!is_void(def->type)) { fprintf(client, "\n"); print_client("return _RetVal;\n"); @@ -308,18 +264,10 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig fprintf(client, "\n"); method_count++; - func = PREV_LINK(func); } } -static void write_bindinghandledecl(type_t *iface) -{ - print_client("static RPC_BINDING_HANDLE %s__MIDL_AutoBindHandle;\n", iface->name); - fprintf(client, "\n"); -} - - static void write_stubdescdecl(type_t *iface) { print_client("static const MIDL_STUB_DESC %s_StubDesc;\n", iface->name); @@ -358,7 +306,7 @@ static void write_stubdescriptor(type_t *iface, int expr_eval_routines) print_client("0,\n"); print_client("0x50100a4, /* MIDL Version 5.1.164 */\n"); print_client("0,\n"); - print_client("0,\n"); + print_client("%s,\n", list_empty(&user_type_list) ? "0" : "UserMarshalRoutines"); print_client("0, /* notify & notify_flag routine table */\n"); print_client("1, /* Flags */\n"); print_client("0, /* Reserved3 */\n"); @@ -374,6 +322,9 @@ static void write_clientinterfacedecl(type_t *iface) { unsigned long ver = get_attrv(iface->attrs, ATTR_VERSION); const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID); + const str_list_t *endpoints = get_attrp(iface->attrs, ATTR_ENDPOINT); + + if (endpoints) write_endpoints( client, iface->name, endpoints ); print_client("static const RPC_CLIENT_INTERFACE %s___RpcClientInterface =\n", iface->name ); print_client("{\n"); @@ -382,11 +333,19 @@ static void write_clientinterfacedecl(type_t *iface) print_client("{{0x%08lx,0x%04x,0x%04x,{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x}},{%d,%d}},\n", uuid->Data1, uuid->Data2, uuid->Data3, uuid->Data4[0], uuid->Data4[1], uuid->Data4[2], uuid->Data4[3], uuid->Data4[4], uuid->Data4[5], uuid->Data4[6], - uuid->Data4[7], LOWORD(ver), HIWORD(ver)); + uuid->Data4[7], MAJORVERSION(ver), MINORVERSION(ver)); print_client("{{0x8a885d04,0x1ceb,0x11c9,{0x9f,0xe8,0x08,0x00,0x2b,0x10,0x48,0x60}},{2,0}},\n"); /* FIXME */ print_client("0,\n"); - print_client("0,\n"); - print_client("0,\n"); + if (endpoints) + { + print_client("%u,\n", list_count(endpoints)); + print_client("(PRPC_PROTSEQ_ENDPOINT)%s__RpcProtseqEndpoint,\n", iface->name); + } + else + { + print_client("0,\n"); + print_client("0,\n"); + } print_client("0,\n"); print_client("0,\n"); print_client("0,\n"); @@ -396,43 +355,12 @@ static void write_clientinterfacedecl(type_t *iface) print_client("RPC_IF_HANDLE %s_ClientIfHandle = (RPC_IF_HANDLE)& %s___RpcClientInterface;\n", iface->name, iface->name); else - print_client("RPC_IF_HANDLE %s_v%d_%d_c_ifspec = (RPC_IF_HANDLE)& %s___RpcClientInterface;\n", - iface->name, LOWORD(ver), HIWORD(ver), iface->name); + print_client("RPC_IF_HANDLE %s%s_v%d_%d_c_ifspec = (RPC_IF_HANDLE)& %s___RpcClientInterface;\n", + prefix_client, iface->name, MAJORVERSION(ver), MINORVERSION(ver), iface->name); fprintf(client, "\n"); } -static void write_formatdesc( const char *str ) -{ - print_client("typedef struct _MIDL_%s_FORMAT_STRING\n", str ); - print_client("{\n"); - indent++; - print_client("short Pad;\n"); - print_client("unsigned char Format[%s_FORMAT_STRING_SIZE];\n", str); - indent--; - print_client("} MIDL_%s_FORMAT_STRING;\n", str); - print_client("\n"); -} - - -static void write_formatstringsdecl(ifref_t *ifaces) -{ - print_client("#define TYPE_FORMAT_STRING_SIZE %d\n", - get_size_typeformatstring(ifaces)); - - print_client("#define PROC_FORMAT_STRING_SIZE %d\n", - get_size_procformatstring(ifaces)); - - fprintf(client, "\n"); - write_formatdesc("TYPE"); - write_formatdesc("PROC"); - fprintf(client, "\n"); - print_client("static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString;\n"); - print_client("static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString;\n"); - print_client("\n"); -} - - static void write_implicithandledecl(type_t *iface) { const char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE); @@ -451,7 +379,7 @@ static void init_client(void) if (!(client = fopen(client_name, "w"))) error("Could not open %s for output\n", client_name); - print_client("/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n", WIDL_FULLVERSION, input_name); + print_client("/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n", PACKAGE_VERSION, input_name); print_client("#include \n"); print_client("#ifdef _ALPHA_\n"); print_client("#include \n"); @@ -462,27 +390,30 @@ static void init_client(void) } -void write_client(ifref_t *ifaces) +void write_client(ifref_list_t *ifaces) { unsigned int proc_offset = 0; - unsigned int type_offset = 2; - ifref_t *iface = ifaces; + int expr_eval_routines; + ifref_t *iface; if (!do_client) return; - if (!iface) + if (do_everything && !need_stub_files(ifaces)) return; - END_OF_LIST(iface); init_client(); if (!client) return; - write_formatstringsdecl(ifaces); + write_formatstringsdecl(client, indent, ifaces, need_stub); + expr_eval_routines = write_expr_eval_routines(client, client_token); + if (expr_eval_routines) + write_expr_eval_routine_list(client, client_token); + write_user_quad_list(client); - for (; iface; iface = PREV_LINK(iface)) + if (ifaces) LIST_FOR_EACH_ENTRY( iface, ifaces, ifref_t, entry ) { - if (is_object(iface->iface->attrs) || is_local(iface->iface->attrs)) + if (!need_stub(iface->iface)) continue; fprintf(client, "/*****************************************************************************\n"); @@ -492,33 +423,25 @@ void write_client(ifref_t *ifaces) if (iface->iface->funcs) { - int expr_eval_routines; - write_implicithandledecl(iface->iface); - + write_clientinterfacedecl(iface->iface); write_stubdescdecl(iface->iface); - write_bindinghandledecl(iface->iface); - - write_function_stubs(iface->iface, &proc_offset, &type_offset); + write_function_stubs(iface->iface, &proc_offset); print_client("#if !defined(__RPC_WIN32__)\n"); print_client("#error Invalid build platform for this stub.\n"); print_client("#endif\n"); fprintf(client, "\n"); - - expr_eval_routines = write_expr_eval_routines(client, iface->iface->name); - if (expr_eval_routines) - write_expr_eval_routine_list(client, iface->iface->name); write_stubdescriptor(iface->iface, expr_eval_routines); } } fprintf(client, "\n"); - write_procformatstring(client, ifaces); - write_typeformatstring(client, ifaces); + write_procformatstring(client, ifaces, need_stub); + write_typeformatstring(client, ifaces, need_stub); fclose(client); } diff --git a/reactos/tools/widl/hash.c b/reactos/tools/widl/hash.c index 484e426b0e2..46eafeed9fa 100644 --- a/reactos/tools/widl/hash.c +++ b/reactos/tools/widl/hash.c @@ -21,7 +21,10 @@ #include #include -#include +#include "windef.h" +#include "winbase.h" +#include "winnls.h" + #include "hash.h" static const unsigned char Lookup_16[128 * 3] = { @@ -511,7 +514,7 @@ unsigned long lhash_val_of_name_sys( syskind_t skind, LCID lcid, LPCSTR lpStr) switch (PRIMARYLANGID(LANGIDFROMLCID(lcid))) { default: - fprintf(stderr, "Unknown lcid %lx, treating as latin-based, please report\n", lcid); + fprintf(stderr, "Unknown lcid %x, treating as latin-based, please report\n", lcid); /* .. Fall Through .. */ case LANG_AFRIKAANS: case LANG_ALBANIAN: case LANG_ARMENIAN: case LANG_ASSAMESE: case LANG_AZERI: case LANG_BASQUE: @@ -532,6 +535,7 @@ unsigned long lhash_val_of_name_sys( syskind_t skind, LCID lcid, LPCSTR lpStr) case LANG_SWEDISH: case LANG_SYRIAC: case LANG_TAMIL: case LANG_TATAR: case LANG_TELUGU: case LANG_THAI: case LANG_UKRAINIAN: case LANG_URDU: case LANG_UZBEK: +#ifndef __REACTOS__ case LANG_VIETNAMESE: case LANG_GAELIC: case LANG_MALTESE: case LANG_TAJIK: case LANG_ROMANSH: case LANG_IRISH: case LANG_SAMI: case LANG_UPPER_SORBIAN: case LANG_SUTU: @@ -539,6 +543,12 @@ unsigned long lhash_val_of_name_sys( syskind_t skind, LCID lcid, LPCSTR lpStr) case LANG_XHOSA: case LANG_ZULU: case LANG_ESPERANTO: case LANG_WALON: case LANG_CORNISH: case LANG_WELSH: case LANG_BRETON: +#else + case LANG_VIETNAMESE: case LANG_MALTESE: case LANG_IRISH: + case LANG_SAMI: case LANG_UPPER_SORBIAN: case LANG_TSWANA: + case LANG_XHOSA: case LANG_ZULU: case LANG_WELSH: + case LANG_BRETON: +#endif nOffset = 16; pnLookup = Lookup_16; break; @@ -602,13 +612,7 @@ unsigned long lhash_val_of_name_sys( syskind_t skind, LCID lcid, LPCSTR lpStr) while (*str) { - ULONG newLoWord = 0, i; - - /* Cumulative prime multiplication (*37) with modulo 2^32 wrap-around */ - for (i = 0; i < 37; i++) - newLoWord += nLoWord; - - nLoWord = newLoWord + pnLookup[*str > 0x7f && nMask ? *str + 0x80 : *str]; + nLoWord = 37 * nLoWord + pnLookup[*str > 0x7f && nMask ? *str + 0x80 : *str]; str++; } /* Constrain to a prime modulo and sizeof(WORD) */ diff --git a/reactos/tools/widl/header.c b/reactos/tools/widl/header.c index 10c42ffedad..fd895348b3a 100644 --- a/reactos/tools/widl/header.c +++ b/reactos/tools/widl/header.c @@ -20,6 +20,7 @@ #include "config.h" +#include #include #include #ifdef HAVE_UNISTD_H @@ -36,6 +37,8 @@ #include "header.h" static int indentation = 0; +user_type_list_t user_type_list = LIST_INIT(user_type_list); +static context_handle_list_t context_handle_list = LIST_INIT(context_handle_list); static void indent(FILE *h, int delta) { @@ -45,59 +48,73 @@ static void indent(FILE *h, int delta) if (delta > 0) indentation += delta; } -int is_attr(const attr_t *a, enum attr_type t) +int is_ptrchain_attr(const var_t *var, enum attr_type t) { - while (a) { - if (a->type == t) return 1; - a = NEXT_LINK(a); - } - return 0; + if (is_attr(var->attrs, t)) + return 1; + else + { + type_t *type = var->type; + for (;;) + { + if (is_attr(type->attrs, t)) + return 1; + else if (type->kind == TKIND_ALIAS) + type = type->orig; + else if (is_ptr(type)) + type = type->ref; + else return 0; + } + } } -void *get_attrp(const attr_t *a, enum attr_type t) +int is_attr(const attr_list_t *list, enum attr_type t) { - while (a) { - if (a->type == t) return a->u.pval; - a = NEXT_LINK(a); - } - return NULL; + const attr_t *attr; + if (list) LIST_FOR_EACH_ENTRY( attr, list, const attr_t, entry ) + if (attr->type == t) return 1; + return 0; } -unsigned long get_attrv(const attr_t *a, enum attr_type t) +void *get_attrp(const attr_list_t *list, enum attr_type t) { - while (a) { - if (a->type == t) return a->u.ival; - a = NEXT_LINK(a); - } - return 0; + const attr_t *attr; + if (list) LIST_FOR_EACH_ENTRY( attr, list, const attr_t, entry ) + if (attr->type == t) return attr->u.pval; + return NULL; } -int is_void(const type_t *t, const var_t *v) +unsigned long get_attrv(const attr_list_t *list, enum attr_type t) +{ + const attr_t *attr; + if (list) LIST_FOR_EACH_ENTRY( attr, list, const attr_t, entry ) + if (attr->type == t) return attr->u.ival; + return 0; +} + +int is_void(const type_t *t) { - if (v && v->ptr_level) return 0; if (!t->type && !t->ref) return 1; return 0; } -static void write_guid(const char *guid_prefix, const char *name, const UUID *uuid) +int is_conformant_array(const type_t *t) +{ + return t->type == RPC_FC_CARRAY + || t->type == RPC_FC_CVARRAY + || (t->type == RPC_FC_BOGUS_ARRAY && t->size_is); +} + +void write_guid(FILE *f, const char *guid_prefix, const char *name, const UUID *uuid) { if (!uuid) return; - fprintf(header, "DEFINE_GUID(%s_%s, 0x%08lx, 0x%04x, 0x%04x, 0x%02x,0x%02x, 0x%02x," + fprintf(f, "DEFINE_GUID(%s_%s, 0x%08x, 0x%04x, 0x%04x, 0x%02x,0x%02x, 0x%02x," "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x);\n", guid_prefix, name, uuid->Data1, uuid->Data2, uuid->Data3, uuid->Data4[0], uuid->Data4[1], uuid->Data4[2], uuid->Data4[3], uuid->Data4[4], uuid->Data4[5], uuid->Data4[6], uuid->Data4[7]); } -static void write_pident(FILE *h, const var_t *v) -{ - int c; - for (c=0; cptr_level; c++) { - fprintf(h, "*"); - } - if (v->name) fprintf(h, "%s", v->name); -} - void write_name(FILE *h, const var_t *v) { if (is_attr( v->attrs, ATTR_PROPGET )) @@ -109,40 +126,18 @@ void write_name(FILE *h, const var_t *v) fprintf(h, "%s", v->name); } -const char* get_name(const var_t *v) +void write_prefix_name(FILE *h, const char *prefix, const var_t *v) { - return v->name; -} - -void write_array(FILE *h, const expr_t *v, int field) -{ - if (!v) return; - while (NEXT_LINK(v)) v = NEXT_LINK(v); - fprintf(h, "["); - while (v) { - if (v->is_const) - fprintf(h, "%ld", v->cval); /* statically sized array */ - else - if (field) fprintf(h, "1"); /* dynamically sized array */ - if (PREV_LINK(v)) - fprintf(h, ", "); - v = PREV_LINK(v); - } - fprintf(h, "]"); + fprintf(h, "%s", prefix); + write_name(h, v); } static void write_field(FILE *h, var_t *v) { if (!v) return; if (v->type) { - indent(h, 0); - write_type(h, v->type, NULL, v->tname); - if (get_name(v)) { - fprintf(h, " "); - write_pident(h, v); - } - else { - /* not all C/C++ compilers support anonymous structs and unions */ + const char *name = v->name; + if (name == NULL) { switch (v->type->type) { case RPC_FC_STRUCT: case RPC_FC_CVSTRUCT: @@ -151,39 +146,36 @@ static void write_field(FILE *h, var_t *v) case RPC_FC_PSTRUCT: case RPC_FC_BOGUS_STRUCT: case RPC_FC_ENCAPSULATED_UNION: - fprintf(h, " DUMMYSTRUCTNAME"); + name = "DUMMYSTRUCTNAME"; break; case RPC_FC_NON_ENCAPSULATED_UNION: - fprintf(h, " DUMMYUNIONNAME"); + name = "DUMMYUNIONNAME"; break; default: /* ? */ break; } } - write_array(h, v->array, 1); + indent(h, 0); + write_type_def_or_decl(h, v->type, TRUE, "%s", name); fprintf(h, ";\n"); } } -static void write_fields(FILE *h, var_t *v) +static void write_fields(FILE *h, var_list_t *fields) { - var_t *first = v; - if (!v) return; - while (NEXT_LINK(v)) v = NEXT_LINK(v); - while (v) { - write_field(h, v); - if (v == first) break; - v = PREV_LINK(v); - } + var_t *v; + if (!fields) return; + LIST_FOR_EACH_ENTRY( v, fields, var_t, entry ) write_field(h, v); } -static void write_enums(FILE *h, var_t *v) +static void write_enums(FILE *h, var_list_t *enums) { - if (!v) return; - while (NEXT_LINK(v)) v = NEXT_LINK(v); - while (v) { - if (get_name(v)) { + var_t *v; + if (!enums) return; + LIST_FOR_EACH_ENTRY( v, enums, var_t, entry ) + { + if (v->name) { indent(h, 0); write_name(h, v); if (v->eval) { @@ -191,63 +183,32 @@ static void write_enums(FILE *h, var_t *v) write_expr(h, v->eval, 0); } } - if (PREV_LINK(v)) - fprintf(h, ",\n"); - v = PREV_LINK(v); + if (list_next( enums, &v->entry )) fprintf(h, ",\n"); } fprintf(h, "\n"); } -void write_type(FILE *h, type_t *t, const var_t *v, const char *n) +int needs_space_after(type_t *t) { - int c; + return (t->kind == TKIND_ALIAS + || (!is_ptr(t) && (!is_conformant_array(t) || t->declarray))); +} - if (n) fprintf(h, "%s", n); +void write_type_left(FILE *h, type_t *t, int declonly) +{ + if (!h) return; + + if (t->is_const) fprintf(h, "const "); + + if (t->kind == TKIND_ALIAS) fprintf(h, "%s", t->name); + else if (t->declarray) write_type_left(h, t->ref, declonly); else { - if (t->is_const) fprintf(h, "const "); - if (t->type) { - if (t->sign > 0) fprintf(h, "signed "); - else if (t->sign < 0) fprintf(h, "unsigned "); - switch (t->type) { - case RPC_FC_BYTE: - if (t->ref) fprintf(h, t->ref->name); - else fprintf(h, "byte"); - break; - case RPC_FC_CHAR: - if (t->ref) fprintf(h, t->ref->name); - else fprintf(h, "char"); - break; - case RPC_FC_WCHAR: - fprintf(h, "WCHAR"); - break; - case RPC_FC_USMALL: - case RPC_FC_SMALL: - if (t->ref) fprintf(h, t->ref->name); - else fprintf(h, "small"); - break; - case RPC_FC_USHORT: - case RPC_FC_SHORT: - if (t->ref) fprintf(h, t->ref->name); - else fprintf(h, "short"); - break; - case RPC_FC_ULONG: - case RPC_FC_LONG: - if (t->ref) fprintf(h, t->ref->name); - else fprintf(h, "long"); - break; - case RPC_FC_HYPER: - if (t->ref) fprintf(h, t->ref->name); - else fprintf(h, "hyper"); - break; - case RPC_FC_FLOAT: - fprintf(h, "float"); - break; - case RPC_FC_DOUBLE: - fprintf(h, "double"); - break; + if (t->sign > 0) fprintf(h, "signed "); + else if (t->sign < 0) fprintf(h, "unsigned "); + switch (t->type) { case RPC_FC_ENUM16: case RPC_FC_ENUM32: - if (t->defined && !t->written && !t->ignore) { + if (!declonly && t->defined && !t->written && !t->ignore) { if (t->name) fprintf(h, "enum %s {\n", t->name); else fprintf(h, "enum {\n"); t->written = TRUE; @@ -256,15 +217,7 @@ void write_type(FILE *h, type_t *t, const var_t *v, const char *n) indent(h, -1); fprintf(h, "}"); } - else fprintf(h, "enum %s", t->name); - break; - case RPC_FC_ERROR_STATUS_T: - if (t->ref) fprintf(h, t->ref->name); - else fprintf(h, "error_status_t"); - break; - case RPC_FC_BIND_PRIMITIVE: - if (t->ref) fprintf(h, t->ref->name); - else fprintf(h, "handle_t"); + else fprintf(h, "enum %s", t->name ? t->name : ""); break; case RPC_FC_STRUCT: case RPC_FC_CVSTRUCT: @@ -273,7 +226,7 @@ void write_type(FILE *h, type_t *t, const var_t *v, const char *n) case RPC_FC_PSTRUCT: case RPC_FC_BOGUS_STRUCT: case RPC_FC_ENCAPSULATED_UNION: - if (t->defined && !t->written && !t->ignore) { + if (!declonly && t->defined && !t->written && !t->ignore) { if (t->name) fprintf(h, "struct %s {\n", t->name); else fprintf(h, "struct {\n"); t->written = TRUE; @@ -282,10 +235,10 @@ void write_type(FILE *h, type_t *t, const var_t *v, const char *n) indent(h, -1); fprintf(h, "}"); } - else fprintf(h, "struct %s", t->name); + else fprintf(h, "struct %s", t->name ? t->name : ""); break; case RPC_FC_NON_ENCAPSULATED_UNION: - if (t->defined && !t->written && !t->ignore) { + if (!declonly && t->defined && !t->written && !t->ignore) { if (t->name) fprintf(h, "union %s {\n", t->name); else fprintf(h, "union {\n"); t->written = TRUE; @@ -294,111 +247,159 @@ void write_type(FILE *h, type_t *t, const var_t *v, const char *n) indent(h, -1); fprintf(h, "}"); } - else fprintf(h, "union %s", t->name); + else fprintf(h, "union %s", t->name ? t->name : ""); break; + case RPC_FC_RP: + case RPC_FC_UP: case RPC_FC_FP: - if (t->ref) write_type(h, t->ref, NULL, t->name); - fprintf(h, "*"); + case RPC_FC_OP: + case RPC_FC_CARRAY: + case RPC_FC_CVARRAY: + case RPC_FC_BOGUS_ARRAY: + write_type_left(h, t->ref, declonly); + fprintf(h, "%s*", needs_space_after(t->ref) ? " " : ""); break; default: - fprintf(h, "(unknown-type:%d)", t->type); - } - } - else { - if (t->ref) { - write_type(h, t->ref, NULL, t->name); - } - else fprintf(h, "void"); - } - } - if (v) { - for (c=0; cptr_level; c++) { - fprintf(h, "*"); + fprintf(h, "%s", t->name); } } } - -struct user_type +void write_type_right(FILE *h, type_t *t, int is_field) { - struct user_type *next; - char name[1]; -}; + if (!h) return; -static struct user_type *user_type_list; + if (t->declarray) { + if (is_conformant_array(t)) { + fprintf(h, "[%s]", is_field ? "1" : ""); + t = t->ref; + } + for ( ; t->declarray; t = t->ref) + fprintf(h, "[%lu]", t->dim); + } +} + +void write_type_v(FILE *h, type_t *t, int is_field, int declonly, + const char *fmt, va_list args) +{ + if (!h) return; + + write_type_left(h, t, declonly); + if (fmt) { + if (needs_space_after(t)) + fprintf(h, " "); + vfprintf(h, fmt, args); + } + write_type_right(h, t, is_field); +} + +void write_type_def_or_decl(FILE *f, type_t *t, int field, const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + write_type_v(f, t, field, FALSE, fmt, args); + va_end(args); +} + +void write_type_decl(FILE *f, type_t *t, const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + write_type_v(f, t, FALSE, TRUE, fmt, args); + va_end(args); +} + +void write_type_decl_left(FILE *f, type_t *t) +{ + write_type_left(f, t, TRUE); +} static int user_type_registered(const char *name) { - struct user_type *ut; - for (ut = user_type_list; ut; ut = ut->next) + user_type_t *ut; + LIST_FOR_EACH_ENTRY(ut, &user_type_list, user_type_t, entry) if (!strcmp(name, ut->name)) - return 1; + return 1; return 0; } -static void check_for_user_types(const var_t *v) +static int context_handle_registered(const char *name) { - while (v) { - type_t *type = v->type; - const char *name = v->tname; - for (type = v->type; type; type = type->ref) { + context_handle_t *ch; + LIST_FOR_EACH_ENTRY(ch, &context_handle_list, context_handle_t, entry) + if (!strcmp(name, ch->name)) + return 1; + return 0; +} + +void check_for_user_types_and_context_handles(const var_list_t *list) +{ + const var_t *v; + + if (!list) return; + LIST_FOR_EACH_ENTRY( v, list, const var_t, entry ) + { + type_t *type; + for (type = v->type; type; type = type->kind == TKIND_ALIAS ? type->orig : type->ref) { + const char *name = type->name; if (type->user_types_registered) continue; type->user_types_registered = 1; + if (is_attr(type->attrs, ATTR_CONTEXTHANDLE)) { + if (!context_handle_registered(name)) + { + context_handle_t *ch = xmalloc(sizeof(*ch)); + ch->name = xstrdup(name); + list_add_tail(&context_handle_list, &ch->entry); + } + /* don't carry on parsing fields within this type */ + break; + } if (is_attr(type->attrs, ATTR_WIREMARSHAL)) { if (!user_type_registered(name)) { - struct user_type *ut = xmalloc(sizeof(struct user_type) + strlen(name)); - strcpy(ut->name, name); - ut->next = user_type_list; - user_type_list = ut; + user_type_t *ut = xmalloc(sizeof *ut); + ut->name = xstrdup(name); + list_add_tail(&user_type_list, &ut->entry); } /* don't carry on parsing fields within this type as we are already * using a wire marshaled type */ break; } - else if (type->fields) + else { - const var_t *fields = type->fields; - while (NEXT_LINK(fields)) fields = NEXT_LINK(fields); - check_for_user_types(fields); + check_for_user_types_and_context_handles(type->fields); } - /* the wire_marshal attribute is always at least one reference away - * from the name of the type, so update it after the rest of the - * processing above */ - if (type->name) name = type->name; } - v = PREV_LINK(v); } } void write_user_types(void) { - struct user_type *ut; - for (ut = user_type_list; ut; ut = ut->next) + user_type_t *ut; + LIST_FOR_EACH_ENTRY(ut, &user_type_list, user_type_t, entry) { const char *name = ut->name; - fprintf(header, "unsigned long __RPC_USER %s_UserSize (unsigned long *, unsigned long, %s *);\n", name, name); - fprintf(header, "unsigned char * __RPC_USER %s_UserMarshal (unsigned long *, unsigned char *, %s *);\n", name, name); - fprintf(header, "unsigned char * __RPC_USER %s_UserUnmarshal(unsigned long *, unsigned char *, %s *);\n", name, name); - fprintf(header, "void __RPC_USER %s_UserFree (unsigned long *, %s *);\n", name, name); + fprintf(header, "ULONG __RPC_USER %s_UserSize (ULONG *, ULONG, %s *);\n", name, name); + fprintf(header, "unsigned char * __RPC_USER %s_UserMarshal (ULONG *, unsigned char *, %s *);\n", name, name); + fprintf(header, "unsigned char * __RPC_USER %s_UserUnmarshal(ULONG *, unsigned char *, %s *);\n", name, name); + fprintf(header, "void __RPC_USER %s_UserFree (ULONG *, %s *);\n", name, name); } } -void write_typedef(type_t *type, const var_t *names) +void write_context_handle_rundowns(void) { - const char *tname = names->tname; - const var_t *lname; - while (NEXT_LINK(names)) names = NEXT_LINK(names); - lname = names; - fprintf(header, "typedef "); - write_type(header, type, NULL, tname); - fprintf(header, " "); - while (names) { - write_pident(header, names); - if (PREV_LINK(names)) - fprintf(header, ", "); - names = PREV_LINK(names); + context_handle_t *ch; + LIST_FOR_EACH_ENTRY(ch, &context_handle_list, context_handle_t, entry) + { + const char *name = ch->name; + fprintf(header, "void __RPC_USER %s_rundown(%s);\n", name, name); } +} + +void write_typedef(type_t *type) +{ + fprintf(header, "typedef "); + write_type_def_or_decl(header, type->orig, FALSE, "%s", type->name); fprintf(header, ";\n"); } @@ -408,11 +409,14 @@ void write_expr(FILE *h, const expr_t *e, int brackets) case EXPR_VOID: break; case EXPR_NUM: - fprintf(h, "%ld", e->u.lval); + fprintf(h, "%lu", e->u.lval); break; case EXPR_HEXNUM: fprintf(h, "0x%lx", e->u.lval); break; + case EXPR_DOUBLE: + fprintf(h, "%#.15g", e->u.dval); + break; case EXPR_TRUEFALSE: if (e->u.lval == 0) fprintf(h, "FALSE"); @@ -436,13 +440,13 @@ void write_expr(FILE *h, const expr_t *e, int brackets) break; case EXPR_CAST: fprintf(h, "("); - write_type(h, e->u.tref->ref, NULL, e->u.tref->name); + write_type_decl(h, e->u.tref, NULL); fprintf(h, ")"); write_expr(h, e->ref, 1); break; case EXPR_SIZEOF: fprintf(h, "sizeof("); - write_type(h, e->u.tref->ref, NULL, e->u.tref->name); + write_type_decl(h, e->u.tref, NULL); fprintf(h, ")"); break; case EXPR_SHL: @@ -478,12 +482,16 @@ void write_expr(FILE *h, const expr_t *e, int brackets) write_expr(h, e->ext2, 1); if (brackets) fprintf(h, ")"); break; + case EXPR_ADDRESSOF: + fprintf(h, "&"); + write_expr(h, e->ref, 1); + break; } } void write_constdef(const var_t *v) { - fprintf(header, "#define %s (", get_name(v)); + fprintf(header, "#define %s (", v->name); write_expr(header, v->eval, 0); fprintf(header, ")\n\n"); } @@ -491,18 +499,15 @@ void write_constdef(const var_t *v) void write_externdef(const var_t *v) { fprintf(header, "extern const "); - write_type(header, v->type, NULL, v->tname); - if (get_name(v)) { - fprintf(header, " "); - write_pident(header, v); - } + write_type_def_or_decl(header, v->type, FALSE, "%s", v->name); fprintf(header, ";\n\n"); } -void write_library(const char *name, const attr_t *attr) { +void write_library(const char *name, const attr_list_t *attr) +{ const UUID *uuid = get_attrp(attr, ATTR_UUID); fprintf(header, "\n"); - write_guid("LIBID", name, uuid); + write_guid(header, "LIBID", name, uuid); fprintf(header, "\n"); } @@ -514,85 +519,69 @@ const var_t* get_explicit_handle_var(const func_t* func) if (!func->args) return NULL; - var = func->args; - while (NEXT_LINK(var)) var = NEXT_LINK(var); - while (var) - { + LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) if (var->type->type == RPC_FC_BIND_PRIMITIVE) return var; - var = PREV_LINK(var); - } - return NULL; } int has_out_arg_or_return(const func_t *func) { - var_t *var; + const var_t *var; - if (!is_void(func->def->type, NULL)) + if (!is_void(func->def->type)) return 1; if (!func->args) return 0; - var = func->args; - while (NEXT_LINK(var)) var = NEXT_LINK(var); - while (var) - { + LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) if (is_attr(var->attrs, ATTR_OUT)) return 1; - var = PREV_LINK(var); - } return 0; } /********** INTERFACES **********/ -int is_object(const attr_t *a) +int is_object(const attr_list_t *list) { - while (a) { - if (a->type == ATTR_OBJECT || a->type == ATTR_ODL) return 1; - a = NEXT_LINK(a); - } - return 0; + const attr_t *attr; + if (list) LIST_FOR_EACH_ENTRY( attr, list, const attr_t, entry ) + if (attr->type == ATTR_OBJECT || attr->type == ATTR_ODL) return 1; + return 0; } -int is_local(const attr_t *a) +int is_local(const attr_list_t *a) { return is_attr(a, ATTR_LOCAL); } -const var_t *is_callas(const attr_t *a) +const var_t *is_callas(const attr_list_t *a) { return get_attrp(a, ATTR_CALLAS); } -static int write_method_macro(const type_t *iface, const char *name) +static void write_method_macro(const type_t *iface, const char *name) { - int idx; - func_t *cur = iface->funcs; + const func_t *cur; - if (iface->ref) idx = write_method_macro(iface->ref, name); - else idx = 0; + if (iface->ref) write_method_macro(iface->ref, name); - if (!cur) return idx; - while (NEXT_LINK(cur)) cur = NEXT_LINK(cur); + if (!iface->funcs) return; fprintf(header, "/*** %s methods ***/\n", iface->name); - while (cur) { + LIST_FOR_EACH_ENTRY( cur, iface->funcs, const func_t, entry ) + { var_t *def = cur->def; if (!is_callas(def->attrs)) { - var_t *arg = cur->args; + const var_t *arg; int argc = 0; int c; - while (arg) { - arg = NEXT_LINK(arg); - argc++; - } + + if (cur->args) LIST_FOR_EACH_ENTRY( arg, cur->args, const var_t, entry ) argc++; fprintf(header, "#define %s_", name); write_name(header,def); @@ -607,22 +596,15 @@ static int write_method_macro(const type_t *iface, const char *name) for (c=0; cidx == -1) cur->idx = idx; - else if (cur->idx != idx) yyerror("BUG: method index mismatch in write_method_macro"); - idx++; } - cur = PREV_LINK(cur); } - return idx; } -void write_args(FILE *h, var_t *arg, const char *name, int method, int do_indent) +void write_args(FILE *h, const var_list_t *args, const char *name, int method, int do_indent) { + const var_t *arg; int count = 0; - if (arg) { - while (NEXT_LINK(arg)) - arg = NEXT_LINK(arg); - } + if (do_indent) { indentation++; @@ -632,7 +614,7 @@ void write_args(FILE *h, var_t *arg, const char *name, int method, int do_indent fprintf(h, "%s* This", name); count++; } - while (arg) { + if (args) LIST_FOR_EACH_ENTRY( arg, args, const var_t, entry ) { if (count) { if (do_indent) { @@ -641,9 +623,9 @@ void write_args(FILE *h, var_t *arg, const char *name, int method, int do_indent } else fprintf(h, ","); } - write_type(h, arg->type, arg, arg->tname); if (arg->args) { + write_type_decl_left(h, arg->type); fprintf(h, " (STDMETHODCALLTYPE *"); write_name(h,arg); fprintf(h, ")("); @@ -651,12 +633,7 @@ void write_args(FILE *h, var_t *arg, const char *name, int method, int do_indent fprintf(h, ")"); } else - { - fprintf(h, " "); - write_name(h, arg); - } - write_array(h, arg->array, 0); - arg = PREV_LINK(arg); + write_type_decl(h, arg->type, "%s", arg->name); count++; } if (do_indent) indentation--; @@ -664,16 +641,17 @@ void write_args(FILE *h, var_t *arg, const char *name, int method, int do_indent static void write_cpp_method_def(const type_t *iface) { - func_t *cur = iface->funcs; + const func_t *cur; - if (!cur) return; - while (NEXT_LINK(cur)) cur = NEXT_LINK(cur); - while (cur) { + if (!iface->funcs) return; + + LIST_FOR_EACH_ENTRY( cur, iface->funcs, const func_t, entry ) + { var_t *def = cur->def; if (!is_callas(def->attrs)) { indent(header, 0); fprintf(header, "virtual "); - write_type(header, def->type, def, def->tname); + write_type_decl_left(header, def->type); fprintf(header, " STDMETHODCALLTYPE "); write_name(header, def); fprintf(header, "(\n"); @@ -681,25 +659,24 @@ static void write_cpp_method_def(const type_t *iface) fprintf(header, ") = 0;\n"); fprintf(header, "\n"); } - cur = PREV_LINK(cur); } } static void do_write_c_method_def(const type_t *iface, const char *name) { - const func_t *cur = iface->funcs; + const func_t *cur; if (iface->ref) do_write_c_method_def(iface->ref, name); - if (!cur) return; - while (NEXT_LINK(cur)) cur = NEXT_LINK(cur); + if (!iface->funcs) return; indent(header, 0); fprintf(header, "/*** %s methods ***/\n", iface->name); - while (cur) { + LIST_FOR_EACH_ENTRY( cur, iface->funcs, const func_t, entry ) + { const var_t *def = cur->def; if (!is_callas(def->attrs)) { indent(header, 0); - write_type(header, def->type, def, def->tname); + write_type_decl_left(header, def->type); fprintf(header, " (STDMETHODCALLTYPE *"); write_name(header, def); fprintf(header, ")(\n"); @@ -707,7 +684,6 @@ static void do_write_c_method_def(const type_t *iface, const char *name) fprintf(header, ");\n"); fprintf(header, "\n"); } - cur = PREV_LINK(cur); } } @@ -723,17 +699,16 @@ static void write_c_disp_method_def(const type_t *iface) static void write_method_proto(const type_t *iface) { - const func_t *cur = iface->funcs; + const func_t *cur; - if (!cur) return; - while (NEXT_LINK(cur)) cur = NEXT_LINK(cur); - while (cur) { + if (!iface->funcs) return; + LIST_FOR_EACH_ENTRY( cur, iface->funcs, const func_t, entry ) + { const var_t *def = cur->def; - const var_t *cas = is_callas(def->attrs); - const var_t *args; + if (!is_local(def->attrs)) { /* proxy prototype */ - write_type(header, def->type, def, def->tname); + write_type_decl_left(header, def->type); fprintf(header, " CALLBACK %s_", iface->name); write_name(header, def); fprintf(header, "_Proxy(\n"); @@ -747,53 +722,101 @@ static void write_method_proto(const type_t *iface) fprintf(header, " IRpcChannelBuffer* pRpcChannelBuffer,\n"); fprintf(header, " PRPC_MESSAGE pRpcMessage,\n"); fprintf(header, " DWORD* pdwStubPhase);\n"); - - args = cur->args; - if (args) { - while (NEXT_LINK(args)) - args = NEXT_LINK(args); - } - check_for_user_types(args); } - if (cas) { - const func_t *m = iface->funcs; - while (m && strcmp(get_name(m->def), cas->name)) - m = NEXT_LINK(m); - if (m) { - const var_t *mdef = m->def; - /* proxy prototype - use local prototype */ - write_type(header, mdef->type, mdef, mdef->tname); - fprintf(header, " CALLBACK %s_", iface->name); - write_name(header, mdef); - fprintf(header, "_Proxy(\n"); - write_args(header, m->args, iface->name, 1, TRUE); - fprintf(header, ");\n"); - /* stub prototype - use remotable prototype */ - write_type(header, def->type, def, def->tname); - fprintf(header, " __RPC_STUB %s_", iface->name); - write_name(header, mdef); - fprintf(header, "_Stub(\n"); - write_args(header, cur->args, iface->name, 1, TRUE); - fprintf(header, ");\n"); - } - else { - yywarning("invalid call_as attribute (%s -> %s)\n", get_name(def), cas->name); - } - } - - cur = PREV_LINK(cur); } } -static void write_function_proto(const type_t *iface) +void write_locals(FILE *fp, const type_t *iface, int body) +{ + static const char comment[] + = "/* WIDL-generated stub. You must provide an implementation for this. */"; + const func_list_t *funcs = iface->funcs; + const func_t *cur; + + if (!is_object(iface->attrs) || !funcs) + return; + + LIST_FOR_EACH_ENTRY(cur, funcs, const func_t, entry) { + const var_t *def = cur->def; + const var_t *cas = is_callas(def->attrs); + + if (cas) { + const func_t *m; + LIST_FOR_EACH_ENTRY(m, iface->funcs, const func_t, entry) + if (!strcmp(m->def->name, cas->name)) + break; + if (&m->entry != iface->funcs) { + const var_t *mdef = m->def; + /* proxy prototype - use local prototype */ + write_type_decl_left(fp, mdef->type); + fprintf(fp, " CALLBACK %s_", iface->name); + write_name(fp, mdef); + fprintf(fp, "_Proxy(\n"); + write_args(fp, m->args, iface->name, 1, TRUE); + fprintf(fp, ")"); + if (body) { + type_t *rt = mdef->type; + fprintf(fp, "\n{\n"); + fprintf(fp, " %s\n", comment); + if (rt->name && strcmp(rt->name, "HRESULT") == 0) + fprintf(fp, " return E_NOTIMPL;\n"); + else if (rt->type) { + fprintf(fp, " "); + write_type_decl(fp, rt, "rv"); + fprintf(fp, ";\n"); + fprintf(fp, " memset(&rv, 0, sizeof rv);\n"); + fprintf(fp, " return rv;\n"); + } + fprintf(fp, "}\n\n"); + } + else + fprintf(fp, ";\n"); + /* stub prototype - use remotable prototype */ + write_type_decl_left(fp, def->type); + fprintf(fp, " __RPC_STUB %s_", iface->name); + write_name(fp, mdef); + fprintf(fp, "_Stub(\n"); + write_args(fp, cur->args, iface->name, 1, TRUE); + fprintf(fp, ")"); + if (body) + /* Remotable methods must all return HRESULTs. */ + fprintf(fp, "\n{\n %s\n return E_NOTIMPL;\n}\n\n", comment); + else + fprintf(fp, ";\n"); + } + else + error_loc("invalid call_as attribute (%s -> %s)\n", def->name, cas->name); + } + } +} + +static void write_function_proto(const type_t *iface, const func_t *fun, const char *prefix) +{ + var_t *def = fun->def; + + /* FIXME: do we need to handle call_as? */ + write_type_decl_left(header, def->type); + fprintf(header, " "); + write_prefix_name(header, prefix, def); + fprintf(header, "(\n"); + if (fun->args) + write_args(header, fun->args, iface->name, 0, TRUE); + else + fprintf(header, " void"); + fprintf(header, ");\n"); +} + +static void write_function_protos(const type_t *iface) { const char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE); int explicit_handle = is_attr(iface->attrs, ATTR_EXPLICIT_HANDLE); const var_t* explicit_handle_var; + const func_t *cur; + int prefixes_differ = strcmp(prefix_client, prefix_server); - func_t *cur = iface->funcs; - while (NEXT_LINK(cur)) cur = NEXT_LINK(cur); - while (cur) { + if (!iface->funcs) return; + LIST_FOR_EACH_ENTRY( cur, iface->funcs, const func_t, entry ) + { var_t *def = cur->def; /* check for a defined binding handle */ @@ -810,18 +833,12 @@ static void write_function_proto(const type_t *iface) } } - /* FIXME: do we need to handle call_as? */ - write_type(header, def->type, def, def->tname); - fprintf(header, " "); - write_name(header, def); - fprintf(header, "(\n"); - if (cur->args) - write_args(header, cur->args, iface->name, 0, TRUE); - else - fprintf(header, " void"); - fprintf(header, ");\n"); - - cur = PREV_LINK(cur); + if (prefixes_differ) { + fprintf(header, "/* client prototype */\n"); + write_function_proto(iface, cur, prefix_client); + fprintf(header, "/* server prototype */\n"); + } + write_function_proto(iface, cur, prefix_server); } } @@ -845,25 +862,25 @@ void write_forward(type_t *iface) static void write_iface_guid(const type_t *iface) { const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID); - write_guid("IID", iface->name, uuid); -} + write_guid(header, "IID", iface->name, uuid); +} static void write_dispiface_guid(const type_t *iface) { const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID); - write_guid("DIID", iface->name, uuid); + write_guid(header, "DIID", iface->name, uuid); } static void write_coclass_guid(type_t *cocl) { const UUID *uuid = get_attrp(cocl->attrs, ATTR_UUID); - write_guid("CLSID", cocl->name, uuid); + write_guid(header, "CLSID", cocl->name, uuid); } static void write_com_interface(type_t *iface) { if (!iface->funcs && !iface->ref) { - yywarning("%s has no methods", iface->name); + parser_warning("%s has no methods\n", iface->name); return; } @@ -908,7 +925,7 @@ static void write_com_interface(type_t *iface) fprintf(header, " END_INTERFACE\n"); fprintf(header, "} %sVtbl;\n", iface->name); fprintf(header, "interface %s {\n", iface->name); - fprintf(header, " const %sVtbl* lpVtbl;\n", iface->name); + fprintf(header, " CONST_VTBL %sVtbl* lpVtbl;\n", iface->name); fprintf(header, "};\n"); fprintf(header, "\n"); fprintf(header, "#ifdef COBJMACROS\n"); @@ -918,12 +935,13 @@ static void write_com_interface(type_t *iface) fprintf(header, "#endif\n"); fprintf(header, "\n"); write_method_proto(iface); + write_locals(header, iface, FALSE); fprintf(header,"\n#endif /* __%s_INTERFACE_DEFINED__ */\n\n", iface->name); } static void write_rpc_interface(const type_t *iface) { - unsigned long ver = get_attrv(iface->attrs, ATTR_VERSION); + unsigned int ver = get_attrv(iface->attrs, ATTR_VERSION); const char *var = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE); static int allocate_written = 0; @@ -935,7 +953,7 @@ static void write_rpc_interface(const type_t *iface) } fprintf(header, "/*****************************************************************************\n"); - fprintf(header, " * %s interface (v%d.%d)\n", iface->name, LOWORD(ver), HIWORD(ver)); + fprintf(header, " * %s interface (v%d.%d)\n", iface->name, MAJORVERSION(ver), MINORVERSION(ver)); fprintf(header, " */\n"); fprintf(header,"#ifndef __%s_INTERFACE_DEFINED__\n", iface->name); fprintf(header,"#define __%s_INTERFACE_DEFINED__\n\n", iface->name); @@ -945,15 +963,17 @@ static void write_rpc_interface(const type_t *iface) if (var) fprintf(header, "extern handle_t %s;\n", var); if (old_names) { - fprintf(header, "extern RPC_IF_HANDLE %s_ClientIfHandle;\n", iface->name); - fprintf(header, "extern RPC_IF_HANDLE %s_ServerIfHandle;\n", iface->name); + fprintf(header, "extern RPC_IF_HANDLE %s%s_ClientIfHandle;\n", prefix_client, iface->name); + fprintf(header, "extern RPC_IF_HANDLE %s%s_ServerIfHandle;\n", prefix_server, iface->name); } else { - fprintf(header, "extern RPC_IF_HANDLE %s_v%d_%d_c_ifspec;\n", iface->name, LOWORD(ver), HIWORD(ver)); - fprintf(header, "extern RPC_IF_HANDLE %s_v%d_%d_s_ifspec;\n", iface->name, LOWORD(ver), HIWORD(ver)); + fprintf(header, "extern RPC_IF_HANDLE %s%s_v%d_%d_c_ifspec;\n", + prefix_client, iface->name, MAJORVERSION(ver), MINORVERSION(ver)); + fprintf(header, "extern RPC_IF_HANDLE %s%s_v%d_%d_s_ifspec;\n", + prefix_server, iface->name, MAJORVERSION(ver), MINORVERSION(ver)); } - write_function_proto(iface); + write_function_protos(iface); } fprintf(header,"\n#endif /* __%s_INTERFACE_DEFINED__ */\n\n", iface->name); @@ -993,7 +1013,7 @@ void write_dispinterface(type_t *iface) fprintf(header, " END_INTERFACE\n"); fprintf(header, "} %sVtbl;\n", iface->name); fprintf(header, "interface %s {\n", iface->name); - fprintf(header, " const %sVtbl* lpVtbl;\n", iface->name); + fprintf(header, " CONST_VTBL %sVtbl* lpVtbl;\n", iface->name); fprintf(header, "};\n"); fprintf(header, "\n"); fprintf(header, "#ifdef COBJMACROS\n"); diff --git a/reactos/tools/widl/header.h b/reactos/tools/widl/header.h index 5863f3b0eff..41784a0b152 100644 --- a/reactos/tools/widl/header.h +++ b/reactos/tools/widl/header.h @@ -21,42 +21,73 @@ #ifndef __WIDL_HEADER_H #define __WIDL_HEADER_H -extern int is_attr(const attr_t *a, enum attr_type t); -extern void *get_attrp(const attr_t *a, enum attr_type t); -extern unsigned long get_attrv(const attr_t *a, enum attr_type t); -extern int is_void(const type_t *t, const var_t *v); +#include "widltypes.h" + +extern int is_ptrchain_attr(const var_t *var, enum attr_type t); +extern int is_attr(const attr_list_t *list, enum attr_type t); +extern void *get_attrp(const attr_list_t *list, enum attr_type t); +extern unsigned long get_attrv(const attr_list_t *list, enum attr_type t); +extern int is_void(const type_t *t); +extern int is_conformant_array(const type_t *t); +extern int is_declptr(const type_t *t); extern void write_name(FILE *h, const var_t *v); +extern void write_prefix_name(FILE *h, const char *prefix, const var_t *v); extern const char* get_name(const var_t *v); -extern void write_type(FILE *h, type_t *t, const var_t *v, const char *n); -extern int is_object(const attr_t *a); -extern int is_local(const attr_t *a); -extern const var_t *is_callas(const attr_t *a); -extern void write_args(FILE *h, var_t *arg, const char *name, int obj, int do_indent); -extern void write_array(FILE *h, const expr_t *v, int field); +extern void write_type_left(FILE *h, type_t *t, int declonly); +extern void write_type_right(FILE *h, type_t *t, int is_field); +extern void write_type_def_or_decl(FILE *h, type_t *t, int is_field, const char *fmt, ...); +extern void write_type_decl(FILE *f, type_t *t, const char *fmt, ...); +extern void write_type_decl_left(FILE *f, type_t *t); +extern int needs_space_after(type_t *t); +extern int is_object(const attr_list_t *list); +extern int is_local(const attr_list_t *list); +extern int need_stub(const type_t *iface); +extern int need_proxy(const type_t *iface); +extern int need_stub_files(const ifref_list_t *ifaces); +extern int need_proxy_file(const ifref_list_t *ifaces); +extern const var_t *is_callas(const attr_list_t *list); +extern void write_args(FILE *h, const var_list_t *arg, const char *name, int obj, int do_indent); +extern void write_array(FILE *h, array_dims_t *v, int field); extern void write_forward(type_t *iface); extern void write_interface(type_t *iface); extern void write_dispinterface(type_t *iface); +extern void write_locals(FILE *fp, const type_t *iface, int body); extern void write_coclass(type_t *cocl); extern void write_coclass_forward(type_t *cocl); -extern void write_typedef(type_t *type, const var_t *names); +extern void write_typedef(type_t *type); extern void write_expr(FILE *h, const expr_t *e, int brackets); extern void write_constdef(const var_t *v); extern void write_externdef(const var_t *v); -extern void write_library(const char *name, const attr_t *attr); +extern void write_library(const char *name, const attr_list_t *attr); extern void write_user_types(void); +extern void write_context_handle_rundowns(void); extern const var_t* get_explicit_handle_var(const func_t* func); extern int has_out_arg_or_return(const func_t *func); +extern void write_guid(FILE *f, const char *guid_prefix, const char *name, + const UUID *uuid); -static inline int is_string_type(const attr_t *attrs, int ptr_level, const expr_t *array) +static inline int last_ptr(const type_t *type) { - return (is_attr(attrs, ATTR_STRING) && - ((ptr_level == 1 && !array) || (ptr_level == 0 && array))); + return is_ptr(type) && !is_declptr(type->ref); } -static inline int is_array_type(const attr_t *attrs, int ptr_level, const expr_t *array) +static inline int last_array(const type_t *type) { - return ((ptr_level == 1 && !array && is_attr(attrs, ATTR_SIZEIS)) || - (ptr_level == 0 && array)); + return is_array(type) && !is_array(type->ref); +} + +static inline int is_string_type(const attr_list_t *attrs, const type_t *type) +{ + return is_attr(attrs, ATTR_STRING) && (last_ptr(type) || last_array(type)); +} + +static inline int is_context_handle(const type_t *type) +{ + const type_t *t; + for (t = type; is_ptr(t); t = t->ref) + if (is_attr(t->attrs, ATTR_CONTEXTHANDLE)) + return 1; + return 0; } #endif diff --git a/reactos/tools/widl/lex.yy.c b/reactos/tools/widl/lex.yy.c deleted file mode 100644 index c5601a7d0cc..00000000000 --- a/reactos/tools/widl/lex.yy.c +++ /dev/null @@ -1,5082 +0,0 @@ -#line 2 "lex.yy.c" -/* A lexical scanner generated by flex */ - -/* Scanner skeleton version: - * $Header: /home/daffy/u0/vern/flex/RCS/flex.skl,v 2.91 96/09/10 16:58:48 vern Exp $ - */ - -#define FLEX_SCANNER -#define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 5 - -#include - - -/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ -#ifdef c_plusplus -#ifndef __cplusplus -#define __cplusplus -#endif -#endif - - -#ifdef __cplusplus - -#include -#include - -/* Use prototypes in function declarations. */ -#define YY_USE_PROTOS - -/* The "const" storage-class-modifier is valid. */ -#define YY_USE_CONST - -#else /* ! __cplusplus */ - -#if __STDC__ - -#define YY_USE_PROTOS -#define YY_USE_CONST - -#endif /* __STDC__ */ -#endif /* ! __cplusplus */ - -#ifdef __TURBOC__ - #pragma warn -rch - #pragma warn -use -#include -#include -#define YY_USE_CONST -#define YY_USE_PROTOS -#endif - -#ifdef YY_USE_CONST -#define yyconst const -#else -#define yyconst -#endif - - -#ifdef YY_USE_PROTOS -#define YY_PROTO(proto) proto -#else -#define YY_PROTO(proto) () -#endif - -/* Returned upon end-of-file. */ -#define YY_NULL 0 - -/* Promotes a possibly negative, possibly signed char to an unsigned - * integer for use as an array index. If the signed char is negative, - * we want to instead treat it as an 8-bit unsigned char, hence the - * double cast. - */ -#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) - -/* Enter a start condition. This macro really ought to take a parameter, - * but we do it the disgusting crufty way forced on us by the ()-less - * definition of BEGIN. - */ -#define BEGIN yy_start = 1 + 2 * - -/* Translate the current start state into a value that can be later handed - * to BEGIN to return to the state. The YYSTATE alias is for lex - * compatibility. - */ -#define YY_START ((yy_start - 1) / 2) -#define YYSTATE YY_START - -/* Action number for EOF rule of a given start state. */ -#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) - -/* Special action meaning "start processing a new file". */ -#define YY_NEW_FILE yyrestart( yyin ) - -#define YY_END_OF_BUFFER_CHAR 0 - -/* Size of default input buffer. */ -#define YY_BUF_SIZE 16384 - -typedef struct yy_buffer_state *YY_BUFFER_STATE; - -extern int yyleng; -extern FILE *yyin, *yyout; - -#define EOB_ACT_CONTINUE_SCAN 0 -#define EOB_ACT_END_OF_FILE 1 -#define EOB_ACT_LAST_MATCH 2 - -/* The funky do-while in the following #define is used to turn the definition - * int a single C statement (which needs a semi-colon terminator). This - * avoids problems with code like: - * - * if ( condition_holds ) - * yyless( 5 ); - * else - * do_something_else(); - * - * Prior to using the do-while the compiler would get upset at the - * "else" because it interpreted the "if" statement as being all - * done when it reached the ';' after the yyless() call. - */ - -/* Return all but the first 'n' matched characters back to the input stream. */ - -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - *yy_cp = yy_hold_char; \ - YY_RESTORE_YY_MORE_OFFSET \ - yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \ - YY_DO_BEFORE_ACTION; /* set up yytext again */ \ - } \ - while ( 0 ) - -#define unput(c) yyunput( c, yytext_ptr ) - -/* The following is because we cannot portably get our hands on size_t - * (without autoconf's help, which isn't available because we want - * flex-generated scanners to compile on their own). - */ -typedef unsigned int yy_size_t; - - -struct yy_buffer_state - { - FILE *yy_input_file; - - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ - - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ - yy_size_t yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ - int yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to - * delete it. - */ - int yy_is_our_buffer; - - /* Whether this is an "interactive" input source; if so, and - * if we're using stdio for input, then we want to use getc() - * instead of fread(), to make sure we stop fetching input after - * each newline. - */ - int yy_is_interactive; - - /* Whether we're considered to be at the beginning of a line. - * If so, '^' rules will be active on the next match, otherwise - * not. - */ - int yy_at_bol; - - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ - int yy_fill_buffer; - - int yy_buffer_status; -#define YY_BUFFER_NEW 0 -#define YY_BUFFER_NORMAL 1 - /* When an EOF's been seen but there's still some text to process - * then we mark the buffer as YY_EOF_PENDING, to indicate that we - * shouldn't try reading from the input source any more. We might - * still have a bunch of tokens to match, though, because of - * possible backing-up. - * - * When we actually see the EOF, we change the status to "new" - * (via yyrestart()), so that the user can continue scanning by - * just pointing yyin at a new input file. - */ -#define YY_BUFFER_EOF_PENDING 2 - }; - -static YY_BUFFER_STATE yy_current_buffer = 0; - -/* We provide macros for accessing buffer states in case in the - * future we want to put the buffer states in a more general - * "scanner state". - */ -#define YY_CURRENT_BUFFER yy_current_buffer - - -/* yy_hold_char holds the character lost when yytext is formed. */ -static char yy_hold_char; - -static int yy_n_chars; /* number of characters read into yy_ch_buf */ - - -int yyleng; - -/* Points to current character in buffer. */ -static char *yy_c_buf_p = (char *) 0; -static int yy_init = 1; /* whether we need to initialize */ -static int yy_start = 0; /* start state number */ - -/* Flag which is used to allow yywrap()'s to do buffer switches - * instead of setting up a fresh yyin. A bit of a hack ... - */ -static int yy_did_buffer_switch_on_eof; - -void yyrestart YY_PROTO(( FILE *input_file )); - -void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer )); -void yy_load_buffer_state YY_PROTO(( void )); -YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size )); -void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b )); -void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file )); -void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b )); -#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer ) - -YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size )); -YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str )); -YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len )); - -static void *yy_flex_alloc YY_PROTO(( yy_size_t )); -static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t )); -static void yy_flex_free YY_PROTO(( void * )); - -#define yy_new_buffer yy_create_buffer - -#define yy_set_interactive(is_interactive) \ - { \ - if ( ! yy_current_buffer ) \ - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ - yy_current_buffer->yy_is_interactive = is_interactive; \ - } - -#define yy_set_bol(at_bol) \ - { \ - if ( ! yy_current_buffer ) \ - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ - yy_current_buffer->yy_at_bol = at_bol; \ - } - -#define YY_AT_BOL() (yy_current_buffer->yy_at_bol) - - -#define FLEX_DEBUG -typedef unsigned char YY_CHAR; -FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; -typedef int yy_state_type; - -#define FLEX_DEBUG -extern char *yytext; -#define yytext_ptr yytext -static yyconst short yy_nxt[][256] = - { - { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0 - }, - - { - 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, - 10, 8, 9, 9, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 9, 8, 11, 8, 8, 8, 8, 8, - - 8, 8, 8, 8, 8, 8, 8, 8, 12, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 8, 8, - 14, 8, 15, 8, 8, 16, 16, 16, 16, 16, - 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 18, 17, 17, 17, 17, 17, 17, - 17, 8, 8, 8, 8, 17, 8, 16, 16, 16, - 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8 - }, - - { - 7, 8, 8, 8, 8, 8, 8, 8, 8, 19, - 10, 8, 19, 19, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 19, 8, 11, 20, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 12, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 8, 8, - 14, 8, 15, 8, 8, 16, 16, 16, 16, 16, - 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, - - 17, 17, 17, 18, 17, 17, 17, 17, 17, 17, - 17, 8, 8, 8, 8, 17, 8, 16, 16, 16, - 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8 - }, - - { - 7, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 22, 21, 21, 21, 21, 21, 21, 21, 21, 21, - - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 23, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 24, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21 - }, - - { - 7, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 22, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 23, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 24, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21 - - }, - - { - 7, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 22, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25 - }, - - { - 7, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 22, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25 - }, - - { - -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, - -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, - -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, - -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, - -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, - -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, - -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, - -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, - - -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, - -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, - -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, - -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, - -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, - -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, - -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, - -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, - -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, - -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, - - -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, - -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, - -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, - -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, - -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, - -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, - -7, -7, -7, -7, -7, -7, -7, -7, -7, -7, - -7, -7, -7, -7, -7, -7 - }, - - { - 7, -8, -8, -8, -8, -8, -8, -8, -8, -8, - -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, - - -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, - -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, - -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, - -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, - -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, - -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, - -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, - -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, - -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, - -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, - - -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, - -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, - -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, - -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, - -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, - -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, - -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, - -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, - -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, - -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, - - -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, - -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, - -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, - -8, -8, -8, -8, -8, -8 - }, - - { - 7, -9, -9, -9, -9, -9, -9, -9, -9, -9, - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, - - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, - - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, - -9, -9, -9, -9, -9, -9 - - }, - - { - 7, -10, -10, -10, -10, -10, -10, -10, -10, -10, - -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, - -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, - -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, - -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, - -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, - -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, - -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, - -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, - -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, - - -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, - -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, - -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, - -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, - -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, - -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, - -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, - -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, - -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, - -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, - - -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, - -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, - -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, - -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, - -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, - -10, -10, -10, -10, -10, -10 - }, - - { - 7, -11, -11, -11, -11, -11, -11, -11, -11, -11, - -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, - -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, - -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, - - -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, - -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, - -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, - -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, - -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, - -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, - -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, - -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, - -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, - -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, - - -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, - -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, - -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, - -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, - -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, - -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, - -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, - -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, - -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, - -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, - - -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, - -11, -11, -11, -11, -11, -11 - }, - - { - 7, -12, -12, -12, -12, -12, -12, -12, -12, -12, - -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, - -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, - -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, - -12, -12, -12, -12, -12, -12, -12, -12, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, -12, -12, - -12, -12, -12, -12, -12, 27, 27, 27, 27, 27, - 27, -12, -12, -12, -12, -12, -12, -12, -12, -12, - - -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, - -12, -12, -12, -12, -12, -12, -12, 27, 27, 27, - 27, 27, 27, -12, -12, -12, -12, -12, -12, -12, - -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, - 28, -12, -12, -12, -12, -12, -12, -12, -12, -12, - -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, - -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, - -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, - -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, - -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, - - -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, - -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, - -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, - -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, - -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, - -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, - -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, - -12, -12, -12, -12, -12, -12 - }, - - { - 7, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13, -13, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, -13, -13, - -13, -13, -13, -13, -13, 27, 27, 27, 27, 27, - 27, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13, 27, 27, 27, - 27, 27, 27, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, -13 - }, - - { - 7, -14, -14, -14, -14, -14, -14, -14, -14, -14, - -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, - -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, - -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, - -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, - -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, - - 29, -14, -14, -14, -14, -14, -14, -14, -14, -14, - -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, - -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, - -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, - -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, - -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, - -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, - -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, - -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, - -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, - - -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, - -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, - -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, - -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, - -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, - -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, - -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, - -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, - -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, - -14, -14, -14, -14, -14, -14 - - }, - - { - 7, -15, -15, -15, -15, -15, -15, -15, -15, -15, - -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, - -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, - -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, - -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, - -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, - -15, -15, 30, -15, -15, -15, -15, -15, -15, -15, - -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, - -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, - -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, - - -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, - -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, - -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, - -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, - -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, - -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, - -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, - -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, - -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, - -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, - - -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, - -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, - -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, - -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, - -15, -15, -15, -15, -15, -15, -15, -15, -15, -15, - -15, -15, -15, -15, -15, -15 - }, - - { - 7, -16, -16, -16, -16, -16, -16, -16, -16, -16, - -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, - -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, - -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, - - -16, -16, -16, -16, -16, -16, -16, -16, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, -16, -16, - -16, -16, -16, -16, -16, 31, 31, 31, 31, 31, - 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, -16, -16, -16, -16, 32, -16, 31, 31, 31, - 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, -16, -16, -16, -16, -16, -16, -16, - -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, - - -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, - -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, - -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, - -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, - -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, - -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, - -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, - -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, - -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, - -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, - - -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, - -16, -16, -16, -16, -16, -16 - }, - - { - 7, -17, -17, -17, -17, -17, -17, -17, -17, -17, - -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, - -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, - -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, - -17, -17, -17, -17, -17, -17, -17, -17, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, -17, -17, - -17, -17, -17, -17, -17, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, -17, -17, -17, -17, 32, -17, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, -17, -17, -17, -17, -17, -17, -17, - -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, - -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, - -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, - -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, - -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, - - -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, - -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, - -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, - -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, - -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, - -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, - -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, - -17, -17, -17, -17, -17, -17 - }, - - { - 7, -18, -18, -18, -18, -18, -18, -18, -18, -18, - -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, - - -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, - -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, - -18, -18, -18, -18, -18, -18, -18, -18, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, -18, -18, - -18, -18, -18, -18, -18, 33, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, -18, -18, -18, -18, 32, -18, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - - 32, 32, 32, -18, -18, -18, -18, -18, -18, -18, - -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, - -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, - -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, - -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, - -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, - -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, - -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, - -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, - -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, - - -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, - -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, - -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, - -18, -18, -18, -18, -18, -18 - }, - - { - 7, -19, -19, -19, -19, -19, -19, -19, -19, 34, - -19, -19, 34, 34, -19, -19, -19, -19, -19, -19, - -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, - -19, -19, 34, -19, -19, 35, -19, -19, -19, -19, - -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, - -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, - - -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, - -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, - -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, - -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, - -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, - -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, - -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, - -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, - -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, - -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, - - -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, - -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, - -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, - -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, - -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, - -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, - -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, - -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, - -19, -19, -19, -19, -19, -19, -19, -19, -19, -19, - -19, -19, -19, -19, -19, -19 - - }, - - { - 7, -20, -20, -20, -20, -20, -20, -20, -20, 36, - -20, -20, 36, 36, -20, -20, -20, -20, -20, -20, - -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, - -20, -20, 36, -20, -20, -20, -20, -20, -20, -20, - -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, - -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, - -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, - -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, - -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, - -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, - - -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, - -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, - -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, - -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, - -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, - -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, - -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, - -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, - -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, - -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, - - -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, - -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, - -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, - -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, - -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, - -20, -20, -20, -20, -20, -20 - }, - - { - 7, -21, -21, -21, -21, -21, -21, -21, -21, -21, - -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, - -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, - -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, - - -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, - -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, - -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, - -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, - -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, - -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, - -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, - -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, - -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, - -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, - - -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, - -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, - -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, - -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, - -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, - -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, - -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, - -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, - -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, - -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, - - -21, -21, -21, -21, -21, -21, -21, -21, -21, -21, - -21, -21, -21, -21, -21, -21 - }, - - { - 7, -22, -22, -22, -22, -22, -22, -22, -22, -22, - -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, - -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, - -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, - -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, - -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, - -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, - -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, - - -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, - -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, - -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, - -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, - -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, - -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, - -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, - -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, - -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, - -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, - - -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, - -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, - -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, - -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, - -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, - -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, - -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, - -22, -22, -22, -22, -22, -22 - }, - - { - 7, -23, -23, -23, -23, -23, -23, -23, -23, -23, - -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, - - -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, - -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, - -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, - -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, - -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, - -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, - -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, - -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, - -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, - -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, - - -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, - -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, - -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, - -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, - -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, - -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, - -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, - -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, - -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, - -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, - - -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, - -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, - -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, - -23, -23, -23, -23, -23, -23 - }, - - { - 7, 37, 37, 37, 37, 37, 37, 37, 37, 37, - -24, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 38, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 39, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37 - - }, - - { - 7, 40, 40, 40, 40, 40, 40, 40, 40, 40, - -25, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40 - }, - - { - 7, -26, -26, -26, -26, -26, -26, -26, -26, -26, - -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, - -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, - -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, - - -26, -26, -26, -26, -26, -26, -26, -26, 41, 41, - 41, 41, 41, 41, 41, 41, 41, 41, -26, -26, - -26, -26, -26, -26, -26, 42, 42, 42, 42, 42, - 42, -26, -26, -26, -26, -26, -26, -26, -26, -26, - -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, - -26, -26, -26, -26, -26, -26, -26, 42, 42, 42, - 42, 42, 42, -26, -26, -26, -26, -26, -26, -26, - -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, - -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, - -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, - - -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, - -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, - -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, - -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, - -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, - -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, - -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, - -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, - -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, - -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, - - -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, - -26, -26, -26, -26, -26, -26 - }, - - { - 7, -27, -27, -27, -27, -27, -27, -27, -27, -27, - -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, - -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, - -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, - -27, -27, -27, -27, -27, -27, -27, -27, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, -27, -27, - -27, -27, -27, -27, -27, 42, 42, 42, 42, 42, - 42, -27, -27, -27, -27, -27, -27, -27, -27, -27, - - -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, - -27, -27, -27, -27, -27, -27, -27, 42, 42, 42, - 42, 42, 42, -27, -27, -27, -27, -27, -27, -27, - -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, - -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, - -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, - -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, - -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, - -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, - -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, - - -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, - -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, - -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, - -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, - -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, - -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, - -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, - -27, -27, -27, -27, -27, -27 - }, - - { - 7, -28, -28, -28, -28, -28, -28, -28, -28, -28, - -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, - - -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, - -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, - -28, -28, -28, -28, -28, -28, -28, -28, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 43, -28, -28, - -28, -28, -28, -28, -28, 43, 43, 43, 43, 43, - 43, -28, -28, -28, -28, -28, -28, -28, -28, -28, - -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, - -28, -28, -28, -28, -28, -28, -28, 43, 43, 43, - 43, 43, 43, -28, -28, -28, -28, -28, -28, -28, - -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, - - -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, - -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, - -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, - -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, - -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, - -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, - -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, - -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, - -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, - -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, - - -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, - -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, - -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, - -28, -28, -28, -28, -28, -28 - }, - - { - 7, -29, -29, -29, -29, -29, -29, -29, -29, -29, - -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, - -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, - -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, - -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, - -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, - - -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, - -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, - -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, - -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, - -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, - -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, - -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, - -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, - -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, - -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, - - -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, - -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, - -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, - -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, - -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, - -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, - -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, - -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, - -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, - -29, -29, -29, -29, -29, -29 - - }, - - { - 7, -30, -30, -30, -30, -30, -30, -30, -30, -30, - -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, - -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, - -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, - -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, - -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, - -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, - -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, - -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, - -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, - - -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, - -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, - -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, - -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, - -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, - -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, - -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, - -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, - -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, - -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, - - -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, - -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, - -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, - -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, - -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, - -30, -30, -30, -30, -30, -30 - }, - - { - 7, -31, -31, -31, -31, -31, -31, -31, -31, -31, - -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, - -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, - -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, - - -31, -31, -31, -31, -31, -31, -31, -31, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, -31, -31, - -31, -31, -31, -31, -31, 44, 44, 44, 44, 44, - 44, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, -31, -31, -31, -31, 32, -31, 44, 44, 44, - 44, 44, 44, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, -31, -31, -31, -31, -31, -31, -31, - -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, - - -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, - -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, - -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, - -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, - -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, - -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, - -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, - -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, - -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, - -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, - - -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, - -31, -31, -31, -31, -31, -31 - }, - - { - 7, -32, -32, -32, -32, -32, -32, -32, -32, -32, - -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, - -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, - -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, - -32, -32, -32, -32, -32, -32, -32, -32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, -32, -32, - -32, -32, -32, -32, -32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, -32, -32, -32, -32, 32, -32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, -32, -32, -32, -32, -32, -32, -32, - -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, - -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, - -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, - -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, - -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, - - -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, - -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, - -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, - -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, - -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, - -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, - -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, - -32, -32, -32, -32, -32, -32 - }, - - { - 7, -33, -33, -33, -33, -33, -33, -33, -33, -33, - -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, - - -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, - -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, - -33, -33, -33, -33, -33, -33, -33, -33, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, -33, -33, - -33, -33, -33, -33, -33, 32, 32, 32, 32, 32, - 45, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, -33, -33, -33, -33, 32, -33, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - - 32, 32, 32, -33, -33, -33, -33, -33, -33, -33, - -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, - -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, - -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, - -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, - -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, - -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, - -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, - -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, - -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, - - -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, - -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, - -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, - -33, -33, -33, -33, -33, -33 - }, - - { - 7, -34, -34, -34, -34, -34, -34, -34, -34, 34, - -34, -34, 34, 34, -34, -34, -34, -34, -34, -34, - -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, - -34, -34, 34, -34, -34, 35, -34, -34, -34, -34, - -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, - -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, - - -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, - -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, - -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, - -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, - -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, - -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, - -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, - -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, - -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, - -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, - - -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, - -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, - -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, - -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, - -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, - -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, - -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, - -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, - -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, - -34, -34, -34, -34, -34, -34 - - }, - - { - 7, -35, -35, -35, -35, -35, -35, -35, -35, 36, - -35, -35, 36, 36, -35, -35, -35, -35, -35, -35, - -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, - -35, -35, 36, -35, -35, -35, -35, -35, -35, -35, - -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, - -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, - -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, - -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, - -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, - -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, - - -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, - -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, - -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, - -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, - -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, - -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, - -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, - -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, - -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, - -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, - - -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, - -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, - -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, - -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, - -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, - -35, -35, -35, -35, -35, -35 - }, - - { - 7, -36, -36, -36, -36, -36, -36, -36, -36, 36, - -36, -36, 36, 36, -36, -36, -36, -36, -36, -36, - -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, - -36, -36, 36, -36, -36, -36, -36, -36, -36, -36, - - -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, - -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, - -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, - -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, - -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, - -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, - -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, - -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, - -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, - -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, - - -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, - -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, - -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, - -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, - -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, - -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, - -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, - -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, - -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, - -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, - - -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, - -36, -36, -36, -36, -36, -36 - }, - - { - 7, -37, -37, -37, -37, -37, -37, -37, -37, -37, - -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, - -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, - -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, - -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, - -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, - -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, - -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, - - -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, - -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, - -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, - -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, - -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, - -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, - -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, - -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, - -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, - -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, - - -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, - -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, - -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, - -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, - -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, - -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, - -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, - -37, -37, -37, -37, -37, -37 - }, - - { - 7, -38, -38, -38, -38, -38, -38, -38, -38, -38, - -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, - - -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, - -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, - -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, - -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, - -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, - -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, - -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, - -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, - -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, - -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, - - -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, - -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, - -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, - -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, - -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, - -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, - -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, - -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, - -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, - -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, - - -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, - -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, - -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, - -38, -38, -38, -38, -38, -38 - }, - - { - 7, -39, -39, -39, -39, -39, -39, -39, -39, -39, - -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, - -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, - -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, - -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, - -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, - - -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, - -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, - -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, - -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, - -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, - -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, - -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, - -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, - -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, - -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, - - -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, - -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, - -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, - -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, - -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, - -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, - -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, - -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, - -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, - -39, -39, -39, -39, -39, -39 - - }, - - { - 7, 40, 40, 40, 40, 40, 40, 40, 40, 40, - -40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40 - }, - - { - 7, -41, -41, -41, -41, -41, -41, -41, -41, -41, - -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, - -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, - -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, - - -41, -41, -41, -41, -41, -41, -41, -41, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, -41, -41, - -41, -41, -41, -41, -41, 47, 47, 47, 47, 47, - 47, -41, -41, -41, -41, -41, -41, -41, -41, -41, - -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, - -41, -41, -41, -41, -41, -41, -41, 47, 47, 47, - 47, 47, 47, -41, -41, -41, -41, -41, -41, -41, - -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, - -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, - -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, - - -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, - -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, - -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, - -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, - -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, - -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, - -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, - -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, - -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, - -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, - - -41, -41, -41, -41, -41, -41, -41, -41, -41, -41, - -41, -41, -41, -41, -41, -41 - }, - - { - 7, -42, -42, -42, -42, -42, -42, -42, -42, -42, - -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, - -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, - -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, - -42, -42, -42, -42, -42, -42, -42, -42, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, -42, -42, - -42, -42, -42, -42, -42, 47, 47, 47, 47, 47, - 47, -42, -42, -42, -42, -42, -42, -42, -42, -42, - - -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, - -42, -42, -42, -42, -42, -42, -42, 47, 47, 47, - 47, 47, 47, -42, -42, -42, -42, -42, -42, -42, - -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, - -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, - -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, - -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, - -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, - -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, - -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, - - -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, - -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, - -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, - -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, - -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, - -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, - -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, - -42, -42, -42, -42, -42, -42 - }, - - { - 7, -43, -43, -43, -43, -43, -43, -43, -43, -43, - -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, - - -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, - -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, - -43, -43, -43, -43, -43, -43, -43, -43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 43, -43, -43, - -43, -43, -43, -43, -43, 43, 43, 43, 43, 43, - 43, -43, -43, -43, -43, -43, -43, -43, -43, -43, - -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, - -43, -43, -43, -43, -43, -43, -43, 43, 43, 43, - 43, 43, 43, -43, -43, -43, -43, -43, -43, -43, - -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, - - -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, - -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, - -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, - -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, - -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, - -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, - -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, - -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, - -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, - -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, - - -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, - -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, - -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, - -43, -43, -43, -43, -43, -43 - }, - - { - 7, -44, -44, -44, -44, -44, -44, -44, -44, -44, - -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, - -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, - -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, - -44, -44, -44, -44, -44, -44, -44, -44, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, -44, -44, - - -44, -44, -44, -44, -44, 48, 48, 48, 48, 48, - 48, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, -44, -44, -44, -44, 32, -44, 48, 48, 48, - 48, 48, 48, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, -44, -44, -44, -44, -44, -44, -44, - -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, - -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, - -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, - - -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, - -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, - -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, - -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, - -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, - -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, - -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, - -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, - -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, - -44, -44, -44, -44, -44, -44 - - }, - - { - 7, -45, -45, -45, -45, -45, -45, -45, -45, -45, - -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, - -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, - -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, - -45, -45, -45, -45, -45, -45, -45, -45, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, -45, -45, - -45, -45, -45, -45, -45, 32, 32, 32, 32, 49, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, -45, -45, -45, -45, 32, -45, 32, 32, 32, - - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, -45, -45, -45, -45, -45, -45, -45, - -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, - -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, - -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, - -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, - -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, - -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, - -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, - - -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, - -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, - -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, - -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, - -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, - -45, -45, -45, -45, -45, -45 - }, - - { - 7, -46, -46, -46, -46, -46, -46, -46, -46, -46, - -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, - -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, - -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, - - -46, -46, -46, -46, -46, -46, -46, -46, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, -46, -46, - -46, -46, -46, -46, -46, 51, 51, 51, 51, 51, - 51, -46, -46, -46, -46, -46, -46, -46, -46, -46, - -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, - -46, -46, -46, -46, -46, -46, -46, 51, 51, 51, - 51, 51, 51, -46, -46, -46, -46, -46, -46, -46, - -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, - -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, - -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, - - -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, - -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, - -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, - -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, - -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, - -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, - -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, - -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, - -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, - -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, - - -46, -46, -46, -46, -46, -46, -46, -46, -46, -46, - -46, -46, -46, -46, -46, -46 - }, - - { - 7, -47, -47, -47, -47, -47, -47, -47, -47, -47, - -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, - -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, - -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, - -47, -47, -47, -47, -47, -47, -47, -47, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, -47, -47, - -47, -47, -47, -47, -47, 51, 51, 51, 51, 51, - 51, -47, -47, -47, -47, -47, -47, -47, -47, -47, - - -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, - -47, -47, -47, -47, -47, -47, -47, 51, 51, 51, - 51, 51, 51, -47, -47, -47, -47, -47, -47, -47, - -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, - -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, - -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, - -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, - -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, - -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, - -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, - - -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, - -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, - -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, - -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, - -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, - -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, - -47, -47, -47, -47, -47, -47, -47, -47, -47, -47, - -47, -47, -47, -47, -47, -47 - }, - - { - 7, -48, -48, -48, -48, -48, -48, -48, -48, -48, - -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, - - -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, - -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, - -48, -48, -48, -48, -48, -48, -48, -48, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, -48, -48, - -48, -48, -48, -48, -48, 52, 52, 52, 52, 52, - 52, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, -48, -48, -48, -48, 32, -48, 52, 52, 52, - 52, 52, 52, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - - 32, 32, 32, -48, -48, -48, -48, -48, -48, -48, - -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, - -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, - -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, - -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, - -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, - -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, - -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, - -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, - -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, - - -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, - -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, - -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, - -48, -48, -48, -48, -48, -48 - }, - - { - 7, -49, -49, -49, -49, -49, -49, -49, -49, -49, - -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, - -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, - -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, - -49, -49, -49, -49, -49, -49, -49, -49, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, -49, -49, - - -49, -49, -49, -49, -49, 53, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, -49, -49, -49, -49, 32, -49, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, -49, -49, -49, -49, -49, -49, -49, - -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, - -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, - -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, - - -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, - -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, - -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, - -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, - -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, - -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, - -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, - -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, - -49, -49, -49, -49, -49, -49, -49, -49, -49, -49, - -49, -49, -49, -49, -49, -49 - - }, - - { - 7, -50, -50, -50, -50, -50, -50, -50, -50, -50, - -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, - -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, - -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, - -50, -50, -50, -50, -50, -50, -50, -50, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, -50, -50, - -50, -50, -50, -50, -50, 55, 55, 55, 55, 55, - 55, -50, -50, -50, -50, -50, -50, -50, -50, -50, - -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, - -50, -50, -50, -50, -50, -50, -50, 55, 55, 55, - - 55, 55, 55, -50, -50, -50, -50, -50, -50, -50, - -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, - -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, - -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, - -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, - -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, - -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, - -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, - -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, - -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, - - -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, - -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, - -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, - -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, - -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, - -50, -50, -50, -50, -50, -50 - }, - - { - 7, -51, -51, -51, -51, -51, -51, -51, -51, -51, - -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, - -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, - -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, - - -51, -51, -51, -51, -51, -51, -51, -51, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, -51, -51, - -51, -51, -51, -51, -51, 55, 55, 55, 55, 55, - 55, -51, -51, -51, -51, -51, -51, -51, -51, -51, - -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, - -51, -51, -51, -51, -51, -51, -51, 55, 55, 55, - 55, 55, 55, -51, -51, -51, -51, -51, -51, -51, - -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, - -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, - -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, - - -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, - -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, - -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, - -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, - -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, - -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, - -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, - -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, - -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, - -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, - - -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, - -51, -51, -51, -51, -51, -51 - }, - - { - 7, -52, -52, -52, -52, -52, -52, -52, -52, -52, - -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, - -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, - -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, - -52, -52, -52, -52, -52, -52, -52, -52, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, -52, -52, - -52, -52, -52, -52, -52, 56, 56, 56, 56, 56, - 56, 32, 32, 32, 32, 32, 32, 32, 32, 32, - - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, -52, -52, -52, -52, 32, -52, 56, 56, 56, - 56, 56, 56, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, -52, -52, -52, -52, -52, -52, -52, - -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, - -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, - -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, - -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, - -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, - - -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, - -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, - -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, - -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, - -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, - -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, - -52, -52, -52, -52, -52, -52, -52, -52, -52, -52, - -52, -52, -52, -52, -52, -52 - }, - - { - 7, -53, -53, -53, -53, -53, -53, -53, -53, -53, - -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, - - -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, - -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, - -53, -53, -53, -53, -53, -53, -53, -53, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, -53, -53, - -53, -53, -53, -53, -53, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 57, 32, 32, 32, 32, 32, 32, 32, - 32, -53, -53, -53, -53, 32, -53, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - - 32, 32, 32, -53, -53, -53, -53, -53, -53, -53, - -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, - -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, - -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, - -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, - -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, - -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, - -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, - -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, - -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, - - -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, - -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, - -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, - -53, -53, -53, -53, -53, -53 - }, - - { - 7, -54, -54, -54, -54, -54, -54, -54, -54, -54, - -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, - -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, - -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, - -54, -54, -54, -54, -54, -54, -54, -54, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, -54, -54, - - -54, -54, -54, -54, -54, 59, 59, 59, 59, 59, - 59, -54, -54, -54, -54, -54, -54, -54, -54, -54, - -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, - -54, -54, -54, -54, -54, -54, -54, 59, 59, 59, - 59, 59, 59, -54, -54, -54, -54, -54, -54, -54, - -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, - -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, - -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, - -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, - -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, - - -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, - -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, - -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, - -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, - -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, - -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, - -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, - -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, - -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, - -54, -54, -54, -54, -54, -54 - - }, - - { - 7, -55, -55, -55, -55, -55, -55, -55, -55, -55, - -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, - -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, - -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, - -55, -55, -55, -55, -55, -55, -55, -55, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, -55, -55, - -55, -55, -55, -55, -55, 59, 59, 59, 59, 59, - 59, -55, -55, -55, -55, -55, -55, -55, -55, -55, - -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, - -55, -55, -55, -55, -55, -55, -55, 59, 59, 59, - - 59, 59, 59, -55, -55, -55, -55, -55, -55, -55, - -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, - -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, - -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, - -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, - -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, - -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, - -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, - -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, - -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, - - -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, - -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, - -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, - -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, - -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, - -55, -55, -55, -55, -55, -55 - }, - - { - 7, -56, -56, -56, -56, -56, -56, -56, -56, -56, - -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, - -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, - -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, - - -56, -56, -56, -56, -56, -56, -56, -56, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, -56, -56, - -56, -56, -56, -56, -56, 60, 60, 60, 60, 60, - 60, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, -56, -56, -56, -56, 32, -56, 60, 60, 60, - 60, 60, 60, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, -56, -56, -56, -56, -56, -56, -56, - -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, - - -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, - -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, - -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, - -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, - -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, - -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, - -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, - -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, - -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, - -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, - - -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, - -56, -56, -56, -56, -56, -56 - }, - - { - 7, -57, -57, -57, -57, -57, -57, -57, -57, -57, - -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, - -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, - -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, - -57, -57, -57, -57, -57, -57, -57, -57, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, -57, -57, - -57, -57, -57, -57, -57, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - - 32, 32, 61, 32, 32, 32, 32, 32, 32, 32, - 32, -57, -57, -57, -57, 32, -57, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, -57, -57, -57, -57, -57, -57, -57, - -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, - -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, - -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, - -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, - -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, - - -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, - -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, - -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, - -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, - -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, - -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, - -57, -57, -57, -57, -57, -57, -57, -57, -57, -57, - -57, -57, -57, -57, -57, -57 - }, - - { - 7, -58, -58, -58, -58, -58, -58, -58, -58, -58, - -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, - - -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, - -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, - -58, -58, -58, -58, -58, -58, -58, -58, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, -58, -58, - -58, -58, -58, -58, -58, 63, 63, 63, 63, 63, - 63, -58, -58, -58, -58, -58, -58, -58, -58, -58, - -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, - -58, -58, -58, -58, -58, -58, -58, 63, 63, 63, - 63, 63, 63, -58, -58, -58, -58, -58, -58, -58, - -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, - - -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, - -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, - -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, - -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, - -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, - -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, - -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, - -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, - -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, - -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, - - -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, - -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, - -58, -58, -58, -58, -58, -58, -58, -58, -58, -58, - -58, -58, -58, -58, -58, -58 - }, - - { - 7, -59, -59, -59, -59, -59, -59, -59, -59, -59, - -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, - -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, - -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, - -59, -59, -59, -59, -59, -59, -59, -59, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, -59, -59, - - -59, -59, -59, -59, -59, 63, 63, 63, 63, 63, - 63, -59, -59, -59, -59, -59, -59, -59, -59, -59, - -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, - -59, -59, -59, -59, -59, -59, -59, 63, 63, 63, - 63, 63, 63, -59, -59, -59, -59, -59, -59, -59, - -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, - -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, - -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, - -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, - -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, - - -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, - -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, - -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, - -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, - -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, - -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, - -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, - -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, - -59, -59, -59, -59, -59, -59, -59, -59, -59, -59, - -59, -59, -59, -59, -59, -59 - - }, - - { - 7, -60, -60, -60, -60, -60, -60, -60, -60, -60, - -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, - -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, - -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, - -60, -60, -60, -60, -60, -60, -60, -60, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, -60, -60, - -60, -60, -60, -60, -60, 64, 64, 64, 64, 64, - 64, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, -60, -60, -60, -60, 32, -60, 64, 64, 64, - - 64, 64, 64, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, -60, -60, -60, -60, -60, -60, -60, - -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, - -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, - -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, - -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, - -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, - -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, - -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, - - -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, - -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, - -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, - -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, - -60, -60, -60, -60, -60, -60, -60, -60, -60, -60, - -60, -60, -60, -60, -60, -60 - }, - - { - 7, -61, -61, -61, -61, -61, -61, -61, -61, -61, - -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, - -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, - -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, - - -61, -61, -61, -61, -61, -61, -61, -61, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, -61, -61, - -61, -61, -61, -61, -61, 65, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, -61, -61, -61, -61, 32, -61, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, -61, -61, -61, -61, -61, -61, -61, - -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, - - -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, - -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, - -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, - -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, - -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, - -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, - -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, - -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, - -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, - -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, - - -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, - -61, -61, -61, -61, -61, -61 - }, - - { - 7, -62, -62, -62, -62, -62, -62, -62, -62, -62, - -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, - -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, - -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, - -62, -62, -62, -62, -62, 66, -62, -62, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, -62, -62, - -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, - -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, - - -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, - -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, - -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, - -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, - -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, - -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, - -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, - -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, - -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, - -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, - - -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, - -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, - -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, - -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, - -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, - -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, - -62, -62, -62, -62, -62, -62, -62, -62, -62, -62, - -62, -62, -62, -62, -62, -62 - }, - - { - 7, -63, -63, -63, -63, -63, -63, -63, -63, -63, - -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, - - -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, - -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, - -63, -63, -63, -63, -63, 66, -63, -63, -63, -63, - -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, - -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, - -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, - -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, - -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, - -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, - -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, - - -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, - -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, - -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, - -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, - -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, - -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, - -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, - -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, - -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, - -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, - - -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, - -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, - -63, -63, -63, -63, -63, -63, -63, -63, -63, -63, - -63, -63, -63, -63, -63, -63 - }, - - { - 7, -64, -64, -64, -64, -64, -64, -64, -64, -64, - -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, - -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, - -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, - -64, -64, -64, -64, -64, 66, -64, -64, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, -64, -64, - - -64, -64, -64, -64, -64, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, -64, -64, -64, -64, 32, -64, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, -64, -64, -64, -64, -64, -64, -64, - -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, - -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, - -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, - - -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, - -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, - -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, - -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, - -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, - -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, - -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, - -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, - -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, - -64, -64, -64, -64, -64, -64 - - }, - - { - 7, -65, -65, -65, -65, -65, -65, -65, -65, -65, - -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, - -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, - -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, - -65, -65, -65, -65, -65, -65, -65, -65, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, -65, -65, - -65, -65, -65, -65, -65, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 68, - 32, -65, -65, -65, -65, 32, -65, 32, 32, 32, - - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, -65, -65, -65, -65, -65, -65, -65, - -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, - -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, - -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, - -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, - -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, - -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, - -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, - - -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, - -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, - -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, - -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, - -65, -65, -65, -65, -65, -65, -65, -65, -65, -65, - -65, -65, -65, -65, -65, -65 - }, - - { - 7, -66, -66, -66, -66, -66, -66, -66, -66, -66, - -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, - -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, - -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, - - -66, -66, -66, -66, -66, -66, -66, -66, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, -66, -66, - -66, -66, -66, -66, -66, 69, 69, 69, 69, 69, - 69, -66, -66, -66, -66, -66, -66, -66, -66, -66, - -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, - -66, -66, -66, -66, -66, -66, -66, 69, 69, 69, - 69, 69, 69, -66, -66, -66, -66, -66, -66, -66, - -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, - -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, - -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, - - -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, - -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, - -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, - -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, - -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, - -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, - -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, - -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, - -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, - -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, - - -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, - -66, -66, -66, -66, -66, -66 - }, - - { - 7, -67, -67, -67, -67, -67, -67, -67, -67, -67, - -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, - -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, - -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, - -67, -67, -67, -67, -67, -67, -67, -67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, -67, -67, - -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, - -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, - - -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, - -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, - -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, - -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, - -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, - -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, - -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, - -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, - -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, - -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, - - -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, - -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, - -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, - -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, - -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, - -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, - -67, -67, -67, -67, -67, -67, -67, -67, -67, -67, - -67, -67, -67, -67, -67, -67 - }, - - { - 7, -68, -68, -68, -68, -68, -68, -68, -68, 70, - -68, -68, 70, 70, -68, -68, -68, -68, -68, -68, - - -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, - -68, -68, 70, -68, -68, -68, -68, -68, -68, -68, - 71, -68, -68, -68, -68, -68, -68, -68, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, -68, -68, - -68, -68, -68, -68, -68, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, -68, -68, -68, -68, 32, -68, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - - 32, 32, 32, -68, -68, -68, -68, -68, -68, -68, - -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, - -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, - -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, - -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, - -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, - -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, - -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, - -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, - -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, - - -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, - -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, - -68, -68, -68, -68, -68, -68, -68, -68, -68, -68, - -68, -68, -68, -68, -68, -68 - }, - - { - 7, -69, -69, -69, -69, -69, -69, -69, -69, -69, - -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, - -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, - -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, - -69, -69, -69, -69, -69, -69, -69, -69, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, -69, -69, - - -69, -69, -69, -69, -69, 72, 72, 72, 72, 72, - 72, -69, -69, -69, -69, -69, -69, -69, -69, -69, - -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, - -69, -69, -69, -69, -69, -69, -69, 72, 72, 72, - 72, 72, 72, -69, -69, -69, -69, -69, -69, -69, - -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, - -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, - -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, - -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, - -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, - - -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, - -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, - -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, - -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, - -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, - -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, - -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, - -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, - -69, -69, -69, -69, -69, -69, -69, -69, -69, -69, - -69, -69, -69, -69, -69, -69 - - }, - - { - 7, -70, -70, -70, -70, -70, -70, -70, -70, 70, - -70, -70, 70, 70, -70, -70, -70, -70, -70, -70, - -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, - -70, -70, 70, -70, -70, -70, -70, -70, -70, -70, - 71, -70, -70, -70, -70, -70, -70, -70, -70, -70, - -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, - -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, - -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, - -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, - -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, - - -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, - -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, - -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, - -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, - -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, - -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, - -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, - -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, - -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, - -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, - - -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, - -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, - -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, - -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, - -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, - -70, -70, -70, -70, -70, -70 - }, - - { - 7, -71, -71, -71, -71, -71, -71, -71, -71, -71, - -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, - -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, - -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, - - -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, - -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, - -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, - -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, - -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, - -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, - -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, - -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, - -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, - -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, - - -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, - -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, - -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, - -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, - -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, - -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, - -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, - -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, - -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, - -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, - - -71, -71, -71, -71, -71, -71, -71, -71, -71, -71, - -71, -71, -71, -71, -71, -71 - }, - - { - 7, -72, -72, -72, -72, -72, -72, -72, -72, -72, - -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, - -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, - -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, - -72, -72, -72, -72, -72, -72, -72, -72, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, -72, -72, - -72, -72, -72, -72, -72, 73, 73, 73, 73, 73, - 73, -72, -72, -72, -72, -72, -72, -72, -72, -72, - - -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, - -72, -72, -72, -72, -72, -72, -72, 73, 73, 73, - 73, 73, 73, -72, -72, -72, -72, -72, -72, -72, - -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, - -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, - -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, - -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, - -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, - -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, - -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, - - -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, - -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, - -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, - -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, - -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, - -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, - -72, -72, -72, -72, -72, -72, -72, -72, -72, -72, - -72, -72, -72, -72, -72, -72 - }, - - { - 7, -73, -73, -73, -73, -73, -73, -73, -73, -73, - -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, - - -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, - -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, - -73, -73, -73, -73, -73, -73, -73, -73, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, -73, -73, - -73, -73, -73, -73, -73, 74, 74, 74, 74, 74, - 74, -73, -73, -73, -73, -73, -73, -73, -73, -73, - -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, - -73, -73, -73, -73, -73, -73, -73, 74, 74, 74, - 74, 74, 74, -73, -73, -73, -73, -73, -73, -73, - -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, - - -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, - -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, - -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, - -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, - -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, - -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, - -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, - -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, - -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, - -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, - - -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, - -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, - -73, -73, -73, -73, -73, -73, -73, -73, -73, -73, - -73, -73, -73, -73, -73, -73 - }, - - { - 7, -74, -74, -74, -74, -74, -74, -74, -74, -74, - -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, - -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, - -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, - -74, -74, -74, -74, -74, 75, -74, -74, -74, -74, - -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, - - -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, - -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, - -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, - -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, - -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, - -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, - -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, - -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, - -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, - -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, - - -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, - -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, - -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, - -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, - -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, - -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, - -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, - -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, - -74, -74, -74, -74, -74, -74, -74, -74, -74, -74, - -74, -74, -74, -74, -74, -74 - - }, - - { - 7, -75, -75, -75, -75, -75, -75, -75, -75, -75, - -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, - -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, - -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, - -75, -75, -75, -75, -75, -75, -75, -75, 76, 76, - 76, 76, 76, 76, 76, 76, 76, 76, -75, -75, - -75, -75, -75, -75, -75, 76, 76, 76, 76, 76, - 76, -75, -75, -75, -75, -75, -75, -75, -75, -75, - -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, - -75, -75, -75, -75, -75, -75, -75, 76, 76, 76, - - 76, 76, 76, -75, -75, -75, -75, -75, -75, -75, - -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, - -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, - -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, - -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, - -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, - -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, - -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, - -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, - -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, - - -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, - -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, - -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, - -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, - -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, - -75, -75, -75, -75, -75, -75 - }, - - { - 7, -76, -76, -76, -76, -76, -76, -76, -76, -76, - -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, - -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, - -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, - - -76, -76, -76, -76, -76, -76, -76, -76, 77, 77, - 77, 77, 77, 77, 77, 77, 77, 77, -76, -76, - -76, -76, -76, -76, -76, 77, 77, 77, 77, 77, - 77, -76, -76, -76, -76, -76, -76, -76, -76, -76, - -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, - -76, -76, -76, -76, -76, -76, -76, 77, 77, 77, - 77, 77, 77, -76, -76, -76, -76, -76, -76, -76, - -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, - -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, - -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, - - -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, - -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, - -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, - -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, - -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, - -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, - -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, - -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, - -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, - -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, - - -76, -76, -76, -76, -76, -76, -76, -76, -76, -76, - -76, -76, -76, -76, -76, -76 - }, - - { - 7, -77, -77, -77, -77, -77, -77, -77, -77, -77, - -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, - -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, - -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, - -77, -77, -77, -77, -77, -77, -77, -77, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, -77, -77, - -77, -77, -77, -77, -77, 78, 78, 78, 78, 78, - 78, -77, -77, -77, -77, -77, -77, -77, -77, -77, - - -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, - -77, -77, -77, -77, -77, -77, -77, 78, 78, 78, - 78, 78, 78, -77, -77, -77, -77, -77, -77, -77, - -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, - -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, - -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, - -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, - -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, - -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, - -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, - - -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, - -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, - -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, - -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, - -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, - -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, - -77, -77, -77, -77, -77, -77, -77, -77, -77, -77, - -77, -77, -77, -77, -77, -77 - }, - - { - 7, -78, -78, -78, -78, -78, -78, -78, -78, -78, - -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, - - -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, - -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, - -78, -78, -78, -78, -78, -78, -78, -78, 79, 79, - 79, 79, 79, 79, 79, 79, 79, 79, -78, -78, - -78, -78, -78, -78, -78, 79, 79, 79, 79, 79, - 79, -78, -78, -78, -78, -78, -78, -78, -78, -78, - -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, - -78, -78, -78, -78, -78, -78, -78, 79, 79, 79, - 79, 79, 79, -78, -78, -78, -78, -78, -78, -78, - -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, - - -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, - -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, - -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, - -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, - -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, - -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, - -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, - -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, - -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, - -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, - - -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, - -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, - -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, - -78, -78, -78, -78, -78, -78 - }, - - { - 7, -79, -79, -79, -79, -79, -79, -79, -79, -79, - -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, - -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, - -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, - -79, -79, -79, -79, -79, 80, -79, -79, -79, -79, - -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, - - -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, - -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, - -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, - -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, - -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, - -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, - -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, - -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, - -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, - -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, - - -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, - -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, - -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, - -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, - -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, - -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, - -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, - -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, - -79, -79, -79, -79, -79, -79, -79, -79, -79, -79, - -79, -79, -79, -79, -79, -79 - - }, - - { - 7, -80, -80, -80, -80, -80, -80, -80, -80, -80, - -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, - -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, - -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, - -80, -80, -80, -80, -80, -80, -80, -80, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, -80, -80, - -80, -80, -80, -80, -80, 81, 81, 81, 81, 81, - 81, -80, -80, -80, -80, -80, -80, -80, -80, -80, - -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, - -80, -80, -80, -80, -80, -80, -80, 81, 81, 81, - - 81, 81, 81, -80, -80, -80, -80, -80, -80, -80, - -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, - -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, - -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, - -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, - -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, - -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, - -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, - -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, - -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, - - -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, - -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, - -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, - -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, - -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, - -80, -80, -80, -80, -80, -80 - }, - - { - 7, -81, -81, -81, -81, -81, -81, -81, -81, -81, - -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, - -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, - -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, - - -81, -81, -81, -81, -81, -81, -81, -81, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, -81, -81, - -81, -81, -81, -81, -81, 82, 82, 82, 82, 82, - 82, -81, -81, -81, -81, -81, -81, -81, -81, -81, - -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, - -81, -81, -81, -81, -81, -81, -81, 82, 82, 82, - 82, 82, 82, -81, -81, -81, -81, -81, -81, -81, - -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, - -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, - -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, - - -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, - -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, - -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, - -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, - -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, - -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, - -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, - -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, - -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, - -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, - - -81, -81, -81, -81, -81, -81, -81, -81, -81, -81, - -81, -81, -81, -81, -81, -81 - }, - - { - 7, -82, -82, -82, -82, -82, -82, -82, -82, -82, - -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, - -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, - -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, - -82, -82, -82, -82, -82, -82, -82, -82, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, -82, -82, - -82, -82, -82, -82, -82, 83, 83, 83, 83, 83, - 83, -82, -82, -82, -82, -82, -82, -82, -82, -82, - - -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, - -82, -82, -82, -82, -82, -82, -82, 83, 83, 83, - 83, 83, 83, -82, -82, -82, -82, -82, -82, -82, - -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, - -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, - -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, - -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, - -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, - -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, - -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, - - -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, - -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, - -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, - -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, - -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, - -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, - -82, -82, -82, -82, -82, -82, -82, -82, -82, -82, - -82, -82, -82, -82, -82, -82 - }, - - { - 7, -83, -83, -83, -83, -83, -83, -83, -83, -83, - -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, - - -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, - -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, - -83, -83, -83, -83, -83, -83, -83, -83, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, -83, -83, - -83, -83, -83, -83, -83, 84, 84, 84, 84, 84, - 84, -83, -83, -83, -83, -83, -83, -83, -83, -83, - -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, - -83, -83, -83, -83, -83, -83, -83, 84, 84, 84, - 84, 84, 84, -83, -83, -83, -83, -83, -83, -83, - -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, - - -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, - -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, - -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, - -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, - -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, - -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, - -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, - -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, - -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, - -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, - - -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, - -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, - -83, -83, -83, -83, -83, -83, -83, -83, -83, -83, - -83, -83, -83, -83, -83, -83 - }, - - { - 7, -84, -84, -84, -84, -84, -84, -84, -84, -84, - -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, - -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, - -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, - -84, -84, -84, -84, -84, 85, -84, -84, -84, -84, - -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, - - -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, - -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, - -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, - -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, - -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, - -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, - -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, - -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, - -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, - -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, - - -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, - -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, - -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, - -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, - -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, - -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, - -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, - -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, - -84, -84, -84, -84, -84, -84, -84, -84, -84, -84, - -84, -84, -84, -84, -84, -84 - - }, - - { - 7, -85, -85, -85, -85, -85, -85, -85, -85, -85, - -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, - -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, - -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, - -85, -85, -85, -85, -85, -85, -85, -85, 86, 86, - 86, 86, 86, 86, 86, 86, 86, 86, -85, -85, - -85, -85, -85, -85, -85, 86, 86, 86, 86, 86, - 86, -85, -85, -85, -85, -85, -85, -85, -85, -85, - -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, - -85, -85, -85, -85, -85, -85, -85, 86, 86, 86, - - 86, 86, 86, -85, -85, -85, -85, -85, -85, -85, - -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, - -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, - -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, - -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, - -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, - -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, - -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, - -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, - -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, - - -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, - -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, - -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, - -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, - -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, - -85, -85, -85, -85, -85, -85 - }, - - { - 7, -86, -86, -86, -86, -86, -86, -86, -86, -86, - -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, - -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, - -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, - - -86, -86, -86, -86, -86, -86, -86, -86, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, -86, -86, - -86, -86, -86, -86, -86, 87, 87, 87, 87, 87, - 87, -86, -86, -86, -86, -86, -86, -86, -86, -86, - -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, - -86, -86, -86, -86, -86, -86, -86, 87, 87, 87, - 87, 87, 87, -86, -86, -86, -86, -86, -86, -86, - -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, - -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, - -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, - - -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, - -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, - -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, - -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, - -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, - -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, - -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, - -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, - -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, - -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, - - -86, -86, -86, -86, -86, -86, -86, -86, -86, -86, - -86, -86, -86, -86, -86, -86 - }, - - { - 7, -87, -87, -87, -87, -87, -87, -87, -87, -87, - -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, - -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, - -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, - -87, -87, -87, -87, -87, -87, -87, -87, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, -87, -87, - -87, -87, -87, -87, -87, 88, 88, 88, 88, 88, - 88, -87, -87, -87, -87, -87, -87, -87, -87, -87, - - -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, - -87, -87, -87, -87, -87, -87, -87, 88, 88, 88, - 88, 88, 88, -87, -87, -87, -87, -87, -87, -87, - -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, - -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, - -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, - -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, - -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, - -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, - -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, - - -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, - -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, - -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, - -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, - -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, - -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, - -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, - -87, -87, -87, -87, -87, -87 - }, - - { - 7, -88, -88, -88, -88, -88, -88, -88, -88, -88, - -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, - - -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, - -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, - -88, -88, -88, -88, -88, -88, -88, -88, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, -88, -88, - -88, -88, -88, -88, -88, 89, 89, 89, 89, 89, - 89, -88, -88, -88, -88, -88, -88, -88, -88, -88, - -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, - -88, -88, -88, -88, -88, -88, -88, 89, 89, 89, - 89, 89, 89, -88, -88, -88, -88, -88, -88, -88, - -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, - - -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, - -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, - -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, - -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, - -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, - -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, - -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, - -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, - -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, - -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, - - -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, - -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, - -88, -88, -88, -88, -88, -88, -88, -88, -88, -88, - -88, -88, -88, -88, -88, -88 - }, - - { - 7, -89, -89, -89, -89, -89, -89, -89, -89, -89, - -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, - -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, - -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, - -89, -89, -89, -89, -89, -89, -89, -89, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, -89, -89, - - -89, -89, -89, -89, -89, 90, 90, 90, 90, 90, - 90, -89, -89, -89, -89, -89, -89, -89, -89, -89, - -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, - -89, -89, -89, -89, -89, -89, -89, 90, 90, 90, - 90, 90, 90, -89, -89, -89, -89, -89, -89, -89, - -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, - -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, - -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, - -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, - -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, - - -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, - -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, - -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, - -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, - -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, - -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, - -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, - -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, - -89, -89, -89, -89, -89, -89, -89, -89, -89, -89, - -89, -89, -89, -89, -89, -89 - - }, - - { - 7, -90, -90, -90, -90, -90, -90, -90, -90, -90, - -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, - -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, - -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, - -90, -90, -90, -90, -90, -90, -90, -90, 91, 91, - 91, 91, 91, 91, 91, 91, 91, 91, -90, -90, - -90, -90, -90, -90, -90, 91, 91, 91, 91, 91, - 91, -90, -90, -90, -90, -90, -90, -90, -90, -90, - -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, - -90, -90, -90, -90, -90, -90, -90, 91, 91, 91, - - 91, 91, 91, -90, -90, -90, -90, -90, -90, -90, - -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, - -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, - -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, - -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, - -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, - -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, - -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, - -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, - -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, - - -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, - -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, - -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, - -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, - -90, -90, -90, -90, -90, -90, -90, -90, -90, -90, - -90, -90, -90, -90, -90, -90 - }, - - { - 7, -91, -91, -91, -91, -91, -91, -91, -91, -91, - -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, - -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, - -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, - - -91, -91, -91, -91, -91, -91, -91, -91, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, -91, -91, - -91, -91, -91, -91, -91, 92, 92, 92, 92, 92, - 92, -91, -91, -91, -91, -91, -91, -91, -91, -91, - -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, - -91, -91, -91, -91, -91, -91, -91, 92, 92, 92, - 92, 92, 92, -91, -91, -91, -91, -91, -91, -91, - -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, - -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, - -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, - - -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, - -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, - -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, - -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, - -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, - -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, - -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, - -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, - -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, - -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, - - -91, -91, -91, -91, -91, -91, -91, -91, -91, -91, - -91, -91, -91, -91, -91, -91 - }, - - { - 7, -92, -92, -92, -92, -92, -92, -92, -92, -92, - -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, - -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, - -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, - -92, -92, -92, -92, -92, -92, -92, -92, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, -92, -92, - -92, -92, -92, -92, -92, 93, 93, 93, 93, 93, - 93, -92, -92, -92, -92, -92, -92, -92, -92, -92, - - -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, - -92, -92, -92, -92, -92, -92, -92, 93, 93, 93, - 93, 93, 93, -92, -92, -92, -92, -92, -92, -92, - -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, - -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, - -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, - -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, - -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, - -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, - -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, - - -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, - -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, - -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, - -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, - -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, - -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, - -92, -92, -92, -92, -92, -92, -92, -92, -92, -92, - -92, -92, -92, -92, -92, -92 - }, - - { - 7, -93, -93, -93, -93, -93, -93, -93, -93, -93, - -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, - - -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, - -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, - -93, -93, -93, -93, -93, -93, -93, -93, 94, 94, - 94, 94, 94, 94, 94, 94, 94, 94, -93, -93, - -93, -93, -93, -93, -93, 94, 94, 94, 94, 94, - 94, -93, -93, -93, -93, -93, -93, -93, -93, -93, - -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, - -93, -93, -93, -93, -93, -93, -93, 94, 94, 94, - 94, 94, 94, -93, -93, -93, -93, -93, -93, -93, - -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, - - -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, - -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, - -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, - -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, - -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, - -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, - -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, - -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, - -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, - -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, - - -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, - -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, - -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, - -93, -93, -93, -93, -93, -93 - }, - - { - 7, -94, -94, -94, -94, -94, -94, -94, -94, -94, - -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, - -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, - -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, - -94, -94, -94, -94, -94, -94, -94, -94, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, -94, -94, - - -94, -94, -94, -94, -94, 95, 95, 95, 95, 95, - 95, -94, -94, -94, -94, -94, -94, -94, -94, -94, - -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, - -94, -94, -94, -94, -94, -94, -94, 95, 95, 95, - 95, 95, 95, -94, -94, -94, -94, -94, -94, -94, - -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, - -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, - -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, - -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, - -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, - - -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, - -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, - -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, - -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, - -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, - -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, - -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, - -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, - -94, -94, -94, -94, -94, -94, -94, -94, -94, -94, - -94, -94, -94, -94, -94, -94 - - }, - - { - 7, -95, -95, -95, -95, -95, -95, -95, -95, -95, - -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, - -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, - -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, - -95, -95, -95, -95, -95, -95, -95, -95, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, -95, -95, - -95, -95, -95, -95, -95, 96, 96, 96, 96, 96, - 96, -95, -95, -95, -95, -95, -95, -95, -95, -95, - -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, - -95, -95, -95, -95, -95, -95, -95, 96, 96, 96, - - 96, 96, 96, -95, -95, -95, -95, -95, -95, -95, - -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, - -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, - -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, - -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, - -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, - -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, - -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, - -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, - -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, - - -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, - -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, - -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, - -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, - -95, -95, -95, -95, -95, -95, -95, -95, -95, -95, - -95, -95, -95, -95, -95, -95 - }, - - { - 7, -96, -96, -96, -96, -96, -96, -96, -96, -96, - -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, - -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, - -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, - - -96, -96, -96, -96, -96, -96, -96, -96, 97, 97, - 97, 97, 97, 97, 97, 97, 97, 97, -96, -96, - -96, -96, -96, -96, -96, 97, 97, 97, 97, 97, - 97, -96, -96, -96, -96, -96, -96, -96, -96, -96, - -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, - -96, -96, -96, -96, -96, -96, -96, 97, 97, 97, - 97, 97, 97, -96, -96, -96, -96, -96, -96, -96, - -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, - -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, - -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, - - -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, - -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, - -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, - -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, - -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, - -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, - -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, - -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, - -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, - -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, - - -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, - -96, -96, -96, -96, -96, -96 - }, - - { - 7, -97, -97, -97, -97, -97, -97, -97, -97, -97, - -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, - -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, - -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, - -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, - -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, - -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, - -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, - - -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, - -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, - -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, - -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, - -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, - -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, - -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, - -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, - -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, - -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, - - -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, - -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, - -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, - -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, - -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, - -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, - -97, -97, -97, -97, -97, -97, -97, -97, -97, -97, - -97, -97, -97, -97, -97, -97 - }, - - } ; - - -static yy_state_type yy_get_previous_state YY_PROTO(( void )); -static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state )); -static int yy_get_next_buffer YY_PROTO(( void )); -static void yy_fatal_error YY_PROTO(( yyconst char msg[] )); - -/* Done after the current pattern has been matched and before the - * corresponding action - sets up yytext. - */ -#define YY_DO_BEFORE_ACTION \ - yytext_ptr = yy_bp; \ - yyleng = (int) (yy_cp - yy_bp); \ - yy_hold_char = *yy_cp; \ - *yy_cp = '\0'; \ - yy_c_buf_p = yy_cp; - -#define YY_NUM_RULES 19 -#define YY_END_OF_BUFFER 20 -static yyconst short int yy_accept[98] = - { 0, - 0, 0, 0, 0, 2, 2, 20, 18, 15, 14, - 3, 11, 11, 18, 18, 13, 13, 13, 15, 1, - 8, 19, 4, 8, 2, 11, 0, 0, 16, 17, - 13, 13, 13, 0, 1, 1, 7, 6, 5, 2, - 11, 0, 10, 13, 13, 11, 0, 13, 13, 11, - 0, 13, 13, 11, 0, 13, 13, 11, 0, 13, - 13, 11, 0, 13, 13, 0, 11, 13, 0, 0, - 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 9 - - } ; - -static yy_state_type yy_last_accepting_state; -static char *yy_last_accepting_cpos; - -static yyconst yy_state_type yy_NUL_trans[98] = - { 0, - 8, 8, 21, 21, 25, 25, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 37, 40, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0 - - } ; - -extern int yy_flex_debug; -int yy_flex_debug = 1; - -static yyconst short int yy_rule_linenum[19] = - { 0, - 106, 107, 126, 127, 132, 133, 134, 135, 136, 140, - 144, 148, 149, 150, 151, 152, 153, 154 - } ; - -/* The intent behind this definition is that it'll catch - * any uses of REJECT which flex missed. - */ -#define REJECT reject_used_but_not_detected -#define yymore() yymore_used_but_not_detected -#define YY_MORE_ADJ 0 -#define YY_RESTORE_YY_MORE_OFFSET -char *yytext; -#line 1 "parser.l" -#define INITIAL 0 -/* -*-C-*- - * IDL Compiler - * - * Copyright 2002 Ove Kaaven - * - * 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 - */ -#define YY_STACK_USED 1 -#define YY_NO_UNPUT 1 -#define YY_NO_TOP_STATE 1 -#define YY_NEVER_INTERACTIVE 1 -#define QUOTE 1 - -#define pp_line 2 - -#line 37 "parser.l" - -#include "config.h" - -#include -#include -#include -#include -#include -#ifdef HAVE_UNISTD_H -# include -#endif - -#include "widl.h" -#include "utils.h" -#include "parser.h" -#include "wine/wpp.h" - -#include "parser.tab.h" - -extern char *temp_name; - -static void addcchar(char c); -static char *get_buffered_cstring(void); - -static char *cbuffer; -static int cbufidx; -static int cbufalloc = 0; - -static int kw_token(const char *kw); - -#define MAX_IMPORT_DEPTH 10 -struct { - YY_BUFFER_STATE state; - char *input_name; - int line_number; - char *temp_name; -} import_stack[MAX_IMPORT_DEPTH]; -int import_stack_ptr = 0; - -static void pop_import(void); - -static UUID* parse_uuid(const char*u) -{ - UUID* uuid = xmalloc(sizeof(UUID)); - char b[3]; - /* it would be nice to use UuidFromStringA */ - uuid->Data1 = strtoul(u, NULL, 16); - uuid->Data2 = strtoul(u+9, NULL, 16); - uuid->Data3 = strtoul(u+14, NULL, 16); - b[2] = 0; - memcpy(b, u+19, 2); uuid->Data4[0] = strtoul(b, NULL, 16); - memcpy(b, u+21, 2); uuid->Data4[1] = strtoul(b, NULL, 16); - memcpy(b, u+24, 2); uuid->Data4[2] = strtoul(b, NULL, 16); - memcpy(b, u+26, 2); uuid->Data4[3] = strtoul(b, NULL, 16); - memcpy(b, u+28, 2); uuid->Data4[4] = strtoul(b, NULL, 16); - memcpy(b, u+30, 2); uuid->Data4[5] = strtoul(b, NULL, 16); - memcpy(b, u+32, 2); uuid->Data4[6] = strtoul(b, NULL, 16); - memcpy(b, u+34, 2); uuid->Data4[7] = strtoul(b, NULL, 16); - return uuid; -} - -/* - ************************************************************************** - * The flexer starts here - ************************************************************************** - */ -#line 3539 "lex.yy.c" - -/* Macros after this point can all be overridden by user definitions in - * section 1. - */ - -#ifndef YY_SKIP_YYWRAP -#ifdef __cplusplus -extern "C" int yywrap YY_PROTO(( void )); -#else -extern int yywrap YY_PROTO(( void )); -#endif -#endif - -#ifndef YY_NO_UNPUT -static void yyunput YY_PROTO(( int c, char *buf_ptr )); -#endif - -#ifndef yytext_ptr -static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int )); -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen YY_PROTO(( yyconst char * )); -#endif - -#ifndef YY_NO_INPUT -#ifdef __cplusplus -static int yyinput YY_PROTO(( void )); -#else -static int input YY_PROTO(( void )); -#endif -#endif - -#if YY_STACK_USED -static int yy_start_stack_ptr = 0; -static int yy_start_stack_depth = 0; -static int *yy_start_stack = 0; -#ifndef YY_NO_PUSH_STATE -static void yy_push_state YY_PROTO(( int new_state )); -#endif -#ifndef YY_NO_POP_STATE -static void yy_pop_state YY_PROTO(( void )); -#endif -#ifndef YY_NO_TOP_STATE -static int yy_top_state YY_PROTO(( void )); -#endif - -#else -#define YY_NO_PUSH_STATE 1 -#define YY_NO_POP_STATE 1 -#define YY_NO_TOP_STATE 1 -#endif - -#ifdef YY_MALLOC_DECL -YY_MALLOC_DECL -#else -#if __STDC__ -#ifndef __cplusplus -#include -#endif -#else -/* Just try to get by without declaring the routines. This will fail - * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int) - * or sizeof(void*) != sizeof(int). - */ -#endif -#endif - -/* Amount of stuff to slurp up with each read. */ -#ifndef YY_READ_BUF_SIZE -#define YY_READ_BUF_SIZE 8192 -#endif - -/* Copy whatever the last rule matched to the standard output. */ - -#ifndef ECHO -/* This used to be an fputs(), but since the string might contain NUL's, - * we now use fwrite(). - */ -#define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) -#endif - -/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, - * is returned in "result". - */ -#ifndef YY_INPUT -#define YY_INPUT(buf,result,max_size) \ - if ( yy_current_buffer->yy_is_interactive ) \ - { \ - int c = '*', n; \ - for ( n = 0; n < max_size && \ - (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ - buf[n] = (char) c; \ - if ( c == '\n' ) \ - buf[n++] = (char) c; \ - if ( c == EOF && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - result = n; \ - } \ - else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \ - && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); -#endif - -/* No semi-colon after return; correct usage is to write "yyterminate();" - - * we don't want an extra ';' after the "return" because that will cause - * some compilers to complain about unreachable statements. - */ -#ifndef yyterminate -#define yyterminate() return YY_NULL -#endif - -/* Number of entries by which start-condition stack grows. */ -#ifndef YY_START_STACK_INCR -#define YY_START_STACK_INCR 25 -#endif - -/* Report a fatal error. */ -#ifndef YY_FATAL_ERROR -#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) -#endif - -/* Default declaration of generated scanner - a define so the user can - * easily add parameters. - */ -#ifndef YY_DECL -#define YY_DECL int yylex YY_PROTO(( void )) -#endif - -/* Code executed at the beginning of each rule, after yytext and yyleng - * have been set up. - */ -#ifndef YY_USER_ACTION -#define YY_USER_ACTION -#endif - -/* Code executed at the end of each rule. */ -#ifndef YY_BREAK -#define YY_BREAK break; -#endif - -#define YY_RULE_SETUP \ - if ( yyleng > 0 ) \ - yy_current_buffer->yy_at_bol = \ - (yytext[yyleng - 1] == '\n'); \ - YY_USER_ACTION - -YY_DECL - { - register yy_state_type yy_current_state; - register char *yy_cp, *yy_bp; - register int yy_act; - -#line 105 "parser.l" - -#line 3695 "lex.yy.c" - - if ( yy_init ) - { - yy_init = 0; - -#ifdef YY_USER_INIT - YY_USER_INIT; -#endif - - if ( ! yy_start ) - yy_start = 1; /* first start state */ - - if ( ! yyin ) - yyin = stdin; - - if ( ! yyout ) - yyout = stdout; - - if ( ! yy_current_buffer ) - yy_current_buffer = - yy_create_buffer( yyin, YY_BUF_SIZE ); - - yy_load_buffer_state(); - } - - while ( 1 ) /* loops until end-of-file is reached */ - { - yy_cp = yy_c_buf_p; - - /* Support of yytext. */ - *yy_cp = yy_hold_char; - - /* yy_bp points to the position in yy_ch_buf of the start of - * the current run. - */ - yy_bp = yy_cp; - - yy_current_state = yy_start; - yy_current_state += YY_AT_BOL(); -yy_match: - while ( (yy_current_state = yy_nxt[yy_current_state][YY_SC_TO_UI(*yy_cp)]) > 0 ) - { - if ( yy_accept[yy_current_state] ) - { - yy_last_accepting_state = yy_current_state; - yy_last_accepting_cpos = yy_cp; - } - - ++yy_cp; - } - - yy_current_state = -yy_current_state; - -yy_find_action: - yy_act = yy_accept[yy_current_state]; - - YY_DO_BEFORE_ACTION; - - -do_action: /* This label is used only to access EOF actions. */ - - if ( yy_flex_debug ) - { - if ( yy_act == 0 ) - fprintf( stderr, "--scanner backing up\n" ); - else if ( yy_act < 19 ) - fprintf( stderr, "--accepting rule at line %d (\"%s\")\n", - yy_rule_linenum[yy_act], yytext ); - else if ( yy_act == 19 ) - fprintf( stderr, "--accepting default rule (\"%s\")\n", - yytext ); - else if ( yy_act == 20 ) - fprintf( stderr, "--(end of buffer or a NUL)\n" ); - else - fprintf( stderr, "--EOF (start condition %d)\n", YY_START ); - } - - switch ( yy_act ) - { /* beginning of action switch */ - case 0: /* must back up */ - /* undo the effects of YY_DO_BEFORE_ACTION */ - *yy_cp = yy_hold_char; - yy_cp = yy_last_accepting_cpos + 1; - yy_current_state = yy_last_accepting_state; - goto yy_find_action; - -case 1: -YY_RULE_SETUP -#line 106 "parser.l" -yy_push_state(pp_line); - YY_BREAK -case 2: -YY_RULE_SETUP -#line 107 "parser.l" -{ - int lineno; - char *cptr, *fname; - yy_pop_state(); - lineno = (int)strtol(yytext, &cptr, 10); - if(!lineno) - yyerror("Malformed '#...' line-directive; invalid linenumber"); - fname = strchr(cptr, '"'); - if(!fname) - yyerror("Malformed '#...' line-directive; missing filename"); - fname++; - cptr = strchr(fname, '"'); - if(!cptr) - yyerror("Malformed '#...' line-directive; missing terminating \""); - *cptr = '\0'; - line_number = lineno - 1; /* We didn't read the newline */ - free( input_name ); - input_name = xstrdup(fname); - } - YY_BREAK -case 3: -YY_RULE_SETUP -#line 126 "parser.l" -yy_push_state(QUOTE); cbufidx = 0; - YY_BREAK -case 4: -YY_RULE_SETUP -#line 127 "parser.l" -{ - yy_pop_state(); - yylval.str = get_buffered_cstring(); - return aSTRING; - } - YY_BREAK -case 5: -#line 133 "parser.l" -case 6: -YY_RULE_SETUP -#line 133 "parser.l" -addcchar(yytext[1]); - YY_BREAK -case 7: -YY_RULE_SETUP -#line 134 "parser.l" -addcchar('\\'); addcchar(yytext[1]); - YY_BREAK -case 8: -YY_RULE_SETUP -#line 135 "parser.l" -addcchar(yytext[0]); - YY_BREAK -case 9: -YY_RULE_SETUP -#line 136 "parser.l" -{ - yylval.uuid = parse_uuid(yytext); - return aUUID; - } - YY_BREAK -case 10: -YY_RULE_SETUP -#line 140 "parser.l" -{ - yylval.num = strtoul(yytext, NULL, 0); - return aHEXNUM; - } - YY_BREAK -case 11: -YY_RULE_SETUP -#line 144 "parser.l" -{ - yylval.num = strtoul(yytext, NULL, 0); - return aNUM; - } - YY_BREAK -case 12: -*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ -yy_c_buf_p = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -YY_RULE_SETUP -#line 148 "parser.l" -return tSAFEARRAY; - YY_BREAK -case 13: -YY_RULE_SETUP -#line 149 "parser.l" -return kw_token(yytext); - YY_BREAK -case 14: -YY_RULE_SETUP -#line 150 "parser.l" -line_number++; - YY_BREAK -case 15: -YY_RULE_SETUP -#line 151 "parser.l" - - YY_BREAK -case 16: -YY_RULE_SETUP -#line 152 "parser.l" -return SHL; - YY_BREAK -case 17: -YY_RULE_SETUP -#line 153 "parser.l" -return SHR; - YY_BREAK -case 18: -YY_RULE_SETUP -#line 154 "parser.l" -return yytext[0]; - YY_BREAK -case YY_STATE_EOF(INITIAL): -case YY_STATE_EOF(QUOTE): -case YY_STATE_EOF(pp_line): -#line 155 "parser.l" -{ - if (import_stack_ptr) { - pop_import(); - return aEOF; - } - else yyterminate(); - } - YY_BREAK -case 19: -YY_RULE_SETUP -#line 162 "parser.l" -ECHO; - YY_BREAK -#line 3920 "lex.yy.c" - - case YY_END_OF_BUFFER: - { - /* Amount of text matched not including the EOB char. */ - int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1; - - /* Undo the effects of YY_DO_BEFORE_ACTION. */ - *yy_cp = yy_hold_char; - YY_RESTORE_YY_MORE_OFFSET - - if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW ) - { - /* We're scanning a new file or input source. It's - * possible that this happened because the user - * just pointed yyin at a new source and called - * yylex(). If so, then we have to assure - * consistency between yy_current_buffer and our - * globals. Here is the right place to do so, because - * this is the first action (other than possibly a - * back-up) that will match for the new input source. - */ - yy_n_chars = yy_current_buffer->yy_n_chars; - yy_current_buffer->yy_input_file = yyin; - yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL; - } - - /* Note that here we test for yy_c_buf_p "<=" to the position - * of the first EOB in the buffer, since yy_c_buf_p will - * already have been incremented past the NUL character - * (since all states make transitions on EOB to the - * end-of-buffer state). Contrast this with the test - * in input(). - */ - if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) - { /* This was really a NUL. */ - yy_state_type yy_next_state; - - yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state(); - - /* Okay, we're now positioned to make the NUL - * transition. We couldn't have - * yy_get_previous_state() go ahead and do it - * for us because it doesn't know how to deal - * with the possibility of jamming (and we don't - * want to build jamming into it because then it - * will run more slowly). - */ - - yy_next_state = yy_try_NUL_trans( yy_current_state ); - - yy_bp = yytext_ptr + YY_MORE_ADJ; - - if ( yy_next_state ) - { - /* Consume the NUL. */ - yy_cp = ++yy_c_buf_p; - yy_current_state = yy_next_state; - goto yy_match; - } - - else - { - yy_cp = yy_c_buf_p; - goto yy_find_action; - } - } - - else switch ( yy_get_next_buffer() ) - { - case EOB_ACT_END_OF_FILE: - { - yy_did_buffer_switch_on_eof = 0; - - if ( yywrap() ) - { - /* Note: because we've taken care in - * yy_get_next_buffer() to have set up - * yytext, we can now set up - * yy_c_buf_p so that if some total - * hoser (like flex itself) wants to - * call the scanner after we return the - * YY_NULL, it'll still work - another - * YY_NULL will get returned. - */ - yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; - - yy_act = YY_STATE_EOF(YY_START); - goto do_action; - } - - else - { - if ( ! yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; - } - break; - } - - case EOB_ACT_CONTINUE_SCAN: - yy_c_buf_p = - yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state(); - - yy_cp = yy_c_buf_p; - yy_bp = yytext_ptr + YY_MORE_ADJ; - goto yy_match; - - case EOB_ACT_LAST_MATCH: - yy_c_buf_p = - &yy_current_buffer->yy_ch_buf[yy_n_chars]; - - yy_current_state = yy_get_previous_state(); - - yy_cp = yy_c_buf_p; - yy_bp = yytext_ptr + YY_MORE_ADJ; - goto yy_find_action; - } - break; - } - - default: - YY_FATAL_ERROR( - "fatal flex scanner internal error--no action found" ); - } /* end of action switch */ - } /* end of scanning one token */ - } /* end of yylex */ - - -/* yy_get_next_buffer - try to read in a new buffer - * - * Returns a code representing an action: - * EOB_ACT_LAST_MATCH - - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position - * EOB_ACT_END_OF_FILE - end of file - */ - -static int yy_get_next_buffer() - { - register char *dest = yy_current_buffer->yy_ch_buf; - register char *source = yytext_ptr; - register int number_to_move, i; - int ret_val; - - if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) - YY_FATAL_ERROR( - "fatal flex scanner internal error--end of buffer missed" ); - - if ( yy_current_buffer->yy_fill_buffer == 0 ) - { /* Don't try to fill the buffer, so this is an EOF. */ - if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 ) - { - /* We matched a single character, the EOB, so - * treat this as a final EOF. - */ - return EOB_ACT_END_OF_FILE; - } - - else - { - /* We matched some text prior to the EOB, first - * process it. - */ - return EOB_ACT_LAST_MATCH; - } - } - - /* Try to read more data. */ - - /* First move last chars to start of buffer. */ - number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1; - - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); - - if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING ) - /* don't do the read, it's not guaranteed to return an EOF, - * just force an EOF - */ - yy_current_buffer->yy_n_chars = yy_n_chars = 0; - - else - { - int num_to_read = - yy_current_buffer->yy_buf_size - number_to_move - 1; - - while ( num_to_read <= 0 ) - { /* Not enough room in the buffer - grow it. */ -#ifdef YY_USES_REJECT - YY_FATAL_ERROR( -"input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); -#else - - /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = yy_current_buffer; - - int yy_c_buf_p_offset = - (int) (yy_c_buf_p - b->yy_ch_buf); - - if ( b->yy_is_our_buffer ) - { - int new_size = b->yy_buf_size * 2; - - if ( new_size <= 0 ) - b->yy_buf_size += b->yy_buf_size / 8; - else - b->yy_buf_size *= 2; - - b->yy_ch_buf = (char *) - /* Include room in for 2 EOB chars. */ - yy_flex_realloc( (void *) b->yy_ch_buf, - b->yy_buf_size + 2 ); - } - else - /* Can't grow it, we don't own it. */ - b->yy_ch_buf = 0; - - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( - "fatal error - scanner input buffer overflow" ); - - yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; - - num_to_read = yy_current_buffer->yy_buf_size - - number_to_move - 1; -#endif - } - - if ( num_to_read > YY_READ_BUF_SIZE ) - num_to_read = YY_READ_BUF_SIZE; - - /* Read in more data. */ - YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), - yy_n_chars, num_to_read ); - - yy_current_buffer->yy_n_chars = yy_n_chars; - } - - if ( yy_n_chars == 0 ) - { - if ( number_to_move == YY_MORE_ADJ ) - { - ret_val = EOB_ACT_END_OF_FILE; - yyrestart( yyin ); - } - - else - { - ret_val = EOB_ACT_LAST_MATCH; - yy_current_buffer->yy_buffer_status = - YY_BUFFER_EOF_PENDING; - } - } - - else - ret_val = EOB_ACT_CONTINUE_SCAN; - - yy_n_chars += number_to_move; - yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; - yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; - - yytext_ptr = &yy_current_buffer->yy_ch_buf[0]; - - return ret_val; - } - - -/* yy_get_previous_state - get the state just before the EOB char was reached */ - -static yy_state_type yy_get_previous_state() - { - register yy_state_type yy_current_state; - register char *yy_cp; - - yy_current_state = yy_start; - yy_current_state += YY_AT_BOL(); - - for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) - { - if ( *yy_cp ) - { - yy_current_state = yy_nxt[yy_current_state][YY_SC_TO_UI(*yy_cp)]; - } - else - yy_current_state = yy_NUL_trans[yy_current_state]; - if ( yy_accept[yy_current_state] ) - { - yy_last_accepting_state = yy_current_state; - yy_last_accepting_cpos = yy_cp; - } - } - - return yy_current_state; - } - - -/* yy_try_NUL_trans - try to make a transition on the NUL character - * - * synopsis - * next_state = yy_try_NUL_trans( current_state ); - */ - -#ifdef YY_USE_PROTOS -static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state ) -#else -static yy_state_type yy_try_NUL_trans( yy_current_state ) -yy_state_type yy_current_state; -#endif - { - register int yy_is_jam; - register char *yy_cp = yy_c_buf_p; - - yy_current_state = yy_NUL_trans[yy_current_state]; - yy_is_jam = (yy_current_state == 0); - - if ( ! yy_is_jam ) - { - if ( yy_accept[yy_current_state] ) - { - yy_last_accepting_state = yy_current_state; - yy_last_accepting_cpos = yy_cp; - } - } - - return yy_is_jam ? 0 : yy_current_state; - } - - -#ifndef YY_NO_UNPUT -#ifdef YY_USE_PROTOS -static void yyunput( int c, register char *yy_bp ) -#else -static void yyunput( c, yy_bp ) -int c; -register char *yy_bp; -#endif - { - register char *yy_cp = yy_c_buf_p; - - /* undo effects of setting up yytext */ - *yy_cp = yy_hold_char; - - if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) - { /* need to shift things up to make room */ - /* +2 for EOB chars. */ - register int number_to_move = yy_n_chars + 2; - register char *dest = &yy_current_buffer->yy_ch_buf[ - yy_current_buffer->yy_buf_size + 2]; - register char *source = - &yy_current_buffer->yy_ch_buf[number_to_move]; - - while ( source > yy_current_buffer->yy_ch_buf ) - *--dest = *--source; - - yy_cp += (int) (dest - source); - yy_bp += (int) (dest - source); - yy_current_buffer->yy_n_chars = - yy_n_chars = yy_current_buffer->yy_buf_size; - - if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) - YY_FATAL_ERROR( "flex scanner push-back overflow" ); - } - - *--yy_cp = (char) c; - - - yytext_ptr = yy_bp; - yy_hold_char = *yy_cp; - yy_c_buf_p = yy_cp; - } -#endif /* ifndef YY_NO_UNPUT */ - - -#ifdef __cplusplus -static int yyinput() -#else -static int input() -#endif - { - int c; - - *yy_c_buf_p = yy_hold_char; - - if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) - { - /* yy_c_buf_p now points to the character we want to return. - * If this occurs *before* the EOB characters, then it's a - * valid NUL; if not, then we've hit the end of the buffer. - */ - if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) - /* This was really a NUL. */ - *yy_c_buf_p = '\0'; - - else - { /* need more input */ - int offset = yy_c_buf_p - yytext_ptr; - ++yy_c_buf_p; - - switch ( yy_get_next_buffer() ) - { - case EOB_ACT_LAST_MATCH: - /* This happens because yy_g_n_b() - * sees that we've accumulated a - * token and flags that we need to - * try matching the token before - * proceeding. But for input(), - * there's no matching to consider. - * So convert the EOB_ACT_LAST_MATCH - * to EOB_ACT_END_OF_FILE. - */ - - /* Reset buffer status. */ - yyrestart( yyin ); - - /* fall through */ - - case EOB_ACT_END_OF_FILE: - { - if ( yywrap() ) - return EOF; - - if ( ! yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; -#ifdef __cplusplus - return yyinput(); -#else - return input(); -#endif - } - - case EOB_ACT_CONTINUE_SCAN: - yy_c_buf_p = yytext_ptr + offset; - break; - } - } - } - - c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */ - *yy_c_buf_p = '\0'; /* preserve yytext */ - yy_hold_char = *++yy_c_buf_p; - - yy_current_buffer->yy_at_bol = (c == '\n'); - - return c; - } - - -#ifdef YY_USE_PROTOS -void yyrestart( FILE *input_file ) -#else -void yyrestart( input_file ) -FILE *input_file; -#endif - { - if ( ! yy_current_buffer ) - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); - - yy_init_buffer( yy_current_buffer, input_file ); - yy_load_buffer_state(); - } - - -#ifdef YY_USE_PROTOS -void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) -#else -void yy_switch_to_buffer( new_buffer ) -YY_BUFFER_STATE new_buffer; -#endif - { - if ( yy_current_buffer == new_buffer ) - return; - - if ( yy_current_buffer ) - { - /* Flush out information for old buffer. */ - *yy_c_buf_p = yy_hold_char; - yy_current_buffer->yy_buf_pos = yy_c_buf_p; - yy_current_buffer->yy_n_chars = yy_n_chars; - } - - yy_current_buffer = new_buffer; - yy_load_buffer_state(); - - /* We don't actually know whether we did this switch during - * EOF (yywrap()) processing, but the only time this flag - * is looked at is after yywrap() is called, so it's safe - * to go ahead and always set it. - */ - yy_did_buffer_switch_on_eof = 1; - } - - -#ifdef YY_USE_PROTOS -void yy_load_buffer_state( void ) -#else -void yy_load_buffer_state() -#endif - { - yy_n_chars = yy_current_buffer->yy_n_chars; - yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos; - yyin = yy_current_buffer->yy_input_file; - yy_hold_char = *yy_c_buf_p; - } - - -#ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_create_buffer( FILE *file, int size ) -#else -YY_BUFFER_STATE yy_create_buffer( file, size ) -FILE *file; -int size; -#endif - { - YY_BUFFER_STATE b; - - b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_buf_size = size; - - /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. - */ - b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 ); - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_is_our_buffer = 1; - - yy_init_buffer( b, file ); - - return b; - } - - -#ifdef YY_USE_PROTOS -void yy_delete_buffer( YY_BUFFER_STATE b ) -#else -void yy_delete_buffer( b ) -YY_BUFFER_STATE b; -#endif - { - if ( ! b ) - return; - - if ( b == yy_current_buffer ) - yy_current_buffer = (YY_BUFFER_STATE) 0; - - if ( b->yy_is_our_buffer ) - yy_flex_free( (void *) b->yy_ch_buf ); - - yy_flex_free( (void *) b ); - } - - -#ifndef YY_ALWAYS_INTERACTIVE -#ifndef YY_NEVER_INTERACTIVE -extern int isatty YY_PROTO(( int )); -#endif -#endif - -#ifdef YY_USE_PROTOS -void yy_init_buffer( YY_BUFFER_STATE b, FILE *file ) -#else -void yy_init_buffer( b, file ) -YY_BUFFER_STATE b; -FILE *file; -#endif - - - { - yy_flush_buffer( b ); - - b->yy_input_file = file; - b->yy_fill_buffer = 1; - -#if YY_ALWAYS_INTERACTIVE - b->yy_is_interactive = 1; -#else -#if YY_NEVER_INTERACTIVE - b->yy_is_interactive = 0; -#else - b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; -#endif -#endif - } - - -#ifdef YY_USE_PROTOS -void yy_flush_buffer( YY_BUFFER_STATE b ) -#else -void yy_flush_buffer( b ) -YY_BUFFER_STATE b; -#endif - - { - if ( ! b ) - return; - - b->yy_n_chars = 0; - - /* We always need two end-of-buffer characters. The first causes - * a transition to the end-of-buffer state. The second causes - * a jam in that state. - */ - b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; - b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; - - b->yy_buf_pos = &b->yy_ch_buf[0]; - - b->yy_at_bol = 1; - b->yy_buffer_status = YY_BUFFER_NEW; - - if ( b == yy_current_buffer ) - yy_load_buffer_state(); - } - - -#ifndef YY_NO_SCAN_BUFFER -#ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size ) -#else -YY_BUFFER_STATE yy_scan_buffer( base, size ) -char *base; -yy_size_t size; -#endif - { - YY_BUFFER_STATE b; - - if ( size < 2 || - base[size-2] != YY_END_OF_BUFFER_CHAR || - base[size-1] != YY_END_OF_BUFFER_CHAR ) - /* They forgot to leave room for the EOB's. */ - return 0; - - b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); - - b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ - b->yy_buf_pos = b->yy_ch_buf = base; - b->yy_is_our_buffer = 0; - b->yy_input_file = 0; - b->yy_n_chars = b->yy_buf_size; - b->yy_is_interactive = 0; - b->yy_at_bol = 1; - b->yy_fill_buffer = 0; - b->yy_buffer_status = YY_BUFFER_NEW; - - yy_switch_to_buffer( b ); - - return b; - } -#endif - - -#ifndef YY_NO_SCAN_STRING -#ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str ) -#else -YY_BUFFER_STATE yy_scan_string( yy_str ) -yyconst char *yy_str; -#endif - { - int len; - for ( len = 0; yy_str[len]; ++len ) - ; - - return yy_scan_bytes( yy_str, len ); - } -#endif - - -#ifndef YY_NO_SCAN_BYTES -#ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len ) -#else -YY_BUFFER_STATE yy_scan_bytes( bytes, len ) -yyconst char *bytes; -int len; -#endif - { - YY_BUFFER_STATE b; - char *buf; - yy_size_t n; - int i; - - /* Get memory for full buffer, including space for trailing EOB's. */ - n = len + 2; - buf = (char *) yy_flex_alloc( n ); - if ( ! buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); - - for ( i = 0; i < len; ++i ) - buf[i] = bytes[i]; - - buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; - - b = yy_scan_buffer( buf, n ); - if ( ! b ) - YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); - - /* It's okay to grow etc. this buffer, and we should throw it - * away when we're done. - */ - b->yy_is_our_buffer = 1; - - return b; - } -#endif - - -#ifndef YY_NO_PUSH_STATE -#ifdef YY_USE_PROTOS -static void yy_push_state( int new_state ) -#else -static void yy_push_state( new_state ) -int new_state; -#endif - { - if ( yy_start_stack_ptr >= yy_start_stack_depth ) - { - yy_size_t new_size; - - yy_start_stack_depth += YY_START_STACK_INCR; - new_size = yy_start_stack_depth * sizeof( int ); - - if ( ! yy_start_stack ) - yy_start_stack = (int *) yy_flex_alloc( new_size ); - - else - yy_start_stack = (int *) yy_flex_realloc( - (void *) yy_start_stack, new_size ); - - if ( ! yy_start_stack ) - YY_FATAL_ERROR( - "out of memory expanding start-condition stack" ); - } - - yy_start_stack[yy_start_stack_ptr++] = YY_START; - - BEGIN(new_state); - } -#endif - - -#ifndef YY_NO_POP_STATE -static void yy_pop_state() - { - if ( --yy_start_stack_ptr < 0 ) - YY_FATAL_ERROR( "start-condition stack underflow" ); - - BEGIN(yy_start_stack[yy_start_stack_ptr]); - } -#endif - - -#ifndef YY_NO_TOP_STATE -static int yy_top_state() - { - return yy_start_stack[yy_start_stack_ptr - 1]; - } -#endif - -#ifndef YY_EXIT_FAILURE -#define YY_EXIT_FAILURE 2 -#endif - -#ifdef YY_USE_PROTOS -static void yy_fatal_error( yyconst char msg[] ) -#else -static void yy_fatal_error( msg ) -char msg[]; -#endif - { - (void) fprintf( stderr, "%s\n", msg ); - exit( YY_EXIT_FAILURE ); - } - - - -/* Redefine yyless() so it works in section 3 code. */ - -#undef yyless -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - yytext[yyleng] = yy_hold_char; \ - yy_c_buf_p = yytext + n; \ - yy_hold_char = *yy_c_buf_p; \ - *yy_c_buf_p = '\0'; \ - yyleng = n; \ - } \ - while ( 0 ) - - -/* Internal utility routines. */ - -#ifndef yytext_ptr -#ifdef YY_USE_PROTOS -static void yy_flex_strncpy( char *s1, yyconst char *s2, int n ) -#else -static void yy_flex_strncpy( s1, s2, n ) -char *s1; -yyconst char *s2; -int n; -#endif - { - register int i; - for ( i = 0; i < n; ++i ) - s1[i] = s2[i]; - } -#endif - -#ifdef YY_NEED_STRLEN -#ifdef YY_USE_PROTOS -static int yy_flex_strlen( yyconst char *s ) -#else -static int yy_flex_strlen( s ) -yyconst char *s; -#endif - { - register int n; - for ( n = 0; s[n]; ++n ) - ; - - return n; - } -#endif - - -#ifdef YY_USE_PROTOS -static void *yy_flex_alloc( yy_size_t size ) -#else -static void *yy_flex_alloc( size ) -yy_size_t size; -#endif - { - return (void *) malloc( size ); - } - -#ifdef YY_USE_PROTOS -static void *yy_flex_realloc( void *ptr, yy_size_t size ) -#else -static void *yy_flex_realloc( ptr, size ) -void *ptr; -yy_size_t size; -#endif - { - /* The cast to (char *) in the following accommodates both - * implementations that use char* generic pointers, and those - * that use void* generic pointers. It works with the latter - * because both ANSI C and C++ allow castless assignment from - * any pointer type to void*, and deal with argument conversions - * as though doing an assignment. - */ - return (void *) realloc( (char *) ptr, size ); - } - -#ifdef YY_USE_PROTOS -static void yy_flex_free( void *ptr ) -#else -static void yy_flex_free( ptr ) -void *ptr; -#endif - { - free( ptr ); - } - -#if YY_MAIN -int main() - { - yylex(); - return 0; - } -#endif -#line 162 "parser.l" - - -#ifndef yywrap -int yywrap(void) -{ - return 1; -} -#endif - -static struct keyword { - const char *kw; - int token; - int val; -} keywords[] = { - {"FALSE", tFALSE}, - {"TRUE", tTRUE}, - {"__cdecl", tCDECL}, - {"__int64", tINT64}, - {"__stdcall", tSTDCALL}, - {"_stdcall", tSTDCALL}, - {"aggregatable", tAGGREGATABLE}, - {"allocate", tALLOCATE}, - {"appobject", tAPPOBJECT}, - {"async", tASYNC}, - {"async_uuid", tASYNCUUID}, - {"auto_handle", tAUTOHANDLE}, - {"bindable", tBINDABLE}, - {"boolean", tBOOLEAN}, - {"broadcast", tBROADCAST}, - {"byte", tBYTE}, - {"byte_count", tBYTECOUNT}, - {"call_as", tCALLAS}, - {"callback", tCALLBACK}, - {"case", tCASE}, - {"char", tCHAR}, - {"coclass", tCOCLASS}, - {"code", tCODE}, - {"comm_status", tCOMMSTATUS}, - {"const", tCONST}, - {"context_handle", tCONTEXTHANDLE}, - {"context_handle_noserialize", tCONTEXTHANDLENOSERIALIZE}, - {"context_handle_serialize", tCONTEXTHANDLENOSERIALIZE}, - {"control", tCONTROL}, - {"cpp_quote", tCPPQUOTE}, -/* ... */ - {"default", tDEFAULT}, - {"defaultcollelem", tDEFAULTCOLLELEM}, - {"defaultvalue", tDEFAULTVALUE}, - {"defaultvtable", tDEFAULTVTABLE}, - {"dispinterface", tDISPINTERFACE}, - {"displaybind", tDISPLAYBIND}, - {"dllname", tDLLNAME}, - {"double", tDOUBLE}, - {"dual", tDUAL}, - {"endpoint", tENDPOINT}, - {"entry", tENTRY}, - {"enum", tENUM}, - {"error_status_t", tERRORSTATUST}, - {"explicit_handle", tEXPLICITHANDLE}, - {"extern", tEXTERN}, - {"float", tFLOAT}, - {"handle", tHANDLE}, - {"handle_t", tHANDLET}, - {"helpcontext", tHELPCONTEXT}, - {"helpfile", tHELPFILE}, - {"helpstring", tHELPSTRING}, - {"helpstringcontext", tHELPSTRINGCONTEXT}, - {"helpstringdll", tHELPSTRINGDLL}, - {"hidden", tHIDDEN}, - {"hyper", tHYPER}, - {"id", tID}, - {"idempotent", tIDEMPOTENT}, -/* ... */ - {"iid_is", tIIDIS}, - {"immediatebind", tIMMEDIATEBIND}, - {"implicit_handle", tIMPLICITHANDLE}, - {"import", tIMPORT}, - {"importlib", tIMPORTLIB}, - {"in", tIN}, - {"in_line", tINLINE}, - {"input_sync", tINPUTSYNC}, - {"int", tINT}, -/* ... */ - {"interface", tINTERFACE}, - {"lcid", tLCID}, - {"length_is", tLENGTHIS}, - {"library", tLIBRARY}, -/* ... */ - {"local", tLOCAL}, - {"long", tLONG}, -/* ... */ - {"methods", tMETHODS}, -/* ... */ - {"module", tMODULE}, -/* ... */ - {"nonbrowsable", tNONBROWSABLE}, - {"noncreatable", tNONCREATABLE}, - {"nonextensible", tNONEXTENSIBLE}, - {"object", tOBJECT}, - {"odl", tODL}, - {"oleautomation", tOLEAUTOMATION}, -/* ... */ - {"optional", tOPTIONAL}, - {"out", tOUT}, -/* ... */ - {"pointer_default", tPOINTERDEFAULT}, -/* ... */ - {"properties", tPROPERTIES}, - {"propget", tPROPGET}, - {"propput", tPROPPUT}, - {"propputref", tPROPPUTREF}, - {"ptr", tPTR}, -/* ... */ - {"public", tPUBLIC}, - {"range", tRANGE}, -/* ... */ - {"readonly", tREADONLY}, - {"ref", tREF}, - {"requestedit", tREQUESTEDIT}, - {"restricted", tRESTRICTED}, - {"retval", tRETVAL}, -/* ... */ - {"short", tSHORT}, - {"signed", tSIGNED}, - {"single", tSINGLE}, - {"size_is", tSIZEIS}, - {"sizeof", tSIZEOF}, - {"small", tSMALL}, -/* ... */ - {"source", tSOURCE}, -/* ... */ - {"string", tSTRING}, - {"struct", tSTRUCT}, - {"switch", tSWITCH}, - {"switch_is", tSWITCHIS}, - {"switch_type", tSWITCHTYPE}, -/* ... */ - {"transmit_as", tTRANSMITAS}, - {"typedef", tTYPEDEF}, - {"union", tUNION}, -/* ... */ - {"unique", tUNIQUE}, - {"unsigned", tUNSIGNED}, -/* ... */ - {"uuid", tUUID}, - {"v1_enum", tV1ENUM}, -/* ... */ - {"vararg", tVARARG}, - {"version", tVERSION}, - {"void", tVOID}, - {"wchar_t", tWCHAR}, - {"wire_marshal", tWIREMARSHAL}, -}; -#define NKEYWORDS (sizeof(keywords)/sizeof(keywords[0])) -#define KWP(p) ((const struct keyword *)(p)) - -static int kw_cmp_func(const void *s1, const void *s2) -{ - return strcmp(KWP(s1)->kw, KWP(s2)->kw); -} - -#define KW_BSEARCH -static int kw_token(const char *kw) -{ - struct keyword key, *kwp; - key.kw = kw; -#ifdef KW_BSEARCH - kwp = bsearch(&key, keywords, NKEYWORDS, sizeof(keywords[0]), kw_cmp_func); -#else - { - int i; - for (kwp=NULL, i=0; i < NKEYWORDS; i++) - if (!kw_cmp_func(&key, &keywords[i])) { - kwp = &keywords[i]; - break; - } - } -#endif - if (kwp) { - yylval.str = (char*)kwp->kw; - return kwp->token; - } - yylval.str = xstrdup(kw); - return is_type(kw) ? aKNOWNTYPE : aIDENTIFIER; -} - -static void addcchar(char c) -{ - if(cbufidx >= cbufalloc) - { - cbufalloc += 1024; - cbuffer = xrealloc(cbuffer, cbufalloc * sizeof(cbuffer[0])); - if(cbufalloc > 65536) - yywarning("Reallocating string buffer larger than 64kB"); - } - cbuffer[cbufidx++] = c; -} - -static char *get_buffered_cstring(void) -{ - addcchar(0); - return xstrdup(cbuffer); -} - -static void pop_import(void) -{ - int ptr = import_stack_ptr-1; - - fclose(yyin); - yy_delete_buffer( YY_CURRENT_BUFFER ); - yy_switch_to_buffer( import_stack[ptr].state ); - if (temp_name) { - unlink(temp_name); - free(temp_name); - } - temp_name = import_stack[ptr].temp_name; - free( input_name ); - input_name = import_stack[ptr].input_name; - line_number = import_stack[ptr].line_number; - import_stack_ptr--; -} - -struct imports { - char *name; - struct imports *next; -} *first_import; - -int do_import(char *fname) -{ - FILE *f; - char *hname, *path, *p; - struct imports *import; - int ptr = import_stack_ptr; - int ret; - - if (!parse_only && do_header) { - hname = dup_basename(fname, ".idl"); - p = hname + strlen(hname) - 2; - if (p <= hname || strcmp( p, ".h" )) strcat(hname, ".h"); - - fprintf(header, "#include <%s>\n", hname); - free(hname); - } - - import = first_import; - while (import && strcmp(import->name, fname)) - import = import->next; - if (import) return 0; /* already imported */ - - import = xmalloc(sizeof(struct imports)); - import->name = xstrdup(fname); - import->next = first_import; - first_import = import; - - if (!(path = wpp_find_include( fname, input_name ))) - yyerror("Unable to open include file %s", fname); - - import_stack[ptr].temp_name = temp_name; - import_stack[ptr].input_name = input_name; - import_stack[ptr].line_number = line_number; - import_stack_ptr++; - input_name = path; - line_number = 1; - - ret = wpp_parse_temp( path, NULL, &temp_name ); - if (ret) exit(1); - - if((f = fopen(temp_name, "r")) == NULL) - yyerror("Unable to open %s", temp_name); - - import_stack[ptr].state = YY_CURRENT_BUFFER; - yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE)); - return 1; -} - -void abort_import(void) -{ - int ptr; - - for (ptr=0; ptr^{ws}*\#{ws}* yy_push_state(pp_line); -[^\n]* { +^{ws}*\#{ws}* yy_push_state(PP_LINE); +[^\n]* { int lineno; char *cptr, *fname; yy_pop_state(); lineno = (int)strtol(yytext, &cptr, 10); if(!lineno) - yyerror("Malformed '#...' line-directive; invalid linenumber"); + error_loc("Malformed '#...' line-directive; invalid linenumber\n"); fname = strchr(cptr, '"'); if(!fname) - yyerror("Malformed '#...' line-directive; missing filename"); + error_loc("Malformed '#...' line-directive; missing filename\n"); fname++; cptr = strchr(fname, '"'); if(!cptr) - yyerror("Malformed '#...' line-directive; missing terminating \""); + error_loc("Malformed '#...' line-directive; missing terminating \"\n"); *cptr = '\0'; line_number = lineno - 1; /* We didn't read the newline */ free( input_name ); input_name = xstrdup(fname); } -\" yy_push_state(QUOTE); cbufidx = 0; +\" yy_push_state(QUOTE); cbufidx = 0; \" { yy_pop_state(); - yylval.str = get_buffered_cstring(); + parser_lval.str = get_buffered_cstring(); return aSTRING; } \\\\ | \\\" addcchar(yytext[1]); \\. addcchar('\\'); addcchar(yytext[1]); . addcchar(yytext[0]); -{uuid} { - yylval.uuid = parse_uuid(yytext); +\[ yy_push_state(ATTR); return '['; +\] yy_pop_state(); return ']'; +{cident} return attr_token(yytext); +{uuid} { + parser_lval.uuid = parse_uuid(yytext); return aUUID; } -{hex} { - yylval.num = strtoul(yytext, NULL, 0); +{hex} { + parser_lval.num = strtoul(yytext, NULL, 0); return aHEXNUM; } -{int} { - yylval.num = strtoul(yytext, NULL, 0); +{int} { + parser_lval.num = strtoul(yytext, NULL, 0); return aNUM; } +{double} { + parser_lval.dbl = strtod(yytext, NULL); + return aDOUBLE; + } SAFEARRAY{ws}*/\( return tSAFEARRAY; {cident} return kw_token(yytext); -\n line_number++; -{ws} -\<\< return SHL; -\>\> return SHR; -. return yytext[0]; +\n line_number++; +{ws} +\<\< return SHL; +\>\> return SHR; +. return yytext[0]; <> { if (import_stack_ptr) { pop_import(); @@ -161,36 +171,27 @@ SAFEARRAY{ws}*/\( return tSAFEARRAY; } %% -#ifndef yywrap -int yywrap(void) +#ifndef parser_wrap +int parser_wrap(void) { return 1; } #endif -static struct keyword { +struct keyword { const char *kw; int token; - int val; -} keywords[] = { +}; + +static const struct keyword keywords[] = { {"FALSE", tFALSE}, {"TRUE", tTRUE}, {"__cdecl", tCDECL}, {"__int64", tINT64}, {"__stdcall", tSTDCALL}, {"_stdcall", tSTDCALL}, - {"aggregatable", tAGGREGATABLE}, - {"allocate", tALLOCATE}, - {"appobject", tAPPOBJECT}, - {"async", tASYNC}, - {"async_uuid", tASYNCUUID}, - {"auto_handle", tAUTOHANDLE}, - {"bindable", tBINDABLE}, {"boolean", tBOOLEAN}, - {"broadcast", tBROADCAST}, {"byte", tBYTE}, - {"byte_count", tBYTECOUNT}, - {"call_as", tCALLAS}, {"callback", tCALLBACK}, {"case", tCASE}, {"char", tCHAR}, @@ -198,121 +199,119 @@ static struct keyword { {"code", tCODE}, {"comm_status", tCOMMSTATUS}, {"const", tCONST}, - {"context_handle", tCONTEXTHANDLE}, - {"context_handle_noserialize", tCONTEXTHANDLENOSERIALIZE}, - {"context_handle_serialize", tCONTEXTHANDLENOSERIALIZE}, - {"control", tCONTROL}, {"cpp_quote", tCPPQUOTE}, -/* ... */ {"default", tDEFAULT}, - {"defaultcollelem", tDEFAULTCOLLELEM}, - {"defaultvalue", tDEFAULTVALUE}, - {"defaultvtable", tDEFAULTVTABLE}, {"dispinterface", tDISPINTERFACE}, - {"displaybind", tDISPLAYBIND}, - {"dllname", tDLLNAME}, {"double", tDOUBLE}, - {"dual", tDUAL}, - {"endpoint", tENDPOINT}, - {"entry", tENTRY}, {"enum", tENUM}, {"error_status_t", tERRORSTATUST}, - {"explicit_handle", tEXPLICITHANDLE}, {"extern", tEXTERN}, {"float", tFLOAT}, - {"handle", tHANDLE}, {"handle_t", tHANDLET}, - {"helpcontext", tHELPCONTEXT}, - {"helpfile", tHELPFILE}, - {"helpstring", tHELPSTRING}, - {"helpstringcontext", tHELPSTRINGCONTEXT}, - {"helpstringdll", tHELPSTRINGDLL}, - {"hidden", tHIDDEN}, {"hyper", tHYPER}, - {"id", tID}, - {"idempotent", tIDEMPOTENT}, -/* ... */ - {"iid_is", tIIDIS}, - {"immediatebind", tIMMEDIATEBIND}, - {"implicit_handle", tIMPLICITHANDLE}, {"import", tIMPORT}, {"importlib", tIMPORTLIB}, - {"in", tIN}, {"in_line", tINLINE}, - {"input_sync", tINPUTSYNC}, {"int", tINT}, -/* ... */ {"interface", tINTERFACE}, - {"lcid", tLCID}, - {"length_is", tLENGTHIS}, {"library", tLIBRARY}, -/* ... */ - {"local", tLOCAL}, {"long", tLONG}, -/* ... */ {"methods", tMETHODS}, -/* ... */ {"module", tMODULE}, -/* ... */ - {"nonbrowsable", tNONBROWSABLE}, - {"noncreatable", tNONCREATABLE}, - {"nonextensible", tNONEXTENSIBLE}, - {"object", tOBJECT}, - {"odl", tODL}, - {"oleautomation", tOLEAUTOMATION}, -/* ... */ - {"optional", tOPTIONAL}, - {"out", tOUT}, -/* ... */ - {"pointer_default", tPOINTERDEFAULT}, -/* ... */ {"properties", tPROPERTIES}, - {"propget", tPROPGET}, - {"propput", tPROPPUT}, - {"propputref", tPROPPUTREF}, - {"ptr", tPTR}, -/* ... */ - {"public", tPUBLIC}, - {"range", tRANGE}, -/* ... */ - {"readonly", tREADONLY}, - {"ref", tREF}, - {"requestedit", tREQUESTEDIT}, - {"restricted", tRESTRICTED}, - {"retval", tRETVAL}, -/* ... */ {"short", tSHORT}, {"signed", tSIGNED}, - {"single", tSINGLE}, - {"size_is", tSIZEIS}, {"sizeof", tSIZEOF}, {"small", tSMALL}, -/* ... */ - {"source", tSOURCE}, -/* ... */ - {"string", tSTRING}, {"struct", tSTRUCT}, {"switch", tSWITCH}, - {"switch_is", tSWITCHIS}, - {"switch_type", tSWITCHTYPE}, -/* ... */ - {"transmit_as", tTRANSMITAS}, {"typedef", tTYPEDEF}, {"union", tUNION}, -/* ... */ - {"unique", tUNIQUE}, {"unsigned", tUNSIGNED}, -/* ... */ - {"uuid", tUUID}, - {"v1_enum", tV1ENUM}, -/* ... */ - {"vararg", tVARARG}, - {"version", tVERSION}, {"void", tVOID}, {"wchar_t", tWCHAR}, - {"wire_marshal", tWIREMARSHAL}, }; #define NKEYWORDS (sizeof(keywords)/sizeof(keywords[0])) + +/* keywords only recognized in attribute lists */ +static const struct keyword attr_keywords[] = +{ + {"aggregatable", tAGGREGATABLE}, + {"allocate", tALLOCATE}, + {"appobject", tAPPOBJECT}, + {"async", tASYNC}, + {"async_uuid", tASYNCUUID}, + {"auto_handle", tAUTOHANDLE}, + {"bindable", tBINDABLE}, + {"broadcast", tBROADCAST}, + {"byte_count", tBYTECOUNT}, + {"call_as", tCALLAS}, + {"context_handle", tCONTEXTHANDLE}, + {"context_handle_noserialize", tCONTEXTHANDLENOSERIALIZE}, + {"context_handle_serialize", tCONTEXTHANDLENOSERIALIZE}, + {"control", tCONTROL}, + {"defaultcollelem", tDEFAULTCOLLELEM}, + {"defaultvalue", tDEFAULTVALUE}, + {"defaultvtable", tDEFAULTVTABLE}, + {"displaybind", tDISPLAYBIND}, + {"dllname", tDLLNAME}, + {"dual", tDUAL}, + {"endpoint", tENDPOINT}, + {"entry", tENTRY}, + {"explicit_handle", tEXPLICITHANDLE}, + {"handle", tHANDLE}, + {"helpcontext", tHELPCONTEXT}, + {"helpfile", tHELPFILE}, + {"helpstring", tHELPSTRING}, + {"helpstringcontext", tHELPSTRINGCONTEXT}, + {"helpstringdll", tHELPSTRINGDLL}, + {"hidden", tHIDDEN}, + {"id", tID}, + {"idempotent", tIDEMPOTENT}, + {"iid_is", tIIDIS}, + {"immediatebind", tIMMEDIATEBIND}, + {"implicit_handle", tIMPLICITHANDLE}, + {"in", tIN}, + {"input_sync", tINPUTSYNC}, + {"lcid", tLCID}, + {"length_is", tLENGTHIS}, + {"local", tLOCAL}, + {"nonbrowsable", tNONBROWSABLE}, + {"noncreatable", tNONCREATABLE}, + {"nonextensible", tNONEXTENSIBLE}, + {"object", tOBJECT}, + {"odl", tODL}, + {"oleautomation", tOLEAUTOMATION}, + {"optional", tOPTIONAL}, + {"out", tOUT}, + {"pointer_default", tPOINTERDEFAULT}, + {"propget", tPROPGET}, + {"propput", tPROPPUT}, + {"propputref", tPROPPUTREF}, + {"ptr", tPTR}, + {"public", tPUBLIC}, + {"range", tRANGE}, + {"readonly", tREADONLY}, + {"ref", tREF}, + {"requestedit", tREQUESTEDIT}, + {"restricted", tRESTRICTED}, + {"retval", tRETVAL}, + {"single", tSINGLE}, + {"size_is", tSIZEIS}, + {"source", tSOURCE}, + {"string", tSTRING}, + {"switch_is", tSWITCHIS}, + {"switch_type", tSWITCHTYPE}, + {"transmit_as", tTRANSMITAS}, + {"unique", tUNIQUE}, + {"uuid", tUUID}, + {"v1_enum", tV1ENUM}, + {"vararg", tVARARG}, + {"version", tVERSION}, + {"wire_marshal", tWIREMARSHAL}, +}; + + #define KWP(p) ((const struct keyword *)(p)) static int kw_cmp_func(const void *s1, const void *s2) @@ -320,31 +319,32 @@ static int kw_cmp_func(const void *s1, const void *s2) return strcmp(KWP(s1)->kw, KWP(s2)->kw); } -#define KW_BSEARCH static int kw_token(const char *kw) { struct keyword key, *kwp; key.kw = kw; -#ifdef KW_BSEARCH kwp = bsearch(&key, keywords, NKEYWORDS, sizeof(keywords[0]), kw_cmp_func); -#else - { - int i; - for (kwp=NULL, i=0; i < NKEYWORDS; i++) - if (!kw_cmp_func(&key, &keywords[i])) { - kwp = &keywords[i]; - break; - } - } -#endif if (kwp) { - yylval.str = (char*)kwp->kw; + parser_lval.str = xstrdup(kwp->kw); return kwp->token; } - yylval.str = xstrdup(kw); + parser_lval.str = xstrdup(kw); return is_type(kw) ? aKNOWNTYPE : aIDENTIFIER; } +static int attr_token(const char *kw) +{ + struct keyword key, *kwp; + key.kw = kw; + kwp = bsearch(&key, attr_keywords, sizeof(attr_keywords)/sizeof(attr_keywords[0]), + sizeof(attr_keywords[0]), kw_cmp_func); + if (kwp) { + parser_lval.str = xstrdup(kwp->kw); + return kwp->token; + } + return kw_token(kw); +} + static void addcchar(char c) { if(cbufidx >= cbufalloc) @@ -352,7 +352,7 @@ static void addcchar(char c) cbufalloc += 1024; cbuffer = xrealloc(cbuffer, cbufalloc * sizeof(cbuffer[0])); if(cbufalloc > 65536) - yywarning("Reallocating string buffer larger than 64kB"); + parser_warning("Reallocating string buffer larger than 64kB\n"); } cbuffer[cbufidx++] = c; } @@ -414,7 +414,7 @@ int do_import(char *fname) first_import = import; if (!(path = wpp_find_include( fname, input_name ))) - yyerror("Unable to open include file %s", fname); + error_loc("Unable to open include file %s\n", fname); import_stack[ptr].temp_name = temp_name; import_stack[ptr].input_name = input_name; @@ -427,7 +427,7 @@ int do_import(char *fname) if (ret) exit(1); if((f = fopen(temp_name, "r")) == NULL) - yyerror("Unable to open %s", temp_name); + error_loc("Unable to open %s\n", temp_name); import_stack[ptr].state = YY_CURRENT_BUFFER; yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE)); diff --git a/reactos/tools/widl/parser.tab.c b/reactos/tools/widl/parser.tab.c index b0eeb5a405f..4c5f1c2d1a8 100644 --- a/reactos/tools/widl/parser.tab.c +++ b/reactos/tools/widl/parser.tab.c @@ -1,7 +1,7 @@ -/* A Bison parser, made by GNU Bison 1.875. */ +/* A Bison parser, made by GNU Bison 2.1. */ /* Skeleton parser for Yacc-like parsing with Bison, - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc. + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -15,8 +15,8 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ /* As a special exception, when this file is copied by Bison into a Bison output file, you may use that output file without restriction. @@ -36,6 +36,9 @@ /* Identify Bison output. */ #define YYBISON 1 +/* Bison version. */ +#define YYBISON_VERSION "2.1" + /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -45,6 +48,14 @@ /* Using locations. */ #define YYLSP_NEEDED 0 +/* Substitute the variable and function names. */ +#define yyparse parser_parse +#define yylex parser_lex +#define yyerror parser_error +#define yylval parser_lval +#define yychar parser_char +#define yydebug parser_debug +#define yynerrs parser_nerrs /* Tokens. */ @@ -57,266 +68,271 @@ aKNOWNTYPE = 259, aNUM = 260, aHEXNUM = 261, - aSTRING = 262, - aUUID = 263, - aEOF = 264, - SHL = 265, - SHR = 266, - tAGGREGATABLE = 267, - tALLOCATE = 268, - tAPPOBJECT = 269, - tASYNC = 270, - tASYNCUUID = 271, - tAUTOHANDLE = 272, - tBINDABLE = 273, - tBOOLEAN = 274, - tBROADCAST = 275, - tBYTE = 276, - tBYTECOUNT = 277, - tCALLAS = 278, - tCALLBACK = 279, - tCASE = 280, - tCDECL = 281, - tCHAR = 282, - tCOCLASS = 283, - tCODE = 284, - tCOMMSTATUS = 285, - tCONST = 286, - tCONTEXTHANDLE = 287, - tCONTEXTHANDLENOSERIALIZE = 288, - tCONTEXTHANDLESERIALIZE = 289, - tCONTROL = 290, - tCPPQUOTE = 291, - tDEFAULT = 292, - tDEFAULTCOLLELEM = 293, - tDEFAULTVALUE = 294, - tDEFAULTVTABLE = 295, - tDISPLAYBIND = 296, - tDISPINTERFACE = 297, - tDLLNAME = 298, - tDOUBLE = 299, - tDUAL = 300, - tENDPOINT = 301, - tENTRY = 302, - tENUM = 303, - tERRORSTATUST = 304, - tEXPLICITHANDLE = 305, - tEXTERN = 306, - tFALSE = 307, - tFLOAT = 308, - tHANDLE = 309, - tHANDLET = 310, - tHELPCONTEXT = 311, - tHELPFILE = 312, - tHELPSTRING = 313, - tHELPSTRINGCONTEXT = 314, - tHELPSTRINGDLL = 315, - tHIDDEN = 316, - tHYPER = 317, - tID = 318, - tIDEMPOTENT = 319, - tIIDIS = 320, - tIMMEDIATEBIND = 321, - tIMPLICITHANDLE = 322, - tIMPORT = 323, - tIMPORTLIB = 324, - tIN = 325, - tINLINE = 326, - tINPUTSYNC = 327, - tINT = 328, - tINT64 = 329, - tINTERFACE = 330, - tLCID = 331, - tLENGTHIS = 332, - tLIBRARY = 333, - tLOCAL = 334, - tLONG = 335, - tMETHODS = 336, - tMODULE = 337, - tNONBROWSABLE = 338, - tNONCREATABLE = 339, - tNONEXTENSIBLE = 340, - tOBJECT = 341, - tODL = 342, - tOLEAUTOMATION = 343, - tOPTIONAL = 344, - tOUT = 345, - tPOINTERDEFAULT = 346, - tPROPERTIES = 347, - tPROPGET = 348, - tPROPPUT = 349, - tPROPPUTREF = 350, - tPTR = 351, - tPUBLIC = 352, - tRANGE = 353, - tREADONLY = 354, - tREF = 355, - tREQUESTEDIT = 356, - tRESTRICTED = 357, - tRETVAL = 358, - tSAFEARRAY = 359, - tSHORT = 360, - tSIGNED = 361, - tSINGLE = 362, - tSIZEIS = 363, - tSIZEOF = 364, - tSMALL = 365, - tSOURCE = 366, - tSTDCALL = 367, - tSTRING = 368, - tSTRUCT = 369, - tSWITCH = 370, - tSWITCHIS = 371, - tSWITCHTYPE = 372, - tTRANSMITAS = 373, - tTRUE = 374, - tTYPEDEF = 375, - tUNION = 376, - tUNIQUE = 377, - tUNSIGNED = 378, - tUUID = 379, - tV1ENUM = 380, - tVARARG = 381, - tVERSION = 382, - tVOID = 383, - tWCHAR = 384, - tWIREMARSHAL = 385, - CAST = 386, - PPTR = 387, - NEG = 388 + aDOUBLE = 262, + aSTRING = 263, + aUUID = 264, + aEOF = 265, + SHL = 266, + SHR = 267, + tAGGREGATABLE = 268, + tALLOCATE = 269, + tAPPOBJECT = 270, + tASYNC = 271, + tASYNCUUID = 272, + tAUTOHANDLE = 273, + tBINDABLE = 274, + tBOOLEAN = 275, + tBROADCAST = 276, + tBYTE = 277, + tBYTECOUNT = 278, + tCALLAS = 279, + tCALLBACK = 280, + tCASE = 281, + tCDECL = 282, + tCHAR = 283, + tCOCLASS = 284, + tCODE = 285, + tCOMMSTATUS = 286, + tCONST = 287, + tCONTEXTHANDLE = 288, + tCONTEXTHANDLENOSERIALIZE = 289, + tCONTEXTHANDLESERIALIZE = 290, + tCONTROL = 291, + tCPPQUOTE = 292, + tDEFAULT = 293, + tDEFAULTCOLLELEM = 294, + tDEFAULTVALUE = 295, + tDEFAULTVTABLE = 296, + tDISPLAYBIND = 297, + tDISPINTERFACE = 298, + tDLLNAME = 299, + tDOUBLE = 300, + tDUAL = 301, + tENDPOINT = 302, + tENTRY = 303, + tENUM = 304, + tERRORSTATUST = 305, + tEXPLICITHANDLE = 306, + tEXTERN = 307, + tFALSE = 308, + tFLOAT = 309, + tHANDLE = 310, + tHANDLET = 311, + tHELPCONTEXT = 312, + tHELPFILE = 313, + tHELPSTRING = 314, + tHELPSTRINGCONTEXT = 315, + tHELPSTRINGDLL = 316, + tHIDDEN = 317, + tHYPER = 318, + tID = 319, + tIDEMPOTENT = 320, + tIIDIS = 321, + tIMMEDIATEBIND = 322, + tIMPLICITHANDLE = 323, + tIMPORT = 324, + tIMPORTLIB = 325, + tIN = 326, + tINLINE = 327, + tINPUTSYNC = 328, + tINT = 329, + tINT64 = 330, + tINTERFACE = 331, + tLCID = 332, + tLENGTHIS = 333, + tLIBRARY = 334, + tLOCAL = 335, + tLONG = 336, + tMETHODS = 337, + tMODULE = 338, + tNONBROWSABLE = 339, + tNONCREATABLE = 340, + tNONEXTENSIBLE = 341, + tOBJECT = 342, + tODL = 343, + tOLEAUTOMATION = 344, + tOPTIONAL = 345, + tOUT = 346, + tPOINTERDEFAULT = 347, + tPROPERTIES = 348, + tPROPGET = 349, + tPROPPUT = 350, + tPROPPUTREF = 351, + tPTR = 352, + tPUBLIC = 353, + tRANGE = 354, + tREADONLY = 355, + tREF = 356, + tREQUESTEDIT = 357, + tRESTRICTED = 358, + tRETVAL = 359, + tSAFEARRAY = 360, + tSHORT = 361, + tSIGNED = 362, + tSINGLE = 363, + tSIZEIS = 364, + tSIZEOF = 365, + tSMALL = 366, + tSOURCE = 367, + tSTDCALL = 368, + tSTRING = 369, + tSTRUCT = 370, + tSWITCH = 371, + tSWITCHIS = 372, + tSWITCHTYPE = 373, + tTRANSMITAS = 374, + tTRUE = 375, + tTYPEDEF = 376, + tUNION = 377, + tUNIQUE = 378, + tUNSIGNED = 379, + tUUID = 380, + tV1ENUM = 381, + tVARARG = 382, + tVERSION = 383, + tVOID = 384, + tWCHAR = 385, + tWIREMARSHAL = 386, + CAST = 387, + PPTR = 388, + NEG = 389, + ADDRESSOF = 390 }; #endif +/* Tokens. */ #define aIDENTIFIER 258 #define aKNOWNTYPE 259 #define aNUM 260 #define aHEXNUM 261 -#define aSTRING 262 -#define aUUID 263 -#define aEOF 264 -#define SHL 265 -#define SHR 266 -#define tAGGREGATABLE 267 -#define tALLOCATE 268 -#define tAPPOBJECT 269 -#define tASYNC 270 -#define tASYNCUUID 271 -#define tAUTOHANDLE 272 -#define tBINDABLE 273 -#define tBOOLEAN 274 -#define tBROADCAST 275 -#define tBYTE 276 -#define tBYTECOUNT 277 -#define tCALLAS 278 -#define tCALLBACK 279 -#define tCASE 280 -#define tCDECL 281 -#define tCHAR 282 -#define tCOCLASS 283 -#define tCODE 284 -#define tCOMMSTATUS 285 -#define tCONST 286 -#define tCONTEXTHANDLE 287 -#define tCONTEXTHANDLENOSERIALIZE 288 -#define tCONTEXTHANDLESERIALIZE 289 -#define tCONTROL 290 -#define tCPPQUOTE 291 -#define tDEFAULT 292 -#define tDEFAULTCOLLELEM 293 -#define tDEFAULTVALUE 294 -#define tDEFAULTVTABLE 295 -#define tDISPLAYBIND 296 -#define tDISPINTERFACE 297 -#define tDLLNAME 298 -#define tDOUBLE 299 -#define tDUAL 300 -#define tENDPOINT 301 -#define tENTRY 302 -#define tENUM 303 -#define tERRORSTATUST 304 -#define tEXPLICITHANDLE 305 -#define tEXTERN 306 -#define tFALSE 307 -#define tFLOAT 308 -#define tHANDLE 309 -#define tHANDLET 310 -#define tHELPCONTEXT 311 -#define tHELPFILE 312 -#define tHELPSTRING 313 -#define tHELPSTRINGCONTEXT 314 -#define tHELPSTRINGDLL 315 -#define tHIDDEN 316 -#define tHYPER 317 -#define tID 318 -#define tIDEMPOTENT 319 -#define tIIDIS 320 -#define tIMMEDIATEBIND 321 -#define tIMPLICITHANDLE 322 -#define tIMPORT 323 -#define tIMPORTLIB 324 -#define tIN 325 -#define tINLINE 326 -#define tINPUTSYNC 327 -#define tINT 328 -#define tINT64 329 -#define tINTERFACE 330 -#define tLCID 331 -#define tLENGTHIS 332 -#define tLIBRARY 333 -#define tLOCAL 334 -#define tLONG 335 -#define tMETHODS 336 -#define tMODULE 337 -#define tNONBROWSABLE 338 -#define tNONCREATABLE 339 -#define tNONEXTENSIBLE 340 -#define tOBJECT 341 -#define tODL 342 -#define tOLEAUTOMATION 343 -#define tOPTIONAL 344 -#define tOUT 345 -#define tPOINTERDEFAULT 346 -#define tPROPERTIES 347 -#define tPROPGET 348 -#define tPROPPUT 349 -#define tPROPPUTREF 350 -#define tPTR 351 -#define tPUBLIC 352 -#define tRANGE 353 -#define tREADONLY 354 -#define tREF 355 -#define tREQUESTEDIT 356 -#define tRESTRICTED 357 -#define tRETVAL 358 -#define tSAFEARRAY 359 -#define tSHORT 360 -#define tSIGNED 361 -#define tSINGLE 362 -#define tSIZEIS 363 -#define tSIZEOF 364 -#define tSMALL 365 -#define tSOURCE 366 -#define tSTDCALL 367 -#define tSTRING 368 -#define tSTRUCT 369 -#define tSWITCH 370 -#define tSWITCHIS 371 -#define tSWITCHTYPE 372 -#define tTRANSMITAS 373 -#define tTRUE 374 -#define tTYPEDEF 375 -#define tUNION 376 -#define tUNIQUE 377 -#define tUNSIGNED 378 -#define tUUID 379 -#define tV1ENUM 380 -#define tVARARG 381 -#define tVERSION 382 -#define tVOID 383 -#define tWCHAR 384 -#define tWIREMARSHAL 385 -#define CAST 386 -#define PPTR 387 -#define NEG 388 +#define aDOUBLE 262 +#define aSTRING 263 +#define aUUID 264 +#define aEOF 265 +#define SHL 266 +#define SHR 267 +#define tAGGREGATABLE 268 +#define tALLOCATE 269 +#define tAPPOBJECT 270 +#define tASYNC 271 +#define tASYNCUUID 272 +#define tAUTOHANDLE 273 +#define tBINDABLE 274 +#define tBOOLEAN 275 +#define tBROADCAST 276 +#define tBYTE 277 +#define tBYTECOUNT 278 +#define tCALLAS 279 +#define tCALLBACK 280 +#define tCASE 281 +#define tCDECL 282 +#define tCHAR 283 +#define tCOCLASS 284 +#define tCODE 285 +#define tCOMMSTATUS 286 +#define tCONST 287 +#define tCONTEXTHANDLE 288 +#define tCONTEXTHANDLENOSERIALIZE 289 +#define tCONTEXTHANDLESERIALIZE 290 +#define tCONTROL 291 +#define tCPPQUOTE 292 +#define tDEFAULT 293 +#define tDEFAULTCOLLELEM 294 +#define tDEFAULTVALUE 295 +#define tDEFAULTVTABLE 296 +#define tDISPLAYBIND 297 +#define tDISPINTERFACE 298 +#define tDLLNAME 299 +#define tDOUBLE 300 +#define tDUAL 301 +#define tENDPOINT 302 +#define tENTRY 303 +#define tENUM 304 +#define tERRORSTATUST 305 +#define tEXPLICITHANDLE 306 +#define tEXTERN 307 +#define tFALSE 308 +#define tFLOAT 309 +#define tHANDLE 310 +#define tHANDLET 311 +#define tHELPCONTEXT 312 +#define tHELPFILE 313 +#define tHELPSTRING 314 +#define tHELPSTRINGCONTEXT 315 +#define tHELPSTRINGDLL 316 +#define tHIDDEN 317 +#define tHYPER 318 +#define tID 319 +#define tIDEMPOTENT 320 +#define tIIDIS 321 +#define tIMMEDIATEBIND 322 +#define tIMPLICITHANDLE 323 +#define tIMPORT 324 +#define tIMPORTLIB 325 +#define tIN 326 +#define tINLINE 327 +#define tINPUTSYNC 328 +#define tINT 329 +#define tINT64 330 +#define tINTERFACE 331 +#define tLCID 332 +#define tLENGTHIS 333 +#define tLIBRARY 334 +#define tLOCAL 335 +#define tLONG 336 +#define tMETHODS 337 +#define tMODULE 338 +#define tNONBROWSABLE 339 +#define tNONCREATABLE 340 +#define tNONEXTENSIBLE 341 +#define tOBJECT 342 +#define tODL 343 +#define tOLEAUTOMATION 344 +#define tOPTIONAL 345 +#define tOUT 346 +#define tPOINTERDEFAULT 347 +#define tPROPERTIES 348 +#define tPROPGET 349 +#define tPROPPUT 350 +#define tPROPPUTREF 351 +#define tPTR 352 +#define tPUBLIC 353 +#define tRANGE 354 +#define tREADONLY 355 +#define tREF 356 +#define tREQUESTEDIT 357 +#define tRESTRICTED 358 +#define tRETVAL 359 +#define tSAFEARRAY 360 +#define tSHORT 361 +#define tSIGNED 362 +#define tSINGLE 363 +#define tSIZEIS 364 +#define tSIZEOF 365 +#define tSMALL 366 +#define tSOURCE 367 +#define tSTDCALL 368 +#define tSTRING 369 +#define tSTRUCT 370 +#define tSWITCH 371 +#define tSWITCHIS 372 +#define tSWITCHTYPE 373 +#define tTRANSMITAS 374 +#define tTRUE 375 +#define tTYPEDEF 376 +#define tUNION 377 +#define tUNIQUE 378 +#define tUNSIGNED 379 +#define tUUID 380 +#define tV1ENUM 381 +#define tVARARG 382 +#define tVERSION 383 +#define tVOID 384 +#define tWCHAR 385 +#define tWIREMARSHAL 386 +#define CAST 387 +#define PPTR 388 +#define NEG 389 +#define ADDRESSOF 390 @@ -361,6 +377,7 @@ #include "parser.h" #include "header.h" #include "typelib.h" +#include "typegen.h" #if defined(YYBYACC) /* Berkeley yacc (byacc) doesn't seem to know about these */ @@ -387,52 +404,80 @@ # endif #endif +unsigned char pointer_default = RPC_FC_UP; + +typedef struct list typelist_t; +struct typenode { + type_t *type; + struct list entry; +}; + +typelist_t incomplete_types = LIST_INIT(incomplete_types); + +static void add_incomplete(type_t *t); +static void fix_incomplete(void); + +static str_list_t *append_str(str_list_t *list, char *str); +static attr_list_t *append_attr(attr_list_t *list, attr_t *attr); static attr_t *make_attr(enum attr_type type); static attr_t *make_attrv(enum attr_type type, unsigned long val); static attr_t *make_attrp(enum attr_type type, void *val); static expr_t *make_expr(enum expr_type type); static expr_t *make_exprl(enum expr_type type, long val); +static expr_t *make_exprd(enum expr_type type, double val); static expr_t *make_exprs(enum expr_type type, char *val); -static expr_t *make_exprt(enum expr_type type, typeref_t *tref, expr_t *expr); +static expr_t *make_exprt(enum expr_type type, type_t *tref, expr_t *expr); static expr_t *make_expr1(enum expr_type type, expr_t *expr); static expr_t *make_expr2(enum expr_type type, expr_t *exp1, expr_t *exp2); static expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, expr_t *expr3); static type_t *make_type(unsigned char type, type_t *ref); -static typeref_t *make_tref(char *name, type_t *ref); -static typeref_t *uniq_tref(typeref_t *ref); -static type_t *type_ref(typeref_t *ref); -static void set_type(var_t *v, typeref_t *ref, expr_t *arr); +static expr_list_t *append_expr(expr_list_t *list, expr_t *expr); +static array_dims_t *append_array(array_dims_t *list, expr_t *expr); +static void set_type(var_t *v, type_t *type, int ptr_level, array_dims_t *arr, int top); +static ifref_list_t *append_ifref(ifref_list_t *list, ifref_t *iface); static ifref_t *make_ifref(type_t *iface); +static var_list_t *append_var(var_list_t *list, var_t *var); static var_t *make_var(char *name); -static func_t *make_func(var_t *def, var_t *args); +static pident_list_t *append_pident(pident_list_t *list, pident_t *p); +static pident_t *make_pident(var_t *var); +static func_list_t *append_func(func_list_t *list, func_t *func); +static func_t *make_func(var_t *def, var_list_t *args); static type_t *make_class(char *name); -static type_t *make_safearray(void); +static type_t *make_safearray(type_t *type); +static type_t *make_builtin(char *name); +static type_t *make_int(int sign); static type_t *reg_type(type_t *type, const char *name, int t); -static type_t *reg_types(type_t *type, var_t *names, int t); +static type_t *reg_typedefs(type_t *type, var_list_t *names, attr_list_t *attrs); static type_t *find_type(const char *name, int t); static type_t *find_type2(char *name, int t); static type_t *get_type(unsigned char type, char *name, int t); static type_t *get_typev(unsigned char type, var_t *name, int t); -static int get_struct_type(var_t *fields); +static int get_struct_type(var_list_t *fields); static var_t *reg_const(var_t *var); static var_t *find_const(char *name, int f); +static void write_libid(const char *name, const attr_list_t *attr); +static void write_clsid(type_t *cls); +static void write_diid(type_t *iface); +static void write_iid(type_t *iface); + +static int compute_method_indexes(type_t *iface); +static char *gen_name(void); +static void process_typedefs(var_list_t *names); +static void check_arg(var_t *arg); +static void check_all_user_types(ifref_list_t *ifaces); + #define tsENUM 1 #define tsSTRUCT 2 #define tsUNION 3 -static type_t std_bool = { "boolean" }; -static type_t std_int = { "int" }; -static type_t std_int64 = { "__int64" }; -static type_t std_uhyper = { "MIDL_uhyper" }; - /* Enabling traces. */ #ifndef YYDEBUG -# define YYDEBUG 1 +# define YYDEBUG 0 #endif /* Enabling verbose error messages. */ @@ -443,22 +488,37 @@ static type_t std_uhyper = { "MIDL_uhyper" }; # define YYERROR_VERBOSE 0 #endif +/* Enabling the token table. */ +#ifndef YYTOKEN_TABLE +# define YYTOKEN_TABLE 0 +#endif + #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) -#line 109 "parser.y" +#line 136 "parser.y" typedef union YYSTYPE { attr_t *attr; + attr_list_t *attr_list; + str_list_t *str_list; expr_t *expr; + expr_list_t *expr_list; + array_dims_t *array_dims; type_t *type; - typeref_t *tref; var_t *var; + var_list_t *var_list; + pident_t *pident; + pident_list_t *pident_list; func_t *func; + func_list_t *func_list; ifref_t *ifref; + ifref_list_t *ifref_list; char *str; UUID *uuid; unsigned int num; + double dbl; + interface_info_t ifinfo; } YYSTYPE; -/* Line 191 of yacc.c. */ -#line 463 "parser.tab.c" +/* Line 196 of yacc.c. */ +#line 522 "parser.tab.c" # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 @@ -469,22 +529,48 @@ typedef union YYSTYPE { /* Copy the second part of user declarations. */ -/* Line 214 of yacc.c. */ -#line 475 "parser.tab.c" +/* Line 219 of yacc.c. */ +#line 534 "parser.tab.c" + +#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) +# define YYSIZE_T __SIZE_TYPE__ +#endif +#if ! defined (YYSIZE_T) && defined (size_t) +# define YYSIZE_T size_t +#endif +#if ! defined (YYSIZE_T) && (defined (__STDC__) || defined (__cplusplus)) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +#endif +#if ! defined (YYSIZE_T) +# define YYSIZE_T unsigned int +#endif + +#ifndef YY_ +# if YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(msgid) dgettext ("bison-runtime", msgid) +# endif +# endif +# ifndef YY_ +# define YY_(msgid) msgid +# endif +#endif #if ! defined (yyoverflow) || YYERROR_VERBOSE /* The parser invokes alloca or malloc; define the necessary symbols. */ -# if YYSTACK_USE_ALLOCA -# define YYSTACK_ALLOC alloca -# else -# ifndef YYSTACK_USE_ALLOCA -# if defined (alloca) || defined (_ALLOCA_H) -# define YYSTACK_ALLOC alloca +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca # else -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca +# define YYSTACK_ALLOC alloca +# if defined (__STDC__) || defined (__cplusplus) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYINCLUDED_STDLIB_H # endif # endif # endif @@ -493,25 +579,51 @@ typedef union YYSTYPE { # ifdef YYSTACK_ALLOC /* Pacify GCC's `empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) -# else -# if defined (__STDC__) || defined (__cplusplus) -# include /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2005 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM ((YYSIZE_T) -1) +# endif +# ifdef __cplusplus +extern "C" { +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if (! defined (malloc) && ! defined (YYINCLUDED_STDLIB_H) \ + && (defined (__STDC__) || defined (__cplusplus))) +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if (! defined (free) && ! defined (YYINCLUDED_STDLIB_H) \ + && (defined (__STDC__) || defined (__cplusplus))) +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifdef __cplusplus +} # endif -# define YYSTACK_ALLOC malloc -# define YYSTACK_FREE free # endif #endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ #if (! defined (yyoverflow) \ && (! defined (__cplusplus) \ - || (YYSTYPE_IS_TRIVIAL))) + || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { - short yyss; + short int yyss; YYSTYPE yyvs; }; @@ -521,20 +633,20 @@ union yyalloc /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ - ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ + ((N) * (sizeof (short int) + sizeof (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) /* Copy COUNT objects from FROM to TO. The source and destination do not overlap. */ # ifndef YYCOPY -# if 1 < __GNUC__ +# if defined (__GNUC__) && 1 < __GNUC__ # define YYCOPY(To, From, Count) \ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) # else # define YYCOPY(To, From, Count) \ do \ { \ - register YYSIZE_T yyi; \ + YYSIZE_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (To)[yyi] = (From)[yyi]; \ } \ @@ -563,28 +675,28 @@ union yyalloc #if defined (__STDC__) || defined (__cplusplus) typedef signed char yysigned_char; #else - typedef short yysigned_char; + typedef short int yysigned_char; #endif /* YYFINAL -- State number of the termination state. */ #define YYFINAL 3 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 1059 +#define YYLAST 1065 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 153 +#define YYNTOKENS 155 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 74 +#define YYNNTS 76 /* YYNRULES -- Number of rules. */ -#define YYNRULES 272 +#define YYNRULES 271 /* YYNRULES -- Number of states. */ -#define YYNSTATES 496 +#define YYNSTATES 499 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 388 +#define YYMAXUTOK 390 -#define YYTRANSLATE(YYX) \ +#define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ @@ -593,16 +705,16 @@ static const unsigned char yytranslate[] = 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 135, 2, - 145, 146, 138, 137, 131, 136, 152, 139, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 133, 144, - 2, 151, 2, 132, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 136, 2, + 147, 148, 139, 138, 132, 137, 154, 140, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 134, 146, + 2, 153, 2, 133, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 149, 2, 150, 2, 2, 2, 2, 2, 2, + 2, 151, 2, 152, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 147, 134, 148, 140, 2, 2, 2, + 2, 2, 2, 149, 135, 150, 141, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -628,13 +740,14 @@ static const unsigned char yytranslate[] = 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, - 125, 126, 127, 128, 129, 130, 141, 142, 143 + 125, 126, 127, 128, 129, 130, 131, 142, 143, 144, + 145 }; #if YYDEBUG /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in YYRHS. */ -static const unsigned short yyprhs[] = +static const unsigned short int yyprhs[] = { 0, 0, 3, 5, 6, 9, 12, 16, 19, 22, 25, 28, 29, 32, 35, 39, 42, 45, 48, 51, @@ -642,206 +755,207 @@ static const unsigned short yyprhs[] = 80, 83, 88, 92, 96, 101, 104, 108, 112, 113, 115, 117, 119, 123, 125, 130, 134, 141, 147, 148, 152, 156, 158, 162, 167, 168, 170, 174, 176, 180, - 185, 186, 188, 190, 192, 194, 196, 201, 206, 208, - 210, 212, 214, 216, 218, 223, 228, 230, 232, 237, - 239, 244, 249, 254, 256, 258, 263, 268, 273, 278, - 283, 285, 290, 292, 297, 299, 305, 307, 309, 314, - 316, 318, 320, 322, 324, 326, 328, 330, 332, 337, - 339, 341, 343, 345, 352, 354, 356, 358, 360, 365, - 367, 369, 374, 379, 384, 389, 391, 393, 398, 403, - 405, 406, 408, 409, 412, 417, 421, 427, 428, 431, - 433, 435, 439, 443, 445, 451, 453, 457, 458, 460, - 462, 464, 466, 468, 470, 476, 480, 484, 488, 492, - 496, 500, 504, 508, 511, 514, 517, 522, 527, 531, - 533, 537, 539, 544, 545, 548, 551, 555, 558, 560, - 565, 573, 574, 576, 577, 579, 581, 583, 585, 587, - 589, 591, 593, 595, 597, 599, 601, 603, 605, 607, - 610, 613, 615, 617, 619, 621, 623, 625, 627, 628, - 630, 632, 635, 637, 640, 643, 645, 647, 650, 653, - 656, 661, 662, 665, 668, 671, 674, 677, 680, 684, - 687, 691, 697, 698, 701, 704, 707, 710, 716, 724, - 726, 729, 732, 735, 738, 741, 746, 749, 752, 754, - 756, 760, 762, 766, 768, 770, 772, 778, 780, 782, - 784, 787, 789, 792, 794, 797, 799, 802, 807, 812, - 818, 829, 831 + 185, 187, 191, 192, 194, 196, 198, 200, 202, 207, + 212, 214, 216, 218, 220, 222, 224, 229, 234, 236, + 238, 243, 245, 250, 255, 260, 262, 264, 269, 274, + 279, 284, 289, 291, 296, 298, 303, 305, 311, 313, + 315, 320, 322, 324, 326, 328, 330, 332, 334, 336, + 338, 343, 345, 347, 349, 351, 358, 360, 362, 364, + 366, 371, 373, 375, 380, 385, 390, 395, 397, 399, + 404, 409, 411, 413, 415, 416, 418, 419, 422, 427, + 431, 437, 438, 441, 443, 445, 449, 453, 455, 461, + 463, 467, 468, 470, 472, 474, 476, 478, 480, 482, + 488, 492, 496, 500, 504, 508, 512, 516, 520, 523, + 526, 529, 532, 537, 542, 546, 548, 552, 554, 559, + 560, 563, 566, 570, 573, 575, 580, 588, 589, 591, + 592, 594, 596, 598, 600, 602, 604, 606, 609, 612, + 614, 616, 618, 620, 622, 624, 626, 627, 629, 631, + 634, 636, 639, 642, 644, 646, 649, 652, 655, 660, + 661, 664, 667, 670, 673, 676, 679, 683, 686, 690, + 696, 702, 703, 706, 709, 712, 715, 721, 729, 731, + 734, 737, 740, 743, 746, 751, 754, 757, 759, 761, + 765, 767, 771, 773, 775, 777, 783, 785, 787, 789, + 792, 794, 797, 799, 802, 804, 807, 812, 817, 823, + 834, 836 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ -static const short yyrhs[] = +static const short int yyrhs[] = { - 154, 0, -1, 155, -1, -1, 155, 214, -1, 155, - 213, -1, 155, 200, 144, -1, 155, 202, -1, 155, - 217, -1, 155, 165, -1, 155, 158, -1, -1, 156, - 214, -1, 156, 213, -1, 156, 200, 144, -1, 156, - 202, -1, 156, 217, -1, 156, 158, -1, 156, 162, - -1, -1, 157, 193, 144, -1, 157, 158, -1, 144, - -1, 179, 144, -1, 159, -1, 183, 144, -1, 189, - 144, -1, 161, -1, 222, 144, -1, 224, 144, -1, - 225, 144, -1, 36, 145, 7, 146, -1, 68, 7, - 144, -1, 160, 156, 9, -1, 69, 145, 7, 146, - -1, 78, 3, -1, 173, 163, 147, -1, 164, 156, - 148, -1, -1, 168, -1, 128, -1, 169, -1, 168, - 131, 169, -1, 167, -1, 173, 223, 219, 170, -1, - 223, 219, 170, -1, 173, 223, 219, 145, 166, 146, - -1, 223, 219, 145, 166, 146, -1, -1, 149, 171, - 150, -1, 149, 138, 150, -1, 185, -1, 171, 131, - 186, -1, 171, 150, 149, 186, -1, -1, 173, -1, - 149, 174, 150, -1, 175, -1, 174, 131, 175, -1, - 174, 150, 149, 175, -1, -1, 12, -1, 14, -1, - 15, -1, 17, -1, 18, -1, 23, 145, 196, 146, - -1, 25, 145, 187, 146, -1, 32, -1, 33, -1, - 34, -1, 35, -1, 37, -1, 38, -1, 39, 145, - 188, 146, -1, 39, 145, 7, 146, -1, 40, -1, - 41, -1, 43, 145, 7, 146, -1, 45, -1, 46, - 145, 7, 146, -1, 47, 145, 7, 146, -1, 47, - 145, 188, 146, -1, 50, -1, 54, -1, 56, 145, - 188, 146, -1, 57, 145, 7, 146, -1, 58, 145, - 7, 146, -1, 59, 145, 188, 146, -1, 60, 145, - 7, 146, -1, 61, -1, 63, 145, 188, 146, -1, - 64, -1, 65, 145, 196, 146, -1, 66, -1, 67, - 145, 55, 3, 146, -1, 70, -1, 72, -1, 77, - 145, 184, 146, -1, 79, -1, 83, -1, 84, -1, - 85, -1, 86, -1, 87, -1, 88, -1, 89, -1, - 90, -1, 91, 145, 221, 146, -1, 93, -1, 94, - -1, 95, -1, 97, -1, 98, 145, 188, 131, 188, - 146, -1, 99, -1, 101, -1, 102, -1, 103, -1, - 108, 145, 184, 146, -1, 111, -1, 113, -1, 116, - 145, 186, 146, -1, 117, 145, 223, 146, -1, 118, - 145, 223, 146, -1, 124, 145, 8, 146, -1, 125, - -1, 126, -1, 127, 145, 226, 146, -1, 130, 145, - 223, 146, -1, 221, -1, -1, 112, -1, -1, 177, - 178, -1, 25, 186, 133, 191, -1, 37, 133, 191, - -1, 31, 223, 196, 151, 188, -1, -1, 181, 131, - -1, 181, -1, 182, -1, 181, 131, 182, -1, 196, - 151, 188, -1, 196, -1, 48, 195, 147, 180, 148, - -1, 185, -1, 184, 131, 185, -1, -1, 186, -1, - 5, -1, 6, -1, 52, -1, 119, -1, 3, -1, - 186, 132, 186, 133, 186, -1, 186, 134, 186, -1, - 186, 135, 186, -1, 186, 137, 186, -1, 186, 136, - 186, -1, 186, 138, 186, -1, 186, 139, 186, -1, - 186, 10, 186, -1, 186, 11, 186, -1, 140, 186, - -1, 136, 186, -1, 138, 186, -1, 145, 223, 146, - 186, -1, 109, 145, 223, 146, -1, 145, 186, 146, - -1, 188, -1, 187, 131, 188, -1, 186, -1, 51, - 31, 223, 196, -1, -1, 190, 191, -1, 192, 144, - -1, 172, 225, 144, -1, 173, 144, -1, 144, -1, - 172, 223, 219, 170, -1, 172, 223, 176, 219, 145, - 166, 146, -1, -1, 196, -1, -1, 3, -1, 4, - -1, 3, -1, 4, -1, 15, -1, 63, -1, 76, - -1, 86, -1, 98, -1, 103, -1, 124, -1, 127, - -1, 21, -1, 129, -1, 199, -1, 106, 199, -1, - 123, 199, -1, 123, -1, 53, -1, 107, -1, 44, - -1, 19, -1, 49, -1, 55, -1, -1, 73, -1, - 73, -1, 105, 198, -1, 110, -1, 80, 198, -1, - 62, 198, -1, 74, -1, 27, -1, 28, 3, -1, - 28, 4, -1, 173, 200, -1, 201, 147, 203, 148, - -1, -1, 203, 204, -1, 172, 214, -1, 42, 3, - -1, 42, 4, -1, 173, 205, -1, 92, 133, -1, - 207, 192, 144, -1, 81, 133, -1, 208, 193, 144, - -1, 206, 147, 207, 208, 148, -1, -1, 133, 4, - -1, 75, 3, -1, 75, 4, -1, 173, 211, -1, - 212, 210, 147, 157, 148, -1, 212, 133, 3, 147, - 161, 157, 148, -1, 209, -1, 211, 144, -1, 205, - 144, -1, 82, 3, -1, 82, 4, -1, 173, 215, - -1, 216, 147, 157, 148, -1, 138, 219, -1, 31, - 218, -1, 196, -1, 218, -1, 145, 219, 146, -1, - 219, -1, 220, 131, 219, -1, 100, -1, 122, -1, - 96, -1, 114, 195, 147, 190, 148, -1, 128, -1, - 4, -1, 197, -1, 31, 223, -1, 183, -1, 48, - 3, -1, 222, -1, 114, 3, -1, 225, -1, 121, - 3, -1, 104, 145, 223, 146, -1, 120, 172, 223, - 220, -1, 121, 195, 147, 190, 148, -1, 121, 195, - 115, 145, 192, 146, 194, 147, 177, 148, -1, 5, - -1, 5, 152, 5, -1 + 156, 0, -1, 157, -1, -1, 157, 218, -1, 157, + 217, -1, 157, 204, 146, -1, 157, 206, -1, 157, + 221, -1, 157, 167, -1, 157, 160, -1, -1, 158, + 218, -1, 158, 217, -1, 158, 204, 146, -1, 158, + 206, -1, 158, 221, -1, 158, 160, -1, 158, 164, + -1, -1, 159, 197, 146, -1, 159, 160, -1, 146, + -1, 183, 146, -1, 161, -1, 187, 146, -1, 193, + 146, -1, 163, -1, 226, 146, -1, 228, 146, -1, + 229, 146, -1, 37, 147, 8, 148, -1, 69, 8, + 146, -1, 162, 158, 10, -1, 70, 147, 8, 148, + -1, 79, 3, -1, 175, 165, 149, -1, 166, 158, + 150, -1, -1, 170, -1, 129, -1, 171, -1, 170, + 132, 171, -1, 169, -1, 175, 227, 223, 172, -1, + 227, 223, 172, -1, 175, 227, 223, 147, 168, 148, + -1, 227, 223, 147, 168, 148, -1, -1, 151, 173, + 152, -1, 151, 139, 152, -1, 189, -1, 173, 132, + 190, -1, 173, 152, 151, 190, -1, -1, 175, -1, + 151, 176, 152, -1, 178, -1, 176, 132, 178, -1, + 176, 152, 151, 178, -1, 8, -1, 177, 132, 8, + -1, -1, 13, -1, 15, -1, 16, -1, 18, -1, + 19, -1, 24, 147, 200, 148, -1, 26, 147, 191, + 148, -1, 33, -1, 34, -1, 35, -1, 36, -1, + 38, -1, 39, -1, 40, 147, 192, 148, -1, 40, + 147, 8, 148, -1, 41, -1, 42, -1, 44, 147, + 8, 148, -1, 46, -1, 47, 147, 177, 148, -1, + 48, 147, 8, 148, -1, 48, 147, 192, 148, -1, + 51, -1, 55, -1, 57, 147, 192, 148, -1, 58, + 147, 8, 148, -1, 59, 147, 8, 148, -1, 60, + 147, 192, 148, -1, 61, 147, 8, 148, -1, 62, + -1, 64, 147, 192, 148, -1, 65, -1, 66, 147, + 190, 148, -1, 67, -1, 68, 147, 56, 3, 148, + -1, 71, -1, 73, -1, 78, 147, 188, 148, -1, + 80, -1, 84, -1, 85, -1, 86, -1, 87, -1, + 88, -1, 89, -1, 90, -1, 91, -1, 92, 147, + 225, 148, -1, 94, -1, 95, -1, 96, -1, 98, + -1, 99, 147, 192, 132, 192, 148, -1, 100, -1, + 102, -1, 103, -1, 104, -1, 109, 147, 188, 148, + -1, 112, -1, 114, -1, 117, 147, 190, 148, -1, + 118, 147, 227, 148, -1, 119, 147, 227, 148, -1, + 125, 147, 179, 148, -1, 126, -1, 127, -1, 128, + 147, 230, 148, -1, 131, 147, 227, 148, -1, 225, + -1, 9, -1, 8, -1, -1, 113, -1, -1, 181, + 182, -1, 26, 190, 134, 195, -1, 38, 134, 195, + -1, 32, 227, 200, 153, 192, -1, -1, 185, 132, + -1, 185, -1, 186, -1, 185, 132, 186, -1, 200, + 153, 192, -1, 200, -1, 49, 199, 149, 184, 150, + -1, 189, -1, 188, 132, 189, -1, -1, 190, -1, + 5, -1, 6, -1, 7, -1, 53, -1, 120, -1, + 3, -1, 190, 133, 190, 134, 190, -1, 190, 135, + 190, -1, 190, 136, 190, -1, 190, 138, 190, -1, + 190, 137, 190, -1, 190, 139, 190, -1, 190, 140, + 190, -1, 190, 11, 190, -1, 190, 12, 190, -1, + 141, 190, -1, 137, 190, -1, 136, 190, -1, 139, + 190, -1, 147, 227, 148, 190, -1, 110, 147, 227, + 148, -1, 147, 190, 148, -1, 192, -1, 191, 132, + 192, -1, 190, -1, 52, 32, 227, 200, -1, -1, + 194, 195, -1, 196, 146, -1, 174, 229, 146, -1, + 175, 146, -1, 146, -1, 174, 227, 223, 172, -1, + 174, 227, 180, 223, 147, 168, 148, -1, -1, 200, + -1, -1, 3, -1, 4, -1, 3, -1, 4, -1, + 22, -1, 130, -1, 203, -1, 107, 203, -1, 124, + 203, -1, 124, -1, 54, -1, 108, -1, 45, -1, + 20, -1, 50, -1, 56, -1, -1, 74, -1, 74, + -1, 106, 202, -1, 111, -1, 81, 202, -1, 63, + 202, -1, 75, -1, 28, -1, 29, 3, -1, 29, + 4, -1, 175, 204, -1, 205, 149, 207, 150, -1, + -1, 207, 208, -1, 174, 218, -1, 43, 3, -1, + 43, 4, -1, 175, 209, -1, 93, 134, -1, 211, + 196, 146, -1, 82, 134, -1, 212, 197, 146, -1, + 210, 149, 211, 212, 150, -1, 210, 149, 215, 146, + 150, -1, -1, 134, 4, -1, 76, 3, -1, 76, + 4, -1, 175, 215, -1, 216, 214, 149, 159, 150, + -1, 216, 134, 3, 149, 163, 159, 150, -1, 213, + -1, 215, 146, -1, 209, 146, -1, 83, 3, -1, + 83, 4, -1, 175, 219, -1, 220, 149, 159, 150, + -1, 139, 223, -1, 32, 222, -1, 200, -1, 222, + -1, 147, 223, 148, -1, 223, -1, 224, 132, 223, + -1, 101, -1, 123, -1, 97, -1, 115, 199, 149, + 194, 150, -1, 129, -1, 4, -1, 201, -1, 32, + 227, -1, 187, -1, 49, 3, -1, 226, -1, 115, + 3, -1, 229, -1, 122, 3, -1, 105, 147, 227, + 148, -1, 121, 174, 227, 224, -1, 122, 199, 149, + 194, 150, -1, 122, 199, 116, 147, 196, 148, 198, + 149, 181, 150, -1, 5, -1, 5, 154, 5, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -static const unsigned short yyrline[] = +static const unsigned short int yyrline[] = { - 0, 239, 239, 242, 243, 244, 245, 249, 253, 254, - 255, 258, 259, 260, 261, 262, 265, 266, 267, 270, - 271, 272, 275, 276, 277, 278, 279, 280, 281, 282, - 283, 286, 288, 291, 294, 297, 299, 302, 305, 306, - 309, 312, 313, 314, 318, 322, 325, 331, 338, 339, - 340, 343, 344, 345, 348, 349, 353, 359, 360, 363, - 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, - 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, - 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, - 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, - 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, - 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, - 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, - 440, 441, 444, 445, 450, 454, 460, 466, 467, 468, - 471, 474, 480, 484, 489, 497, 498, 511, 512, 515, - 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, - 526, 527, 528, 529, 530, 531, 532, 533, 534, 537, - 538, 541, 547, 552, 553, 558, 559, 560, 561, 564, - 568, 578, 579, 582, 583, 584, 587, 589, 590, 591, - 592, 593, 594, 595, 596, 597, 600, 601, 602, 603, - 604, 616, 617, 618, 619, 620, 621, 622, 625, 626, - 629, 630, 631, 632, 633, 634, 635, 638, 639, 645, - 652, 657, 658, 662, 665, 666, 669, 682, 683, 686, - 687, 690, 705, 706, 709, 710, 713, 721, 729, 736, - 740, 741, 744, 745, 748, 753, 759, 760, 763, 764, - 765, 769, 770, 774, 775, 776, 779, 789, 790, 791, - 792, 793, 794, 795, 796, 797, 798, 799, 802, 815, - 819, 833, 834 + 0, 285, 285, 294, 295, 296, 297, 301, 306, 307, + 308, 311, 312, 313, 314, 315, 319, 320, 321, 324, + 325, 326, 329, 330, 331, 332, 337, 338, 339, 344, + 345, 352, 354, 357, 360, 363, 365, 370, 373, 374, + 377, 380, 381, 382, 386, 391, 395, 401, 408, 409, + 410, 413, 414, 415, 418, 419, 423, 429, 430, 431, + 434, 435, 438, 439, 440, 441, 442, 443, 444, 445, + 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, + 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, + 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, + 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, + 486, 487, 488, 489, 490, 491, 494, 495, 496, 497, + 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, + 508, 509, 513, 514, 519, 520, 523, 524, 527, 531, + 537, 543, 544, 545, 548, 552, 561, 565, 570, 579, + 580, 593, 594, 597, 598, 599, 600, 601, 602, 603, + 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, + 614, 615, 616, 617, 618, 621, 622, 625, 631, 636, + 637, 640, 641, 642, 643, 646, 654, 666, 667, 670, + 671, 672, 675, 677, 680, 681, 682, 683, 684, 700, + 701, 702, 703, 704, 705, 706, 709, 710, 713, 714, + 715, 716, 717, 718, 719, 722, 723, 729, 738, 744, + 745, 749, 752, 753, 756, 768, 769, 772, 773, 776, + 785, 794, 795, 798, 799, 802, 813, 825, 836, 840, + 841, 844, 845, 848, 853, 859, 860, 863, 864, 865, + 869, 870, 874, 875, 876, 879, 890, 891, 892, 893, + 894, 895, 896, 897, 898, 899, 900, 903, 908, 913, + 930, 931 }; #endif -#if YYDEBUG || YYERROR_VERBOSE -/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. +#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { "$end", "error", "$undefined", "aIDENTIFIER", "aKNOWNTYPE", "aNUM", - "aHEXNUM", "aSTRING", "aUUID", "aEOF", "SHL", "SHR", "tAGGREGATABLE", - "tALLOCATE", "tAPPOBJECT", "tASYNC", "tASYNCUUID", "tAUTOHANDLE", - "tBINDABLE", "tBOOLEAN", "tBROADCAST", "tBYTE", "tBYTECOUNT", "tCALLAS", - "tCALLBACK", "tCASE", "tCDECL", "tCHAR", "tCOCLASS", "tCODE", - "tCOMMSTATUS", "tCONST", "tCONTEXTHANDLE", "tCONTEXTHANDLENOSERIALIZE", - "tCONTEXTHANDLESERIALIZE", "tCONTROL", "tCPPQUOTE", "tDEFAULT", - "tDEFAULTCOLLELEM", "tDEFAULTVALUE", "tDEFAULTVTABLE", "tDISPLAYBIND", - "tDISPINTERFACE", "tDLLNAME", "tDOUBLE", "tDUAL", "tENDPOINT", "tENTRY", - "tENUM", "tERRORSTATUST", "tEXPLICITHANDLE", "tEXTERN", "tFALSE", - "tFLOAT", "tHANDLE", "tHANDLET", "tHELPCONTEXT", "tHELPFILE", - "tHELPSTRING", "tHELPSTRINGCONTEXT", "tHELPSTRINGDLL", "tHIDDEN", - "tHYPER", "tID", "tIDEMPOTENT", "tIIDIS", "tIMMEDIATEBIND", - "tIMPLICITHANDLE", "tIMPORT", "tIMPORTLIB", "tIN", "tINLINE", - "tINPUTSYNC", "tINT", "tINT64", "tINTERFACE", "tLCID", "tLENGTHIS", - "tLIBRARY", "tLOCAL", "tLONG", "tMETHODS", "tMODULE", "tNONBROWSABLE", - "tNONCREATABLE", "tNONEXTENSIBLE", "tOBJECT", "tODL", "tOLEAUTOMATION", - "tOPTIONAL", "tOUT", "tPOINTERDEFAULT", "tPROPERTIES", "tPROPGET", - "tPROPPUT", "tPROPPUTREF", "tPTR", "tPUBLIC", "tRANGE", "tREADONLY", - "tREF", "tREQUESTEDIT", "tRESTRICTED", "tRETVAL", "tSAFEARRAY", - "tSHORT", "tSIGNED", "tSINGLE", "tSIZEIS", "tSIZEOF", "tSMALL", - "tSOURCE", "tSTDCALL", "tSTRING", "tSTRUCT", "tSWITCH", "tSWITCHIS", - "tSWITCHTYPE", "tTRANSMITAS", "tTRUE", "tTYPEDEF", "tUNION", "tUNIQUE", - "tUNSIGNED", "tUUID", "tV1ENUM", "tVARARG", "tVERSION", "tVOID", - "tWCHAR", "tWIREMARSHAL", "','", "'?'", "':'", "'|'", "'&'", "'-'", - "'+'", "'*'", "'/'", "'~'", "CAST", "PPTR", "NEG", "';'", "'('", "')'", - "'{'", "'}'", "'['", "']'", "'='", "'.'", "$accept", "input", - "gbl_statements", "imp_statements", "int_statements", "statement", - "cppquote", "import_start", "import", "importlib", "libraryhdr", - "library_start", "librarydef", "m_args", "no_args", "args", "arg", - "array", "array_list", "m_attributes", "attributes", "attrib_list", - "attribute", "callconv", "cases", "case", "constdef", "enums", - "enum_list", "enum", "enumdef", "m_exprs", "m_expr", "expr", - "expr_list_const", "expr_const", "externdef", "fields", "field", - "s_field", "funcdef", "m_ident", "t_ident", "ident", "base_type", - "m_int", "int_std", "coclass", "coclasshdr", "coclassdef", - "coclass_ints", "coclass_int", "dispinterface", "dispinterfacehdr", - "dispint_props", "dispint_meths", "dispinterfacedef", "inherit", - "interface", "interfacehdr", "interfacedef", "interfacedec", "module", - "modulehdr", "moduledef", "p_ident", "pident", "pident_list", - "pointer_type", "structdef", "type", "typedef", "uniondef", "version", 0 + "aHEXNUM", "aDOUBLE", "aSTRING", "aUUID", "aEOF", "SHL", "SHR", + "tAGGREGATABLE", "tALLOCATE", "tAPPOBJECT", "tASYNC", "tASYNCUUID", + "tAUTOHANDLE", "tBINDABLE", "tBOOLEAN", "tBROADCAST", "tBYTE", + "tBYTECOUNT", "tCALLAS", "tCALLBACK", "tCASE", "tCDECL", "tCHAR", + "tCOCLASS", "tCODE", "tCOMMSTATUS", "tCONST", "tCONTEXTHANDLE", + "tCONTEXTHANDLENOSERIALIZE", "tCONTEXTHANDLESERIALIZE", "tCONTROL", + "tCPPQUOTE", "tDEFAULT", "tDEFAULTCOLLELEM", "tDEFAULTVALUE", + "tDEFAULTVTABLE", "tDISPLAYBIND", "tDISPINTERFACE", "tDLLNAME", + "tDOUBLE", "tDUAL", "tENDPOINT", "tENTRY", "tENUM", "tERRORSTATUST", + "tEXPLICITHANDLE", "tEXTERN", "tFALSE", "tFLOAT", "tHANDLE", "tHANDLET", + "tHELPCONTEXT", "tHELPFILE", "tHELPSTRING", "tHELPSTRINGCONTEXT", + "tHELPSTRINGDLL", "tHIDDEN", "tHYPER", "tID", "tIDEMPOTENT", "tIIDIS", + "tIMMEDIATEBIND", "tIMPLICITHANDLE", "tIMPORT", "tIMPORTLIB", "tIN", + "tINLINE", "tINPUTSYNC", "tINT", "tINT64", "tINTERFACE", "tLCID", + "tLENGTHIS", "tLIBRARY", "tLOCAL", "tLONG", "tMETHODS", "tMODULE", + "tNONBROWSABLE", "tNONCREATABLE", "tNONEXTENSIBLE", "tOBJECT", "tODL", + "tOLEAUTOMATION", "tOPTIONAL", "tOUT", "tPOINTERDEFAULT", "tPROPERTIES", + "tPROPGET", "tPROPPUT", "tPROPPUTREF", "tPTR", "tPUBLIC", "tRANGE", + "tREADONLY", "tREF", "tREQUESTEDIT", "tRESTRICTED", "tRETVAL", + "tSAFEARRAY", "tSHORT", "tSIGNED", "tSINGLE", "tSIZEIS", "tSIZEOF", + "tSMALL", "tSOURCE", "tSTDCALL", "tSTRING", "tSTRUCT", "tSWITCH", + "tSWITCHIS", "tSWITCHTYPE", "tTRANSMITAS", "tTRUE", "tTYPEDEF", "tUNION", + "tUNIQUE", "tUNSIGNED", "tUUID", "tV1ENUM", "tVARARG", "tVERSION", + "tVOID", "tWCHAR", "tWIREMARSHAL", "','", "'?'", "':'", "'|'", "'&'", + "'-'", "'+'", "'*'", "'/'", "'~'", "CAST", "PPTR", "NEG", "ADDRESSOF", + "';'", "'('", "')'", "'{'", "'}'", "'['", "']'", "'='", "'.'", "$accept", + "input", "gbl_statements", "imp_statements", "int_statements", + "statement", "cppquote", "import_start", "import", "importlib", + "libraryhdr", "library_start", "librarydef", "m_args", "no_args", "args", + "arg", "array", "array_list", "m_attributes", "attributes", + "attrib_list", "str_list", "attribute", "uuid_string", "callconv", + "cases", "case", "constdef", "enums", "enum_list", "enum", "enumdef", + "m_exprs", "m_expr", "expr", "expr_list_const", "expr_const", + "externdef", "fields", "field", "s_field", "funcdef", "m_ident", + "t_ident", "ident", "base_type", "m_int", "int_std", "coclass", + "coclasshdr", "coclassdef", "coclass_ints", "coclass_int", + "dispinterface", "dispinterfacehdr", "dispint_props", "dispint_meths", + "dispinterfacedef", "inherit", "interface", "interfacehdr", + "interfacedef", "interfacedec", "module", "modulehdr", "moduledef", + "p_ident", "pident", "pident_list", "pointer_type", "structdef", "type", + "typedef", "uniondef", "version", 0 }; #endif # ifdef YYPRINT /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to token YYLEX-NUM. */ -static const unsigned short yytoknum[] = +static const unsigned short int yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, @@ -856,43 +970,43 @@ static const unsigned short yytoknum[] = 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 44, 63, 58, 124, 38, 45, 43, 42, 47, - 126, 386, 387, 388, 59, 40, 41, 123, 125, 91, - 93, 61, 46 + 385, 386, 44, 63, 58, 124, 38, 45, 43, 42, + 47, 126, 387, 388, 389, 390, 59, 40, 41, 123, + 125, 91, 93, 61, 46 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const unsigned char yyr1[] = { - 0, 153, 154, 155, 155, 155, 155, 155, 155, 155, - 155, 156, 156, 156, 156, 156, 156, 156, 156, 157, - 157, 157, 158, 158, 158, 158, 158, 158, 158, 158, - 158, 159, 160, 161, 162, 163, 164, 165, 166, 166, - 167, 168, 168, 168, 169, 169, 169, 169, 170, 170, - 170, 171, 171, 171, 172, 172, 173, 174, 174, 174, - 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, - 176, 176, 177, 177, 178, 178, 179, 180, 180, 180, - 181, 181, 182, 182, 183, 184, 184, 185, 185, 186, - 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, 186, 187, - 187, 188, 189, 190, 190, 191, 191, 191, 191, 192, - 193, 194, 194, 195, 195, 195, 196, 196, 196, 196, - 196, 196, 196, 196, 196, 196, 197, 197, 197, 197, - 197, 197, 197, 197, 197, 197, 197, 197, 198, 198, - 199, 199, 199, 199, 199, 199, 199, 200, 200, 201, - 202, 203, 203, 204, 205, 205, 206, 207, 207, 208, - 208, 209, 210, 210, 211, 211, 212, 213, 213, 213, - 214, 214, 215, 215, 216, 217, 218, 218, 219, 219, - 219, 220, 220, 221, 221, 221, 222, 223, 223, 223, - 223, 223, 223, 223, 223, 223, 223, 223, 224, 225, - 225, 226, 226 + 0, 155, 156, 157, 157, 157, 157, 157, 157, 157, + 157, 158, 158, 158, 158, 158, 158, 158, 158, 159, + 159, 159, 160, 160, 160, 160, 160, 160, 160, 160, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 168, + 169, 170, 170, 170, 171, 171, 171, 171, 172, 172, + 172, 173, 173, 173, 174, 174, 175, 176, 176, 176, + 177, 177, 178, 178, 178, 178, 178, 178, 178, 178, + 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, + 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, + 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, + 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, + 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, + 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, + 178, 178, 179, 179, 180, 180, 181, 181, 182, 182, + 183, 184, 184, 184, 185, 185, 186, 186, 187, 188, + 188, 189, 189, 190, 190, 190, 190, 190, 190, 190, + 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, + 190, 190, 190, 190, 190, 191, 191, 192, 193, 194, + 194, 195, 195, 195, 195, 196, 197, 198, 198, 199, + 199, 199, 200, 200, 201, 201, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 202, 202, 203, 203, + 203, 203, 203, 203, 203, 204, 204, 205, 206, 207, + 207, 208, 209, 209, 210, 211, 211, 212, 212, 213, + 213, 214, 214, 215, 215, 216, 217, 217, 217, 218, + 218, 219, 219, 220, 221, 222, 222, 223, 223, 223, + 224, 224, 225, 225, 225, 226, 227, 227, 227, 227, + 227, 227, 227, 227, 227, 227, 227, 228, 229, 229, + 230, 230 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ @@ -904,467 +1018,453 @@ static const unsigned char yyr2[] = 2, 4, 3, 3, 4, 2, 3, 3, 0, 1, 1, 1, 3, 1, 4, 3, 6, 5, 0, 3, 3, 1, 3, 4, 0, 1, 3, 1, 3, 4, - 0, 1, 1, 1, 1, 1, 4, 4, 1, 1, - 1, 1, 1, 1, 4, 4, 1, 1, 4, 1, - 4, 4, 4, 1, 1, 4, 4, 4, 4, 4, - 1, 4, 1, 4, 1, 5, 1, 1, 4, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, - 1, 1, 1, 6, 1, 1, 1, 1, 4, 1, - 1, 4, 4, 4, 4, 1, 1, 4, 4, 1, - 0, 1, 0, 2, 4, 3, 5, 0, 2, 1, - 1, 3, 3, 1, 5, 1, 3, 0, 1, 1, - 1, 1, 1, 1, 5, 3, 3, 3, 3, 3, - 3, 3, 3, 2, 2, 2, 4, 4, 3, 1, - 3, 1, 4, 0, 2, 2, 3, 2, 1, 4, - 7, 0, 1, 0, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, - 2, 1, 1, 1, 1, 1, 1, 1, 0, 1, - 1, 2, 1, 2, 2, 1, 1, 2, 2, 2, - 4, 0, 2, 2, 2, 2, 2, 2, 3, 2, - 3, 5, 0, 2, 2, 2, 2, 5, 7, 1, - 2, 2, 2, 2, 2, 4, 2, 2, 1, 1, - 3, 1, 3, 1, 1, 1, 5, 1, 1, 1, - 2, 1, 2, 1, 2, 1, 2, 4, 4, 5, - 10, 1, 3 + 1, 3, 0, 1, 1, 1, 1, 1, 4, 4, + 1, 1, 1, 1, 1, 1, 4, 4, 1, 1, + 4, 1, 4, 4, 4, 1, 1, 4, 4, 4, + 4, 4, 1, 4, 1, 4, 1, 5, 1, 1, + 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 4, 1, 1, 1, 1, 6, 1, 1, 1, 1, + 4, 1, 1, 4, 4, 4, 4, 1, 1, 4, + 4, 1, 1, 1, 0, 1, 0, 2, 4, 3, + 5, 0, 2, 1, 1, 3, 3, 1, 5, 1, + 3, 0, 1, 1, 1, 1, 1, 1, 1, 5, + 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, + 2, 2, 4, 4, 3, 1, 3, 1, 4, 0, + 2, 2, 3, 2, 1, 4, 7, 0, 1, 0, + 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, + 1, 1, 1, 1, 1, 1, 0, 1, 1, 2, + 1, 2, 2, 1, 1, 2, 2, 2, 4, 0, + 2, 2, 2, 2, 2, 2, 3, 2, 3, 5, + 5, 0, 2, 2, 2, 2, 5, 7, 1, 2, + 2, 2, 2, 2, 4, 2, 2, 1, 1, 3, + 1, 3, 1, 1, 1, 5, 1, 1, 1, 2, + 1, 2, 1, 2, 1, 2, 4, 4, 5, 10, + 1, 3 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state STATE-NUM when YYTABLE doesn't specify something else to do. Zero means the default is an error. */ -static const unsigned short yydefact[] = +static const unsigned short int yydefact[] = { - 3, 0, 2, 1, 0, 0, 0, 0, 183, 0, - 0, 0, 183, 54, 183, 22, 60, 10, 24, 11, + 3, 0, 2, 1, 0, 0, 0, 0, 189, 0, + 0, 0, 189, 54, 189, 22, 62, 10, 24, 11, 27, 11, 9, 0, 0, 0, 0, 0, 0, 7, - 0, 0, 239, 0, 232, 5, 4, 0, 8, 0, - 0, 0, 217, 218, 258, 205, 196, 216, 0, 204, - 183, 206, 202, 207, 208, 210, 215, 208, 0, 208, - 0, 203, 212, 183, 183, 201, 257, 197, 261, 259, - 198, 263, 0, 265, 0, 224, 225, 184, 185, 0, - 0, 0, 234, 235, 0, 0, 55, 0, 61, 62, - 63, 64, 65, 0, 0, 68, 69, 70, 71, 72, - 73, 0, 76, 77, 0, 79, 0, 0, 83, 84, - 0, 0, 0, 0, 0, 90, 0, 92, 0, 94, - 0, 96, 97, 0, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 0, 109, 110, 111, 255, 112, 0, - 114, 253, 115, 116, 117, 0, 119, 120, 0, 0, - 0, 254, 0, 125, 126, 0, 0, 0, 57, 129, - 0, 0, 0, 0, 0, 219, 226, 236, 244, 23, - 25, 26, 6, 221, 241, 0, 240, 0, 0, 19, - 28, 29, 30, 260, 262, 209, 214, 213, 0, 211, - 199, 264, 266, 200, 186, 187, 188, 189, 190, 191, - 192, 193, 194, 195, 0, 0, 137, 0, 32, 173, - 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 147, 0, 0, - 147, 0, 0, 0, 0, 0, 0, 60, 56, 33, - 0, 17, 18, 0, 0, 15, 13, 12, 16, 37, - 35, 242, 243, 36, 54, 0, 54, 0, 233, 19, - 54, 0, 0, 31, 0, 139, 140, 143, 172, 54, - 0, 0, 0, 248, 249, 251, 268, 54, 54, 0, - 153, 149, 150, 151, 0, 152, 0, 0, 0, 0, - 171, 0, 169, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 145, 148, - 0, 0, 0, 0, 0, 0, 0, 271, 0, 0, - 58, 60, 0, 14, 220, 0, 222, 227, 0, 0, - 0, 54, 0, 54, 245, 21, 0, 0, 267, 136, - 144, 138, 0, 178, 256, 0, 55, 174, 0, 247, - 246, 0, 0, 0, 269, 66, 0, 164, 165, 163, + 0, 0, 238, 0, 231, 5, 4, 0, 8, 0, + 0, 0, 215, 216, 257, 203, 194, 214, 0, 202, + 189, 204, 200, 205, 206, 208, 213, 206, 0, 206, + 0, 201, 210, 189, 189, 199, 256, 195, 260, 258, + 196, 262, 0, 264, 0, 222, 223, 190, 191, 0, + 0, 0, 233, 234, 0, 0, 55, 0, 63, 64, + 65, 66, 67, 0, 0, 70, 71, 72, 73, 74, + 75, 0, 78, 79, 0, 81, 0, 0, 85, 86, + 0, 0, 0, 0, 0, 92, 0, 94, 0, 96, + 0, 98, 99, 0, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 0, 111, 112, 113, 254, 114, 0, + 116, 252, 117, 118, 119, 0, 121, 122, 0, 0, + 0, 253, 0, 127, 128, 0, 0, 0, 57, 131, + 0, 0, 0, 0, 0, 217, 224, 235, 243, 23, + 25, 26, 6, 219, 240, 0, 239, 0, 0, 19, + 28, 29, 30, 259, 261, 207, 212, 211, 0, 209, + 197, 263, 265, 198, 192, 193, 0, 0, 141, 0, + 32, 179, 0, 0, 179, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 151, + 0, 0, 151, 0, 0, 0, 0, 0, 0, 62, + 56, 33, 0, 17, 18, 0, 0, 15, 13, 12, + 16, 37, 35, 241, 242, 36, 54, 0, 54, 0, + 0, 232, 19, 54, 0, 0, 31, 0, 143, 144, + 147, 178, 54, 0, 0, 0, 247, 248, 250, 267, + 54, 54, 0, 158, 153, 154, 155, 156, 0, 157, + 0, 0, 0, 0, 0, 177, 0, 175, 0, 0, + 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 149, 152, 0, 0, 0, 0, + 0, 0, 133, 132, 0, 270, 0, 0, 58, 62, + 0, 14, 218, 0, 220, 225, 0, 0, 0, 54, + 0, 0, 54, 244, 21, 0, 0, 266, 140, 148, + 142, 0, 184, 255, 0, 55, 180, 0, 246, 245, + 0, 0, 0, 268, 68, 0, 170, 169, 171, 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 67, 75, 74, 78, 80, 81, 82, 85, - 86, 87, 88, 89, 91, 93, 0, 147, 98, 108, - 0, 118, 121, 122, 123, 124, 0, 127, 128, 59, - 0, 223, 229, 0, 228, 231, 0, 19, 237, 130, - 20, 141, 142, 265, 177, 175, 250, 252, 181, 0, - 168, 0, 161, 162, 0, 155, 156, 158, 157, 159, - 160, 170, 95, 146, 0, 272, 34, 48, 230, 54, - 131, 0, 176, 0, 182, 167, 166, 0, 113, 147, - 179, 238, 0, 132, 154, 0, 0, 51, 38, 0, - 50, 0, 49, 257, 0, 43, 39, 41, 0, 0, - 0, 0, 270, 133, 52, 0, 180, 0, 0, 48, - 0, 54, 53, 42, 48, 38, 45, 54, 135, 38, - 44, 0, 134, 0, 47, 46 + 0, 0, 69, 77, 76, 80, 0, 82, 83, 84, + 87, 88, 89, 90, 91, 93, 95, 0, 151, 100, + 110, 0, 120, 123, 124, 125, 126, 0, 129, 130, + 59, 0, 221, 227, 0, 226, 229, 0, 230, 19, + 236, 134, 20, 145, 146, 264, 183, 181, 249, 251, + 187, 0, 174, 0, 166, 167, 0, 160, 161, 163, + 162, 164, 165, 176, 61, 97, 150, 0, 271, 34, + 48, 228, 54, 135, 0, 182, 0, 188, 173, 172, + 0, 115, 151, 185, 237, 0, 136, 159, 0, 0, + 51, 38, 0, 50, 0, 49, 256, 0, 43, 39, + 41, 0, 0, 0, 0, 269, 137, 52, 0, 186, + 0, 0, 48, 0, 54, 53, 42, 48, 38, 45, + 54, 139, 38, 44, 0, 138, 0, 47, 46 }; /* YYDEFGOTO[NTERM-NUM]. */ -static const short yydefgoto[] = +static const short int yydefgoto[] = { - -1, 1, 2, 160, 260, 335, 18, 19, 20, 242, - 164, 21, 22, 464, 465, 466, 467, 450, 456, 336, - 86, 157, 158, 441, 459, 473, 24, 264, 265, 266, - 68, 307, 308, 290, 291, 292, 26, 269, 347, 348, - 337, 443, 79, 273, 69, 186, 70, 165, 28, 245, - 254, 326, 30, 31, 256, 331, 32, 178, 33, 34, - 246, 247, 168, 37, 248, 274, 275, 276, 159, 71, - 469, 40, 73, 318 + -1, 1, 2, 160, 253, 334, 18, 19, 20, 234, + 164, 21, 22, 467, 468, 469, 470, 453, 459, 335, + 86, 157, 292, 158, 314, 444, 462, 476, 24, 257, + 258, 259, 68, 303, 304, 285, 286, 287, 26, 262, + 346, 347, 336, 446, 79, 266, 69, 186, 70, 165, + 28, 237, 246, 324, 30, 31, 248, 329, 32, 178, + 33, 34, 238, 239, 168, 37, 240, 267, 268, 269, + 159, 71, 472, 40, 73, 316 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -447 -static const short yypact[] = +#define YYPACT_NINF -376 +static const short int yypact[] = { - -447, 43, 696, -447, 65, 655, -111, 97, 109, 35, - 78, 118, 109, -46, 109, -447, 809, -447, -447, -447, - -447, -447, -447, 66, -30, 2, 13, 16, -5, -447, - 26, 40, -447, 38, 76, -447, -447, 50, -447, 67, - 69, 71, -447, -447, -447, -447, -447, -447, 655, -447, - 129, -447, -447, -447, 161, -447, -447, 161, 91, 161, - 10, -447, -447, 182, 191, 10, -447, -447, -447, -447, - -447, -447, 587, -447, 235, -447, -447, -447, -447, 96, - 655, 102, -447, -447, 103, 655, -447, -94, -447, -447, - -447, -447, -447, 108, 110, -447, -447, -447, -447, -447, - -447, 112, -447, -447, 114, -447, 121, 127, -447, -447, - 130, 135, 136, 137, 138, -447, 142, -447, 144, -447, - 146, -447, -447, 147, -447, -447, -447, -447, -447, -447, - -447, -447, -447, 148, -447, -447, -447, -447, -447, 149, - -447, -447, -447, -447, -447, 152, -447, -447, 156, 158, - 159, -447, 160, -447, -447, 165, 166, -100, -447, -447, - 528, 665, 271, 201, 167, -447, -447, -447, -447, -447, - -447, -447, -447, -447, -447, 214, -447, 203, 168, -447, - -447, -447, -447, -447, 169, -447, -447, -447, 655, -447, - -447, 169, -82, -447, -447, -447, -447, -447, -447, -447, - -447, -447, -447, -447, 172, 173, 587, 587, -447, -447, - 223, 175, -447, 587, 246, 9, 305, 320, 99, 246, - 321, 323, 246, 326, 246, 587, 280, 246, -68, 246, - 246, 246, 655, 655, 329, 334, 655, 809, 195, -447, - 200, -447, -447, 220, 196, -447, -447, -447, -447, -447, - -447, -447, -447, -447, 72, 218, -61, 206, -447, -447, - 892, 208, 246, -447, 209, 225, -447, 207, -447, -25, - -21, 223, 223, -447, -447, -447, 228, -46, -19, 216, - -447, -447, -447, -447, 215, -447, 246, 246, 246, 500, - 532, -84, -447, 217, 221, 224, 226, 231, 239, 241, - 242, 243, 247, 248, 249, 250, 361, -79, -447, 532, - 254, 238, -76, 267, 261, 262, 263, 219, 264, 265, - -447, 809, 359, -447, -447, -16, -447, -447, 279, 655, - 270, 92, 347, 901, -447, -447, 655, 272, -447, -447, - -447, 587, 246, -447, -447, 655, 273, -447, 275, -447, - -447, 274, 223, 277, -447, -447, 655, -447, -447, -447, - 297, 278, 246, 246, 246, 246, 246, 246, 246, 246, - 246, 246, -447, -447, -447, -447, -447, -447, -447, -447, - -447, -447, -447, -447, -447, -447, 282, 246, -447, -447, - 246, -447, -447, -447, -447, -447, 416, -447, -447, -447, - 284, -447, -447, 223, -447, -447, 281, -447, -447, 314, - -447, -447, -447, 294, -447, -447, -447, -447, 587, 295, - -447, 246, -447, -447, 449, 64, 53, 14, 14, 212, - 212, -447, -447, -447, 300, -447, -447, 298, -447, 910, - -447, 223, -447, 301, -447, -447, -447, 246, -447, 375, - -447, -447, 306, -447, 532, 74, -93, -447, 269, -8, - -447, 246, 303, -60, 304, -447, 322, -447, 655, 223, - 246, 324, -447, -447, 532, 246, -447, 418, 223, -18, - 519, -71, 532, -447, -11, 269, -447, -71, -447, 269, - -447, 308, -447, 309, -447, -447 + -376, 24, 773, -376, 86, 684, -43, 190, 193, 79, + 109, 210, 193, -28, 193, -376, 934, -376, -376, -376, + -376, -376, -376, 27, -20, -14, -7, -5, 20, -376, + 14, 40, -376, 53, 0, -376, -376, 59, -376, 77, + 89, 92, -376, -376, -376, -376, -376, -376, 684, -376, + 213, -376, -376, -376, 178, -376, -376, 178, 108, 178, + -6, -376, -376, 226, 228, -6, -376, -376, -376, -376, + -376, -376, 237, -376, 251, -376, -376, -376, -376, 115, + 684, 122, -376, -376, 123, 684, -376, -91, -376, -376, + -376, -376, -376, 128, 132, -376, -376, -376, -376, -376, + -376, 136, -376, -376, 138, -376, 143, 145, -376, -376, + 146, 147, 148, 151, 152, -376, 153, -376, 154, -376, + 155, -376, -376, 158, -376, -376, -376, -376, -376, -376, + -376, -376, -376, 159, -376, -376, -376, -376, -376, 160, + -376, -376, -376, -376, -376, 161, -376, -376, 162, 163, + 164, -376, 165, -376, -376, 167, 169, -79, -376, -376, + 615, 731, 314, 239, 170, -376, -376, -376, -376, -376, + -376, -376, -376, -376, -376, -16, -376, 241, 171, -376, + -376, -376, -376, -376, 173, -376, -376, -376, 684, -376, + -376, 173, -85, -376, -376, -376, 175, 176, 237, 237, + -376, -376, 48, 179, -376, 237, 382, 243, 310, 321, + 450, 382, 322, 324, 382, 326, 382, 382, 280, 382, + -51, 382, 382, 382, 684, 684, 217, 334, 684, 934, + 195, -376, 194, -376, -376, 16, 198, -376, -376, -376, + -376, -376, -376, -376, -376, -376, 116, 214, -63, 206, + 205, -376, -376, 605, 216, 382, -376, 215, 234, -376, + 218, -376, -32, -15, 48, 48, -376, -376, -376, 240, + -28, -30, 221, -376, -376, -376, -376, -376, 229, -376, + 382, 382, 382, 382, 502, 17, -93, -376, 225, 227, + 230, -376, -83, 233, 235, 238, 244, 245, 246, 247, + 248, 67, 374, -47, -376, 17, 249, 259, -46, 222, + 254, 255, -376, -376, 257, 252, 261, 262, -376, 934, + 399, -376, -376, -10, -376, -376, 277, 684, 266, 131, + 263, 345, 786, -376, -376, 684, 270, -376, -376, -376, + 237, 382, -376, -376, 684, 272, -376, 273, -376, -376, + 285, 48, 286, -376, -376, 684, -376, -376, -376, -376, + 542, 288, 382, 382, 382, 382, 382, 382, 382, 382, + 382, 382, -376, -376, -376, -376, 412, -376, -376, -376, + -376, -376, -376, -376, -376, -376, -376, 289, 382, -376, + -376, 382, -376, -376, -376, -376, -376, 416, -376, -376, + -376, 290, -376, -376, 48, -376, -376, 295, -376, -376, + -376, 333, -376, -376, -376, 303, -376, -376, -376, -376, + 237, 291, -376, 382, -376, -376, 292, 9, 72, -3, + -3, 276, 276, -376, -376, -376, -376, 302, -376, -376, + 300, -376, 795, -376, 48, -376, 305, -376, -376, -376, + 382, -376, 509, -376, -376, 313, -376, 17, 137, -78, + -376, 293, -12, -376, 382, 311, -41, 315, -376, 329, + -376, 684, 48, 382, 330, -376, -376, 17, 382, -376, + 420, 48, -80, 561, -104, 17, -376, 23, 293, -376, + -104, -376, 293, -376, 318, -376, 320, -376, -376 }; /* YYPGOTO[NTERM-NUM]. */ -static const short yypgoto[] = +static const short int yypgoto[] = { - -447, -447, -447, 437, -251, 7, -447, -447, 131, -447, - -447, -447, -447, -350, -447, -447, -7, -397, -447, -9, - -2, -447, -214, -447, -447, -447, -447, -447, -447, 120, - 3, 244, -357, -191, -447, -173, -447, 253, -446, -229, - 145, -447, 46, -70, -447, 34, 51, 20, -447, 466, - -447, -447, -12, -447, -447, -447, -447, -447, -10, -447, - 467, 4, -447, -447, 475, 211, -253, -447, 258, 5, - -4, -447, 1, -447 + -376, -376, -376, 451, -236, 11, -376, -376, 140, -376, + -376, -376, -376, -300, -376, -376, -1, -360, -376, -9, + -2, -376, -376, -211, -376, -376, -376, -376, -376, -376, + -376, 133, 3, 258, -365, -187, -376, -173, -376, 281, + -375, -208, 168, -376, 49, -70, -376, 74, 65, 25, + -376, 475, -376, -376, -13, -376, -376, -376, -376, -376, + -8, -376, 482, 4, -376, -376, 485, 236, -253, -376, + 269, 5, -4, -376, 1, -376 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If zero, do what YYDEFACT says. If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -185 -static const short yytable[] = +#define YYTABLE_NINF -191 +static const short int yytable[] = { - 23, 72, 204, 41, 85, 25, 36, 39, 333, 17, - 270, 166, 280, 167, 281, 282, 293, 470, 350, 351, - 328, 211, 27, 320, 362, 363, 7, 330, 137, 471, - 433, 237, 141, -184, 74, 488, 309, 47, 461, 309, - 313, 492, 294, 3, 183, 298, 299, 371, 353, 302, - 238, 304, 387, 212, 151, 387, 311, 462, 84, 11, - 87, 283, 372, 362, 363, -184, 80, 388, 42, 43, - 391, -40, 54, 343, 362, 363, 207, 280, 16, 281, - 282, 210, 486, 55, 56, 81, -40, 490, 16, 339, - 57, 187, 457, 189, 4, 357, 358, 359, 360, 417, - 75, 76, 280, 16, 281, 282, 297, 399, 7, 84, - 87, 190, 77, 78, 169, 59, 193, 271, 284, 343, - 62, 82, 83, 344, 16, 343, 283, 485, 285, 354, - 16, 449, 184, 78, 489, 491, 267, 268, 449, 493, - 472, 11, 173, 279, 162, 286, 170, 287, 163, 288, - 437, 283, 369, 370, 289, 305, 439, 171, 243, 243, - 172, 41, 41, 25, 25, 39, 39, 241, 241, 412, - 174, 422, 423, 424, 425, 426, 427, 428, 429, 430, - 244, 244, 176, 284, 261, 191, 78, 175, 452, 367, - 368, 369, 370, 285, 192, 78, 309, 179, 431, 366, - 367, 368, 369, 370, 251, 252, 257, 258, 284, 177, - 286, 180, 287, 181, 288, 182, 479, 434, 285, 289, - 324, 16, 362, 363, 460, 484, 194, 195, 314, 315, - 446, 166, 319, 167, 185, 286, 188, 287, 196, 288, - 405, 16, 205, 206, 289, 325, 208, 329, 4, 280, - 209, 281, 282, 213, 270, 214, 454, 215, 309, 216, - 345, 41, 7, 25, 358, 39, 217, 346, 329, 345, - 474, 267, 218, 44, 250, 219, 346, 362, 363, 480, - 220, 221, 222, 223, 482, 361, 197, 224, 45, 225, - 46, 226, 227, 228, 229, 11, 47, 230, 283, 198, - 48, 231, 163, 232, 233, 234, 255, 362, 363, 199, - 235, 236, 295, 49, 253, 259, -184, 50, 51, 263, - 277, 200, 52, 262, 53, 403, 201, 296, 300, 401, - 301, 54, 409, 303, 41, 306, 25, 316, 39, 317, - 323, 403, 55, 56, 321, 322, 413, 202, 444, 57, - 203, 327, 419, 332, 338, 284, 341, 340, 342, 352, - 356, 271, 355, 373, 386, 285, 400, 374, 272, 390, - 375, 396, 376, 58, 59, 60, 61, 377, 280, 62, - 281, 282, 286, 63, 287, 378, 288, 379, 380, 381, - 64, 289, 65, 382, 383, 384, 385, 463, 67, 364, - 389, 365, 366, 367, 368, 369, 370, 393, 394, 395, - 397, 398, 402, 392, 404, 10, 410, 414, 16, 415, - 416, 435, 44, 418, 421, 438, 440, 283, 432, 364, - 436, 365, 366, 367, 368, 369, 370, 45, 442, 46, - 41, 445, 25, 420, 39, 47, 448, 449, 453, 48, - 476, 458, 475, 477, 494, 495, 468, 481, 161, 362, - 363, 411, 49, 407, 478, 278, 50, 51, 29, 35, - 483, 52, 345, 53, 312, 468, 406, 38, 345, 346, - 54, 349, 0, 468, 284, 346, 310, 468, 0, 0, - 0, 55, 56, 0, 285, 0, 0, 0, 57, 0, - 0, 0, 0, 280, 44, 281, 282, 0, 0, 0, - 0, 286, 0, 455, 0, 288, 0, 0, 0, 45, - 289, 46, 58, 59, 60, 61, 0, 47, 62, 362, - 363, 48, 63, 0, 0, 0, 0, 239, 0, 64, - 0, 65, 362, 363, 49, 0, 66, 67, 50, 51, - 0, 0, 283, 52, 0, 53, 4, 0, 0, 5, - 0, 0, 54, 0, 6, 0, 0, 16, 0, 0, - 7, 0, 0, 55, 56, 0, 8, 0, 0, 9, - 57, 364, 447, 365, 366, 367, 368, 369, 370, 0, - 194, 195, 0, 0, 0, 0, 10, 240, 0, 0, - 0, 0, 196, 11, 58, 59, 60, 61, 0, 284, - 62, 0, 0, 0, 63, 0, 0, 0, 0, 285, - 0, 64, 0, 65, 0, 0, 0, 0, 66, 67, - 0, 0, 0, 0, 0, 0, 286, 0, 287, 0, - 288, 0, 12, 0, 0, 289, 0, 0, 13, 14, - 197, 364, 487, 365, 366, 367, 368, 369, 370, 44, - 0, 0, 0, 198, 364, 0, 365, 366, 367, 368, - 369, 370, 15, 199, 45, 0, 46, 16, 0, 0, - 0, 0, 47, 0, 0, 200, 48, 0, 0, 0, - 201, 0, 0, 4, 0, 0, 5, 0, 0, 49, - 0, 6, 0, 50, 51, 0, 0, 7, 52, 0, - 53, 202, 0, 8, 203, 0, 9, 54, 0, 0, - 0, 0, 0, 0, 4, 0, 0, 5, 55, 56, - 0, 0, 6, 10, 240, 57, 0, 0, 7, 0, - 11, 0, 0, 0, 8, 0, 0, 9, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, - 59, 60, 61, 0, 10, 62, 0, 0, 0, 63, - 0, 11, 0, 0, 0, 0, 64, 0, 65, 12, - 0, 0, 0, 66, 67, 13, 14, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, - 12, 0, 0, 249, 16, 0, 13, 14, 0, 0, - 0, 88, 0, 89, 90, 0, 91, 92, 0, 0, - 0, 0, 93, 0, 94, 0, 0, 0, 0, 0, - 15, 95, 96, 97, 98, 16, 99, 100, 101, 102, - 103, 0, 104, 0, 105, 106, 107, 0, 0, 108, - 0, 0, 0, 109, 0, 110, 111, 112, 113, 114, - 115, 0, 116, 117, 118, 119, 120, 0, 0, 121, - 0, 122, 0, 0, 0, 0, 123, 0, 124, 0, - 0, 0, 125, 126, 127, 128, 129, 130, 131, 132, - 133, 0, 134, 135, 136, 137, 138, 139, 140, 141, - 142, 143, 144, 0, 0, 0, 0, 145, 0, 0, - 146, 0, 147, 5, 0, 148, 149, 150, 6, 0, - 0, 151, 5, 152, 153, 154, 155, 6, 0, 156, - 8, 5, 0, 9, 0, 0, 6, 0, 0, 8, - 0, 0, 9, 0, 0, 0, 0, 0, 8, 0, - 10, 9, 0, 0, 0, 0, 0, 0, 0, 10, - 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, - 0, 0, 13, 14, 0, 12, 0, 0, 0, 0, - 0, 13, 14, 0, 12, 0, 0, 0, 0, 0, - 13, 14, 0, 0, 0, 0, 15, 0, 0, 0, - 334, 16, 0, 0, 0, 15, 0, 0, 0, 408, - 16, 0, 0, 0, 15, 0, 0, 0, 451, 16 + 23, 72, 196, 41, 85, 25, 36, 39, 362, 363, + 166, 349, 350, 17, 473, 167, 332, 263, 318, 326, + 362, 363, 47, 436, 3, 203, 474, 27, 362, 363, + 301, -190, 305, 7, 289, 305, 309, 294, 295, 371, + 328, 298, 342, 300, 183, 4, 137, 16, 307, 376, + 141, 194, 195, 229, 464, 372, 4, 54, 204, 7, + 11, 84, 352, 87, -190, 377, 11, 488, 55, 56, + 7, 452, 151, 230, 465, 57, 199, 247, 362, 363, + 263, 202, 338, 362, 363, 388, 388, 460, 16, 42, + 43, -40, 11, 356, 357, 358, 359, 360, 419, 163, + 59, 389, 392, 11, 74, 62, 162, -40, 400, 491, + 163, 80, 84, 87, 342, 495, 342, 81, 343, 16, + 353, 16, 489, 16, 264, 190, 169, 493, 260, 261, + 193, 187, 170, 189, 177, 272, 369, 370, 475, 171, + 273, 172, 274, 275, 276, 366, 367, 368, 369, 370, + 364, 440, 365, 366, 367, 368, 369, 370, 235, 235, + 174, 41, 41, 25, 25, 39, 39, 249, 414, 173, + 492, 233, 233, 442, 452, 424, 425, 426, 427, 428, + 429, 430, 431, 432, 254, 236, 236, 264, 494, 175, + 277, 455, 496, 75, 76, 265, 77, 78, 433, 176, + 364, 305, 365, 366, 367, 368, 369, 370, 179, 367, + 368, 369, 370, 82, 83, 386, 184, 78, 437, 482, + 310, 311, 166, 180, 317, 312, 313, 167, 487, 191, + 78, 192, 78, 362, 363, 181, 449, 323, 182, 327, + 194, 195, 243, 244, 250, 251, 273, 278, 274, 275, + 276, 288, 185, 344, 41, 188, 25, 279, 39, 197, + 345, 327, 344, 457, 198, 305, 322, 16, 200, 345, + 260, 358, 201, 280, 281, 205, 282, 477, 283, 206, + 361, 406, 16, 207, 284, 208, 483, 362, 363, 463, + 209, 485, 210, 211, 212, 213, 277, 44, 214, 215, + 216, 217, 218, 362, 363, 219, 220, 221, 222, 223, + 224, 225, 226, 45, 227, 46, 228, 242, 290, 245, + 252, 47, -190, 404, 256, 48, 270, 402, 255, 291, + 296, 411, 297, 41, 299, 25, 302, 39, 49, 315, + 404, 320, 50, 51, 321, 415, 319, 52, 325, 53, + 447, 421, 330, 278, 331, 364, 54, 365, 366, 367, + 368, 369, 370, 279, 337, 339, 340, 55, 56, 354, + 393, 341, 351, 373, 57, 374, 355, 387, 375, 280, + 281, 378, 282, 379, 283, 273, 380, 274, 275, 276, + 284, 391, 381, 382, 383, 384, 385, 390, 58, 59, + 60, 61, 394, 395, 62, 396, 397, 401, 63, 398, + 399, 403, 405, 408, 10, 64, 412, 65, 416, 417, + 434, 438, 466, 67, 44, 364, 450, 365, 366, 367, + 368, 369, 370, 418, 420, 277, 423, 435, 439, 448, + 45, 441, 46, 41, 16, 25, 443, 39, 47, 445, + 451, 452, 48, 273, 456, 274, 275, 276, 293, 471, + 461, 480, 478, 479, 484, 49, 497, 481, 498, 50, + 51, 409, 161, 413, 52, 344, 53, 29, 471, 486, + 308, 344, 345, 54, 35, 271, 471, 38, 345, 306, + 471, 0, 278, 0, 55, 56, 0, 407, 0, 348, + 0, 57, 279, 277, 0, 273, 44, 274, 275, 276, + 0, 0, 273, 0, 274, 275, 276, 0, 280, 281, + 0, 282, 45, 283, 46, 58, 59, 60, 61, 284, + 47, 62, 0, 0, 48, 63, 0, 0, 0, 0, + 0, 0, 64, 0, 65, 0, 0, 49, 0, 66, + 67, 50, 51, 362, 363, 277, 52, 0, 53, 0, + 278, 0, 277, 0, 0, 54, 0, 0, 0, 0, + 279, 16, 362, 363, 0, 0, 55, 56, 0, 0, + 0, 0, 0, 57, 0, 0, 280, 281, 0, 282, + 0, 283, 0, 0, 0, 0, 0, 284, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 58, 59, 60, + 61, 0, 278, 62, 0, 0, 0, 63, 0, 278, + 0, 0, 279, 0, 64, 231, 65, 0, 0, 279, + 0, 66, 67, 0, 0, 0, 0, 5, 280, 281, + 0, 282, 6, 283, 4, 280, 281, 5, 458, 284, + 283, 0, 6, 0, 8, 0, 284, 9, 7, 0, + 0, 0, 0, 0, 8, 0, 0, 9, 0, 0, + 0, 0, 0, 0, 10, 364, 0, 365, 366, 367, + 368, 369, 370, 0, 10, 232, 0, 0, 44, 0, + 422, 11, 0, 0, 364, 490, 365, 366, 367, 368, + 369, 370, 0, 0, 45, 0, 46, 0, 0, 0, + 0, 0, 47, 0, 0, 0, 48, 0, 0, 0, + 12, 0, 0, 0, 0, 0, 13, 14, 0, 49, + 12, 0, 0, 50, 51, 0, 13, 14, 52, 0, + 53, 0, 0, 0, 0, 0, 0, 54, 0, 0, + 0, 15, 0, 0, 0, 333, 16, 0, 55, 56, + 4, 15, 0, 5, 0, 57, 16, 0, 6, 0, + 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, + 8, 0, 0, 9, 0, 0, 0, 0, 0, 58, + 59, 60, 61, 0, 0, 62, 0, 0, 0, 63, + 10, 232, 4, 0, 0, 5, 64, 11, 65, 0, + 6, 0, 0, 66, 67, 0, 7, 0, 5, 0, + 0, 0, 8, 6, 0, 9, 0, 5, 0, 0, + 0, 0, 6, 0, 0, 8, 0, 0, 9, 0, + 0, 0, 10, 0, 8, 0, 12, 9, 0, 11, + 0, 0, 13, 14, 0, 10, 0, 0, 0, 0, + 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, + 0, 241, 16, 0, 0, 0, 0, 0, 12, 0, + 0, 0, 0, 0, 13, 14, 0, 0, 0, 0, + 0, 12, 0, 0, 0, 0, 0, 13, 14, 0, + 12, 0, 0, 0, 0, 0, 13, 14, 0, 15, + 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, 410, 16, 0, 0, + 0, 15, 0, 0, 0, 454, 16, 88, 0, 89, + 90, 0, 91, 92, 0, 0, 0, 0, 93, 0, + 94, 0, 0, 0, 0, 0, 0, 95, 96, 97, + 98, 0, 99, 100, 101, 102, 103, 0, 104, 0, + 105, 106, 107, 0, 0, 108, 0, 0, 0, 109, + 0, 110, 111, 112, 113, 114, 115, 0, 116, 117, + 118, 119, 120, 0, 0, 121, 0, 122, 0, 0, + 0, 0, 123, 0, 124, 0, 0, 0, 125, 126, + 127, 128, 129, 130, 131, 132, 133, 0, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, 144, 0, + 0, 0, 0, 145, 0, 0, 146, 0, 147, 0, + 0, 148, 149, 150, 0, 0, 0, 151, 0, 152, + 153, 154, 155, 0, 0, 156 }; -static const short yycheck[] = +static const short int yycheck[] = { - 2, 5, 72, 2, 13, 2, 2, 2, 259, 2, - 31, 23, 3, 23, 5, 6, 7, 25, 271, 272, - 81, 115, 2, 237, 10, 11, 42, 256, 96, 37, - 387, 131, 100, 115, 145, 481, 227, 27, 131, 230, - 231, 487, 215, 0, 48, 218, 219, 131, 277, 222, - 150, 224, 131, 147, 122, 131, 229, 150, 12, 75, - 14, 52, 146, 10, 11, 147, 31, 146, 3, 4, - 146, 131, 62, 144, 10, 11, 80, 3, 149, 5, - 6, 85, 479, 73, 74, 7, 146, 484, 149, 262, - 80, 57, 449, 59, 28, 286, 287, 288, 289, 352, - 3, 4, 3, 149, 5, 6, 7, 321, 42, 63, - 64, 60, 3, 4, 144, 105, 65, 138, 109, 144, - 110, 3, 4, 148, 149, 144, 52, 145, 119, 148, - 149, 149, 3, 4, 145, 485, 206, 207, 149, 489, - 148, 75, 147, 213, 78, 136, 144, 138, 82, 140, - 403, 52, 138, 139, 145, 225, 407, 144, 160, 161, - 144, 160, 161, 160, 161, 160, 161, 160, 161, 342, - 144, 362, 363, 364, 365, 366, 367, 368, 369, 370, - 160, 161, 144, 109, 188, 3, 4, 147, 441, 136, - 137, 138, 139, 119, 3, 4, 387, 147, 371, 135, - 136, 137, 138, 139, 3, 4, 3, 4, 109, 133, - 136, 144, 138, 144, 140, 144, 469, 390, 119, 145, - 148, 149, 10, 11, 150, 478, 3, 4, 232, 233, - 421, 243, 236, 243, 73, 136, 145, 138, 15, 140, - 148, 149, 7, 147, 145, 254, 144, 256, 28, 3, - 147, 5, 6, 145, 31, 145, 447, 145, 449, 145, - 269, 260, 42, 260, 455, 260, 145, 269, 277, 278, - 461, 341, 145, 4, 3, 145, 278, 10, 11, 470, - 145, 145, 145, 145, 475, 289, 63, 145, 19, 145, - 21, 145, 145, 145, 145, 75, 27, 145, 52, 76, - 31, 145, 82, 145, 145, 145, 92, 10, 11, 86, - 145, 145, 7, 44, 147, 147, 147, 48, 49, 146, - 145, 98, 53, 151, 55, 329, 103, 7, 7, 325, - 7, 62, 336, 7, 333, 55, 333, 8, 333, 5, - 144, 345, 73, 74, 149, 145, 345, 124, 418, 80, - 127, 133, 356, 147, 146, 109, 131, 148, 151, 131, - 145, 138, 146, 146, 3, 119, 7, 146, 145, 131, - 146, 152, 146, 104, 105, 106, 107, 146, 3, 110, - 5, 6, 136, 114, 138, 146, 140, 146, 146, 146, - 121, 145, 123, 146, 146, 146, 146, 128, 129, 132, - 146, 134, 135, 136, 137, 138, 139, 146, 146, 146, - 146, 146, 133, 146, 144, 68, 144, 144, 149, 144, - 146, 5, 4, 146, 146, 144, 112, 52, 146, 132, - 146, 134, 135, 136, 137, 138, 139, 19, 144, 21, - 439, 146, 439, 146, 439, 27, 146, 149, 147, 31, - 146, 145, 149, 131, 146, 146, 458, 133, 21, 10, - 11, 341, 44, 332, 468, 212, 48, 49, 2, 2, - 477, 53, 481, 55, 230, 477, 331, 2, 487, 481, - 62, 270, -1, 485, 109, 487, 228, 489, -1, -1, - -1, 73, 74, -1, 119, -1, -1, -1, 80, -1, - -1, -1, -1, 3, 4, 5, 6, -1, -1, -1, - -1, 136, -1, 138, -1, 140, -1, -1, -1, 19, - 145, 21, 104, 105, 106, 107, -1, 27, 110, 10, - 11, 31, 114, -1, -1, -1, -1, 9, -1, 121, - -1, 123, 10, 11, 44, -1, 128, 129, 48, 49, - -1, -1, 52, 53, -1, 55, 28, -1, -1, 31, - -1, -1, 62, -1, 36, -1, -1, 149, -1, -1, - 42, -1, -1, 73, 74, -1, 48, -1, -1, 51, - 80, 132, 133, 134, 135, 136, 137, 138, 139, -1, - 3, 4, -1, -1, -1, -1, 68, 69, -1, -1, - -1, -1, 15, 75, 104, 105, 106, 107, -1, 109, - 110, -1, -1, -1, 114, -1, -1, -1, -1, 119, - -1, 121, -1, 123, -1, -1, -1, -1, 128, 129, - -1, -1, -1, -1, -1, -1, 136, -1, 138, -1, - 140, -1, 114, -1, -1, 145, -1, -1, 120, 121, - 63, 132, 133, 134, 135, 136, 137, 138, 139, 4, - -1, -1, -1, 76, 132, -1, 134, 135, 136, 137, - 138, 139, 144, 86, 19, -1, 21, 149, -1, -1, - -1, -1, 27, -1, -1, 98, 31, -1, -1, -1, - 103, -1, -1, 28, -1, -1, 31, -1, -1, 44, - -1, 36, -1, 48, 49, -1, -1, 42, 53, -1, - 55, 124, -1, 48, 127, -1, 51, 62, -1, -1, - -1, -1, -1, -1, 28, -1, -1, 31, 73, 74, - -1, -1, 36, 68, 69, 80, -1, -1, 42, -1, - 75, -1, -1, -1, 48, -1, -1, 51, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 104, - 105, 106, 107, -1, 68, 110, -1, -1, -1, 114, - -1, 75, -1, -1, -1, -1, 121, -1, 123, 114, - -1, -1, -1, 128, 129, 120, 121, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 144, - 114, -1, -1, 148, 149, -1, 120, 121, -1, -1, - -1, 12, -1, 14, 15, -1, 17, 18, -1, -1, - -1, -1, 23, -1, 25, -1, -1, -1, -1, -1, - 144, 32, 33, 34, 35, 149, 37, 38, 39, 40, - 41, -1, 43, -1, 45, 46, 47, -1, -1, 50, - -1, -1, -1, 54, -1, 56, 57, 58, 59, 60, - 61, -1, 63, 64, 65, 66, 67, -1, -1, 70, - -1, 72, -1, -1, -1, -1, 77, -1, 79, -1, - -1, -1, 83, 84, 85, 86, 87, 88, 89, 90, - 91, -1, 93, 94, 95, 96, 97, 98, 99, 100, - 101, 102, 103, -1, -1, -1, -1, 108, -1, -1, - 111, -1, 113, 31, -1, 116, 117, 118, 36, -1, - -1, 122, 31, 124, 125, 126, 127, 36, -1, 130, - 48, 31, -1, 51, -1, -1, 36, -1, -1, 48, - -1, -1, 51, -1, -1, -1, -1, -1, 48, -1, - 68, 51, -1, -1, -1, -1, -1, -1, -1, 68, - -1, -1, -1, -1, -1, -1, -1, -1, 68, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 114, -1, -1, -1, - -1, -1, 120, 121, -1, 114, -1, -1, -1, -1, - -1, 120, 121, -1, 114, -1, -1, -1, -1, -1, - 120, 121, -1, -1, -1, -1, 144, -1, -1, -1, - 148, 149, -1, -1, -1, 144, -1, -1, -1, 148, - 149, -1, -1, -1, 144, -1, -1, -1, 148, 149 + 2, 5, 72, 2, 13, 2, 2, 2, 11, 12, + 23, 264, 265, 2, 26, 23, 252, 32, 229, 82, + 11, 12, 28, 388, 0, 116, 38, 2, 11, 12, + 217, 116, 219, 43, 207, 222, 223, 210, 211, 132, + 248, 214, 146, 216, 48, 29, 97, 151, 221, 132, + 101, 3, 4, 132, 132, 148, 29, 63, 149, 43, + 76, 12, 270, 14, 149, 148, 76, 147, 74, 75, + 43, 151, 123, 152, 152, 81, 80, 93, 11, 12, + 32, 85, 255, 11, 12, 132, 132, 452, 151, 3, + 4, 132, 76, 280, 281, 282, 283, 284, 351, 83, + 106, 148, 148, 76, 147, 111, 79, 148, 319, 484, + 83, 32, 63, 64, 146, 490, 146, 8, 150, 151, + 150, 151, 482, 151, 139, 60, 146, 487, 198, 199, + 65, 57, 146, 59, 134, 205, 139, 140, 150, 146, + 3, 146, 5, 6, 7, 136, 137, 138, 139, 140, + 133, 404, 135, 136, 137, 138, 139, 140, 160, 161, + 146, 160, 161, 160, 161, 160, 161, 175, 341, 149, + 147, 160, 161, 409, 151, 362, 363, 364, 365, 366, + 367, 368, 369, 370, 188, 160, 161, 139, 488, 149, + 53, 444, 492, 3, 4, 147, 3, 4, 371, 146, + 133, 388, 135, 136, 137, 138, 139, 140, 149, 137, + 138, 139, 140, 3, 4, 148, 3, 4, 391, 472, + 224, 225, 235, 146, 228, 8, 9, 235, 481, 3, + 4, 3, 4, 11, 12, 146, 423, 246, 146, 248, + 3, 4, 3, 4, 3, 4, 3, 110, 5, 6, + 7, 8, 74, 262, 253, 147, 253, 120, 253, 8, + 262, 270, 271, 450, 149, 452, 150, 151, 146, 271, + 340, 458, 149, 136, 137, 147, 139, 464, 141, 147, + 284, 150, 151, 147, 147, 147, 473, 11, 12, 152, + 147, 478, 147, 147, 147, 147, 53, 4, 147, 147, + 147, 147, 147, 11, 12, 147, 147, 147, 147, 147, + 147, 147, 147, 20, 147, 22, 147, 3, 8, 149, + 149, 28, 149, 327, 148, 32, 147, 323, 153, 8, + 8, 335, 8, 332, 8, 332, 56, 332, 45, 5, + 344, 147, 49, 50, 146, 344, 151, 54, 134, 56, + 420, 355, 146, 110, 149, 133, 63, 135, 136, 137, + 138, 139, 140, 120, 148, 150, 132, 74, 75, 148, + 148, 153, 132, 148, 81, 148, 147, 3, 148, 136, + 137, 148, 139, 148, 141, 3, 148, 5, 6, 7, + 147, 132, 148, 148, 148, 148, 148, 148, 105, 106, + 107, 108, 148, 148, 111, 148, 154, 8, 115, 148, + 148, 134, 146, 150, 69, 122, 146, 124, 146, 146, + 8, 5, 129, 130, 4, 133, 134, 135, 136, 137, + 138, 139, 140, 148, 148, 53, 148, 148, 148, 148, + 20, 146, 22, 442, 151, 442, 113, 442, 28, 146, + 148, 151, 32, 3, 149, 5, 6, 7, 8, 461, + 147, 132, 151, 148, 134, 45, 148, 471, 148, 49, + 50, 331, 21, 340, 54, 484, 56, 2, 480, 480, + 222, 490, 484, 63, 2, 204, 488, 2, 490, 220, + 492, -1, 110, -1, 74, 75, -1, 329, -1, 263, + -1, 81, 120, 53, -1, 3, 4, 5, 6, 7, + -1, -1, 3, -1, 5, 6, 7, -1, 136, 137, + -1, 139, 20, 141, 22, 105, 106, 107, 108, 147, + 28, 111, -1, -1, 32, 115, -1, -1, -1, -1, + -1, -1, 122, -1, 124, -1, -1, 45, -1, 129, + 130, 49, 50, 11, 12, 53, 54, -1, 56, -1, + 110, -1, 53, -1, -1, 63, -1, -1, -1, -1, + 120, 151, 11, 12, -1, -1, 74, 75, -1, -1, + -1, -1, -1, 81, -1, -1, 136, 137, -1, 139, + -1, 141, -1, -1, -1, -1, -1, 147, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 105, 106, 107, + 108, -1, 110, 111, -1, -1, -1, 115, -1, 110, + -1, -1, 120, -1, 122, 10, 124, -1, -1, 120, + -1, 129, 130, -1, -1, -1, -1, 32, 136, 137, + -1, 139, 37, 141, 29, 136, 137, 32, 139, 147, + 141, -1, 37, -1, 49, -1, 147, 52, 43, -1, + -1, -1, -1, -1, 49, -1, -1, 52, -1, -1, + -1, -1, -1, -1, 69, 133, -1, 135, 136, 137, + 138, 139, 140, -1, 69, 70, -1, -1, 4, -1, + 148, 76, -1, -1, 133, 134, 135, 136, 137, 138, + 139, 140, -1, -1, 20, -1, 22, -1, -1, -1, + -1, -1, 28, -1, -1, -1, 32, -1, -1, -1, + 115, -1, -1, -1, -1, -1, 121, 122, -1, 45, + 115, -1, -1, 49, 50, -1, 121, 122, 54, -1, + 56, -1, -1, -1, -1, -1, -1, 63, -1, -1, + -1, 146, -1, -1, -1, 150, 151, -1, 74, 75, + 29, 146, -1, 32, -1, 81, 151, -1, 37, -1, + -1, -1, -1, -1, 43, -1, -1, -1, -1, -1, + 49, -1, -1, 52, -1, -1, -1, -1, -1, 105, + 106, 107, 108, -1, -1, 111, -1, -1, -1, 115, + 69, 70, 29, -1, -1, 32, 122, 76, 124, -1, + 37, -1, -1, 129, 130, -1, 43, -1, 32, -1, + -1, -1, 49, 37, -1, 52, -1, 32, -1, -1, + -1, -1, 37, -1, -1, 49, -1, -1, 52, -1, + -1, -1, 69, -1, 49, -1, 115, 52, -1, 76, + -1, -1, 121, 122, -1, 69, -1, -1, -1, -1, + -1, -1, -1, -1, 69, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 146, -1, -1, + -1, 150, 151, -1, -1, -1, -1, -1, 115, -1, + -1, -1, -1, -1, 121, 122, -1, -1, -1, -1, + -1, 115, -1, -1, -1, -1, -1, 121, 122, -1, + 115, -1, -1, -1, -1, -1, 121, 122, -1, 146, + -1, -1, -1, -1, 151, -1, -1, -1, -1, -1, + -1, -1, 146, -1, -1, -1, 150, 151, -1, -1, + -1, 146, -1, -1, -1, 150, 151, 13, -1, 15, + 16, -1, 18, 19, -1, -1, -1, -1, 24, -1, + 26, -1, -1, -1, -1, -1, -1, 33, 34, 35, + 36, -1, 38, 39, 40, 41, 42, -1, 44, -1, + 46, 47, 48, -1, -1, 51, -1, -1, -1, 55, + -1, 57, 58, 59, 60, 61, 62, -1, 64, 65, + 66, 67, 68, -1, -1, 71, -1, 73, -1, -1, + -1, -1, 78, -1, 80, -1, -1, -1, 84, 85, + 86, 87, 88, 89, 90, 91, 92, -1, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, 104, -1, + -1, -1, -1, 109, -1, -1, 112, -1, 114, -1, + -1, 117, 118, 119, -1, -1, -1, 123, -1, 125, + 126, 127, 128, -1, -1, 131 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const unsigned char yystos[] = { - 0, 154, 155, 0, 28, 31, 36, 42, 48, 51, - 68, 75, 114, 120, 121, 144, 149, 158, 159, 160, - 161, 164, 165, 173, 179, 183, 189, 200, 201, 202, - 205, 206, 209, 211, 212, 213, 214, 216, 217, 222, - 224, 225, 3, 4, 4, 19, 21, 27, 31, 44, - 48, 49, 53, 55, 62, 73, 74, 80, 104, 105, - 106, 107, 110, 114, 121, 123, 128, 129, 183, 197, - 199, 222, 223, 225, 145, 3, 4, 3, 4, 195, - 31, 7, 3, 4, 195, 172, 173, 195, 12, 14, - 15, 17, 18, 23, 25, 32, 33, 34, 35, 37, - 38, 39, 40, 41, 43, 45, 46, 47, 50, 54, - 56, 57, 58, 59, 60, 61, 63, 64, 65, 66, - 67, 70, 72, 77, 79, 83, 84, 85, 86, 87, - 88, 89, 90, 91, 93, 94, 95, 96, 97, 98, - 99, 100, 101, 102, 103, 108, 111, 113, 116, 117, - 118, 122, 124, 125, 126, 127, 130, 174, 175, 221, - 156, 156, 78, 82, 163, 200, 205, 211, 215, 144, - 144, 144, 144, 147, 144, 147, 144, 133, 210, 147, - 144, 144, 144, 223, 3, 73, 198, 198, 145, 198, - 199, 3, 3, 199, 3, 4, 15, 63, 76, 86, - 98, 103, 124, 127, 196, 7, 147, 223, 144, 147, - 223, 115, 147, 145, 145, 145, 145, 145, 145, 145, - 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, - 145, 145, 145, 145, 145, 145, 145, 131, 150, 9, - 69, 158, 162, 173, 200, 202, 213, 214, 217, 148, - 3, 3, 4, 147, 203, 92, 207, 3, 4, 147, - 157, 223, 151, 146, 180, 181, 182, 196, 196, 190, - 31, 138, 145, 196, 218, 219, 220, 145, 190, 196, - 3, 5, 6, 52, 109, 119, 136, 138, 140, 145, - 186, 187, 188, 7, 188, 7, 7, 7, 188, 188, - 7, 7, 188, 7, 188, 196, 55, 184, 185, 186, - 221, 188, 184, 186, 223, 223, 8, 5, 226, 223, - 175, 149, 145, 144, 148, 172, 204, 133, 81, 172, - 192, 208, 147, 157, 148, 158, 172, 193, 146, 188, - 148, 131, 151, 144, 148, 172, 173, 191, 192, 218, - 219, 219, 131, 192, 148, 146, 145, 186, 186, 186, - 186, 223, 10, 11, 132, 134, 135, 136, 137, 138, - 139, 131, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 3, 131, 146, 146, - 131, 146, 146, 146, 146, 146, 152, 146, 146, 175, - 7, 214, 133, 223, 144, 148, 193, 161, 148, 223, - 144, 182, 188, 225, 144, 144, 146, 219, 146, 223, - 146, 146, 186, 186, 186, 186, 186, 186, 186, 186, - 186, 188, 146, 185, 188, 5, 146, 219, 144, 157, - 112, 176, 144, 194, 196, 146, 186, 133, 146, 149, - 170, 148, 219, 147, 186, 138, 171, 185, 145, 177, - 150, 131, 150, 128, 166, 167, 168, 169, 173, 223, - 25, 37, 148, 178, 186, 149, 146, 131, 223, 219, - 186, 133, 186, 169, 219, 145, 170, 133, 191, 145, - 170, 166, 191, 166, 146, 146 + 0, 156, 157, 0, 29, 32, 37, 43, 49, 52, + 69, 76, 115, 121, 122, 146, 151, 160, 161, 162, + 163, 166, 167, 175, 183, 187, 193, 204, 205, 206, + 209, 210, 213, 215, 216, 217, 218, 220, 221, 226, + 228, 229, 3, 4, 4, 20, 22, 28, 32, 45, + 49, 50, 54, 56, 63, 74, 75, 81, 105, 106, + 107, 108, 111, 115, 122, 124, 129, 130, 187, 201, + 203, 226, 227, 229, 147, 3, 4, 3, 4, 199, + 32, 8, 3, 4, 199, 174, 175, 199, 13, 15, + 16, 18, 19, 24, 26, 33, 34, 35, 36, 38, + 39, 40, 41, 42, 44, 46, 47, 48, 51, 55, + 57, 58, 59, 60, 61, 62, 64, 65, 66, 67, + 68, 71, 73, 78, 80, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 94, 95, 96, 97, 98, 99, + 100, 101, 102, 103, 104, 109, 112, 114, 117, 118, + 119, 123, 125, 126, 127, 128, 131, 176, 178, 225, + 158, 158, 79, 83, 165, 204, 209, 215, 219, 146, + 146, 146, 146, 149, 146, 149, 146, 134, 214, 149, + 146, 146, 146, 227, 3, 74, 202, 202, 147, 202, + 203, 3, 3, 203, 3, 4, 200, 8, 149, 227, + 146, 149, 227, 116, 149, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 132, + 152, 10, 70, 160, 164, 175, 204, 206, 217, 218, + 221, 150, 3, 3, 4, 149, 207, 93, 211, 215, + 3, 4, 149, 159, 227, 153, 148, 184, 185, 186, + 200, 200, 194, 32, 139, 147, 200, 222, 223, 224, + 147, 194, 200, 3, 5, 6, 7, 53, 110, 120, + 136, 137, 139, 141, 147, 190, 191, 192, 8, 192, + 8, 8, 177, 8, 192, 192, 8, 8, 192, 8, + 192, 190, 56, 188, 189, 190, 225, 192, 188, 190, + 227, 227, 8, 9, 179, 5, 230, 227, 178, 151, + 147, 146, 150, 174, 208, 134, 82, 174, 196, 212, + 146, 149, 159, 150, 160, 174, 197, 148, 192, 150, + 132, 153, 146, 150, 174, 175, 195, 196, 222, 223, + 223, 132, 196, 150, 148, 147, 190, 190, 190, 190, + 190, 227, 11, 12, 133, 135, 136, 137, 138, 139, + 140, 132, 148, 148, 148, 148, 132, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 3, 132, 148, + 148, 132, 148, 148, 148, 148, 148, 154, 148, 148, + 178, 8, 218, 134, 227, 146, 150, 197, 150, 163, + 150, 227, 146, 186, 192, 229, 146, 146, 148, 223, + 148, 227, 148, 148, 190, 190, 190, 190, 190, 190, + 190, 190, 190, 192, 8, 148, 189, 192, 5, 148, + 223, 146, 159, 113, 180, 146, 198, 200, 148, 190, + 134, 148, 151, 172, 150, 223, 149, 190, 139, 173, + 189, 147, 181, 152, 132, 152, 129, 168, 169, 170, + 171, 175, 227, 26, 38, 150, 182, 190, 151, 148, + 132, 227, 223, 190, 134, 190, 171, 223, 147, 172, + 134, 195, 147, 172, 168, 195, 168, 148, 148 }; -#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) -# define YYSIZE_T __SIZE_TYPE__ -#endif -#if ! defined (YYSIZE_T) && defined (size_t) -# define YYSIZE_T size_t -#endif -#if ! defined (YYSIZE_T) -# if defined (__STDC__) || defined (__cplusplus) -# include /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# endif -#endif -#if ! defined (YYSIZE_T) -# define YYSIZE_T unsigned int -#endif - #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYEMPTY (-2) @@ -1372,7 +1472,8 @@ static const unsigned char yystos[] = #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab -#define YYERROR goto yyerrlab1 +#define YYERROR goto yyerrorlab + /* Like YYERROR except do call yyerror. This remains here temporarily to ease the transition to the new meaning of YYERROR, for GCC. @@ -1393,26 +1494,59 @@ do \ goto yybackup; \ } \ else \ - { \ - yyerror ("syntax error: cannot back up");\ + { \ + yyerror (YY_("syntax error: cannot back up")); \ YYERROR; \ } \ while (0) + #define YYTERROR 1 #define YYERRCODE 256 -/* YYLLOC_DEFAULT -- Compute the default location (before the actions - are run). */ +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + +#define YYRHSLOC(Rhs, K) ((Rhs)[K]) #ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - Current.first_line = Rhs[1].first_line; \ - Current.first_column = Rhs[1].first_column; \ - Current.last_line = Rhs[N].last_line; \ - Current.last_column = Rhs[N].last_column; +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (N) \ + { \ + (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ + } \ + else \ + { \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC (Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC (Rhs, 0).last_column; \ + } \ + while (0) #endif + +/* YY_LOCATION_PRINT -- Print the location on the stream. + This macro was not mandated originally: define only if we know + we won't break user code: when these are the locations we know. */ + +#ifndef YY_LOCATION_PRINT +# if YYLTYPE_IS_TRIVIAL +# define YY_LOCATION_PRINT(File, Loc) \ + fprintf (File, "%d.%d-%d.%d", \ + (Loc).first_line, (Loc).first_column, \ + (Loc).last_line, (Loc).last_column) +# else +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +# endif +#endif + + /* YYLEX -- calling `yylex' with the right arguments. */ #ifdef YYLEX_PARAM @@ -1435,36 +1569,30 @@ do { \ YYFPRINTF Args; \ } while (0) -# define YYDSYMPRINT(Args) \ -do { \ - if (yydebug) \ - yysymprint Args; \ -} while (0) - -# define YYDSYMPRINTF(Title, Token, Value, Location) \ +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ - yysymprint (stderr, \ - Token, Value); \ + yysymprint (stderr, \ + Type, Value); \ YYFPRINTF (stderr, "\n"); \ } \ } while (0) /*------------------------------------------------------------------. | yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (cinluded). | +| TOP (included). | `------------------------------------------------------------------*/ #if defined (__STDC__) || defined (__cplusplus) static void -yy_stack_print (short *bottom, short *top) +yy_stack_print (short int *bottom, short int *top) #else static void yy_stack_print (bottom, top) - short *bottom; - short *top; + short int *bottom; + short int *top; #endif { YYFPRINTF (stderr, "Stack now"); @@ -1494,13 +1622,13 @@ yy_reduce_print (yyrule) #endif { int yyi; - unsigned int yylineno = yyrline[yyrule]; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ", - yyrule - 1, yylineno); + unsigned long int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu), ", + yyrule - 1, yylno); /* Print the symbols being reduced, and their result. */ for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) - YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]); - YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]); + YYFPRINTF (stderr, "%s ", yytname[yyrhs[yyi]]); + YYFPRINTF (stderr, "-> %s\n", yytname[yyr1[yyrule]]); } # define YY_REDUCE_PRINT(Rule) \ @@ -1514,8 +1642,7 @@ do { \ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) -# define YYDSYMPRINT(Args) -# define YYDSYMPRINTF(Title, Token, Value, Location) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ @@ -1530,13 +1657,9 @@ int yydebug; if the built-in stack extension method is used). Do not make this value too large; the results are undefined if - SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ -#if YYMAXDEPTH == 0 -# undef YYMAXDEPTH -#endif - #ifndef YYMAXDEPTH # define YYMAXDEPTH 10000 #endif @@ -1558,7 +1681,7 @@ yystrlen (yystr) const char *yystr; # endif { - register const char *yys = yystr; + const char *yys = yystr; while (*yys++ != '\0') continue; @@ -1583,8 +1706,8 @@ yystpcpy (yydest, yysrc) const char *yysrc; # endif { - register char *yyd = yydest; - register const char *yys = yysrc; + char *yyd = yydest; + const char *yys = yysrc; while ((*yyd++ = *yys++) != '\0') continue; @@ -1594,7 +1717,55 @@ yystpcpy (yydest, yysrc) # endif # endif -#endif /* !YYERROR_VERBOSE */ +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + size_t yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return yystrlen (yystr); + + return yystpcpy (yyres, yystr) - yyres; +} +# endif + +#endif /* YYERROR_VERBOSE */ @@ -1618,15 +1789,15 @@ yysymprint (yyoutput, yytype, yyvaluep) (void) yyvaluep; if (yytype < YYNTOKENS) - { - YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); -# ifdef YYPRINT - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# endif - } + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); else YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# endif switch (yytype) { default: @@ -1642,10 +1813,11 @@ yysymprint (yyoutput, yytype, yyvaluep) #if defined (__STDC__) || defined (__cplusplus) static void -yydestruct (int yytype, YYSTYPE *yyvaluep) +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) #else static void -yydestruct (yytype, yyvaluep) +yydestruct (yymsg, yytype, yyvaluep) + const char *yymsg; int yytype; YYSTYPE *yyvaluep; #endif @@ -1653,6 +1825,10 @@ yydestruct (yytype, yyvaluep) /* Pacify ``unused variable'' warnings. */ (void) yyvaluep; + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + switch (yytype) { @@ -1680,10 +1856,10 @@ int yyparse (); -/* The lookahead symbol. */ +/* The look-ahead symbol. */ int yychar; -/* The semantic value of the lookahead symbol. */ +/* The semantic value of the look-ahead symbol. */ YYSTYPE yylval; /* Number of syntax errors so far. */ @@ -1709,17 +1885,17 @@ yyparse (void) #else int yyparse () - + ; #endif #endif { - - register int yystate; - register int yyn; + + int yystate; + int yyn; int yyresult; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; - /* Lookahead token as an internal (translated) token number. */ + /* Look-ahead token as an internal (translated) token number. */ int yytoken = 0; /* Three stacks and their tools: @@ -1731,14 +1907,14 @@ yyparse () to reallocate them elsewhere. */ /* The state stack. */ - short yyssa[YYINITDEPTH]; - short *yyss = yyssa; - register short *yyssp; + short int yyssa[YYINITDEPTH]; + short int *yyss = yyssa; + short int *yyssp; /* The semantic value stack. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs = yyvsa; - register YYSTYPE *yyvsp; + YYSTYPE *yyvsp; @@ -1795,14 +1971,14 @@ yyparse () these so that the &'s don't force the real ones into memory. */ YYSTYPE *yyvs1 = yyvs; - short *yyss1 = yyss; + short int *yyss1 = yyss; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ - yyoverflow ("parser stack overflow", + yyoverflow (YY_("memory exhausted"), &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), @@ -1813,21 +1989,21 @@ yyparse () } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE - goto yyoverflowlab; + goto yyexhaustedlab; # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) - goto yyoverflowlab; + goto yyexhaustedlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; { - short *yyss1 = yyss; + short int *yyss1 = yyss; union yyalloc *yyptr = (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) - goto yyoverflowlab; + goto yyexhaustedlab; YYSTACK_RELOCATE (yyss); YYSTACK_RELOCATE (yyvs); @@ -1859,18 +2035,18 @@ yyparse () yybackup: /* Do appropriate processing given the current state. */ -/* Read a lookahead token if we need one and don't already have one. */ +/* Read a look-ahead token if we need one and don't already have one. */ /* yyresume: */ - /* First try to decide what to do without reference to lookahead token. */ + /* First try to decide what to do without reference to look-ahead token. */ yyn = yypact[yystate]; if (yyn == YYPACT_NINF) goto yydefault; - /* Not known => get a lookahead token if don't already have one. */ + /* Not known => get a look-ahead token if don't already have one. */ - /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); @@ -1885,7 +2061,7 @@ yybackup: else { yytoken = YYTRANSLATE (yychar); - YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); } /* If the proper action on seeing token YYTOKEN is to reduce or to @@ -1905,8 +2081,8 @@ yybackup: if (yyn == YYFINAL) YYACCEPT; - /* Shift the lookahead token. */ - YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken])); + /* Shift the look-ahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); /* Discard the token being shifted unless it is eof. */ if (yychar != YYEOF) @@ -1956,1421 +2132,1498 @@ yyreduce: switch (yyn) { case 2: -#line 239 "parser.y" - { write_proxies(yyvsp[0].ifref); write_client(yyvsp[0].ifref); write_server(yyvsp[0].ifref); ;} +#line 285 "parser.y" + { fix_incomplete(); + check_all_user_types((yyvsp[0].ifref_list)); + write_proxies((yyvsp[0].ifref_list)); + write_client((yyvsp[0].ifref_list)); + write_server((yyvsp[0].ifref_list)); + write_dlldata((yyvsp[0].ifref_list)); + ;} break; case 3: -#line 242 "parser.y" - { yyval.ifref = NULL; ;} +#line 294 "parser.y" + { (yyval.ifref_list) = NULL; ;} break; case 4: -#line 243 "parser.y" - { yyval.ifref = yyvsp[-1].ifref; ;} +#line 295 "parser.y" + { (yyval.ifref_list) = (yyvsp[-1].ifref_list); ;} break; case 5: -#line 244 "parser.y" - { yyval.ifref = make_ifref(yyvsp[0].type); LINK(yyval.ifref, yyvsp[-1].ifref); ;} +#line 296 "parser.y" + { (yyval.ifref_list) = append_ifref( (yyvsp[-1].ifref_list), make_ifref((yyvsp[0].type)) ); ;} break; case 6: -#line 245 "parser.y" - { yyval.ifref = yyvsp[-2].ifref; - reg_type(yyvsp[-1].type, yyvsp[-1].type->name, 0); - if (!parse_only && do_header) write_coclass_forward(yyvsp[-1].type); +#line 297 "parser.y" + { (yyval.ifref_list) = (yyvsp[-2].ifref_list); + reg_type((yyvsp[-1].type), (yyvsp[-1].type)->name, 0); + if (!parse_only && do_header) write_coclass_forward((yyvsp[-1].type)); ;} break; case 7: -#line 249 "parser.y" - { yyval.ifref = yyvsp[-1].ifref; - add_coclass(yyvsp[0].type); - reg_type(yyvsp[0].type, yyvsp[0].type->name, 0); +#line 301 "parser.y" + { (yyval.ifref_list) = (yyvsp[-1].ifref_list); + add_typelib_entry((yyvsp[0].type)); + reg_type((yyvsp[0].type), (yyvsp[0].type)->name, 0); + if (!parse_only && do_header) write_coclass_forward((yyvsp[0].type)); ;} break; case 8: -#line 253 "parser.y" - { yyval.ifref = yyvsp[-1].ifref; add_module(yyvsp[0].type); ;} +#line 306 "parser.y" + { (yyval.ifref_list) = (yyvsp[-1].ifref_list); add_typelib_entry((yyvsp[0].type)); ;} break; case 9: -#line 254 "parser.y" - { yyval.ifref = yyvsp[-1].ifref; ;} +#line 307 "parser.y" + { (yyval.ifref_list) = (yyvsp[-1].ifref_list); ;} break; case 10: -#line 255 "parser.y" - { yyval.ifref = yyvsp[-1].ifref; ;} +#line 308 "parser.y" + { (yyval.ifref_list) = (yyvsp[-1].ifref_list); ;} break; case 11: -#line 258 "parser.y" +#line 311 "parser.y" {;} break; case 12: -#line 259 "parser.y" - { if (!parse_only) add_interface(yyvsp[0].type); ;} +#line 312 "parser.y" + { if (!parse_only) add_typelib_entry((yyvsp[0].type)); ;} break; case 13: -#line 260 "parser.y" - { if (!parse_only) add_interface(yyvsp[0].type); ;} +#line 313 "parser.y" + { if (!parse_only) add_typelib_entry((yyvsp[0].type)); ;} break; case 14: -#line 261 "parser.y" - { reg_type(yyvsp[-1].type, yyvsp[-1].type->name, 0); if (!parse_only && do_header) write_coclass_forward(yyvsp[-1].type); ;} +#line 314 "parser.y" + { reg_type((yyvsp[-1].type), (yyvsp[-1].type)->name, 0); if (!parse_only && do_header) write_coclass_forward((yyvsp[-1].type)); ;} break; case 15: -#line 262 "parser.y" - { if (!parse_only) add_coclass(yyvsp[0].type); - reg_type(yyvsp[0].type, yyvsp[0].type->name, 0); +#line 315 "parser.y" + { if (!parse_only) add_typelib_entry((yyvsp[0].type)); + reg_type((yyvsp[0].type), (yyvsp[0].type)->name, 0); + if (!parse_only && do_header) write_coclass_forward((yyvsp[0].type)); ;} break; case 16: -#line 265 "parser.y" - { if (!parse_only) add_module(yyvsp[0].type); ;} +#line 319 "parser.y" + { if (!parse_only) add_typelib_entry((yyvsp[0].type)); ;} break; case 17: -#line 266 "parser.y" +#line 320 "parser.y" {;} break; case 18: -#line 267 "parser.y" +#line 321 "parser.y" {;} break; case 19: -#line 270 "parser.y" - { yyval.func = NULL; ;} +#line 324 "parser.y" + { (yyval.func_list) = NULL; ;} break; case 20: -#line 271 "parser.y" - { yyval.func = yyvsp[-1].func; LINK(yyval.func, yyvsp[-2].func); ;} +#line 325 "parser.y" + { (yyval.func_list) = append_func( (yyvsp[-2].func_list), (yyvsp[-1].func) ); ;} break; case 21: -#line 272 "parser.y" - { yyval.func = yyvsp[-1].func; ;} +#line 326 "parser.y" + { (yyval.func_list) = (yyvsp[-1].func_list); ;} break; case 22: -#line 275 "parser.y" +#line 329 "parser.y" {;} break; case 23: -#line 276 "parser.y" - { if (!parse_only && do_header) { write_constdef(yyvsp[-1].var); } ;} +#line 330 "parser.y" + { if (!parse_only && do_header) { write_constdef((yyvsp[-1].var)); } ;} break; case 24: -#line 277 "parser.y" +#line 331 "parser.y" {;} break; case 25: -#line 278 "parser.y" - { if (!parse_only && do_header) { write_type(header, yyvsp[-1].type, NULL, NULL); fprintf(header, ";\n\n"); } ;} - break; - - case 26: -#line 279 "parser.y" - { if (!parse_only && do_header) { write_externdef(yyvsp[-1].var); } ;} - break; - - case 27: -#line 280 "parser.y" - {;} - break; - - case 28: -#line 281 "parser.y" - { if (!parse_only && do_header) { write_type(header, yyvsp[-1].type, NULL, NULL); fprintf(header, ";\n\n"); } ;} - break; - - case 29: -#line 282 "parser.y" - {;} - break; - - case 30: -#line 283 "parser.y" - { if (!parse_only && do_header) { write_type(header, yyvsp[-1].type, NULL, NULL); fprintf(header, ";\n\n"); } ;} - break; - - case 31: -#line 286 "parser.y" - { if (!parse_only && do_header) fprintf(header, "%s\n", yyvsp[-1].str); ;} - break; - - case 32: -#line 288 "parser.y" - { assert(yychar == YYEMPTY); - if (!do_import(yyvsp[-1].str)) yychar = aEOF; ;} - break; - - case 33: -#line 291 "parser.y" - {;} - break; - - case 34: -#line 294 "parser.y" - { if(!parse_only) add_importlib(yyvsp[-1].str); ;} - break; - - case 35: -#line 297 "parser.y" - { yyval.str = yyvsp[0].str; ;} - break; - - case 36: -#line 299 "parser.y" - { start_typelib(yyvsp[-1].str, yyvsp[-2].attr); - if (!parse_only && do_header) write_library(yyvsp[-1].str, yyvsp[-2].attr); ;} - break; - - case 37: -#line 302 "parser.y" - { end_typelib(); ;} - break; - - case 38: -#line 305 "parser.y" - { yyval.var = NULL; ;} - break; - - case 40: -#line 309 "parser.y" - { yyval.var = NULL; ;} - break; - - case 42: -#line 313 "parser.y" - { LINK(yyvsp[0].var, yyvsp[-2].var); yyval.var = yyvsp[0].var; ;} - break; - - case 44: -#line 318 "parser.y" - { yyval.var = yyvsp[-1].var; - set_type(yyval.var, yyvsp[-2].tref, yyvsp[0].expr); - yyval.var->attrs = yyvsp[-3].attr; - ;} - break; - - case 45: -#line 322 "parser.y" - { yyval.var = yyvsp[-1].var; - set_type(yyval.var, yyvsp[-2].tref, yyvsp[0].expr); - ;} - break; - - case 46: -#line 325 "parser.y" - { yyval.var = yyvsp[-3].var; - yyval.var->ptr_level--; - set_type(yyval.var, yyvsp[-4].tref, NULL); - yyval.var->attrs = yyvsp[-5].attr; - yyval.var->args = yyvsp[-1].var; - ;} - break; - - case 47: -#line 331 "parser.y" - { yyval.var = yyvsp[-3].var; - yyval.var->ptr_level--; - set_type(yyval.var, yyvsp[-4].tref, NULL); - yyval.var->args = yyvsp[-1].var; - ;} - break; - - case 48: -#line 338 "parser.y" - { yyval.expr = NULL; ;} - break; - - case 49: -#line 339 "parser.y" - { yyval.expr = yyvsp[-1].expr; ;} - break; - - case 50: -#line 340 "parser.y" - { yyval.expr = make_expr(EXPR_VOID); ;} - break; - - case 52: -#line 344 "parser.y" - { LINK(yyvsp[0].expr, yyvsp[-2].expr); yyval.expr = yyvsp[0].expr; ;} - break; - - case 53: -#line 345 "parser.y" - { LINK(yyvsp[0].expr, yyvsp[-3].expr); yyval.expr = yyvsp[0].expr; ;} - break; - - case 54: -#line 348 "parser.y" - { yyval.attr = NULL; ;} - break; - - case 56: -#line 353 "parser.y" - { yyval.attr = yyvsp[-1].attr; - if (!yyval.attr) - yyerror("empty attribute lists unsupported"); - ;} - break; - - case 58: -#line 360 "parser.y" - { if (yyvsp[0].attr) { LINK(yyvsp[0].attr, yyvsp[-2].attr); yyval.attr = yyvsp[0].attr; } - else { yyval.attr = yyvsp[-2].attr; } - ;} - break; - - case 59: -#line 363 "parser.y" - { if (yyvsp[0].attr) { LINK(yyvsp[0].attr, yyvsp[-3].attr); yyval.attr = yyvsp[0].attr; } - else { yyval.attr = yyvsp[-3].attr; } - ;} - break; - - case 60: -#line 368 "parser.y" - { yyval.attr = NULL; ;} - break; - - case 61: -#line 369 "parser.y" - { yyval.attr = make_attr(ATTR_AGGREGATABLE); ;} - break; - - case 62: -#line 370 "parser.y" - { yyval.attr = make_attr(ATTR_APPOBJECT); ;} - break; - - case 63: -#line 371 "parser.y" - { yyval.attr = make_attr(ATTR_ASYNC); ;} - break; - - case 64: -#line 372 "parser.y" - { yyval.attr = make_attr(ATTR_AUTO_HANDLE); ;} - break; - - case 65: -#line 373 "parser.y" - { yyval.attr = make_attr(ATTR_BINDABLE); ;} - break; - - case 66: -#line 374 "parser.y" - { yyval.attr = make_attrp(ATTR_CALLAS, yyvsp[-1].var); ;} - break; - - case 67: -#line 375 "parser.y" - { yyval.attr = make_attrp(ATTR_CASE, yyvsp[-1].expr); ;} - break; - - case 68: -#line 376 "parser.y" - { yyval.attr = make_attrv(ATTR_CONTEXTHANDLE, 0); ;} - break; - - case 69: -#line 377 "parser.y" - { yyval.attr = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_DONT_SERIALIZE */ ;} - break; - - case 70: -#line 378 "parser.y" - { yyval.attr = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_SERIALIZE */ ;} - break; - - case 71: -#line 379 "parser.y" - { yyval.attr = make_attr(ATTR_CONTROL); ;} - break; - - case 72: -#line 380 "parser.y" - { yyval.attr = make_attr(ATTR_DEFAULT); ;} - break; - - case 73: -#line 381 "parser.y" - { yyval.attr = make_attr(ATTR_DEFAULTCOLLELEM); ;} - break; - - case 74: -#line 382 "parser.y" - { yyval.attr = make_attrp(ATTR_DEFAULTVALUE_EXPR, yyvsp[-1].expr); ;} - break; - - case 75: -#line 383 "parser.y" - { yyval.attr = make_attrp(ATTR_DEFAULTVALUE_STRING, yyvsp[-1].str); ;} - break; - - case 76: -#line 384 "parser.y" - { yyval.attr = make_attr(ATTR_DEFAULTVTABLE); ;} - break; - - case 77: -#line 385 "parser.y" - { yyval.attr = make_attr(ATTR_DISPLAYBIND); ;} - break; - - case 78: -#line 386 "parser.y" - { yyval.attr = make_attrp(ATTR_DLLNAME, yyvsp[-1].str); ;} - break; - - case 79: -#line 387 "parser.y" - { yyval.attr = make_attr(ATTR_DUAL); ;} - break; - - case 80: -#line 388 "parser.y" - { yyval.attr = make_attrp(ATTR_ENDPOINT, yyvsp[-1].str); ;} - break; - - case 81: -#line 389 "parser.y" - { yyval.attr = make_attrp(ATTR_ENTRY_STRING, yyvsp[-1].str); ;} - break; - - case 82: -#line 390 "parser.y" - { yyval.attr = make_attrp(ATTR_ENTRY_ORDINAL, yyvsp[-1].expr); ;} - break; - - case 83: -#line 391 "parser.y" - { yyval.attr = make_attr(ATTR_EXPLICIT_HANDLE); ;} - break; - - case 84: -#line 392 "parser.y" - { yyval.attr = make_attr(ATTR_HANDLE); ;} - break; - - case 85: -#line 393 "parser.y" - { yyval.attr = make_attrp(ATTR_HELPCONTEXT, yyvsp[-1].expr); ;} - break; - - case 86: -#line 394 "parser.y" - { yyval.attr = make_attrp(ATTR_HELPFILE, yyvsp[-1].str); ;} - break; - - case 87: -#line 395 "parser.y" - { yyval.attr = make_attrp(ATTR_HELPSTRING, yyvsp[-1].str); ;} - break; - - case 88: -#line 396 "parser.y" - { yyval.attr = make_attrp(ATTR_HELPSTRINGCONTEXT, yyvsp[-1].expr); ;} - break; - - case 89: -#line 397 "parser.y" - { yyval.attr = make_attrp(ATTR_HELPSTRINGDLL, yyvsp[-1].str); ;} - break; - - case 90: -#line 398 "parser.y" - { yyval.attr = make_attr(ATTR_HIDDEN); ;} - break; - - case 91: -#line 399 "parser.y" - { yyval.attr = make_attrp(ATTR_ID, yyvsp[-1].expr); ;} - break; - - case 92: -#line 400 "parser.y" - { yyval.attr = make_attr(ATTR_IDEMPOTENT); ;} - break; - - case 93: -#line 401 "parser.y" - { yyval.attr = make_attrp(ATTR_IIDIS, yyvsp[-1].var); ;} - break; - - case 94: -#line 402 "parser.y" - { yyval.attr = make_attr(ATTR_IMMEDIATEBIND); ;} - break; - - case 95: -#line 403 "parser.y" - { yyval.attr = make_attrp(ATTR_IMPLICIT_HANDLE, yyvsp[-1].str); ;} - break; - - case 96: -#line 404 "parser.y" - { yyval.attr = make_attr(ATTR_IN); ;} - break; - - case 97: -#line 405 "parser.y" - { yyval.attr = make_attr(ATTR_INPUTSYNC); ;} - break; - - case 98: -#line 406 "parser.y" - { yyval.attr = make_attrp(ATTR_LENGTHIS, yyvsp[-1].expr); ;} - break; - - case 99: -#line 407 "parser.y" - { yyval.attr = make_attr(ATTR_LOCAL); ;} - break; - - case 100: -#line 408 "parser.y" - { yyval.attr = make_attr(ATTR_NONBROWSABLE); ;} - break; - - case 101: -#line 409 "parser.y" - { yyval.attr = make_attr(ATTR_NONCREATABLE); ;} - break; - - case 102: -#line 410 "parser.y" - { yyval.attr = make_attr(ATTR_NONEXTENSIBLE); ;} - break; - - case 103: -#line 411 "parser.y" - { yyval.attr = make_attr(ATTR_OBJECT); ;} - break; - - case 104: -#line 412 "parser.y" - { yyval.attr = make_attr(ATTR_ODL); ;} - break; - - case 105: -#line 413 "parser.y" - { yyval.attr = make_attr(ATTR_OLEAUTOMATION); ;} - break; - - case 106: -#line 414 "parser.y" - { yyval.attr = make_attr(ATTR_OPTIONAL); ;} - break; - - case 107: -#line 415 "parser.y" - { yyval.attr = make_attr(ATTR_OUT); ;} - break; - - case 108: -#line 416 "parser.y" - { yyval.attr = make_attrv(ATTR_POINTERDEFAULT, yyvsp[-1].num); ;} - break; - - case 109: -#line 417 "parser.y" - { yyval.attr = make_attr(ATTR_PROPGET); ;} - break; - - case 110: -#line 418 "parser.y" - { yyval.attr = make_attr(ATTR_PROPPUT); ;} - break; - - case 111: -#line 419 "parser.y" - { yyval.attr = make_attr(ATTR_PROPPUTREF); ;} - break; - - case 112: -#line 420 "parser.y" - { yyval.attr = make_attr(ATTR_PUBLIC); ;} - break; - - case 113: -#line 421 "parser.y" - { LINK(yyvsp[-1].expr, yyvsp[-3].expr); yyval.attr = make_attrp(ATTR_RANGE, yyvsp[-1].expr); ;} - break; - - case 114: -#line 422 "parser.y" - { yyval.attr = make_attr(ATTR_READONLY); ;} - break; - - case 115: -#line 423 "parser.y" - { yyval.attr = make_attr(ATTR_REQUESTEDIT); ;} - break; - - case 116: -#line 424 "parser.y" - { yyval.attr = make_attr(ATTR_RESTRICTED); ;} - break; - - case 117: -#line 425 "parser.y" - { yyval.attr = make_attr(ATTR_RETVAL); ;} - break; - - case 118: -#line 426 "parser.y" - { yyval.attr = make_attrp(ATTR_SIZEIS, yyvsp[-1].expr); ;} - break; - - case 119: -#line 427 "parser.y" - { yyval.attr = make_attr(ATTR_SOURCE); ;} - break; - - case 120: -#line 428 "parser.y" - { yyval.attr = make_attr(ATTR_STRING); ;} - break; - - case 121: -#line 429 "parser.y" - { yyval.attr = make_attrp(ATTR_SWITCHIS, yyvsp[-1].expr); ;} - break; - - case 122: -#line 430 "parser.y" - { yyval.attr = make_attrp(ATTR_SWITCHTYPE, type_ref(yyvsp[-1].tref)); ;} - break; - - case 123: -#line 431 "parser.y" - { yyval.attr = make_attrp(ATTR_TRANSMITAS, type_ref(yyvsp[-1].tref)); ;} - break; - - case 124: -#line 432 "parser.y" - { yyval.attr = make_attrp(ATTR_UUID, yyvsp[-1].uuid); ;} - break; - - case 125: -#line 433 "parser.y" - { yyval.attr = make_attr(ATTR_V1ENUM); ;} - break; - - case 126: -#line 434 "parser.y" - { yyval.attr = make_attr(ATTR_VARARG); ;} - break; - - case 127: -#line 435 "parser.y" - { yyval.attr = make_attrv(ATTR_VERSION, yyvsp[-1].num); ;} - break; - - case 128: -#line 436 "parser.y" - { yyval.attr = make_attrp(ATTR_WIREMARSHAL, type_ref(yyvsp[-1].tref)); ;} - break; - - case 129: -#line 437 "parser.y" - { yyval.attr = make_attrv(ATTR_POINTERTYPE, yyvsp[0].num); ;} - break; - - case 132: -#line 444 "parser.y" - { yyval.var = NULL; ;} - break; - - case 133: -#line 445 "parser.y" - { if (yyvsp[0].var) { LINK(yyvsp[0].var, yyvsp[-1].var); yyval.var = yyvsp[0].var; } - else { yyval.var = yyvsp[-1].var; } - ;} - break; - - case 134: -#line 450 "parser.y" - { attr_t *a = make_attrp(ATTR_CASE, yyvsp[-2].expr); - yyval.var = yyvsp[0].var; if (!yyval.var) yyval.var = make_var(NULL); - LINK(a, yyval.var->attrs); yyval.var->attrs = a; - ;} - break; - - case 135: -#line 454 "parser.y" - { attr_t *a = make_attr(ATTR_DEFAULT); - yyval.var = yyvsp[0].var; if (!yyval.var) yyval.var = make_var(NULL); - LINK(a, yyval.var->attrs); yyval.var->attrs = a; - ;} - break; - - case 136: -#line 460 "parser.y" - { yyval.var = reg_const(yyvsp[-2].var); - set_type(yyval.var, yyvsp[-3].tref, NULL); - yyval.var->eval = yyvsp[0].expr; - ;} - break; - - case 137: -#line 466 "parser.y" - { yyval.var = NULL; ;} - break; - - case 138: -#line 467 "parser.y" - { yyval.var = yyvsp[-1].var; ;} - break; - - case 140: -#line 471 "parser.y" - { if (!yyval.var->eval) - yyval.var->eval = make_exprl(EXPR_NUM, 0 /* default for first enum entry */); - ;} - break; - - case 141: -#line 474 "parser.y" - { LINK(yyvsp[0].var, yyvsp[-2].var); yyval.var = yyvsp[0].var; - if (!yyval.var->eval) - yyval.var->eval = make_exprl(EXPR_NUM, yyvsp[-2].var->eval->cval + 1); - ;} - break; - - case 142: -#line 480 "parser.y" - { yyval.var = reg_const(yyvsp[-2].var); - yyval.var->eval = yyvsp[0].expr; - yyval.var->type = make_type(RPC_FC_LONG, &std_int); - ;} - break; - - case 143: -#line 484 "parser.y" - { yyval.var = reg_const(yyvsp[0].var); - yyval.var->type = make_type(RPC_FC_LONG, &std_int); - ;} - break; - - case 144: -#line 489 "parser.y" - { yyval.type = get_typev(RPC_FC_ENUM16, yyvsp[-3].var, tsENUM); - yyval.type->fields = yyvsp[-1].var; - yyval.type->defined = TRUE; - if(in_typelib) - add_enum(yyval.type); - ;} - break; - - case 146: -#line 498 "parser.y" - { LINK(yyvsp[0].expr, yyvsp[-2].expr); yyval.expr = yyvsp[0].expr; ;} - break; - - case 147: -#line 511 "parser.y" - { yyval.expr = make_expr(EXPR_VOID); ;} - break; - - case 149: -#line 515 "parser.y" - { yyval.expr = make_exprl(EXPR_NUM, yyvsp[0].num); ;} - break; - - case 150: -#line 516 "parser.y" - { yyval.expr = make_exprl(EXPR_HEXNUM, yyvsp[0].num); ;} - break; - - case 151: -#line 517 "parser.y" - { yyval.expr = make_exprl(EXPR_TRUEFALSE, 0); ;} - break; - - case 152: -#line 518 "parser.y" - { yyval.expr = make_exprl(EXPR_TRUEFALSE, 1); ;} - break; - - case 153: -#line 519 "parser.y" - { yyval.expr = make_exprs(EXPR_IDENTIFIER, yyvsp[0].str); ;} - break; - - case 154: -#line 520 "parser.y" - { yyval.expr = make_expr3(EXPR_COND, yyvsp[-4].expr, yyvsp[-2].expr, yyvsp[0].expr); ;} - break; - - case 155: -#line 521 "parser.y" - { yyval.expr = make_expr2(EXPR_OR , yyvsp[-2].expr, yyvsp[0].expr); ;} - break; - - case 156: -#line 522 "parser.y" - { yyval.expr = make_expr2(EXPR_AND, yyvsp[-2].expr, yyvsp[0].expr); ;} - break; - - case 157: -#line 523 "parser.y" - { yyval.expr = make_expr2(EXPR_ADD, yyvsp[-2].expr, yyvsp[0].expr); ;} - break; - - case 158: -#line 524 "parser.y" - { yyval.expr = make_expr2(EXPR_SUB, yyvsp[-2].expr, yyvsp[0].expr); ;} - break; - - case 159: -#line 525 "parser.y" - { yyval.expr = make_expr2(EXPR_MUL, yyvsp[-2].expr, yyvsp[0].expr); ;} - break; - - case 160: -#line 526 "parser.y" - { yyval.expr = make_expr2(EXPR_DIV, yyvsp[-2].expr, yyvsp[0].expr); ;} - break; - - case 161: -#line 527 "parser.y" - { yyval.expr = make_expr2(EXPR_SHL, yyvsp[-2].expr, yyvsp[0].expr); ;} - break; - - case 162: -#line 528 "parser.y" - { yyval.expr = make_expr2(EXPR_SHR, yyvsp[-2].expr, yyvsp[0].expr); ;} - break; - - case 163: -#line 529 "parser.y" - { yyval.expr = make_expr1(EXPR_NOT, yyvsp[0].expr); ;} - break; - - case 164: -#line 530 "parser.y" - { yyval.expr = make_expr1(EXPR_NEG, yyvsp[0].expr); ;} - break; - - case 165: -#line 531 "parser.y" - { yyval.expr = make_expr1(EXPR_PPTR, yyvsp[0].expr); ;} - break; - - case 166: -#line 532 "parser.y" - { yyval.expr = make_exprt(EXPR_CAST, yyvsp[-2].tref, yyvsp[0].expr); ;} - break; - - case 167: -#line 533 "parser.y" - { yyval.expr = make_exprt(EXPR_SIZEOF, yyvsp[-1].tref, NULL); ;} - break; - - case 168: -#line 534 "parser.y" - { yyval.expr = yyvsp[-1].expr; ;} - break; - - case 170: -#line 538 "parser.y" - { LINK(yyvsp[0].expr, yyvsp[-2].expr); yyval.expr = yyvsp[0].expr; ;} - break; - - case 171: -#line 541 "parser.y" - { yyval.expr = yyvsp[0].expr; - if (!yyval.expr->is_const) - yyerror("expression is not constant"); - ;} - break; - - case 172: -#line 547 "parser.y" - { yyval.var = yyvsp[0].var; - set_type(yyval.var, yyvsp[-1].tref, NULL); - ;} - break; - - case 173: -#line 552 "parser.y" - { yyval.var = NULL; ;} - break; - - case 174: -#line 553 "parser.y" - { if (yyvsp[0].var) { LINK(yyvsp[0].var, yyvsp[-1].var); yyval.var = yyvsp[0].var; } - else { yyval.var = yyvsp[-1].var; } - ;} - break; - - case 175: -#line 558 "parser.y" - { yyval.var = yyvsp[-1].var; ;} - break; - - case 176: -#line 559 "parser.y" - { yyval.var = make_var(NULL); yyval.var->type = yyvsp[-1].type; yyval.var->attrs = yyvsp[-2].attr; ;} - break; - - case 177: -#line 560 "parser.y" - { yyval.var = make_var(NULL); yyval.var->attrs = yyvsp[-1].attr; ;} - break; - - case 178: -#line 561 "parser.y" - { yyval.var = NULL; ;} - break; - - case 179: -#line 564 "parser.y" - { yyval.var = yyvsp[-1].var; set_type(yyval.var, yyvsp[-2].tref, yyvsp[0].expr); yyval.var->attrs = yyvsp[-3].attr; ;} - break; - - case 180: -#line 569 "parser.y" - { set_type(yyvsp[-3].var, yyvsp[-5].tref, NULL); - yyvsp[-3].var->attrs = yyvsp[-6].attr; - yyval.func = make_func(yyvsp[-3].var, yyvsp[-1].var); - if (is_attr(yyvsp[-3].var->attrs, ATTR_IN)) { - yyerror("inapplicable attribute [in] for function '%s'",yyval.func->def->name); +#line 332 "parser.y" + { if (!parse_only && do_header) { + write_type_def_or_decl(header, (yyvsp[-1].type), FALSE, NULL); + fprintf(header, ";\n\n"); } ;} break; + case 26: +#line 337 "parser.y" + { if (!parse_only && do_header) { write_externdef((yyvsp[-1].var)); } ;} + break; + + case 27: +#line 338 "parser.y" + {;} + break; + + case 28: +#line 339 "parser.y" + { if (!parse_only && do_header) { + write_type_def_or_decl(header, (yyvsp[-1].type), FALSE, NULL); + fprintf(header, ";\n\n"); + } + ;} + break; + + case 29: +#line 344 "parser.y" + {;} + break; + + case 30: +#line 345 "parser.y" + { if (!parse_only && do_header) { + write_type_def_or_decl(header, (yyvsp[-1].type), FALSE, NULL); + fprintf(header, ";\n\n"); + } + ;} + break; + + case 31: +#line 352 "parser.y" + { if (!parse_only && do_header) fprintf(header, "%s\n", (yyvsp[-1].str)); ;} + break; + + case 32: +#line 354 "parser.y" + { assert(yychar == YYEMPTY); + if (!do_import((yyvsp[-1].str))) yychar = aEOF; ;} + break; + + case 33: +#line 357 "parser.y" + {;} + break; + + case 34: +#line 360 "parser.y" + { if(!parse_only) add_importlib((yyvsp[-1].str)); ;} + break; + + case 35: +#line 363 "parser.y" + { (yyval.str) = (yyvsp[0].str); ;} + break; + + case 36: +#line 365 "parser.y" + { start_typelib((yyvsp[-1].str), (yyvsp[-2].attr_list)); + if (!parse_only && do_header) write_library((yyvsp[-1].str), (yyvsp[-2].attr_list)); + if (!parse_only && do_idfile) write_libid((yyvsp[-1].str), (yyvsp[-2].attr_list)); + ;} + break; + + case 37: +#line 370 "parser.y" + { end_typelib(); ;} + break; + + case 38: +#line 373 "parser.y" + { (yyval.var_list) = NULL; ;} + break; + + case 40: +#line 377 "parser.y" + { (yyval.var_list) = NULL; ;} + break; + + case 41: +#line 380 "parser.y" + { check_arg((yyvsp[0].var)); (yyval.var_list) = append_var( NULL, (yyvsp[0].var) ); ;} + break; + + case 42: +#line 381 "parser.y" + { check_arg((yyvsp[0].var)); (yyval.var_list) = append_var( (yyvsp[-2].var_list), (yyvsp[0].var)); ;} + break; + + case 44: +#line 386 "parser.y" + { (yyval.var) = (yyvsp[-1].pident)->var; + (yyval.var)->attrs = (yyvsp[-3].attr_list); + set_type((yyval.var), (yyvsp[-2].type), (yyvsp[-1].pident)->ptr_level, (yyvsp[0].array_dims), TRUE); + free((yyvsp[-1].pident)); + ;} + break; + + case 45: +#line 391 "parser.y" + { (yyval.var) = (yyvsp[-1].pident)->var; + set_type((yyval.var), (yyvsp[-2].type), (yyvsp[-1].pident)->ptr_level, (yyvsp[0].array_dims), TRUE); + free((yyvsp[-1].pident)); + ;} + break; + + case 46: +#line 395 "parser.y" + { (yyval.var) = (yyvsp[-3].pident)->var; + (yyval.var)->attrs = (yyvsp[-5].attr_list); + set_type((yyval.var), (yyvsp[-4].type), (yyvsp[-3].pident)->ptr_level - 1, NULL, TRUE); + free((yyvsp[-3].pident)); + (yyval.var)->args = (yyvsp[-1].var_list); + ;} + break; + + case 47: +#line 401 "parser.y" + { (yyval.var) = (yyvsp[-3].pident)->var; + set_type((yyval.var), (yyvsp[-4].type), (yyvsp[-3].pident)->ptr_level - 1, NULL, TRUE); + free((yyvsp[-3].pident)); + (yyval.var)->args = (yyvsp[-1].var_list); + ;} + break; + + case 48: +#line 408 "parser.y" + { (yyval.array_dims) = NULL; ;} + break; + + case 49: +#line 409 "parser.y" + { (yyval.array_dims) = (yyvsp[-1].array_dims); ;} + break; + + case 50: +#line 410 "parser.y" + { (yyval.array_dims) = append_array( NULL, make_expr(EXPR_VOID) ); ;} + break; + + case 51: +#line 413 "parser.y" + { (yyval.array_dims) = append_array( NULL, (yyvsp[0].expr) ); ;} + break; + + case 52: +#line 414 "parser.y" + { (yyval.array_dims) = append_array( (yyvsp[-2].array_dims), (yyvsp[0].expr) ); ;} + break; + + case 53: +#line 415 "parser.y" + { (yyval.array_dims) = append_array( (yyvsp[-3].array_dims), (yyvsp[0].expr) ); ;} + break; + + case 54: +#line 418 "parser.y" + { (yyval.attr_list) = NULL; ;} + break; + + case 56: +#line 423 "parser.y" + { (yyval.attr_list) = (yyvsp[-1].attr_list); + if (!(yyval.attr_list)) + error_loc("empty attribute lists unsupported\n"); + ;} + break; + + case 57: +#line 429 "parser.y" + { (yyval.attr_list) = append_attr( NULL, (yyvsp[0].attr) ); ;} + break; + + case 58: +#line 430 "parser.y" + { (yyval.attr_list) = append_attr( (yyvsp[-2].attr_list), (yyvsp[0].attr) ); ;} + break; + + case 59: +#line 431 "parser.y" + { (yyval.attr_list) = append_attr( (yyvsp[-3].attr_list), (yyvsp[0].attr) ); ;} + break; + + case 60: +#line 434 "parser.y" + { (yyval.str_list) = append_str( NULL, (yyvsp[0].str) ); ;} + break; + + case 61: +#line 435 "parser.y" + { (yyval.str_list) = append_str( (yyvsp[-2].str_list), (yyvsp[0].str) ); ;} + break; + + case 62: +#line 438 "parser.y" + { (yyval.attr) = NULL; ;} + break; + + case 63: +#line 439 "parser.y" + { (yyval.attr) = make_attr(ATTR_AGGREGATABLE); ;} + break; + + case 64: +#line 440 "parser.y" + { (yyval.attr) = make_attr(ATTR_APPOBJECT); ;} + break; + + case 65: +#line 441 "parser.y" + { (yyval.attr) = make_attr(ATTR_ASYNC); ;} + break; + + case 66: +#line 442 "parser.y" + { (yyval.attr) = make_attr(ATTR_AUTO_HANDLE); ;} + break; + + case 67: +#line 443 "parser.y" + { (yyval.attr) = make_attr(ATTR_BINDABLE); ;} + break; + + case 68: +#line 444 "parser.y" + { (yyval.attr) = make_attrp(ATTR_CALLAS, (yyvsp[-1].var)); ;} + break; + + case 69: +#line 445 "parser.y" + { (yyval.attr) = make_attrp(ATTR_CASE, (yyvsp[-1].expr_list)); ;} + break; + + case 70: +#line 446 "parser.y" + { (yyval.attr) = make_attrv(ATTR_CONTEXTHANDLE, 0); ;} + break; + + case 71: +#line 447 "parser.y" + { (yyval.attr) = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_DONT_SERIALIZE */ ;} + break; + + case 72: +#line 448 "parser.y" + { (yyval.attr) = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_SERIALIZE */ ;} + break; + + case 73: +#line 449 "parser.y" + { (yyval.attr) = make_attr(ATTR_CONTROL); ;} + break; + + case 74: +#line 450 "parser.y" + { (yyval.attr) = make_attr(ATTR_DEFAULT); ;} + break; + + case 75: +#line 451 "parser.y" + { (yyval.attr) = make_attr(ATTR_DEFAULTCOLLELEM); ;} + break; + + case 76: +#line 452 "parser.y" + { (yyval.attr) = make_attrp(ATTR_DEFAULTVALUE_EXPR, (yyvsp[-1].expr)); ;} + break; + + case 77: +#line 453 "parser.y" + { (yyval.attr) = make_attrp(ATTR_DEFAULTVALUE_STRING, (yyvsp[-1].str)); ;} + break; + + case 78: +#line 454 "parser.y" + { (yyval.attr) = make_attr(ATTR_DEFAULTVTABLE); ;} + break; + + case 79: +#line 455 "parser.y" + { (yyval.attr) = make_attr(ATTR_DISPLAYBIND); ;} + break; + + case 80: +#line 456 "parser.y" + { (yyval.attr) = make_attrp(ATTR_DLLNAME, (yyvsp[-1].str)); ;} + break; + + case 81: +#line 457 "parser.y" + { (yyval.attr) = make_attr(ATTR_DUAL); ;} + break; + + case 82: +#line 458 "parser.y" + { (yyval.attr) = make_attrp(ATTR_ENDPOINT, (yyvsp[-1].str_list)); ;} + break; + + case 83: +#line 459 "parser.y" + { (yyval.attr) = make_attrp(ATTR_ENTRY_STRING, (yyvsp[-1].str)); ;} + break; + + case 84: +#line 460 "parser.y" + { (yyval.attr) = make_attrp(ATTR_ENTRY_ORDINAL, (yyvsp[-1].expr)); ;} + break; + + case 85: +#line 461 "parser.y" + { (yyval.attr) = make_attr(ATTR_EXPLICIT_HANDLE); ;} + break; + + case 86: +#line 462 "parser.y" + { (yyval.attr) = make_attr(ATTR_HANDLE); ;} + break; + + case 87: +#line 463 "parser.y" + { (yyval.attr) = make_attrp(ATTR_HELPCONTEXT, (yyvsp[-1].expr)); ;} + break; + + case 88: +#line 464 "parser.y" + { (yyval.attr) = make_attrp(ATTR_HELPFILE, (yyvsp[-1].str)); ;} + break; + + case 89: +#line 465 "parser.y" + { (yyval.attr) = make_attrp(ATTR_HELPSTRING, (yyvsp[-1].str)); ;} + break; + + case 90: +#line 466 "parser.y" + { (yyval.attr) = make_attrp(ATTR_HELPSTRINGCONTEXT, (yyvsp[-1].expr)); ;} + break; + + case 91: +#line 467 "parser.y" + { (yyval.attr) = make_attrp(ATTR_HELPSTRINGDLL, (yyvsp[-1].str)); ;} + break; + + case 92: +#line 468 "parser.y" + { (yyval.attr) = make_attr(ATTR_HIDDEN); ;} + break; + + case 93: +#line 469 "parser.y" + { (yyval.attr) = make_attrp(ATTR_ID, (yyvsp[-1].expr)); ;} + break; + + case 94: +#line 470 "parser.y" + { (yyval.attr) = make_attr(ATTR_IDEMPOTENT); ;} + break; + + case 95: +#line 471 "parser.y" + { (yyval.attr) = make_attrp(ATTR_IIDIS, (yyvsp[-1].expr)); ;} + break; + + case 96: +#line 472 "parser.y" + { (yyval.attr) = make_attr(ATTR_IMMEDIATEBIND); ;} + break; + + case 97: +#line 473 "parser.y" + { (yyval.attr) = make_attrp(ATTR_IMPLICIT_HANDLE, (yyvsp[-1].str)); ;} + break; + + case 98: +#line 474 "parser.y" + { (yyval.attr) = make_attr(ATTR_IN); ;} + break; + + case 99: +#line 475 "parser.y" + { (yyval.attr) = make_attr(ATTR_INPUTSYNC); ;} + break; + + case 100: +#line 476 "parser.y" + { (yyval.attr) = make_attrp(ATTR_LENGTHIS, (yyvsp[-1].expr_list)); ;} + break; + + case 101: +#line 477 "parser.y" + { (yyval.attr) = make_attr(ATTR_LOCAL); ;} + break; + + case 102: +#line 478 "parser.y" + { (yyval.attr) = make_attr(ATTR_NONBROWSABLE); ;} + break; + + case 103: +#line 479 "parser.y" + { (yyval.attr) = make_attr(ATTR_NONCREATABLE); ;} + break; + + case 104: +#line 480 "parser.y" + { (yyval.attr) = make_attr(ATTR_NONEXTENSIBLE); ;} + break; + + case 105: +#line 481 "parser.y" + { (yyval.attr) = make_attr(ATTR_OBJECT); ;} + break; + + case 106: +#line 482 "parser.y" + { (yyval.attr) = make_attr(ATTR_ODL); ;} + break; + + case 107: +#line 483 "parser.y" + { (yyval.attr) = make_attr(ATTR_OLEAUTOMATION); ;} + break; + + case 108: +#line 484 "parser.y" + { (yyval.attr) = make_attr(ATTR_OPTIONAL); ;} + break; + + case 109: +#line 485 "parser.y" + { (yyval.attr) = make_attr(ATTR_OUT); ;} + break; + + case 110: +#line 486 "parser.y" + { (yyval.attr) = make_attrv(ATTR_POINTERDEFAULT, (yyvsp[-1].num)); ;} + break; + + case 111: +#line 487 "parser.y" + { (yyval.attr) = make_attr(ATTR_PROPGET); ;} + break; + + case 112: +#line 488 "parser.y" + { (yyval.attr) = make_attr(ATTR_PROPPUT); ;} + break; + + case 113: +#line 489 "parser.y" + { (yyval.attr) = make_attr(ATTR_PROPPUTREF); ;} + break; + + case 114: +#line 490 "parser.y" + { (yyval.attr) = make_attr(ATTR_PUBLIC); ;} + break; + + case 115: +#line 491 "parser.y" + { expr_list_t *list = append_expr( NULL, (yyvsp[-3].expr) ); + list = append_expr( list, (yyvsp[-1].expr) ); + (yyval.attr) = make_attrp(ATTR_RANGE, list); ;} + break; + + case 116: +#line 494 "parser.y" + { (yyval.attr) = make_attr(ATTR_READONLY); ;} + break; + + case 117: +#line 495 "parser.y" + { (yyval.attr) = make_attr(ATTR_REQUESTEDIT); ;} + break; + + case 118: +#line 496 "parser.y" + { (yyval.attr) = make_attr(ATTR_RESTRICTED); ;} + break; + + case 119: +#line 497 "parser.y" + { (yyval.attr) = make_attr(ATTR_RETVAL); ;} + break; + + case 120: +#line 498 "parser.y" + { (yyval.attr) = make_attrp(ATTR_SIZEIS, (yyvsp[-1].expr_list)); ;} + break; + + case 121: +#line 499 "parser.y" + { (yyval.attr) = make_attr(ATTR_SOURCE); ;} + break; + + case 122: +#line 500 "parser.y" + { (yyval.attr) = make_attr(ATTR_STRING); ;} + break; + + case 123: +#line 501 "parser.y" + { (yyval.attr) = make_attrp(ATTR_SWITCHIS, (yyvsp[-1].expr)); ;} + break; + + case 124: +#line 502 "parser.y" + { (yyval.attr) = make_attrp(ATTR_SWITCHTYPE, (yyvsp[-1].type)); ;} + break; + + case 125: +#line 503 "parser.y" + { (yyval.attr) = make_attrp(ATTR_TRANSMITAS, (yyvsp[-1].type)); ;} + break; + + case 126: +#line 504 "parser.y" + { (yyval.attr) = make_attrp(ATTR_UUID, (yyvsp[-1].uuid)); ;} + break; + + case 127: +#line 505 "parser.y" + { (yyval.attr) = make_attr(ATTR_V1ENUM); ;} + break; + + case 128: +#line 506 "parser.y" + { (yyval.attr) = make_attr(ATTR_VARARG); ;} + break; + + case 129: +#line 507 "parser.y" + { (yyval.attr) = make_attrv(ATTR_VERSION, (yyvsp[-1].num)); ;} + break; + + case 130: +#line 508 "parser.y" + { (yyval.attr) = make_attrp(ATTR_WIREMARSHAL, (yyvsp[-1].type)); ;} + break; + + case 131: +#line 509 "parser.y" + { (yyval.attr) = make_attrv(ATTR_POINTERTYPE, (yyvsp[0].num)); ;} + break; + + case 133: +#line 514 "parser.y" + { if (!is_valid_uuid((yyvsp[0].str))) + error_loc("invalid UUID: %s\n", (yyvsp[0].str)); + (yyval.uuid) = parse_uuid((yyvsp[0].str)); ;} + break; + + case 136: +#line 523 "parser.y" + { (yyval.var_list) = NULL; ;} + break; + + case 137: +#line 524 "parser.y" + { (yyval.var_list) = append_var( (yyvsp[-1].var_list), (yyvsp[0].var) ); ;} + break; + + case 138: +#line 527 "parser.y" + { attr_t *a = make_attrp(ATTR_CASE, append_expr( NULL, (yyvsp[-2].expr) )); + (yyval.var) = (yyvsp[0].var); if (!(yyval.var)) (yyval.var) = make_var(NULL); + (yyval.var)->attrs = append_attr( (yyval.var)->attrs, a ); + ;} + break; + + case 139: +#line 531 "parser.y" + { attr_t *a = make_attr(ATTR_DEFAULT); + (yyval.var) = (yyvsp[0].var); if (!(yyval.var)) (yyval.var) = make_var(NULL); + (yyval.var)->attrs = append_attr( (yyval.var)->attrs, a ); + ;} + break; + + case 140: +#line 537 "parser.y" + { (yyval.var) = reg_const((yyvsp[-2].var)); + set_type((yyval.var), (yyvsp[-3].type), 0, NULL, FALSE); + (yyval.var)->eval = (yyvsp[0].expr); + ;} + break; + + case 141: +#line 543 "parser.y" + { (yyval.var_list) = NULL; ;} + break; + + case 142: +#line 544 "parser.y" + { (yyval.var_list) = (yyvsp[-1].var_list); ;} + break; + + case 144: +#line 548 "parser.y" + { if (!(yyvsp[0].var)->eval) + (yyvsp[0].var)->eval = make_exprl(EXPR_NUM, 0 /* default for first enum entry */); + (yyval.var_list) = append_var( NULL, (yyvsp[0].var) ); + ;} + break; + + case 145: +#line 552 "parser.y" + { if (!(yyvsp[0].var)->eval) + { + var_t *last = LIST_ENTRY( list_tail((yyval.var_list)), var_t, entry ); + (yyvsp[0].var)->eval = make_exprl(EXPR_NUM, last->eval->cval + 1); + } + (yyval.var_list) = append_var( (yyvsp[-2].var_list), (yyvsp[0].var) ); + ;} + break; + + case 146: +#line 561 "parser.y" + { (yyval.var) = reg_const((yyvsp[-2].var)); + (yyval.var)->eval = (yyvsp[0].expr); + (yyval.var)->type = make_int(0); + ;} + break; + + case 147: +#line 565 "parser.y" + { (yyval.var) = reg_const((yyvsp[0].var)); + (yyval.var)->type = make_int(0); + ;} + break; + + case 148: +#line 570 "parser.y" + { (yyval.type) = get_typev(RPC_FC_ENUM16, (yyvsp[-3].var), tsENUM); + (yyval.type)->kind = TKIND_ENUM; + (yyval.type)->fields = (yyvsp[-1].var_list); + (yyval.type)->defined = TRUE; + if(in_typelib) + add_typelib_entry((yyval.type)); + ;} + break; + + case 149: +#line 579 "parser.y" + { (yyval.expr_list) = append_expr( NULL, (yyvsp[0].expr) ); ;} + break; + + case 150: +#line 580 "parser.y" + { (yyval.expr_list) = append_expr( (yyvsp[-2].expr_list), (yyvsp[0].expr) ); ;} + break; + + case 151: +#line 593 "parser.y" + { (yyval.expr) = make_expr(EXPR_VOID); ;} + break; + + case 153: +#line 597 "parser.y" + { (yyval.expr) = make_exprl(EXPR_NUM, (yyvsp[0].num)); ;} + break; + + case 154: +#line 598 "parser.y" + { (yyval.expr) = make_exprl(EXPR_HEXNUM, (yyvsp[0].num)); ;} + break; + + case 155: +#line 599 "parser.y" + { (yyval.expr) = make_exprd(EXPR_DOUBLE, (yyvsp[0].dbl)); ;} + break; + + case 156: +#line 600 "parser.y" + { (yyval.expr) = make_exprl(EXPR_TRUEFALSE, 0); ;} + break; + + case 157: +#line 601 "parser.y" + { (yyval.expr) = make_exprl(EXPR_TRUEFALSE, 1); ;} + break; + + case 158: +#line 602 "parser.y" + { (yyval.expr) = make_exprs(EXPR_IDENTIFIER, (yyvsp[0].str)); ;} + break; + + case 159: +#line 603 "parser.y" + { (yyval.expr) = make_expr3(EXPR_COND, (yyvsp[-4].expr), (yyvsp[-2].expr), (yyvsp[0].expr)); ;} + break; + + case 160: +#line 604 "parser.y" + { (yyval.expr) = make_expr2(EXPR_OR , (yyvsp[-2].expr), (yyvsp[0].expr)); ;} + break; + + case 161: +#line 605 "parser.y" + { (yyval.expr) = make_expr2(EXPR_AND, (yyvsp[-2].expr), (yyvsp[0].expr)); ;} + break; + + case 162: +#line 606 "parser.y" + { (yyval.expr) = make_expr2(EXPR_ADD, (yyvsp[-2].expr), (yyvsp[0].expr)); ;} + break; + + case 163: +#line 607 "parser.y" + { (yyval.expr) = make_expr2(EXPR_SUB, (yyvsp[-2].expr), (yyvsp[0].expr)); ;} + break; + + case 164: +#line 608 "parser.y" + { (yyval.expr) = make_expr2(EXPR_MUL, (yyvsp[-2].expr), (yyvsp[0].expr)); ;} + break; + + case 165: +#line 609 "parser.y" + { (yyval.expr) = make_expr2(EXPR_DIV, (yyvsp[-2].expr), (yyvsp[0].expr)); ;} + break; + + case 166: +#line 610 "parser.y" + { (yyval.expr) = make_expr2(EXPR_SHL, (yyvsp[-2].expr), (yyvsp[0].expr)); ;} + break; + + case 167: +#line 611 "parser.y" + { (yyval.expr) = make_expr2(EXPR_SHR, (yyvsp[-2].expr), (yyvsp[0].expr)); ;} + break; + + case 168: +#line 612 "parser.y" + { (yyval.expr) = make_expr1(EXPR_NOT, (yyvsp[0].expr)); ;} + break; + + case 169: +#line 613 "parser.y" + { (yyval.expr) = make_expr1(EXPR_NEG, (yyvsp[0].expr)); ;} + break; + + case 170: +#line 614 "parser.y" + { (yyval.expr) = make_expr1(EXPR_ADDRESSOF, (yyvsp[0].expr)); ;} + break; + + case 171: +#line 615 "parser.y" + { (yyval.expr) = make_expr1(EXPR_PPTR, (yyvsp[0].expr)); ;} + break; + + case 172: +#line 616 "parser.y" + { (yyval.expr) = make_exprt(EXPR_CAST, (yyvsp[-2].type), (yyvsp[0].expr)); ;} + break; + + case 173: +#line 617 "parser.y" + { (yyval.expr) = make_exprt(EXPR_SIZEOF, (yyvsp[-1].type), NULL); ;} + break; + + case 174: +#line 618 "parser.y" + { (yyval.expr) = (yyvsp[-1].expr); ;} + break; + + case 175: +#line 621 "parser.y" + { (yyval.expr_list) = append_expr( NULL, (yyvsp[0].expr) ); ;} + break; + + case 176: +#line 622 "parser.y" + { (yyval.expr_list) = append_expr( (yyvsp[-2].expr_list), (yyvsp[0].expr) ); ;} + break; + + case 177: +#line 625 "parser.y" + { (yyval.expr) = (yyvsp[0].expr); + if (!(yyval.expr)->is_const) + error_loc("expression is not constant\n"); + ;} + break; + + case 178: +#line 631 "parser.y" + { (yyval.var) = (yyvsp[0].var); + set_type((yyval.var), (yyvsp[-1].type), 0, NULL, FALSE); + ;} + break; + + case 179: +#line 636 "parser.y" + { (yyval.var_list) = NULL; ;} + break; + + case 180: +#line 637 "parser.y" + { (yyval.var_list) = append_var( (yyvsp[-1].var_list), (yyvsp[0].var) ); ;} + break; + case 181: -#line 578 "parser.y" - { yyval.var = NULL; ;} +#line 640 "parser.y" + { (yyval.var) = (yyvsp[-1].var); ;} + break; + + case 182: +#line 641 "parser.y" + { (yyval.var) = make_var(NULL); (yyval.var)->type = (yyvsp[-1].type); (yyval.var)->attrs = (yyvsp[-2].attr_list); ;} break; case 183: -#line 582 "parser.y" - { yyval.var = NULL; ;} +#line 642 "parser.y" + { (yyval.var) = make_var(NULL); (yyval.var)->attrs = (yyvsp[-1].attr_list); ;} break; case 184: -#line 583 "parser.y" - { yyval.var = make_var(yyvsp[0].str); ;} +#line 643 "parser.y" + { (yyval.var) = NULL; ;} break; case 185: -#line 584 "parser.y" - { yyval.var = make_var(yyvsp[0].str); ;} +#line 646 "parser.y" + { (yyval.var) = (yyvsp[-1].pident)->var; + (yyval.var)->attrs = (yyvsp[-3].attr_list); + set_type((yyval.var), (yyvsp[-2].type), (yyvsp[-1].pident)->ptr_level, (yyvsp[0].array_dims), FALSE); + free((yyvsp[-1].pident)); + ;} break; case 186: -#line 587 "parser.y" - { yyval.var = make_var(yyvsp[0].str); ;} +#line 655 "parser.y" + { var_t *v = (yyvsp[-3].pident)->var; + v->attrs = (yyvsp[-6].attr_list); + set_type(v, (yyvsp[-5].type), (yyvsp[-3].pident)->ptr_level, NULL, FALSE); + free((yyvsp[-3].pident)); + (yyval.func) = make_func(v, (yyvsp[-1].var_list)); + if (is_attr(v->attrs, ATTR_IN)) { + error_loc("inapplicable attribute [in] for function '%s'\n",(yyval.func)->def->name); + } + ;} break; case 187: -#line 589 "parser.y" - { yyval.var = make_var(yyvsp[0].str); ;} - break; - - case 188: -#line 590 "parser.y" - { yyval.var = make_var(yyvsp[0].str); ;} +#line 666 "parser.y" + { (yyval.var) = NULL; ;} break; case 189: -#line 591 "parser.y" - { yyval.var = make_var(yyvsp[0].str); ;} +#line 670 "parser.y" + { (yyval.var) = NULL; ;} break; case 190: -#line 592 "parser.y" - { yyval.var = make_var(yyvsp[0].str); ;} +#line 671 "parser.y" + { (yyval.var) = make_var((yyvsp[0].str)); ;} break; case 191: -#line 593 "parser.y" - { yyval.var = make_var(yyvsp[0].str); ;} +#line 672 "parser.y" + { (yyval.var) = make_var((yyvsp[0].str)); ;} break; case 192: -#line 594 "parser.y" - { yyval.var = make_var(yyvsp[0].str); ;} +#line 675 "parser.y" + { (yyval.var) = make_var((yyvsp[0].str)); ;} break; case 193: -#line 595 "parser.y" - { yyval.var = make_var(yyvsp[0].str); ;} +#line 677 "parser.y" + { (yyval.var) = make_var((yyvsp[0].str)); ;} break; case 194: -#line 596 "parser.y" - { yyval.var = make_var(yyvsp[0].str); ;} +#line 680 "parser.y" + { (yyval.type) = make_builtin((yyvsp[0].str)); ;} break; case 195: -#line 597 "parser.y" - { yyval.var = make_var(yyvsp[0].str); ;} - break; - - case 196: -#line 600 "parser.y" - { yyval.type = make_type(RPC_FC_BYTE, NULL); ;} +#line 681 "parser.y" + { (yyval.type) = make_builtin((yyvsp[0].str)); ;} break; case 197: -#line 601 "parser.y" - { yyval.type = make_type(RPC_FC_WCHAR, NULL); ;} +#line 683 "parser.y" + { (yyval.type) = (yyvsp[0].type); (yyval.type)->sign = 1; ;} break; - case 199: -#line 603 "parser.y" - { yyval.type = yyvsp[0].type; yyval.type->sign = 1; ;} - break; - - case 200: -#line 604 "parser.y" - { yyval.type = yyvsp[0].type; yyval.type->sign = -1; - switch (yyval.type->type) { + case 198: +#line 684 "parser.y" + { (yyval.type) = (yyvsp[0].type); (yyval.type)->sign = -1; + switch ((yyval.type)->type) { case RPC_FC_CHAR: break; - case RPC_FC_SMALL: yyval.type->type = RPC_FC_USMALL; break; - case RPC_FC_SHORT: yyval.type->type = RPC_FC_USHORT; break; - case RPC_FC_LONG: yyval.type->type = RPC_FC_ULONG; break; + case RPC_FC_SMALL: (yyval.type)->type = RPC_FC_USMALL; break; + case RPC_FC_SHORT: (yyval.type)->type = RPC_FC_USHORT; break; + case RPC_FC_LONG: (yyval.type)->type = RPC_FC_ULONG; break; case RPC_FC_HYPER: - if (!yyval.type->ref) { yyval.type->ref = &std_uhyper; yyval.type->sign = 0; } + if ((yyval.type)->name[0] == 'h') /* hyper, as opposed to __int64 */ + { + (yyval.type) = alias((yyval.type), "MIDL_uhyper"); + (yyval.type)->sign = 0; + } break; default: break; } ;} break; + case 199: +#line 700 "parser.y" + { (yyval.type) = make_int(-1); ;} + break; + + case 200: +#line 701 "parser.y" + { (yyval.type) = make_builtin((yyvsp[0].str)); ;} + break; + case 201: -#line 616 "parser.y" - { yyval.type = make_type(RPC_FC_ULONG, &std_int); yyval.type->sign = -1; ;} +#line 702 "parser.y" + { (yyval.type) = duptype(find_type("float", 0), 1); ;} break; case 202: -#line 617 "parser.y" - { yyval.type = make_type(RPC_FC_FLOAT, NULL); ;} +#line 703 "parser.y" + { (yyval.type) = make_builtin((yyvsp[0].str)); ;} break; case 203: -#line 618 "parser.y" - { yyval.type = make_type(RPC_FC_FLOAT, NULL); ;} +#line 704 "parser.y" + { (yyval.type) = make_builtin((yyvsp[0].str)); ;} break; case 204: -#line 619 "parser.y" - { yyval.type = make_type(RPC_FC_DOUBLE, NULL); ;} +#line 705 "parser.y" + { (yyval.type) = make_builtin((yyvsp[0].str)); ;} break; case 205: -#line 620 "parser.y" - { yyval.type = make_type(RPC_FC_BYTE, &std_bool); /* ? */ ;} +#line 706 "parser.y" + { (yyval.type) = make_builtin((yyvsp[0].str)); ;} break; - case 206: -#line 621 "parser.y" - { yyval.type = make_type(RPC_FC_ERROR_STATUS_T, NULL); ;} + case 208: +#line 713 "parser.y" + { (yyval.type) = make_builtin((yyvsp[0].str)); ;} break; - case 207: -#line 622 "parser.y" - { yyval.type = make_type(RPC_FC_BIND_PRIMITIVE, NULL); /* ? */ ;} + case 209: +#line 714 "parser.y" + { (yyval.type) = make_builtin((yyvsp[-1].str)); ;} break; case 210: -#line 629 "parser.y" - { yyval.type = make_type(RPC_FC_LONG, &std_int); ;} +#line 715 "parser.y" + { (yyval.type) = make_builtin((yyvsp[0].str)); ;} break; case 211: -#line 630 "parser.y" - { yyval.type = make_type(RPC_FC_SHORT, NULL); ;} +#line 716 "parser.y" + { (yyval.type) = make_builtin((yyvsp[-1].str)); ;} break; case 212: -#line 631 "parser.y" - { yyval.type = make_type(RPC_FC_SMALL, NULL); ;} +#line 717 "parser.y" + { (yyval.type) = make_builtin((yyvsp[-1].str)); ;} break; case 213: -#line 632 "parser.y" - { yyval.type = make_type(RPC_FC_LONG, NULL); ;} +#line 718 "parser.y" + { (yyval.type) = make_builtin((yyvsp[0].str)); ;} break; case 214: -#line 633 "parser.y" - { yyval.type = make_type(RPC_FC_HYPER, NULL); ;} +#line 719 "parser.y" + { (yyval.type) = make_builtin((yyvsp[0].str)); ;} break; case 215: -#line 634 "parser.y" - { yyval.type = make_type(RPC_FC_HYPER, &std_int64); ;} +#line 722 "parser.y" + { (yyval.type) = make_class((yyvsp[0].str)); ;} break; case 216: -#line 635 "parser.y" - { yyval.type = make_type(RPC_FC_CHAR, NULL); ;} +#line 723 "parser.y" + { (yyval.type) = find_type((yyvsp[0].str), 0); + if ((yyval.type)->defined) error_loc("multiple definition error\n"); + if ((yyval.type)->kind != TKIND_COCLASS) error_loc("%s was not declared a coclass\n", (yyvsp[0].str)); + ;} break; case 217: -#line 638 "parser.y" - { yyval.type = make_class(yyvsp[0].str); ;} +#line 729 "parser.y" + { (yyval.type) = (yyvsp[0].type); + (yyval.type)->attrs = (yyvsp[-1].attr_list); + if (!parse_only && do_header) + write_coclass((yyval.type)); + if (!parse_only && do_idfile) + write_clsid((yyval.type)); + ;} break; case 218: -#line 639 "parser.y" - { yyval.type = find_type(yyvsp[0].str, 0); - if (yyval.type->defined) yyerror("multiple definition error"); - if (yyval.type->kind != TKIND_COCLASS) yyerror("%s was not declared a coclass", yyvsp[0].str); +#line 738 "parser.y" + { (yyval.type) = (yyvsp[-3].type); + (yyval.type)->ifaces = (yyvsp[-1].ifref_list); + (yyval.type)->defined = TRUE; ;} break; case 219: -#line 645 "parser.y" - { yyval.type = yyvsp[0].type; - yyval.type->attrs = yyvsp[-1].attr; - if (!parse_only && do_header) - write_coclass(yyval.type); - ;} +#line 744 "parser.y" + { (yyval.ifref_list) = NULL; ;} break; case 220: -#line 652 "parser.y" - { yyval.type = yyvsp[-3].type; - yyval.type->ifaces = yyvsp[-1].ifref; - ;} +#line 745 "parser.y" + { (yyval.ifref_list) = append_ifref( (yyvsp[-1].ifref_list), (yyvsp[0].ifref) ); ;} break; case 221: -#line 657 "parser.y" - { yyval.ifref = NULL; ;} +#line 749 "parser.y" + { (yyval.ifref) = make_ifref((yyvsp[0].type)); (yyval.ifref)->attrs = (yyvsp[-1].attr_list); ;} break; case 222: -#line 658 "parser.y" - { LINK(yyvsp[0].ifref, yyvsp[-1].ifref); yyval.ifref = yyvsp[0].ifref; ;} +#line 752 "parser.y" + { (yyval.type) = get_type(0, (yyvsp[0].str), 0); (yyval.type)->kind = TKIND_DISPATCH; ;} break; case 223: -#line 662 "parser.y" - { yyval.ifref = make_ifref(yyvsp[0].type); yyval.ifref->attrs = yyvsp[-1].attr; ;} +#line 753 "parser.y" + { (yyval.type) = get_type(0, (yyvsp[0].str), 0); (yyval.type)->kind = TKIND_DISPATCH; ;} break; case 224: -#line 665 "parser.y" - { yyval.type = get_type(0, yyvsp[0].str, 0); ;} +#line 756 "parser.y" + { attr_t *attrs; + (yyval.type) = (yyvsp[0].type); + if ((yyval.type)->defined) error_loc("multiple definition error\n"); + attrs = make_attr(ATTR_DISPINTERFACE); + (yyval.type)->attrs = append_attr( (yyvsp[-1].attr_list), attrs ); + (yyval.type)->ref = find_type("IDispatch", 0); + if (!(yyval.type)->ref) error_loc("IDispatch is undefined\n"); + (yyval.type)->defined = TRUE; + if (!parse_only && do_header) write_forward((yyval.type)); + ;} break; case 225: -#line 666 "parser.y" - { yyval.type = get_type(0, yyvsp[0].str, 0); ;} +#line 768 "parser.y" + { (yyval.var_list) = NULL; ;} break; case 226: -#line 669 "parser.y" - { attr_t *attrs; - yyval.type = yyvsp[0].type; - if (yyval.type->defined) yyerror("multiple definition error"); - attrs = make_attr(ATTR_DISPINTERFACE); - LINK(attrs, yyvsp[-1].attr); - yyval.type->attrs = attrs; - yyval.type->ref = find_type("IDispatch", 0); - if (!yyval.type->ref) yyerror("IDispatch is undefined"); - yyval.type->defined = TRUE; - if (!parse_only && do_header) write_forward(yyval.type); - ;} +#line 769 "parser.y" + { (yyval.var_list) = append_var( (yyvsp[-2].var_list), (yyvsp[-1].var) ); ;} break; case 227: -#line 682 "parser.y" - { yyval.var = NULL; ;} +#line 772 "parser.y" + { (yyval.func_list) = NULL; ;} break; case 228: -#line 683 "parser.y" - { LINK(yyvsp[-1].var, yyvsp[-2].var); yyval.var = yyvsp[-1].var; ;} +#line 773 "parser.y" + { (yyval.func_list) = append_func( (yyvsp[-2].func_list), (yyvsp[-1].func) ); ;} break; case 229: -#line 686 "parser.y" - { yyval.func = NULL; ;} - break; - - case 230: -#line 687 "parser.y" - { LINK(yyvsp[-1].func, yyvsp[-2].func); yyval.func = yyvsp[-1].func; ;} - break; - - case 231: -#line 693 "parser.y" - { yyval.type = yyvsp[-4].type; - yyval.type->fields = yyvsp[-2].var; - yyval.type->funcs = yyvsp[-1].func; - if (!parse_only && do_header) write_dispinterface(yyval.type); +#line 779 "parser.y" + { (yyval.type) = (yyvsp[-4].type); + (yyval.type)->fields = (yyvsp[-2].var_list); + (yyval.type)->funcs = (yyvsp[-1].func_list); + if (!parse_only && do_header) write_dispinterface((yyval.type)); + if (!parse_only && do_idfile) write_diid((yyval.type)); ;} break; + case 230: +#line 786 "parser.y" + { (yyval.type) = (yyvsp[-4].type); + (yyval.type)->fields = (yyvsp[-2].type)->fields; + (yyval.type)->funcs = (yyvsp[-2].type)->funcs; + if (!parse_only && do_header) write_dispinterface((yyval.type)); + if (!parse_only && do_idfile) write_diid((yyval.type)); + ;} + break; + + case 231: +#line 794 "parser.y" + { (yyval.type) = NULL; ;} + break; + case 232: -#line 705 "parser.y" - { yyval.type = NULL; ;} +#line 795 "parser.y" + { (yyval.type) = find_type2((yyvsp[0].str), 0); ;} break; case 233: -#line 706 "parser.y" - { yyval.type = find_type2(yyvsp[0].str, 0); ;} +#line 798 "parser.y" + { (yyval.type) = get_type(RPC_FC_IP, (yyvsp[0].str), 0); (yyval.type)->kind = TKIND_INTERFACE; ;} break; case 234: -#line 709 "parser.y" - { yyval.type = get_type(RPC_FC_IP, yyvsp[0].str, 0); ;} +#line 799 "parser.y" + { (yyval.type) = get_type(RPC_FC_IP, (yyvsp[0].str), 0); (yyval.type)->kind = TKIND_INTERFACE; ;} break; case 235: -#line 710 "parser.y" - { yyval.type = get_type(RPC_FC_IP, yyvsp[0].str, 0); ;} +#line 802 "parser.y" + { (yyval.ifinfo).interface = (yyvsp[0].type); + (yyval.ifinfo).old_pointer_default = pointer_default; + if (is_attr((yyvsp[-1].attr_list), ATTR_POINTERDEFAULT)) + pointer_default = get_attrv((yyvsp[-1].attr_list), ATTR_POINTERDEFAULT); + if ((yyvsp[0].type)->defined) error_loc("multiple definition error\n"); + (yyvsp[0].type)->attrs = (yyvsp[-1].attr_list); + (yyvsp[0].type)->defined = TRUE; + if (!parse_only && do_header) write_forward((yyvsp[0].type)); + ;} break; case 236: -#line 713 "parser.y" - { yyval.type = yyvsp[0].type; - if (yyval.type->defined) yyerror("multiple definition error"); - yyval.type->attrs = yyvsp[-1].attr; - yyval.type->defined = TRUE; - if (!parse_only && do_header) write_forward(yyval.type); +#line 814 "parser.y" + { (yyval.type) = (yyvsp[-4].ifinfo).interface; + (yyval.type)->ref = (yyvsp[-3].type); + (yyval.type)->funcs = (yyvsp[-1].func_list); + compute_method_indexes((yyval.type)); + if (!parse_only && do_header) write_interface((yyval.type)); + if (!parse_only && local_stubs) write_locals(local_stubs, (yyval.type), TRUE); + if (!parse_only && do_idfile) write_iid((yyval.type)); + pointer_default = (yyvsp[-4].ifinfo).old_pointer_default; ;} break; case 237: -#line 722 "parser.y" - { yyval.type = yyvsp[-4].type; - yyval.type->ref = yyvsp[-3].type; - yyval.type->funcs = yyvsp[-1].func; - if (!parse_only && do_header) write_interface(yyval.type); +#line 826 "parser.y" + { (yyval.type) = (yyvsp[-6].ifinfo).interface; + (yyval.type)->ref = find_type2((yyvsp[-4].str), 0); + if (!(yyval.type)->ref) error_loc("base class '%s' not found in import\n", (yyvsp[-4].str)); + (yyval.type)->funcs = (yyvsp[-1].func_list); + compute_method_indexes((yyval.type)); + if (!parse_only && do_header) write_interface((yyval.type)); + if (!parse_only && local_stubs) write_locals(local_stubs, (yyval.type), TRUE); + if (!parse_only && do_idfile) write_iid((yyval.type)); + pointer_default = (yyvsp[-6].ifinfo).old_pointer_default; ;} break; case 238: -#line 730 "parser.y" - { yyval.type = yyvsp[-6].type; - yyval.type->ref = find_type2(yyvsp[-4].str, 0); - if (!yyval.type->ref) yyerror("base class '%s' not found in import", yyvsp[-4].str); - yyval.type->funcs = yyvsp[-1].func; - if (!parse_only && do_header) write_interface(yyval.type); - ;} +#line 836 "parser.y" + { (yyval.type) = (yyvsp[0].type); ;} break; case 239: -#line 736 "parser.y" - { yyval.type = yyvsp[0].type; ;} +#line 840 "parser.y" + { (yyval.type) = (yyvsp[-1].type); if (!parse_only && do_header) write_forward((yyval.type)); ;} break; case 240: -#line 740 "parser.y" - { yyval.type = yyvsp[-1].type; if (!parse_only && do_header) write_forward(yyval.type); ;} +#line 841 "parser.y" + { (yyval.type) = (yyvsp[-1].type); if (!parse_only && do_header) write_forward((yyval.type)); ;} break; case 241: -#line 741 "parser.y" - { yyval.type = yyvsp[-1].type; if (!parse_only && do_header) write_forward(yyval.type); ;} +#line 844 "parser.y" + { (yyval.type) = make_type(0, NULL); (yyval.type)->name = (yyvsp[0].str); (yyval.type)->kind = TKIND_MODULE; ;} break; case 242: -#line 744 "parser.y" - { yyval.type = make_type(0, NULL); yyval.type->name = yyvsp[0].str; ;} +#line 845 "parser.y" + { (yyval.type) = make_type(0, NULL); (yyval.type)->name = (yyvsp[0].str); (yyval.type)->kind = TKIND_MODULE; ;} break; case 243: -#line 745 "parser.y" - { yyval.type = make_type(0, NULL); yyval.type->name = yyvsp[0].str; ;} - break; - - case 244: -#line 748 "parser.y" - { yyval.type = yyvsp[0].type; - yyval.type->attrs = yyvsp[-1].attr; +#line 848 "parser.y" + { (yyval.type) = (yyvsp[0].type); + (yyval.type)->attrs = (yyvsp[-1].attr_list); ;} break; - case 245: -#line 753 "parser.y" - { yyval.type = yyvsp[-3].type; - yyval.type->funcs = yyvsp[-1].func; + case 244: +#line 853 "parser.y" + { (yyval.type) = (yyvsp[-3].type); + (yyval.type)->funcs = (yyvsp[-1].func_list); /* FIXME: if (!parse_only && do_header) write_module($$); */ ;} break; + case 245: +#line 859 "parser.y" + { (yyval.pident) = (yyvsp[0].pident); (yyval.pident)->ptr_level++; ;} + break; + case 246: -#line 759 "parser.y" - { yyval.var = yyvsp[0].var; yyval.var->ptr_level++; ;} +#line 860 "parser.y" + { (yyval.pident) = (yyvsp[0].pident); /* FIXME */ ;} break; case 247: -#line 760 "parser.y" - { yyval.var = yyvsp[0].var; /* FIXME */ ;} +#line 863 "parser.y" + { (yyval.pident) = make_pident((yyvsp[0].var)); ;} + break; + + case 249: +#line 865 "parser.y" + { (yyval.pident) = (yyvsp[-1].pident); ;} break; case 250: -#line 765 "parser.y" - { yyval.var = yyvsp[-1].var; ;} +#line 869 "parser.y" + { (yyval.pident_list) = append_pident( NULL, (yyvsp[0].pident) ); ;} + break; + + case 251: +#line 870 "parser.y" + { (yyval.pident_list) = append_pident( (yyvsp[-2].pident_list), (yyvsp[0].pident) ); ;} break; case 252: -#line 770 "parser.y" - { LINK(yyvsp[0].var, yyvsp[-2].var); yyval.var = yyvsp[0].var; ;} +#line 874 "parser.y" + { (yyval.num) = RPC_FC_RP; ;} break; case 253: -#line 774 "parser.y" - { yyval.num = RPC_FC_RP; ;} +#line 875 "parser.y" + { (yyval.num) = RPC_FC_UP; ;} break; case 254: -#line 775 "parser.y" - { yyval.num = RPC_FC_UP; ;} +#line 876 "parser.y" + { (yyval.num) = RPC_FC_FP; ;} break; case 255: -#line 776 "parser.y" - { yyval.num = RPC_FC_FP; ;} - break; - - case 256: -#line 779 "parser.y" - { yyval.type = get_typev(RPC_FC_STRUCT, yyvsp[-3].var, tsSTRUCT); +#line 879 "parser.y" + { (yyval.type) = get_typev(RPC_FC_STRUCT, (yyvsp[-3].var), tsSTRUCT); /* overwrite RPC_FC_STRUCT with a more exact type */ - yyval.type->type = get_struct_type( yyvsp[-1].var ); - yyval.type->fields = yyvsp[-1].var; - yyval.type->defined = TRUE; + (yyval.type)->type = get_struct_type( (yyvsp[-1].var_list) ); + (yyval.type)->kind = TKIND_RECORD; + (yyval.type)->fields = (yyvsp[-1].var_list); + (yyval.type)->defined = TRUE; if(in_typelib) - add_struct(yyval.type); + add_typelib_entry((yyval.type)); ;} break; + case 256: +#line 890 "parser.y" + { (yyval.type) = duptype(find_type("void", 0), 1); ;} + break; + case 257: -#line 789 "parser.y" - { yyval.tref = make_tref(NULL, make_type(0, NULL)); ;} +#line 891 "parser.y" + { (yyval.type) = find_type((yyvsp[0].str), 0); ;} break; case 258: -#line 790 "parser.y" - { yyval.tref = make_tref(yyvsp[0].str, find_type(yyvsp[0].str, 0)); ;} +#line 892 "parser.y" + { (yyval.type) = (yyvsp[0].type); ;} break; case 259: -#line 791 "parser.y" - { yyval.tref = make_tref(NULL, yyvsp[0].type); ;} +#line 893 "parser.y" + { (yyval.type) = duptype((yyvsp[0].type), 1); (yyval.type)->is_const = TRUE; ;} break; case 260: -#line 792 "parser.y" - { yyval.tref = uniq_tref(yyvsp[0].tref); yyval.tref->ref->is_const = TRUE; ;} +#line 894 "parser.y" + { (yyval.type) = (yyvsp[0].type); ;} break; case 261: -#line 793 "parser.y" - { yyval.tref = make_tref(NULL, yyvsp[0].type); ;} +#line 895 "parser.y" + { (yyval.type) = find_type2((yyvsp[0].str), tsENUM); ;} break; case 262: -#line 794 "parser.y" - { yyval.tref = make_tref(NULL, find_type2(yyvsp[0].str, tsENUM)); ;} +#line 896 "parser.y" + { (yyval.type) = (yyvsp[0].type); ;} break; case 263: -#line 795 "parser.y" - { yyval.tref = make_tref(NULL, yyvsp[0].type); ;} +#line 897 "parser.y" + { (yyval.type) = get_type(RPC_FC_STRUCT, (yyvsp[0].str), tsSTRUCT); ;} break; case 264: -#line 796 "parser.y" - { yyval.tref = make_tref(NULL, get_type(RPC_FC_STRUCT, yyvsp[0].str, tsSTRUCT)); ;} +#line 898 "parser.y" + { (yyval.type) = (yyvsp[0].type); ;} break; case 265: -#line 797 "parser.y" - { yyval.tref = make_tref(NULL, yyvsp[0].type); ;} +#line 899 "parser.y" + { (yyval.type) = find_type2((yyvsp[0].str), tsUNION); ;} break; case 266: -#line 798 "parser.y" - { yyval.tref = make_tref(NULL, find_type2(yyvsp[0].str, tsUNION)); ;} +#line 900 "parser.y" + { (yyval.type) = make_safearray((yyvsp[-1].type)); ;} break; case 267: -#line 799 "parser.y" - { yyval.tref = make_tref(NULL, make_safearray()); ;} +#line 903 "parser.y" + { reg_typedefs((yyvsp[-1].type), (yyvsp[0].pident_list), (yyvsp[-2].attr_list)); + process_typedefs((yyvsp[0].pident_list)); + ;} break; case 268: -#line 802 "parser.y" - { typeref_t *tref = uniq_tref(yyvsp[-1].tref); - yyvsp[0].var->tname = tref->name; - tref->name = NULL; - yyval.type = type_ref(tref); - yyval.type->attrs = yyvsp[-2].attr; - if (!parse_only && do_header) - write_typedef(yyval.type, yyvsp[0].var); - if (in_typelib && yyval.type->attrs) - add_typedef(yyval.type, yyvsp[0].var); - reg_types(yyval.type, yyvsp[0].var, 0); +#line 908 "parser.y" + { (yyval.type) = get_typev(RPC_FC_NON_ENCAPSULATED_UNION, (yyvsp[-3].var), tsUNION); + (yyval.type)->kind = TKIND_UNION; + (yyval.type)->fields = (yyvsp[-1].var_list); + (yyval.type)->defined = TRUE; ;} break; case 269: -#line 815 "parser.y" - { yyval.type = get_typev(RPC_FC_NON_ENCAPSULATED_UNION, yyvsp[-3].var, tsUNION); - yyval.type->fields = yyvsp[-1].var; - yyval.type->defined = TRUE; +#line 915 "parser.y" + { var_t *u = (yyvsp[-3].var); + (yyval.type) = get_typev(RPC_FC_ENCAPSULATED_UNION, (yyvsp[-8].var), tsUNION); + (yyval.type)->kind = TKIND_UNION; + if (!u) u = make_var( xstrdup("tagged_union") ); + u->type = make_type(RPC_FC_NON_ENCAPSULATED_UNION, NULL); + u->type->kind = TKIND_UNION; + u->type->fields = (yyvsp[-1].var_list); + u->type->defined = TRUE; + (yyval.type)->fields = append_var( (yyval.type)->fields, (yyvsp[-5].var) ); + (yyval.type)->fields = append_var( (yyval.type)->fields, u ); + (yyval.type)->defined = TRUE; ;} break; case 270: -#line 821 "parser.y" - { var_t *u = yyvsp[-3].var; - yyval.type = get_typev(RPC_FC_ENCAPSULATED_UNION, yyvsp[-8].var, tsUNION); - if (!u) u = make_var("tagged_union"); - u->type = make_type(RPC_FC_NON_ENCAPSULATED_UNION, NULL); - u->type->fields = yyvsp[-1].var; - u->type->defined = TRUE; - LINK(u, yyvsp[-5].var); yyval.type->fields = u; - yyval.type->defined = TRUE; - ;} +#line 930 "parser.y" + { (yyval.num) = MAKEVERSION((yyvsp[0].num), 0); ;} break; case 271: -#line 833 "parser.y" - { yyval.num = MAKELONG(yyvsp[0].num, 0); ;} - break; - - case 272: -#line 834 "parser.y" - { yyval.num = MAKELONG(yyvsp[-2].num, yyvsp[0].num); ;} +#line 931 "parser.y" + { (yyval.num) = MAKEVERSION((yyvsp[-2].num), (yyvsp[0].num)); ;} break; + default: break; } -/* Line 991 of yacc.c. */ -#line 3375 "parser.tab.c" +/* Line 1126 of yacc.c. */ +#line 3627 "parser.tab.c" yyvsp -= yylen; yyssp -= yylen; @@ -3409,103 +3662,153 @@ yyerrlab: if (YYPACT_NINF < yyn && yyn < YYLAST) { - YYSIZE_T yysize = 0; int yytype = YYTRANSLATE (yychar); - char *yymsg; - int yyx, yycount; + YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); + YYSIZE_T yysize = yysize0; + YYSIZE_T yysize1; + int yysize_overflow = 0; + char *yymsg = 0; +# define YYERROR_VERBOSE_ARGS_MAXIMUM 5 + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + int yyx; + +#if 0 + /* This is so xgettext sees the translatable formats that are + constructed on the fly. */ + YY_("syntax error, unexpected %s"); + YY_("syntax error, unexpected %s, expecting %s"); + YY_("syntax error, unexpected %s, expecting %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); +#endif + char *yyfmt; + char const *yyf; + static char const yyunexpected[] = "syntax error, unexpected %s"; + static char const yyexpecting[] = ", expecting %s"; + static char const yyor[] = " or %s"; + char yyformat[sizeof yyunexpected + + sizeof yyexpecting - 1 + + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) + * (sizeof yyor - 1))]; + char const *yyprefix = yyexpecting; - yycount = 0; /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. */ - for (yyx = yyn < 0 ? -yyn : 0; - yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - yysize += yystrlen (yytname[yyx]) + 15, yycount++; - yysize += yystrlen ("syntax error, unexpected ") + 1; - yysize += yystrlen (yytname[yytype]); - yymsg = (char *) YYSTACK_ALLOC (yysize); - if (yymsg != 0) - { - char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); - yyp = yystpcpy (yyp, yytname[yytype]); + int yyxbegin = yyn < 0 ? -yyn : 0; - if (yycount < 5) + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yycount = 1; + + yyarg[0] = yytname[yytype]; + yyfmt = yystpcpy (yyformat, yyunexpected); + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + yyformat[sizeof yyunexpected - 1] = '\0'; + break; + } + yyarg[yycount++] = yytname[yyx]; + yysize1 = yysize + yytnamerr (0, yytname[yyx]); + yysize_overflow |= yysize1 < yysize; + yysize = yysize1; + yyfmt = yystpcpy (yyfmt, yyprefix); + yyprefix = yyor; + } + + yyf = YY_(yyformat); + yysize1 = yysize + yystrlen (yyf); + yysize_overflow |= yysize1 < yysize; + yysize = yysize1; + + if (!yysize_overflow && yysize <= YYSTACK_ALLOC_MAXIMUM) + yymsg = (char *) YYSTACK_ALLOC (yysize); + if (yymsg) + { + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + char *yyp = yymsg; + int yyi = 0; + while ((*yyp = *yyf)) { - yycount = 0; - for (yyx = yyn < 0 ? -yyn : 0; - yyx < (int) (sizeof (yytname) / sizeof (char *)); - yyx++) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - { - const char *yyq = ! yycount ? ", expecting " : " or "; - yyp = yystpcpy (yyp, yyq); - yyp = yystpcpy (yyp, yytname[yyx]); - yycount++; - } + if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyf += 2; + } + else + { + yyp++; + yyf++; + } } yyerror (yymsg); YYSTACK_FREE (yymsg); } else - yyerror ("syntax error; also virtual memory exhausted"); + { + yyerror (YY_("syntax error")); + goto yyexhaustedlab; + } } else #endif /* YYERROR_VERBOSE */ - yyerror ("syntax error"); + yyerror (YY_("syntax error")); } if (yyerrstatus == 3) { - /* If just tried and failed to reuse lookahead token after an + /* If just tried and failed to reuse look-ahead token after an error, discard it. */ - /* Return failure if at end of input. */ - if (yychar == YYEOF) + if (yychar <= YYEOF) { - /* Pop the error token. */ - YYPOPSTACK; - /* Pop the rest of the stack. */ - while (yyss < yyssp) - { - YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); - yydestruct (yystos[*yyssp], yyvsp); - YYPOPSTACK; - } - YYABORT; + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; } - - YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc); - yydestruct (yytoken, &yylval); - yychar = YYEMPTY; - + else + { + yydestruct ("Error: discarding", yytoken, &yylval); + yychar = YYEMPTY; + } } - /* Else will try to reuse lookahead token after shifting the error + /* Else will try to reuse look-ahead token after shifting the error token. */ - goto yyerrlab2; + goto yyerrlab1; -/*----------------------------------------------------. -| yyerrlab1 -- error raised explicitly by an action. | -`----------------------------------------------------*/ +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + + /* Pacify compilers like GCC when the user code never invokes + YYERROR and the label yyerrorlab therefore never appears in user + code. */ + if (0) + goto yyerrorlab; + +yyvsp -= yylen; + yyssp -= yylen; + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ yyerrlab1: - - /* Suppress GCC warning that yyerrlab1 is unused when no action - invokes YYERROR. */ -#if defined (__GNUC_MINOR__) && 2093 <= (__GNUC__ * 1000 + __GNUC_MINOR__) - __attribute__ ((__unused__)) -#endif - - - goto yyerrlab2; - - -/*---------------------------------------------------------------. -| yyerrlab2 -- pop states until the error token can be shifted. | -`---------------------------------------------------------------*/ -yyerrlab2: yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) @@ -3526,22 +3829,22 @@ yyerrlab2: if (yyssp == yyss) YYABORT; - YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); - yydestruct (yystos[yystate], yyvsp); - yyvsp--; - yystate = *--yyssp; + yydestruct ("Error: popping", yystos[yystate], yyvsp); + YYPOPSTACK; + yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } if (yyn == YYFINAL) YYACCEPT; - YYDPRINTF ((stderr, "Shifting error token, ")); - *++yyvsp = yylval; + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + yystate = yyn; goto yynewstate; @@ -3561,16 +3864,25 @@ yyabortlab: goto yyreturn; #ifndef yyoverflow -/*----------------------------------------------. -| yyoverflowlab -- parser overflow comes here. | -`----------------------------------------------*/ -yyoverflowlab: - yyerror ("parser stack overflow"); +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (YY_("memory exhausted")); yyresult = 2; /* Fall through. */ #endif yyreturn: + if (yychar != YYEOF && yychar != YYEMPTY) + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[*yyssp], yyvsp); + YYPOPSTACK; + } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); @@ -3579,15 +3891,87 @@ yyreturn: } -#line 837 "parser.y" +#line 934 "parser.y" +static void decl_builtin(const char *name, unsigned char type) +{ + type_t *t = make_type(type, NULL); + t->name = xstrdup(name); + reg_type(t, name, 0); +} + +static type_t *make_builtin(char *name) +{ + /* NAME is strdup'd in the lexer */ + type_t *t = duptype(find_type(name, 0), 0); + t->name = name; + return t; +} + +static type_t *make_int(int sign) +{ + type_t *t = duptype(find_type("int", 0), 1); + + t->sign = sign; + if (sign < 0) + t->type = t->type == RPC_FC_LONG ? RPC_FC_ULONG : RPC_FC_USHORT; + + return t; +} + +void init_types(void) +{ + decl_builtin("void", 0); + decl_builtin("byte", RPC_FC_BYTE); + decl_builtin("wchar_t", RPC_FC_WCHAR); + decl_builtin("int", RPC_FC_LONG); /* win32 */ + decl_builtin("short", RPC_FC_SHORT); + decl_builtin("small", RPC_FC_SMALL); + decl_builtin("long", RPC_FC_LONG); + decl_builtin("hyper", RPC_FC_HYPER); + decl_builtin("__int64", RPC_FC_HYPER); + decl_builtin("char", RPC_FC_CHAR); + decl_builtin("float", RPC_FC_FLOAT); + decl_builtin("double", RPC_FC_DOUBLE); + decl_builtin("boolean", RPC_FC_BYTE); + decl_builtin("error_status_t", RPC_FC_ERROR_STATUS_T); + decl_builtin("handle_t", RPC_FC_BIND_PRIMITIVE); +} + +static str_list_t *append_str(str_list_t *list, char *str) +{ + struct str_list_entry_t *entry; + + if (!str) return list; + if (!list) + { + list = xmalloc( sizeof(*list) ); + list_init( list ); + } + entry = xmalloc( sizeof(*entry) ); + entry->str = str; + list_add_tail( list, &entry->entry ); + return list; +} + +static attr_list_t *append_attr(attr_list_t *list, attr_t *attr) +{ + if (!attr) return list; + if (!list) + { + list = xmalloc( sizeof(*list) ); + list_init( list ); + } + list_add_tail( list, &attr->entry ); + return list; +} + static attr_t *make_attr(enum attr_type type) { attr_t *a = xmalloc(sizeof(attr_t)); a->type = type; a->u.ival = 0; - INIT_LINK(a); return a; } @@ -3596,7 +3980,6 @@ static attr_t *make_attrv(enum attr_type type, unsigned long val) attr_t *a = xmalloc(sizeof(attr_t)); a->type = type; a->u.ival = val; - INIT_LINK(a); return a; } @@ -3605,7 +3988,6 @@ static attr_t *make_attrp(enum attr_type type, void *val) attr_t *a = xmalloc(sizeof(attr_t)); a->type = type; a->u.pval = val; - INIT_LINK(a); return a; } @@ -3616,7 +3998,7 @@ static expr_t *make_expr(enum expr_type type) e->ref = NULL; e->u.lval = 0; e->is_const = FALSE; - INIT_LINK(e); + e->cval = 0; return e; } @@ -3627,7 +4009,6 @@ static expr_t *make_exprl(enum expr_type type, long val) e->ref = NULL; e->u.lval = val; e->is_const = FALSE; - INIT_LINK(e); /* check for numeric constant */ if (type == EXPR_NUM || type == EXPR_HEXNUM || type == EXPR_TRUEFALSE) { /* make sure true/false value is valid */ @@ -3638,6 +4019,17 @@ static expr_t *make_exprl(enum expr_type type, long val) return e; } +static expr_t *make_exprd(enum expr_type type, double val) +{ + expr_t *e = xmalloc(sizeof(expr_t)); + e->type = type; + e->ref = NULL; + e->u.dval = val; + e->is_const = TRUE; + e->cval = val; + return e; +} + static expr_t *make_exprs(enum expr_type type, char *val) { expr_t *e; @@ -3646,7 +4038,6 @@ static expr_t *make_exprs(enum expr_type type, char *val) e->ref = NULL; e->u.sval = val; e->is_const = FALSE; - INIT_LINK(e); /* check for predefined constants */ if (type == EXPR_IDENTIFIER) { var_t *c = find_const(val, 0); @@ -3660,7 +4051,7 @@ static expr_t *make_exprs(enum expr_type type, char *val) return e; } -static expr_t *make_exprt(enum expr_type type, typeref_t *tref, expr_t *expr) +static expr_t *make_exprt(enum expr_type type, type_t *tref, expr_t *expr) { expr_t *e; e = xmalloc(sizeof(expr_t)); @@ -3668,10 +4059,9 @@ static expr_t *make_exprt(enum expr_type type, typeref_t *tref, expr_t *expr) e->ref = expr; e->u.tref = tref; e->is_const = FALSE; - INIT_LINK(e); /* check for cast of constant expression */ if (type == EXPR_SIZEOF) { - switch (tref->ref->type) { + switch (tref->type) { case RPC_FC_BYTE: case RPC_FC_CHAR: case RPC_FC_SMALL: @@ -3709,12 +4099,13 @@ static expr_t *make_exprt(enum expr_type type, typeref_t *tref, expr_t *expr) static expr_t *make_expr1(enum expr_type type, expr_t *expr) { expr_t *e; + if (type == EXPR_ADDRESSOF && expr->type != EXPR_IDENTIFIER) + error("address-of operator applied to invalid expression\n"); e = xmalloc(sizeof(expr_t)); e->type = type; e->ref = expr; e->u.lval = 0; e->is_const = FALSE; - INIT_LINK(e); /* check for compile-time optimization */ if (expr->is_const) { e->is_const = TRUE; @@ -3741,7 +4132,6 @@ static expr_t *make_expr2(enum expr_type type, expr_t *expr1, expr_t *expr2) e->ref = expr1; e->u.ext = expr2; e->is_const = FALSE; - INIT_LINK(e); /* check for compile-time optimization */ if (expr1->is_const && expr2->is_const) { e->is_const = TRUE; @@ -3787,7 +4177,6 @@ static expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, exp e->u.ext = expr2; e->ext2 = expr3; e->is_const = FALSE; - INIT_LINK(e); /* check for compile-time optimization */ if (expr1->is_const && expr2->is_const && expr3->is_const) { e->is_const = TRUE; @@ -3803,64 +4192,244 @@ static expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, exp return e; } +static expr_list_t *append_expr(expr_list_t *list, expr_t *expr) +{ + if (!expr) return list; + if (!list) + { + list = xmalloc( sizeof(*list) ); + list_init( list ); + } + list_add_tail( list, &expr->entry ); + return list; +} + +static array_dims_t *append_array(array_dims_t *list, expr_t *expr) +{ + if (!expr) return list; + if (!list) + { + list = xmalloc( sizeof(*list) ); + list_init( list ); + } + list_add_tail( list, &expr->entry ); + return list; +} + +static struct list type_pool = LIST_INIT(type_pool); +typedef struct +{ + type_t data; + struct list link; +} type_pool_node_t; + +type_t *alloc_type(void) +{ + type_pool_node_t *node = xmalloc(sizeof *node); + list_add_tail(&type_pool, &node->link); + return &node->data; +} + +void set_all_tfswrite(int val) +{ + type_pool_node_t *node; + LIST_FOR_EACH_ENTRY(node, &type_pool, type_pool_node_t, link) + node->data.tfswrite = val; +} + static type_t *make_type(unsigned char type, type_t *ref) { - type_t *t = xmalloc(sizeof(type_t)); + type_t *t = alloc_type(); t->name = NULL; t->kind = TKIND_PRIMITIVE; t->type = type; t->ref = ref; t->attrs = NULL; + t->orig = NULL; t->funcs = NULL; t->fields = NULL; t->ifaces = NULL; - t->ignore = parse_only; + t->dim = 0; + t->size_is = NULL; + t->length_is = NULL; + t->typestring_offset = 0; + t->ptrdesc = 0; + t->declarray = FALSE; + t->ignore = (parse_only != 0); t->is_const = FALSE; t->sign = 0; t->defined = FALSE; t->written = FALSE; + t->user_types_registered = FALSE; + t->tfswrite = FALSE; t->typelib_idx = -1; - INIT_LINK(t); return t; } -static typeref_t *make_tref(char *name, type_t *ref) +static void set_type(var_t *v, type_t *type, int ptr_level, array_dims_t *arr, + int top) { - typeref_t *t = xmalloc(sizeof(typeref_t)); - t->name = name; - t->ref = ref; - t->uniq = ref ? 0 : 1; - return t; + expr_list_t *sizes = get_attrp(v->attrs, ATTR_SIZEIS); + expr_list_t *lengs = get_attrp(v->attrs, ATTR_LENGTHIS); + int ptr_attr = get_attrv(v->attrs, ATTR_POINTERTYPE); + int ptr_type = ptr_attr; + int sizeless, has_varconf; + expr_t *dim; + type_t *atype, **ptype; + + v->type = type; + + if (!ptr_type && top) + ptr_type = RPC_FC_RP; + + for ( ; 0 < ptr_level; --ptr_level) + { + v->type = make_type(pointer_default, v->type); + if (ptr_level == 1 && ptr_type && !arr) + { + v->type->type = ptr_type; + ptr_type = 0; + } + } + + if (ptr_type && !arr) + { + if (is_ptr(v->type)) + { + if (v->type->type != ptr_type) + { + v->type = duptype(v->type, 1); + v->type->type = ptr_type; + } + } + else if (!arr && ptr_attr) + error("%s: pointer attribute applied to non-pointer type\n", v->name); + } + + sizeless = FALSE; + if (arr) LIST_FOR_EACH_ENTRY_REV(dim, arr, expr_t, entry) + { + if (sizeless) + error("%s: only the first array dimension can be unspecified\n", v->name); + + if (dim->is_const) + { + unsigned int align = 0; + size_t size = type_memsize(v->type, &align); + + if (dim->cval <= 0) + error("%s: array dimension must be positive\n", v->name); + + if (0xffffffffuL / size < (unsigned long) dim->cval) + error("%s: total array size is too large\n", v->name); + else if (0xffffuL < size * dim->cval) + v->type = make_type(RPC_FC_LGFARRAY, v->type); + else + v->type = make_type(RPC_FC_SMFARRAY, v->type); + } + else + { + sizeless = TRUE; + v->type = make_type(RPC_FC_CARRAY, v->type); + } + + v->type->declarray = TRUE; + v->type->dim = dim->cval; + } + + ptype = &v->type; + has_varconf = FALSE; + if (sizes) LIST_FOR_EACH_ENTRY(dim, sizes, expr_t, entry) + { + if (dim->type != EXPR_VOID) + { + has_varconf = TRUE; + atype = *ptype = duptype(*ptype, 0); + + if (atype->type == RPC_FC_SMFARRAY || atype->type == RPC_FC_LGFARRAY) + error("%s: cannot specify size_is for a fixed sized array\n", v->name); + + if (atype->type != RPC_FC_CARRAY && !is_ptr(atype)) + error("%s: size_is attribute applied to illegal type\n", v->name); + + atype->type = RPC_FC_CARRAY; + atype->size_is = dim; + } + + ptype = &(*ptype)->ref; + if (*ptype == NULL) + error("%s: too many expressions in size_is attribute\n", v->name); + } + + ptype = &v->type; + if (lengs) LIST_FOR_EACH_ENTRY(dim, lengs, expr_t, entry) + { + if (dim->type != EXPR_VOID) + { + has_varconf = TRUE; + atype = *ptype = duptype(*ptype, 0); + + if (atype->type == RPC_FC_SMFARRAY) + atype->type = RPC_FC_SMVARRAY; + else if (atype->type == RPC_FC_LGFARRAY) + atype->type = RPC_FC_LGVARRAY; + else if (atype->type == RPC_FC_CARRAY) + atype->type = RPC_FC_CVARRAY; + else + error("%s: length_is attribute applied to illegal type\n", v->name); + + atype->length_is = dim; + } + + ptype = &(*ptype)->ref; + if (*ptype == NULL) + error("%s: too many expressions in length_is attribute\n", v->name); + } + + if (has_varconf && !last_array(v->type)) + { + ptype = &v->type; + for (ptype = &v->type; is_array(*ptype); ptype = &(*ptype)->ref) + { + *ptype = duptype(*ptype, 0); + (*ptype)->type = RPC_FC_BOGUS_ARRAY; + } + } + + if (is_array(v->type)) + { + const type_t *rt = v->type->ref; + if (is_user_type(rt)) + v->type->type = RPC_FC_BOGUS_ARRAY; + else + switch (rt->type) + { + case RPC_FC_BOGUS_STRUCT: + case RPC_FC_NON_ENCAPSULATED_UNION: + case RPC_FC_ENCAPSULATED_UNION: + case RPC_FC_ENUM16: + v->type->type = RPC_FC_BOGUS_ARRAY; + break; + /* FC_RP should be above, but widl overuses these, and will break things. */ + case RPC_FC_UP: + case RPC_FC_RP: + if (rt->ref->type == RPC_FC_IP) + v->type->type = RPC_FC_BOGUS_ARRAY; + break; + } + } } -static typeref_t *uniq_tref(typeref_t *ref) +static ifref_list_t *append_ifref(ifref_list_t *list, ifref_t *iface) { - typeref_t *t = ref; - type_t *tp; - if (t->uniq) return t; - tp = make_type(0, t->ref); - tp->name = t->name; - t->name = NULL; - t->ref = tp; - t->uniq = 1; - return t; -} - -static type_t *type_ref(typeref_t *ref) -{ - type_t *t = ref->ref; - if (ref->name) free(ref->name); - free(ref); - return t; -} - -static void set_type(var_t *v, typeref_t *ref, expr_t *arr) -{ - v->type = ref->ref; - v->tname = ref->name; - ref->name = NULL; - free(ref); - v->array = arr; + if (!iface) return list; + if (!list) + { + list = xmalloc( sizeof(*list) ); + list_init( list ); + } + list_add_tail( list, &iface->entry ); + return list; } static ifref_t *make_ifref(type_t *iface) @@ -3868,32 +4437,70 @@ static ifref_t *make_ifref(type_t *iface) ifref_t *l = xmalloc(sizeof(ifref_t)); l->iface = iface; l->attrs = NULL; - INIT_LINK(l); return l; } +static var_list_t *append_var(var_list_t *list, var_t *var) +{ + if (!var) return list; + if (!list) + { + list = xmalloc( sizeof(*list) ); + list_init( list ); + } + list_add_tail( list, &var->entry ); + return list; +} + static var_t *make_var(char *name) { var_t *v = xmalloc(sizeof(var_t)); v->name = name; - v->ptr_level = 0; v->type = NULL; - v->tname = NULL; + v->args = NULL; v->attrs = NULL; - v->array = NULL; v->eval = NULL; - INIT_LINK(v); return v; } -static func_t *make_func(var_t *def, var_t *args) +static pident_list_t *append_pident(pident_list_t *list, pident_t *p) +{ + if (!p) return list; + if (!list) { + list = xmalloc(sizeof(*list)); + list_init(list); + } + list_add_tail(list, &p->entry); + return list; +} + +static pident_t *make_pident(var_t *var) +{ + pident_t *p = xmalloc(sizeof(*p)); + p->var = var; + p->ptr_level = 0; + return p; +} + +static func_list_t *append_func(func_list_t *list, func_t *func) +{ + if (!func) return list; + if (!list) + { + list = xmalloc( sizeof(*list) ); + list_init( list ); + } + list_add_tail( list, &func->entry ); + return list; +} + +static func_t *make_func(var_t *def, var_list_t *args) { func_t *f = xmalloc(sizeof(func_t)); f->def = def; f->args = args; f->ignore = parse_only; f->idx = -1; - INIT_LINK(f); return f; } @@ -3902,13 +4509,14 @@ static type_t *make_class(char *name) type_t *c = make_type(0, NULL); c->name = name; c->kind = TKIND_COCLASS; - INIT_LINK(c); return c; } -static type_t *make_safearray(void) +static type_t *make_safearray(type_t *type) { - return make_type(RPC_FC_FP, find_type("SAFEARRAY", 0)); + type_t *sa = duptype(find_type("SAFEARRAY", 0), 1); + sa->ref = type; + return make_type(pointer_default, sa); } #define HASHMAX 64 @@ -3941,7 +4549,7 @@ static type_t *reg_type(type_t *type, const char *name, int t) struct rtype *nt; int hash; if (!name) { - yyerror("registering named type without name"); + error_loc("registering named type without name\n"); return type; } hash = hash_ident(name); @@ -3954,42 +4562,85 @@ static type_t *reg_type(type_t *type, const char *name, int t) return type; } -/* determine pointer type from attrs */ -static unsigned char get_pointer_type( type_t *type ) +static int is_incomplete(const type_t *t) { - int t; - if (is_attr( type->attrs, ATTR_STRING )) - { - type_t *t = type; - while( t->type == 0 && t->ref ) - t = t->ref; - switch( t->type ) - { - case RPC_FC_CHAR: - return RPC_FC_C_CSTRING; - case RPC_FC_WCHAR: - return RPC_FC_C_WSTRING; - } - } - t = get_attrv( type->attrs, ATTR_POINTERTYPE ); - if (t) return t; - return RPC_FC_FP; + return !t->defined && (is_struct(t->type) || is_union(t->type)); } -static type_t *reg_types(type_t *type, var_t *names, int t) +static void add_incomplete(type_t *t) +{ + struct typenode *tn = xmalloc(sizeof *tn); + tn->type = t; + list_add_tail(&incomplete_types, &tn->entry); +} + +static void fix_type(type_t *t) +{ + if (t->kind == TKIND_ALIAS && is_incomplete(t)) { + type_t *ot = t->orig; + fix_type(ot); + t->fields = ot->fields; + t->defined = ot->defined; + } +} + +static void fix_incomplete(void) +{ + struct typenode *tn, *next; + + LIST_FOR_EACH_ENTRY_SAFE(tn, next, &incomplete_types, struct typenode, entry) { + fix_type(tn->type); + free(tn); + } +} + +static type_t *reg_typedefs(type_t *type, pident_list_t *pidents, attr_list_t *attrs) { type_t *ptr = type; + const pident_t *pident; int ptrc = 0; + int is_str = is_attr(attrs, ATTR_STRING); + unsigned char ptr_type = get_attrv(attrs, ATTR_POINTERTYPE); - while (names) { - var_t *next = NEXT_LINK(names); - if (names->name) { + if (is_str) + { + type_t *t = type; + unsigned char c; + + while (is_ptr(t)) + t = t->ref; + + c = t->type; + if (c != RPC_FC_CHAR && c != RPC_FC_BYTE && c != RPC_FC_WCHAR) + { + pident = LIST_ENTRY( list_head( pidents ), const pident_t, entry ); + error_loc("'%s': [string] attribute is only valid on 'char', 'byte', or 'wchar_t' pointers and arrays\n", + pident->var->name); + } + } + + /* We must generate names for tagless enum, struct or union. + Typedef-ing a tagless enum, struct or union means we want the typedef + to be included in a library whether it has other attributes or not, + hence the public attribute. */ + if ((type->kind == TKIND_ENUM || type->kind == TKIND_RECORD + || type->kind == TKIND_UNION) && ! type->name && ! parse_only) + { + if (! is_attr(attrs, ATTR_PUBLIC)) + attrs = append_attr( attrs, make_attr(ATTR_PUBLIC) ); + type->name = gen_name(); + } + + LIST_FOR_EACH_ENTRY( pident, pidents, const pident_t, entry ) + { + var_t *name = pident->var; + + if (name->name) { type_t *cur = ptr; - int cptr = names->ptr_level; + int cptr = pident->ptr_level; if (cptr > ptrc) { while (cptr > ptrc) { - int t = get_pointer_type( cur ); - cur = ptr = make_type(t, cur); + cur = ptr = make_type(pointer_default, cur); ptrc++; } } else { @@ -3998,10 +4649,24 @@ static type_t *reg_types(type_t *type, var_t *names, int t) cptr++; } } - reg_type(cur, names->name, t); + cur = alias(cur, name->name); + cur->attrs = attrs; + if (ptr_type) + { + if (is_ptr(cur)) + cur->type = ptr_type; + else + error_loc("'%s': pointer attribute applied to non-pointer type\n", + cur->name); + } + else if (is_str && ! is_ptr(cur)) + error_loc("'%s': [string] attribute applied to non-pointer type\n", + cur->name); + + if (is_incomplete(cur)) + add_incomplete(cur); + reg_type(cur, cur->name, 0); } - free(names); - names = next; } return type; } @@ -4012,7 +4677,7 @@ static type_t *find_type(const char *name, int t) while (cur && (cur->t != t || strcmp(cur->name, name))) cur = cur->next; if (!cur) { - yyerror("type '%s' not found", name); + error_loc("type '%s' not found\n", name); return NULL; } return cur->type; @@ -4063,44 +4728,66 @@ static type_t *get_typev(unsigned char type, var_t *name, int t) return get_type(type, sname, t); } -static int get_struct_type(var_t *field) +static int get_struct_type(var_list_t *fields) { int has_pointer = 0; int has_conformance = 0; int has_variance = 0; + var_t *field; - for (; field; field = NEXT_LINK(field)) + if (get_padding(fields)) + return RPC_FC_BOGUS_STRUCT; + + if (fields) LIST_FOR_EACH_ENTRY( field, fields, var_t, entry ) { type_t *t = field->type; - /* get the base type */ - while( (t->type == 0) && t->ref ) - t = t->ref; + if (is_user_type(t)) + return RPC_FC_BOGUS_STRUCT; - if (field->ptr_level > 0) + if (is_ptr(t)) { + do + t = t->ref; + while (is_ptr(t)); + + switch (t->type) + { + case RPC_FC_IP: + case RPC_FC_ENCAPSULATED_UNION: + case RPC_FC_NON_ENCAPSULATED_UNION: + case RPC_FC_BOGUS_STRUCT: + return RPC_FC_BOGUS_STRUCT; + } + has_pointer = 1; continue; } - if (is_string_type(field->attrs, 0, field->array)) + if (field->type->declarray) { - has_conformance = 1; - has_variance = 1; - continue; - } + if (is_string_type(field->attrs, field->type)) + { + if (is_conformant_array(field->type)) + has_conformance = 1; + has_variance = 1; + continue; + } - if (is_array_type(field->attrs, 0, field->array)) - { - if (field->array && !field->array->is_const) + if (is_array(field->type->ref)) + return RPC_FC_BOGUS_STRUCT; + + if (is_conformant_array(field->type)) { has_conformance = 1; - if (PREV_LINK(field)) - yyerror("field '%s' deriving from a conformant array must be the last field in the structure", + if (field->type->declarray && list_next(fields, &field->entry)) + error_loc("field '%s' deriving from a conformant array must be the last field in the structure\n", field->name); } - if (is_attr(field->attrs, ATTR_LENGTHIS)) + if (field->type->length_is) has_variance = 1; + + t = field->type->ref; } switch (t->type) @@ -4131,20 +4818,14 @@ static int get_struct_type(var_t *field) case RPC_FC_ENUM32: break; + case RPC_FC_RP: case RPC_FC_UP: case RPC_FC_FP: - has_pointer = 1; - break; + case RPC_FC_OP: case RPC_FC_CARRAY: - has_conformance = 1; - if (PREV_LINK(field)) - yyerror("field '%s' deriving from a conformant array must be the last field in the structure", - field->name); - break; - case RPC_FC_C_CSTRING: - case RPC_FC_C_WSTRING: - has_conformance = 1; - has_variance = 1; + case RPC_FC_CVARRAY: + case RPC_FC_BOGUS_ARRAY: + has_pointer = 1; break; /* @@ -4159,16 +4840,16 @@ static int get_struct_type(var_t *field) case RPC_FC_CPSTRUCT: has_conformance = 1; - if (PREV_LINK(field)) - yyerror("field '%s' deriving from a conformant array must be the last field in the structure", + if (list_next( fields, &field->entry )) + error_loc("field '%s' deriving from a conformant array must be the last field in the structure\n", field->name); has_pointer = 1; break; case RPC_FC_CSTRUCT: has_conformance = 1; - if (PREV_LINK(field)) - yyerror("field '%s' deriving from a conformant array must be the last field in the structure", + if (list_next( fields, &field->entry )) + error_loc("field '%s' deriving from a conformant array must be the last field in the structure\n", field->name); break; @@ -4177,25 +4858,24 @@ static int get_struct_type(var_t *field) break; default: - fprintf(stderr,"Unknown struct member %s with type (0x%02x)\n", - field->name, t->type); + error_loc("Unknown struct member %s with type (0x%02x)\n", field->name, t->type); /* fallthru - treat it as complex */ /* as soon as we see one of these these members, it's bogus... */ - case RPC_FC_IP: case RPC_FC_ENCAPSULATED_UNION: case RPC_FC_NON_ENCAPSULATED_UNION: - case RPC_FC_TRANSMIT_AS: - case RPC_FC_REPRESENT_AS: - case RPC_FC_PAD: - case RPC_FC_EMBEDDED_COMPLEX: case RPC_FC_BOGUS_STRUCT: return RPC_FC_BOGUS_STRUCT; } } if( has_variance ) - return RPC_FC_CVSTRUCT; + { + if ( has_conformance ) + return RPC_FC_CVSTRUCT; + else + return RPC_FC_BOGUS_STRUCT; + } if( has_conformance && has_pointer ) return RPC_FC_CPSTRUCT; if( has_conformance ) @@ -4220,7 +4900,7 @@ static var_t *reg_const(var_t *var) struct rconst *nc; int hash; if (!var->name) { - yyerror("registering constant without name"); + error_loc("registering constant without name\n"); return var; } hash = hash_ident(var->name); @@ -4238,9 +4918,136 @@ static var_t *find_const(char *name, int f) while (cur && strcmp(cur->name, name)) cur = cur->next; if (!cur) { - if (f) yyerror("constant '%s' not found", name); + if (f) error_loc("constant '%s' not found\n", name); return NULL; } return cur->var; } +static void write_libid(const char *name, const attr_list_t *attr) +{ + const UUID *uuid = get_attrp(attr, ATTR_UUID); + write_guid(idfile, "LIBID", name, uuid); +} + +static void write_clsid(type_t *cls) +{ + const UUID *uuid = get_attrp(cls->attrs, ATTR_UUID); + write_guid(idfile, "CLSID", cls->name, uuid); +} + +static void write_diid(type_t *iface) +{ + const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID); + write_guid(idfile, "DIID", iface->name, uuid); +} + +static void write_iid(type_t *iface) +{ + const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID); + write_guid(idfile, "IID", iface->name, uuid); +} + +static int compute_method_indexes(type_t *iface) +{ + int idx; + func_t *f; + + if (iface->ref) + idx = compute_method_indexes(iface->ref); + else + idx = 0; + + if (!iface->funcs) + return idx; + + LIST_FOR_EACH_ENTRY( f, iface->funcs, func_t, entry ) + if (! is_callas(f->def->attrs)) + f->idx = idx++; + + return idx; +} + +static char *gen_name(void) +{ + static const char format[] = "__WIDL_%s_generated_name_%08lX"; + static unsigned long n = 0; + static const char *file_id; + static size_t size; + char *name; + + if (! file_id) + { + char *dst = dup_basename(input_name, ".idl"); + file_id = dst; + + for (; *dst; ++dst) + if (! isalnum((unsigned char) *dst)) + *dst = '_'; + + size = sizeof format - 7 + strlen(file_id) + 8; + } + + name = xmalloc(size); + sprintf(name, format, file_id, n++); + return name; +} + +static void process_typedefs(pident_list_t *pidents) +{ + pident_t *pident, *next; + + if (!pidents) return; + LIST_FOR_EACH_ENTRY_SAFE( pident, next, pidents, pident_t, entry ) + { + var_t *var = pident->var; + type_t *type = find_type(var->name, 0); + + if (! parse_only && do_header) + write_typedef(type); + if (in_typelib && type->attrs) + add_typelib_entry(type); + + free(pident); + free(var); + } +} + +static void check_arg(var_t *arg) +{ + type_t *t = arg->type; + + if (t->type == 0 && ! is_var_ptr(arg)) + error_loc("argument '%s' has void type\n", arg->name); +} + +static void check_all_user_types(ifref_list_t *ifrefs) +{ + const ifref_t *ifref; + const func_t *f; + + if (ifrefs) LIST_FOR_EACH_ENTRY(ifref, ifrefs, const ifref_t, entry) + { + const func_list_t *fs = ifref->iface->funcs; + if (fs) LIST_FOR_EACH_ENTRY(f, fs, const func_t, entry) + check_for_user_types_and_context_handles(f->args); + } +} + +int is_valid_uuid(const char *s) +{ + int i; + + for (i = 0; i < 36; ++i) + if (i == 8 || i == 13 || i == 18 || i == 23) + { + if (s[i] != '-') + return FALSE; + } + else + if (!isxdigit(s[i])) + return FALSE; + + return s[i] == '\0'; +} + diff --git a/reactos/tools/widl/parser.tab.h b/reactos/tools/widl/parser.tab.h index 8c33a70aa9f..33694501d63 100644 --- a/reactos/tools/widl/parser.tab.h +++ b/reactos/tools/widl/parser.tab.h @@ -1,7 +1,7 @@ -/* A Bison parser, made by GNU Bison 1.875. */ +/* A Bison parser, made by GNU Bison 2.1. */ /* Skeleton parser for Yacc-like parsing with Bison, - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc. + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -15,8 +15,8 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ /* As a special exception, when this file is copied by Bison into a Bison output file, you may use that output file without restriction. @@ -33,292 +33,307 @@ aKNOWNTYPE = 259, aNUM = 260, aHEXNUM = 261, - aSTRING = 262, - aUUID = 263, - aEOF = 264, - SHL = 265, - SHR = 266, - tAGGREGATABLE = 267, - tALLOCATE = 268, - tAPPOBJECT = 269, - tASYNC = 270, - tASYNCUUID = 271, - tAUTOHANDLE = 272, - tBINDABLE = 273, - tBOOLEAN = 274, - tBROADCAST = 275, - tBYTE = 276, - tBYTECOUNT = 277, - tCALLAS = 278, - tCALLBACK = 279, - tCASE = 280, - tCDECL = 281, - tCHAR = 282, - tCOCLASS = 283, - tCODE = 284, - tCOMMSTATUS = 285, - tCONST = 286, - tCONTEXTHANDLE = 287, - tCONTEXTHANDLENOSERIALIZE = 288, - tCONTEXTHANDLESERIALIZE = 289, - tCONTROL = 290, - tCPPQUOTE = 291, - tDEFAULT = 292, - tDEFAULTCOLLELEM = 293, - tDEFAULTVALUE = 294, - tDEFAULTVTABLE = 295, - tDISPLAYBIND = 296, - tDISPINTERFACE = 297, - tDLLNAME = 298, - tDOUBLE = 299, - tDUAL = 300, - tENDPOINT = 301, - tENTRY = 302, - tENUM = 303, - tERRORSTATUST = 304, - tEXPLICITHANDLE = 305, - tEXTERN = 306, - tFALSE = 307, - tFLOAT = 308, - tHANDLE = 309, - tHANDLET = 310, - tHELPCONTEXT = 311, - tHELPFILE = 312, - tHELPSTRING = 313, - tHELPSTRINGCONTEXT = 314, - tHELPSTRINGDLL = 315, - tHIDDEN = 316, - tHYPER = 317, - tID = 318, - tIDEMPOTENT = 319, - tIIDIS = 320, - tIMMEDIATEBIND = 321, - tIMPLICITHANDLE = 322, - tIMPORT = 323, - tIMPORTLIB = 324, - tIN = 325, - tINLINE = 326, - tINPUTSYNC = 327, - tINT = 328, - tINT64 = 329, - tINTERFACE = 330, - tLCID = 331, - tLENGTHIS = 332, - tLIBRARY = 333, - tLOCAL = 334, - tLONG = 335, - tMETHODS = 336, - tMODULE = 337, - tNONBROWSABLE = 338, - tNONCREATABLE = 339, - tNONEXTENSIBLE = 340, - tOBJECT = 341, - tODL = 342, - tOLEAUTOMATION = 343, - tOPTIONAL = 344, - tOUT = 345, - tPOINTERDEFAULT = 346, - tPROPERTIES = 347, - tPROPGET = 348, - tPROPPUT = 349, - tPROPPUTREF = 350, - tPTR = 351, - tPUBLIC = 352, - tRANGE = 353, - tREADONLY = 354, - tREF = 355, - tREQUESTEDIT = 356, - tRESTRICTED = 357, - tRETVAL = 358, - tSAFEARRAY = 359, - tSHORT = 360, - tSIGNED = 361, - tSINGLE = 362, - tSIZEIS = 363, - tSIZEOF = 364, - tSMALL = 365, - tSOURCE = 366, - tSTDCALL = 367, - tSTRING = 368, - tSTRUCT = 369, - tSWITCH = 370, - tSWITCHIS = 371, - tSWITCHTYPE = 372, - tTRANSMITAS = 373, - tTRUE = 374, - tTYPEDEF = 375, - tUNION = 376, - tUNIQUE = 377, - tUNSIGNED = 378, - tUUID = 379, - tV1ENUM = 380, - tVARARG = 381, - tVERSION = 382, - tVOID = 383, - tWCHAR = 384, - tWIREMARSHAL = 385, - CAST = 386, - PPTR = 387, - NEG = 388 + aDOUBLE = 262, + aSTRING = 263, + aUUID = 264, + aEOF = 265, + SHL = 266, + SHR = 267, + tAGGREGATABLE = 268, + tALLOCATE = 269, + tAPPOBJECT = 270, + tASYNC = 271, + tASYNCUUID = 272, + tAUTOHANDLE = 273, + tBINDABLE = 274, + tBOOLEAN = 275, + tBROADCAST = 276, + tBYTE = 277, + tBYTECOUNT = 278, + tCALLAS = 279, + tCALLBACK = 280, + tCASE = 281, + tCDECL = 282, + tCHAR = 283, + tCOCLASS = 284, + tCODE = 285, + tCOMMSTATUS = 286, + tCONST = 287, + tCONTEXTHANDLE = 288, + tCONTEXTHANDLENOSERIALIZE = 289, + tCONTEXTHANDLESERIALIZE = 290, + tCONTROL = 291, + tCPPQUOTE = 292, + tDEFAULT = 293, + tDEFAULTCOLLELEM = 294, + tDEFAULTVALUE = 295, + tDEFAULTVTABLE = 296, + tDISPLAYBIND = 297, + tDISPINTERFACE = 298, + tDLLNAME = 299, + tDOUBLE = 300, + tDUAL = 301, + tENDPOINT = 302, + tENTRY = 303, + tENUM = 304, + tERRORSTATUST = 305, + tEXPLICITHANDLE = 306, + tEXTERN = 307, + tFALSE = 308, + tFLOAT = 309, + tHANDLE = 310, + tHANDLET = 311, + tHELPCONTEXT = 312, + tHELPFILE = 313, + tHELPSTRING = 314, + tHELPSTRINGCONTEXT = 315, + tHELPSTRINGDLL = 316, + tHIDDEN = 317, + tHYPER = 318, + tID = 319, + tIDEMPOTENT = 320, + tIIDIS = 321, + tIMMEDIATEBIND = 322, + tIMPLICITHANDLE = 323, + tIMPORT = 324, + tIMPORTLIB = 325, + tIN = 326, + tINLINE = 327, + tINPUTSYNC = 328, + tINT = 329, + tINT64 = 330, + tINTERFACE = 331, + tLCID = 332, + tLENGTHIS = 333, + tLIBRARY = 334, + tLOCAL = 335, + tLONG = 336, + tMETHODS = 337, + tMODULE = 338, + tNONBROWSABLE = 339, + tNONCREATABLE = 340, + tNONEXTENSIBLE = 341, + tOBJECT = 342, + tODL = 343, + tOLEAUTOMATION = 344, + tOPTIONAL = 345, + tOUT = 346, + tPOINTERDEFAULT = 347, + tPROPERTIES = 348, + tPROPGET = 349, + tPROPPUT = 350, + tPROPPUTREF = 351, + tPTR = 352, + tPUBLIC = 353, + tRANGE = 354, + tREADONLY = 355, + tREF = 356, + tREQUESTEDIT = 357, + tRESTRICTED = 358, + tRETVAL = 359, + tSAFEARRAY = 360, + tSHORT = 361, + tSIGNED = 362, + tSINGLE = 363, + tSIZEIS = 364, + tSIZEOF = 365, + tSMALL = 366, + tSOURCE = 367, + tSTDCALL = 368, + tSTRING = 369, + tSTRUCT = 370, + tSWITCH = 371, + tSWITCHIS = 372, + tSWITCHTYPE = 373, + tTRANSMITAS = 374, + tTRUE = 375, + tTYPEDEF = 376, + tUNION = 377, + tUNIQUE = 378, + tUNSIGNED = 379, + tUUID = 380, + tV1ENUM = 381, + tVARARG = 382, + tVERSION = 383, + tVOID = 384, + tWCHAR = 385, + tWIREMARSHAL = 386, + CAST = 387, + PPTR = 388, + NEG = 389, + ADDRESSOF = 390 }; #endif +/* Tokens. */ #define aIDENTIFIER 258 #define aKNOWNTYPE 259 #define aNUM 260 #define aHEXNUM 261 -#define aSTRING 262 -#define aUUID 263 -#define aEOF 264 -#define SHL 265 -#define SHR 266 -#define tAGGREGATABLE 267 -#define tALLOCATE 268 -#define tAPPOBJECT 269 -#define tASYNC 270 -#define tASYNCUUID 271 -#define tAUTOHANDLE 272 -#define tBINDABLE 273 -#define tBOOLEAN 274 -#define tBROADCAST 275 -#define tBYTE 276 -#define tBYTECOUNT 277 -#define tCALLAS 278 -#define tCALLBACK 279 -#define tCASE 280 -#define tCDECL 281 -#define tCHAR 282 -#define tCOCLASS 283 -#define tCODE 284 -#define tCOMMSTATUS 285 -#define tCONST 286 -#define tCONTEXTHANDLE 287 -#define tCONTEXTHANDLENOSERIALIZE 288 -#define tCONTEXTHANDLESERIALIZE 289 -#define tCONTROL 290 -#define tCPPQUOTE 291 -#define tDEFAULT 292 -#define tDEFAULTCOLLELEM 293 -#define tDEFAULTVALUE 294 -#define tDEFAULTVTABLE 295 -#define tDISPLAYBIND 296 -#define tDISPINTERFACE 297 -#define tDLLNAME 298 -#define tDOUBLE 299 -#define tDUAL 300 -#define tENDPOINT 301 -#define tENTRY 302 -#define tENUM 303 -#define tERRORSTATUST 304 -#define tEXPLICITHANDLE 305 -#define tEXTERN 306 -#define tFALSE 307 -#define tFLOAT 308 -#define tHANDLE 309 -#define tHANDLET 310 -#define tHELPCONTEXT 311 -#define tHELPFILE 312 -#define tHELPSTRING 313 -#define tHELPSTRINGCONTEXT 314 -#define tHELPSTRINGDLL 315 -#define tHIDDEN 316 -#define tHYPER 317 -#define tID 318 -#define tIDEMPOTENT 319 -#define tIIDIS 320 -#define tIMMEDIATEBIND 321 -#define tIMPLICITHANDLE 322 -#define tIMPORT 323 -#define tIMPORTLIB 324 -#define tIN 325 -#define tINLINE 326 -#define tINPUTSYNC 327 -#define tINT 328 -#define tINT64 329 -#define tINTERFACE 330 -#define tLCID 331 -#define tLENGTHIS 332 -#define tLIBRARY 333 -#define tLOCAL 334 -#define tLONG 335 -#define tMETHODS 336 -#define tMODULE 337 -#define tNONBROWSABLE 338 -#define tNONCREATABLE 339 -#define tNONEXTENSIBLE 340 -#define tOBJECT 341 -#define tODL 342 -#define tOLEAUTOMATION 343 -#define tOPTIONAL 344 -#define tOUT 345 -#define tPOINTERDEFAULT 346 -#define tPROPERTIES 347 -#define tPROPGET 348 -#define tPROPPUT 349 -#define tPROPPUTREF 350 -#define tPTR 351 -#define tPUBLIC 352 -#define tRANGE 353 -#define tREADONLY 354 -#define tREF 355 -#define tREQUESTEDIT 356 -#define tRESTRICTED 357 -#define tRETVAL 358 -#define tSAFEARRAY 359 -#define tSHORT 360 -#define tSIGNED 361 -#define tSINGLE 362 -#define tSIZEIS 363 -#define tSIZEOF 364 -#define tSMALL 365 -#define tSOURCE 366 -#define tSTDCALL 367 -#define tSTRING 368 -#define tSTRUCT 369 -#define tSWITCH 370 -#define tSWITCHIS 371 -#define tSWITCHTYPE 372 -#define tTRANSMITAS 373 -#define tTRUE 374 -#define tTYPEDEF 375 -#define tUNION 376 -#define tUNIQUE 377 -#define tUNSIGNED 378 -#define tUUID 379 -#define tV1ENUM 380 -#define tVARARG 381 -#define tVERSION 382 -#define tVOID 383 -#define tWCHAR 384 -#define tWIREMARSHAL 385 -#define CAST 386 -#define PPTR 387 -#define NEG 388 +#define aDOUBLE 262 +#define aSTRING 263 +#define aUUID 264 +#define aEOF 265 +#define SHL 266 +#define SHR 267 +#define tAGGREGATABLE 268 +#define tALLOCATE 269 +#define tAPPOBJECT 270 +#define tASYNC 271 +#define tASYNCUUID 272 +#define tAUTOHANDLE 273 +#define tBINDABLE 274 +#define tBOOLEAN 275 +#define tBROADCAST 276 +#define tBYTE 277 +#define tBYTECOUNT 278 +#define tCALLAS 279 +#define tCALLBACK 280 +#define tCASE 281 +#define tCDECL 282 +#define tCHAR 283 +#define tCOCLASS 284 +#define tCODE 285 +#define tCOMMSTATUS 286 +#define tCONST 287 +#define tCONTEXTHANDLE 288 +#define tCONTEXTHANDLENOSERIALIZE 289 +#define tCONTEXTHANDLESERIALIZE 290 +#define tCONTROL 291 +#define tCPPQUOTE 292 +#define tDEFAULT 293 +#define tDEFAULTCOLLELEM 294 +#define tDEFAULTVALUE 295 +#define tDEFAULTVTABLE 296 +#define tDISPLAYBIND 297 +#define tDISPINTERFACE 298 +#define tDLLNAME 299 +#define tDOUBLE 300 +#define tDUAL 301 +#define tENDPOINT 302 +#define tENTRY 303 +#define tENUM 304 +#define tERRORSTATUST 305 +#define tEXPLICITHANDLE 306 +#define tEXTERN 307 +#define tFALSE 308 +#define tFLOAT 309 +#define tHANDLE 310 +#define tHANDLET 311 +#define tHELPCONTEXT 312 +#define tHELPFILE 313 +#define tHELPSTRING 314 +#define tHELPSTRINGCONTEXT 315 +#define tHELPSTRINGDLL 316 +#define tHIDDEN 317 +#define tHYPER 318 +#define tID 319 +#define tIDEMPOTENT 320 +#define tIIDIS 321 +#define tIMMEDIATEBIND 322 +#define tIMPLICITHANDLE 323 +#define tIMPORT 324 +#define tIMPORTLIB 325 +#define tIN 326 +#define tINLINE 327 +#define tINPUTSYNC 328 +#define tINT 329 +#define tINT64 330 +#define tINTERFACE 331 +#define tLCID 332 +#define tLENGTHIS 333 +#define tLIBRARY 334 +#define tLOCAL 335 +#define tLONG 336 +#define tMETHODS 337 +#define tMODULE 338 +#define tNONBROWSABLE 339 +#define tNONCREATABLE 340 +#define tNONEXTENSIBLE 341 +#define tOBJECT 342 +#define tODL 343 +#define tOLEAUTOMATION 344 +#define tOPTIONAL 345 +#define tOUT 346 +#define tPOINTERDEFAULT 347 +#define tPROPERTIES 348 +#define tPROPGET 349 +#define tPROPPUT 350 +#define tPROPPUTREF 351 +#define tPTR 352 +#define tPUBLIC 353 +#define tRANGE 354 +#define tREADONLY 355 +#define tREF 356 +#define tREQUESTEDIT 357 +#define tRESTRICTED 358 +#define tRETVAL 359 +#define tSAFEARRAY 360 +#define tSHORT 361 +#define tSIGNED 362 +#define tSINGLE 363 +#define tSIZEIS 364 +#define tSIZEOF 365 +#define tSMALL 366 +#define tSOURCE 367 +#define tSTDCALL 368 +#define tSTRING 369 +#define tSTRUCT 370 +#define tSWITCH 371 +#define tSWITCHIS 372 +#define tSWITCHTYPE 373 +#define tTRANSMITAS 374 +#define tTRUE 375 +#define tTYPEDEF 376 +#define tUNION 377 +#define tUNIQUE 378 +#define tUNSIGNED 379 +#define tUUID 380 +#define tV1ENUM 381 +#define tVARARG 382 +#define tVERSION 383 +#define tVOID 384 +#define tWCHAR 385 +#define tWIREMARSHAL 386 +#define CAST 387 +#define PPTR 388 +#define NEG 389 +#define ADDRESSOF 390 #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) -#line 109 "parser.y" +#line 136 "parser.y" typedef union YYSTYPE { attr_t *attr; + attr_list_t *attr_list; + str_list_t *str_list; expr_t *expr; + expr_list_t *expr_list; + array_dims_t *array_dims; type_t *type; - typeref_t *tref; var_t *var; + var_list_t *var_list; + pident_t *pident; + pident_list_t *pident_list; func_t *func; + func_list_t *func_list; ifref_t *ifref; + ifref_list_t *ifref_list; char *str; UUID *uuid; unsigned int num; + double dbl; + interface_info_t ifinfo; } YYSTYPE; -/* Line 1248 of yacc.c. */ -#line 315 "parser.tab.h" +/* Line 1447 of yacc.c. */ +#line 331 "parser.tab.h" # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 #endif -extern YYSTYPE yylval; +extern YYSTYPE parser_lval; diff --git a/reactos/tools/widl/parser.y b/reactos/tools/widl/parser.y index 24ec8703f6d..6c8337efefc 100644 --- a/reactos/tools/widl/parser.y +++ b/reactos/tools/widl/parser.y @@ -36,6 +36,7 @@ #include "parser.h" #include "header.h" #include "typelib.h" +#include "typegen.h" #if defined(YYBYACC) /* Berkeley yacc (byacc) doesn't seem to know about these */ @@ -62,64 +63,103 @@ # endif #endif +unsigned char pointer_default = RPC_FC_UP; + +typedef struct list typelist_t; +struct typenode { + type_t *type; + struct list entry; +}; + +typelist_t incomplete_types = LIST_INIT(incomplete_types); + +static void add_incomplete(type_t *t); +static void fix_incomplete(void); + +static str_list_t *append_str(str_list_t *list, char *str); +static attr_list_t *append_attr(attr_list_t *list, attr_t *attr); static attr_t *make_attr(enum attr_type type); static attr_t *make_attrv(enum attr_type type, unsigned long val); static attr_t *make_attrp(enum attr_type type, void *val); static expr_t *make_expr(enum expr_type type); static expr_t *make_exprl(enum expr_type type, long val); +static expr_t *make_exprd(enum expr_type type, double val); static expr_t *make_exprs(enum expr_type type, char *val); -static expr_t *make_exprt(enum expr_type type, typeref_t *tref, expr_t *expr); +static expr_t *make_exprt(enum expr_type type, type_t *tref, expr_t *expr); static expr_t *make_expr1(enum expr_type type, expr_t *expr); static expr_t *make_expr2(enum expr_type type, expr_t *exp1, expr_t *exp2); static expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, expr_t *expr3); static type_t *make_type(unsigned char type, type_t *ref); -static typeref_t *make_tref(char *name, type_t *ref); -static typeref_t *uniq_tref(typeref_t *ref); -static type_t *type_ref(typeref_t *ref); -static void set_type(var_t *v, typeref_t *ref, expr_t *arr); +static expr_list_t *append_expr(expr_list_t *list, expr_t *expr); +static array_dims_t *append_array(array_dims_t *list, expr_t *expr); +static void set_type(var_t *v, type_t *type, int ptr_level, array_dims_t *arr, int top); +static ifref_list_t *append_ifref(ifref_list_t *list, ifref_t *iface); static ifref_t *make_ifref(type_t *iface); +static var_list_t *append_var(var_list_t *list, var_t *var); static var_t *make_var(char *name); -static func_t *make_func(var_t *def, var_t *args); +static pident_list_t *append_pident(pident_list_t *list, pident_t *p); +static pident_t *make_pident(var_t *var); +static func_list_t *append_func(func_list_t *list, func_t *func); +static func_t *make_func(var_t *def, var_list_t *args); static type_t *make_class(char *name); -static type_t *make_safearray(void); +static type_t *make_safearray(type_t *type); +static type_t *make_builtin(char *name); +static type_t *make_int(int sign); static type_t *reg_type(type_t *type, const char *name, int t); -static type_t *reg_types(type_t *type, var_t *names, int t); +static type_t *reg_typedefs(type_t *type, var_list_t *names, attr_list_t *attrs); static type_t *find_type(const char *name, int t); static type_t *find_type2(char *name, int t); static type_t *get_type(unsigned char type, char *name, int t); static type_t *get_typev(unsigned char type, var_t *name, int t); -static int get_struct_type(var_t *fields); +static int get_struct_type(var_list_t *fields); static var_t *reg_const(var_t *var); static var_t *find_const(char *name, int f); +static void write_libid(const char *name, const attr_list_t *attr); +static void write_clsid(type_t *cls); +static void write_diid(type_t *iface); +static void write_iid(type_t *iface); + +static int compute_method_indexes(type_t *iface); +static char *gen_name(void); +static void process_typedefs(var_list_t *names); +static void check_arg(var_t *arg); +static void check_all_user_types(ifref_list_t *ifaces); + #define tsENUM 1 #define tsSTRUCT 2 #define tsUNION 3 -static type_t std_bool = { "boolean" }; -static type_t std_int = { "int" }; -static type_t std_int64 = { "__int64" }; -static type_t std_uhyper = { "MIDL_uhyper" }; - %} %union { attr_t *attr; + attr_list_t *attr_list; + str_list_t *str_list; expr_t *expr; + expr_list_t *expr_list; + array_dims_t *array_dims; type_t *type; - typeref_t *tref; var_t *var; + var_list_t *var_list; + pident_t *pident; + pident_list_t *pident_list; func_t *func; + func_list_t *func_list; ifref_t *ifref; + ifref_list_t *ifref_list; char *str; UUID *uuid; unsigned int num; + double dbl; + interface_info_t ifinfo; } %token aIDENTIFIER %token aKNOWNTYPE %token aNUM aHEXNUM +%token aDOUBLE %token aSTRING %token aUUID %token aEOF @@ -200,25 +240,32 @@ static type_t std_uhyper = { "MIDL_uhyper" }; %token tVOID %token tWCHAR tWIREMARSHAL -%type m_attributes attributes attrib_list attribute -%type m_exprs /* exprs expr_list */ m_expr expr expr_list_const expr_const -%type array array_list -%type inherit interface interfacehdr interfacedef interfacedec +%type attribute +%type m_attributes attributes attrib_list +%type str_list +%type m_expr expr expr_const +%type m_exprs /* exprs expr_list */ expr_list_const +%type array array_list +%type interfacehdr +%type inherit interface interfacedef interfacedec %type dispinterface dispinterfacehdr dispinterfacedef %type module modulehdr moduledef %type base_type int_std -%type enumdef structdef typedef uniondef -%type gbl_statements coclass_ints coclass_int -%type type -%type m_args no_args args arg -%type fields field s_field cases case enums enum_list enum constdef externdef -%type m_ident t_ident ident p_ident pident pident_list -%type dispint_props -%type funcdef int_statements -%type dispint_meths +%type enumdef structdef uniondef +%type type +%type coclass_int +%type gbl_statements coclass_ints +%type arg field s_field case enum constdef externdef +%type m_args no_args args fields cases enums enum_list dispint_props +%type m_ident t_ident ident +%type p_ident pident +%type pident_list +%type funcdef +%type int_statements dispint_meths %type coclass coclasshdr coclassdef %type pointer_type version %type libraryhdr +%type uuid_string %left ',' %right '?' ':' @@ -231,54 +278,75 @@ static type_t std_uhyper = { "MIDL_uhyper" }; %right CAST %right PPTR %right NEG +%right ADDRESSOF %% -input: gbl_statements { write_proxies($1); write_client($1); write_server($1); } +input: gbl_statements { fix_incomplete(); + check_all_user_types($1); + write_proxies($1); + write_client($1); + write_server($1); + write_dlldata($1); + } ; gbl_statements: { $$ = NULL; } | gbl_statements interfacedec { $$ = $1; } - | gbl_statements interfacedef { $$ = make_ifref($2); LINK($$, $1); } + | gbl_statements interfacedef { $$ = append_ifref( $1, make_ifref($2) ); } | gbl_statements coclass ';' { $$ = $1; reg_type($2, $2->name, 0); if (!parse_only && do_header) write_coclass_forward($2); } | gbl_statements coclassdef { $$ = $1; - add_coclass($2); + add_typelib_entry($2); reg_type($2, $2->name, 0); + if (!parse_only && do_header) write_coclass_forward($2); } - | gbl_statements moduledef { $$ = $1; add_module($2); } + | gbl_statements moduledef { $$ = $1; add_typelib_entry($2); } | gbl_statements librarydef { $$ = $1; } | gbl_statements statement { $$ = $1; } ; imp_statements: {} - | imp_statements interfacedec { if (!parse_only) add_interface($2); } - | imp_statements interfacedef { if (!parse_only) add_interface($2); } + | imp_statements interfacedec { if (!parse_only) add_typelib_entry($2); } + | imp_statements interfacedef { if (!parse_only) add_typelib_entry($2); } | imp_statements coclass ';' { reg_type($2, $2->name, 0); if (!parse_only && do_header) write_coclass_forward($2); } - | imp_statements coclassdef { if (!parse_only) add_coclass($2); + | imp_statements coclassdef { if (!parse_only) add_typelib_entry($2); reg_type($2, $2->name, 0); + if (!parse_only && do_header) write_coclass_forward($2); } - | imp_statements moduledef { if (!parse_only) add_module($2); } + | imp_statements moduledef { if (!parse_only) add_typelib_entry($2); } | imp_statements statement {} | imp_statements importlib {} ; int_statements: { $$ = NULL; } - | int_statements funcdef ';' { $$ = $2; LINK($$, $1); } + | int_statements funcdef ';' { $$ = append_func( $1, $2 ); } | int_statements statement { $$ = $1; } ; statement: ';' {} | constdef ';' { if (!parse_only && do_header) { write_constdef($1); } } | cppquote {} - | enumdef ';' { if (!parse_only && do_header) { write_type(header, $1, NULL, NULL); fprintf(header, ";\n\n"); } } + | enumdef ';' { if (!parse_only && do_header) { + write_type_def_or_decl(header, $1, FALSE, NULL); + fprintf(header, ";\n\n"); + } + } | externdef ';' { if (!parse_only && do_header) { write_externdef($1); } } | import {} - | structdef ';' { if (!parse_only && do_header) { write_type(header, $1, NULL, NULL); fprintf(header, ";\n\n"); } } + | structdef ';' { if (!parse_only && do_header) { + write_type_def_or_decl(header, $1, FALSE, NULL); + fprintf(header, ";\n\n"); + } + } | typedef ';' {} - | uniondef ';' { if (!parse_only && do_header) { write_type(header, $1, NULL, NULL); fprintf(header, ";\n\n"); } } + | uniondef ';' { if (!parse_only && do_header) { + write_type_def_or_decl(header, $1, FALSE, NULL); + fprintf(header, ";\n\n"); + } + } ; cppquote: tCPPQUOTE '(' aSTRING ')' { if (!parse_only && do_header) fprintf(header, "%s\n", $3); } @@ -295,7 +363,9 @@ importlib: tIMPORTLIB '(' aSTRING ')' { if(!parse_only) add_importlib($3); } libraryhdr: tLIBRARY aIDENTIFIER { $$ = $2; } ; library_start: attributes libraryhdr '{' { start_typelib($2, $1); - if (!parse_only && do_header) write_library($2, $1); } + if (!parse_only && do_header) write_library($2, $1); + if (!parse_only && do_idfile) write_libid($2, $1); + } ; librarydef: library_start imp_statements '}' { end_typelib(); } ; @@ -307,40 +377,42 @@ m_args: { $$ = NULL; } no_args: tVOID { $$ = NULL; } ; -args: arg - | args ',' arg { LINK($3, $1); $$ = $3; } +args: arg { check_arg($1); $$ = append_var( NULL, $1 ); } + | args ',' arg { check_arg($3); $$ = append_var( $1, $3); } | no_args ; /* split into two rules to get bison to resolve a tVOID conflict */ -arg: attributes type pident array { $$ = $3; - set_type($$, $2, $4); +arg: attributes type pident array { $$ = $3->var; $$->attrs = $1; + set_type($$, $2, $3->ptr_level, $4, TRUE); + free($3); } - | type pident array { $$ = $2; - set_type($$, $1, $3); + | type pident array { $$ = $2->var; + set_type($$, $1, $2->ptr_level, $3, TRUE); + free($2); } - | attributes type pident '(' m_args ')' { $$ = $3; - $$->ptr_level--; - set_type($$, $2, NULL); + | attributes type pident '(' m_args ')' { $$ = $3->var; $$->attrs = $1; + set_type($$, $2, $3->ptr_level - 1, NULL, TRUE); + free($3); $$->args = $5; } - | type pident '(' m_args ')' { $$ = $2; - $$->ptr_level--; - set_type($$, $1, NULL); + | type pident '(' m_args ')' { $$ = $2->var; + set_type($$, $1, $2->ptr_level - 1, NULL, TRUE); + free($2); $$->args = $4; } ; array: { $$ = NULL; } | '[' array_list ']' { $$ = $2; } - | '[' '*' ']' { $$ = make_expr(EXPR_VOID); } + | '[' '*' ']' { $$ = append_array( NULL, make_expr(EXPR_VOID) ); } ; -array_list: m_expr /* size of first dimension is optional */ - | array_list ',' expr { LINK($3, $1); $$ = $3; } - | array_list ']' '[' expr { LINK($4, $1); $$ = $4; } +array_list: m_expr /* size of first dimension is optional */ { $$ = append_array( NULL, $1 ); } + | array_list ',' expr { $$ = append_array( $1, $3 ); } + | array_list ']' '[' expr { $$ = append_array( $1, $4 ); } ; m_attributes: { $$ = NULL; } @@ -350,17 +422,17 @@ m_attributes: { $$ = NULL; } attributes: '[' attrib_list ']' { $$ = $2; if (!$$) - yyerror("empty attribute lists unsupported"); + error_loc("empty attribute lists unsupported\n"); } ; -attrib_list: attribute - | attrib_list ',' attribute { if ($3) { LINK($3, $1); $$ = $3; } - else { $$ = $1; } - } - | attrib_list ']' '[' attribute { if ($4) { LINK($4, $1); $$ = $4; } - else { $$ = $1; } - } +attrib_list: attribute { $$ = append_attr( NULL, $1 ); } + | attrib_list ',' attribute { $$ = append_attr( $1, $3 ); } + | attrib_list ']' '[' attribute { $$ = append_attr( $1, $4 ); } + ; + +str_list: aSTRING { $$ = append_str( NULL, $1 ); } + | str_list ',' aSTRING { $$ = append_str( $1, $3 ); } ; attribute: { $$ = NULL; } @@ -383,7 +455,7 @@ attribute: { $$ = NULL; } | tDISPLAYBIND { $$ = make_attr(ATTR_DISPLAYBIND); } | tDLLNAME '(' aSTRING ')' { $$ = make_attrp(ATTR_DLLNAME, $3); } | tDUAL { $$ = make_attr(ATTR_DUAL); } - | tENDPOINT '(' aSTRING ')' { $$ = make_attrp(ATTR_ENDPOINT, $3); } + | tENDPOINT '(' str_list ')' { $$ = make_attrp(ATTR_ENDPOINT, $3); } | tENTRY '(' aSTRING ')' { $$ = make_attrp(ATTR_ENTRY_STRING, $3); } | tENTRY '(' expr_const ')' { $$ = make_attrp(ATTR_ENTRY_ORDINAL, $3); } | tEXPLICITHANDLE { $$ = make_attr(ATTR_EXPLICIT_HANDLE); } @@ -396,7 +468,7 @@ attribute: { $$ = NULL; } | tHIDDEN { $$ = make_attr(ATTR_HIDDEN); } | tID '(' expr_const ')' { $$ = make_attrp(ATTR_ID, $3); } | tIDEMPOTENT { $$ = make_attr(ATTR_IDEMPOTENT); } - | tIIDIS '(' ident ')' { $$ = make_attrp(ATTR_IIDIS, $3); } + | tIIDIS '(' expr ')' { $$ = make_attrp(ATTR_IIDIS, $3); } | tIMMEDIATEBIND { $$ = make_attr(ATTR_IMMEDIATEBIND); } | tIMPLICITHANDLE '(' tHANDLET aIDENTIFIER ')' { $$ = make_attrp(ATTR_IMPLICIT_HANDLE, $4); } | tIN { $$ = make_attr(ATTR_IN); } @@ -416,7 +488,9 @@ attribute: { $$ = NULL; } | tPROPPUT { $$ = make_attr(ATTR_PROPPUT); } | tPROPPUTREF { $$ = make_attr(ATTR_PROPPUTREF); } | tPUBLIC { $$ = make_attr(ATTR_PUBLIC); } - | tRANGE '(' expr_const ',' expr_const ')' { LINK($5, $3); $$ = make_attrp(ATTR_RANGE, $5); } + | tRANGE '(' expr_const ',' expr_const ')' { expr_list_t *list = append_expr( NULL, $3 ); + list = append_expr( list, $5 ); + $$ = make_attrp(ATTR_RANGE, list); } | tREADONLY { $$ = make_attr(ATTR_READONLY); } | tREQUESTEDIT { $$ = make_attr(ATTR_REQUESTEDIT); } | tRESTRICTED { $$ = make_attr(ATTR_RESTRICTED); } @@ -425,38 +499,43 @@ attribute: { $$ = NULL; } | tSOURCE { $$ = make_attr(ATTR_SOURCE); } | tSTRING { $$ = make_attr(ATTR_STRING); } | tSWITCHIS '(' expr ')' { $$ = make_attrp(ATTR_SWITCHIS, $3); } - | tSWITCHTYPE '(' type ')' { $$ = make_attrp(ATTR_SWITCHTYPE, type_ref($3)); } - | tTRANSMITAS '(' type ')' { $$ = make_attrp(ATTR_TRANSMITAS, type_ref($3)); } - | tUUID '(' aUUID ')' { $$ = make_attrp(ATTR_UUID, $3); } + | tSWITCHTYPE '(' type ')' { $$ = make_attrp(ATTR_SWITCHTYPE, $3); } + | tTRANSMITAS '(' type ')' { $$ = make_attrp(ATTR_TRANSMITAS, $3); } + | tUUID '(' uuid_string ')' { $$ = make_attrp(ATTR_UUID, $3); } | tV1ENUM { $$ = make_attr(ATTR_V1ENUM); } | tVARARG { $$ = make_attr(ATTR_VARARG); } | tVERSION '(' version ')' { $$ = make_attrv(ATTR_VERSION, $3); } - | tWIREMARSHAL '(' type ')' { $$ = make_attrp(ATTR_WIREMARSHAL, type_ref($3)); } + | tWIREMARSHAL '(' type ')' { $$ = make_attrp(ATTR_WIREMARSHAL, $3); } | pointer_type { $$ = make_attrv(ATTR_POINTERTYPE, $1); } ; +uuid_string: + aUUID + | aSTRING { if (!is_valid_uuid($1)) + error_loc("invalid UUID: %s\n", $1); + $$ = parse_uuid($1); } + ; + callconv: | tSTDCALL ; cases: { $$ = NULL; } - | cases case { if ($2) { LINK($2, $1); $$ = $2; } - else { $$ = $1; } - } + | cases case { $$ = append_var( $1, $2 ); } ; -case: tCASE expr ':' field { attr_t *a = make_attrp(ATTR_CASE, $2); +case: tCASE expr ':' field { attr_t *a = make_attrp(ATTR_CASE, append_expr( NULL, $2 )); $$ = $4; if (!$$) $$ = make_var(NULL); - LINK(a, $$->attrs); $$->attrs = a; + $$->attrs = append_attr( $$->attrs, a ); } | tDEFAULT ':' field { attr_t *a = make_attr(ATTR_DEFAULT); $$ = $3; if (!$$) $$ = make_var(NULL); - LINK(a, $$->attrs); $$->attrs = a; + $$->attrs = append_attr( $$->attrs, a ); } ; constdef: tCONST type ident '=' expr_const { $$ = reg_const($3); - set_type($$, $2, NULL); + set_type($$, $2, 0, NULL, FALSE); $$->eval = $5; } ; @@ -466,34 +545,39 @@ enums: { $$ = NULL; } | enum_list ; -enum_list: enum { if (!$$->eval) - $$->eval = make_exprl(EXPR_NUM, 0 /* default for first enum entry */); +enum_list: enum { if (!$1->eval) + $1->eval = make_exprl(EXPR_NUM, 0 /* default for first enum entry */); + $$ = append_var( NULL, $1 ); } - | enum_list ',' enum { LINK($3, $1); $$ = $3; - if (!$$->eval) - $$->eval = make_exprl(EXPR_NUM, $1->eval->cval + 1); + | enum_list ',' enum { if (!$3->eval) + { + var_t *last = LIST_ENTRY( list_tail($$), var_t, entry ); + $3->eval = make_exprl(EXPR_NUM, last->eval->cval + 1); + } + $$ = append_var( $1, $3 ); } ; enum: ident '=' expr_const { $$ = reg_const($1); $$->eval = $3; - $$->type = make_type(RPC_FC_LONG, &std_int); + $$->type = make_int(0); } | ident { $$ = reg_const($1); - $$->type = make_type(RPC_FC_LONG, &std_int); + $$->type = make_int(0); } ; enumdef: tENUM t_ident '{' enums '}' { $$ = get_typev(RPC_FC_ENUM16, $2, tsENUM); + $$->kind = TKIND_ENUM; $$->fields = $4; $$->defined = TRUE; if(in_typelib) - add_enum($$); + add_typelib_entry($$); } ; -m_exprs: m_expr - | m_exprs ',' m_expr { LINK($3, $1); $$ = $3; } +m_exprs: m_expr { $$ = append_expr( NULL, $1 ); } + | m_exprs ',' m_expr { $$ = append_expr( $1, $3 ); } ; /* @@ -512,6 +596,7 @@ m_expr: { $$ = make_expr(EXPR_VOID); } expr: aNUM { $$ = make_exprl(EXPR_NUM, $1); } | aHEXNUM { $$ = make_exprl(EXPR_HEXNUM, $1); } + | aDOUBLE { $$ = make_exprd(EXPR_DOUBLE, $1); } | tFALSE { $$ = make_exprl(EXPR_TRUEFALSE, 0); } | tTRUE { $$ = make_exprl(EXPR_TRUEFALSE, 1); } | aIDENTIFIER { $$ = make_exprs(EXPR_IDENTIFIER, $1); } @@ -526,31 +611,30 @@ expr: aNUM { $$ = make_exprl(EXPR_NUM, $1); } | expr SHR expr { $$ = make_expr2(EXPR_SHR, $1, $3); } | '~' expr { $$ = make_expr1(EXPR_NOT, $2); } | '-' expr %prec NEG { $$ = make_expr1(EXPR_NEG, $2); } + | '&' expr %prec ADDRESSOF { $$ = make_expr1(EXPR_ADDRESSOF, $2); } | '*' expr %prec PPTR { $$ = make_expr1(EXPR_PPTR, $2); } | '(' type ')' expr %prec CAST { $$ = make_exprt(EXPR_CAST, $2, $4); } | tSIZEOF '(' type ')' { $$ = make_exprt(EXPR_SIZEOF, $3, NULL); } | '(' expr ')' { $$ = $2; } ; -expr_list_const: expr_const - | expr_list_const ',' expr_const { LINK($3, $1); $$ = $3; } +expr_list_const: expr_const { $$ = append_expr( NULL, $1 ); } + | expr_list_const ',' expr_const { $$ = append_expr( $1, $3 ); } ; expr_const: expr { $$ = $1; if (!$$->is_const) - yyerror("expression is not constant"); + error_loc("expression is not constant\n"); } ; externdef: tEXTERN tCONST type ident { $$ = $4; - set_type($$, $3, NULL); + set_type($$, $3, 0, NULL, FALSE); } ; fields: { $$ = NULL; } - | fields field { if ($2) { LINK($2, $1); $$ = $2; } - else { $$ = $1; } - } + | fields field { $$ = append_var( $1, $2 ); } ; field: s_field ';' { $$ = $1; } @@ -559,16 +643,22 @@ field: s_field ';' { $$ = $1; } | ';' { $$ = NULL; } ; -s_field: m_attributes type pident array { $$ = $3; set_type($$, $2, $4); $$->attrs = $1; } +s_field: m_attributes type pident array { $$ = $3->var; + $$->attrs = $1; + set_type($$, $2, $3->ptr_level, $4, FALSE); + free($3); + } ; funcdef: m_attributes type callconv pident - '(' m_args ')' { set_type($4, $2, NULL); - $4->attrs = $1; - $$ = make_func($4, $6); - if (is_attr($4->attrs, ATTR_IN)) { - yyerror("inapplicable attribute [in] for function '%s'",$$->def->name); + '(' m_args ')' { var_t *v = $4->var; + v->attrs = $1; + set_type(v, $2, $4->ptr_level, NULL, FALSE); + free($4); + $$ = make_func(v, $6); + if (is_attr(v->attrs, ATTR_IN)) { + error_loc("inapplicable attribute [in] for function '%s'\n",$$->def->name); } } ; @@ -585,18 +675,10 @@ t_ident: { $$ = NULL; } ident: aIDENTIFIER { $$ = make_var($1); } /* some "reserved words" used in attributes are also used as field names in some MS IDL files */ | aKNOWNTYPE { $$ = make_var($1); } - | tASYNC { $$ = make_var($1); } - | tID { $$ = make_var($1); } - | tLCID { $$ = make_var($1); } - | tOBJECT { $$ = make_var($1); } - | tRANGE { $$ = make_var($1); } - | tRETVAL { $$ = make_var($1); } - | tUUID { $$ = make_var($1); } - | tVERSION { $$ = make_var($1); } ; -base_type: tBYTE { $$ = make_type(RPC_FC_BYTE, NULL); } - | tWCHAR { $$ = make_type(RPC_FC_WCHAR, NULL); } +base_type: tBYTE { $$ = make_builtin($1); } + | tWCHAR { $$ = make_builtin($1); } | int_std | tSIGNED int_std { $$ = $2; $$->sign = 1; } | tUNSIGNED int_std { $$ = $2; $$->sign = -1; @@ -606,37 +688,41 @@ base_type: tBYTE { $$ = make_type(RPC_FC_BYTE, NULL); } case RPC_FC_SHORT: $$->type = RPC_FC_USHORT; break; case RPC_FC_LONG: $$->type = RPC_FC_ULONG; break; case RPC_FC_HYPER: - if (!$$->ref) { $$->ref = &std_uhyper; $$->sign = 0; } + if ($$->name[0] == 'h') /* hyper, as opposed to __int64 */ + { + $$ = alias($$, "MIDL_uhyper"); + $$->sign = 0; + } break; default: break; } } - | tUNSIGNED { $$ = make_type(RPC_FC_ULONG, &std_int); $$->sign = -1; } - | tFLOAT { $$ = make_type(RPC_FC_FLOAT, NULL); } - | tSINGLE { $$ = make_type(RPC_FC_FLOAT, NULL); } - | tDOUBLE { $$ = make_type(RPC_FC_DOUBLE, NULL); } - | tBOOLEAN { $$ = make_type(RPC_FC_BYTE, &std_bool); /* ? */ } - | tERRORSTATUST { $$ = make_type(RPC_FC_ERROR_STATUS_T, NULL); } - | tHANDLET { $$ = make_type(RPC_FC_BIND_PRIMITIVE, NULL); /* ? */ } + | tUNSIGNED { $$ = make_int(-1); } + | tFLOAT { $$ = make_builtin($1); } + | tSINGLE { $$ = duptype(find_type("float", 0), 1); } + | tDOUBLE { $$ = make_builtin($1); } + | tBOOLEAN { $$ = make_builtin($1); } + | tERRORSTATUST { $$ = make_builtin($1); } + | tHANDLET { $$ = make_builtin($1); } ; m_int: | tINT ; -int_std: tINT { $$ = make_type(RPC_FC_LONG, &std_int); } /* win32 only */ - | tSHORT m_int { $$ = make_type(RPC_FC_SHORT, NULL); } - | tSMALL { $$ = make_type(RPC_FC_SMALL, NULL); } - | tLONG m_int { $$ = make_type(RPC_FC_LONG, NULL); } - | tHYPER m_int { $$ = make_type(RPC_FC_HYPER, NULL); } - | tINT64 { $$ = make_type(RPC_FC_HYPER, &std_int64); } - | tCHAR { $$ = make_type(RPC_FC_CHAR, NULL); } +int_std: tINT { $$ = make_builtin($1); } + | tSHORT m_int { $$ = make_builtin($1); } + | tSMALL { $$ = make_builtin($1); } + | tLONG m_int { $$ = make_builtin($1); } + | tHYPER m_int { $$ = make_builtin($1); } + | tINT64 { $$ = make_builtin($1); } + | tCHAR { $$ = make_builtin($1); } ; coclass: tCOCLASS aIDENTIFIER { $$ = make_class($2); } | tCOCLASS aKNOWNTYPE { $$ = find_type($2, 0); - if ($$->defined) yyerror("multiple definition error"); - if ($$->kind != TKIND_COCLASS) yyerror("%s was not declared a coclass", $2); + if ($$->defined) error_loc("multiple definition error\n"); + if ($$->kind != TKIND_COCLASS) error_loc("%s was not declared a coclass\n", $2); } ; @@ -644,45 +730,47 @@ coclasshdr: attributes coclass { $$ = $2; $$->attrs = $1; if (!parse_only && do_header) write_coclass($$); + if (!parse_only && do_idfile) + write_clsid($$); } ; coclassdef: coclasshdr '{' coclass_ints '}' { $$ = $1; $$->ifaces = $3; + $$->defined = TRUE; } ; coclass_ints: { $$ = NULL; } - | coclass_ints coclass_int { LINK($2, $1); $$ = $2; } + | coclass_ints coclass_int { $$ = append_ifref( $1, $2 ); } ; coclass_int: m_attributes interfacedec { $$ = make_ifref($2); $$->attrs = $1; } ; -dispinterface: tDISPINTERFACE aIDENTIFIER { $$ = get_type(0, $2, 0); } - | tDISPINTERFACE aKNOWNTYPE { $$ = get_type(0, $2, 0); } +dispinterface: tDISPINTERFACE aIDENTIFIER { $$ = get_type(0, $2, 0); $$->kind = TKIND_DISPATCH; } + | tDISPINTERFACE aKNOWNTYPE { $$ = get_type(0, $2, 0); $$->kind = TKIND_DISPATCH; } ; dispinterfacehdr: attributes dispinterface { attr_t *attrs; $$ = $2; - if ($$->defined) yyerror("multiple definition error"); + if ($$->defined) error_loc("multiple definition error\n"); attrs = make_attr(ATTR_DISPINTERFACE); - LINK(attrs, $1); - $$->attrs = attrs; + $$->attrs = append_attr( $1, attrs ); $$->ref = find_type("IDispatch", 0); - if (!$$->ref) yyerror("IDispatch is undefined"); + if (!$$->ref) error_loc("IDispatch is undefined\n"); $$->defined = TRUE; if (!parse_only && do_header) write_forward($$); } ; dispint_props: tPROPERTIES ':' { $$ = NULL; } - | dispint_props s_field ';' { LINK($2, $1); $$ = $2; } + | dispint_props s_field ';' { $$ = append_var( $1, $2 ); } ; dispint_meths: tMETHODS ':' { $$ = NULL; } - | dispint_meths funcdef ';' { LINK($2, $1); $$ = $2; } + | dispint_meths funcdef ';' { $$ = append_func( $1, $2 ); } ; dispinterfacedef: dispinterfacehdr '{' @@ -692,44 +780,58 @@ dispinterfacedef: dispinterfacehdr '{' $$->fields = $3; $$->funcs = $4; if (!parse_only && do_header) write_dispinterface($$); + if (!parse_only && do_idfile) write_diid($$); } -/* FIXME: not sure how to handle this yet - | dispinterfacehdr '{' interface '}' { $$ = $1; - if (!parse_only && do_header) write_interface($$); + | dispinterfacehdr + '{' interface ';' '}' { $$ = $1; + $$->fields = $3->fields; + $$->funcs = $3->funcs; + if (!parse_only && do_header) write_dispinterface($$); + if (!parse_only && do_idfile) write_diid($$); } -*/ ; inherit: { $$ = NULL; } | ':' aKNOWNTYPE { $$ = find_type2($2, 0); } ; -interface: tINTERFACE aIDENTIFIER { $$ = get_type(RPC_FC_IP, $2, 0); } - | tINTERFACE aKNOWNTYPE { $$ = get_type(RPC_FC_IP, $2, 0); } +interface: tINTERFACE aIDENTIFIER { $$ = get_type(RPC_FC_IP, $2, 0); $$->kind = TKIND_INTERFACE; } + | tINTERFACE aKNOWNTYPE { $$ = get_type(RPC_FC_IP, $2, 0); $$->kind = TKIND_INTERFACE; } ; -interfacehdr: attributes interface { $$ = $2; - if ($$->defined) yyerror("multiple definition error"); - $$->attrs = $1; - $$->defined = TRUE; - if (!parse_only && do_header) write_forward($$); +interfacehdr: attributes interface { $$.interface = $2; + $$.old_pointer_default = pointer_default; + if (is_attr($1, ATTR_POINTERDEFAULT)) + pointer_default = get_attrv($1, ATTR_POINTERDEFAULT); + if ($2->defined) error_loc("multiple definition error\n"); + $2->attrs = $1; + $2->defined = TRUE; + if (!parse_only && do_header) write_forward($2); } ; interfacedef: interfacehdr inherit - '{' int_statements '}' { $$ = $1; + '{' int_statements '}' { $$ = $1.interface; $$->ref = $2; $$->funcs = $4; + compute_method_indexes($$); if (!parse_only && do_header) write_interface($$); + if (!parse_only && local_stubs) write_locals(local_stubs, $$, TRUE); + if (!parse_only && do_idfile) write_iid($$); + pointer_default = $1.old_pointer_default; } /* MIDL is able to import the definition of a base class from inside the * definition of a derived class, I'll try to support it with this rule */ | interfacehdr ':' aIDENTIFIER - '{' import int_statements '}' { $$ = $1; + '{' import int_statements '}' { $$ = $1.interface; $$->ref = find_type2($3, 0); - if (!$$->ref) yyerror("base class '%s' not found in import", $3); + if (!$$->ref) error_loc("base class '%s' not found in import\n", $3); $$->funcs = $6; + compute_method_indexes($$); if (!parse_only && do_header) write_interface($$); + if (!parse_only && local_stubs) write_locals(local_stubs, $$, TRUE); + if (!parse_only && do_idfile) write_iid($$); + pointer_default = $1.old_pointer_default; } | dispinterfacedef { $$ = $1; } ; @@ -739,8 +841,8 @@ interfacedec: | dispinterface ';' { $$ = $1; if (!parse_only && do_header) write_forward($$); } ; -module: tMODULE aIDENTIFIER { $$ = make_type(0, NULL); $$->name = $2; } - | tMODULE aKNOWNTYPE { $$ = make_type(0, NULL); $$->name = $2; } +module: tMODULE aIDENTIFIER { $$ = make_type(0, NULL); $$->name = $2; $$->kind = TKIND_MODULE; } + | tMODULE aKNOWNTYPE { $$ = make_type(0, NULL); $$->name = $2; $$->kind = TKIND_MODULE; } ; modulehdr: attributes module { $$ = $2; @@ -758,14 +860,14 @@ p_ident: '*' pident %prec PPTR { $$ = $2; $$->ptr_level++; } | tCONST p_ident { $$ = $2; /* FIXME */ } ; -pident: ident +pident: ident { $$ = make_pident($1); } | p_ident | '(' pident ')' { $$ = $2; } ; pident_list: - pident - | pident_list ',' pident { LINK($3, $1); $$ = $3; } + pident { $$ = append_pident( NULL, $1 ); } + | pident_list ',' pident { $$ = append_pident( $1, $3 ); } ; pointer_type: @@ -777,40 +879,34 @@ pointer_type: structdef: tSTRUCT t_ident '{' fields '}' { $$ = get_typev(RPC_FC_STRUCT, $2, tsSTRUCT); /* overwrite RPC_FC_STRUCT with a more exact type */ $$->type = get_struct_type( $4 ); + $$->kind = TKIND_RECORD; $$->fields = $4; $$->defined = TRUE; if(in_typelib) - add_struct($$); + add_typelib_entry($$); } ; -type: tVOID { $$ = make_tref(NULL, make_type(0, NULL)); } - | aKNOWNTYPE { $$ = make_tref($1, find_type($1, 0)); } - | base_type { $$ = make_tref(NULL, $1); } - | tCONST type { $$ = uniq_tref($2); $$->ref->is_const = TRUE; } - | enumdef { $$ = make_tref(NULL, $1); } - | tENUM aIDENTIFIER { $$ = make_tref(NULL, find_type2($2, tsENUM)); } - | structdef { $$ = make_tref(NULL, $1); } - | tSTRUCT aIDENTIFIER { $$ = make_tref(NULL, get_type(RPC_FC_STRUCT, $2, tsSTRUCT)); } - | uniondef { $$ = make_tref(NULL, $1); } - | tUNION aIDENTIFIER { $$ = make_tref(NULL, find_type2($2, tsUNION)); } - | tSAFEARRAY '(' type ')' { $$ = make_tref(NULL, make_safearray()); } +type: tVOID { $$ = duptype(find_type("void", 0), 1); } + | aKNOWNTYPE { $$ = find_type($1, 0); } + | base_type { $$ = $1; } + | tCONST type { $$ = duptype($2, 1); $$->is_const = TRUE; } + | enumdef { $$ = $1; } + | tENUM aIDENTIFIER { $$ = find_type2($2, tsENUM); } + | structdef { $$ = $1; } + | tSTRUCT aIDENTIFIER { $$ = get_type(RPC_FC_STRUCT, $2, tsSTRUCT); } + | uniondef { $$ = $1; } + | tUNION aIDENTIFIER { $$ = find_type2($2, tsUNION); } + | tSAFEARRAY '(' type ')' { $$ = make_safearray($3); } ; -typedef: tTYPEDEF m_attributes type pident_list { typeref_t *tref = uniq_tref($3); - $4->tname = tref->name; - tref->name = NULL; - $$ = type_ref(tref); - $$->attrs = $2; - if (!parse_only && do_header) - write_typedef($$, $4); - if (in_typelib && $$->attrs) - add_typedef($$, $4); - reg_types($$, $4, 0); +typedef: tTYPEDEF m_attributes type pident_list { reg_typedefs($3, $4, $2); + process_typedefs($4); } ; uniondef: tUNION t_ident '{' fields '}' { $$ = get_typev(RPC_FC_NON_ENCAPSULATED_UNION, $2, tsUNION); + $$->kind = TKIND_UNION; $$->fields = $4; $$->defined = TRUE; } @@ -818,28 +914,103 @@ uniondef: tUNION t_ident '{' fields '}' { $$ = get_typev(RPC_FC_NON_ENCAPSULATE tSWITCH '(' s_field ')' m_ident '{' cases '}' { var_t *u = $7; $$ = get_typev(RPC_FC_ENCAPSULATED_UNION, $2, tsUNION); - if (!u) u = make_var("tagged_union"); + $$->kind = TKIND_UNION; + if (!u) u = make_var( xstrdup("tagged_union") ); u->type = make_type(RPC_FC_NON_ENCAPSULATED_UNION, NULL); + u->type->kind = TKIND_UNION; u->type->fields = $9; u->type->defined = TRUE; - LINK(u, $5); $$->fields = u; + $$->fields = append_var( $$->fields, $5 ); + $$->fields = append_var( $$->fields, u ); $$->defined = TRUE; } ; version: - aNUM { $$ = MAKELONG($1, 0); } - | aNUM '.' aNUM { $$ = MAKELONG($1, $3); } + aNUM { $$ = MAKEVERSION($1, 0); } + | aNUM '.' aNUM { $$ = MAKEVERSION($1, $3); } ; %% +static void decl_builtin(const char *name, unsigned char type) +{ + type_t *t = make_type(type, NULL); + t->name = xstrdup(name); + reg_type(t, name, 0); +} + +static type_t *make_builtin(char *name) +{ + /* NAME is strdup'd in the lexer */ + type_t *t = duptype(find_type(name, 0), 0); + t->name = name; + return t; +} + +static type_t *make_int(int sign) +{ + type_t *t = duptype(find_type("int", 0), 1); + + t->sign = sign; + if (sign < 0) + t->type = t->type == RPC_FC_LONG ? RPC_FC_ULONG : RPC_FC_USHORT; + + return t; +} + +void init_types(void) +{ + decl_builtin("void", 0); + decl_builtin("byte", RPC_FC_BYTE); + decl_builtin("wchar_t", RPC_FC_WCHAR); + decl_builtin("int", RPC_FC_LONG); /* win32 */ + decl_builtin("short", RPC_FC_SHORT); + decl_builtin("small", RPC_FC_SMALL); + decl_builtin("long", RPC_FC_LONG); + decl_builtin("hyper", RPC_FC_HYPER); + decl_builtin("__int64", RPC_FC_HYPER); + decl_builtin("char", RPC_FC_CHAR); + decl_builtin("float", RPC_FC_FLOAT); + decl_builtin("double", RPC_FC_DOUBLE); + decl_builtin("boolean", RPC_FC_BYTE); + decl_builtin("error_status_t", RPC_FC_ERROR_STATUS_T); + decl_builtin("handle_t", RPC_FC_BIND_PRIMITIVE); +} + +static str_list_t *append_str(str_list_t *list, char *str) +{ + struct str_list_entry_t *entry; + + if (!str) return list; + if (!list) + { + list = xmalloc( sizeof(*list) ); + list_init( list ); + } + entry = xmalloc( sizeof(*entry) ); + entry->str = str; + list_add_tail( list, &entry->entry ); + return list; +} + +static attr_list_t *append_attr(attr_list_t *list, attr_t *attr) +{ + if (!attr) return list; + if (!list) + { + list = xmalloc( sizeof(*list) ); + list_init( list ); + } + list_add_tail( list, &attr->entry ); + return list; +} + static attr_t *make_attr(enum attr_type type) { attr_t *a = xmalloc(sizeof(attr_t)); a->type = type; a->u.ival = 0; - INIT_LINK(a); return a; } @@ -848,7 +1019,6 @@ static attr_t *make_attrv(enum attr_type type, unsigned long val) attr_t *a = xmalloc(sizeof(attr_t)); a->type = type; a->u.ival = val; - INIT_LINK(a); return a; } @@ -857,7 +1027,6 @@ static attr_t *make_attrp(enum attr_type type, void *val) attr_t *a = xmalloc(sizeof(attr_t)); a->type = type; a->u.pval = val; - INIT_LINK(a); return a; } @@ -868,7 +1037,7 @@ static expr_t *make_expr(enum expr_type type) e->ref = NULL; e->u.lval = 0; e->is_const = FALSE; - INIT_LINK(e); + e->cval = 0; return e; } @@ -879,7 +1048,6 @@ static expr_t *make_exprl(enum expr_type type, long val) e->ref = NULL; e->u.lval = val; e->is_const = FALSE; - INIT_LINK(e); /* check for numeric constant */ if (type == EXPR_NUM || type == EXPR_HEXNUM || type == EXPR_TRUEFALSE) { /* make sure true/false value is valid */ @@ -890,6 +1058,17 @@ static expr_t *make_exprl(enum expr_type type, long val) return e; } +static expr_t *make_exprd(enum expr_type type, double val) +{ + expr_t *e = xmalloc(sizeof(expr_t)); + e->type = type; + e->ref = NULL; + e->u.dval = val; + e->is_const = TRUE; + e->cval = val; + return e; +} + static expr_t *make_exprs(enum expr_type type, char *val) { expr_t *e; @@ -898,7 +1077,6 @@ static expr_t *make_exprs(enum expr_type type, char *val) e->ref = NULL; e->u.sval = val; e->is_const = FALSE; - INIT_LINK(e); /* check for predefined constants */ if (type == EXPR_IDENTIFIER) { var_t *c = find_const(val, 0); @@ -912,7 +1090,7 @@ static expr_t *make_exprs(enum expr_type type, char *val) return e; } -static expr_t *make_exprt(enum expr_type type, typeref_t *tref, expr_t *expr) +static expr_t *make_exprt(enum expr_type type, type_t *tref, expr_t *expr) { expr_t *e; e = xmalloc(sizeof(expr_t)); @@ -920,10 +1098,9 @@ static expr_t *make_exprt(enum expr_type type, typeref_t *tref, expr_t *expr) e->ref = expr; e->u.tref = tref; e->is_const = FALSE; - INIT_LINK(e); /* check for cast of constant expression */ if (type == EXPR_SIZEOF) { - switch (tref->ref->type) { + switch (tref->type) { case RPC_FC_BYTE: case RPC_FC_CHAR: case RPC_FC_SMALL: @@ -961,12 +1138,13 @@ static expr_t *make_exprt(enum expr_type type, typeref_t *tref, expr_t *expr) static expr_t *make_expr1(enum expr_type type, expr_t *expr) { expr_t *e; + if (type == EXPR_ADDRESSOF && expr->type != EXPR_IDENTIFIER) + error("address-of operator applied to invalid expression\n"); e = xmalloc(sizeof(expr_t)); e->type = type; e->ref = expr; e->u.lval = 0; e->is_const = FALSE; - INIT_LINK(e); /* check for compile-time optimization */ if (expr->is_const) { e->is_const = TRUE; @@ -993,7 +1171,6 @@ static expr_t *make_expr2(enum expr_type type, expr_t *expr1, expr_t *expr2) e->ref = expr1; e->u.ext = expr2; e->is_const = FALSE; - INIT_LINK(e); /* check for compile-time optimization */ if (expr1->is_const && expr2->is_const) { e->is_const = TRUE; @@ -1039,7 +1216,6 @@ static expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, exp e->u.ext = expr2; e->ext2 = expr3; e->is_const = FALSE; - INIT_LINK(e); /* check for compile-time optimization */ if (expr1->is_const && expr2->is_const && expr3->is_const) { e->is_const = TRUE; @@ -1055,64 +1231,244 @@ static expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, exp return e; } +static expr_list_t *append_expr(expr_list_t *list, expr_t *expr) +{ + if (!expr) return list; + if (!list) + { + list = xmalloc( sizeof(*list) ); + list_init( list ); + } + list_add_tail( list, &expr->entry ); + return list; +} + +static array_dims_t *append_array(array_dims_t *list, expr_t *expr) +{ + if (!expr) return list; + if (!list) + { + list = xmalloc( sizeof(*list) ); + list_init( list ); + } + list_add_tail( list, &expr->entry ); + return list; +} + +static struct list type_pool = LIST_INIT(type_pool); +typedef struct +{ + type_t data; + struct list link; +} type_pool_node_t; + +type_t *alloc_type(void) +{ + type_pool_node_t *node = xmalloc(sizeof *node); + list_add_tail(&type_pool, &node->link); + return &node->data; +} + +void set_all_tfswrite(int val) +{ + type_pool_node_t *node; + LIST_FOR_EACH_ENTRY(node, &type_pool, type_pool_node_t, link) + node->data.tfswrite = val; +} + static type_t *make_type(unsigned char type, type_t *ref) { - type_t *t = xmalloc(sizeof(type_t)); + type_t *t = alloc_type(); t->name = NULL; t->kind = TKIND_PRIMITIVE; t->type = type; t->ref = ref; t->attrs = NULL; + t->orig = NULL; t->funcs = NULL; t->fields = NULL; t->ifaces = NULL; - t->ignore = parse_only; + t->dim = 0; + t->size_is = NULL; + t->length_is = NULL; + t->typestring_offset = 0; + t->ptrdesc = 0; + t->declarray = FALSE; + t->ignore = (parse_only != 0); t->is_const = FALSE; t->sign = 0; t->defined = FALSE; t->written = FALSE; + t->user_types_registered = FALSE; + t->tfswrite = FALSE; t->typelib_idx = -1; - INIT_LINK(t); return t; } -static typeref_t *make_tref(char *name, type_t *ref) +static void set_type(var_t *v, type_t *type, int ptr_level, array_dims_t *arr, + int top) { - typeref_t *t = xmalloc(sizeof(typeref_t)); - t->name = name; - t->ref = ref; - t->uniq = ref ? 0 : 1; - return t; + expr_list_t *sizes = get_attrp(v->attrs, ATTR_SIZEIS); + expr_list_t *lengs = get_attrp(v->attrs, ATTR_LENGTHIS); + int ptr_attr = get_attrv(v->attrs, ATTR_POINTERTYPE); + int ptr_type = ptr_attr; + int sizeless, has_varconf; + expr_t *dim; + type_t *atype, **ptype; + + v->type = type; + + if (!ptr_type && top) + ptr_type = RPC_FC_RP; + + for ( ; 0 < ptr_level; --ptr_level) + { + v->type = make_type(pointer_default, v->type); + if (ptr_level == 1 && ptr_type && !arr) + { + v->type->type = ptr_type; + ptr_type = 0; + } + } + + if (ptr_type && !arr) + { + if (is_ptr(v->type)) + { + if (v->type->type != ptr_type) + { + v->type = duptype(v->type, 1); + v->type->type = ptr_type; + } + } + else if (!arr && ptr_attr) + error("%s: pointer attribute applied to non-pointer type\n", v->name); + } + + sizeless = FALSE; + if (arr) LIST_FOR_EACH_ENTRY_REV(dim, arr, expr_t, entry) + { + if (sizeless) + error("%s: only the first array dimension can be unspecified\n", v->name); + + if (dim->is_const) + { + unsigned int align = 0; + size_t size = type_memsize(v->type, &align); + + if (dim->cval <= 0) + error("%s: array dimension must be positive\n", v->name); + + if (0xffffffffuL / size < (unsigned long) dim->cval) + error("%s: total array size is too large\n", v->name); + else if (0xffffuL < size * dim->cval) + v->type = make_type(RPC_FC_LGFARRAY, v->type); + else + v->type = make_type(RPC_FC_SMFARRAY, v->type); + } + else + { + sizeless = TRUE; + v->type = make_type(RPC_FC_CARRAY, v->type); + } + + v->type->declarray = TRUE; + v->type->dim = dim->cval; + } + + ptype = &v->type; + has_varconf = FALSE; + if (sizes) LIST_FOR_EACH_ENTRY(dim, sizes, expr_t, entry) + { + if (dim->type != EXPR_VOID) + { + has_varconf = TRUE; + atype = *ptype = duptype(*ptype, 0); + + if (atype->type == RPC_FC_SMFARRAY || atype->type == RPC_FC_LGFARRAY) + error("%s: cannot specify size_is for a fixed sized array\n", v->name); + + if (atype->type != RPC_FC_CARRAY && !is_ptr(atype)) + error("%s: size_is attribute applied to illegal type\n", v->name); + + atype->type = RPC_FC_CARRAY; + atype->size_is = dim; + } + + ptype = &(*ptype)->ref; + if (*ptype == NULL) + error("%s: too many expressions in size_is attribute\n", v->name); + } + + ptype = &v->type; + if (lengs) LIST_FOR_EACH_ENTRY(dim, lengs, expr_t, entry) + { + if (dim->type != EXPR_VOID) + { + has_varconf = TRUE; + atype = *ptype = duptype(*ptype, 0); + + if (atype->type == RPC_FC_SMFARRAY) + atype->type = RPC_FC_SMVARRAY; + else if (atype->type == RPC_FC_LGFARRAY) + atype->type = RPC_FC_LGVARRAY; + else if (atype->type == RPC_FC_CARRAY) + atype->type = RPC_FC_CVARRAY; + else + error("%s: length_is attribute applied to illegal type\n", v->name); + + atype->length_is = dim; + } + + ptype = &(*ptype)->ref; + if (*ptype == NULL) + error("%s: too many expressions in length_is attribute\n", v->name); + } + + if (has_varconf && !last_array(v->type)) + { + ptype = &v->type; + for (ptype = &v->type; is_array(*ptype); ptype = &(*ptype)->ref) + { + *ptype = duptype(*ptype, 0); + (*ptype)->type = RPC_FC_BOGUS_ARRAY; + } + } + + if (is_array(v->type)) + { + const type_t *rt = v->type->ref; + if (is_user_type(rt)) + v->type->type = RPC_FC_BOGUS_ARRAY; + else + switch (rt->type) + { + case RPC_FC_BOGUS_STRUCT: + case RPC_FC_NON_ENCAPSULATED_UNION: + case RPC_FC_ENCAPSULATED_UNION: + case RPC_FC_ENUM16: + v->type->type = RPC_FC_BOGUS_ARRAY; + break; + /* FC_RP should be above, but widl overuses these, and will break things. */ + case RPC_FC_UP: + case RPC_FC_RP: + if (rt->ref->type == RPC_FC_IP) + v->type->type = RPC_FC_BOGUS_ARRAY; + break; + } + } } -static typeref_t *uniq_tref(typeref_t *ref) +static ifref_list_t *append_ifref(ifref_list_t *list, ifref_t *iface) { - typeref_t *t = ref; - type_t *tp; - if (t->uniq) return t; - tp = make_type(0, t->ref); - tp->name = t->name; - t->name = NULL; - t->ref = tp; - t->uniq = 1; - return t; -} - -static type_t *type_ref(typeref_t *ref) -{ - type_t *t = ref->ref; - if (ref->name) free(ref->name); - free(ref); - return t; -} - -static void set_type(var_t *v, typeref_t *ref, expr_t *arr) -{ - v->type = ref->ref; - v->tname = ref->name; - ref->name = NULL; - free(ref); - v->array = arr; + if (!iface) return list; + if (!list) + { + list = xmalloc( sizeof(*list) ); + list_init( list ); + } + list_add_tail( list, &iface->entry ); + return list; } static ifref_t *make_ifref(type_t *iface) @@ -1120,32 +1476,70 @@ static ifref_t *make_ifref(type_t *iface) ifref_t *l = xmalloc(sizeof(ifref_t)); l->iface = iface; l->attrs = NULL; - INIT_LINK(l); return l; } +static var_list_t *append_var(var_list_t *list, var_t *var) +{ + if (!var) return list; + if (!list) + { + list = xmalloc( sizeof(*list) ); + list_init( list ); + } + list_add_tail( list, &var->entry ); + return list; +} + static var_t *make_var(char *name) { var_t *v = xmalloc(sizeof(var_t)); v->name = name; - v->ptr_level = 0; v->type = NULL; - v->tname = NULL; + v->args = NULL; v->attrs = NULL; - v->array = NULL; v->eval = NULL; - INIT_LINK(v); return v; } -static func_t *make_func(var_t *def, var_t *args) +static pident_list_t *append_pident(pident_list_t *list, pident_t *p) +{ + if (!p) return list; + if (!list) { + list = xmalloc(sizeof(*list)); + list_init(list); + } + list_add_tail(list, &p->entry); + return list; +} + +static pident_t *make_pident(var_t *var) +{ + pident_t *p = xmalloc(sizeof(*p)); + p->var = var; + p->ptr_level = 0; + return p; +} + +static func_list_t *append_func(func_list_t *list, func_t *func) +{ + if (!func) return list; + if (!list) + { + list = xmalloc( sizeof(*list) ); + list_init( list ); + } + list_add_tail( list, &func->entry ); + return list; +} + +static func_t *make_func(var_t *def, var_list_t *args) { func_t *f = xmalloc(sizeof(func_t)); f->def = def; f->args = args; f->ignore = parse_only; f->idx = -1; - INIT_LINK(f); return f; } @@ -1154,13 +1548,14 @@ static type_t *make_class(char *name) type_t *c = make_type(0, NULL); c->name = name; c->kind = TKIND_COCLASS; - INIT_LINK(c); return c; } -static type_t *make_safearray(void) +static type_t *make_safearray(type_t *type) { - return make_type(RPC_FC_FP, find_type("SAFEARRAY", 0)); + type_t *sa = duptype(find_type("SAFEARRAY", 0), 1); + sa->ref = type; + return make_type(pointer_default, sa); } #define HASHMAX 64 @@ -1193,7 +1588,7 @@ static type_t *reg_type(type_t *type, const char *name, int t) struct rtype *nt; int hash; if (!name) { - yyerror("registering named type without name"); + error_loc("registering named type without name\n"); return type; } hash = hash_ident(name); @@ -1206,42 +1601,85 @@ static type_t *reg_type(type_t *type, const char *name, int t) return type; } -/* determine pointer type from attrs */ -static unsigned char get_pointer_type( type_t *type ) +static int is_incomplete(const type_t *t) { - int t; - if (is_attr( type->attrs, ATTR_STRING )) - { - type_t *t = type; - while( t->type == 0 && t->ref ) - t = t->ref; - switch( t->type ) - { - case RPC_FC_CHAR: - return RPC_FC_C_CSTRING; - case RPC_FC_WCHAR: - return RPC_FC_C_WSTRING; - } - } - t = get_attrv( type->attrs, ATTR_POINTERTYPE ); - if (t) return t; - return RPC_FC_FP; + return !t->defined && (is_struct(t->type) || is_union(t->type)); } -static type_t *reg_types(type_t *type, var_t *names, int t) +static void add_incomplete(type_t *t) +{ + struct typenode *tn = xmalloc(sizeof *tn); + tn->type = t; + list_add_tail(&incomplete_types, &tn->entry); +} + +static void fix_type(type_t *t) +{ + if (t->kind == TKIND_ALIAS && is_incomplete(t)) { + type_t *ot = t->orig; + fix_type(ot); + t->fields = ot->fields; + t->defined = ot->defined; + } +} + +static void fix_incomplete(void) +{ + struct typenode *tn, *next; + + LIST_FOR_EACH_ENTRY_SAFE(tn, next, &incomplete_types, struct typenode, entry) { + fix_type(tn->type); + free(tn); + } +} + +static type_t *reg_typedefs(type_t *type, pident_list_t *pidents, attr_list_t *attrs) { type_t *ptr = type; + const pident_t *pident; int ptrc = 0; + int is_str = is_attr(attrs, ATTR_STRING); + unsigned char ptr_type = get_attrv(attrs, ATTR_POINTERTYPE); - while (names) { - var_t *next = NEXT_LINK(names); - if (names->name) { + if (is_str) + { + type_t *t = type; + unsigned char c; + + while (is_ptr(t)) + t = t->ref; + + c = t->type; + if (c != RPC_FC_CHAR && c != RPC_FC_BYTE && c != RPC_FC_WCHAR) + { + pident = LIST_ENTRY( list_head( pidents ), const pident_t, entry ); + error_loc("'%s': [string] attribute is only valid on 'char', 'byte', or 'wchar_t' pointers and arrays\n", + pident->var->name); + } + } + + /* We must generate names for tagless enum, struct or union. + Typedef-ing a tagless enum, struct or union means we want the typedef + to be included in a library whether it has other attributes or not, + hence the public attribute. */ + if ((type->kind == TKIND_ENUM || type->kind == TKIND_RECORD + || type->kind == TKIND_UNION) && ! type->name && ! parse_only) + { + if (! is_attr(attrs, ATTR_PUBLIC)) + attrs = append_attr( attrs, make_attr(ATTR_PUBLIC) ); + type->name = gen_name(); + } + + LIST_FOR_EACH_ENTRY( pident, pidents, const pident_t, entry ) + { + var_t *name = pident->var; + + if (name->name) { type_t *cur = ptr; - int cptr = names->ptr_level; + int cptr = pident->ptr_level; if (cptr > ptrc) { while (cptr > ptrc) { - int t = get_pointer_type( cur ); - cur = ptr = make_type(t, cur); + cur = ptr = make_type(pointer_default, cur); ptrc++; } } else { @@ -1250,10 +1688,24 @@ static type_t *reg_types(type_t *type, var_t *names, int t) cptr++; } } - reg_type(cur, names->name, t); + cur = alias(cur, name->name); + cur->attrs = attrs; + if (ptr_type) + { + if (is_ptr(cur)) + cur->type = ptr_type; + else + error_loc("'%s': pointer attribute applied to non-pointer type\n", + cur->name); + } + else if (is_str && ! is_ptr(cur)) + error_loc("'%s': [string] attribute applied to non-pointer type\n", + cur->name); + + if (is_incomplete(cur)) + add_incomplete(cur); + reg_type(cur, cur->name, 0); } - free(names); - names = next; } return type; } @@ -1264,7 +1716,7 @@ static type_t *find_type(const char *name, int t) while (cur && (cur->t != t || strcmp(cur->name, name))) cur = cur->next; if (!cur) { - yyerror("type '%s' not found", name); + error_loc("type '%s' not found\n", name); return NULL; } return cur->type; @@ -1315,44 +1767,66 @@ static type_t *get_typev(unsigned char type, var_t *name, int t) return get_type(type, sname, t); } -static int get_struct_type(var_t *field) +static int get_struct_type(var_list_t *fields) { int has_pointer = 0; int has_conformance = 0; int has_variance = 0; + var_t *field; - for (; field; field = NEXT_LINK(field)) + if (get_padding(fields)) + return RPC_FC_BOGUS_STRUCT; + + if (fields) LIST_FOR_EACH_ENTRY( field, fields, var_t, entry ) { type_t *t = field->type; - /* get the base type */ - while( (t->type == 0) && t->ref ) - t = t->ref; + if (is_user_type(t)) + return RPC_FC_BOGUS_STRUCT; - if (field->ptr_level > 0) + if (is_ptr(t)) { + do + t = t->ref; + while (is_ptr(t)); + + switch (t->type) + { + case RPC_FC_IP: + case RPC_FC_ENCAPSULATED_UNION: + case RPC_FC_NON_ENCAPSULATED_UNION: + case RPC_FC_BOGUS_STRUCT: + return RPC_FC_BOGUS_STRUCT; + } + has_pointer = 1; continue; } - if (is_string_type(field->attrs, 0, field->array)) + if (field->type->declarray) { - has_conformance = 1; - has_variance = 1; - continue; - } + if (is_string_type(field->attrs, field->type)) + { + if (is_conformant_array(field->type)) + has_conformance = 1; + has_variance = 1; + continue; + } - if (is_array_type(field->attrs, 0, field->array)) - { - if (field->array && !field->array->is_const) + if (is_array(field->type->ref)) + return RPC_FC_BOGUS_STRUCT; + + if (is_conformant_array(field->type)) { has_conformance = 1; - if (PREV_LINK(field)) - yyerror("field '%s' deriving from a conformant array must be the last field in the structure", + if (field->type->declarray && list_next(fields, &field->entry)) + error_loc("field '%s' deriving from a conformant array must be the last field in the structure\n", field->name); } - if (is_attr(field->attrs, ATTR_LENGTHIS)) + if (field->type->length_is) has_variance = 1; + + t = field->type->ref; } switch (t->type) @@ -1383,20 +1857,14 @@ static int get_struct_type(var_t *field) case RPC_FC_ENUM32: break; + case RPC_FC_RP: case RPC_FC_UP: case RPC_FC_FP: - has_pointer = 1; - break; + case RPC_FC_OP: case RPC_FC_CARRAY: - has_conformance = 1; - if (PREV_LINK(field)) - yyerror("field '%s' deriving from a conformant array must be the last field in the structure", - field->name); - break; - case RPC_FC_C_CSTRING: - case RPC_FC_C_WSTRING: - has_conformance = 1; - has_variance = 1; + case RPC_FC_CVARRAY: + case RPC_FC_BOGUS_ARRAY: + has_pointer = 1; break; /* @@ -1411,16 +1879,16 @@ static int get_struct_type(var_t *field) case RPC_FC_CPSTRUCT: has_conformance = 1; - if (PREV_LINK(field)) - yyerror("field '%s' deriving from a conformant array must be the last field in the structure", + if (list_next( fields, &field->entry )) + error_loc("field '%s' deriving from a conformant array must be the last field in the structure\n", field->name); has_pointer = 1; break; case RPC_FC_CSTRUCT: has_conformance = 1; - if (PREV_LINK(field)) - yyerror("field '%s' deriving from a conformant array must be the last field in the structure", + if (list_next( fields, &field->entry )) + error_loc("field '%s' deriving from a conformant array must be the last field in the structure\n", field->name); break; @@ -1429,25 +1897,24 @@ static int get_struct_type(var_t *field) break; default: - fprintf(stderr,"Unknown struct member %s with type (0x%02x)\n", - field->name, t->type); + error_loc("Unknown struct member %s with type (0x%02x)\n", field->name, t->type); /* fallthru - treat it as complex */ /* as soon as we see one of these these members, it's bogus... */ - case RPC_FC_IP: case RPC_FC_ENCAPSULATED_UNION: case RPC_FC_NON_ENCAPSULATED_UNION: - case RPC_FC_TRANSMIT_AS: - case RPC_FC_REPRESENT_AS: - case RPC_FC_PAD: - case RPC_FC_EMBEDDED_COMPLEX: case RPC_FC_BOGUS_STRUCT: return RPC_FC_BOGUS_STRUCT; } } if( has_variance ) - return RPC_FC_CVSTRUCT; + { + if ( has_conformance ) + return RPC_FC_CVSTRUCT; + else + return RPC_FC_BOGUS_STRUCT; + } if( has_conformance && has_pointer ) return RPC_FC_CPSTRUCT; if( has_conformance ) @@ -1472,7 +1939,7 @@ static var_t *reg_const(var_t *var) struct rconst *nc; int hash; if (!var->name) { - yyerror("registering constant without name"); + error_loc("registering constant without name\n"); return var; } hash = hash_ident(var->name); @@ -1490,8 +1957,135 @@ static var_t *find_const(char *name, int f) while (cur && strcmp(cur->name, name)) cur = cur->next; if (!cur) { - if (f) yyerror("constant '%s' not found", name); + if (f) error_loc("constant '%s' not found\n", name); return NULL; } return cur->var; } + +static void write_libid(const char *name, const attr_list_t *attr) +{ + const UUID *uuid = get_attrp(attr, ATTR_UUID); + write_guid(idfile, "LIBID", name, uuid); +} + +static void write_clsid(type_t *cls) +{ + const UUID *uuid = get_attrp(cls->attrs, ATTR_UUID); + write_guid(idfile, "CLSID", cls->name, uuid); +} + +static void write_diid(type_t *iface) +{ + const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID); + write_guid(idfile, "DIID", iface->name, uuid); +} + +static void write_iid(type_t *iface) +{ + const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID); + write_guid(idfile, "IID", iface->name, uuid); +} + +static int compute_method_indexes(type_t *iface) +{ + int idx; + func_t *f; + + if (iface->ref) + idx = compute_method_indexes(iface->ref); + else + idx = 0; + + if (!iface->funcs) + return idx; + + LIST_FOR_EACH_ENTRY( f, iface->funcs, func_t, entry ) + if (! is_callas(f->def->attrs)) + f->idx = idx++; + + return idx; +} + +static char *gen_name(void) +{ + static const char format[] = "__WIDL_%s_generated_name_%08lX"; + static unsigned long n = 0; + static const char *file_id; + static size_t size; + char *name; + + if (! file_id) + { + char *dst = dup_basename(input_name, ".idl"); + file_id = dst; + + for (; *dst; ++dst) + if (! isalnum((unsigned char) *dst)) + *dst = '_'; + + size = sizeof format - 7 + strlen(file_id) + 8; + } + + name = xmalloc(size); + sprintf(name, format, file_id, n++); + return name; +} + +static void process_typedefs(pident_list_t *pidents) +{ + pident_t *pident, *next; + + if (!pidents) return; + LIST_FOR_EACH_ENTRY_SAFE( pident, next, pidents, pident_t, entry ) + { + var_t *var = pident->var; + type_t *type = find_type(var->name, 0); + + if (! parse_only && do_header) + write_typedef(type); + if (in_typelib && type->attrs) + add_typelib_entry(type); + + free(pident); + free(var); + } +} + +static void check_arg(var_t *arg) +{ + type_t *t = arg->type; + + if (t->type == 0 && ! is_var_ptr(arg)) + error_loc("argument '%s' has void type\n", arg->name); +} + +static void check_all_user_types(ifref_list_t *ifrefs) +{ + const ifref_t *ifref; + const func_t *f; + + if (ifrefs) LIST_FOR_EACH_ENTRY(ifref, ifrefs, const ifref_t, entry) + { + const func_list_t *fs = ifref->iface->funcs; + if (fs) LIST_FOR_EACH_ENTRY(f, fs, const func_t, entry) + check_for_user_types_and_context_handles(f->args); + } +} + +int is_valid_uuid(const char *s) +{ + int i; + + for (i = 0; i < 36; ++i) + if (i == 8 || i == 13 || i == 18 || i == 23) + { + if (s[i] != '-') + return FALSE; + } + else + if (!isxdigit(s[i])) + return FALSE; + + return s[i] == '\0'; +} diff --git a/reactos/tools/widl_20080105/parser.yy.c b/reactos/tools/widl/parser.yy.c similarity index 100% rename from reactos/tools/widl_20080105/parser.yy.c rename to reactos/tools/widl/parser.yy.c diff --git a/reactos/tools/widl/proxy.c b/reactos/tools/widl/proxy.c index 6da9e893508..731629f732c 100644 --- a/reactos/tools/widl/proxy.c +++ b/reactos/tools/widl/proxy.c @@ -36,6 +36,7 @@ #include "utils.h" #include "parser.h" #include "header.h" +#include "typegen.h" #define END_OF_LIST(list) \ do { \ @@ -50,109 +51,58 @@ static int indent = 0; /* FIXME: support generation of stubless proxies */ -static int print_proxy( const char *format, ... ) +static void print_proxy( const char *format, ... ) { va_list va; - int i, r; - va_start( va, format ); - for( i=0; itype; - while( (t->type == 0) && t->ref ) - t = t->ref; - return t; } static void write_stubdescproto(void) { - print_proxy( "extern const MIDL_STUB_DESC Object_StubDesc;\n"); + print_proxy( "static const MIDL_STUB_DESC Object_StubDesc;\n"); print_proxy( "\n"); } -static void write_stubdesc(void) +static void write_stubdesc(int expr_eval_routines) { - print_proxy( "const MIDL_STUB_DESC Object_StubDesc = {\n"); - print_proxy( " 0,\n"); - print_proxy( " NdrOleAllocate,\n"); - print_proxy( " NdrOleFree,\n"); - print_proxy( " {0}, 0, 0, 0, 0,\n"); - print_proxy( " 0 /* __MIDL_TypeFormatString.Format */\n"); - print_proxy( "};\n"); - print_proxy( "\n"); -} - -static void write_formatdesc( const char *str ) -{ - print_proxy( "typedef struct _MIDL_%s_FORMAT_STRING\n", str ); - indent++; - print_proxy( "{\n"); - print_proxy( "short Pad;\n"); - print_proxy( "unsigned char Format[%s_FORMAT_STRING_SIZE];\n", str); - indent--; - print_proxy( "} MIDL_%s_FORMAT_STRING;\n", str); - print_proxy( "\n"); -} - -static void write_formatstringsdecl(void) -{ - print_proxy( "#define TYPE_FORMAT_STRING_SIZE %d\n",1); /* FIXME */ - print_proxy( "#define PROC_FORMAT_STRING_SIZE %d\n",1); /* FIXME */ - fprintf(proxy, "\n"); - write_formatdesc( "TYPE" ); - write_formatdesc( "PROC" ); - fprintf(proxy, "\n"); - print_proxy( "static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString;\n"); - print_proxy( "static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString;\n"); - print_proxy( "\n"); -} - -static void write_formatstring( int proc ) -{ - const char *t, *n; - if( !proc ) - { - t = "TYPE"; - n = "Type"; - } - else - { - t = "PROC"; - n = "Proc"; - } - print_proxy( "static const MIDL_%s_FORMAT_STRING __MIDL_%sFormatString =\n", t, n); - print_proxy( "{\n"); + print_proxy( "static const MIDL_STUB_DESC Object_StubDesc =\n{\n"); indent++; print_proxy( "0,\n"); - print_proxy( "{\n"); - indent++; - print_proxy( "0\n"); - indent--; - print_proxy( "}\n"); + print_proxy( "NdrOleAllocate,\n"); + print_proxy( "NdrOleFree,\n"); + print_proxy( "{0}, 0, 0, %s, 0,\n", expr_eval_routines ? "ExprEvalRoutines" : "0"); + print_proxy( "__MIDL_TypeFormatString.Format,\n"); + print_proxy( "1, /* -error bounds_check flag */\n"); + print_proxy( "0x10001, /* Ndr library version */\n"); + print_proxy( "0,\n"); + print_proxy( "0x50100a4, /* MIDL Version 5.1.164 */\n"); + print_proxy( "0,\n"); + print_proxy("%s,\n", list_empty(&user_type_list) ? "0" : "UserMarshalRoutines"); + print_proxy( "0, /* notify & notify_flag routine table */\n"); + print_proxy( "1, /* Flags */\n"); + print_proxy( "0, /* Reserved3 */\n"); + print_proxy( "0, /* Reserved4 */\n"); + print_proxy( "0 /* Reserved5 */\n"); indent--; print_proxy( "};\n"); print_proxy( "\n"); } -static void init_proxy(void) +static void init_proxy(ifref_list_t *ifaces) { if (proxy) return; if(!(proxy = fopen(proxy_name, "w"))) error("Could not open %s for output\n", proxy_name); - print_proxy( "/*** Autogenerated by WIDL %s - Do not edit ***/\n", WIDL_FULLVERSION); + print_proxy( "/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n", PACKAGE_VERSION, input_name); print_proxy( "\n"); print_proxy( "#ifndef __REDQ_RPCPROXY_H_VERSION__\n"); print_proxy( "#define __REQUIRED_RPCPROXY_H_VERSION__ 440\n"); print_proxy( "#endif /* __REDQ_RPCPROXY_H_VERSION__ */\n"); print_proxy( "\n"); + print_proxy( "#define __midl_proxy\n"); + print_proxy( "#include \"objbase.h\"\n"); print_proxy( "#include \"rpcproxy.h\"\n"); print_proxy( "#ifndef __RPCPROXY_H_VERSION__\n"); print_proxy( "#error This code needs a newer version of rpcproxy.h\n"); @@ -160,349 +110,99 @@ static void init_proxy(void) print_proxy( "\n"); print_proxy( "#include \"%s\"\n", header_name); print_proxy( "\n"); - write_formatstringsdecl(); + write_formatstringsdecl(proxy, indent, ifaces, need_proxy); write_stubdescproto(); } -static void clear_output_vars( var_t *arg ) +static void clear_output_vars( const var_list_t *args ) { - END_OF_LIST(arg); - while (arg) { + const var_t *arg; + + if (!args) return; + LIST_FOR_EACH_ENTRY( arg, args, const var_t, entry ) + { if (is_attr(arg->attrs, ATTR_OUT) && !is_attr(arg->attrs, ATTR_IN)) { print_proxy( "if(%s)\n", arg->name ); indent++; - print_proxy( "MIDL_memset( %s, 0, sizeof( ", arg->name ); + print_proxy( "MIDL_memset( %s, 0, sizeof( *%s ));\n", arg->name, arg->name ); indent--; - write_type(proxy, arg->type, arg, arg->tname); - fprintf( proxy, " ));\n" ); } - arg = PREV_LINK(arg); } } -static int is_pointer(var_t *arg) +int is_var_ptr(const var_t *v) { - if (arg->ptr_level) - return 1; - if (arg->type->type == RPC_FC_FP ) - return 1; - return 0; + return is_ptr(v->type); } -static void proxy_check_pointers( var_t *arg ) +int cant_be_null(const var_t *v) { - END_OF_LIST(arg); - while (arg) { - if (is_pointer(arg)) { + /* Search backwards for the most recent pointer attribute. */ + const attr_list_t *attrs = v->attrs; + const type_t *type = v->type; + + if (! attrs && type) + { + attrs = type->attrs; + type = type->ref; + } + + while (attrs) + { + int t = get_attrv(attrs, ATTR_POINTERTYPE); + + if (t == RPC_FC_FP || t == RPC_FC_OP || t == RPC_FC_UP) + return 0; + + if (t == RPC_FC_RP) + return 1; + + if (type) + { + attrs = type->attrs; + type = type->ref; + } + else + attrs = NULL; + } + + return 1; /* Default is RPC_FC_RP. */ +} + +static void proxy_check_pointers( const var_list_t *args ) +{ + const var_t *arg; + + if (!args) return; + LIST_FOR_EACH_ENTRY( arg, args, const var_t, entry ) + { + if (is_var_ptr(arg) && cant_be_null(arg)) { print_proxy( "if(!%s)\n", arg->name ); indent++; print_proxy( "RpcRaiseException(RPC_X_NULL_REF_POINTER);\n"); indent--; } - arg = PREV_LINK(arg); } } -static void marshall_size_arg( var_t *arg ) +static void free_variable( const var_t *arg ) { - int index = 0; - const type_t *type = get_base_type(arg); - expr_t *expr; + unsigned int type_offset = arg->type->typestring_offset; + expr_t *iid; + type_t *type = arg->type; + expr_t *size = get_size_is_expr(type, arg->name); - expr = get_attrp( arg->attrs, ATTR_SIZEIS ); - if (expr) + if (size) { - print_proxy( "_StubMsg.MaxCount = ", arg->name ); - write_expr(proxy, expr, 0); - fprintf(proxy, ";\n\n"); - print_proxy( "NdrConformantArrayBufferSize( &_StubMsg, (unsigned char*)%s, ", arg->name ); - fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d]);\n", index ); - return; - } - - switch( type->type ) - { - case RPC_FC_BYTE: - case RPC_FC_CHAR: - print_proxy( "_StubMsg.BufferLength += %d; /* %s */\n", 1, arg->name ); - break; - - case RPC_FC_WCHAR: - case RPC_FC_SHORT: - case RPC_FC_USHORT: - case RPC_FC_ENUM16: - print_proxy( "_StubMsg.BufferLength += %d; /* %s */\n", 2, arg->name ); - break; - - case RPC_FC_LONG: - case RPC_FC_ULONG: - case RPC_FC_ENUM32: - print_proxy( "_StubMsg.BufferLength += %d; /* %s */\n", 4, arg->name ); - break; - - case RPC_FC_STRUCT: - print_proxy( "NdrSimpleStructBufferSize(&_StubMsg, (unsigned char*)%s, ", arg->name ); - fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d] );\n", index ); - break; - - case RPC_FC_C_CSTRING: - case RPC_FC_C_WSTRING: - case RPC_FC_CARRAY: - print_proxy( "NdrConformantArrayBufferSize( &_StubMsg, (unsigned char*)%s, ", arg->name ); - fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d]);\n", index ); - break; - - case RPC_FC_BOGUS_STRUCT: - print_proxy( "NdrComplexStructBufferSize(&_StubMsg, (unsigned char*)%s, ", arg->name ); - fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d] );\n", index ); - break; - - case RPC_FC_FP: - { - var_t temp; - memset( &temp, 0, sizeof temp ); - temp.type = type->ref; - temp.name = arg->name; /* FIXME */ -#if 0 - print_proxy( "/* FIXME: %s use the right name for %s */\n", __FUNCTION__, arg->name ); -#endif - marshall_size_arg( &temp ); - } - break; - - case RPC_FC_IP: - print_proxy( "NdrPointerBufferSize( &_StubMsg, (unsigned char*)%s, ", arg->name ); - fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d]);\n", index ); - break; - - default: - print_proxy("/* FIXME: %s code for %s type %d missing */\n", __FUNCTION__, arg->name, type->type ); - } -} - -static void proxy_gen_marshall_size( var_t *arg ) -{ - print_proxy( "_StubMsg.BufferLength = 0U;\n" ); - - END_OF_LIST(arg); - while (arg) { - if (is_attr(arg->attrs, ATTR_IN)) - { - marshall_size_arg( arg ); - fprintf(proxy, "\n"); - } - arg = PREV_LINK(arg); - } -} - -static void marshall_copy_arg( var_t *arg ) -{ - int index = 0; - type_t *type = get_base_type(arg); - expr_t *expr; - - expr = get_attrp( arg->attrs, ATTR_SIZEIS ); - if (expr) - { - print_proxy( "_StubMsg.MaxCount = ", arg->name ); - write_expr(proxy, expr, 0); - fprintf(proxy, ";\n\n"); - print_proxy( "NdrConformantArrayMarshall( &_StubMsg, (unsigned char*)%s, ", arg->name ); - fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d]);\n", index ); - return; - } - - switch( type->type ) - { - case RPC_FC_BYTE: - case RPC_FC_CHAR: - case RPC_FC_WCHAR: - case RPC_FC_SHORT: - case RPC_FC_USHORT: - case RPC_FC_ENUM16: - case RPC_FC_LONG: - case RPC_FC_ULONG: - case RPC_FC_ENUM32: - print_proxy( "*("); - write_type(proxy, arg->type, arg, arg->tname); - fprintf(proxy, " *)_StubMsg.Buffer = %s;\n", arg->name ); - print_proxy("_StubMsg.Buffer += sizeof("); - write_type(proxy, arg->type, arg, arg->tname); - fprintf(proxy, ");\n"); - break; - - case RPC_FC_STRUCT: - /* FIXME: add the format string, and set the index below */ - print_proxy( "NdrSimpleStructMarshall(&_StubMsg, (unsigned char*)%s, ", arg->name ); - fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d]);\n", index ); - break; - - case RPC_FC_C_CSTRING: - case RPC_FC_C_WSTRING: - case RPC_FC_CARRAY: - break; - - case RPC_FC_BOGUS_STRUCT: - print_proxy( "NdrComplexStructMarshall(&_StubMsg, (unsigned char*)%s, ", arg->name ); - fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d] );\n", index ); - break; - - case RPC_FC_FP: - { - var_t temp; - memset( &temp, 0, sizeof temp ); - temp.type = type->ref; - temp.name = arg->name; /* FIXME */ -#if 0 - print_proxy( "/* FIXME: %s use the right name for %s */\n", __FUNCTION__, arg->name ); -#endif - marshall_copy_arg( &temp ); - } - break; - - case RPC_FC_IP: - print_proxy( "NdrPointerMarshall( &_StubMsg, (unsigned char*)%s, ", arg->name ); - fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d]);\n", index ); - break; - - default: - print_proxy("/* FIXME: %s code for %s type %d missing */\n", __FUNCTION__, arg->name, type->type ); - } -} - -static void gen_marshall_copydata( var_t *arg ) -{ - END_OF_LIST(arg); - while (arg) { - if (is_attr(arg->attrs, ATTR_IN)) - { - marshall_copy_arg( arg ); - fprintf(proxy, "\n"); - } - arg = PREV_LINK(arg); - } -} - -static void gen_marshall( var_t *arg ) -{ - /* generated code to determine the size of the buffer required */ - proxy_gen_marshall_size( arg ); - - /* generated code to allocate the buffer */ - print_proxy( "NdrProxyGetBuffer(This, &_StubMsg);\n" ); - - /* generated code to copy the args into the buffer */ - gen_marshall_copydata( arg ); - - print_proxy( "\n"); -} - -static void unmarshall_copy_arg( var_t *arg ) -{ - int index = 0; - type_t *type = get_base_type(arg); - expr_t *expr; - - expr = get_attrp( arg->attrs, ATTR_SIZEIS ); - if (expr) - { - print_proxy( "NdrConformantArrayUnmarshall( &_StubMsg, (unsigned char*)%s, ", arg->name ); - fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d]);\n", index ); - return; - } - - switch( type->type ) - { - case RPC_FC_BYTE: - case RPC_FC_CHAR: - case RPC_FC_WCHAR: - case RPC_FC_SHORT: - case RPC_FC_USHORT: - case RPC_FC_ENUM16: - case RPC_FC_LONG: - case RPC_FC_ULONG: - case RPC_FC_ENUM32: - print_proxy( "%s = *(", arg->name ); - write_type(proxy, arg->type, arg, arg->tname); - fprintf(proxy," *)_StubMsg.Buffer;\n"); - print_proxy("_StubMsg.Buffer += sizeof("); - write_type(proxy, arg->type, arg, arg->tname); - fprintf(proxy, ");\n"); - break; - - case RPC_FC_STRUCT: - print_proxy( "NdrSimpleStructUnmarshall(&_StubMsg, (unsigned char**)%s, ", arg->name ); - fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d], 0);\n", index ); - break; - - case RPC_FC_C_CSTRING: - case RPC_FC_C_WSTRING: - case RPC_FC_CARRAY: - print_proxy( "NdrConformantArrayUnmarshall( &_StubMsg, (unsigned char*)%s, ", arg->name ); - fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d]);\n", index ); - break; - - case RPC_FC_BOGUS_STRUCT: - print_proxy( "NdrComplexStructUnmarshall(&_StubMsg, (unsigned char*)%s, ", arg->name ); - fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d], 0 );\n", index ); - break; - - case RPC_FC_FP: - { - var_t temp; - memset( &temp, 0, sizeof temp ); - temp.type = type->ref; - temp.name = arg->name; /* FIXME */ -#if 1 - print_proxy( "/* FIXME: %s use the right name for %s */\n", __FUNCTION__, arg->name ); -#endif - unmarshall_copy_arg( &temp ); - } - break; - - case RPC_FC_IP: - print_proxy( "NdrPointerUnmarshall(&_StubMsg, (unsigned char**)&%s, ", arg->name ); - fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d], 0);\n", index ); - break; - - default: - print_proxy("/* FIXME: %s code for %s type %d missing */\n", __FUNCTION__, arg->name, type->type ); - } -} - -static void gen_unmarshall( var_t *arg ) -{ - END_OF_LIST(arg); - while (arg) { - if (is_attr(arg->attrs, ATTR_OUT)) - { - unmarshall_copy_arg( arg ); - fprintf(proxy, "\n"); - } - arg = PREV_LINK(arg); - } -} - -static void free_variable( var_t *arg ) -{ - var_t *constraint; - int index = 0; /* FIXME */ - type_t *type; - expr_t *expr; - - expr = get_attrp( arg->attrs, ATTR_SIZEIS ); - if (expr) - { - print_proxy( "_StubMsg.MaxCount = ", arg->name ); - write_expr(proxy, expr, 0); + print_proxy( "_StubMsg.MaxCount = " ); + write_expr(proxy, size, 0); fprintf(proxy, ";\n\n"); print_proxy( "NdrClearOutParameters( &_StubMsg, "); - fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d], ", index ); + fprintf(proxy, "&__MIDL_TypeFormatString.Format[%u], ", type_offset ); fprintf(proxy, "(void*)%s );\n", arg->name ); return; } - type = get_base_type(arg); switch( type->type ) { case RPC_FC_BYTE: @@ -519,11 +219,15 @@ static void free_variable( var_t *arg ) case RPC_FC_FP: case RPC_FC_IP: - constraint = get_attrp( arg->attrs, ATTR_IIDIS ); - if( constraint ) - print_proxy( "_StubMsg.MaxCount = (unsigned long) ( %s );\n",constraint->name); + iid = get_attrp( arg->attrs, ATTR_IIDIS ); + if( iid ) + { + print_proxy( "_StubMsg.MaxCount = (unsigned long) " ); + write_expr(proxy, iid, 1); + print_proxy( ";\n\n" ); + } print_proxy( "NdrClearOutParameters( &_StubMsg, "); - fprintf(proxy, "&__MIDL_TypeFormatString.Format[%d], ", index ); + fprintf(proxy, "&__MIDL_TypeFormatString.Format[%u], ", type_offset ); fprintf(proxy, "(void*)%s );\n", arg->name ); break; @@ -532,26 +236,27 @@ static void free_variable( var_t *arg ) } } -static void proxy_free_variables( var_t *arg ) +static void proxy_free_variables( var_list_t *args ) { - END_OF_LIST(arg); - while (arg) { + const var_t *arg; + + if (!args) return; + LIST_FOR_EACH_ENTRY( arg, args, const var_t, entry ) if (is_attr(arg->attrs, ATTR_OUT)) { free_variable( arg ); fprintf(proxy, "\n"); } - arg = PREV_LINK(arg); - } } -static void gen_proxy(type_t *iface, func_t *cur, int idx) +static void gen_proxy(type_t *iface, const func_t *cur, int idx, + unsigned int proc_offset) { var_t *def = cur->def; - int has_ret = !is_void(def->type, def); + int has_ret = !is_void(def->type); indent = 0; - write_type(proxy, def->type, def, def->tname); + write_type_decl_left(proxy, def->type); print_proxy( " STDMETHODCALLTYPE %s_", iface->name); write_name(proxy, def); print_proxy( "_Proxy(\n"); @@ -562,11 +267,16 @@ static void gen_proxy(type_t *iface, func_t *cur, int idx) /* local variables */ if (has_ret) { print_proxy( "" ); - write_type(proxy, def->type, def, def->tname); + write_type_decl_left(proxy, def->type); print_proxy( " _RetVal;\n"); } - print_proxy( "RPC_MESSAGE _Msg;\n" ); + print_proxy( "RPC_MESSAGE _RpcMessage;\n" ); print_proxy( "MIDL_STUB_MESSAGE _StubMsg;\n" ); + if (has_ret) { + if (decl_indirect(def->type)) + print_proxy("void *_p_%s = &%s;\n", + "_RetVal", "_RetVal"); + } print_proxy( "\n"); /* FIXME: trace */ @@ -575,38 +285,39 @@ static void gen_proxy(type_t *iface, func_t *cur, int idx) print_proxy( "RpcTryExcept\n" ); print_proxy( "{\n" ); indent++; - print_proxy( "NdrProxyInitialize(This, &_Msg, &_StubMsg, &Object_StubDesc, %d);\n", idx); + print_proxy( "NdrProxyInitialize(This, &_RpcMessage, &_StubMsg, &Object_StubDesc, %d);\n", idx); proxy_check_pointers( cur->args ); print_proxy( "RpcTryFinally\n" ); print_proxy( "{\n" ); indent++; - gen_marshall( cur->args ); + write_remoting_arguments(proxy, indent, cur, PASS_IN, PHASE_BUFFERSIZE); + + print_proxy( "NdrProxyGetBuffer(This, &_StubMsg);\n" ); + + write_remoting_arguments(proxy, indent, cur, PASS_IN, PHASE_MARSHAL); print_proxy( "NdrProxySendReceive(This, &_StubMsg);\n" ); fprintf(proxy, "\n"); - print_proxy("if ((_Msg.DataRepresentation&0xffff) != NDR_LOCAL_DATA_REPRESENTATION)\n"); + print_proxy( "_StubMsg.BufferStart = _RpcMessage.Buffer;\n" ); + print_proxy( "_StubMsg.BufferEnd = _StubMsg.BufferStart + _RpcMessage.BufferLength;\n\n" ); + + print_proxy("if ((_RpcMessage.DataRepresentation & 0xffff) != NDR_LOCAL_DATA_REPRESENTATION)\n"); indent++; - print_proxy("NdrConvert( &_StubMsg, &__MIDL_ProcFormatString.Format[0]);\n" ); + print_proxy("NdrConvert( &_StubMsg, &__MIDL_ProcFormatString.Format[%u]);\n", proc_offset ); indent--; fprintf(proxy, "\n"); - gen_unmarshall( cur->args ); - if (has_ret) { - /* - * FIXME: We only need to round the buffer up if it could be unaligned... - * We should calculate how much buffer we used and output the following - * line only if necessary. - */ - print_proxy( "_StubMsg.Buffer = (unsigned char *)(((long)_StubMsg.Buffer + 3) & ~ 0x3);\n"); + write_remoting_arguments(proxy, indent, cur, PASS_OUT, PHASE_UNMARSHAL); - print_proxy( "_RetVal = *(" ); - write_type(proxy, def->type, def, def->tname); - fprintf(proxy, " *)_StubMsg.Buffer;\n"); - print_proxy("_StubMsg.Buffer += sizeof("); - write_type(proxy, def->type, def, def->tname); - fprintf(proxy, ");\n"); + if (has_ret) + { + if (decl_indirect(def->type)) + print_proxy("MIDL_memset(&%s, 0, sizeof(%s));\n", "_RetVal", "_RetVal"); + else if (is_ptr(def->type) || is_array(def->type)) + print_proxy("%s = 0;\n", "_RetVal"); + write_remoting_arguments(proxy, indent, cur, PASS_RETURN, PHASE_UNMARSHAL); } indent--; @@ -639,100 +350,12 @@ static void gen_proxy(type_t *iface, func_t *cur, int idx) print_proxy( "\n"); } -static void stub_write_locals( var_t *arg ) -{ - int n = 0; - while (arg) { - int outptr = is_attr(arg->attrs, ATTR_OUT); - - /* create a temporary variable to store the output */ - if (outptr) { - var_t temp; - memset( &temp, 0, sizeof temp ); - temp.ptr_level = arg->ptr_level - 1; /* dereference once */ - print_proxy(""); - write_type(proxy, arg->type, &temp, arg->tname); - fprintf(proxy, " _M%d;\n",n++); - } - print_proxy(""); - write_type(proxy, arg->type, arg, arg->tname); - fprintf(proxy, " "); - write_name(proxy, arg); - fprintf(proxy, ";\n"); - arg = NEXT_LINK(arg); - } -} - -static void stub_unmarshall( var_t *arg ) -{ - int n = 0; - END_OF_LIST(arg); - while (arg) { - if (is_attr(arg->attrs, ATTR_IN)) - { - unmarshall_copy_arg( arg ); - fprintf(proxy,"\n"); - } - else if (is_attr(arg->attrs, ATTR_OUT)) { - type_t *type = get_base_type(arg); - switch( type->type ) - { - case RPC_FC_STRUCT: - print_proxy("MIDL_memset("); - write_name(proxy, arg); - fprintf(proxy,", 0, sizeof("); - write_type(proxy, arg->type, arg, arg->tname); - fprintf(proxy,"));\n"); - break; - default: - print_proxy(""); - write_name(proxy, arg); - fprintf(proxy," = &_M%d;\n", n); - print_proxy("_M%d = 0;\n", n++); - break; - } - } - arg = PREV_LINK(arg); - } -} - -static void stub_gen_marshall_size( var_t *arg ) -{ - print_proxy( "_StubMsg.BufferLength = 0U;\n" ); - - END_OF_LIST(arg); - while (arg) { - if (is_attr(arg->attrs, ATTR_OUT)) - marshall_size_arg( arg ); - arg = PREV_LINK(arg); - } -} - -static void stub_gen_marshall_copydata( var_t *arg ) -{ - END_OF_LIST(arg); - while (arg) { - if (is_attr(arg->attrs, ATTR_OUT)) - marshall_copy_arg( arg ); - arg = PREV_LINK(arg); - } -} - -static void stub_genmarshall( var_t *args ) -{ - /* FIXME: size buffer */ - stub_gen_marshall_size( args ); - - print_proxy("NdrStubGetBuffer(This, pRpcChannelBuffer, &_StubMsg);\n"); - - stub_gen_marshall_copydata( args ); -} - -static void gen_stub(type_t *iface, func_t *cur, const char *cas) +static void gen_stub(type_t *iface, const func_t *cur, const char *cas, + unsigned int proc_offset) { var_t *def = cur->def; - var_t *arg; - int has_ret = !is_void(def->type, def); + const var_t *arg; + int has_ret = !is_void(def->type); indent = 0; print_proxy( "void __RPC_STUB %s_", iface->name); @@ -740,89 +363,86 @@ static void gen_stub(type_t *iface, func_t *cur, const char *cas) print_proxy( "_Stub(\n"); indent++; print_proxy( "IRpcStubBuffer* This,\n"); - print_proxy( "IRpcChannelBuffer* pRpcChannelBuffer,\n"); - print_proxy( "PRPC_MESSAGE _Msg,\n"); + print_proxy( "IRpcChannelBuffer *_pRpcChannelBuffer,\n"); + print_proxy( "PRPC_MESSAGE _pRpcMessage,\n"); print_proxy( "DWORD* _pdwStubPhase)\n"); indent--; print_proxy( "{\n"); indent++; - /* local variables */ - if (has_ret) { - print_proxy(""); - write_type(proxy, def->type, def, def->tname); - fprintf(proxy, " _RetVal;\n"); - } print_proxy("%s * _This = (%s*)((CStdStubBuffer*)This)->pvServerObject;\n", iface->name, iface->name); print_proxy("MIDL_STUB_MESSAGE _StubMsg;\n"); - stub_write_locals( cur->args ); + declare_stub_args( proxy, indent, cur ); fprintf(proxy, "\n"); /* FIXME: trace */ - print_proxy("NdrStubInitialize(_Msg, &_StubMsg, &Object_StubDesc, pRpcChannelBuffer);\n"); + print_proxy("NdrStubInitialize(_pRpcMessage, &_StubMsg, &Object_StubDesc, _pRpcChannelBuffer);\n"); fprintf(proxy, "\n"); + write_parameters_init(proxy, indent, cur); + print_proxy("RpcTryFinally\n"); print_proxy("{\n"); indent++; - print_proxy("if ((_Msg->DataRepresentation&0xffff) != NDR_LOCAL_DATA_REPRESENTATION)\n"); + print_proxy("if ((_pRpcMessage->DataRepresentation & 0xffff) != NDR_LOCAL_DATA_REPRESENTATION)\n"); indent++; - print_proxy("NdrConvert( &_StubMsg, &__MIDL_ProcFormatString.Format[0]);\n" ); + print_proxy("NdrConvert( &_StubMsg, &__MIDL_ProcFormatString.Format[%u]);\n", proc_offset ); indent--; fprintf(proxy, "\n"); - stub_unmarshall( cur->args ); + write_remoting_arguments(proxy, indent, cur, PASS_IN, PHASE_UNMARSHAL); fprintf(proxy, "\n"); + assign_stub_out_args( proxy, indent, cur ); + print_proxy("*_pdwStubPhase = STUB_CALL_SERVER;\n"); fprintf(proxy, "\n"); print_proxy(""); if (has_ret) fprintf(proxy, "_RetVal = "); - fprintf(proxy, "%s_", iface->name); - if (cas) fprintf(proxy, "%s_Stub", cas); - else write_name(proxy, def); + if (cas) fprintf(proxy, "%s_%s_Stub", iface->name, cas); + else + { + fprintf(proxy, "_This->lpVtbl->"); + write_name(proxy, def); + } fprintf(proxy, "(_This"); - arg = cur->args; - if (arg) { - END_OF_LIST(arg); - while (arg) { - fprintf(proxy, ", "); - write_name(proxy, arg); - arg = PREV_LINK(arg); - } + + if (cur->args) + { + LIST_FOR_EACH_ENTRY( arg, cur->args, const var_t, entry ) + { + fprintf(proxy, ", "); + if (arg->type->declarray) + fprintf(proxy, "*"); + write_name(proxy, arg); + } } fprintf(proxy, ");\n"); fprintf(proxy, "\n"); print_proxy("*_pdwStubPhase = STUB_MARSHAL;\n"); fprintf(proxy, "\n"); - stub_genmarshall( cur->args ); + write_remoting_arguments(proxy, indent, cur, PASS_OUT, PHASE_BUFFERSIZE); + + print_proxy("NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg);\n"); + + write_remoting_arguments(proxy, indent, cur, PASS_OUT, PHASE_MARSHAL); fprintf(proxy, "\n"); - if (has_ret) { - /* - * FIXME: We only need to round the buffer up if it could be unaligned... - * We should calculate how much buffer we used and output the following - * line only if necessary. - */ - print_proxy( "_StubMsg.Buffer = (unsigned char *)(((long)_StubMsg.Buffer + 3) & ~ 0x3);\n"); - - print_proxy( "*(" ); - write_type(proxy, def->type, def, def->tname); - fprintf(proxy, " *)_StubMsg.Buffer = _RetVal;\n"); - print_proxy("_StubMsg.Buffer += sizeof("); - write_type(proxy, def->type, def, def->tname); - fprintf(proxy, ");\n"); - } + if (has_ret) + print_phase_basetype(proxy, indent, PHASE_MARSHAL, PASS_RETURN, def, "_RetVal"); indent--; print_proxy("}\n"); print_proxy("RpcFinally\n"); print_proxy("{\n"); + + write_remoting_arguments(proxy, indent+1, cur, PASS_OUT, PHASE_FREE); + print_proxy("}\n"); print_proxy("RpcEndFinally\n"); - print_proxy("_Msg->BufferLength = _StubMsg.Buffer - (unsigned char *)_Msg->Buffer;\n"); + print_proxy("_pRpcMessage->BufferLength = _StubMsg.Buffer - (unsigned char *)_pRpcMessage->Buffer;\n"); indent--; print_proxy("}\n"); @@ -831,13 +451,11 @@ static void gen_stub(type_t *iface, func_t *cur, const char *cas) static int write_proxy_methods(type_t *iface) { - func_t *cur = iface->funcs; + const func_t *cur; int i = 0; - END_OF_LIST(cur); - if (iface->ref) i = write_proxy_methods(iface->ref); - while (cur) { + if (iface->funcs) LIST_FOR_EACH_ENTRY( cur, iface->funcs, const func_t, entry ) { var_t *def = cur->def; if (!is_callas(def->attrs)) { if (i) fprintf(proxy, ",\n"); @@ -846,21 +464,19 @@ static int write_proxy_methods(type_t *iface) fprintf(proxy, "_Proxy"); i++; } - cur = PREV_LINK(cur); } return i; } static int write_stub_methods(type_t *iface) { - func_t *cur = iface->funcs; + const func_t *cur; int i = 0; - END_OF_LIST(cur); - if (iface->ref) i = write_stub_methods(iface->ref); else return i; /* skip IUnknown */ - while (cur) { + + if (iface->funcs) LIST_FOR_EACH_ENTRY( cur, iface->funcs, const func_t, entry ) { var_t *def = cur->def; if (!is_local(def->attrs)) { if (i) fprintf(proxy,",\n"); @@ -869,48 +485,49 @@ static int write_stub_methods(type_t *iface) fprintf(proxy, "_Stub"); i++; } - cur = PREV_LINK(cur); } return i; } -static void write_proxy(type_t *iface) +static void write_proxy(type_t *iface, unsigned int *proc_offset) { int midx = -1, stubs; - func_t *cur = iface->funcs; + const func_t *cur; - if (!cur) return; - - END_OF_LIST(cur); + if (!iface->funcs) return; /* FIXME: check for [oleautomation], shouldn't generate proxies/stubs if specified */ fprintf(proxy, "/*****************************************************************************\n"); fprintf(proxy, " * %s interface\n", iface->name); fprintf(proxy, " */\n"); - while (cur) { + LIST_FOR_EACH_ENTRY( cur, iface->funcs, const func_t, entry ) + { const var_t *def = cur->def; if (!is_local(def->attrs)) { const var_t *cas = is_callas(def->attrs); const char *cname = cas ? cas->name : NULL; int idx = cur->idx; if (cname) { - const func_t *m = iface->funcs; - while (m && strcmp(get_name(m->def), cname)) - m = NEXT_LINK(m); - idx = m->idx; + const func_t *m; + LIST_FOR_EACH_ENTRY( m, iface->funcs, const func_t, entry ) + if (!strcmp(m->def->name, cname)) + { + idx = m->idx; + break; + } } - gen_proxy(iface, cur, idx); - gen_stub(iface, cur, cname); + gen_proxy(iface, cur, idx, *proc_offset); + gen_stub(iface, cur, cname, *proc_offset); + *proc_offset += get_size_procformatstring_func( cur ); if (midx == -1) midx = idx; - else if (midx != idx) yyerror("method index mismatch in write_proxy"); + else if (midx != idx) error("method index mismatch in write_proxy\n"); midx++; } - cur = PREV_LINK(cur); } /* proxy vtable */ - print_proxy( "const CINTERFACE_PROXY_VTABLE(%d) _%sProxyVtbl =\n", midx, iface->name); + print_proxy( "static const CINTERFACE_PROXY_VTABLE(%d) _%sProxyVtbl =\n", midx, iface->name); print_proxy( "{\n"); indent++; print_proxy( "{\n", iface->name); @@ -937,7 +554,7 @@ static void write_proxy(type_t *iface) indent--; fprintf(proxy, "};\n"); print_proxy( "\n"); - print_proxy( "const CInterfaceStubVtbl _%sStubVtbl =\n", iface->name); + print_proxy( "static const CInterfaceStubVtbl _%sStubVtbl =\n", iface->name); print_proxy( "{\n"); indent++; print_proxy( "{\n"); @@ -958,73 +575,97 @@ static void write_proxy(type_t *iface) print_proxy( "\n"); } -void write_proxies(ifref_t *ifaces) +static int does_any_iface(const ifref_list_t *ifaces, type_pred_t pred) +{ + ifref_t *ir; + + if (ifaces) + LIST_FOR_EACH_ENTRY(ir, ifaces, ifref_t, entry) + if (pred(ir->iface)) + return TRUE; + + return FALSE; +} + +int need_proxy(const type_t *iface) +{ + return is_object(iface->attrs) && !is_local(iface->attrs); +} + +int need_stub(const type_t *iface) +{ + return !is_object(iface->attrs) && !is_local(iface->attrs); +} + +int need_proxy_file(const ifref_list_t *ifaces) +{ + return does_any_iface(ifaces, need_proxy); +} + +int need_stub_files(const ifref_list_t *ifaces) +{ + return does_any_iface(ifaces, need_stub); +} + +void write_proxies(ifref_list_t *ifaces) { - ifref_t *lcur = ifaces; ifref_t *cur; + int expr_eval_routines; char *file_id = proxy_token; int c; + unsigned int proc_offset = 0; if (!do_proxies) return; - if (!lcur) return; - END_OF_LIST(lcur); + if (do_everything && !need_proxy_file(ifaces)) return; - init_proxy(); + init_proxy(ifaces); if(!proxy) return; - cur = lcur; - while (cur) { - if (is_object(cur->iface->attrs) && !is_local(cur->iface->attrs)) - write_proxy(cur->iface); - cur = PREV_LINK(cur); - } + if (ifaces) + LIST_FOR_EACH_ENTRY( cur, ifaces, ifref_t, entry ) + if (need_proxy(cur->iface)) + write_proxy(cur->iface, &proc_offset); - if (!proxy) return; - - write_stubdesc(); + expr_eval_routines = write_expr_eval_routines(proxy, proxy_token); + if (expr_eval_routines) + write_expr_eval_routine_list(proxy, proxy_token); + write_user_quad_list(proxy); + write_stubdesc(expr_eval_routines); print_proxy( "#if !defined(__RPC_WIN32__)\n"); print_proxy( "#error Currently only Wine and WIN32 are supported.\n"); print_proxy( "#endif\n"); print_proxy( "\n"); - write_formatstring( 1 ); - write_formatstring( 0 ); + write_procformatstring(proxy, ifaces, need_proxy); + write_typeformatstring(proxy, ifaces, need_proxy); - fprintf(proxy, "const CInterfaceProxyVtbl* _%s_ProxyVtblList[] =\n", file_id); + fprintf(proxy, "static const CInterfaceProxyVtbl* const _%s_ProxyVtblList[] =\n", file_id); fprintf(proxy, "{\n"); - cur = lcur; - while (cur) { - if(cur->iface->ref && cur->iface->funcs && - is_object(cur->iface->attrs) && !is_local(cur->iface->attrs)) - fprintf(proxy, " (CInterfaceProxyVtbl*)&_%sProxyVtbl,\n", cur->iface->name); - cur = PREV_LINK(cur); - } + if (ifaces) + LIST_FOR_EACH_ENTRY( cur, ifaces, ifref_t, entry ) + if(cur->iface->ref && cur->iface->funcs && need_proxy(cur->iface)) + fprintf(proxy, " (const CInterfaceProxyVtbl*)&_%sProxyVtbl,\n", cur->iface->name); + fprintf(proxy, " 0\n"); fprintf(proxy, "};\n"); fprintf(proxy, "\n"); - fprintf(proxy, "const CInterfaceStubVtbl* _%s_StubVtblList[] =\n", file_id); + fprintf(proxy, "static const CInterfaceStubVtbl* const _%s_StubVtblList[] =\n", file_id); fprintf(proxy, "{\n"); - cur = lcur; - while (cur) { - if(cur->iface->ref && cur->iface->funcs && - is_object(cur->iface->attrs) && !is_local(cur->iface->attrs)) - fprintf(proxy, " (CInterfaceStubVtbl*)&_%sStubVtbl,\n", cur->iface->name); - cur = PREV_LINK(cur); - } + if (ifaces) + LIST_FOR_EACH_ENTRY( cur, ifaces, ifref_t, entry ) + if(cur->iface->ref && cur->iface->funcs && need_proxy(cur->iface)) + fprintf(proxy, " (const CInterfaceStubVtbl*)&_%sStubVtbl,\n", cur->iface->name); fprintf(proxy, " 0\n"); fprintf(proxy, "};\n"); fprintf(proxy, "\n"); - fprintf(proxy, "PCInterfaceName const _%s_InterfaceNamesList[] =\n", file_id); + fprintf(proxy, "static PCInterfaceName const _%s_InterfaceNamesList[] =\n", file_id); fprintf(proxy, "{\n"); - cur = lcur; - while (cur) { - if(cur->iface->ref && cur->iface->funcs && - is_object(cur->iface->attrs) && !is_local(cur->iface->attrs)) - fprintf(proxy, " \"%s\",\n", cur->iface->name); - cur = PREV_LINK(cur); - } + if (ifaces) + LIST_FOR_EACH_ENTRY( cur, ifaces, ifref_t, entry ) + if(cur->iface->ref && cur->iface->funcs && need_proxy(cur->iface)) + fprintf(proxy, " \"%s\",\n", cur->iface->name); fprintf(proxy, " 0\n"); fprintf(proxy, "};\n"); fprintf(proxy, "\n"); @@ -1033,29 +674,27 @@ void write_proxies(ifref_t *ifaces) fprintf(proxy, "\n"); fprintf(proxy, "int __stdcall _%s_IID_Lookup(const IID* pIID, int* pIndex)\n", file_id); fprintf(proxy, "{\n"); - cur = lcur; c = 0; - while (cur) { - if(cur->iface->ref) - { - fprintf(proxy, " if (!_%s_CHECK_IID(%d))\n", file_id, c); - fprintf(proxy, " {\n"); - fprintf(proxy, " *pIndex = %d;\n", c); - fprintf(proxy, " return 1;\n"); - fprintf(proxy, " }\n"); - c++; - } - cur = PREV_LINK(cur); - } + if (ifaces) + LIST_FOR_EACH_ENTRY( cur, ifaces, ifref_t, entry ) + if(cur->iface->ref && cur->iface->funcs && need_proxy(cur->iface)) + { + fprintf(proxy, " if (!_%s_CHECK_IID(%d))\n", file_id, c); + fprintf(proxy, " {\n"); + fprintf(proxy, " *pIndex = %d;\n", c); + fprintf(proxy, " return 1;\n"); + fprintf(proxy, " }\n"); + c++; + } fprintf(proxy, " return 0;\n"); fprintf(proxy, "}\n"); fprintf(proxy, "\n"); fprintf(proxy, "const ExtendedProxyFileInfo %s_ProxyFileInfo =\n", file_id); fprintf(proxy, "{\n"); - fprintf(proxy, " (PCInterfaceProxyVtblList*)&_%s_ProxyVtblList,\n", file_id); - fprintf(proxy, " (PCInterfaceStubVtblList*)&_%s_StubVtblList,\n", file_id); - fprintf(proxy, " (const PCInterfaceName*)&_%s_InterfaceNamesList,\n", file_id); + fprintf(proxy, " (const PCInterfaceProxyVtblList*)&_%s_ProxyVtblList,\n", file_id); + fprintf(proxy, " (const PCInterfaceStubVtblList*)&_%s_StubVtblList,\n", file_id); + fprintf(proxy, " _%s_InterfaceNamesList,\n", file_id); fprintf(proxy, " 0,\n"); fprintf(proxy, " &_%s_IID_Lookup,\n", file_id); fprintf(proxy, " %d,\n", c); diff --git a/reactos/tools/widl/server.c b/reactos/tools/widl/server.c index 386fc1a1444..3fc6dd80053 100644 --- a/reactos/tools/widl/server.c +++ b/reactos/tools/widl/server.c @@ -36,166 +36,32 @@ #include "parser.h" #include "header.h" -#include "widl.h" -#include "typelib.h" -#include "typelib_struct.h" #include "typegen.h" static FILE* server; static int indent = 0; -static int print_server(const char *format, ...) +static void print_server(const char *format, ...) { va_list va; - int i, r; - va_start(va, format); - for (i = 0; i < indent; i++) - fprintf(server, " "); - r = vfprintf(server, format, va); + print(server, indent, format, va); va_end(va); - return r; } - -static void write_parameters_init(const func_t *func) -{ - const var_t *var; - - if (!func->args) - return; - - var = func->args; - while (NEXT_LINK(var)) var = NEXT_LINK(var); - while (var) - { - if (var->type->type != RPC_FC_BIND_PRIMITIVE) - print_server("%s = 0;\n", var->name); - - var = PREV_LINK(var); - } - fprintf(server, "\n"); -} - - -static void declare_args(const func_t *func) -{ - int in_attr, out_attr; - int i = 0; - var_t *var; - - if (!func->args) - return; - - var = func->args; - while (NEXT_LINK(var)) var = NEXT_LINK(var); - while (var) - { - const expr_t *size_is = get_attrp(var->attrs, ATTR_SIZEIS); - int has_size = size_is && (size_is->type != EXPR_VOID); - int is_string = is_attr(var->attrs, ATTR_STRING); - - in_attr = is_attr(var->attrs, ATTR_IN); - out_attr = is_attr(var->attrs, ATTR_OUT); - if (!out_attr && !in_attr) - in_attr = 1; - - if (!in_attr && !has_size && !is_string) - { - int indirection; - print_server(""); - write_type(server, var->type, NULL, var->tname); - for (indirection = 0; indirection < var->ptr_level - 1; indirection++) - fprintf(server, "*"); - fprintf(server, " _W%u;\n", i++); - } - - print_server(""); - write_type(server, var->type, var, var->tname); - fprintf(server, " "); - write_name(server, var); - write_array(server, var->array, 0); - fprintf(server, ";\n"); - - var = PREV_LINK(var); - } -} - - -static void assign_out_args(const func_t *func) -{ - int in_attr, out_attr; - int i = 0, sep = 0; - var_t *var; - const expr_t *size_is; - int has_size; - - if (!func->args) - return; - - var = func->args; - while (NEXT_LINK(var)) var = NEXT_LINK(var); - while (var) - { - int is_string = is_attr(var->attrs, ATTR_STRING); - size_is = get_attrp(var->attrs, ATTR_SIZEIS); - has_size = size_is && (size_is->type != EXPR_VOID); - in_attr = is_attr(var->attrs, ATTR_IN); - out_attr = is_attr(var->attrs, ATTR_OUT); - if (!out_attr && !in_attr) - in_attr = 1; - - if (!in_attr) - { - print_server(""); - write_name(server, var); - - if (has_size) - { - unsigned int size; - type_t *type = var->type; - while (type->type == 0 && type->ref) - type = type->ref; - - fprintf(server, " = NdrAllocate(&_StubMsg, "); - write_expr(server, size_is, 1); - size = get_type_memsize(type); - fprintf(server, " * %u);\n", size); - } - else if (!is_string) - { - fprintf(server, " = &_W%u;\n", i); - if (var->ptr_level > 1) - print_server("_W%u = 0;\n", i); - i++; - } - - sep = 1; - } - - var = PREV_LINK(var); - } - - if (sep) - fprintf(server, "\n"); -} - - -static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsigned int *type_offset) +static void write_function_stubs(type_t *iface, unsigned int *proc_offset) { char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE); int explicit_handle = is_attr(iface->attrs, ATTR_EXPLICIT_HANDLE); - const func_t *func = iface->funcs; + const func_t *func; const var_t *var; const var_t* explicit_handle_var; - while (NEXT_LINK(func)) func = NEXT_LINK(func); - while (func) + if (!iface->funcs) return; + LIST_FOR_EACH_ENTRY( func, iface->funcs, const func_t, entry ) { const var_t *def = func->def; - unsigned long buffer_size = 0; - unsigned int type_offset_func; /* check for a defined binding handle */ explicit_handle_var = get_explicit_handle_var(func); @@ -228,16 +94,8 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig fprintf(server, "{\n"); indent++; - /* declare return value '_RetVal' */ - if (!is_void(def->type, NULL)) - { - print_server(""); - write_type(server, def->type, def, def->tname); - fprintf(server, " _RetVal;\n"); - } - /* Declare arguments */ - declare_args(func); + declare_stub_args(server, indent, func); print_server("MIDL_STUB_MESSAGE _StubMsg;\n"); print_server("RPC_STATUS _Status;\n"); @@ -253,7 +111,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig indent--; fprintf(server, "\n"); - write_parameters_init(func); + write_parameters_init(server, indent, func); if (explicit_handle_var) { @@ -279,11 +137,8 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig indent -= 2; fprintf(server, "\n"); - /* make a copy so we don't increment the type offset twice */ - type_offset_func = *type_offset; - /* unmarshall arguments */ - write_remoting_arguments(server, indent, func, &type_offset_func, PASS_IN, PHASE_UNMARSHAL); + write_remoting_arguments(server, indent, func, PASS_IN, PHASE_UNMARSHAL); } print_server("if (_StubMsg.Buffer > _StubMsg.BufferEnd)\n"); @@ -304,14 +159,14 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig fprintf(server, "\n"); /* Assign 'out' arguments */ - assign_out_args(func); + assign_stub_out_args(server, indent, func); /* Call the real server function */ - if (!is_void(def->type, NULL)) + if (!is_void(def->type)) print_server("_RetVal = "); else print_server(""); - write_name(server, def); + write_prefix_name(server, prefix_server, def); if (func->args) { @@ -319,17 +174,25 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig fprintf(server, "(\n"); indent++; - var = func->args; - while (NEXT_LINK(var)) var = NEXT_LINK(var); - while (var) + LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) { if (first_arg) first_arg = 0; else fprintf(server, ",\n"); - print_server(""); - write_name(server, var); - var = PREV_LINK(var); + if (is_context_handle(var->type)) + { + print_server("("); + write_type_decl_left(server, var->type); + fprintf(server, ")%sNDRSContextValue(%s)", is_ptr(var->type) ? "" : "*", var->name); + } + else + { + print_server(""); + if (var->type->declarray) + fprintf(server, "*"); + write_name(server, var); + } } fprintf(server, ");\n"); indent--; @@ -339,37 +202,12 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig fprintf(server, "();\n"); } - if (func->args) - { - const var_t *var = func->args; - while (NEXT_LINK(var)) var = NEXT_LINK(var); - while (var) - { - if (is_attr(var->attrs, ATTR_OUT)) - { - unsigned int alignment; - buffer_size += get_required_buffer_size(var, &alignment, PASS_OUT); - buffer_size += alignment; - } - - var = PREV_LINK(var); - } - } - - if (!is_void(def->type, NULL)) - { - unsigned int alignment; - buffer_size += get_required_buffer_size(def, &alignment, PASS_RETURN); - buffer_size += alignment; - } - if (has_out_arg_or_return(func)) { - fprintf(server, "\n"); - print_server("_StubMsg.BufferLength = %u;\n", buffer_size); + write_remoting_arguments(server, indent, func, PASS_OUT, PHASE_BUFFERSIZE); - type_offset_func = *type_offset; - write_remoting_arguments(server, indent, func, &type_offset_func, PASS_OUT, PHASE_BUFFERSIZE); + if (!is_void(def->type)) + write_remoting_arguments(server, indent, func, PASS_RETURN, PHASE_BUFFERSIZE); print_server("_pRpcMessage->BufferLength = _StubMsg.BufferLength;\n"); fprintf(server, "\n"); @@ -383,14 +221,12 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig fprintf(server, "\n"); } - type_offset_func = *type_offset; - /* marshall arguments */ - write_remoting_arguments(server, indent, func, type_offset, PASS_OUT, PHASE_MARSHAL); + write_remoting_arguments(server, indent, func, PASS_OUT, PHASE_MARSHAL); /* marshall the return value */ - if (!is_void(def->type, NULL)) - print_phase_basetype(server, indent, PHASE_MARSHAL, PASS_RETURN, def, "_RetVal"); + if (!is_void(def->type)) + write_remoting_arguments(server, indent, func, PASS_RETURN, PHASE_MARSHAL); indent--; print_server("}\n"); @@ -398,7 +234,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig print_server("{\n"); indent++; - write_remoting_arguments(server, indent, func, &type_offset_func, PASS_OUT, PHASE_FREE); + write_remoting_arguments(server, indent, func, PASS_OUT, PHASE_FREE); indent--; print_server("}\n"); @@ -415,22 +251,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig fprintf(server, "\n"); /* update proc_offset */ - if (func->args) - { - var = func->args; - while (NEXT_LINK(var)) var = NEXT_LINK(var); - while (var) - { - *proc_offset += get_size_procformatstring_var(var); - var = PREV_LINK(var); - } - } - if (!is_void(def->type, NULL)) - *proc_offset += get_size_procformatstring_var(def); - else - *proc_offset += 2; /* FC_END and FC_PAD */ - - func = PREV_LINK(func); + *proc_offset += get_size_procformatstring_func( func ); } } @@ -439,13 +260,13 @@ static void write_dispatchtable(type_t *iface) { unsigned long ver = get_attrv(iface->attrs, ATTR_VERSION); unsigned long method_count = 0; - func_t *func = iface->funcs; + const func_t *func; print_server("static RPC_DISPATCH_FUNCTION %s_table[] =\n", iface->name); print_server("{\n"); indent++; - while (NEXT_LINK(func)) func = NEXT_LINK(func); - while (func) + + if (iface->funcs) LIST_FOR_EACH_ENTRY( func, iface->funcs, const func_t, entry ) { var_t *def = func->def; @@ -454,12 +275,11 @@ static void write_dispatchtable(type_t *iface) fprintf(server, ",\n"); method_count++; - func = PREV_LINK(func); } print_server("0\n"); indent--; print_server("};\n"); - print_server("RPC_DISPATCH_TABLE %s_v%d_%d_DispatchTable =\n", iface->name, LOWORD(ver), HIWORD(ver)); + print_server("RPC_DISPATCH_TABLE %s_v%d_%d_DispatchTable =\n", iface->name, MAJORVERSION(ver), MINORVERSION(ver)); print_server("{\n"); indent++; print_server("%u,\n", method_count); @@ -503,7 +323,7 @@ static void write_stubdescriptor(type_t *iface, int expr_eval_routines) print_server("0,\n"); print_server("0x50100a4, /* MIDL Version 5.1.164 */\n"); print_server("0,\n"); - print_server("0,\n"); + print_server("%s,\n", list_empty(&user_type_list) ? "0" : "UserMarshalRoutines"); print_server("0, /* notify & notify_flag routine table */\n"); print_server("1, /* Flags */\n"); print_server("0, /* Reserved3 */\n"); @@ -519,8 +339,11 @@ static void write_serverinterfacedecl(type_t *iface) { unsigned long ver = get_attrv(iface->attrs, ATTR_VERSION); UUID *uuid = get_attrp(iface->attrs, ATTR_UUID); + const str_list_t *endpoints = get_attrp(iface->attrs, ATTR_ENDPOINT); - print_server("extern RPC_DISPATCH_TABLE %s_v%d_%d_DispatchTable;\n", iface->name, LOWORD(ver), HIWORD(ver)); + if (endpoints) write_endpoints( server, iface->name, endpoints ); + + print_server("extern RPC_DISPATCH_TABLE %s_v%d_%d_DispatchTable;\n", iface->name, MAJORVERSION(ver), MINORVERSION(ver)); fprintf(server, "\n"); print_server("static const RPC_SERVER_INTERFACE %s___RpcServerInterface =\n", iface->name ); print_server("{\n"); @@ -529,11 +352,19 @@ static void write_serverinterfacedecl(type_t *iface) print_server("{{0x%08lx,0x%04x,0x%04x,{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x}},{%d,%d}},\n", uuid->Data1, uuid->Data2, uuid->Data3, uuid->Data4[0], uuid->Data4[1], uuid->Data4[2], uuid->Data4[3], uuid->Data4[4], uuid->Data4[5], uuid->Data4[6], - uuid->Data4[7], LOWORD(ver), HIWORD(ver)); + uuid->Data4[7], MAJORVERSION(ver), MINORVERSION(ver)); print_server("{{0x8a885d04,0x1ceb,0x11c9,{0x9f,0xe8,0x08,0x00,0x2b,0x10,0x48,0x60}},{2,0}},\n"); /* FIXME */ - print_server("&%s_v%d_%d_DispatchTable,\n", iface->name, LOWORD(ver), HIWORD(ver)); - print_server("0,\n"); - print_server("0,\n"); + print_server("&%s_v%d_%d_DispatchTable,\n", iface->name, MAJORVERSION(ver), MINORVERSION(ver)); + if (endpoints) + { + print_server("%u,\n", list_count(endpoints)); + print_server("(PRPC_PROTSEQ_ENDPOINT)%s__RpcProtseqEndpoint,\n", iface->name); + } + else + { + print_server("0,\n"); + print_server("0,\n"); + } print_server("0,\n"); print_server("0,\n"); print_server("0,\n"); @@ -543,41 +374,11 @@ static void write_serverinterfacedecl(type_t *iface) print_server("RPC_IF_HANDLE %s_ServerIfHandle = (RPC_IF_HANDLE)& %s___RpcServerInterface;\n", iface->name, iface->name); else - print_server("RPC_IF_HANDLE %s_v%d_%d_s_ifspec = (RPC_IF_HANDLE)& %s___RpcServerInterface;\n", - iface->name, LOWORD(ver), HIWORD(ver), iface->name); + print_server("RPC_IF_HANDLE %s%s_v%d_%d_s_ifspec = (RPC_IF_HANDLE)& %s___RpcServerInterface;\n", + prefix_server, iface->name, MAJORVERSION(ver), MINORVERSION(ver), iface->name); fprintf(server, "\n"); } -static void write_formatdesc( const char *str ) -{ - print_server("typedef struct _MIDL_%s_FORMAT_STRING\n", str ); - print_server("{\n"); - indent++; - print_server("short Pad;\n"); - print_server("unsigned char Format[%s_FORMAT_STRING_SIZE];\n", str); - indent--; - print_server("} MIDL_%s_FORMAT_STRING;\n", str); - print_server("\n"); -} - - -static void write_formatstringsdecl(ifref_t *ifaces) -{ - print_server("#define TYPE_FORMAT_STRING_SIZE %d\n", - get_size_typeformatstring(ifaces)); - - print_server("#define PROC_FORMAT_STRING_SIZE %d\n", - get_size_procformatstring(ifaces)); - - fprintf(server, "\n"); - write_formatdesc("TYPE"); - write_formatdesc("PROC"); - fprintf(server, "\n"); - print_server("static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString;\n"); - print_server("static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString;\n"); - print_server("\n"); -} - static void init_server(void) { @@ -586,35 +387,39 @@ static void init_server(void) if (!(server = fopen(server_name, "w"))) error("Could not open %s for output\n", server_name); - print_server("/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n", WIDL_FULLVERSION, input_name); + print_server("/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n", PACKAGE_VERSION, input_name); print_server("#include \n"); fprintf(server, "\n"); + print_server("#define _SEH_NO_NATIVE_NLG\n"); print_server("#include \"%s\"\n", header_name); fprintf(server, "\n"); } -void write_server(ifref_t *ifaces) +void write_server(ifref_list_t *ifaces) { unsigned int proc_offset = 0; - unsigned int type_offset = 2; - ifref_t *iface = ifaces; + int expr_eval_routines; + ifref_t *iface; if (!do_server) return; - if (!ifaces) + if (do_everything && !need_stub_files(ifaces)) return; - END_OF_LIST(iface); init_server(); if (!server) return; - write_formatstringsdecl(ifaces); + write_formatstringsdecl(server, indent, ifaces, need_stub); + expr_eval_routines = write_expr_eval_routines(server, server_token); + if (expr_eval_routines) + write_expr_eval_routine_list(server, server_token); + write_user_quad_list(server); - for (; iface; iface = PREV_LINK(iface)) + if (ifaces) LIST_FOR_EACH_ENTRY( iface, ifaces, ifref_t, entry ) { - if (is_object(iface->iface->attrs) || is_local(iface->iface->attrs)) + if (!need_stub(iface->iface)) continue; fprintf(server, "/*****************************************************************************\n"); @@ -624,23 +429,16 @@ void write_server(ifref_t *ifaces) if (iface->iface->funcs) { - int expr_eval_routines; - write_serverinterfacedecl(iface->iface); write_stubdescdecl(iface->iface); - - write_function_stubs(iface->iface, &proc_offset, &type_offset); - + + write_function_stubs(iface->iface, &proc_offset); + print_server("#if !defined(__RPC_WIN32__)\n"); print_server("#error Invalid build platform for this stub.\n"); print_server("#endif\n"); fprintf(server, "\n"); - - expr_eval_routines = write_expr_eval_routines(server, iface->iface->name); - if (expr_eval_routines) - write_expr_eval_routine_list(server, iface->iface->name); - write_stubdescriptor(iface->iface, expr_eval_routines); write_dispatchtable(iface->iface); } @@ -648,8 +446,8 @@ void write_server(ifref_t *ifaces) fprintf(server, "\n"); - write_procformatstring(server, ifaces); - write_typeformatstring(server, ifaces); + write_procformatstring(server, ifaces, need_stub); + write_typeformatstring(server, ifaces, need_stub); fclose(server); } diff --git a/reactos/tools/widl/typegen.c b/reactos/tools/widl/typegen.c index 8b0d3313dec..f40399f16b2 100644 --- a/reactos/tools/widl/typegen.c +++ b/reactos/tools/widl/typegen.c @@ -39,27 +39,246 @@ #include "header.h" #include "wine/list.h" -#include "widl.h" #include "typegen.h" static const func_t *current_func; static const type_t *current_structure; -/* name of the structure variable for structure callbacks */ -#define STRUCT_EXPR_EVAL_VAR "pS" - static struct list expr_eval_routines = LIST_INIT(expr_eval_routines); - struct expr_eval_routine { struct list entry; const type_t *structure; - size_t structure_size; + unsigned int baseoff; const expr_t *expr; }; -static size_t type_memsize(const type_t *t, int ptr_level, const expr_t *array); -static size_t fields_memsize(const var_t *v); +static size_t fields_memsize(const var_list_t *fields, unsigned int *align); +static size_t write_struct_tfs(FILE *file, type_t *type, const char *name, unsigned int *tfsoff); +static int write_embedded_types(FILE *file, const attr_list_t *attrs, type_t *type, + const char *name, int write_ptr, unsigned int *tfsoff); +static const var_t *find_array_or_string_in_struct(const type_t *type); + +const char *string_of_type(unsigned char type) +{ + switch (type) + { + case RPC_FC_BYTE: return "FC_BYTE"; + case RPC_FC_CHAR: return "FC_CHAR"; + case RPC_FC_SMALL: return "FC_SMALL"; + case RPC_FC_USMALL: return "FC_USMALL"; + case RPC_FC_WCHAR: return "FC_WCHAR"; + case RPC_FC_SHORT: return "FC_SHORT"; + case RPC_FC_USHORT: return "FC_USHORT"; + case RPC_FC_LONG: return "FC_LONG"; + case RPC_FC_ULONG: return "FC_ULONG"; + case RPC_FC_FLOAT: return "FC_FLOAT"; + case RPC_FC_HYPER: return "FC_HYPER"; + case RPC_FC_DOUBLE: return "FC_DOUBLE"; + case RPC_FC_ENUM16: return "FC_ENUM16"; + case RPC_FC_ENUM32: return "FC_ENUM32"; + case RPC_FC_IGNORE: return "FC_IGNORE"; + case RPC_FC_ERROR_STATUS_T: return "FC_ERROR_STATUS_T"; + case RPC_FC_RP: return "FC_RP"; + case RPC_FC_UP: return "FC_UP"; + case RPC_FC_OP: return "FC_OP"; + case RPC_FC_FP: return "FC_FP"; + case RPC_FC_ENCAPSULATED_UNION: return "FC_ENCAPSULATED_UNION"; + case RPC_FC_NON_ENCAPSULATED_UNION: return "FC_NON_ENCAPSULATED_UNION"; + case RPC_FC_STRUCT: return "FC_STRUCT"; + case RPC_FC_PSTRUCT: return "FC_PSTRUCT"; + case RPC_FC_CSTRUCT: return "FC_CSTRUCT"; + case RPC_FC_CPSTRUCT: return "FC_CPSTRUCT"; + case RPC_FC_CVSTRUCT: return "FC_CVSTRUCT"; + case RPC_FC_BOGUS_STRUCT: return "FC_BOGUS_STRUCT"; + case RPC_FC_SMFARRAY: return "FC_SMFARRAY"; + case RPC_FC_LGFARRAY: return "FC_LGFARRAY"; + case RPC_FC_SMVARRAY: return "FC_SMVARRAY"; + case RPC_FC_LGVARRAY: return "FC_LGVARRAY"; + case RPC_FC_CARRAY: return "FC_CARRAY"; + case RPC_FC_CVARRAY: return "FC_CVARRAY"; + case RPC_FC_BOGUS_ARRAY: return "FC_BOGUS_ARRAY"; + case RPC_FC_ALIGNM4: return "FC_ALIGNM4"; + case RPC_FC_ALIGNM8: return "FC_ALIGNM8"; + case RPC_FC_POINTER: return "FC_POINTER"; + case RPC_FC_C_CSTRING: return "FC_C_CSTRING"; + case RPC_FC_C_WSTRING: return "FC_C_WSTRING"; + case RPC_FC_CSTRING: return "FC_CSTRING"; + case RPC_FC_WSTRING: return "FC_WSTRING"; + default: + error("string_of_type: unknown type 0x%02x\n", type); + return NULL; + } +} + +int is_struct(unsigned char type) +{ + switch (type) + { + case RPC_FC_STRUCT: + case RPC_FC_PSTRUCT: + case RPC_FC_CSTRUCT: + case RPC_FC_CPSTRUCT: + case RPC_FC_CVSTRUCT: + case RPC_FC_BOGUS_STRUCT: + return 1; + default: + return 0; + } +} + +static int is_non_complex_struct(const type_t *type) +{ + switch (type->type) + { + case RPC_FC_STRUCT: + case RPC_FC_PSTRUCT: + case RPC_FC_CSTRUCT: + case RPC_FC_CPSTRUCT: + case RPC_FC_CVSTRUCT: + return 1; + default: + return 0; + } +} + +int is_union(unsigned char type) +{ + switch (type) + { + case RPC_FC_ENCAPSULATED_UNION: + case RPC_FC_NON_ENCAPSULATED_UNION: + return 1; + default: + return 0; + } +} + +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; + unsigned short off = 0; + LIST_FOR_EACH_ENTRY(ut, &user_type_list, user_type_t, entry) + { + if (strcmp(name, ut->name) == 0) + return off; + ++off; + } + error("user_type_offset: couldn't find type (%s)\n", name); + return 0; +} + +static void update_tfsoff(type_t *type, unsigned int offset, FILE *file) +{ + type->typestring_offset = offset; + if (file) type->tfswrite = FALSE; +} + +static void guard_rec(type_t *type) +{ + /* types that contain references to themselves (like a linked list), + need to be shielded from infinite recursion when writing embedded + types */ + if (type->typestring_offset) + type->tfswrite = FALSE; + else + type->typestring_offset = 1; +} + +static type_t *get_user_type(const type_t *t, const char **pname) +{ + for (;;) + { + type_t *ut = get_attrp(t->attrs, ATTR_WIREMARSHAL); + if (ut) + { + if (pname) + *pname = t->name; + return ut; + } + + if (t->kind == TKIND_ALIAS) + t = t->orig; + else + return 0; + } +} + +int is_user_type(const type_t *t) +{ + return get_user_type(t, NULL) != NULL; +} + +static int is_embedded_complex(const type_t *type) +{ + unsigned char tc = type->type; + return is_struct(tc) || is_union(tc) || is_array(type) || is_user_type(type) + || (is_ptr(type) && type->ref->type == RPC_FC_IP); +} + +static const char *get_context_handle_type_name(const type_t *type) +{ + const type_t *t; + for (t = type; is_ptr(t); t = t->ref) + if (is_attr(t->attrs, ATTR_CONTEXTHANDLE)) + return t->name; + assert(0); + return NULL; +} + +/* This is actually fairly involved to implement precisely, due to the + effects attributes may have and things like that. Right now this is + only used for optimization, so just check for a very small set of + criteria that guarantee the types are equivalent; assume every thing + else is different. */ +static int compare_type(const type_t *a, const type_t *b) +{ + if (a == b + || (a->name + && b->name + && strcmp(a->name, b->name) == 0)) + return 0; + /* Ordering doesn't need to be implemented yet. */ + return 1; +} static int compare_expr(const expr_t *a, const expr_t *b) { @@ -74,6 +293,8 @@ static int compare_expr(const expr_t *a, const expr_t *b) case EXPR_HEXNUM: case EXPR_TRUEFALSE: return a->u.lval - b->u.lval; + case EXPR_DOUBLE: + return a->u.dval - b->u.dval; case EXPR_IDENTIFIER: return strcmp(a->u.sval, b->u.sval); case EXPR_COND: @@ -96,12 +317,18 @@ static int compare_expr(const expr_t *a, const expr_t *b) if (ret != 0) return ret; return compare_expr(a->u.ext, b->u.ext); + case EXPR_CAST: + ret = compare_type(a->u.tref, b->u.tref); + if (ret != 0) + return ret; + /* Fall through. */ case EXPR_NOT: case EXPR_NEG: case EXPR_PPTR: - case EXPR_CAST: - case EXPR_SIZEOF: + case EXPR_ADDRESSOF: return compare_expr(a->ref, b->ref); + case EXPR_SIZEOF: + return compare_type(a->u.tref, b->u.tref); case EXPR_VOID: return 0; } @@ -116,24 +343,75 @@ static int compare_expr(const expr_t *a, const expr_t *b) } \ while (0) -static int print_file(FILE *file, int indent, const char *format, ...) +static void print_file(FILE *file, int indent, const char *format, ...) { va_list va; - int i, r; - - if (!file) return 0; - va_start(va, format); - for (i = 0; i < indent; i++) - fprintf(file, " "); - r = vfprintf(file, format, va); + print(file, indent, format, va); va_end(va); - return r; } -static inline int type_has_ref(const type_t *type) +void print(FILE *file, int indent, const char *format, va_list va) { - return (type->type == 0 && type->ref); + if (file) + { + if (format[0] != '\n') + while (0 < indent--) + fprintf(file, " "); + vfprintf(file, format, va); + } +} + + +static void write_var_init(FILE *file, int indent, const type_t *t, const char *n) +{ + if (decl_indirect(t)) + print_file(file, indent, "MIDL_memset(&%s, 0, sizeof(%s));\n", n, n); + else if (is_ptr(t) || is_array(t)) + print_file(file, indent, "%s = 0;\n", n); +} + +void write_parameters_init(FILE *file, int indent, const func_t *func) +{ + const var_t *var; + + if (!is_void(func->def->type)) + write_var_init(file, indent, func->def->type, "_RetVal"); + + if (!func->args) + return; + + LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) + write_var_init(file, indent, var->type, var->name); + + fprintf(file, "\n"); +} + +static void write_formatdesc(FILE *f, int indent, const char *str) +{ + print_file(f, indent, "typedef struct _MIDL_%s_FORMAT_STRING\n", str); + print_file(f, indent, "{\n"); + print_file(f, indent + 1, "short Pad;\n"); + print_file(f, indent + 1, "unsigned char Format[%s_FORMAT_STRING_SIZE];\n", str); + print_file(f, indent, "} MIDL_%s_FORMAT_STRING;\n", str); + print_file(f, indent, "\n"); +} + +void write_formatstringsdecl(FILE *f, int indent, ifref_list_t *ifaces, type_pred_t pred) +{ + print_file(f, indent, "#define TYPE_FORMAT_STRING_SIZE %d\n", + get_size_typeformatstring(ifaces, pred)); + + print_file(f, indent, "#define PROC_FORMAT_STRING_SIZE %d\n", + get_size_procformatstring(ifaces, pred)); + + fprintf(f, "\n"); + write_formatdesc(f, indent, "TYPE"); + write_formatdesc(f, indent, "PROC"); + fprintf(f, "\n"); + print_file(f, indent, "static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString;\n"); + print_file(f, indent, "static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString;\n"); + print_file(f, indent, "\n"); } static inline int is_base_type(unsigned char type) @@ -164,11 +442,18 @@ static inline int is_base_type(unsigned char type) } } +int decl_indirect(const type_t *t) +{ + return is_user_type(t) + || (!is_base_type(t->type) + && !is_ptr(t) + && !is_array(t)); +} + static size_t write_procformatstring_var(FILE *file, int indent, - const var_t *var, int is_return, unsigned int *type_offset) + const var_t *var, int is_return) { size_t size; - int ptr_level = var->ptr_level; const type_t *type = var->type; int is_in = is_attr(var->attrs, ATTR_IN); @@ -176,46 +461,25 @@ static size_t write_procformatstring_var(FILE *file, int indent, if (!is_in && !is_out) is_in = TRUE; - if (ptr_level == 0 && type_has_ref(type)) - type = type->ref; - - if (ptr_level == 0 && !var->array && is_base_type(type->type)) + if (!type->declarray && is_base_type(type->type)) { if (is_return) print_file(file, indent, "0x53, /* FC_RETURN_PARAM_BASETYPE */\n"); else print_file(file, indent, "0x4e, /* FC_IN_PARAM_BASETYPE */\n"); - switch(type->type) + if (type->type == RPC_FC_BIND_PRIMITIVE) { -#define CASE_BASETYPE(fctype) \ - case RPC_##fctype: \ - print_file(file, indent, "0x%02x, /* " #fctype " */\n", RPC_##fctype); \ - size = 2; /* includes param type prefix */ \ - break - - CASE_BASETYPE(FC_BYTE); - CASE_BASETYPE(FC_CHAR); - CASE_BASETYPE(FC_WCHAR); - CASE_BASETYPE(FC_USHORT); - CASE_BASETYPE(FC_SHORT); - CASE_BASETYPE(FC_ULONG); - CASE_BASETYPE(FC_LONG); - CASE_BASETYPE(FC_HYPER); - CASE_BASETYPE(FC_IGNORE); - CASE_BASETYPE(FC_USMALL); - CASE_BASETYPE(FC_SMALL); - CASE_BASETYPE(FC_FLOAT); - CASE_BASETYPE(FC_DOUBLE); - CASE_BASETYPE(FC_ERROR_STATUS_T); -#undef CASE_BASETYPE - - case RPC_FC_BIND_PRIMITIVE: print_file(file, indent, "0x%02x, /* FC_IGNORE */\n", RPC_FC_IGNORE); size = 2; /* includes param type prefix */ - break; - - default: + } + else if (is_base_type(type->type)) + { + print_file(file, indent, "0x%02x, /* %s */\n", type->type, string_of_type(type->type)); + size = 2; /* includes param type prefix */ + } + else + { error("Unknown/unsupported type: %s (0x%02x)\n", var->name, type->type); size = 0; } @@ -232,19 +496,17 @@ static size_t write_procformatstring_var(FILE *file, int indent, print_file(file, indent, "0x4d, /* FC_IN_PARAM */\n"); print_file(file, indent, "0x01,\n"); - print_file(file, indent, "NdrFcShort(0x%x),\n", *type_offset); + print_file(file, indent, "NdrFcShort(0x%x),\n", type->typestring_offset); size = 4; /* includes param type prefix */ } - *type_offset += get_size_typeformatstring_var(var); return size; } -void write_procformatstring(FILE *file, const ifref_t *ifaces) +void write_procformatstring(FILE *file, const ifref_list_t *ifaces, type_pred_t pred) { - const ifref_t *iface = ifaces; + const ifref_t *iface; int indent = 0; - var_t *var; - unsigned int type_offset = 2; + const var_t *var; print_file(file, indent, "static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString =\n"); print_file(file, indent, "{\n"); @@ -253,43 +515,33 @@ void write_procformatstring(FILE *file, const ifref_t *ifaces) print_file(file, indent, "{\n"); indent++; - END_OF_LIST(iface); - - for (; iface; iface = PREV_LINK(iface)) + if (ifaces) LIST_FOR_EACH_ENTRY( iface, ifaces, const ifref_t, entry ) { - if (is_object(iface->iface->attrs) || is_local(iface->iface->attrs)) + if (!pred(iface->iface)) continue; if (iface->iface->funcs) { - func_t *func = iface->iface->funcs; - while (NEXT_LINK(func)) func = NEXT_LINK(func); - for (; func; func = PREV_LINK(func)) + const func_t *func; + LIST_FOR_EACH_ENTRY( func, iface->iface->funcs, const func_t, entry ) { + if (is_local(func->def->attrs)) continue; /* emit argument data */ if (func->args) { - var = func->args; - while (NEXT_LINK(var)) var = NEXT_LINK(var); - while (var) - { - write_procformatstring_var(file, indent, var, FALSE, - &type_offset); - - var = PREV_LINK(var); - } + LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) + write_procformatstring_var(file, indent, var, FALSE); } /* emit return value data */ var = func->def; - if (is_void(var->type, NULL)) + if (is_void(var->type)) { print_file(file, indent, "0x5b, /* FC_END */\n"); print_file(file, indent, "0x5c, /* FC_PAD */\n"); } else - write_procformatstring_var(file, indent, var, TRUE, - &type_offset); + write_procformatstring_var(file, indent, var, TRUE); } } } @@ -302,15 +554,44 @@ void write_procformatstring(FILE *file, const ifref_t *ifaces) print_file(file, indent, "\n"); } +static int write_base_type(FILE *file, const type_t *type, unsigned int *typestring_offset) +{ + if (is_base_type(type->type)) + { + print_file(file, 2, "0x%02x,\t/* %s */\n", type->type, string_of_type(type->type)); + *typestring_offset += 1; + return 1; + } + + return 0; +} + /* write conformance / variance descriptor */ -static size_t write_conf_or_var_desc(FILE *file, const func_t *func, const type_t *structure, const expr_t *expr) +static size_t write_conf_or_var_desc(FILE *file, const type_t *structure, + unsigned int baseoff, const type_t *type, + const expr_t *expr) { unsigned char operator_type = 0; + unsigned char conftype = RPC_FC_NORMAL_CONFORMANCE; + const char *conftype_string = ""; const char *operator_string = "no operators"; - const expr_t *subexpr = expr; - unsigned char correlation_type; + const expr_t *subexpr; - if (!file) return 4; /* optimisation for sizing pass */ + if (!expr) + { + print_file(file, 2, "NdrFcLong(0xffffffff),\t/* -1 */\n"); + return 4; + } + + if (!structure) + { + /* Top-level conformance calculations are done inline. */ + print_file (file, 2, "0x%x,\t/* Corr desc: parameter */\n", + RPC_FC_TOP_LEVEL_CONFORMANCE); + print_file (file, 2, "0x0,\n"); + print_file (file, 2, "NdrFcShort(0x0),\n"); + return 4; + } if (expr->is_const) { @@ -327,6 +608,13 @@ static size_t write_conf_or_var_desc(FILE *file, const func_t *func, const type_ return 4; } + if (is_ptr(type) || (is_array(type) && !type->declarray)) + { + conftype = RPC_FC_POINTER_CONFORMANCE; + conftype_string = "field pointer, "; + } + + subexpr = expr; switch (subexpr->type) { case EXPR_PPTR: @@ -373,183 +661,206 @@ static size_t write_conf_or_var_desc(FILE *file, const func_t *func, const type_ if (subexpr->type == EXPR_IDENTIFIER) { const type_t *correlation_variable = NULL; + unsigned char correlation_variable_type; unsigned char param_type = 0; - const char *param_type_string = NULL; - size_t offset; + size_t offset = 0; + const var_t *var; - if (structure) + if (structure->fields) LIST_FOR_EACH_ENTRY( var, structure->fields, const var_t, entry ) { - const var_t *var; - - for (offset = 0, var = structure->fields; var; var = NEXT_LINK(var)) + unsigned int align = 0; + /* FIXME: take alignment into account */ + if (var->name && !strcmp(var->name, subexpr->u.sval)) { - offset -= type_memsize(var->type, var->ptr_level, var->array); - if (!strcmp(var->name, subexpr->u.sval)) - { - correlation_variable = var->type; - break; - } + correlation_variable = var->type; + break; } - if (!correlation_variable) - error("write_conf_or_var_desc: couldn't find variable %s in structure\n", - subexpr->u.sval); - - correlation_type = RPC_FC_NORMAL_CONFORMANCE; + offset += type_memsize(var->type, &align); } - else - { - const var_t *var = func->args; + if (!correlation_variable) + error("write_conf_or_var_desc: couldn't find variable %s in structure\n", + subexpr->u.sval); - while (NEXT_LINK(var)) var = NEXT_LINK(var); - /* FIXME: not all stack variables are sizeof(void *) */ - for (offset = 0; var; offset += sizeof(void *), var = PREV_LINK(var)) - { - if (!strcmp(var->name, subexpr->u.sval)) - { - correlation_variable = var->type; - break; - } - } - if (!correlation_variable) - error("write_conf_or_var_desc: couldn't find variable %s in function\n", - subexpr->u.sval); + offset -= baseoff; + correlation_variable_type = correlation_variable->type; - correlation_type = RPC_FC_TOP_LEVEL_CONFORMANCE; - } - - while (type_has_ref(correlation_variable)) - correlation_variable = correlation_variable->ref; - - switch (correlation_variable->type) + switch (correlation_variable_type) { case RPC_FC_CHAR: case RPC_FC_SMALL: param_type = RPC_FC_SMALL; - param_type_string = "FC_SMALL"; break; case RPC_FC_BYTE: case RPC_FC_USMALL: param_type = RPC_FC_USMALL; - param_type_string = "FC_USMALL"; break; case RPC_FC_WCHAR: case RPC_FC_SHORT: + case RPC_FC_ENUM16: param_type = RPC_FC_SHORT; - param_type_string = "FC_SHORT"; break; case RPC_FC_USHORT: param_type = RPC_FC_USHORT; - param_type_string = "FC_USHORT"; break; case RPC_FC_LONG: + case RPC_FC_ENUM32: param_type = RPC_FC_LONG; - param_type_string = "FC_LONG"; break; case RPC_FC_ULONG: param_type = RPC_FC_ULONG; - param_type_string = "FC_ULONG"; + break; + case RPC_FC_RP: + case RPC_FC_UP: + case RPC_FC_OP: + case RPC_FC_FP: + if (sizeof(void *) == 4) /* FIXME */ + param_type = RPC_FC_LONG; + else + param_type = RPC_FC_HYPER; break; default: error("write_conf_or_var_desc: conformance variable type not supported 0x%x\n", - correlation_variable->type); + correlation_variable_type); } print_file(file, 2, "0x%x, /* Corr desc: %s%s */\n", - correlation_type | param_type, - correlation_type == RPC_FC_TOP_LEVEL_CONFORMANCE ? "parameter, " : "", - param_type_string); + conftype | param_type, conftype_string, string_of_type(param_type)); print_file(file, 2, "0x%x, /* %s */\n", operator_type, operator_string); - print_file(file, 2, "NdrFcShort(0x%x), /* %soffset = %d */\n", - offset, - correlation_type == RPC_FC_TOP_LEVEL_CONFORMANCE ? "x86 stack size / " : "", - offset); + print_file(file, 2, "NdrFcShort(0x%x), /* offset = %d */\n", + offset, offset); } else { unsigned int callback_offset = 0; + struct expr_eval_routine *eval; + int found = 0; - if (structure) + LIST_FOR_EACH_ENTRY(eval, &expr_eval_routines, struct expr_eval_routine, entry) { - struct expr_eval_routine *eval; - int found = 0; - - LIST_FOR_EACH_ENTRY(eval, &expr_eval_routines, struct expr_eval_routine, entry) + if (!strcmp (eval->structure->name, structure->name) + && !compare_expr (eval->expr, expr)) { - if (!strcmp(eval->structure->name, structure->name) && - !compare_expr(eval->expr, expr)) - { - found = 1; - break; - } - callback_offset++; + found = 1; + break; } - - if (!found) - { - eval = xmalloc(sizeof(*eval)); - eval->structure = structure; - eval->structure_size = fields_memsize(structure->fields); - eval->expr = expr; - list_add_tail(&expr_eval_routines, &eval->entry); - } - - correlation_type = RPC_FC_NORMAL_CONFORMANCE; + callback_offset++; } - else + + if (!found) { - error("write_conf_or_var_desc: top-level callback conformance unimplemented\n"); - correlation_type = RPC_FC_TOP_LEVEL_CONFORMANCE; + eval = xmalloc (sizeof(*eval)); + eval->structure = structure; + eval->baseoff = baseoff; + eval->expr = expr; + list_add_tail (&expr_eval_routines, &eval->entry); } if (callback_offset > USHRT_MAX) error("Maximum number of callback routines reached\n"); - print_file(file, 2, "0x%x, /* Corr desc: %s */\n", - correlation_type, - correlation_type == RPC_FC_TOP_LEVEL_CONFORMANCE ? "parameter" : ""); + print_file(file, 2, "0x%x, /* Corr desc: %s */\n", conftype, conftype_string); print_file(file, 2, "0x%x, /* %s */\n", RPC_FC_CALLBACK, "FC_CALLBACK"); print_file(file, 2, "NdrFcShort(0x%x), /* %u */\n", callback_offset, callback_offset); } return 4; } -static size_t fields_memsize(const var_t *v) +static size_t fields_memsize(const var_list_t *fields, unsigned int *align) { + int have_align = FALSE; size_t size = 0; - const var_t *first = v; - if (!v) return 0; - while (NEXT_LINK(v)) v = NEXT_LINK(v); - while (v) { - size += type_memsize(v->type, v->ptr_level, v->array); - if (v == first) break; - v = PREV_LINK(v); + const var_t *v; + + if (!fields) return 0; + LIST_FOR_EACH_ENTRY( v, fields, const var_t, entry ) + { + unsigned int falign = 0; + size_t fsize = type_memsize(v->type, &falign); + if (!have_align) + { + *align = falign; + have_align = TRUE; + } + size = (size + (falign - 1)) & ~(falign - 1); + size += fsize; } + + size = (size + (*align - 1)) & ~(*align - 1); return size; } -static size_t type_memsize(const type_t *t, int ptr_level, const expr_t *array) +static size_t union_memsize(const var_list_t *fields, unsigned int *pmaxa) +{ + size_t size, maxs = 0; + unsigned int align = *pmaxa; + const var_t *v; + + if (fields) LIST_FOR_EACH_ENTRY( v, fields, const var_t, entry ) + { + /* we could have an empty default field with NULL type */ + if (v->type) + { + size = type_memsize(v->type, &align); + if (maxs < size) maxs = size; + if (*pmaxa < align) *pmaxa = align; + } + } + + return maxs; +} + +int get_padding(const var_list_t *fields) +{ + unsigned short offset = 0; + int salign = -1; + const var_t *f; + + if (!fields) + return 0; + + LIST_FOR_EACH_ENTRY(f, fields, const var_t, entry) + { + type_t *ft = f->type; + unsigned int align = 0; + size_t size = type_memsize(ft, &align); + if (salign == -1) + salign = align; + offset = (offset + (align - 1)) & ~(align - 1); + offset += size; + } + + return ((offset + (salign - 1)) & ~(salign - 1)) - offset; +} + +size_t type_memsize(const type_t *t, unsigned int *align) { size_t size = 0; - if (ptr_level) - return sizeof(void *); - - if (type_has_ref(t)) - return type_memsize(t->ref, 0 /* FIXME */, NULL); - - switch (t->type) + if (t->declarray && is_conformant_array(t)) + { + type_memsize(t->ref, align); + size = 0; + } + else if (is_ptr(t) || is_conformant_array(t)) + { + size = sizeof(void *); + if (size > *align) *align = size; + } + else switch (t->type) { case RPC_FC_BYTE: case RPC_FC_CHAR: case RPC_FC_USMALL: case RPC_FC_SMALL: size = 1; + if (size > *align) *align = size; break; case RPC_FC_WCHAR: case RPC_FC_USHORT: case RPC_FC_SHORT: case RPC_FC_ENUM16: size = 2; + if (size > *align) *align = size; break; case RPC_FC_ULONG: case RPC_FC_LONG: @@ -557,10 +868,12 @@ static size_t type_memsize(const type_t *t, int ptr_level, const expr_t *array) case RPC_FC_ENUM32: case RPC_FC_FLOAT: size = 4; + if (size > *align) *align = size; break; case RPC_FC_HYPER: case RPC_FC_DOUBLE: size = 8; + if (size > *align) *align = size; break; case RPC_FC_STRUCT: case RPC_FC_CVSTRUCT: @@ -568,211 +881,672 @@ static size_t type_memsize(const type_t *t, int ptr_level, const expr_t *array) case RPC_FC_CSTRUCT: case RPC_FC_PSTRUCT: case RPC_FC_BOGUS_STRUCT: + size = fields_memsize(t->fields, align); + break; case RPC_FC_ENCAPSULATED_UNION: case RPC_FC_NON_ENCAPSULATED_UNION: - size = fields_memsize(t->fields); + size = union_memsize(t->fields, align); + break; + case RPC_FC_SMFARRAY: + case RPC_FC_LGFARRAY: + case RPC_FC_SMVARRAY: + case RPC_FC_LGVARRAY: + case RPC_FC_BOGUS_ARRAY: + size = t->dim * type_memsize(t->ref, align); break; default: error("type_memsize: Unknown type %d\n", t->type); size = 0; } - if (array) - { - if (array->is_const) - size *= array->cval; - else - size = 0; - } - return size; } -size_t get_type_memsize(const type_t *type) +static unsigned int write_nonsimple_pointer(FILE *file, const type_t *type, size_t offset) { - return type_memsize(type, 0, NULL); + short absoff = type->ref->typestring_offset; + short reloff = absoff - (offset + 2); + int ptr_attr = is_ptr(type->ref) ? 0x10 : 0x0; + + print_file(file, 2, "0x%02x, 0x%x,\t/* %s */\n", + type->type, ptr_attr, string_of_type(type->type)); + print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%hd) */\n", + reloff, reloff, absoff); + return 4; } -static int write_pointers(FILE *file, const attr_t *attrs, - const type_t *type, int ptr_level, - const expr_t *array, int level, - unsigned int *typestring_offset) +static unsigned char conf_string_type_of_char_type(unsigned char t) { - int pointers_written = 0; - const var_t *v; - - /* don't generate a pointer for first-level arrays since we want to - * descend into them to write their pointers, not stop here */ - if ((level == 0 || ptr_level == 0) && is_array_type(attrs, ptr_level, array)) + switch (t) { - return write_pointers(file, NULL, type, 0, NULL, level + 1, typestring_offset); + case RPC_FC_BYTE: + case RPC_FC_CHAR: + return RPC_FC_C_CSTRING; + case RPC_FC_WCHAR: + return RPC_FC_C_WSTRING; } - if (ptr_level != 0) + error("string_type_of_char_type: unrecognized type %d\n", t); + return 0; +} + +static unsigned int write_simple_pointer(FILE *file, const type_t *type) +{ + unsigned char fc + = is_string_type(type->attrs, type) + ? conf_string_type_of_char_type(type->ref->type) + : type->ref->type; + print_file(file, 2, "0x%02x, 0x8,\t/* %s [simple_pointer] */\n", + type->type, string_of_type(type->type)); + print_file(file, 2, "0x%02x,\t/* %s */\n", fc, string_of_type(fc)); + print_file(file, 2, "0x5c,\t/* FC_PAD */\n"); + return 4; +} + +static void print_start_tfs_comment(FILE *file, type_t *t, unsigned int tfsoff) +{ + print_file(file, 0, "/* %u (", tfsoff); + write_type_decl(file, t, NULL); + print_file(file, 0, ") */\n"); +} + +static size_t write_pointer_tfs(FILE *file, type_t *type, unsigned int *typestring_offset) +{ + unsigned int offset = *typestring_offset; + + print_start_tfs_comment(file, type, offset); + update_tfsoff(type, offset, file); + + if (type->ref->typestring_offset) + *typestring_offset += write_nonsimple_pointer(file, type, offset); + else if (is_base_type(type->ref->type)) + *typestring_offset += write_simple_pointer(file, type); + + return offset; +} + +static int processed(const type_t *type) +{ + return type->typestring_offset && !type->tfswrite; +} + +static int user_type_has_variable_size(const type_t *t) +{ + if (is_ptr(t)) + return TRUE; + else + switch (t->type) + { + case RPC_FC_PSTRUCT: + case RPC_FC_CSTRUCT: + case RPC_FC_CPSTRUCT: + case RPC_FC_CVSTRUCT: + return TRUE; + } + /* Note: Since this only applies to user types, we can't have a conformant + array here, and strings should get filed under pointer in this case. */ + return FALSE; +} + +static void write_user_tfs(FILE *file, type_t *type, unsigned int *tfsoff) +{ + unsigned int start, absoff, flags; + unsigned int align = 0, ualign = 0; + const char *name; + type_t *utype = get_user_type(type, &name); + size_t usize = user_type_has_variable_size(utype) ? 0 : type_memsize(utype, &ualign); + size_t size = type_memsize(type, &align); + unsigned short funoff = user_type_offset(name); + short reloff; + + guard_rec(type); + + if (is_base_type(utype->type)) { - /* FIXME: only general algorithm implemented, not the actual writing */ - error("write_pointers: Writing type format string for pointer is unimplemented\n"); + absoff = *tfsoff; + print_start_tfs_comment(file, utype, absoff); + print_file(file, 2, "0x%x,\t/* %s */\n", utype->type, string_of_type(utype->type)); + print_file(file, 2, "0x5c,\t/* FC_PAD */\n"); + *tfsoff += 2; + } + else + { + if (!processed(utype)) + write_embedded_types(file, NULL, utype, utype->name, TRUE, tfsoff); + absoff = utype->typestring_offset; + } + + if (utype->type == RPC_FC_RP) + flags = 0x40; + else if (utype->type == RPC_FC_UP) + flags = 0x80; + else + flags = 0; + + start = *tfsoff; + update_tfsoff(type, start, file); + print_start_tfs_comment(file, type, start); + print_file(file, 2, "0x%x,\t/* FC_USER_MARSHAL */\n", RPC_FC_USER_MARSHAL); + print_file(file, 2, "0x%x,\t/* Alignment= %d, Flags= %02x */\n", + flags | (align - 1), align - 1, flags); + print_file(file, 2, "NdrFcShort(0x%hx),\t/* Function offset= %hu */\n", funoff, funoff); + print_file(file, 2, "NdrFcShort(0x%lx),\t/* %lu */\n", size, size); + print_file(file, 2, "NdrFcShort(0x%lx),\t/* %lu */\n", usize, usize); + *tfsoff += 8; + reloff = absoff - *tfsoff; + print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%lu) */\n", reloff, reloff, absoff); + *tfsoff += 2; +} + +static void write_member_type(FILE *file, const type_t *cont, + const attr_list_t *attrs, const type_t *type, + unsigned int *corroff, unsigned int *tfsoff) +{ + if (is_embedded_complex(type) && !is_conformant_array(type)) + { + size_t absoff; + short reloff; + + if (is_union(type->type) && is_attr(attrs, ATTR_SWITCHIS)) + { + absoff = *corroff; + *corroff += 8; + } + else + { + absoff = type->typestring_offset; + } + reloff = absoff - (*tfsoff + 2); + + print_file(file, 2, "0x4c,\t/* FC_EMBEDDED_COMPLEX */\n"); + /* FIXME: actually compute necessary padding */ + print_file(file, 2, "0x0,\t/* FIXME: padding */\n"); + print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%lu) */\n", + reloff, reloff, absoff); + *tfsoff += 4; + } + else if (is_ptr(type) || is_conformant_array(type)) + { + unsigned char fc = (cont->type == RPC_FC_BOGUS_STRUCT + ? RPC_FC_POINTER + : RPC_FC_LONG); + print_file(file, 2, "0x%x,\t/* %s */\n", fc, string_of_type(fc)); + *tfsoff += 1; + } + else if (!write_base_type(file, type, tfsoff)) + error("Unsupported member type 0x%x\n", type->type); +} + +static void write_end(FILE *file, unsigned int *tfsoff) +{ + if (*tfsoff % 2 == 0) + { + print_file(file, 2, "0x%x,\t\t/* FC_PAD */\n", RPC_FC_PAD); + *tfsoff += 1; + } + print_file(file, 2, "0x%x,\t\t/* FC_END */\n", RPC_FC_END); + *tfsoff += 1; +} + +static void write_descriptors(FILE *file, type_t *type, unsigned int *tfsoff) +{ + unsigned int offset = 0; + var_list_t *fs = type->fields; + var_t *f; + + if (fs) LIST_FOR_EACH_ENTRY(f, fs, var_t, entry) + { + unsigned int align = 0; + type_t *ft = f->type; + if (is_union(ft->type) && is_attr(f->attrs, ATTR_SWITCHIS)) + { + unsigned int absoff = ft->typestring_offset; + short reloff = absoff - (*tfsoff + 6); + print_file(file, 0, "/* %d */\n", *tfsoff); + print_file(file, 2, "0x%x,\t/* %s */\n", ft->type, string_of_type(ft->type)); + print_file(file, 2, "0x%x,\t/* FIXME: always FC_LONG */\n", RPC_FC_LONG); + write_conf_or_var_desc(file, current_structure, offset, ft, + get_attrp(f->attrs, ATTR_SWITCHIS)); + print_file(file, 2, "NdrFcShort(%hd),\t/* Offset= %hd (%u) */\n", + reloff, reloff, absoff); + *tfsoff += 8; + } + + /* FIXME: take alignment into account */ + offset += type_memsize(ft, &align); + } +} + +static int write_no_repeat_pointer_descriptions( + FILE *file, type_t *type, + size_t *offset_in_memory, size_t *offset_in_buffer, + unsigned int *typestring_offset) +{ + int written = 0; + unsigned int align; + + if (is_ptr(type) || (!type->declarray && is_conformant_array(type))) + { + print_file(file, 2, "0x%02x, /* FC_NO_REPEAT */\n", RPC_FC_NO_REPEAT); + print_file(file, 2, "0x%02x, /* FC_PAD */\n", RPC_FC_PAD); + + /* pointer instance */ + print_file(file, 2, "NdrFcShort(0x%x), /* Memory offset = %d */\n", *offset_in_memory, *offset_in_memory); + print_file(file, 2, "NdrFcShort(0x%x), /* Buffer offset = %d */\n", *offset_in_buffer, *offset_in_buffer); + *typestring_offset += 6; + + if (is_ptr(type)) + write_pointer_tfs(file, type, typestring_offset); + else + { + unsigned absoff = type->typestring_offset; + short reloff = absoff - (*typestring_offset + 2); + /* FIXME: get pointer attributes from field */ + print_file(file, 2, "0x%02x, 0x0,\t/* %s */\n", RPC_FC_UP, "FC_UP"); + print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%u) */\n", + reloff, reloff, absoff); + *typestring_offset += 4; + } + + align = 0; + *offset_in_memory += type_memsize(type, &align); + /* FIXME: is there a case where these two are different? */ + align = 0; + *offset_in_buffer += type_memsize(type, &align); + return 1; } - /* FIXME: search through all refs for pointers too */ - while(type_has_ref(type)) - type = type->ref; - - switch (type->type) + if (is_non_complex_struct(type)) { - /* note: don't descend into complex structures or unions since these - * will always be generated as a separate type */ - case RPC_FC_STRUCT: - case RPC_FC_CVSTRUCT: - case RPC_FC_CPSTRUCT: - case RPC_FC_CSTRUCT: - case RPC_FC_PSTRUCT: - v = type->fields; - if (!v) break; - while (NEXT_LINK(v)) v = NEXT_LINK(v); - for (; v; v = PREV_LINK(v)) - pointers_written += write_pointers(file, v->attrs, v->type, - v->ptr_level, v->array, - level + 1, - typestring_offset); - - break; - - default: - /* nothing to do */ - break; + const var_t *v; + LIST_FOR_EACH_ENTRY( v, type->fields, const var_t, entry ) + written += write_no_repeat_pointer_descriptions( + file, v->type, + offset_in_memory, offset_in_buffer, typestring_offset); + } + else + { + align = 0; + *offset_in_memory += type_memsize(type, &align); + /* FIXME: is there a case where these two are different? */ + align = 0; + *offset_in_buffer += type_memsize(type, &align); } - return pointers_written; + return written; } -static size_t write_pointer_description(FILE *file, const attr_t *attrs, - const type_t *type, int ptr_level, - const expr_t *array, int level, - size_t typestring_offset) +static int write_pointer_description_offsets( + FILE *file, const attr_list_t *attrs, type_t *type, + size_t *offset_in_memory, size_t *offset_in_buffer, + unsigned int *typestring_offset) { - size_t size = 0; - const var_t *v; + int written = 0; + unsigned int align; - /* don't generate a pointer for first-level arrays since we want to - * descend into them to write their pointers, not stop here */ - if ((level == 0 || ptr_level == 0) && is_array_type(attrs, ptr_level, array)) + if (is_ptr(type) && type->ref->type != RPC_FC_IP) { - return write_pointer_description(file, NULL, type, 0, NULL, - level + 1, typestring_offset); + if (offset_in_memory && offset_in_buffer) + { + /* pointer instance */ + /* FIXME: sometimes from end of structure, sometimes from beginning */ + print_file(file, 2, "NdrFcShort(0x%x), /* Memory offset = %d */\n", *offset_in_memory, *offset_in_memory); + print_file(file, 2, "NdrFcShort(0x%x), /* Buffer offset = %d */\n", *offset_in_buffer, *offset_in_buffer); + + align = 0; + *offset_in_memory += type_memsize(type, &align); + /* FIXME: is there a case where these two are different? */ + align = 0; + *offset_in_buffer += type_memsize(type, &align); + } + *typestring_offset += 4; + + if (processed(type->ref) || is_base_type(type->ref->type)) + write_pointer_tfs(file, type, typestring_offset); + else + error("write_pointer_description_offsets: type format string unknown\n"); + + return 1; } - if (ptr_level != 0) + if (is_array(type)) { - /* FIXME: only general algorithm implemented, not the actual writing */ - error("write_pointer_description: Writing pointer description is unimplemented\n"); - return 0; + return write_pointer_description_offsets( + file, attrs, type->ref, offset_in_memory, offset_in_buffer, + typestring_offset); + } + else if (is_non_complex_struct(type)) + { + /* otherwise search for interesting fields to parse */ + const var_t *v; + LIST_FOR_EACH_ENTRY( v, type->fields, const var_t, entry ) + { + written += write_pointer_description_offsets( + file, v->attrs, v->type, offset_in_memory, offset_in_buffer, + typestring_offset); + } + } + else + { + align = 0; + if (offset_in_memory) + *offset_in_memory += type_memsize(type, &align); + /* FIXME: is there a case where these two are different? */ + align = 0; + if (offset_in_buffer) + *offset_in_buffer += type_memsize(type, &align); } - /* FIXME: search through all refs for pointers too */ - - switch (type->type) - { - /* note: don't descend into complex structures or unions since these - * will always be generated as a separate type */ - case RPC_FC_STRUCT: - case RPC_FC_CVSTRUCT: - case RPC_FC_CPSTRUCT: - case RPC_FC_CSTRUCT: - case RPC_FC_PSTRUCT: - v = type->fields; - if (!v) break; - while (NEXT_LINK(v)) v = NEXT_LINK(v); - for (; v; v = PREV_LINK(v)) - size += write_pointer_description(file, v->attrs, v->type, - v->ptr_level, v->array, - level + 1, - typestring_offset); - - break; - - default: - /* nothing to do */ - break; - } - - return size; + return written; } -static size_t write_string_tfs(FILE *file, const attr_t *attrs, - const type_t *type, const expr_t *array, - const char *name, unsigned int *typestring_offset) +/* Note: if file is NULL return value is number of pointers to write, else + * it is the number of type format characters written */ +static int write_fixed_array_pointer_descriptions( + FILE *file, const attr_list_t *attrs, type_t *type, + size_t *offset_in_memory, size_t *offset_in_buffer, + unsigned int *typestring_offset) +{ + unsigned int align; + int pointer_count = 0; + + if (type->type == RPC_FC_SMFARRAY || type->type == RPC_FC_LGFARRAY) + { + unsigned int temp = 0; + /* unfortunately, this needs to be done in two passes to avoid + * writing out redundant FC_FIXED_REPEAT descriptions */ + pointer_count = write_pointer_description_offsets( + NULL, attrs, type->ref, NULL, NULL, &temp); + if (pointer_count > 0) + { + unsigned int increment_size; + size_t offset_of_array_pointer_mem = 0; + size_t offset_of_array_pointer_buf = 0; + + align = 0; + increment_size = type_memsize(type->ref, &align); + + print_file(file, 2, "0x%02x, /* FC_FIXED_REPEAT */\n", RPC_FC_FIXED_REPEAT); + print_file(file, 2, "0x%02x, /* FC_PAD */\n", RPC_FC_PAD); + print_file(file, 2, "NdrFcShort(0x%x), /* Iterations = %d */\n", type->dim, type->dim); + print_file(file, 2, "NdrFcShort(0x%x), /* Increment = %d */\n", increment_size, increment_size); + print_file(file, 2, "NdrFcShort(0x%x), /* Offset to array = %d */\n", *offset_in_memory, *offset_in_memory); + print_file(file, 2, "NdrFcShort(0x%x), /* Number of pointers = %d */\n", pointer_count, pointer_count); + *typestring_offset += 10; + + pointer_count = write_pointer_description_offsets( + file, attrs, type, &offset_of_array_pointer_mem, + &offset_of_array_pointer_buf, typestring_offset); + } + } + else if (is_struct(type->type)) + { + const var_t *v; + LIST_FOR_EACH_ENTRY( v, type->fields, const var_t, entry ) + { + pointer_count += write_fixed_array_pointer_descriptions( + file, v->attrs, v->type, offset_in_memory, offset_in_buffer, + typestring_offset); + } + } + else + { + align = 0; + if (offset_in_memory) + *offset_in_memory += type_memsize(type, &align); + /* FIXME: is there a case where these two are different? */ + align = 0; + if (offset_in_buffer) + *offset_in_buffer += type_memsize(type, &align); + } + + return pointer_count; +} + +/* Note: if file is NULL return value is number of pointers to write, else + * it is the number of type format characters written */ +static int write_conformant_array_pointer_descriptions( + FILE *file, const attr_list_t *attrs, type_t *type, + size_t offset_in_memory, unsigned int *typestring_offset) +{ + unsigned int align; + int pointer_count = 0; + + if (is_conformant_array(type) && !type->length_is) + { + unsigned int temp = 0; + /* unfortunately, this needs to be done in two passes to avoid + * writing out redundant FC_VARIABLE_REPEAT descriptions */ + pointer_count = write_pointer_description_offsets( + NULL, attrs, type->ref, NULL, NULL, &temp); + if (pointer_count > 0) + { + unsigned int increment_size; + size_t offset_of_array_pointer_mem = offset_in_memory; + size_t offset_of_array_pointer_buf = offset_in_memory; + + align = 0; + increment_size = type_memsize(type->ref, &align); + + if (increment_size > USHRT_MAX) + error("array size of %u bytes is too large\n", increment_size); + + print_file(file, 2, "0x%02x, /* FC_VARIABLE_REPEAT */\n", RPC_FC_VARIABLE_REPEAT); + print_file(file, 2, "0x%02x, /* FC_FIXED_OFFSET */\n", RPC_FC_FIXED_OFFSET); + print_file(file, 2, "NdrFcShort(0x%x), /* Increment = %d */\n", increment_size, increment_size); + print_file(file, 2, "NdrFcShort(0x%x), /* Offset to array = %d */\n", offset_in_memory, offset_in_memory); + print_file(file, 2, "NdrFcShort(0x%x), /* Number of pointers = %d */\n", pointer_count, pointer_count); + *typestring_offset += 8; + + pointer_count = write_pointer_description_offsets( + file, attrs, type->ref, &offset_of_array_pointer_mem, + &offset_of_array_pointer_buf, typestring_offset); + } + } + + return pointer_count; +} + +/* Note: if file is NULL return value is number of pointers to write, else + * it is the number of type format characters written */ +static int write_varying_array_pointer_descriptions( + FILE *file, const attr_list_t *attrs, type_t *type, + size_t *offset_in_memory, size_t *offset_in_buffer, + unsigned int *typestring_offset) +{ + unsigned int align; + int pointer_count = 0; + + /* FIXME: do varying array searching here, but pointer searching in write_pointer_description_offsets */ + + if (is_array(type) && type->length_is) + { + unsigned int temp = 0; + /* unfortunately, this needs to be done in two passes to avoid + * writing out redundant FC_VARIABLE_REPEAT descriptions */ + pointer_count = write_pointer_description_offsets( + NULL, attrs, type->ref, NULL, NULL, &temp); + if (pointer_count > 0) + { + unsigned int increment_size; + size_t offset_of_array_pointer_mem = 0; + size_t offset_of_array_pointer_buf = 0; + + align = 0; + increment_size = type_memsize(type->ref, &align); + + if (increment_size > USHRT_MAX) + error("array size of %u bytes is too large\n", increment_size); + + print_file(file, 2, "0x%02x, /* FC_VARIABLE_REPEAT */\n", RPC_FC_VARIABLE_REPEAT); + print_file(file, 2, "0x%02x, /* FC_VARIABLE_OFFSET */\n", RPC_FC_VARIABLE_OFFSET); + print_file(file, 2, "NdrFcShort(0x%x), /* Increment = %d */\n", increment_size, increment_size); + print_file(file, 2, "NdrFcShort(0x%x), /* Offset to array = %d */\n", *offset_in_memory, *offset_in_memory); + print_file(file, 2, "NdrFcShort(0x%x), /* Number of pointers = %d */\n", pointer_count, pointer_count); + *typestring_offset += 8; + + pointer_count = write_pointer_description_offsets( + file, attrs, type, &offset_of_array_pointer_mem, + &offset_of_array_pointer_buf, typestring_offset); + } + } + else if (is_struct(type->type)) + { + const var_t *v; + LIST_FOR_EACH_ENTRY( v, type->fields, const var_t, entry ) + { + pointer_count += write_varying_array_pointer_descriptions( + file, v->attrs, v->type, offset_in_memory, offset_in_buffer, + typestring_offset); + } + } + else + { + align = 0; + if (offset_in_memory) + *offset_in_memory += type_memsize(type, &align); + /* FIXME: is there a case where these two are different? */ + align = 0; + if (offset_in_buffer) + *offset_in_buffer += type_memsize(type, &align); + } + + return pointer_count; +} + +static void write_pointer_description(FILE *file, type_t *type, + unsigned int *typestring_offset) +{ + size_t offset_in_buffer; + size_t offset_in_memory; + + /* pass 1: search for single instance of a pointer (i.e. don't descend + * into arrays) */ + if (!is_array(type)) + { + offset_in_memory = 0; + offset_in_buffer = 0; + write_no_repeat_pointer_descriptions( + file, type, + &offset_in_memory, &offset_in_buffer, typestring_offset); + } + + /* pass 2: search for pointers in fixed arrays */ + offset_in_memory = 0; + offset_in_buffer = 0; + write_fixed_array_pointer_descriptions( + file, NULL, type, + &offset_in_memory, &offset_in_buffer, typestring_offset); + + /* pass 3: search for pointers in conformant only arrays (but don't descend + * into conformant varying or varying arrays) */ + if ((!type->declarray || !current_structure) && is_conformant_array(type)) + write_conformant_array_pointer_descriptions( + file, NULL, type, 0, typestring_offset); + else if (type->type == RPC_FC_CPSTRUCT) + { + unsigned int align = 0; + type_t *carray = find_array_or_string_in_struct(type)->type; + write_conformant_array_pointer_descriptions( + file, NULL, carray, + type_memsize(type, &align), + typestring_offset); + } + + /* pass 4: search for pointers in varying arrays */ + offset_in_memory = 0; + offset_in_buffer = 0; + write_varying_array_pointer_descriptions( + file, NULL, type, + &offset_in_memory, &offset_in_buffer, typestring_offset); +} + +int is_declptr(const type_t *t) +{ + return is_ptr(t) || (is_conformant_array(t) && !t->declarray); +} + +static size_t write_string_tfs(FILE *file, const attr_list_t *attrs, + type_t *type, + const char *name, unsigned int *typestring_offset, + int toplevel) { - const expr_t *size_is = get_attrp(attrs, ATTR_SIZEIS); - int has_size = size_is && (size_is->type != EXPR_VOID); size_t start_offset = *typestring_offset; - unsigned char flags = 0; - int pointer_type = get_attrv(attrs, ATTR_POINTERTYPE); - if (!pointer_type) - pointer_type = RPC_FC_RP; + unsigned char rtype; - if (!get_attrp(attrs, ATTR_SIZEIS)) - flags |= RPC_FC_P_SIMPLEPOINTER; + update_tfsoff(type, start_offset, file); - while (type_has_ref(type)) - type = type->ref; - - if ((type->type != RPC_FC_BYTE) && (type->type != RPC_FC_CHAR) && (type->type != RPC_FC_WCHAR)) + if (toplevel && is_declptr(type)) { - error("write_string_tfs: Unimplemented for type 0x%x of name: %s\n", type->type, name); + unsigned char flag = is_conformant_array(type) ? 0 : RPC_FC_P_SIMPLEPOINTER; + int pointer_type = is_ptr(type) ? type->type : get_attrv(attrs, ATTR_POINTERTYPE); + if (!pointer_type) + pointer_type = RPC_FC_RP; + print_file(file, 2,"0x%x, 0x%x,\t/* %s%s */\n", + pointer_type, flag, string_of_type(pointer_type), + flag ? " [simple_pointer]" : ""); + *typestring_offset += 2; + if (!flag) + { + print_file(file, 2, "NdrFcShort(0x2),\n"); + *typestring_offset += 2; + } + } + + rtype = type->ref->type; + + if ((rtype != RPC_FC_BYTE) && (rtype != RPC_FC_CHAR) && (rtype != RPC_FC_WCHAR)) + { + error("write_string_tfs: Unimplemented for type 0x%x of name: %s\n", rtype, name); return start_offset; } - print_file(file, 2,"0x%x, 0x%x, /* %s%s */\n", - pointer_type, flags, - pointer_type == RPC_FC_FP ? "FC_FP" : (pointer_type == RPC_FC_UP ? "FC_UP" : "FC_RP"), - (flags & RPC_FC_P_SIMPLEPOINTER) ? " [simple_pointer]" : ""); - *typestring_offset += 2; - - if (!(flags & RPC_FC_P_SIMPLEPOINTER)) + if (type->declarray && !is_conformant_array(type)) { - print_file(file, 2, "NdrFcShort(0x2),\n"); - *typestring_offset += 2; - } + /* FIXME: multi-dimensional array */ + if (0xffffuL < type->dim) + error("array size for parameter %s exceeds %u bytes by %lu bytes\n", + name, 0xffffu, type->dim - 0xffffu); - if (array && array->is_const) - { - if (array->cval > USHRT_MAX) - error("array size for parameter %s exceeds %d bytes by %ld bytes\n", - name, USHRT_MAX, array->cval - USHRT_MAX); - - if (type->type == RPC_FC_CHAR) + if (rtype == RPC_FC_CHAR) WRITE_FCTYPE(file, FC_CSTRING, *typestring_offset); else WRITE_FCTYPE(file, FC_WSTRING, *typestring_offset); print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD); *typestring_offset += 2; - print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", array->cval, array->cval); + print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", type->dim, type->dim); *typestring_offset += 2; return start_offset; } - else if (has_size) + else if (type->size_is) { - if (type->type == RPC_FC_CHAR) + unsigned int align = 0; + + if (rtype == RPC_FC_CHAR) WRITE_FCTYPE(file, FC_C_CSTRING, *typestring_offset); else WRITE_FCTYPE(file, FC_C_WSTRING, *typestring_offset); print_file(file, 2, "0x%x, /* FC_STRING_SIZED */\n", RPC_FC_STRING_SIZED); *typestring_offset += 2; - *typestring_offset += write_conf_or_var_desc(file, current_func, NULL, size_is); + *typestring_offset += write_conf_or_var_desc( + file, current_structure, + (type->declarray && current_structure + ? type_memsize(current_structure, &align) + : 0), + type, type->size_is); return start_offset; } else { - if (type->type == RPC_FC_CHAR) - WRITE_FCTYPE(file, FC_C_CSTRING, *typestring_offset); - else + if (rtype == RPC_FC_WCHAR) WRITE_FCTYPE(file, FC_C_WSTRING, *typestring_offset); + else + WRITE_FCTYPE(file, FC_C_CSTRING, *typestring_offset); print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD); *typestring_offset += 2; @@ -780,442 +1554,309 @@ static size_t write_string_tfs(FILE *file, const attr_t *attrs, } } -static size_t write_array_tfs(FILE *file, const attr_t *attrs, - const type_t *type, const expr_t *array, +static size_t write_array_tfs(FILE *file, const attr_list_t *attrs, type_t *type, const char *name, unsigned int *typestring_offset) { - const expr_t *length_is = get_attrp(attrs, ATTR_LENGTHIS); - const expr_t *size_is = get_attrp(attrs, ATTR_SIZEIS); - int has_length = length_is && (length_is->type != EXPR_VOID); - int has_size = (size_is && (size_is->type != EXPR_VOID)) || !array->is_const; + const expr_t *length_is = type->length_is; + const expr_t *size_is = type->size_is; + unsigned int align = 0; + size_t size; size_t start_offset; + int has_pointer; int pointer_type = get_attrv(attrs, ATTR_POINTERTYPE); + unsigned int baseoff + = type->declarray && current_structure + ? type_memsize(current_structure, &align) + : 0; + if (!pointer_type) pointer_type = RPC_FC_RP; - print_file(file, 2, "0x%x, 0x00, /* %s */\n", - pointer_type, - pointer_type == RPC_FC_FP ? "FC_FP" : (pointer_type == RPC_FC_UP ? "FC_UP" : "FC_RP")); - print_file(file, 2, "NdrFcShort(0x2),\n"); - *typestring_offset += 4; - - if (array && NEXT_LINK(array)) /* multi-dimensional array */ - { - error("write_array_tfs: Multi-dimensional arrays not implemented yet (param %s)\n", name); - return 0; - } + 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); + + start_offset = *typestring_offset; + update_tfsoff(type, start_offset, file); + print_start_tfs_comment(file, type, start_offset); + print_file(file, 2, "0x%02x,\t/* %s */\n", type->type, string_of_type(type->type)); + print_file(file, 2, "0x%x,\t/* %d */\n", align - 1, align - 1); + *typestring_offset += 2; + + align = 0; + if (type->type != RPC_FC_BOGUS_ARRAY) { - size_t pointer_start_offset = *typestring_offset; - int has_pointer = 0; + unsigned char tc = type->type; - if (write_pointers(file, attrs, type, 0, array, 0, typestring_offset) > 0) - has_pointer = 1; - - start_offset = *typestring_offset; - - if (!has_length && !has_size) + if (tc == RPC_FC_LGFARRAY || tc == RPC_FC_LGVARRAY) { - /* fixed array */ - size_t size = type_memsize(type, 0, array); - if (size < USHRT_MAX) + print_file(file, 2, "NdrFcLong(0x%x),\t/* %lu */\n", size, size); + *typestring_offset += 4; + } + else + { + print_file(file, 2, "NdrFcShort(0x%x),\t/* %lu */\n", size, size); + *typestring_offset += 2; + } + + if (is_conformant_array(type)) + *typestring_offset + += write_conf_or_var_desc(file, current_structure, baseoff, + type, size_is); + + if (type->type == RPC_FC_SMVARRAY || type->type == RPC_FC_LGVARRAY) + { + unsigned int elalign = 0; + size_t elsize = type_memsize(type->ref, &elalign); + + if (type->type == RPC_FC_LGVARRAY) { - WRITE_FCTYPE(file, FC_SMFARRAY, *typestring_offset); - /* alignment */ - print_file(file, 2, "0x%x, /* 0 */\n", 0); - /* size */ - print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", size, size); + print_file(file, 2, "NdrFcLong(0x%x),\t/* %lu */\n", type->dim, type->dim); *typestring_offset += 4; } else { - WRITE_FCTYPE(file, FC_LGFARRAY, *typestring_offset); - /* alignment */ - print_file(file, 2, "0x%x, /* 0 */\n", 0); - /* size */ - print_file(file, 2, "NdrFcLong(0x%x), /* %d */\n", size, size); - *typestring_offset += 6; - } - - if (has_pointer) - { - print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP); - print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD); + print_file(file, 2, "NdrFcShort(0x%x),\t/* %lu */\n", type->dim, type->dim); *typestring_offset += 2; - *typestring_offset = write_pointer_description(file, attrs, - type, 0, array, 0, pointer_start_offset); - print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END); - *typestring_offset += 1; } - print_file(file, 2, "0x0, /* FIXME: write out conversion data */\n"); - print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END); + print_file(file, 2, "NdrFcShort(0x%x),\t/* %lu */\n", elsize, elsize); *typestring_offset += 2; - - return start_offset; } - else if (has_length && !has_size) + + if (length_is) + *typestring_offset + += write_conf_or_var_desc(file, current_structure, baseoff, + type, length_is); + + if (has_pointer && (!type->declarray || !current_structure)) { - /* varying array */ - size_t element_size = type_memsize(type, 0, NULL); - size_t elements = array->cval; - size_t total_size = element_size * elements; - - if (total_size < USHRT_MAX) - { - WRITE_FCTYPE(file, FC_SMVARRAY, *typestring_offset); - /* alignment */ - print_file(file, 2, "0x%x, /* 0 */\n", 0); - /* total size */ - print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", total_size, total_size); - /* number of elements */ - print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", elements, elements); - *typestring_offset += 6; - } - else - { - WRITE_FCTYPE(file, FC_LGVARRAY, *typestring_offset); - /* alignment */ - print_file(file, 2, "0x%x, /* 0 */\n", 0); - /* total size */ - print_file(file, 2, "NdrFcLong(0x%x), /* %d */\n", total_size, total_size); - /* number of elements */ - print_file(file, 2, "NdrFcLong(0x%x), /* %d */\n", elements, elements); - *typestring_offset += 10; - } - /* element size */ - print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", element_size, element_size); + print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP); + print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD); *typestring_offset += 2; - - *typestring_offset += write_conf_or_var_desc(file, current_func, - current_structure, - length_is); - - if (has_pointer) - { - print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP); - print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD); - *typestring_offset += 2; - *typestring_offset += write_pointer_description(file, attrs, - type, 0, array, 0, pointer_start_offset); - print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END); - *typestring_offset += 1; - } - - print_file(file, 2, "0x0, /* FIXME: write out conversion data */\n"); + write_pointer_description(file, type, typestring_offset); print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END); - *typestring_offset += 2; - - return start_offset; + *typestring_offset += 1; } - else if (!has_length && has_size) - { - /* conformant array */ - size_t element_size = type_memsize(type, 0, NULL); - WRITE_FCTYPE(file, FC_CARRAY, *typestring_offset); - /* alignment */ - print_file(file, 2, "0x%x, /* 0 */\n", 0); - /* element size */ - print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", element_size, element_size); - *typestring_offset += 4; - - *typestring_offset += write_conf_or_var_desc(file, current_func, - current_structure, - size_is ? size_is : array); - - if (has_pointer) - { - print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP); - print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD); - *typestring_offset += 2; - *typestring_offset += write_pointer_description(file, attrs, - type, 0, array, 0, pointer_start_offset); - print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END); - *typestring_offset += 1; - } - - print_file(file, 2, "0x%x, /* FIXME: write out conversion data */\n", type->type); - print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END); - *typestring_offset += 2; - - return start_offset; - } - else - { - /* conformant varying array */ - size_t element_size = type_memsize(type, 0, NULL); - - WRITE_FCTYPE(file, FC_CVARRAY, *typestring_offset); - /* alignment */ - print_file(file, 2, "0x%x, /* 0 */\n", 0); - /* element size */ - print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", element_size, element_size); - *typestring_offset += 4; - - *typestring_offset += write_conf_or_var_desc(file, current_func, - current_structure, - size_is ? size_is : array); - *typestring_offset += write_conf_or_var_desc(file, current_func, - current_structure, - length_is); - - if (has_pointer) - { - print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP); - print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD); - *typestring_offset += 2; - *typestring_offset += write_pointer_description(file, attrs, - type, 0, array, 0, pointer_start_offset); - print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END); - *typestring_offset += 1; - } - - print_file(file, 2, "0x0, /* FIXME: write out conversion data */\n"); - print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END); - *typestring_offset += 2; - - return start_offset; - } + write_member_type(file, type, NULL, type->ref, NULL, typestring_offset); + write_end(file, typestring_offset); } + else + { + unsigned int dim = size_is ? 0 : type->dim; + print_file(file, 2, "NdrFcShort(0x%x),\t/* %u */\n", dim, dim); + *typestring_offset += 2; + *typestring_offset + += write_conf_or_var_desc(file, current_structure, baseoff, + type, size_is); + *typestring_offset + += write_conf_or_var_desc(file, current_structure, baseoff, + type, length_is); + write_member_type(file, type, NULL, type->ref, NULL, typestring_offset); + write_end(file, typestring_offset); + } + + return start_offset; } static const var_t *find_array_or_string_in_struct(const type_t *type) { - /* last field is the first in the fields linked list */ - const var_t *last_field = type->fields; - if (is_array_type(last_field->attrs, last_field->ptr_level, last_field->array)) + const var_t *last_field = LIST_ENTRY( list_tail(type->fields), const var_t, entry ); + const type_t *ft = last_field->type; + + if (ft->declarray && is_conformant_array(ft)) return last_field; - assert((last_field->type->type == RPC_FC_CSTRUCT) || - (last_field->type->type == RPC_FC_CPSTRUCT) || - (last_field->type->type == RPC_FC_CVSTRUCT)); - - return find_array_or_string_in_struct(last_field->type); + if (ft->type == RPC_FC_CSTRUCT || ft->type == RPC_FC_CPSTRUCT || ft->type == RPC_FC_CVSTRUCT) + return find_array_or_string_in_struct(last_field->type); + else + return NULL; } -static size_t write_struct_members(FILE *file, const type_t *type) +static void write_struct_members(FILE *file, const type_t *type, + unsigned int *corroff, unsigned int *typestring_offset) { - size_t typestring_size = 0; - var_t *field; + const var_t *field; + unsigned short offset = 0; + int salign = -1; + int padding; - field = type->fields; - while (NEXT_LINK(field)) field = NEXT_LINK(field); - for (; field; field = PREV_LINK(field)) + if (type->fields) LIST_FOR_EACH_ENTRY( field, type->fields, const var_t, entry ) { - if (is_base_type(field->type->type)) + type_t *ft = field->type; + if (!ft->declarray || !is_conformant_array(ft)) { - switch (field->type->type) + unsigned int align = 0; + size_t size = type_memsize(ft, &align); + if (salign == -1) + salign = align; + if ((align - 1) & offset) { -#define CASE_BASETYPE(fctype) \ - case RPC_##fctype: \ - print_file(file, 2, "0x%02x,\t\t/* " #fctype " */\n", RPC_##fctype); \ - typestring_size++; \ - break; - CASE_BASETYPE(FC_BYTE); - CASE_BASETYPE(FC_CHAR); - CASE_BASETYPE(FC_SMALL); - CASE_BASETYPE(FC_USMALL); - CASE_BASETYPE(FC_WCHAR); - CASE_BASETYPE(FC_SHORT); - CASE_BASETYPE(FC_USHORT); - CASE_BASETYPE(FC_LONG); - CASE_BASETYPE(FC_ULONG); - CASE_BASETYPE(FC_FLOAT); - CASE_BASETYPE(FC_HYPER); - CASE_BASETYPE(FC_DOUBLE); - CASE_BASETYPE(FC_ENUM16); - CASE_BASETYPE(FC_ENUM32); - CASE_BASETYPE(FC_IGNORE); - CASE_BASETYPE(FC_ERROR_STATUS_T); - default: - break; -#undef CASE_BASETYPE + unsigned char fc = 0; + switch (align) + { + case 4: + fc = RPC_FC_ALIGNM4; + break; + case 8: + fc = RPC_FC_ALIGNM8; + break; + default: + error("write_struct_members: cannot align type %d\n", ft->type); + } + print_file(file, 2, "0x%x,\t/* %s */\n", fc, string_of_type(fc)); + offset = (offset + (align - 1)) & ~(align - 1); + *typestring_offset += 1; } + write_member_type(file, type, field->attrs, field->type, corroff, + typestring_offset); + offset += size; } - else - error("Unsupported member type 0x%x\n", field->type->type); } - if (typestring_size % 1) + padding = ((offset + (salign - 1)) & ~(salign - 1)) - offset; + if (padding) { - print_file(file, 2, "0x%x,\t\t/* FC_PAD */\n", RPC_FC_PAD); - typestring_size++; + print_file(file, 2, "0x%x,\t/* FC_STRUCTPAD%d */\n", + RPC_FC_STRUCTPAD1 + padding - 1, + padding); + *typestring_offset += 1; } - print_file(file, 2, "0x%x,\t\t/* FC_END */\n", RPC_FC_END); - typestring_size++; - - return typestring_size; + write_end(file, typestring_offset); } -static size_t write_struct_tfs(FILE *file, const type_t *type, - const char *name, unsigned int *typestring_offset) +static size_t write_struct_tfs(FILE *file, type_t *type, + const char *name, unsigned int *tfsoff) { + const type_t *save_current_structure = current_structure; unsigned int total_size; const var_t *array; size_t start_offset; size_t array_offset; - size_t pointer_offset; + int has_pointers = 0; + unsigned int align = 0; + unsigned int corroff; + var_t *f; - switch (type->type) + guard_rec(type); + current_structure = type; + + total_size = type_memsize(type, &align); + if (total_size > USHRT_MAX) + error("structure size for %s exceeds %d bytes by %d bytes\n", + name, USHRT_MAX, total_size - USHRT_MAX); + + 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)) + array_offset + = is_attr(array->attrs, ATTR_STRING) + ? write_string_tfs(file, array->attrs, array->type, array->name, tfsoff, FALSE) + : write_array_tfs(file, array->attrs, array->type, array->name, tfsoff); + + corroff = *tfsoff; + write_descriptors(file, type, tfsoff); + + start_offset = *tfsoff; + update_tfsoff(type, start_offset, file); + print_start_tfs_comment(file, type, start_offset); + print_file(file, 2, "0x%x,\t/* %s */\n", type->type, string_of_type(type->type)); + print_file(file, 2, "0x%x,\t/* %d */\n", align - 1, align - 1); + print_file(file, 2, "NdrFcShort(0x%x),\t/* %d */\n", total_size, total_size); + *tfsoff += 4; + + if (array) { - case RPC_FC_STRUCT: - case RPC_FC_PSTRUCT: - total_size = type_memsize(type, 0, NULL); - - if (total_size > USHRT_MAX) - error("structure size for parameter %s exceeds %d bytes by %d bytes\n", - name, USHRT_MAX, total_size - USHRT_MAX); - - if (type->type == RPC_FC_PSTRUCT) - { - pointer_offset = *typestring_offset; - write_pointers(file, NULL, type, 0, NULL, 0, typestring_offset); - } - else pointer_offset = 0; /* silence warning */ - - start_offset = *typestring_offset; - if (type->type == RPC_FC_STRUCT) - WRITE_FCTYPE(file, FC_STRUCT, *typestring_offset); - else - WRITE_FCTYPE(file, FC_PSTRUCT, *typestring_offset); - /* alignment */ - print_file(file, 2, "0x3,\n"); /* FIXME */ - /* total size */ - print_file(file, 2, "NdrFcShort(0x%x), /* %u */\n", total_size, total_size); - *typestring_offset += 4; - - if (type->type == RPC_FC_PSTRUCT) - { - print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP); - print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD); - *typestring_offset += 2; - *typestring_offset += write_pointer_description(file, NULL, - type, 0, NULL, 0, pointer_offset); - print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END); - *typestring_offset += 1; - } - - /* member layout */ - *typestring_offset += write_struct_members(file, type); - return start_offset; - case RPC_FC_CSTRUCT: - case RPC_FC_CPSTRUCT: - total_size = type_memsize(type, 0, NULL); - - if (total_size > USHRT_MAX) - error("structure size for parameter %s exceeds %d bytes by %d bytes\n", - name, USHRT_MAX, total_size - USHRT_MAX); - - array = find_array_or_string_in_struct(type); - current_structure = type; - array_offset = write_array_tfs(file, array->attrs, array->type, - array->array, array->name, - typestring_offset); - current_structure = NULL; - - if (type->type == RPC_FC_CPSTRUCT) - { - pointer_offset = *typestring_offset; - write_pointers(file, NULL, type, 0, NULL, 0, typestring_offset); - } - else pointer_offset = 0; /* silence warning */ - - start_offset = *typestring_offset; - if (type->type == RPC_FC_CSTRUCT) - WRITE_FCTYPE(file, FC_CSTRUCT, *typestring_offset); - else - WRITE_FCTYPE(file, FC_CPSTRUCT, *typestring_offset); - /* alignment */ - print_file(file, 2, "0x0,\n"); - /* total size */ - print_file(file, 2, "NdrFcShort(0x%x), /* %u */\n", total_size, total_size); - *typestring_offset += 4; - print_file(file, 2, "NdrFcShort(0x%x), /* offset = %d (%u) */\n", - array_offset - *typestring_offset, - array_offset - *typestring_offset, - array_offset); - *typestring_offset += 2; - - if (type->type == RPC_FC_CPSTRUCT) - { - print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP); - print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD); - *typestring_offset += 2; - *typestring_offset += write_pointer_description(file, NULL, - type, 0, NULL, 0, pointer_offset); - print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END); - *typestring_offset += 1; - } - - print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END); - *typestring_offset += 1; - - return start_offset; - case RPC_FC_CVSTRUCT: - total_size = type_memsize(type, 0, NULL); - - if (total_size > USHRT_MAX) - error("structure size for parameter %s exceeds %d bytes by %d bytes\n", - name, USHRT_MAX, total_size - USHRT_MAX); - - array = find_array_or_string_in_struct(type); - current_structure = type; - if (is_attr(array->attrs, ATTR_STRING)) - array_offset = write_string_tfs(file, array->attrs, array->type, - array->array, array->name, - typestring_offset); - else - array_offset = write_array_tfs(file, array->attrs, array->type, - array->array, array->name, - typestring_offset); - current_structure = NULL; - - pointer_offset = *typestring_offset; - if (!write_pointers(file, NULL, type, 0, NULL, 0, typestring_offset)) - pointer_offset = 0; - - start_offset = *typestring_offset; - WRITE_FCTYPE(file, FC_CVSTRUCT, *typestring_offset); - /* alignment */ - print_file(file, 2, "0x0,\n"); - /* total size */ - print_file(file, 2, "NdrFcShort(0x%x), /* %u */\n", total_size, total_size); - *typestring_offset += 4; - print_file(file, 2, "NdrFcShort(0x%x), /* offset = %d (%u) */\n", - array_offset - *typestring_offset, - array_offset - *typestring_offset, - array_offset); - *typestring_offset += 2; - - if (pointer_offset != 0) - { - print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP); - print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD); - *typestring_offset += 2; - *typestring_offset += write_pointer_description(file, NULL, - type, 0, NULL, 0, pointer_offset); - print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END); - *typestring_offset += 1; - } - - print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END); - *typestring_offset += 1; - - return start_offset; - default: - error("write_struct_tfs: Unimplemented for type 0x%x\n", type->type); - return *typestring_offset; + unsigned int absoff = array->type->typestring_offset; + short reloff = absoff - *tfsoff; + print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%lu) */\n", + reloff, reloff, absoff); + *tfsoff += 2; } + else if (type->type == RPC_FC_BOGUS_STRUCT) + { + print_file(file, 2, "NdrFcShort(0x0),\n"); + *tfsoff += 2; + } + + if (type->type == RPC_FC_BOGUS_STRUCT) + { + /* On the sizing pass, type->ptrdesc may be zero, but it's ok as + nothing is written to file yet. On the actual writing pass, + this will have been updated. */ + unsigned int absoff = type->ptrdesc ? type->ptrdesc : *tfsoff; + short reloff = absoff - *tfsoff; + print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%u) */\n", + reloff, reloff, absoff); + *tfsoff += 2; + } + else if ((type->type == RPC_FC_PSTRUCT) || + (type->type == RPC_FC_CPSTRUCT) || + (type->type == RPC_FC_CVSTRUCT && has_pointers)) + { + print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP); + print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD); + *tfsoff += 2; + write_pointer_description(file, type, tfsoff); + print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END); + *tfsoff += 1; + } + + write_struct_members(file, type, &corroff, tfsoff); + + if (type->type == RPC_FC_BOGUS_STRUCT) + { + const var_list_t *fs = type->fields; + const var_t *f; + + type->ptrdesc = *tfsoff; + if (fs) LIST_FOR_EACH_ENTRY(f, fs, const var_t, entry) + { + type_t *ft = f->type; + if (is_ptr(ft)) + write_pointer_tfs(file, ft, tfsoff); + else if (!ft->declarray && is_conformant_array(ft)) + { + unsigned int absoff = ft->typestring_offset; + short reloff = absoff - (*tfsoff + 2); + int ptr_type = get_attrv(f->attrs, ATTR_POINTERTYPE); + /* FIXME: We need to store pointer attributes for arrays + so we don't lose pointer_default info. */ + if (ptr_type == 0) + ptr_type = RPC_FC_UP; + print_file(file, 0, "/* %d */\n", *tfsoff); + print_file(file, 2, "0x%x, 0x0,\t/* %s */\n", ptr_type, + string_of_type(ptr_type)); + print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%u) */\n", + reloff, reloff, absoff); + *tfsoff += 4; + } + } + if (type->ptrdesc == *tfsoff) + type->ptrdesc = 0; + } + + current_structure = save_current_structure; + return start_offset; } -static void write_pointer_only_tfs(FILE *file, const attr_t *attrs, size_t offset, unsigned int *typeformat_offset) +static size_t write_pointer_only_tfs(FILE *file, const attr_list_t *attrs, int pointer_type, + unsigned char flags, size_t offset, + unsigned int *typeformat_offset) { + size_t start_offset = *typeformat_offset; + short reloff = offset - (*typeformat_offset + 2); int in_attr, out_attr; - unsigned char flags = 0; - int pointer_type = get_attrv(attrs, ATTR_POINTERTYPE); - if (!pointer_type) pointer_type = RPC_FC_RP; in_attr = is_attr(attrs, ATTR_IN); out_attr = is_attr(attrs, ATTR_OUT); if (!in_attr && !out_attr) in_attr = 1; @@ -1223,135 +1864,445 @@ static void write_pointer_only_tfs(FILE *file, const attr_t *attrs, size_t offse if (out_attr && !in_attr && pointer_type == RPC_FC_RP) flags |= 0x04; - print_file(file, 2, "0x%x, 0x%x,\t\t/* %s%s */\n", + print_file(file, 2, "0x%x, 0x%x,\t\t/* %s", pointer_type, flags, - pointer_type == RPC_FC_FP ? "FC_FP" : (pointer_type == RPC_FC_UP ? "FC_UP" : "FC_RP"), - (flags & 0x04) ? " [allocated_on_stack]" : ""); - print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", offset, offset); - *typeformat_offset += 4; -} - -static size_t write_union_tfs(FILE *file, const attr_t *attrs, - const type_t *type, const char *name, - unsigned int *typeformat_offset) -{ - error("write_union_tfs: Unimplemented\n"); - return *typeformat_offset; -} - -static size_t write_typeformatstring_var(FILE *file, int indent, - const var_t *var, unsigned int *typeformat_offset) -{ - const type_t *type = var->type; - int ptr_level = var->ptr_level; - - chat("write_typeformatstring_var: %s\n", var->name); - - while (TRUE) + string_of_type(pointer_type)); + if (file) { - chat("write_typeformatstring: type->type = 0x%x, type->name = %s, ptr_level = %d\n", type->type, type->name, ptr_level); + if (flags & 0x04) + fprintf(file, " [allocated_on_stack]"); + if (flags & 0x10) + fprintf(file, " [pointer_deref]"); + fprintf(file, " */\n"); + } - if (is_string_type(var->attrs, ptr_level, var->array)) - return write_string_tfs(file, var->attrs, type, var->array, var->name, typeformat_offset); + print_file(file, 2, "NdrFcShort(0x%x),\t/* %d */\n", reloff, offset); + *typeformat_offset += 4; - if (is_array_type(var->attrs, ptr_level, var->array)) - return write_array_tfs(file, var->attrs, type, var->array, var->name, typeformat_offset); + return start_offset; +} - if (ptr_level == 0) +static void write_branch_type(FILE *file, const type_t *t, unsigned int *tfsoff) +{ + if (t == NULL) + { + print_file(file, 2, "NdrFcShort(0x0),\t/* No type */\n"); + } + else if (is_base_type(t->type)) + { + print_file(file, 2, "NdrFcShort(0x80%02x),\t/* Simple arm type: %s */\n", + t->type, string_of_type(t->type)); + } + else if (t->typestring_offset) + { + short reloff = t->typestring_offset - *tfsoff; + print_file(file, 2, "NdrFcShort(0x%x),\t/* Offset= %d (%d) */\n", + reloff, reloff, t->typestring_offset); + } + else + error("write_branch_type: type unimplemented (0x%x)\n", t->type); + + *tfsoff += 2; +} + +static size_t write_union_tfs(FILE *file, type_t *type, unsigned int *tfsoff) +{ + unsigned int align = 0; + unsigned int start_offset; + size_t size = type_memsize(type, &align); + var_list_t *fields; + size_t nbranch = 0; + type_t *deftype = NULL; + short nodeftype = 0xffff; + var_t *f; + + guard_rec(type); + + 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(f, fields, var_t, entry) + { + expr_list_t *cases = get_attrp(f->attrs, ATTR_CASE); + if (cases) + nbranch += list_count(cases); + if (f->type) + write_embedded_types(file, f->attrs, f->type, f->name, TRUE, tfsoff); + } + + start_offset = *tfsoff; + update_tfsoff(type, start_offset, file); + print_start_tfs_comment(file, type, start_offset); + if (type->type == RPC_FC_ENCAPSULATED_UNION) + { + const var_t *sv = LIST_ENTRY(list_head(type->fields), const var_t, entry); + const type_t *st = sv->type; + + switch (st->type) { - /* follow reference if the type has one */ - if (type_has_ref(type)) - { - type = type->ref; - /* FIXME: get new ptr_level from type */ - continue; - } - - /* basic types don't need a type format string */ - if (is_base_type(type->type)) - return 0; - - switch (type->type) - { - case RPC_FC_STRUCT: - case RPC_FC_PSTRUCT: - case RPC_FC_CSTRUCT: - case RPC_FC_CPSTRUCT: - case RPC_FC_CVSTRUCT: - case RPC_FC_BOGUS_STRUCT: - return write_struct_tfs(file, type, var->name, typeformat_offset); - case RPC_FC_ENCAPSULATED_UNION: - case RPC_FC_NON_ENCAPSULATED_UNION: - return write_union_tfs(file, var->attrs, type, var->name, typeformat_offset); - case RPC_FC_IGNORE: - case RPC_FC_BIND_PRIMITIVE: - /* nothing to do */ - return 0; - default: - error("write_typeformatstring_var: Unsupported type 0x%x for variable %s\n", type->type, var->name); - } + case RPC_FC_CHAR: + case RPC_FC_SMALL: + case RPC_FC_USMALL: + case RPC_FC_SHORT: + case RPC_FC_USHORT: + case RPC_FC_LONG: + case RPC_FC_ULONG: + case RPC_FC_ENUM16: + case RPC_FC_ENUM32: + print_file(file, 2, "0x%x,\t/* %s */\n", type->type, string_of_type(type->type)); + print_file(file, 2, "0x%x,\t/* Switch type= %s */\n", + 0x40 | st->type, string_of_type(st->type)); + *tfsoff += 2; + break; + default: + error("union switch type must be an integer, char, or enum\n"); } - else if (ptr_level == 1 && !type_has_ref(type)) - { - size_t start_offset = *typeformat_offset; - int in_attr = is_attr(var->attrs, ATTR_IN); - int out_attr = is_attr(var->attrs, ATTR_OUT); - int pointer_type = get_attrv(var->attrs, ATTR_POINTERTYPE); - if (!pointer_type) pointer_type = RPC_FC_RP; + } + print_file(file, 2, "NdrFcShort(0x%x),\t/* %d */\n", size, size); + print_file(file, 2, "NdrFcShort(0x%x),\t/* %d */\n", nbranch, nbranch); + *tfsoff += 4; - /* special case for pointers to base types */ - switch (type->type) - { -#define CASE_BASETYPE(fctype) \ - case RPC_##fctype: \ - print_file(file, indent, "0x%x, 0x%x, /* %s %s[simple_pointer] */\n", \ - pointer_type, \ - (!in_attr && out_attr) ? 0x0C : 0x08, \ - pointer_type == RPC_FC_FP ? "FC_FP" : (pointer_type == RPC_FC_UP ? "FC_UP" : "FC_RP"), \ - (!in_attr && out_attr) ? "[allocated_on_stack] " : ""); \ - print_file(file, indent, "0x%02x, /* " #fctype " */\n", RPC_##fctype); \ - print_file(file, indent, "0x5c, /* FC_PAD */\n"); \ - *typeformat_offset += 4; \ - return start_offset - CASE_BASETYPE(FC_BYTE); - CASE_BASETYPE(FC_CHAR); - CASE_BASETYPE(FC_SMALL); - CASE_BASETYPE(FC_USMALL); - CASE_BASETYPE(FC_WCHAR); - CASE_BASETYPE(FC_SHORT); - CASE_BASETYPE(FC_USHORT); - CASE_BASETYPE(FC_LONG); - CASE_BASETYPE(FC_ULONG); - CASE_BASETYPE(FC_FLOAT); - CASE_BASETYPE(FC_HYPER); - CASE_BASETYPE(FC_DOUBLE); - CASE_BASETYPE(FC_ENUM16); - CASE_BASETYPE(FC_ENUM32); - CASE_BASETYPE(FC_IGNORE); - CASE_BASETYPE(FC_ERROR_STATUS_T); - default: - break; - } + if (fields) LIST_FOR_EACH_ENTRY(f, fields, var_t, entry) + { + type_t *ft = f->type; + expr_list_t *cases = get_attrp(f->attrs, ATTR_CASE); + int deflt = is_attr(f->attrs, ATTR_DEFAULT); + expr_t *c; + + if (cases == NULL && !deflt) + error("union field %s with neither case nor default attribute\n", f->name); + + if (cases) LIST_FOR_EACH_ENTRY(c, cases, expr_t, entry) + { + /* MIDL doesn't check for duplicate cases, even though that seems + like a reasonable thing to do, it just dumps them to the TFS + like we're going to do here. */ + print_file(file, 2, "NdrFcLong(0x%x),\t/* %d */\n", c->cval, c->cval); + *tfsoff += 4; + write_branch_type(file, ft, tfsoff); } - assert(ptr_level > 0); + /* MIDL allows multiple default branches, even though that seems + illogical, it just chooses the last one, which is what we will + do. */ + if (deflt) + { + deftype = ft; + nodeftype = 0; + } + } + + if (deftype) + { + write_branch_type(file, deftype, tfsoff); + } + else + { + print_file(file, 2, "NdrFcShort(0x%x),\n", nodeftype); + *tfsoff += 2; + } + + return start_offset; +} + +static size_t write_ip_tfs(FILE *file, const attr_list_t *attrs, type_t *type, + unsigned int *typeformat_offset) +{ + size_t i; + size_t start_offset = *typeformat_offset; + expr_t *iid = get_attrp(attrs, ATTR_IIDIS); + + if (iid) + { + print_file(file, 2, "0x2f, /* FC_IP */\n"); + print_file(file, 2, "0x5c, /* FC_PAD */\n"); + *typeformat_offset + += write_conf_or_var_desc(file, NULL, 0, type, iid) + 2; + } + else + { + const type_t *base = is_ptr(type) ? type->ref : type; + const UUID *uuid = get_attrp(base->attrs, ATTR_UUID); + + if (! uuid) + error("%s: interface %s missing UUID\n", __FUNCTION__, base->name); + + update_tfsoff(type, start_offset, file); + print_start_tfs_comment(file, type, start_offset); + print_file(file, 2, "0x2f,\t/* FC_IP */\n"); + print_file(file, 2, "0x5a,\t/* FC_CONSTANT_IID */\n"); + print_file(file, 2, "NdrFcLong(0x%08lx),\n", uuid->Data1); + print_file(file, 2, "NdrFcShort(0x%04x),\n", uuid->Data2); + print_file(file, 2, "NdrFcShort(0x%04x),\n", uuid->Data3); + for (i = 0; i < 8; ++i) + print_file(file, 2, "0x%02x,\n", uuid->Data4[i]); if (file) - fprintf(file, "/* %2u */\n", *typeformat_offset); - write_pointer_only_tfs(file, var->attrs, 2, typeformat_offset); + fprintf(file, "\n"); - ptr_level--; + *typeformat_offset += 18; } + return start_offset; +} + +static size_t write_contexthandle_tfs(FILE *file, const type_t *type, + const var_t *var, + unsigned int *typeformat_offset) +{ + size_t start_offset = *typeformat_offset; + unsigned char flags = 0x08 /* strict */; + + if (is_ptr(type)) + { + flags |= 0x80; + if (type->type != RPC_FC_RP) + flags |= 0x01; + } + if (is_attr(var->attrs, ATTR_IN)) + flags |= 0x40; + if (is_attr(var->attrs, ATTR_OUT)) + flags |= 0x20; + + WRITE_FCTYPE(file, FC_BIND_CONTEXT, *typeformat_offset); + print_file(file, 2, "0x%x,\t/* Context flags: ", flags); + if (((flags & 0x21) != 0x21) && (flags & 0x01)) + print_file(file, 0, "can't be null, "); + if (flags & 0x02) + print_file(file, 0, "serialize, "); + if (flags & 0x04) + print_file(file, 0, "no serialize, "); + if (flags & 0x08) + print_file(file, 0, "strict, "); + if ((flags & 0x21) == 0x20) + print_file(file, 0, "out, "); + if ((flags & 0x21) == 0x21) + print_file(file, 0, "return, "); + if (flags & 0x40) + print_file(file, 0, "in, "); + if (flags & 0x80) + print_file(file, 0, "via ptr, "); + print_file(file, 0, "*/\n"); + print_file(file, 2, "0, /* FIXME: rundown routine index*/\n"); + print_file(file, 2, "0, /* FIXME: param num */\n"); + *typeformat_offset += 4; + + return start_offset; +} + +static size_t write_typeformatstring_var(FILE *file, int indent, const func_t *func, + type_t *type, const var_t *var, + unsigned int *typeformat_offset) +{ + size_t offset; + + if (is_context_handle(type)) + return write_contexthandle_tfs(file, type, var, typeformat_offset); + + if (is_user_type(type)) + { + write_user_tfs(file, type, typeformat_offset); + return type->typestring_offset; + } + + if ((last_ptr(type) || last_array(type)) && is_ptrchain_attr(var, ATTR_STRING)) + return write_string_tfs(file, var->attrs, type, var->name, typeformat_offset, TRUE); + + if (is_array(type)) + { + int ptr_type; + size_t off; + off = write_array_tfs(file, var->attrs, type, var->name, typeformat_offset); + ptr_type = get_attrv(var->attrs, ATTR_POINTERTYPE); + /* Top level pointers to conformant arrays may be handled specially + since we can bypass the pointer, but if the array is burried + beneath another pointer (e.g., "[size_is(,n)] int **p" then we + always need to write the pointer. */ + if (!ptr_type && var->type != type) + /* FIXME: This should use pointer_default, but the information + isn't kept around for arrays. */ + ptr_type = RPC_FC_UP; + if (ptr_type && ptr_type != RPC_FC_RP) + { + unsigned int absoff = type->typestring_offset; + short reloff = absoff - (*typeformat_offset + 2); + off = *typeformat_offset; + print_file(file, 0, "/* %d */\n", off); + print_file(file, 2, "0x%x, 0x0,\t/* %s */\n", ptr_type, + string_of_type(ptr_type)); + print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%u) */\n", + reloff, reloff, absoff); + *typeformat_offset += 4; + } + return off; + } + + if (!is_ptr(type)) + { + /* basic types don't need a type format string */ + if (is_base_type(type->type)) + return 0; + + switch (type->type) + { + case RPC_FC_STRUCT: + case RPC_FC_PSTRUCT: + case RPC_FC_CSTRUCT: + case RPC_FC_CPSTRUCT: + case RPC_FC_CVSTRUCT: + case RPC_FC_BOGUS_STRUCT: + return write_struct_tfs(file, type, var->name, typeformat_offset); + case RPC_FC_ENCAPSULATED_UNION: + case RPC_FC_NON_ENCAPSULATED_UNION: + return write_union_tfs(file, type, typeformat_offset); + case RPC_FC_IGNORE: + case RPC_FC_BIND_PRIMITIVE: + /* nothing to do */ + return 0; + default: + error("write_typeformatstring_var: Unsupported type 0x%x for variable %s\n", type->type, var->name); + } + } + else if (last_ptr(type)) + { + size_t start_offset = *typeformat_offset; + int in_attr = is_attr(var->attrs, ATTR_IN); + int out_attr = is_attr(var->attrs, ATTR_OUT); + const type_t *base = type->ref; + + if (base->type == RPC_FC_IP + || (base->type == 0 + && is_attr(var->attrs, ATTR_IIDIS))) + { + return write_ip_tfs(file, var->attrs, type, typeformat_offset); + } + + /* special case for pointers to base types */ + if (is_base_type(base->type)) + { + print_file(file, indent, "0x%x, 0x%x, /* %s %s[simple_pointer] */\n", + type->type, (!in_attr && out_attr) ? 0x0C : 0x08, + string_of_type(type->type), + (!in_attr && out_attr) ? "[allocated_on_stack] " : ""); + print_file(file, indent, "0x%02x, /* %s */\n", base->type, string_of_type(base->type)); + print_file(file, indent, "0x5c, /* FC_PAD */\n"); + *typeformat_offset += 4; + return start_offset; + } + } + + assert(is_ptr(type)); + + offset = write_typeformatstring_var(file, indent, func, type->ref, var, typeformat_offset); + if (file) + fprintf(file, "/* %2u */\n", *typeformat_offset); + return write_pointer_only_tfs(file, var->attrs, type->type, + !last_ptr(type) ? 0x10 : 0, + offset, typeformat_offset); +} + +static int write_embedded_types(FILE *file, const attr_list_t *attrs, type_t *type, + const char *name, int write_ptr, unsigned int *tfsoff) +{ + int retmask = 0; + + if (is_user_type(type)) + { + write_user_tfs(file, type, tfsoff); + } + else if (is_ptr(type)) + { + type_t *ref = type->ref; + + if (ref->type == RPC_FC_IP + || (ref->type == 0 + && is_attr(attrs, ATTR_IIDIS))) + { + write_ip_tfs(file, attrs, type, tfsoff); + } + else + { + if (!processed(ref) && !is_base_type(ref->type)) + retmask |= write_embedded_types(file, NULL, ref, name, TRUE, tfsoff); + + if (write_ptr) + write_pointer_tfs(file, type, tfsoff); + + retmask |= 1; + } + } + else if (last_array(type) && is_attr(attrs, ATTR_STRING)) + { + write_string_tfs(file, attrs, type, name, tfsoff, FALSE); + } + else if (type->declarray && is_conformant_array(type)) + ; /* conformant arrays and strings are handled specially */ + else if (is_array(type)) + { + write_array_tfs(file, attrs, type, name, tfsoff); + if (is_conformant_array(type)) + retmask |= 1; + } + else if (is_struct(type->type)) + { + if (!processed(type)) + write_struct_tfs(file, type, name, tfsoff); + } + else if (is_union(type->type)) + { + if (!processed(type)) + write_union_tfs(file, type, tfsoff); + } + else if (!is_base_type(type->type)) + error("write_embedded_types: unknown embedded type for %s (0x%x)\n", + name, type->type); + + return retmask; +} + +static size_t process_tfs(FILE *file, const ifref_list_t *ifaces, type_pred_t pred) +{ + const var_t *var; + const ifref_t *iface; + unsigned int typeformat_offset = 2; + + if (ifaces) LIST_FOR_EACH_ENTRY( iface, ifaces, const ifref_t, entry ) + { + if (!pred(iface->iface)) + continue; + + if (iface->iface->funcs) + { + const func_t *func; + LIST_FOR_EACH_ENTRY( func, iface->iface->funcs, const func_t, entry ) + { + if (is_local(func->def->attrs)) continue; + + current_func = func; + if (func->args) + LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) + update_tfsoff( + var->type, + write_typeformatstring_var( + file, 2, func, var->type, var, + &typeformat_offset), + file); + } + } + } + + return typeformat_offset + 1; } -void write_typeformatstring(FILE *file, const ifref_t *ifaces) +void write_typeformatstring(FILE *file, const ifref_list_t *ifaces, type_pred_t pred) { int indent = 0; - var_t *var; - unsigned int typeformat_offset; - const ifref_t *iface = ifaces; print_file(file, indent, "static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString =\n"); print_file(file, indent, "{\n"); @@ -1360,36 +2311,9 @@ void write_typeformatstring(FILE *file, const ifref_t *ifaces) print_file(file, indent, "{\n"); indent++; print_file(file, indent, "NdrFcShort(0x0),\n"); - typeformat_offset = 2; - END_OF_LIST(iface); - - for (; iface; iface = PREV_LINK(iface)) - { - if (is_object(iface->iface->attrs) || is_local(iface->iface->attrs)) - continue; - - if (iface->iface->funcs) - { - func_t *func = iface->iface->funcs; - while (NEXT_LINK(func)) func = NEXT_LINK(func); - for (; func; func = PREV_LINK(func)) - { - current_func = func; - if (func->args) - { - var = func->args; - while (NEXT_LINK(var)) var = NEXT_LINK(var); - while (var) - { - write_typeformatstring_var(file, indent, var, - &typeformat_offset); - var = PREV_LINK(var); - } - } - } - } - } + set_all_tfswrite(TRUE); + process_tfs(file, ifaces, pred); print_file(file, indent, "0x0\n"); indent--; @@ -1400,11 +2324,16 @@ void write_typeformatstring(FILE *file, const ifref_t *ifaces) } static unsigned int get_required_buffer_size_type( - const type_t *type, int ptr_level, const expr_t *array, - const char *name, unsigned int *alignment) + const type_t *type, const char *name, unsigned int *alignment) { *alignment = 0; - if (ptr_level == 0 && !array && !type_has_ref(type)) + if (is_user_type(type)) + { + const char *uname; + const type_t *utype = get_user_type(type, &uname); + return get_required_buffer_size_type(utype, uname, alignment); + } + else { switch (type->type) { @@ -1418,11 +2347,13 @@ static unsigned int get_required_buffer_size_type( case RPC_FC_WCHAR: case RPC_FC_USHORT: case RPC_FC_SHORT: + case RPC_FC_ENUM16: *alignment = 4; return 2; case RPC_FC_ULONG: case RPC_FC_LONG: + case RPC_FC_ENUM32: case RPC_FC_FLOAT: case RPC_FC_ERROR_STATUS_T: *alignment = 4; @@ -1438,76 +2369,85 @@ static unsigned int get_required_buffer_size_type( return 0; case RPC_FC_STRUCT: + case RPC_FC_PSTRUCT: { size_t size = 0; const var_t *field; - for (field = type->fields; field; field = NEXT_LINK(field)) + if (!type->fields) return 0; + LIST_FOR_EACH_ENTRY( field, type->fields, const var_t, entry ) { unsigned int alignment; - size += get_required_buffer_size_type( - field->type, field->ptr_level, field->array, field->name, - &alignment); + size += get_required_buffer_size_type(field->type, field->name, + &alignment); } return size; } + case RPC_FC_RP: + return + is_base_type( type->ref->type ) || type->ref->type == RPC_FC_STRUCT + ? get_required_buffer_size_type( type->ref, name, alignment ) + : 0; + + case RPC_FC_SMFARRAY: + case RPC_FC_LGFARRAY: + return type->dim * get_required_buffer_size_type(type->ref, name, alignment); + default: - error("get_required_buffer_size: Unknown/unsupported type: %s (0x%02x)\n", name, type->type); return 0; } } - if (ptr_level == 0 && type_has_ref(type)) - return get_required_buffer_size_type(type->ref, 0 /* FIXME */, array, name, alignment); - return 0; } -unsigned int get_required_buffer_size(const var_t *var, unsigned int *alignment, enum pass pass) +static unsigned int get_required_buffer_size(const var_t *var, unsigned int *alignment, enum pass pass) { - expr_t *size_is = get_attrp(var->attrs, ATTR_SIZEIS); - int has_size = (size_is && (size_is->type != EXPR_VOID)); int in_attr = is_attr(var->attrs, ATTR_IN); int out_attr = is_attr(var->attrs, ATTR_OUT); + const type_t *t; if (!in_attr && !out_attr) in_attr = 1; *alignment = 0; + for (t = var->type; is_ptr(t); t = t->ref) + if (is_attr(t->attrs, ATTR_CONTEXTHANDLE)) + { + *alignment = 4; + return 20; + } + if (pass == PASS_OUT) { - if (out_attr && var->ptr_level > 0) + if (out_attr && is_ptr(var->type)) { type_t *type = var->type; - while (type->type == 0 && type->ref) - type = type->ref; if (type->type == RPC_FC_STRUCT) { const var_t *field; unsigned int size = 36; - for (field = type->fields; field; field = NEXT_LINK(field)) + + if (!type->fields) return size; + LIST_FOR_EACH_ENTRY( field, type->fields, const var_t, entry ) { unsigned int align; size += get_required_buffer_size_type( - field->type, field->ptr_level, field->array, field->name, - &align); + field->type, field->name, &align); } return size; } - else - return get_required_buffer_size_type(var->type, 0 /* FIXME */, var->array, var->name, alignment); } return 0; } else { - if ((!out_attr || in_attr) && !has_size && !is_attr(var->attrs, ATTR_STRING) && !var->array) + if ((!out_attr || in_attr) && !var->type->size_is + && !is_attr(var->attrs, ATTR_STRING) && !var->type->declarray) { - if (var->ptr_level > 0 || (var->ptr_level == 0 && type_has_ref(var->type))) + if (is_ptr(var->type)) { type_t *type = var->type; - while (type->type == 0 && type->ref) - type = type->ref; if (is_base_type(type->type)) { @@ -1517,25 +2457,48 @@ unsigned int get_required_buffer_size(const var_t *var, unsigned int *alignment, { unsigned int size = 36; const var_t *field; - for (field = type->fields; field; field = NEXT_LINK(field)) + + if (!type->fields) return size; + LIST_FOR_EACH_ENTRY( field, type->fields, const var_t, entry ) { unsigned int align; size += get_required_buffer_size_type( - field->type, field->ptr_level, field->array, field->name, - &align); + field->type, field->name, &align); } return size; } } } - return get_required_buffer_size_type(var->type, var->ptr_level, var->array, var->name, alignment); + return get_required_buffer_size_type(var->type, var->name, alignment); } } +static unsigned int get_function_buffer_size( const func_t *func, enum pass pass ) +{ + const var_t *var; + unsigned int total_size = 0, alignment; + + if (func->args) + { + LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) + { + total_size += get_required_buffer_size(var, &alignment, pass); + total_size += alignment; + } + } + + if (pass == PASS_OUT && !is_void(func->def->type)) + { + total_size += get_required_buffer_size(func->def, &alignment, PASS_RETURN); + total_size += alignment; + } + return total_size; +} + static void print_phase_function(FILE *file, int indent, const char *type, enum remoting_phase phase, - const char *varname, unsigned int type_offset) + const var_t *var, unsigned int type_offset) { const char *function; switch (phase) @@ -1560,9 +2523,11 @@ static void print_phase_function(FILE *file, int indent, const char *type, print_file(file, indent, "Ndr%s%s(\n", type, function); indent++; print_file(file, indent, "&_StubMsg,\n"); - print_file(file, indent, "%s%s,\n", - (phase == PHASE_UNMARSHAL) ? "(unsigned char **)&" : "(unsigned char *)", - varname); + print_file(file, indent, "%s%s%s%s,\n", + (phase == PHASE_UNMARSHAL) ? "(unsigned char **)" : "(unsigned char *)", + (phase == PHASE_UNMARSHAL || decl_indirect(var->type)) ? "&" : "", + (phase == PHASE_UNMARSHAL && decl_indirect(var->type)) ? "_p_" : "", + var->name); print_file(file, indent, "(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%d]%s\n", type_offset, (phase == PHASE_UNMARSHAL) ? "," : ");"); if (phase == PHASE_UNMARSHAL) @@ -1574,18 +2539,18 @@ void print_phase_basetype(FILE *file, int indent, enum remoting_phase phase, enum pass pass, const var_t *var, const char *varname) { - const type_t *type = var->type; + type_t *type = var->type; unsigned int size; unsigned int alignment = 0; + unsigned char rtype; /* no work to do for other phases, buffer sizing is done elsewhere */ if (phase != PHASE_MARSHAL && phase != PHASE_UNMARSHAL) return; - while (type_has_ref(type)) - type = type->ref; + rtype = is_ptr(type) ? type->ref->type : type->type; - switch (type->type) + switch (rtype) { case RPC_FC_BYTE: case RPC_FC_CHAR: @@ -1598,12 +2563,14 @@ void print_phase_basetype(FILE *file, int indent, enum remoting_phase phase, case RPC_FC_WCHAR: case RPC_FC_USHORT: case RPC_FC_SHORT: + case RPC_FC_ENUM16: size = 2; alignment = 2; break; case RPC_FC_ULONG: case RPC_FC_LONG: + case RPC_FC_ENUM32: case RPC_FC_FLOAT: case RPC_FC_ERROR_STATUS_T: size = 4; @@ -1622,41 +2589,49 @@ void print_phase_basetype(FILE *file, int indent, enum remoting_phase phase, return; default: - error("print_phase_basetype: Unsupported type: %s (0x%02x, ptr_level: 0)\n", var->name, type->type); + error("print_phase_basetype: Unsupported type: %s (0x%02x, ptr_level: 0)\n", var->name, rtype); size = 0; } + if (phase == PHASE_MARSHAL) + print_file(file, indent, "MIDL_memset(_StubMsg.Buffer, 0, (0x%x - (long)_StubMsg.Buffer) & 0x%x);\n", alignment, alignment - 1); print_file(file, indent, "_StubMsg.Buffer = (unsigned char *)(((long)_StubMsg.Buffer + %u) & ~0x%x);\n", alignment - 1, alignment - 1); if (phase == PHASE_MARSHAL) { print_file(file, indent, "*("); - write_type(file, var->type, NULL, var->tname); - if (var->ptr_level) + write_type_decl(file, is_ptr(type) ? type->ref : type, NULL); + if (is_ptr(type)) fprintf(file, " *)_StubMsg.Buffer = *"); else fprintf(file, " *)_StubMsg.Buffer = "); - fprintf(file, varname); + fprintf(file, "%s", varname); fprintf(file, ";\n"); } else if (phase == PHASE_UNMARSHAL) { + print_file(file, indent, "if (_StubMsg.Buffer + sizeof("); + write_type_decl(file, is_ptr(type) ? type->ref : type, NULL); + fprintf(file, ") > _StubMsg.BufferEnd)\n"); + print_file(file, indent, "{\n"); + print_file(file, indent + 1, "RpcRaiseException(RPC_X_BAD_STUB_DATA);\n"); + print_file(file, indent, "}\n"); if (pass == PASS_IN || pass == PASS_RETURN) print_file(file, indent, ""); else print_file(file, indent, "*"); - fprintf(file, varname); - if (pass == PASS_IN && var->ptr_level) + fprintf(file, "%s", varname); + if (pass == PASS_IN && is_ptr(type)) fprintf(file, " = ("); else fprintf(file, " = *("); - write_type(file, var->type, NULL, var->tname); + write_type_decl(file, is_ptr(type) ? type->ref : type, NULL); fprintf(file, " *)_StubMsg.Buffer;\n"); } print_file(file, indent, "_StubMsg.Buffer += sizeof("); - write_type(file, var->type, NULL, var->tname); + write_type_decl(file, var->type, NULL); fprintf(file, ");\n"); } @@ -1667,298 +2642,366 @@ static inline int is_size_needed_for_phase(enum remoting_phase phase) return (phase != PHASE_UNMARSHAL); } -void write_remoting_arguments(FILE *file, int indent, const func_t *func, - unsigned int *type_offset, enum pass pass, - enum remoting_phase phase) +expr_t *get_size_is_expr(const type_t *t, const char *name) { - const expr_t *length_is; - const expr_t *size_is; - int in_attr, out_attr, has_length, has_size, pointer_type; - var_t *var; + expr_t *x = NULL; - if (!func->args) - return; + for ( ; is_ptr(t) || is_array(t); t = t->ref) + if (t->size_is) + { + if (!x) + x = t->size_is; + else + error("%s: multidimensional conformant" + " arrays not supported at the top level\n", + name); + } - var = func->args; - while (NEXT_LINK(var)) var = NEXT_LINK(var); - for (; var; *type_offset += get_size_typeformatstring_var(var), var = PREV_LINK(var)) - { - const type_t *type = var->type; - length_is = get_attrp(var->attrs, ATTR_LENGTHIS); - size_is = get_attrp(var->attrs, ATTR_SIZEIS); - has_length = length_is && (length_is->type != EXPR_VOID); - has_size = (size_is && (size_is->type != EXPR_VOID)) || (var->array && !var->array->is_const); + return x; +} - pointer_type = get_attrv(var->attrs, ATTR_POINTERTYPE); - if (!pointer_type) - pointer_type = RPC_FC_RP; +static void write_remoting_arg(FILE *file, int indent, const func_t *func, + enum pass pass, enum remoting_phase phase, + const var_t *var) +{ + int in_attr, out_attr, pointer_type; + const type_t *type = var->type; + unsigned char rtype; + size_t start_offset = type->typestring_offset; - in_attr = is_attr(var->attrs, ATTR_IN); - out_attr = is_attr(var->attrs, ATTR_OUT); - if (!in_attr && !out_attr) - in_attr = 1; + pointer_type = get_attrv(var->attrs, ATTR_POINTERTYPE); + if (!pointer_type) + pointer_type = RPC_FC_RP; + in_attr = is_attr(var->attrs, ATTR_IN); + out_attr = is_attr(var->attrs, ATTR_OUT); + if (!in_attr && !out_attr) + in_attr = 1; + + if (phase != PHASE_FREE) switch (pass) { case PASS_IN: - if (!in_attr) - continue; + if (!in_attr) return; break; case PASS_OUT: - if (!out_attr) - continue; + if (!out_attr) return; break; case PASS_RETURN: break; } - while (type_has_ref(type)) - type = type->ref; + rtype = type->type; - if (is_string_type(var->attrs, var->ptr_level, var->array)) + if (is_context_handle(type)) + { + if (phase == PHASE_MARSHAL) { - if (var->array && var->array->is_const) - print_phase_function(file, indent, "NonConformantString", phase, var->name, *type_offset); + if (pass == PASS_IN) + { + print_file(file, indent, "NdrClientContextMarshall(\n"); + print_file(file, indent + 1, "&_StubMsg,\n"); + print_file(file, indent + 1, "(NDR_CCONTEXT)%s%s,\n", is_ptr(type) ? "*" : "", var->name); + print_file(file, indent + 1, "%s);\n", in_attr && out_attr ? "1" : "0"); + } else { - if (size_is && is_size_needed_for_phase(phase)) - { - print_file(file, indent, "_StubMsg.MaxCount = (unsigned long)"); - write_expr(file, size_is, 1); - fprintf(file, ";\n"); - } - - if ((phase == PHASE_FREE) || (pointer_type == RPC_FC_UP)) - print_phase_function(file, indent, "Pointer", phase, var->name, *type_offset); - else - print_phase_function(file, indent, "ConformantString", phase, var->name, - *type_offset + (has_size ? 4 : 2)); + print_file(file, indent, "NdrServerContextMarshall(\n"); + print_file(file, indent + 1, "&_StubMsg,\n"); + print_file(file, indent + 1, "(NDR_SCONTEXT)%s,\n", var->name); + print_file(file, indent + 1, "(NDR_RUNDOWN)%s_rundown);\n", get_context_handle_type_name(var->type)); } } - else if (is_array_type(var->attrs, var->ptr_level, var->array)) + else if (phase == PHASE_UNMARSHAL) { - const char *array_type; - - if (var->array && NEXT_LINK(var->array)) /* multi-dimensional array */ - array_type = "ComplexArray"; - else + if (pass == PASS_OUT) { - if (!has_length && !has_size) - array_type = "FixedArray"; - else if (has_length && !has_size) - { - if (is_size_needed_for_phase(phase)) - { - print_file(file, indent, "_StubMsg.Offset = (unsigned long)0;\n"); /* FIXME */ - print_file(file, indent, "_StubMsg.ActualCount = (unsigned long)"); - write_expr(file, length_is, 1); - fprintf(file, ";\n\n"); - } - array_type = "VaryingArray"; - } - else if (!has_length && has_size) - { - if (is_size_needed_for_phase(phase) && phase != PHASE_FREE) - { - print_file(file, indent, "_StubMsg.MaxCount = (unsigned long)"); - write_expr(file, size_is ? size_is : var->array, 1); - fprintf(file, ";\n\n"); - } - array_type = "ConformantArray"; - } - else - { - if (is_size_needed_for_phase(phase)) - { - print_file(file, indent, "_StubMsg.MaxCount = (unsigned long)"); - write_expr(file, size_is ? size_is : var->array, 1); - fprintf(file, ";\n"); - print_file(file, indent, "_StubMsg.Offset = (unsigned long)0;\n"); /* FIXME */ - print_file(file, indent, "_StubMsg.ActualCount = (unsigned long)"); - write_expr(file, length_is, 1); - fprintf(file, ";\n\n"); - } - array_type = "ConformantVaryingArray"; - } + print_file(file, indent, "NdrClientContextUnmarshall(\n"); + print_file(file, indent + 1, "&_StubMsg,\n"); + print_file(file, indent + 1, "(NDR_CCONTEXT *)%s,\n", var->name); + print_file(file, indent + 1, "_Handle);\n"); + } + else + print_file(file, indent, "%s = NdrServerContextUnmarshall(&_StubMsg);\n", var->name); + } + } + else if (is_user_type(var->type)) + { + print_phase_function(file, indent, "UserMarshal", phase, var, start_offset); + } + else if (is_string_type(var->attrs, var->type)) + { + if (is_array(type) && !is_conformant_array(type)) + print_phase_function(file, indent, "NonConformantString", phase, var, start_offset); + else + { + if (type->size_is && is_size_needed_for_phase(phase)) + { + print_file(file, indent, "_StubMsg.MaxCount = (unsigned long)"); + write_expr(file, type->size_is, 1); + fprintf(file, ";\n"); } - if (!in_attr && phase == PHASE_FREE) + if ((phase == PHASE_FREE) || (pointer_type == RPC_FC_UP)) + print_phase_function(file, indent, "Pointer", phase, var, start_offset); + else + print_phase_function(file, indent, "ConformantString", phase, var, + start_offset + (type->size_is ? 4 : 2)); + } + } + else if (is_array(type)) + { + unsigned char tc = type->type; + const char *array_type = "FixedArray"; + + /* We already have the size_is expression since it's at the + top level, but do checks for multidimensional conformant + arrays. When we handle them, we'll need to extend this + function to return a list, and then we'll actually use + the return value. */ + get_size_is_expr(type, var->name); + + if (tc == RPC_FC_SMVARRAY || tc == RPC_FC_LGVARRAY) + { + if (is_size_needed_for_phase(phase)) + { + print_file(file, indent, "_StubMsg.Offset = (unsigned long)0;\n"); /* FIXME */ + print_file(file, indent, "_StubMsg.ActualCount = (unsigned long)"); + write_expr(file, type->length_is, 1); + fprintf(file, ";\n\n"); + } + array_type = "VaryingArray"; + } + else if (tc == RPC_FC_CARRAY) + { + if (is_size_needed_for_phase(phase)) + { + print_file(file, indent, "_StubMsg.MaxCount = (unsigned long)"); + write_expr(file, type->size_is, 1); + fprintf(file, ";\n\n"); + } + array_type = "ConformantArray"; + } + else if (tc == RPC_FC_CVARRAY || tc == RPC_FC_BOGUS_ARRAY) + { + if (is_size_needed_for_phase(phase)) + { + if (type->size_is) + { + print_file(file, indent, "_StubMsg.MaxCount = (unsigned long)"); + write_expr(file, type->size_is, 1); + fprintf(file, ";\n"); + } + if (type->length_is) + { + print_file(file, indent, "_StubMsg.Offset = (unsigned long)0;\n"); /* FIXME */ + print_file(file, indent, "_StubMsg.ActualCount = (unsigned long)"); + write_expr(file, type->length_is, 1); + fprintf(file, ";\n\n"); + } + } + array_type = (tc == RPC_FC_BOGUS_ARRAY + ? "ComplexArray" + : "ConformantVaryingArray"); + } + + if (pointer_type != RPC_FC_RP) array_type = "Pointer"; + print_phase_function(file, indent, array_type, phase, var, start_offset); + if (phase == PHASE_FREE && type->declarray && pointer_type == RPC_FC_RP) + { + /* these are all unmarshalled by pointing into the buffer on the + * server side */ + if (type->type == RPC_FC_BOGUS_ARRAY || + type->type == RPC_FC_CVARRAY || + (type->type == RPC_FC_SMVARRAY && type->type == RPC_FC_LGVARRAY && in_attr) || + (type->type == RPC_FC_CARRAY && type->type == RPC_FC_CARRAY && !in_attr)) { print_file(file, indent, "if (%s)\n", var->name); indent++; print_file(file, indent, "_StubMsg.pfnFree(%s);\n", var->name); } - else if (phase != PHASE_FREE) - { - if (pointer_type == RPC_FC_UP) - print_phase_function(file, indent, "Pointer", phase, var->name, *type_offset); - else - print_phase_function(file, indent, array_type, phase, var->name, *type_offset + 4); - } } - else if (var->ptr_level == 0 && is_base_type(type->type)) - { + } + else if (!is_ptr(var->type) && is_base_type(rtype)) + { + if (phase != PHASE_FREE) print_phase_basetype(file, indent, phase, pass, var, var->name); - } - else if (var->ptr_level == 0) + } + else if (!is_ptr(var->type)) + { + switch (rtype) { - const char *ndrtype; - - switch (type->type) - { - case RPC_FC_STRUCT: - ndrtype = "SimpleStruct"; - break; - case RPC_FC_CSTRUCT: - case RPC_FC_CPSTRUCT: - ndrtype = "ConformantStruct"; - break; - case RPC_FC_CVSTRUCT: - ndrtype = "ConformantVaryingStruct"; - break; - case RPC_FC_BOGUS_STRUCT: - ndrtype = "ComplexStruct"; - break; - default: - error("write_remoting_arguments: Unsupported type: %s (0x%02x, ptr_level: %d)\n", - var->name, type->type, var->ptr_level); - ndrtype = NULL; - } - - print_phase_function(file, indent, ndrtype, phase, var->name, *type_offset); - } - else - { - if ((var->ptr_level == 1) && (pointer_type == RPC_FC_RP) && is_base_type(type->type)) + case RPC_FC_STRUCT: + case RPC_FC_PSTRUCT: + print_phase_function(file, indent, "SimpleStruct", phase, var, start_offset); + break; + case RPC_FC_CSTRUCT: + case RPC_FC_CPSTRUCT: + print_phase_function(file, indent, "ConformantStruct", phase, var, start_offset); + break; + case RPC_FC_CVSTRUCT: + print_phase_function(file, indent, "ConformantVaryingStruct", phase, var, start_offset); + break; + case RPC_FC_BOGUS_STRUCT: + print_phase_function(file, indent, "ComplexStruct", phase, var, start_offset); + break; + case RPC_FC_RP: + if (is_base_type( var->type->ref->type )) { print_phase_basetype(file, indent, phase, pass, var, var->name); } - else if ((var->ptr_level == 1) && (pointer_type == RPC_FC_RP) && (type->type == RPC_FC_STRUCT)) + else if (var->type->ref->type == RPC_FC_STRUCT) { if (phase != PHASE_BUFFERSIZE && phase != PHASE_FREE) - print_phase_function(file, indent, "SimpleStruct", phase, var->name, *type_offset + 4); + print_phase_function(file, indent, "SimpleStruct", phase, var, start_offset + 4); } else { - print_phase_function(file, indent, "Pointer", phase, var->name, *type_offset); + expr_t *iid; + if ((iid = get_attrp( var->attrs, ATTR_IIDIS ))) + { + print_file( file, indent, "_StubMsg.MaxCount = (unsigned long) " ); + write_expr( file, iid, 1 ); + fprintf( file, ";\n\n" ); + } + print_phase_function(file, indent, "Pointer", phase, var, start_offset); } + break; + default: + error("write_remoting_arguments: Unsupported type: %s (0x%02x)\n", var->name, rtype); } - fprintf(file, "\n"); + } + else + { + if (last_ptr(var->type) && (pointer_type == RPC_FC_RP) && is_base_type(rtype)) + { + if (phase != PHASE_FREE) + print_phase_basetype(file, indent, phase, pass, var, var->name); + } + else if (last_ptr(var->type) && (pointer_type == RPC_FC_RP) && (rtype == RPC_FC_STRUCT)) + { + if (phase != PHASE_BUFFERSIZE && phase != PHASE_FREE) + print_phase_function(file, indent, "SimpleStruct", phase, var, start_offset + 4); + } + else + { + expr_t *iid; + expr_t *sx = get_size_is_expr(type, var->name); + + if ((iid = get_attrp( var->attrs, ATTR_IIDIS ))) + { + print_file( file, indent, "_StubMsg.MaxCount = (unsigned long) " ); + write_expr( file, iid, 1 ); + fprintf( file, ";\n\n" ); + } + else if (sx) + { + print_file(file, indent, "_StubMsg.MaxCount = (unsigned long) "); + write_expr(file, sx, 1); + fprintf(file, ";\n\n"); + } + if (var->type->ref->type == RPC_FC_IP) + print_phase_function(file, indent, "InterfacePointer", phase, var, start_offset); + else + print_phase_function(file, indent, "Pointer", phase, var, start_offset); + } + } + fprintf(file, "\n"); +} + +void write_remoting_arguments(FILE *file, int indent, const func_t *func, + enum pass pass, enum remoting_phase phase) +{ + if (phase == PHASE_BUFFERSIZE && pass != PASS_RETURN) + { + unsigned int size = get_function_buffer_size( func, pass ); + print_file(file, indent, "_StubMsg.BufferLength = %u;\n", size); + } + + if (pass == PASS_RETURN) + { + var_t var; + var = *func->def; + var.name = xstrdup( "_RetVal" ); + write_remoting_arg( file, indent, func, pass, phase, &var ); + free( var.name ); + } + else + { + const var_t *var; + if (!func->args) + return; + LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) + write_remoting_arg( file, indent, func, pass, phase, var ); } } size_t get_size_procformatstring_var(const var_t *var) { - unsigned int type_offset = 2; - return write_procformatstring_var(NULL, 0, var, FALSE, &type_offset); + return write_procformatstring_var(NULL, 0, var, FALSE); } -size_t get_size_typeformatstring_var(const var_t *var) +size_t get_size_procformatstring_func(const func_t *func) { - unsigned int type_offset = 0; - write_typeformatstring_var(NULL, 0, var, &type_offset); - return type_offset; + const var_t *var; + size_t size = 0; + + /* argument list size */ + if (func->args) + LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) + size += get_size_procformatstring_var(var); + + /* return value size */ + if (is_void(func->def->type)) + size += 2; /* FC_END and FC_PAD */ + else + size += get_size_procformatstring_var(func->def); + + return size; } -size_t get_size_procformatstring(const ifref_t *ifaces) +size_t get_size_procformatstring(const ifref_list_t *ifaces, type_pred_t pred) { - const ifref_t *iface = ifaces; + const ifref_t *iface; size_t size = 1; - func_t *func; - var_t *var; + const func_t *func; - END_OF_LIST(iface); - - for (; iface; iface = PREV_LINK(iface)) + if (ifaces) LIST_FOR_EACH_ENTRY( iface, ifaces, const ifref_t, entry ) { - if (is_object(iface->iface->attrs) || is_local(iface->iface->attrs)) + if (!pred(iface->iface)) continue; if (iface->iface->funcs) - { - func = iface->iface->funcs; - while (NEXT_LINK(func)) func = NEXT_LINK(func); - while (func) - { - /* argument list size */ - if (func->args) - { - var = func->args; - while (NEXT_LINK(var)) var = NEXT_LINK(var); - while (var) - { - size += get_size_procformatstring_var(var); - var = PREV_LINK(var); - } - } - - var = func->def; - /* return value size */ - if (is_void(var->type, NULL)) - size += 2; - else - size += get_size_procformatstring_var(var); - - func = PREV_LINK(func); - } - } + LIST_FOR_EACH_ENTRY( func, iface->iface->funcs, const func_t, entry ) + if (!is_local(func->def->attrs)) + size += get_size_procformatstring_func( func ); } return size; } -size_t get_size_typeformatstring(const ifref_t *ifaces) +size_t get_size_typeformatstring(const ifref_list_t *ifaces, type_pred_t pred) { - const ifref_t *iface = ifaces; - size_t size = 3; - func_t *func; - var_t *var; - - END_OF_LIST(iface); - - for (; iface; iface = PREV_LINK(iface)) - { - if (is_object(iface->iface->attrs) || is_local(iface->iface->attrs)) - continue; - - if (iface->iface->funcs) - { - func = iface->iface->funcs; - while (NEXT_LINK(func)) func = NEXT_LINK(func); - while (func) - { - /* argument list size */ - if (func->args) - { - var = func->args; - while (NEXT_LINK(var)) var = NEXT_LINK(var); - while (var) - { - size += get_size_typeformatstring_var(var); - var = PREV_LINK(var); - } - } - - func = PREV_LINK(func); - } - } - } - return size; + set_all_tfswrite(FALSE); + return process_tfs(NULL, ifaces, pred); } static void write_struct_expr(FILE *h, const expr_t *e, int brackets, - const var_t *fields, const char *structvar) + const var_list_t *fields, const char *structvar) { switch (e->type) { case EXPR_VOID: break; case EXPR_NUM: - fprintf(h, "%ld", e->u.lval); + fprintf(h, "%lu", e->u.lval); break; case EXPR_HEXNUM: fprintf(h, "0x%lx", e->u.lval); break; + case EXPR_DOUBLE: + fprintf(h, "%#.15g", e->u.dval); + break; case EXPR_TRUEFALSE: if (e->u.lval == 0) fprintf(h, "FALSE"); @@ -1968,15 +3011,14 @@ static void write_struct_expr(FILE *h, const expr_t *e, int brackets, case EXPR_IDENTIFIER: { const var_t *field; - for (field = fields; field; field = NEXT_LINK(field)) - { + LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry ) if (!strcmp(e->u.sval, field->name)) { fprintf(h, "%s->%s", structvar, e->u.sval); break; } - } - if (!field) error("no field found for identifier %s\n", e->u.sval); + + if (&field->entry == fields) error("no field found for identifier %s\n", e->u.sval); break; } case EXPR_NEG: @@ -1993,13 +3035,13 @@ static void write_struct_expr(FILE *h, const expr_t *e, int brackets, break; case EXPR_CAST: fprintf(h, "("); - write_type(h, e->u.tref->ref, NULL, e->u.tref->name); + write_type_decl(h, e->u.tref, NULL); fprintf(h, ")"); write_struct_expr(h, e->ref, 1, fields, structvar); break; case EXPR_SIZEOF: fprintf(h, "sizeof("); - write_type(h, e->u.tref->ref, NULL, e->u.tref->name); + write_type_decl(h, e->u.tref, NULL); fprintf(h, ")"); break; case EXPR_SHL: @@ -2035,32 +3077,155 @@ static void write_struct_expr(FILE *h, const expr_t *e, int brackets, write_struct_expr(h, e->ext2, 1, fields, structvar); if (brackets) fprintf(h, ")"); break; + case EXPR_ADDRESSOF: + fprintf(h, "&"); + write_struct_expr(h, e->ref, 1, fields, structvar); + break; } } + +void declare_stub_args( FILE *file, int indent, const func_t *func ) +{ + int in_attr, out_attr; + int i = 0; + const var_t *def = func->def; + const var_t *var; + + /* declare return value '_RetVal' */ + if (!is_void(def->type)) + { + print_file(file, indent, ""); + write_type_decl_left(file, def->type); + fprintf(file, " _RetVal;\n"); + } + + if (!func->args) + return; + + LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) + { + int is_string = is_attr(var->attrs, ATTR_STRING); + + in_attr = is_attr(var->attrs, ATTR_IN); + out_attr = is_attr(var->attrs, ATTR_OUT); + if (!out_attr && !in_attr) + in_attr = 1; + + if (is_context_handle(var->type)) + print_file(file, indent, "NDR_SCONTEXT %s;\n", var->name); + else + { + if (!in_attr && !var->type->size_is && !is_string) + { + print_file(file, indent, ""); + write_type_decl(file, var->type->declarray ? var->type : var->type->ref, + "_W%u", i++); + fprintf(file, ";\n"); + } + + print_file(file, indent, ""); + write_type_decl_left(file, var->type); + fprintf(file, " "); + if (var->type->declarray) { + fprintf(file, "( *"); + write_name(file, var); + fprintf(file, " )"); + } else + write_name(file, var); + write_type_right(file, var->type, FALSE); + fprintf(file, ";\n"); + + if (decl_indirect(var->type)) + print_file(file, indent, "void *_p_%s = &%s;\n", + var->name, var->name); + } + } +} + + +void assign_stub_out_args( FILE *file, int indent, const func_t *func ) +{ + int in_attr, out_attr; + int i = 0, sep = 0; + const var_t *var; + + if (!func->args) + return; + + LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) + { + int is_string = is_attr(var->attrs, ATTR_STRING); + in_attr = is_attr(var->attrs, ATTR_IN); + out_attr = is_attr(var->attrs, ATTR_OUT); + if (!out_attr && !in_attr) + in_attr = 1; + + if (!in_attr) + { + print_file(file, indent, ""); + write_name(file, var); + + 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; + + fprintf(file, " = NdrAllocate(&_StubMsg, "); + for ( ; type->size_is ; type = type->ref) + { + write_expr(file, type->size_is, TRUE); + fprintf(file, " * "); + } + size = type_memsize(type, &align); + fprintf(file, "%u);\n", size); + } + else if (!is_string) + { + fprintf(file, " = &_W%u;\n", i); + if (is_ptr(var->type) && !last_ptr(var->type)) + print_file(file, indent, "_W%u = 0;\n", i); + i++; + } + + sep = 1; + } + } + if (sep) + fprintf(file, "\n"); +} + + int write_expr_eval_routines(FILE *file, const char *iface) { + static const char *var_name = "pS"; int result = 0; struct expr_eval_routine *eval; unsigned short callback_offset = 0; LIST_FOR_EACH_ENTRY(eval, &expr_eval_routines, struct expr_eval_routine, entry) { - int indent = 0; + const char *name = eval->structure->name; + const var_list_t *fields = eval->structure->fields; result = 1; - print_file(file, indent, "static void __RPC_USER %s_%sExprEval_%04u(PMIDL_STUB_MESSAGE pStubMsg)\n", - iface, eval->structure->name, callback_offset); - print_file(file, indent, "{\n"); - indent++; - print_file(file, indent, "struct %s *" STRUCT_EXPR_EVAL_VAR " = (struct %s *)(pStubMsg->StackTop - %u);\n", - eval->structure->name, eval->structure->name, eval->structure_size); - fprintf(file, "\n"); - print_file(file, indent, "pStubMsg->Offset = 0;\n"); /* FIXME */ - print_file(file, indent, "pStubMsg->MaxCount = (unsigned long)"); - write_struct_expr(file, eval->expr, 1, eval->structure->fields, STRUCT_EXPR_EVAL_VAR); + + print_file(file, 0, "static void __RPC_USER %s_%sExprEval_%04u(PMIDL_STUB_MESSAGE pStubMsg)\n", + iface, name, callback_offset); + print_file(file, 0, "{\n"); + print_file (file, 1, "%s *%s = (%s *)(pStubMsg->StackTop - %u);\n", + name, var_name, name, eval->baseoff); + print_file(file, 1, "pStubMsg->Offset = 0;\n"); /* FIXME */ + print_file(file, 1, "pStubMsg->MaxCount = (unsigned long)"); + write_struct_expr(file, eval->expr, 1, fields, var_name); fprintf(file, ";\n"); - indent--; - print_file(file, indent, "}\n\n"); + print_file(file, 0, "}\n\n"); callback_offset++; } return result; @@ -2077,9 +3242,8 @@ void write_expr_eval_routine_list(FILE *file, const char *iface) LIST_FOR_EACH_ENTRY_SAFE(eval, cursor, &expr_eval_routines, struct expr_eval_routine, entry) { - print_file(file, 1, "%s_%sExprEval_%04u,\n", - iface, eval->structure->name, callback_offset); - + const char *name = eval->structure->name; + print_file(file, 1, "%s_%sExprEval_%04u,\n", iface, name, callback_offset); callback_offset++; list_remove(&eval->entry); free(eval); @@ -2087,3 +3251,59 @@ void write_expr_eval_routine_list(FILE *file, const char *iface) fprintf(file, "};\n\n"); } + +void write_user_quad_list(FILE *file) +{ + user_type_t *ut; + + if (list_empty(&user_type_list)) + return; + + fprintf(file, "static const USER_MARSHAL_ROUTINE_QUADRUPLE UserMarshalRoutines[] =\n"); + fprintf(file, "{\n"); + LIST_FOR_EACH_ENTRY(ut, &user_type_list, user_type_t, entry) + { + const char *sep = &ut->entry == list_tail(&user_type_list) ? "" : ","; + print_file(file, 1, "{\n"); + print_file(file, 2, "(USER_MARSHAL_SIZING_ROUTINE)%s_UserSize,\n", ut->name); + print_file(file, 2, "(USER_MARSHAL_MARSHALLING_ROUTINE)%s_UserMarshal,\n", ut->name); + print_file(file, 2, "(USER_MARSHAL_UNMARSHALLING_ROUTINE)%s_UserUnmarshal,\n", ut->name); + print_file(file, 2, "(USER_MARSHAL_FREEING_ROUTINE)%s_UserFree\n", ut->name); + print_file(file, 1, "}%s\n", sep); + } + fprintf(file, "};\n\n"); +} + +void write_endpoints( FILE *f, const char *prefix, const str_list_t *list ) +{ + const struct str_list_entry_t *endpoint; + const char *p; + + /* this should be an array of RPC_PROTSEQ_ENDPOINT but we want const strings */ + print_file( f, 0, "static const unsigned char * %s__RpcProtseqEndpoint[][2] =\n{\n", prefix ); + LIST_FOR_EACH_ENTRY( endpoint, list, const struct str_list_entry_t, entry ) + { + print_file( f, 1, "{ (const unsigned char *)\"" ); + for (p = endpoint->str; *p && *p != ':'; p++) + { + if (*p == '"' || *p == '\\') fputc( '\\', f ); + fputc( *p, f ); + } + if (!*p) goto error; + if (p[1] != '[') goto error; + + fprintf( f, "\", (const unsigned char *)\"" ); + for (p += 2; *p && *p != ']'; p++) + { + if (*p == '"' || *p == '\\') fputc( '\\', f ); + fputc( *p, f ); + } + if (*p != ']') goto error; + fprintf( f, "\" },\n" ); + } + print_file( f, 0, "};\n\n" ); + return; + +error: + error("Invalid endpoint syntax '%s'\n", endpoint->str); +} diff --git a/reactos/tools/widl/typegen.h b/reactos/tools/widl/typegen.h index eb4c4c7689b..c9a5148290f 100644 --- a/reactos/tools/widl/typegen.h +++ b/reactos/tools/widl/typegen.h @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include enum pass { @@ -35,15 +36,27 @@ enum remoting_phase PHASE_FREE }; -void write_procformatstring(FILE *file, const ifref_t *ifaces); -void write_typeformatstring(FILE *file, const ifref_t *ifaces); -size_t get_type_memsize(const type_t *type); -unsigned int get_required_buffer_size(const var_t *var, unsigned int *alignment, enum pass pass); +typedef int (*type_pred_t)(const type_t *); + +void write_formatstringsdecl(FILE *f, int indent, ifref_list_t *ifaces, type_pred_t pred); +void write_procformatstring(FILE *file, const ifref_list_t *ifaces, type_pred_t pred); +void write_typeformatstring(FILE *file, const ifref_list_t *ifaces, type_pred_t pred); void print_phase_basetype(FILE *file, int indent, enum remoting_phase phase, enum pass pass, const var_t *var, const char *varname); -void write_remoting_arguments(FILE *file, int indent, const func_t *func, unsigned int *type_offset, enum pass pass, enum remoting_phase phase); +void write_remoting_arguments(FILE *file, int indent, const func_t *func, enum pass pass, enum remoting_phase phase); size_t get_size_procformatstring_var(const var_t *var); -size_t get_size_typeformatstring_var(const var_t *var); -size_t get_size_procformatstring(const ifref_t *ifaces); -size_t get_size_typeformatstring(const ifref_t *ifaces); +size_t get_size_procformatstring_func(const func_t *func); +size_t get_size_procformatstring(const ifref_list_t *ifaces, type_pred_t pred); +size_t get_size_typeformatstring(const ifref_list_t *ifaces, type_pred_t pred); +void assign_stub_out_args( FILE *file, int indent, const func_t *func ); +void declare_stub_args( FILE *file, int indent, const func_t *func ); int write_expr_eval_routines(FILE *file, const char *iface); void write_expr_eval_routine_list(FILE *file, const char *iface); +void write_user_quad_list(FILE *file); +void write_endpoints( FILE *f, const char *prefix, const str_list_t *list ); +size_t type_memsize(const type_t *t, unsigned int *align); +int decl_indirect(const type_t *t); +void write_parameters_init(FILE *file, int indent, const func_t *func); +void print(FILE *file, int indent, const char *format, va_list ap); +int get_padding(const var_list_t *fields); +int is_user_type(const type_t *t); +expr_t *get_size_is_expr(const type_t *t, const char *name); diff --git a/reactos/tools/widl/typelib.c b/reactos/tools/widl/typelib.c index 7ac2594c64e..7130e506d77 100644 --- a/reactos/tools/widl/typelib.c +++ b/reactos/tools/widl/typelib.c @@ -35,6 +35,9 @@ #define NONAMELESSUNION #define NONAMELESSSTRUCT +#include "windef.h" +#include "winbase.h" + #include "widl.h" #include "utils.h" #include "parser.h" @@ -47,10 +50,60 @@ int in_typelib = 0; static typelib_t *typelib; +type_t *duptype(type_t *t, int dupname) +{ + type_t *d = alloc_type(); + + *d = *t; + if (dupname && t->name) + d->name = xstrdup(t->name); + + d->orig = t; + return d; +} + +type_t *alias(type_t *t, const char *name) +{ + type_t *a = duptype(t, 0); + + a->name = xstrdup(name); + a->kind = TKIND_ALIAS; + a->attrs = NULL; + a->declarray = FALSE; + + return a; +} + +int is_ptr(const type_t *t) +{ + unsigned char c = t->type; + return c == RPC_FC_RP + || c == RPC_FC_UP + || c == RPC_FC_FP + || c == RPC_FC_OP; +} + +int is_array(const type_t *t) +{ + switch (t->type) + { + case RPC_FC_SMFARRAY: + case RPC_FC_LGFARRAY: + case RPC_FC_SMVARRAY: + case RPC_FC_LGVARRAY: + case RPC_FC_CARRAY: + case RPC_FC_CVARRAY: + case RPC_FC_BOGUS_ARRAY: + return TRUE; + default: + return FALSE; + } +} + /* List of oleauto types that should be recognized by name. * (most of) these seem to be intrinsic types in mktyplib. */ -static struct oatype { +static const struct oatype { const char *kw; unsigned short vt; } oatypes[] = { @@ -73,9 +126,11 @@ static int kw_cmp_func(const void *s1, const void *s2) return strcmp(KWP(s1)->kw, KWP(s2)->kw); } -static unsigned short builtin_vt(const char *kw) +static unsigned short builtin_vt(const type_t *t) { - struct oatype key, *kwp; + const char *kw = t->name; + struct oatype key; + const struct oatype *kwp; key.kw = kw; #ifdef KW_BSEARCH kwp = bsearch(&key, oatypes, NTYPES, sizeof(oatypes[0]), kw_cmp_func); @@ -92,6 +147,13 @@ static unsigned short builtin_vt(const char *kw) if (kwp) { return kwp->vt; } + if (is_string_type (t->attrs, t)) + switch (t->ref->type) + { + case RPC_FC_CHAR: return VT_LPSTR; + case RPC_FC_WCHAR: return VT_LPWSTR; + default: break; + } return 0; } @@ -107,10 +169,13 @@ unsigned short get_type_vt(type_t *t) chat("get_type_vt: %p type->name %s\n", t, t->name); if (t->name) { - vt = builtin_vt(t->name); + vt = builtin_vt(t); if (vt) return vt; } + if (t->kind == TKIND_ALIAS && t->attrs) + return VT_USERDEFINED; + switch (t->type) { case RPC_FC_BYTE: case RPC_FC_USMALL: @@ -125,14 +190,14 @@ unsigned short get_type_vt(type_t *t) case RPC_FC_USHORT: return VT_UI2; case RPC_FC_LONG: - if (t->ref && match(t->ref->name, "int")) return VT_INT; + if (match(t->name, "int")) return VT_INT; return VT_I4; case RPC_FC_ULONG: - if (t->ref && match(t->ref->name, "int")) return VT_UINT; + if (match(t->name, "int")) return VT_UINT; return VT_UI4; case RPC_FC_HYPER: if (t->sign < 0) return VT_UI8; - if (t->ref && match(t->ref->name, "MIDL_uhyper")) return VT_UI8; + if (match(t->name, "MIDL_uhyper")) return VT_UI8; return VT_I8; case RPC_FC_FLOAT: return VT_R4; @@ -142,8 +207,14 @@ unsigned short get_type_vt(type_t *t) case RPC_FC_UP: case RPC_FC_OP: case RPC_FC_FP: + case RPC_FC_CARRAY: + case RPC_FC_CVARRAY: if(t->ref) + { + if (match(t->ref->name, "SAFEARRAY")) + return VT_SAFEARRAY; return VT_PTR; + } error("get_type_vt: unknown-deref-type: %d\n", t->ref->type); break; @@ -163,29 +234,14 @@ unsigned short get_type_vt(type_t *t) case RPC_FC_BOGUS_STRUCT: return VT_USERDEFINED; case 0: - if(t->attrs) - return VT_USERDEFINED; - return 0; + return t->kind == TKIND_PRIMITIVE ? VT_VOID : VT_USERDEFINED; default: error("get_type_vt: unknown type: 0x%02x\n", t->type); } return 0; } -unsigned short get_var_vt(var_t *v) -{ - unsigned short vt; - - chat("get_var_vt: %p tname %s\n", v, v->tname); - if (v->tname) { - vt = builtin_vt(v->tname); - if (vt) return vt; - } - - return get_type_vt(v->type); -} - -void start_typelib(char *name, attr_t *attrs) +void start_typelib(char *name, attr_list_t *attrs) { in_typelib++; if (!do_typelib) return; @@ -194,6 +250,11 @@ void start_typelib(char *name, attr_t *attrs) typelib->name = xstrdup(name); typelib->filename = xstrdup(typelib_name); typelib->attrs = attrs; + list_init( &typelib->entries ); + list_init( &typelib->importlibs ); + + if (is_attr(attrs, ATTR_POINTERDEFAULT)) + pointer_default = get_attrv(attrs, ATTR_POINTERDEFAULT); } void end_typelib(void) @@ -202,93 +263,22 @@ void end_typelib(void) if (!typelib) return; create_msft_typelib(typelib); + pointer_default = RPC_FC_UP; return; } -void add_interface(type_t *iface) +void add_typelib_entry(type_t *t) { typelib_entry_t *entry; if (!typelib) return; - chat("add interface: %s\n", iface->name); + chat("add kind %i: %s\n", t->kind, t->name); entry = xmalloc(sizeof(*entry)); - entry->kind = TKIND_INTERFACE; - entry->u.interface = iface; - LINK(entry, typelib->entry); - typelib->entry = entry; + entry->type = t; + list_add_tail( &typelib->entries, &entry->entry ); } -void add_coclass(type_t *cls) -{ - typelib_entry_t *entry; - - if (!typelib) return; - - chat("add coclass: %s\n", cls->name); - - entry = xmalloc(sizeof(*entry)); - entry->kind = TKIND_COCLASS; - entry->u.class = cls; - LINK(entry, typelib->entry); - typelib->entry = entry; -} - -void add_module(type_t *module) -{ - typelib_entry_t *entry; - if (!typelib) return; - - chat("add module: %s\n", module->name); - entry = xmalloc(sizeof(*entry)); - entry->kind = TKIND_MODULE; - entry->u.module = module; - LINK(entry, typelib->entry); - typelib->entry = entry; -} - -void add_struct(type_t *structure) -{ - typelib_entry_t *entry; - if (!typelib) return; - - chat("add struct: %s\n", structure->name); - entry = xmalloc(sizeof(*entry)); - entry->kind = TKIND_RECORD; - entry->u.structure = structure; - LINK(entry, typelib->entry); - typelib->entry = entry; -} - -void add_enum(type_t *enumeration) -{ - typelib_entry_t *entry; - if (!typelib) return; - - chat("add enum: %s\n", enumeration->name); - entry = xmalloc(sizeof(*entry)); - entry->kind = TKIND_ENUM; - entry->u.enumeration = enumeration; - LINK(entry, typelib->entry); - typelib->entry = entry; -} - -void add_typedef(type_t *tdef, var_t *name) -{ - typelib_entry_t *entry; - if (!typelib) return; - - chat("add typedef: %s\n", name->name); - entry = xmalloc(sizeof(*entry)); - entry->kind = TKIND_ALIAS; - entry->u.tdef = xmalloc(sizeof(*entry->u.tdef)); - memcpy(entry->u.tdef, name, sizeof(*name)); - entry->u.tdef->type = tdef; - entry->u.tdef->name = xstrdup(name->name); - LINK(entry, typelib->entry); - typelib->entry = entry; -} - -static void tlb_read(int fd, void *buf, size_t count) +static void tlb_read(int fd, void *buf, int count) { if(read(fd, buf, count) < count) error("error while reading importlib.\n"); @@ -347,6 +337,7 @@ static void read_msft_importlib(importlib_t *importlib, int fd) importlib->importinfos[i].flags |= MSFT_IMPINFO_OFFSET_IS_GUID; msft_read_guid(fd, &segdir, base.posguid, &importlib->importinfos[i].guid); } + else memset( &importlib->importinfos[i].guid, 0, sizeof(importlib->importinfos[i].guid)); tlb_lseek(fd, segdir.pNametab.offset + base.NameOffset); tlb_read(fd, &nameintro, sizeof(nameintro)); @@ -397,18 +388,16 @@ void add_importlib(const char *name) if(!typelib) return; - for(importlib = typelib->importlibs; importlib; importlib = NEXT_LINK(importlib)) { + LIST_FOR_EACH_ENTRY( importlib, &typelib->importlibs, importlib_t, entry ) if(!strcmp(name, importlib->name)) return; - } chat("add_importlib: %s\n", name); importlib = xmalloc(sizeof(*importlib)); + memset( importlib, 0, sizeof(*importlib) ); importlib->name = xstrdup(name); read_importlib(importlib); - - LINK(importlib, typelib->importlibs); - typelib->importlibs = importlib; + list_add_head( &typelib->importlibs, &importlib->entry ); } diff --git a/reactos/tools/widl/typelib.h b/reactos/tools/widl/typelib.h index 9fb5bdd9345..b17387dfc39 100644 --- a/reactos/tools/widl/typelib.h +++ b/reactos/tools/widl/typelib.h @@ -22,14 +22,9 @@ #define __WIDL_TYPELIB_H extern int in_typelib; -extern void start_typelib(char *name, attr_t *attrs); +extern void start_typelib(char *name, attr_list_t *attrs); extern void end_typelib(void); -extern void add_interface(type_t *iface); -extern void add_coclass(type_t *cls); -extern void add_module(type_t *module); -extern void add_struct(type_t *structure); -extern void add_enum(type_t *enumeration); -extern void add_typedef(type_t *tdef, var_t *name); +extern void add_typelib_entry(type_t *t); extern void add_importlib(const char *name); /* Copied from wtypes.h. Not included directly because that would create a @@ -87,7 +82,6 @@ enum VARENUM { VT_TYPEMASK = 0xfff }; extern unsigned short get_type_vt(type_t *t); -extern unsigned short get_var_vt(var_t *v); extern int create_msft_typelib(typelib_t *typelib); #endif diff --git a/reactos/tools/widl/typelib_struct.h b/reactos/tools/widl/typelib_struct.h index 34c3231c112..e16387c8dcd 100644 --- a/reactos/tools/widl/typelib_struct.h +++ b/reactos/tools/widl/typelib_struct.h @@ -148,7 +148,7 @@ typedef struct tagMSFT_TypeInfoBase { /*050*/ INT size; /* size in bytes, at least for structures */ /* FIXME: name of this field */ INT datatype1; /* position in type description table */ - /* or in base intefaces */ + /* or in base interfaces */ /* if coclass: offset in reftable */ /* if interface: reference to inherited if */ INT datatype2; /* for interfaces: hiword is num of inherited funcs */ @@ -286,7 +286,7 @@ typedef struct { /* 0x3800 if name is typeinfo name */ /* upper 16 bits are hash code */ } MSFT_NameIntro; -/* the custom data table directory has enties like this */ +/* the custom data table directory has entries like this */ typedef struct { INT GuidOffset; INT DataOffset; @@ -302,7 +302,7 @@ typedef struct { * */ -#include +#include "pshpack1.h" typedef struct { /*00*/ DWORD SLTG_magic; /* 0x47544c53 == "SLTG" */ @@ -599,7 +599,7 @@ WORD offset from start of block to SAFEARRAY WORD typeofarray */ -#include +#include "poppack.h" /*---------------------------END--------------------------------------------*/ #endif diff --git a/reactos/tools/widl/utils.c b/reactos/tools/widl/utils.c index 9f82184cd94..e77361ce339 100644 --- a/reactos/tools/widl/utils.c +++ b/reactos/tools/widl/utils.c @@ -27,17 +27,15 @@ #include #include #include -#include #include #include "widl.h" #include "utils.h" #include "parser.h" -/* #define WANT_NEAR_INDICATION */ +static const int want_near_indication = 0; -#ifdef WANT_NEAR_INDICATION -void make_print(char *str) +static void make_print(char *str) { while(*str) { @@ -46,13 +44,13 @@ void make_print(char *str) str++; } } -#endif static void generic_msg(const char *s, const char *t, const char *n, va_list ap) { fprintf(stderr, "%s:%d: %s: ", input_name ? input_name : "stdin", line_number, t); vfprintf(stderr, s, ap); -#ifdef WANT_NEAR_INDICATION + + if (want_near_indication) { char *cpy; if(n) @@ -63,38 +61,37 @@ static void generic_msg(const char *s, const char *t, const char *n, va_list ap) free(cpy); } } -#endif - fprintf(stderr, "\n"); } -int yyerror(const char *s, ...) +/* yyerror: yacc assumes this is not newline terminated. */ +int parser_error(const char *s, ...) { va_list ap; va_start(ap, s); - generic_msg(s, "Error", yytext, ap); + generic_msg(s, "Error", parser_text, ap); + fprintf(stderr, "\n"); va_end(ap); exit(1); return 1; } -int yywarning(const char *s, ...) +void error_loc(const char *s, ...) { va_list ap; va_start(ap, s); - generic_msg(s, "Warning", yytext, ap); + generic_msg(s, "Error", parser_text, ap); va_end(ap); - return 0; + exit(1); } -void internal_error(const char *file, int line, const char *s, ...) +int parser_warning(const char *s, ...) { va_list ap; va_start(ap, s); - fprintf(stderr, "Internal error (please report) %s %d: ", file, line); - vfprintf(stderr, s, ap); + generic_msg(s, "Warning", parser_text, ap); va_end(ap); - exit(3); + return 0; } void error(const char *s, ...) @@ -145,7 +142,7 @@ char *dup_basename(const char *name, const char *ext) namelen = strlen(name); /* +4 for later extension and +1 for '\0' */ - base = (char *)xmalloc(namelen +4 +1); + base = xmalloc(namelen +4 +1); strcpy(base, name); if(!strcasecmp(name + namelen-extlen, ext)) { @@ -154,6 +151,35 @@ char *dup_basename(const char *name, const char *ext) return base; } +size_t widl_getline(char **linep, size_t *lenp, FILE *fp) +{ + char *line = *linep; + size_t len = *lenp; + size_t n = 0; + + if (!line) + { + len = 64; + line = xmalloc(len); + } + + while (fgets(&line[n], len - n, fp)) + { + n += strlen(&line[n]); + if (line[n - 1] == '\n') + break; + else if (n == len - 1) + { + len *= 2; + line = xrealloc(line, len); + } + } + + *linep = line; + *lenp = len; + return n; +} + void *xmalloc(size_t size) { void *res; @@ -164,12 +190,7 @@ void *xmalloc(size_t size) { error("Virtual memory exhausted.\n"); } - /* - * We set it to 0. - * This is *paramount* because we depend on it - * just about everywhere in the rest of the code. - */ - memset(res, 0, size); + memset(res, 0x55, size); return res; } @@ -192,6 +213,6 @@ char *xstrdup(const char *str) char *s; assert(str != NULL); - s = (char *)xmalloc(strlen(str)+1); + s = xmalloc(strlen(str)+1); return strcpy(s, str); } diff --git a/reactos/tools/widl/utils.h b/reactos/tools/widl/utils.h index 089607dd538..7d6ce5c5f30 100644 --- a/reactos/tools/widl/utils.h +++ b/reactos/tools/widl/utils.h @@ -33,13 +33,23 @@ char *xstrdup(const char *str); #define __attribute__(X) #endif -int yyerror(const char *s, ...) __attribute__((format (printf, 1, 2))); -int yywarning(const char *s, ...) __attribute__((format (printf, 1, 2))); -void internal_error(const char *file, int line, const char *s, ...) __attribute__((format (printf, 3, 4))); +int parser_error(const char *s, ...) __attribute__((format (printf, 1, 2))); +int parser_warning(const char *s, ...) __attribute__((format (printf, 1, 2))); +void error_loc(const char *s, ...) __attribute__((format (printf, 1, 2))); void error(const char *s, ...) __attribute__((format (printf, 1, 2))); void warning(const char *s, ...) __attribute__((format (printf, 1, 2))); void chat(const char *s, ...) __attribute__((format (printf, 1, 2))); char *dup_basename(const char *name, const char *ext); +size_t widl_getline(char **linep, size_t *lenp, FILE *fp); + +UUID *parse_uuid(const char *u); +int is_valid_uuid(const char *s); + +/* typelibs expect the minor version to be stored in the higher bits and + * major to be stored in the lower bits */ +#define MAKEVERSION(major, minor) ((((minor) & 0xffff) << 16) | ((major) & 0xffff)) +#define MAJORVERSION(version) ((version) & 0xffff) +#define MINORVERSION(version) (((version) >> 16) & 0xffff) #endif diff --git a/reactos/tools/widl/widl.c b/reactos/tools/widl/widl.c index 399d3cbaee2..dc5ee2c6a35 100644 --- a/reactos/tools/widl/widl.c +++ b/reactos/tools/widl/widl.c @@ -22,6 +22,8 @@ #include "config.h" #include "wine/port.h" +#include +#include #include #include #ifdef HAVE_UNISTD_H @@ -46,28 +48,34 @@ /* A = ACF input filename */ /* J = do not search standard include path */ /* O = generate interpreted stubs */ -/* u = UUID file only? */ -/* U = UUID filename */ /* w = select win16/win32 output (?) */ -static char usage[] = +static const char usage[] = "Usage: widl [options...] infile.idl\n" +" or: widl [options...] --dlldata-only name1 [name2...]\n" " -c Generate client stub\n" " -C file Name of client stub file (default is infile_c.c)\n" " -d n Set debug level to 'n'\n" " -D id[=val] Define preprocessor identifier id=val\n" +" --dlldata=file Name of the dlldata file (default is dlldata.c)\n" " -E Preprocess only\n" " -h Generate headers\n" " -H file Name of header file (default is infile.h)\n" " -I path Set include search dir to path (multiple -I allowed)\n" +" --local-stubs=file Write empty stubs for call_as/local methods to file\n" " -N Do not preprocess input\n" " --oldnames Use old naming conventions\n" " -p Generate proxy\n" " -P file Name of proxy file (default is infile_p.c)\n" +" --prefix-all=p Prefix names of client stubs / server functions with 'p'\n" +" --prefix-client=p Prefix names of client stubs with 'p'\n" +" --prefix-server=p Prefix names of server functions with 'p'\n" " -s Generate server stub\n" " -S file Name of server stub file (default is infile_s.c)\n" " -t Generate typelib\n" " -T file Name of typelib file (default is infile.tlb)\n" +" -u Generate interface identifiers file\n" +" -U file Name of interface identifiers file (default is infile_i.c)\n" " -V Print version and exit\n" " -W Enable pedantic warnings\n" "Debug level 'n' is a bitmask with following meaning:\n" @@ -84,47 +92,72 @@ static const char version_string[] = "Wine IDL Compiler version " PACKAGE_VERSIO int win32 = 1; int debuglevel = DEBUGLEVEL_NONE; -int yy_flex_debug; +int parser_debug, yy_flex_debug; int pedantic = 0; -static int do_everything = 1; +int do_everything = 1; int preprocess_only = 0; int do_header = 0; int do_typelib = 0; int do_proxies = 0; int do_client = 0; int do_server = 0; +int do_idfile = 0; +int do_dlldata = 0; int no_preprocess = 0; int old_names = 0; char *input_name; char *header_name; +char *local_stubs_name; char *header_token; char *typelib_name; +char *dlldata_name; char *proxy_name; char *proxy_token; char *client_name; char *client_token; char *server_name; char *server_token; +char *idfile_name; +char *idfile_token; char *temp_name; +const char *prefix_client = ""; +const char *prefix_server = ""; int line_number = 1; FILE *header; +FILE *local_stubs; FILE *proxy; +FILE *idfile; time_t now; -static const char *short_options = - "cC:d:D:EhH:I:NpP:sS:tT:VW"; -static struct option long_options[] = { - { "oldnames", 0, 0, 1 }, +enum { + OLDNAMES_OPTION = CHAR_MAX + 1, + DLLDATA_OPTION, + DLLDATA_ONLY_OPTION, + LOCAL_STUBS_OPTION, + PREFIX_ALL_OPTION, + PREFIX_CLIENT_OPTION, + PREFIX_SERVER_OPTION +}; + +static const char short_options[] = + "cC:d:D:EhH:I:NpP:sS:tT:uU:VW"; +static const struct option long_options[] = { + { "dlldata", required_argument, 0, DLLDATA_OPTION }, + { "dlldata-only", no_argument, 0, DLLDATA_ONLY_OPTION }, + { "local-stubs", required_argument, 0, LOCAL_STUBS_OPTION }, + { "oldnames", no_argument, 0, OLDNAMES_OPTION }, + { "prefix-all", required_argument, 0, PREFIX_ALL_OPTION }, + { "prefix-client", required_argument, 0, PREFIX_CLIENT_OPTION }, + { "prefix-server", required_argument, 0, PREFIX_SERVER_OPTION }, { 0, 0, 0, 0 } }; static void rm_tempfile(void); -static void segvhandler(int sig); static char *make_token(const char *name) { @@ -158,6 +191,145 @@ static void exit_on_signal( int sig ) exit(1); /* this will call the atexit functions */ } +static void set_everything(int x) +{ + do_header = x; + do_typelib = x; + do_proxies = x; + do_client = x; + do_server = x; + do_idfile = x; + do_dlldata = x; +} + +static void start_cplusplus_guard(FILE *fp) +{ + fprintf(fp, "#ifdef __cplusplus\n"); + fprintf(fp, "extern \"C\" {\n"); + fprintf(fp, "#endif\n\n"); +} + +static void end_cplusplus_guard(FILE *fp) +{ + fprintf(fp, "#ifdef __cplusplus\n"); + fprintf(fp, "}\n"); + fprintf(fp, "#endif\n\n"); +} + +typedef struct +{ + char *filename; + struct list link; +} filename_node_t; + +static void add_filename_node(struct list *list, const char *name) +{ + filename_node_t *node = xmalloc(sizeof *node); + node->filename = dup_basename( name, ".idl" ); + list_add_tail(list, &node->link); +} + +static void free_filename_nodes(struct list *list) +{ + filename_node_t *node, *next; + LIST_FOR_EACH_ENTRY_SAFE(node, next, list, filename_node_t, link) { + list_remove(&node->link); + free(node->filename); + free(node); + } +} + +static void write_dlldata_list(struct list *filenames) +{ + FILE *dlldata; + filename_node_t *node; + + dlldata = fopen(dlldata_name, "w"); + if (!dlldata) + error("couldn't open %s: %s\n", dlldata_name, strerror(errno)); + + fprintf(dlldata, "/*** Autogenerated by WIDL %s ", PACKAGE_VERSION); + fprintf(dlldata, "- Do not edit ***/\n\n"); + fprintf(dlldata, "#include \n"); + fprintf(dlldata, "#include \n\n"); + start_cplusplus_guard(dlldata); + + LIST_FOR_EACH_ENTRY(node, filenames, filename_node_t, link) + fprintf(dlldata, "EXTERN_PROXY_FILE(%s)\n", node->filename); + + fprintf(dlldata, "\nPROXYFILE_LIST_START\n"); + fprintf(dlldata, "/* Start of list */\n"); + LIST_FOR_EACH_ENTRY(node, filenames, filename_node_t, link) + fprintf(dlldata, " REFERENCE_PROXY_FILE(%s),\n", node->filename); + fprintf(dlldata, "/* End of list */\n"); + fprintf(dlldata, "PROXYFILE_LIST_END\n\n"); + + fprintf(dlldata, "DLLDATA_ROUTINES(aProxyFileList, GET_DLL_CLSID)\n\n"); + end_cplusplus_guard(dlldata); + fclose(dlldata); +} + +static char *eat_space(char *s) +{ + while (isspace((unsigned char) *s)) + ++s; + return s; +} + +void write_dlldata(ifref_list_t *ifaces) +{ + struct list filenames = LIST_INIT(filenames); + filename_node_t *node; + FILE *dlldata; + + if (!do_dlldata || !need_proxy_file(ifaces)) + return; + + dlldata = fopen(dlldata_name, "r"); + if (dlldata) { + static char marker[] = "REFERENCE_PROXY_FILE"; + char *line = NULL; + size_t len = 0; + + while (widl_getline(&line, &len, dlldata)) { + char *start, *end; + start = eat_space(line); + if (strncmp(start, marker, sizeof marker - 1) == 0) { + start = eat_space(start + sizeof marker - 1); + if (*start != '(') + continue; + end = start = eat_space(start + 1); + while (*end && *end != ')') + ++end; + if (*end != ')') + continue; + while (isspace((unsigned char) end[-1])) + --end; + *end = '\0'; + if (start < end) + add_filename_node(&filenames, start); + } + } + + if (ferror(dlldata)) + error("couldn't read from %s: %s\n", dlldata_name, strerror(errno)); + + free(line); + fclose(dlldata); + } + + LIST_FOR_EACH_ENTRY(node, &filenames, filename_node_t, link) + if (strcmp(proxy_token, node->filename) == 0) { + /* We're already in the list, no need to regenerate this file. */ + free_filename_nodes(&filenames); + return; + } + + add_filename_node(&filenames, proxy_token); + write_dlldata_list(&filenames); + free_filename_nodes(&filenames); +} + int main(int argc,char *argv[]) { extern char* optarg; @@ -166,7 +338,6 @@ int main(int argc,char *argv[]) int ret = 0; int opti = 0; - signal(SIGSEGV, segvhandler); signal( SIGTERM, exit_on_signal ); signal( SIGINT, exit_on_signal ); #ifdef SIGHUP @@ -177,15 +348,36 @@ int main(int argc,char *argv[]) while((optc = getopt_long(argc, argv, short_options, long_options, &opti)) != EOF) { switch(optc) { - case 1: + case DLLDATA_OPTION: + dlldata_name = xstrdup(optarg); + break; + case DLLDATA_ONLY_OPTION: + do_everything = 0; + do_dlldata = 1; + break; + case LOCAL_STUBS_OPTION: + do_everything = 0; + local_stubs_name = xstrdup(optarg); + break; + case OLDNAMES_OPTION: old_names = 1; break; + case PREFIX_ALL_OPTION: + prefix_client = xstrdup(optarg); + prefix_server = xstrdup(optarg); + break; + case PREFIX_CLIENT_OPTION: + prefix_client = xstrdup(optarg); + break; + case PREFIX_SERVER_OPTION: + prefix_server = xstrdup(optarg); + break; case 'c': do_everything = 0; do_client = 1; break; case 'C': - client_name = strdup(optarg); + client_name = xstrdup(optarg); break; case 'd': debuglevel = strtol(optarg, NULL, 0); @@ -202,7 +394,7 @@ int main(int argc,char *argv[]) do_header = 1; break; case 'H': - header_name = strdup(optarg); + header_name = xstrdup(optarg); break; case 'I': wpp_add_include_path(optarg); @@ -215,42 +407,67 @@ int main(int argc,char *argv[]) do_proxies = 1; break; case 'P': - proxy_name = strdup(optarg); + proxy_name = xstrdup(optarg); break; case 's': do_everything = 0; do_server = 1; break; case 'S': - server_name = strdup(optarg); + server_name = xstrdup(optarg); break; case 't': do_everything = 0; do_typelib = 1; break; case 'T': - typelib_name = strdup(optarg); + typelib_name = xstrdup(optarg); + break; + case 'u': + do_everything = 0; + do_idfile = 1; + break; + case 'U': + idfile_name = xstrdup(optarg); break; case 'V': - printf(version_string); + printf("%s", version_string); return 0; case 'W': pedantic = 1; break; default: - fprintf(stderr, usage); + fprintf(stderr, "%s", usage); return 1; } } if(do_everything) { - do_header = do_typelib = do_proxies = do_client = do_server = 1; + set_everything(TRUE); } + + if (!dlldata_name && do_dlldata) + dlldata_name = xstrdup("dlldata.c"); + if(optind < argc) { - input_name = xstrdup(argv[optind]); + if (do_dlldata && !do_everything) { + struct list filenames = LIST_INIT(filenames); + for ( ; optind < argc; ++optind) + add_filename_node(&filenames, argv[optind]); + + write_dlldata_list(&filenames); + free_filename_nodes(&filenames); + return 0; + } + else if (optind != argc - 1) { + fprintf(stderr, "%s", usage); + return 1; + } + else + input_name = xstrdup(argv[optind]); } else { - fprintf(stderr, usage); + fprintf(stderr, "%s", usage); return 1; } @@ -260,7 +477,7 @@ int main(int argc,char *argv[]) setbuf(stderr,0); } - yydebug = debuglevel & DEBUGLEVEL_TRACE ? 1 : 0; + parser_debug = debuglevel & DEBUGLEVEL_TRACE ? 1 : 0; yy_flex_debug = debuglevel & DEBUGLEVEL_TRACE ? 1 : 0; wpp_set_debug( (debuglevel & DEBUGLEVEL_PPLEX) != 0, @@ -292,6 +509,11 @@ int main(int argc,char *argv[]) strcat(server_name, "_s.c"); } + if (!idfile_name && do_idfile) { + idfile_name = dup_basename(input_name, ".idl"); + strcat(idfile_name, "_i.c"); + } + if (do_proxies) proxy_token = dup_basename_token(proxy_name,"_p.c"); if (do_client) client_token = dup_basename_token(client_name,"_c.c"); if (do_server) server_token = dup_basename_token(server_name,"_s.c"); @@ -314,13 +536,13 @@ int main(int argc,char *argv[]) if(ret) exit(1); if(preprocess_only) exit(0); - if(!(yyin = fopen(temp_name, "r"))) { + if(!(parser_in = fopen(temp_name, "r"))) { fprintf(stderr, "Could not open %s for input\n", temp_name); return 1; } } else { - if(!(yyin = fopen(input_name, "r"))) { + if(!(parser_in = fopen(input_name, "r"))) { fprintf(stderr, "Could not open %s for input\n", input_name); return 1; } @@ -343,35 +565,74 @@ int main(int argc,char *argv[]) fprintf(header, "#include \n\n" ); fprintf(header, "#ifndef __WIDL_%s\n", header_token); fprintf(header, "#define __WIDL_%s\n", header_token); - fprintf(header, "#ifdef __cplusplus\n"); - fprintf(header, "extern \"C\" {\n"); - fprintf(header, "#endif\n"); + start_cplusplus_guard(header); } - ret = yyparse(); + if (local_stubs_name) { + local_stubs = fopen(local_stubs_name, "w"); + if (!local_stubs) { + fprintf(stderr, "Could not open %s for output\n", local_stubs_name); + return 1; + } + fprintf(local_stubs, "/* call_as/local stubs for %s */\n\n", input_name); + fprintf(local_stubs, "#include \n"); + fprintf(local_stubs, "#include \"%s\"\n\n", header_name); + } + + if (do_idfile) { + idfile_token = make_token(idfile_name); + + idfile = fopen(idfile_name, "w"); + if (! idfile) { + fprintf(stderr, "Could not open %s for output\n", idfile_name); + return 1; + } + + fprintf(idfile, "/*** Autogenerated by WIDL %s ", PACKAGE_VERSION); + fprintf(idfile, "from %s - Do not edit ***/\n\n", input_name); + fprintf(idfile, "#include \n"); + fprintf(idfile, "#include \n\n"); + fprintf(idfile, "#include \n\n"); + start_cplusplus_guard(idfile); + } + + init_types(); + ret = parser_parse(); if(do_header) { fprintf(header, "/* Begin additional prototypes for all interfaces */\n"); fprintf(header, "\n"); write_user_types(); + write_context_handle_rundowns(); fprintf(header, "\n"); fprintf(header, "/* End additional prototypes */\n"); fprintf(header, "\n"); - fprintf(header, "#ifdef __cplusplus\n"); - fprintf(header, "}\n"); - fprintf(header, "#endif\n"); + end_cplusplus_guard(header); fprintf(header, "#endif /* __WIDL_%s */\n", header_token); fclose(header); } - fclose(yyin); + if (local_stubs) { + fclose(local_stubs); + } + + if (do_idfile) { + fprintf(idfile, "\n"); + end_cplusplus_guard(idfile); + + fclose(idfile); + } + + fclose(parser_in); if(ret) { exit(1); } - header_name = NULL; - client_name = NULL; - server_name = NULL; + + /* Everything has been done successfully, don't delete any files. */ + set_everything(FALSE); + local_stubs_name = NULL; + return 0; } @@ -380,18 +641,18 @@ static void rm_tempfile(void) abort_import(); if(temp_name) unlink(temp_name); - if (header_name) + if (do_header) unlink(header_name); - if (client_name) + if (local_stubs_name) + unlink(local_stubs_name); + if (do_client) unlink(client_name); - if (server_name) + if (do_server) unlink(server_name); -} - -static void segvhandler(int sig) -{ - fprintf(stderr, "\n%s:%d: Oops, segment violation\n", input_name, line_number); - fflush(stdout); - fflush(stderr); - abort(); + if (do_idfile) + unlink(idfile_name); + if (do_proxies) + unlink(proxy_name); + if (do_typelib) + unlink(typelib_name); } diff --git a/reactos/tools/widl/widl.h b/reactos/tools/widl/widl.h index d41ca7074a4..924b67a3d88 100644 --- a/reactos/tools/widl/widl.h +++ b/reactos/tools/widl/widl.h @@ -25,8 +25,6 @@ #include -#define WIDL_FULLVERSION "0.1" - extern int debuglevel; #define DEBUGLEVEL_NONE 0x0000 #define DEBUGLEVEL_CHAT 0x0001 @@ -38,31 +36,41 @@ extern int debuglevel; extern int win32; extern int pedantic; +extern int do_everything; extern int do_header; extern int do_typelib; extern int do_proxies; extern int do_client; extern int do_server; +extern int do_idfile; +extern int do_dlldata; extern int old_names; extern char *input_name; extern char *header_name; +extern char *local_stubs_name; extern char *typelib_name; +extern char *dlldata_name; extern char *proxy_name; extern char *proxy_token; extern char *client_name; extern char *client_token; extern char *server_name; extern char *server_token; +extern const char *prefix_client; +extern const char *prefix_server; extern time_t now; extern int line_number; extern int char_number; extern FILE* header; +extern FILE* local_stubs; +extern FILE* idfile; -extern void write_proxies(ifref_t *ifaces); -extern void write_client(ifref_t *ifaces); -extern void write_server(ifref_t *ifaces); +extern void write_proxies(ifref_list_t *ifaces); +extern void write_client(ifref_list_t *ifaces); +extern void write_server(ifref_list_t *ifaces); +extern void write_dlldata(ifref_list_t *ifaces); #endif diff --git a/reactos/tools/widl/widl.mak b/reactos/tools/widl/widl.mak index c5664c5d709..de6813ac536 100644 --- a/reactos/tools/widl/widl.mak +++ b/reactos/tools/widl/widl.mak @@ -41,7 +41,6 @@ WIDL_SOURCES = $(addprefix $(WIDL_BASE_), \ client.c \ hash.c \ header.c \ - lex.yy.c \ proxy.c \ server.c \ typegen.c \ @@ -49,6 +48,7 @@ WIDL_SOURCES = $(addprefix $(WIDL_BASE_), \ utils.c \ widl.c \ write_msft.c \ + parser.yy.c \ parser.tab.c \ port$(SEP)mkstemps.c \ ) @@ -56,11 +56,11 @@ WIDL_SOURCES = $(addprefix $(WIDL_BASE_), \ WIDL_OBJECTS = \ $(addprefix $(INTERMEDIATE_), $(WIDL_SOURCES:.c=.o)) -WIDL_HOST_CFLAGS = \ - -DINT16=SHORT -DYYDEBUG=1 \ +WIDL_HOST_CFLAGS = $(TOOLS_CFLAGS) \ + -DINT16=SHORT -D__USE_W32API -DYYDEBUG=1 -D__REACTOS__=1 \ -I$(WIDL_BASE) -I$(WPP_BASE) \ - -Iinclude/reactos/wine -Iinclude/reactos -Iinclude \ - -I$(INTERMEDIATE_)include $(TOOLS_CFLAGS) + -Iinclude/reactos/wine -Iinclude/reactos -Iinclude -Iinclude/psdk \ + -I$(INTERMEDIATE_)include WIDL_HOST_LFLAGS = $(TOOLS_LFLAGS) @@ -85,10 +85,6 @@ $(WIDL_INT_)header.o: $(WIDL_BASE_)header.c $(WIDL_DEPENDS) | $(WIDL_INT) $(ECHO_CC) ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ -$(WIDL_INT_)lex.yy.o: $(WIDL_BASE_)lex.yy.c $(WIDL_DEPENDS) | $(WIDL_INT) - $(ECHO_CC) - ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ - $(WIDL_INT_)proxy.o: $(WIDL_BASE_)proxy.c $(WIDL_DEPENDS) | $(WIDL_INT) $(ECHO_CC) ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ @@ -117,6 +113,10 @@ $(WIDL_INT_)write_msft.o: $(WIDL_BASE_)write_msft.c $(WIDL_DEPENDS) | $(WIDL_INT $(ECHO_CC) ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ +$(WIDL_INT_)parser.yy.o: $(WIDL_BASE_)parser.yy.c $(WIDL_DEPENDS) | $(WIDL_INT) + $(ECHO_CC) + ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ + $(WIDL_INT_)parser.tab.o: $(WIDL_BASE_)parser.tab.c $(WIDL_DEPENDS) | $(WIDL_INT) $(ECHO_CC) ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ diff --git a/reactos/tools/widl/widl.man.in b/reactos/tools/widl/widl.man.in deleted file mode 100644 index 2d9ac8034e8..00000000000 --- a/reactos/tools/widl/widl.man.in +++ /dev/null @@ -1,88 +0,0 @@ -.\" -*- nroff -*- -.TH WIDL 1 "October 2005" "@PACKAGE_STRING@" "Wine Developers Manual" -.SH NAME -widl \- Wine Interface Definition Language Compiler -.SH SYNOPSIS -.BR "widl "\fI[options]\fR " \fIinfile.idl\fR" -.SH DESCRIPTION -.B widl -is a Wine tool which purpose is to compile Interface Definition Language (IDL) files. -.PP -.SH OPTIONS -.B Help mode: -.nf -No options are used. -The program prints the help info and then exits. -.PP -.B General options: -.IP "\fB-V\fR" -Print version number and exits from the program. -.PP -.B Header options: -.IP "\fB-h\fR" -Generate header files. -.IP "\fB-H \fIfile\fR" -Name of header file to generate. The default header -filename is infile.h. -.IP "\fB--oldnames\fR" -Use old naming conventions. -.PP -.B Type library options: -.IP \fB-t\fR -Generate a type library. -.IP "\fB-T \fIfile\fR" -Define the name of the type library to be generated. -The default filename is infile.tlb. -.PP -.B Proxy/stub generation options: -.IP "\fB-c\fR" -Generate client stub. -.IP "\fB-C \fIfile\fR" -Name of client stub file (default is infile_c.c) -.IP "\fB-p\fR" -Generate proxy. -.IP "\fB-P \fIfile\fR" -Name of proxy file (default is infile_p.c) -.IP "\fB-s\fR" -Generate server stub. -.IP "\fB-S \fIfile\fR" -Name of server stub file (default is infile_s.c) -.PP -.B Preprocessor options: -.IP "\fB-I \fIpath\fR" -Add a header search dir to path. Multiple search -dirs are allowed. -.IP "\fB-D \fIid[=val]\fR" -Define preprocessor identifier id value. -.IP "\fB-E\fR" -Preprocess only. -.IP "\fB-N\fR" -Do not preprocess input. -.PP -.B Debug options: -.IP "\fB-W\fR" -Enable pedantic warnings. -.IP "\fB-d \fIn\fR" -.nf -Set debug level to n. -n may be '0x01', '0x02', '0x04', '0x08', '0x10' or '0x20'. -(See section \fBDebug\fR) -.PP -.SH Debug -Debug level 'n' is a bitmask with the following meaning: - * 0x01 Tell which resource is parsed (verbose mode) - * 0x02 Dump internal structures - * 0x04 Create a parser trace (yydebug=1) - * 0x08 Preprocessor messages - * 0x10 Preprocessor lex messages - * 0x20 Preprocessor yacc trace -.SH BUGS -Typelib generation doesn't work at the moment. It is still under development. -.SH AUTHORS -.B widl -was written by Ove Kaaven. This man page was written by Hannu -Valtonen. -.SH "SEE ALSO" -The Winelib User Guide -.nf -The Wine Developers Guide diff --git a/reactos/tools/widl_20080105/widl_ros.diff b/reactos/tools/widl/widl_ros.diff similarity index 100% rename from reactos/tools/widl_20080105/widl_ros.diff rename to reactos/tools/widl/widl_ros.diff diff --git a/reactos/tools/widl/widltypes.h b/reactos/tools/widl/widltypes.h index d7bea8b291e..6930f711719 100644 --- a/reactos/tools/widl/widltypes.h +++ b/reactos/tools/widl/widltypes.h @@ -21,53 +21,44 @@ #ifndef __WIDL_WIDLTYPES_H #define __WIDL_WIDLTYPES_H -#include -#define S_OK ((HRESULT)0x00000000L) -#define S_FALSE ((HRESULT)0x00000001L) -#define E_OUTOFMEMORY ((HRESULT)0x8007000EL) -#define TYPE_E_IOERROR ((HRESULT)0x80028CA2L) - -#define min(a, b) ((a) < (b) ? (a) : (b)) -#define max(a,b) ((a) < (b) ? (b) : (a)) - #include #include "guiddef.h" #include "wine/rpcfc.h" +#include "wine/list.h" #ifndef UUID_DEFINED #define UUID_DEFINED typedef GUID UUID; #endif +#define TRUE 1 +#define FALSE 0 + typedef struct _attr_t attr_t; typedef struct _expr_t expr_t; typedef struct _type_t type_t; typedef struct _typeref_t typeref_t; typedef struct _var_t var_t; +typedef struct _pident_t pident_t; typedef struct _func_t func_t; typedef struct _ifref_t ifref_t; typedef struct _typelib_entry_t typelib_entry_t; typedef struct _importlib_t importlib_t; typedef struct _importinfo_t importinfo_t; typedef struct _typelib_t typelib_t; +typedef struct _user_type_t user_type_t; +typedef struct _user_type_t context_handle_t; -#define DECL_LINK(type) \ - type *l_next; \ - type *l_prev - -#define LINK(x,y) do { x->l_next = y; if (y) y->l_prev = x; } while (0) - -#define INIT_LINK(x) do { x->l_next = NULL; x->l_prev = NULL; } while (0) -#define NEXT_LINK(x) ((x)->l_next) -#define PREV_LINK(x) ((x)->l_prev) - -#define END_OF_LIST(list) \ - do { \ - if (list) { \ - while (NEXT_LINK(list)) \ - list = NEXT_LINK(list); \ - } \ - } while(0) +typedef struct list attr_list_t; +typedef struct list str_list_t; +typedef struct list func_list_t; +typedef struct list expr_list_t; +typedef struct list var_list_t; +typedef struct list pident_list_t; +typedef struct list ifref_list_t; +typedef struct list array_dims_t; +typedef struct list user_type_list_t; +typedef struct list context_handle_list_t; enum attr_type { @@ -146,6 +137,7 @@ enum expr_type EXPR_VOID, EXPR_NUM, EXPR_HEXNUM, + EXPR_DOUBLE, EXPR_IDENTIFIER, EXPR_NEG, EXPR_NOT, @@ -162,6 +154,7 @@ enum expr_type EXPR_OR, EXPR_COND, EXPR_TRUEFALSE, + EXPR_ADDRESSOF, }; enum type_kind @@ -178,6 +171,12 @@ enum type_kind TKIND_MAX }; +struct str_list_entry_t +{ + char *str; + struct list entry; +}; + struct _attr_t { enum attr_type type; union { @@ -185,7 +184,7 @@ struct _attr_t { void *pval; } u; /* parser-internal */ - DECL_LINK(attr_t); + struct list entry; }; struct _expr_t { @@ -193,15 +192,16 @@ struct _expr_t { const expr_t *ref; union { long lval; + double dval; const char *sval; const expr_t *ext; - const typeref_t *tref; + type_t *tref; } u; const expr_t *ext2; int is_const; long cval; /* parser-internal */ - DECL_LINK(expr_t); + struct list entry; }; struct _type_t { @@ -209,65 +209,65 @@ struct _type_t { enum type_kind kind; unsigned char type; struct _type_t *ref; - const attr_t *attrs; - func_t *funcs; /* interfaces and modules */ - var_t *fields; /* interfaces, structures and enumerations */ - ifref_t *ifaces; /* coclasses */ - int ignore, is_const, sign; - int defined, written, user_types_registered; + const attr_list_t *attrs; + func_list_t *funcs; /* interfaces and modules */ + var_list_t *fields; /* interfaces, structures and enumerations */ + ifref_list_t *ifaces; /* coclasses */ + unsigned long dim; /* array dimension */ + expr_t *size_is, *length_is; + type_t *orig; /* dup'd types */ + unsigned int typestring_offset; + unsigned int ptrdesc; /* used for complex structs */ int typelib_idx; - /* parser-internal */ - DECL_LINK(type_t); -}; - -struct _typeref_t { - char *name; - type_t *ref; - int uniq; + unsigned int declarray : 1; /* if declared as an array */ + unsigned int ignore : 1; + unsigned int is_const : 1; + unsigned int defined : 1; + unsigned int written : 1; + unsigned int user_types_registered : 1; + unsigned int tfswrite : 1; /* if the type needs to be written to the TFS */ + int sign : 2; }; struct _var_t { char *name; - int ptr_level; - expr_t *array; type_t *type; - var_t *args; /* for function pointers */ - const char *tname; - attr_t *attrs; + var_list_t *args; /* for function pointers */ + attr_list_t *attrs; expr_t *eval; /* parser-internal */ - DECL_LINK(var_t); + struct list entry; +}; + +struct _pident_t { + var_t *var; + int ptr_level; + + /* parser-internal */ + struct list entry; }; struct _func_t { var_t *def; - var_t *args; + var_list_t *args; int ignore, idx; /* parser-internal */ - DECL_LINK(func_t); + struct list entry; }; struct _ifref_t { type_t *iface; - attr_t *attrs; + attr_list_t *attrs; /* parser-internal */ - DECL_LINK(ifref_t); + struct list entry; }; struct _typelib_entry_t { - enum type_kind kind; - union { - type_t *class; - type_t *interface; - type_t *module; - type_t *structure; - type_t *enumeration; - var_t *tdef; - } u; - DECL_LINK(typelib_entry_t); + type_t *type; + struct list entry; }; struct _importinfo_t { @@ -292,15 +292,39 @@ struct _importlib_t { int allocated; - DECL_LINK(importlib_t); + struct list entry; }; struct _typelib_t { char *name; char *filename; - attr_t *attrs; - typelib_entry_t *entry; - importlib_t *importlibs; + attr_list_t *attrs; + struct list entries; + struct list importlibs; }; +struct _user_type_t { + struct list entry; + const char *name; +}; + +extern unsigned char pointer_default; + +extern user_type_list_t user_type_list; +void check_for_user_types_and_context_handles(const var_list_t *list); + +void init_types(void); +type_t *alloc_type(void); +void set_all_tfswrite(int val); + +type_t *duptype(type_t *t, int dupname); +type_t *alias(type_t *t, const char *name); + +int is_ptr(const type_t *t); +int is_array(const type_t *t); +int is_var_ptr(const var_t *v); +int cant_be_null(const var_t *v); +int is_struct(unsigned char tc); +int is_union(unsigned char tc); + #endif diff --git a/reactos/tools/widl/write_msft.c b/reactos/tools/widl/write_msft.c index 8be205375ea..f5ea2f7f27b 100644 --- a/reactos/tools/widl/write_msft.c +++ b/reactos/tools/widl/write_msft.c @@ -40,12 +40,16 @@ #define NONAMELESSUNION #define NONAMELESSSTRUCT -#include +#include "winerror.h" +#include "windef.h" +#include "winbase.h" +#include "winnls.h" #include "widltypes.h" #include "typelib.h" #include "typelib_struct.h" #include "utils.h" +#include "header.h" #include "hash.h" enum MSFT_segment_index { @@ -326,7 +330,6 @@ static int ctl2_encode_name( * safe in the slightest. */ static int ctl2_encode_string( - msft_typelib_t *typelib, /* [I] The typelib to operate against (not used?). */ const char *string, /* [I] The string to encode. */ char **result) /* [O] A pointer to a pointer to receive the encoded string. */ { @@ -359,7 +362,6 @@ static int ctl2_encode_string( * RETURNS * * Success: The offset within the segment of the new data area. - * Failure: -1 (this is invariably an out of memory condition). * * BUGS * @@ -386,8 +388,7 @@ static int ctl2_alloc_segment( char *block; block_size = typelib->typelib_segment_block_length[segment]; - block = realloc(typelib->typelib_segment_data[segment], block_size << 1); - if (!block) return -1; + block = xrealloc(typelib->typelib_segment_data[segment], block_size << 1); if (segment == MSFT_SEG_TYPEINFO) { /* TypeInfos have a direct pointer to their memory space, so we have to fix them up. */ @@ -427,7 +428,6 @@ static int ctl2_alloc_typeinfo( MSFT_TypeInfoBase *typeinfo; offset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEINFO, sizeof(MSFT_TypeInfoBase), 0); - if (offset == -1) return -1; typelib->typelib_typeinfo_offsets[typelib->typelib_header.nrtypeinfos++] = offset; @@ -472,7 +472,6 @@ static int ctl2_alloc_typeinfo( * RETURNS * * Success: The offset of the new GUID. - * Failure: -1 (this is invariably an out of memory condition). */ static int ctl2_alloc_guid( msft_typelib_t *typelib, /* [I] The type library to allocate in. */ @@ -488,7 +487,6 @@ static int ctl2_alloc_guid( if (offset != -1) return offset; offset = ctl2_alloc_segment(typelib, MSFT_SEG_GUID, sizeof(MSFT_GuidEntry), 0); - if (offset == -1) return -1; guid_space = (void *)(typelib->typelib_segment_data[MSFT_SEG_GUID] + offset); *guid_space = *guid; @@ -525,7 +523,6 @@ static int ctl2_alloc_name( if (offset != -1) return offset; offset = ctl2_alloc_segment(typelib, MSFT_SEG_NAME, length + 8, 0); - if (offset == -1) return -1; name_space = (void *)(typelib->typelib_segment_data[MSFT_SEG_NAME] + offset); name_space->hreftype = -1; @@ -562,7 +559,7 @@ static int ctl2_alloc_string( char *string_space; char *encoded_string; - length = ctl2_encode_string(typelib, string, &encoded_string); + length = ctl2_encode_string(string, &encoded_string); for (offset = 0; offset < typelib->typelib_segdir[MSFT_SEG_STRING].length; offset += ((((typelib->typelib_segment_data[MSFT_SEG_STRING][offset + 1] << 8) & 0xff) @@ -571,7 +568,6 @@ static int ctl2_alloc_string( } offset = ctl2_alloc_segment(typelib, MSFT_SEG_STRING, length, 0); - if (offset == -1) return -1; string_space = typelib->typelib_segment_data[MSFT_SEG_STRING] + offset; memcpy(string_space, encoded_string, length); @@ -608,7 +604,6 @@ static int alloc_msft_importinfo( impinfo->flags |= typelib->typelib_header.nimpinfos++; offset = ctl2_alloc_segment(typelib, MSFT_SEG_IMPORTINFO, sizeof(MSFT_ImpInfo), 0); - if (offset == -1) return -1; impinfo_space = (void *)(typelib->typelib_segment_data[MSFT_SEG_IMPORTINFO] + offset); *impinfo_space = *impinfo; @@ -638,7 +633,7 @@ static int alloc_importfile( MSFT_ImpFile *importfile; char *encoded_string; - length = ctl2_encode_string(typelib, filename, &encoded_string); + length = ctl2_encode_string(filename, &encoded_string); encoded_string[0] <<= 2; encoded_string[0] |= 1; @@ -650,7 +645,6 @@ static int alloc_importfile( } offset = ctl2_alloc_segment(typelib, MSFT_SEG_IMPORTFILES, length + 0xc, 0); - if (offset == -1) return -1; importfile = (MSFT_ImpFile *)&typelib->typelib_segment_data[MSFT_SEG_IMPORTFILES][offset]; importfile->guid = guidoffset; @@ -722,7 +716,8 @@ static importinfo_t *find_importinfo(msft_typelib_t *typelib, const char *name) if(!name) return NULL; - for(importlib = typelib->typelib->importlibs; importlib; importlib = NEXT_LINK(importlib)) { + LIST_FOR_EACH_ENTRY( importlib, &typelib->typelib->importlibs, importlib_t, entry ) + { for(i=0; i < importlib->ntypeinfos; i++) { if(!strcmp(name, importlib->importinfos[i].name)) { chat("Found %s in importlib.\n", name); @@ -738,6 +733,7 @@ static void add_structure_typeinfo(msft_typelib_t *typelib, type_t *structure); static void add_interface_typeinfo(msft_typelib_t *typelib, type_t *interface); static void add_enum_typeinfo(msft_typelib_t *typelib, type_t *enumeration); static void add_coclass_typeinfo(msft_typelib_t *typelib, type_t *cls); +static void add_dispinterface_typeinfo(msft_typelib_t *typelib, type_t *dispinterface); /**************************************************************************** @@ -833,6 +829,7 @@ static int encode_type( break; case VT_CY: + case VT_DATE: *encoded_type = default_type; *width = 8; *alignment = 8; @@ -855,6 +852,13 @@ static int encode_type( *encoded_type = default_type; break; + case VT_LPSTR: + case VT_LPWSTR: + *encoded_type = 0xfffe0000 | vt; + *width = 4; + *alignment = 4; + break; + case VT_PTR: { int next_vt; @@ -884,7 +888,7 @@ static int encode_type( if (typeoffset == typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length) { int mix_field; - + if (target_type & 0x80000000) { mix_field = ((target_type >> 16) & 0x3fff) | VT_BYREF; } else { @@ -906,14 +910,22 @@ static int encode_type( *decoded_size = 8 /*sizeof(TYPEDESC)*/ + child_size; break; } -#if 0 case VT_SAFEARRAY: - /* FIXME: Make with the error checking. */ - FIXME("SAFEARRAY vartype, may not work correctly.\n"); + { + int next_vt; - ctl2_encode_typedesc(typelib, tdesc->u.lptdesc, &target_type, NULL, NULL, &child_size); + /* skip over SAFEARRAY type straight to element type */ + type = type->ref; + + for(next_vt = 0; type->ref; type = type->ref) { + next_vt = get_type_vt(type->ref); + if (next_vt != 0) + break; + } + + encode_type(typelib, next_vt, type->ref, &target_type, NULL, NULL, &child_size); for (typeoffset = 0; typeoffset < typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) { typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; @@ -922,7 +934,7 @@ static int encode_type( if (typeoffset == typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length) { int mix_field; - + if (target_type & 0x80000000) { mix_field = ((target_type >> 16) & VT_TYPEMASK) | VT_ARRAY; } else { @@ -937,19 +949,23 @@ static int encode_type( typedata[1] = target_type; } - *encoded_tdesc = typeoffset; + *encoded_type = typeoffset; *width = 4; *alignment = 4; - *decoded_size = sizeof(TYPEDESC) + child_size; + *decoded_size = 8 /*sizeof(TYPEDESC)*/ + child_size; break; + } -#endif - case VT_USERDEFINED: { int typeinfo_offset; + + /* typedef'd types without attributes aren't included in the typelib */ + while (type->typelib_idx < 0 && type->kind == TKIND_ALIAS && ! type->attrs) + type = type->orig; + chat("encode_type: VT_USERDEFINED - type %p name = %s type->type %d idx %d\n", type, type->name, type->type, type->typelib_idx); @@ -973,6 +989,8 @@ static int encode_type( case 0: if (type->kind == TKIND_COCLASS) add_coclass_typeinfo(typelib, type); + else if (type->kind == TKIND_DISPATCH) + add_dispinterface_typeinfo(typelib, type); else error("encode_type: VT_USERDEFINED - can't yet add typedef's on the fly\n"); break; @@ -1038,7 +1056,8 @@ static void dump_type(type_t *t) static int encode_var( msft_typelib_t *typelib, /* [I] The type library in which to encode the TYPEDESC. */ - var_t *var, /* [I] The type description to encode. */ + type_t *type, /* [I] The type description to encode. */ + var_t *var, /* [I] The var to encode. */ int *encoded_type, /* [O] The encoded type description. */ int *width, /* [O] The width of the type, or NULL. */ int *alignment, /* [O] The alignment of the type, or NULL. */ @@ -1050,19 +1069,57 @@ static int encode_var( int child_size; int vt; int scratch; - type_t *type; if (!width) width = &scratch; if (!alignment) alignment = &scratch; if (!decoded_size) decoded_size = &scratch; *decoded_size = 0; - chat("encode_var: var %p var->tname %s var->type %p var->ptr_level %d var->type->ref %p\n", var, var->tname, var->type, var->ptr_level, var->type->ref); - if(var->ptr_level) { - int skip_ptr; - var->ptr_level--; - skip_ptr = encode_var(typelib, var, &target_type, NULL, NULL, &child_size); - var->ptr_level++; + chat("encode_var: var %p type %p type->name %s type->ref %p\n", + var, type, type->name ? type->name : "NULL", type->ref); + + if (type->declarray) { + int num_dims, elements = 1, arrayoffset; + type_t *atype; + int *arraydata; + + num_dims = 0; + for (atype = type; atype->declarray; atype = atype->ref) + ++num_dims; + + chat("array with %d dimensions\n", num_dims); + encode_var(typelib, atype, var, &target_type, width, alignment, NULL); + arrayoffset = ctl2_alloc_segment(typelib, MSFT_SEG_ARRAYDESC, (2 + 2 * num_dims) * sizeof(long), 0); + arraydata = (void *)&typelib->typelib_segment_data[MSFT_SEG_ARRAYDESC][arrayoffset]; + + arraydata[0] = target_type; + arraydata[1] = num_dims; + arraydata[1] |= ((num_dims * 2 * sizeof(long)) << 16); + + arraydata += 2; + for (atype = type; atype->declarray; atype = atype->ref) + { + arraydata[0] = atype->dim; + arraydata[1] = 0; + arraydata += 2; + elements *= atype->dim; + } + + typeoffset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEDESC, 8, 0); + typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; + + typedata[0] = (0x7ffe << 16) | VT_CARRAY; + typedata[1] = arrayoffset; + + *encoded_type = typeoffset; + *width = *width * elements; + *decoded_size = 20 /*sizeof(ARRAYDESC)*/ + (num_dims - 1) * 8 /*sizeof(SAFEARRAYBOUND)*/; + return 0; + } + + vt = get_type_vt(type); + if (vt == VT_PTR) { + int skip_ptr = encode_var(typelib, type->ref, var, &target_type, NULL, NULL, &child_size); if(skip_ptr == 2) { chat("encode_var: skipping ptr\n"); @@ -1080,7 +1137,7 @@ static int encode_var( if (typeoffset == typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length) { int mix_field; - + if (target_type & 0x80000000) { mix_field = ((target_type >> 16) & 0x3fff) | VT_BYREF; } else { @@ -1103,65 +1160,27 @@ static int encode_var( return 0; } - if(var->array) { - expr_t *dim = var->array; - expr_t *array_save; - int num_dims = 1, elements = 1, arrayoffset; - int *arraydata; + dump_type(type); - while(NEXT_LINK(dim)) { - dim = NEXT_LINK(dim); - num_dims++; - } - chat("array with %d dimensions\n", num_dims); - array_save = var->array; - var->array = NULL; - encode_var(typelib, var, &target_type, width, alignment, NULL); - var->array = array_save; - arrayoffset = ctl2_alloc_segment(typelib, MSFT_SEG_ARRAYDESC, (2 + 2 * num_dims) * sizeof(long), 0); - arraydata = (void *)&typelib->typelib_segment_data[MSFT_SEG_ARRAYDESC][arrayoffset]; - - arraydata[0] = target_type; - arraydata[1] = num_dims; - arraydata[1] |= ((num_dims * 2 * sizeof(long)) << 16); - - arraydata += 2; - while(dim) { - arraydata[0] = dim->cval; - arraydata[1] = 0; - arraydata += 2; - elements *= dim->cval; - dim = PREV_LINK(dim); - } - - typeoffset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEDESC, 8, 0); - typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; - - typedata[0] = (0x7ffe << 16) | VT_CARRAY; - typedata[1] = arrayoffset; - - *encoded_type = typeoffset; - *width = *width * elements; - *decoded_size = 20 /*sizeof(ARRAYDESC)*/ + (num_dims - 1) * 8 /*sizeof(SAFEARRAYBOUND)*/; - return 0; - } - dump_type(var->type); - - vt = get_var_vt(var); - type = var->type; - while(!vt) { - if(type->ref == NULL) { - vt = VT_VOID; - break; - } - type = type->ref; - vt = get_type_vt(type); - } encode_type(typelib, vt, type, encoded_type, width, alignment, decoded_size); if(type->type == RPC_FC_IP) return 2; return 0; } +static unsigned long get_ulong_val(unsigned long val, int vt) +{ + switch(vt) { + case VT_I2: + case VT_BOOL: + case VT_UI2: + return val & 0xffff; + case VT_I1: + case VT_UI1: + return val & 0xff; + } + + return val; +} static void write_value(msft_typelib_t* typelib, int *out, int vt, void *value) { @@ -1177,12 +1196,13 @@ static void write_value(msft_typelib_t* typelib, int *out, int vt, void *value) case VT_INT: case VT_UINT: case VT_HRESULT: + case VT_PTR: { - unsigned long *lv = value; - if((*lv & 0x3ffffff) == *lv) { + const unsigned long lv = get_ulong_val(*(unsigned long*)value, vt); + if((lv & 0x3ffffff) == lv) { *out = 0x80000000; *out |= vt << 26; - *out |= *lv; + *out |= lv; } else { int offset = ctl2_alloc_segment(typelib, MSFT_SEG_CUSTDATA, 8, 0); *((unsigned short *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset]) = vt; @@ -1198,7 +1218,7 @@ static void write_value(msft_typelib_t* typelib, int *out, int vt, void *value) int len = strlen(s), seg_len = (len + 6 + 3) & ~0x3; int offset = ctl2_alloc_segment(typelib, MSFT_SEG_CUSTDATA, seg_len, 0); *((unsigned short *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset]) = vt; - *((unsigned int *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset+2]) = len; + *((unsigned int *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset+2]) = len; memcpy(&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset+6], value, len); len += 6; while(len < seg_len) { @@ -1230,11 +1250,9 @@ static HRESULT set_custdata(msft_typelib_t *typelib, REFGUID guid, guidentry.next_hash = -1; guidoffset = ctl2_alloc_guid(typelib, &guidentry); - if (guidoffset == -1) return E_OUTOFMEMORY; write_value(typelib, &data_out, vt, value); custoffset = ctl2_alloc_segment(typelib, MSFT_SEG_CUSTDATAGUID, 12, 0); - if (custoffset == -1) return E_OUTOFMEMORY; custdata = (int *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATAGUID][custoffset]; custdata[0] = guidoffset; @@ -1245,14 +1263,14 @@ static HRESULT set_custdata(msft_typelib_t *typelib, REFGUID guid, return S_OK; } -static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, func_t *func, int index) +static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, const func_t *func, int index) { int offset, name_offset; int *typedata, typedata_size; int i, id, next_idx; int decoded_size, extra_attr = 0; - int num_params = 0, num_defaults = 0; - var_t *arg, *last_arg = NULL; + int num_params = 0, num_optional = 0, num_defaults = 0; + var_t *arg; char *namedata; const attr_t *attr; unsigned int funcflags = 0, callconv = 4 /* CC_STDCALL */; @@ -1276,31 +1294,36 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, func_t *func, int index) break; } - for(attr = func->def->attrs; attr; attr = NEXT_LINK(attr)) { - if(attr->type == ATTR_LOCAL) { - chat("add_func_desc: skipping local function\n"); - return S_FALSE; - } + if (is_local( func->def->attrs )) { + chat("add_func_desc: skipping local function\n"); + return S_FALSE; } - for(arg = func->args; arg; arg = NEXT_LINK(arg)) { - last_arg = arg; + if (func->args) + LIST_FOR_EACH_ENTRY( arg, func->args, var_t, entry ) + { num_params++; - for(attr = arg->attrs; attr; attr = NEXT_LINK(attr)) { - if(attr->type == ATTR_DEFAULTVALUE_EXPR || attr->type == ATTR_DEFAULTVALUE_STRING) { + if (arg->attrs) LIST_FOR_EACH_ENTRY( attr, arg->attrs, const attr_t, entry ) { + if(attr->type == ATTR_DEFAULTVALUE_EXPR || attr->type == ATTR_DEFAULTVALUE_STRING) num_defaults++; - break; - } + else if(attr->type == ATTR_OPTIONAL) + num_optional++; } - } + } chat("add_func_desc: num of params %d\n", num_params); name_offset = ctl2_alloc_name(typeinfo->typelib, func->def->name); - for(attr = func->def->attrs; attr; attr = NEXT_LINK(attr)) { + if (func->def->attrs) LIST_FOR_EACH_ENTRY( attr, func->def->attrs, const attr_t, entry ) { expr_t *expr = attr->u.pval; switch(attr->type) { + case ATTR_BINDABLE: + funcflags |= 0x4; /* FUNCFLAG_BINDABLE */ + break; + case ATTR_DISPLAYBIND: + funcflags |= 0x10; /* FUNCFLAG_DISPLAYBIND */ + break; case ATTR_ENTRY_ORDINAL: extra_attr = max(extra_attr, 3); entry = expr->cval; @@ -1328,6 +1351,9 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, func_t *func, int index) case ATTR_ID: id = expr->cval; break; + case ATTR_NONBROWSABLE: + funcflags |= 0x400; /* FUNCFLAG_NONBROWSABLE */ + break; case ATTR_OUT: break; case ATTR_PROPGET: @@ -1342,8 +1368,11 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, func_t *func, int index) case ATTR_RESTRICTED: funcflags |= 0x1; /* FUNCFLAG_FRESTRICTED */ break; - case ATTR_BINDABLE: - funcflags |= 0x4; /* FUNCFLAG_BINDABLE */ + case ATTR_VARARG: + if (num_optional || num_defaults) + warning("add_func_desc: ignoring vararg in function with optional or defaultvalue params\n"); + else + num_optional = -1; break; default: warning("add_func_desc: ignoring attr %d\n", attr->type); @@ -1351,25 +1380,6 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, func_t *func, int index) } } - switch(invokekind) { - case 0x2: /* INVOKE_PROPERTYGET */ - if((num_params != 0 && typeinfo->typekind == TKIND_DISPATCH) - || (num_params != 1 && typeinfo->typekind == TKIND_INTERFACE)) { - error("expecting no args on a propget func\n"); - return S_FALSE; - } - break; - case 0x4: /* INVOKE_PROPERTYPUT */ - case 0x8: /* INVOKE_PROPERTYPUTREF */ - if(num_params != 1) { - error("expecting one arg on a propput func\n"); - return S_FALSE; - } - break; - default: - break; - } - /* allocate type data space for us */ typedata_size = 0x18 + extra_attr * sizeof(int) + (num_params * (num_defaults ? 16 : 12)); @@ -1411,13 +1421,13 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, func_t *func, int index) /* fill out the basic type information */ typedata[0] = typedata_size | (index << 16); - encode_var(typeinfo->typelib, func->def, &typedata[1], NULL, NULL, &decoded_size); + encode_var(typeinfo->typelib, func->def->type, func->def, &typedata[1], NULL, NULL, &decoded_size); typedata[2] = funcflags; typedata[3] = ((52 /*sizeof(FUNCDESC)*/ + decoded_size) << 16) | typeinfo->typeinfo->cbSizeVft; typedata[4] = (next_idx << 16) | (callconv << 8) | (invokekind << 3) | funckind; if(num_defaults) typedata[4] |= 0x1000; if(entry_is_ord) typedata[4] |= 0x2000; - typedata[5] = num_params; + typedata[5] = (num_optional << 16) | num_params; /* NOTE: High word of typedata[3] is total size of FUNCDESC + size of all ELEMDESCs for params + TYPEDESCs for pointer params and return types. */ /* That is, total memory allocation required to reconstitute the FUNCDESC in its entirety. */ @@ -1437,7 +1447,11 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, func_t *func, int index) warning("unknown number of optional attrs\n"); } - for (arg = last_arg, i = 0; arg; arg = PREV_LINK(arg), i++) { + if (func->args) + { + i = 0; + LIST_FOR_EACH_ENTRY( arg, func->args, var_t, entry ) + { const attr_t *attr; int paramflags = 0; int *paramdata = typedata + 6 + extra_attr + (num_defaults ? num_params : 0) + i * 3; @@ -1445,8 +1459,8 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, func_t *func, int index) if(defaultdata) *defaultdata = -1; - encode_var(typeinfo->typelib, arg, paramdata, NULL, NULL, &decoded_size); - for(attr = arg->attrs; attr; attr = NEXT_LINK(attr)) { + encode_var(typeinfo->typelib, arg->type, arg, paramdata, NULL, NULL, &decoded_size); + if (arg->attrs) LIST_FOR_EACH_ENTRY( attr, arg->attrs, const attr_t, entry ) { switch(attr->type) { case ATTR_DEFAULTVALUE_EXPR: { @@ -1455,7 +1469,7 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, func_t *func, int index) if (arg->type->type == RPC_FC_ENUM16) vt = VT_INT; else - vt = get_var_vt(arg); + vt = get_type_vt(arg->type); paramflags |= 0x30; /* PARAMFLAG_FHASDEFAULT | PARAMFLAG_FOPT */ chat("default value %ld\n", expr->cval); write_value(typeinfo->typelib, defaultdata, vt, &expr->cval); @@ -1468,7 +1482,7 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, func_t *func, int index) if (arg->type->type == RPC_FC_ENUM16) vt = VT_INT; else - vt = get_var_vt(arg); + vt = get_type_vt(arg->type); paramflags |= 0x30; /* PARAMFLAG_FHASDEFAULT | PARAMFLAG_FOPT */ chat("default value '%s'\n", s); write_value(typeinfo->typelib, defaultdata, vt, s); @@ -1495,6 +1509,8 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, func_t *func, int index) paramdata[1] = -1; paramdata[2] = paramflags; typedata[3] += decoded_size << 16; + i++; + } } if(typeinfo->funcs_allocated == 0) { @@ -1511,7 +1527,7 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, func_t *func, int index) } /* update the index data */ - typeinfo->func_indices[typeinfo->typeinfo->cElement & 0xffff] = id; + typeinfo->func_indices[typeinfo->typeinfo->cElement & 0xffff] = id; typeinfo->func_offsets[typeinfo->typeinfo->cElement & 0xffff] = offset; typeinfo->func_names[typeinfo->typeinfo->cElement & 0xffff] = name_offset; @@ -1543,12 +1559,19 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, func_t *func, int index) if(typeinfo->typekind == TKIND_MODULE) namedata[9] |= 0x20; - if(invokekind != 0x4 /* INVOKE_PROPERTYPUT */ && invokekind != 0x8 /* INVOKE_PROPERTYPUTREF */) { - /* don't give the arg of a [propput*] func a name */ - for (arg = last_arg, i = 0; arg; arg = PREV_LINK(arg), i++) { - int *paramdata = typedata + 6 + extra_attr + (num_defaults ? num_params : 0) + i * 3; - offset = ctl2_alloc_name(typeinfo->typelib, arg->name); - paramdata[1] = offset; + if (func->args) + { + i = 0; + LIST_FOR_EACH_ENTRY( arg, func->args, var_t, entry ) + { + /* don't give the last arg of a [propput*] func a name */ + if(i != num_params - 1 || (invokekind != 0x4 /* INVOKE_PROPERTYPUT */ && invokekind != 0x8 /* INVOKE_PROPERTYPUTREF */)) + { + int *paramdata = typedata + 6 + extra_attr + (num_defaults ? num_params : 0) + i * 3; + offset = ctl2_alloc_name(typeinfo->typelib, arg->name); + paramdata[1] = offset; + } + i++; } } return S_OK; @@ -1561,18 +1584,18 @@ static HRESULT add_var_desc(msft_typeinfo_t *typeinfo, UINT index, var_t* var) INT *typedata; int var_datawidth; int var_alignment; - int var_type_size, var_kind = 0 /* VAR_PERINSTANCE */; + int var_type_size, var_kind = 0 /* VAR_PERINSTANCE */; int alignment; int varflags = 0; const attr_t *attr; char *namedata; int var_num = (typeinfo->typeinfo->cElement >> 16) & 0xffff; - chat("add_var_desc(%d,%s) array %p\n", index, var->name, var->array); + chat("add_var_desc(%d, %s)\n", index, var->name); id = 0x40000000 + index; - for(attr = var->attrs; attr; attr = NEXT_LINK(attr)) { + if (var->attrs) LIST_FOR_EACH_ENTRY( attr, var->attrs, const attr_t, entry ) { expr_t *expr = attr->u.pval; switch(attr->type) { case ATTR_HIDDEN: @@ -1638,7 +1661,7 @@ static HRESULT add_var_desc(msft_typeinfo_t *typeinfo, UINT index, var_t* var) typeinfo->var_offsets[var_num] = offset; /* figure out type widths and whatnot */ - encode_var(typeinfo->typelib, var, &typedata[1], &var_datawidth, + encode_var(typeinfo->typelib, var->type, var, &typedata[1], &var_datawidth, &var_alignment, &var_type_size); /* pad out starting position to data width */ @@ -1731,8 +1754,9 @@ static HRESULT add_impl_type(msft_typeinfo_t *typeinfo, type_t *ref, importinfo_ } static msft_typeinfo_t *create_msft_typeinfo(msft_typelib_t *typelib, enum type_kind kind, - const char *name, const attr_t *attr, int idx) + const char *name, const attr_list_t *attrs) { + const attr_t *attr; msft_typeinfo_t *msft_typeinfo; int nameoffset; int typeinfo_offset; @@ -1742,6 +1766,7 @@ static msft_typeinfo_t *create_msft_typeinfo(msft_typelib_t *typelib, enum type_ chat("create_msft_typeinfo: name %s kind %d\n", name, kind); msft_typeinfo = xmalloc(sizeof(*msft_typeinfo)); + memset( msft_typeinfo, 0, sizeof(*msft_typeinfo) ); msft_typeinfo->typelib = typelib; @@ -1760,7 +1785,7 @@ static msft_typeinfo_t *create_msft_typeinfo(msft_typelib_t *typelib, enum type_ if(kind == TKIND_COCLASS) typeinfo->flags |= 0x2; /* TYPEFLAG_FCANCREATE */ - for( ; attr; attr = NEXT_LINK(attr)) { + if (attrs) LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry ) { switch(attr->type) { case ATTR_AGGREGATABLE: if (kind == TKIND_COCLASS) @@ -1899,7 +1924,7 @@ static void add_dispatch(msft_typelib_t *typelib) static void add_dispinterface_typeinfo(msft_typelib_t *typelib, type_t *dispinterface) { int idx = 0; - func_t *func; + const func_t *func; var_t *var; msft_typeinfo_t *msft_typeinfo; @@ -1908,7 +1933,7 @@ static void add_dispinterface_typeinfo(msft_typelib_t *typelib, type_t *dispinte dispinterface->typelib_idx = typelib->typelib_header.nrtypeinfos; msft_typeinfo = create_msft_typeinfo(typelib, TKIND_DISPATCH, dispinterface->name, - dispinterface->attrs, typelib->typelib_header.nrtypeinfos); + dispinterface->attrs); msft_typeinfo->typeinfo->size = 4; msft_typeinfo->typeinfo->typekind |= 0x2100; @@ -1917,50 +1942,38 @@ static void add_dispinterface_typeinfo(msft_typelib_t *typelib, type_t *dispinte add_dispatch(typelib); msft_typeinfo->typeinfo->cImplTypes = 1; - /* count the no of funcs, as the variable indicies come after the funcs */ - if((func = dispinterface->funcs)) { - idx++; - while(NEXT_LINK(func)) { - func = NEXT_LINK(func); - idx++; - } - } + /* count the no of funcs, as the variable indices come after the funcs */ + if (dispinterface->funcs) + LIST_FOR_EACH_ENTRY( func, dispinterface->funcs, const func_t, entry ) idx++; - if((var = dispinterface->fields)) { - while(NEXT_LINK(var)) var = NEXT_LINK(var); - while(var) { - add_var_desc(msft_typeinfo, idx, var); - idx++; - var = PREV_LINK(var); - } - } + if (dispinterface->fields) + LIST_FOR_EACH_ENTRY( var, dispinterface->fields, var_t, entry ) + add_var_desc(msft_typeinfo, idx++, var); - idx = 0; - /* the func count above has already left us pointing at the first func */ - while(func) { - if(add_func_desc(msft_typeinfo, func, idx) == S_OK) - idx++; - func = PREV_LINK(func); + if (dispinterface->funcs) + { + idx = 0; + LIST_FOR_EACH_ENTRY( func, dispinterface->funcs, const func_t, entry ) + if(add_func_desc(msft_typeinfo, func, idx) == S_OK) + idx++; } } static void add_interface_typeinfo(msft_typelib_t *typelib, type_t *interface) { int idx = 0; - func_t *func; + const func_t *func; type_t *ref; msft_typeinfo_t *msft_typeinfo; importinfo_t *ref_importinfo = NULL; int num_parents = 0, num_funcs = 0; - const attr_t *attr; const type_t *derived; if (-1 < interface->typelib_idx) return; - for(attr = interface->attrs; attr; attr = NEXT_LINK(attr)) - if(attr->type == ATTR_DISPINTERFACE) - return add_dispinterface_typeinfo(typelib, interface); + if (is_attr(interface->attrs, ATTR_DISPINTERFACE)) + return add_dispinterface_typeinfo(typelib, interface); /* midl adds the parent interface first, unless the parent itself has no parent (i.e. it stops before IUnknown). */ @@ -1973,8 +1986,7 @@ static void add_interface_typeinfo(msft_typelib_t *typelib, type_t *interface) } interface->typelib_idx = typelib->typelib_header.nrtypeinfos; - msft_typeinfo = create_msft_typeinfo(typelib, TKIND_INTERFACE, interface->name, interface->attrs, - typelib->typelib_header.nrtypeinfos); + msft_typeinfo = create_msft_typeinfo(typelib, TKIND_INTERFACE, interface->name, interface->attrs); msft_typeinfo->typeinfo->size = 4; msft_typeinfo->typeinfo->typekind |= 0x2200; @@ -1992,86 +2004,64 @@ static void add_interface_typeinfo(msft_typelib_t *typelib, type_t *interface) /* count the number of inherited interfaces and non-local functions */ for(ref = interface->ref; ref; ref = ref->ref) { num_parents++; - for(func = ref->funcs; func; func = NEXT_LINK(func)) { - const attr_t *attr; - for(attr = func->def->attrs; attr; attr = NEXT_LINK(attr)) - if(attr->type == ATTR_LOCAL) - break; - if(!attr) - num_funcs++; - } + if (ref->funcs) + LIST_FOR_EACH_ENTRY( func, ref->funcs, const func_t, entry ) + if (!is_local(func->def->attrs)) num_funcs++; } msft_typeinfo->typeinfo->datatype2 = num_funcs << 16 | num_parents; msft_typeinfo->typeinfo->cbSizeVft = num_funcs * 4; - if((func = interface->funcs)) { - while(NEXT_LINK(func)) func = NEXT_LINK(func); - while(func) { + if (interface->funcs) + LIST_FOR_EACH_ENTRY( func, interface->funcs, const func_t, entry ) if(add_func_desc(msft_typeinfo, func, idx) == S_OK) idx++; - func = PREV_LINK(func); - } - } } static void add_structure_typeinfo(msft_typelib_t *typelib, type_t *structure) { int idx = 0; - var_t *cur = structure->fields; + var_t *cur; msft_typeinfo_t *msft_typeinfo; if (-1 < structure->typelib_idx) return; structure->typelib_idx = typelib->typelib_header.nrtypeinfos; - msft_typeinfo = create_msft_typeinfo(typelib, TKIND_RECORD, structure->name, structure->attrs, - typelib->typelib_header.nrtypeinfos); + msft_typeinfo = create_msft_typeinfo(typelib, TKIND_RECORD, structure->name, structure->attrs); msft_typeinfo->typeinfo->size = 0; - while(NEXT_LINK(cur)) cur = NEXT_LINK(cur); - while(cur) { - add_var_desc(msft_typeinfo, idx, cur); - idx++; - cur = PREV_LINK(cur); - } + if (structure->fields) + LIST_FOR_EACH_ENTRY( cur, structure->fields, var_t, entry ) + add_var_desc(msft_typeinfo, idx++, cur); } static void add_enum_typeinfo(msft_typelib_t *typelib, type_t *enumeration) { int idx = 0; - var_t *cur = enumeration->fields; + var_t *cur; msft_typeinfo_t *msft_typeinfo; enumeration->typelib_idx = typelib->typelib_header.nrtypeinfos; - msft_typeinfo = create_msft_typeinfo(typelib, TKIND_ENUM, enumeration->name, enumeration->attrs, - typelib->typelib_header.nrtypeinfos); + msft_typeinfo = create_msft_typeinfo(typelib, TKIND_ENUM, enumeration->name, enumeration->attrs); msft_typeinfo->typeinfo->size = 0; - while(NEXT_LINK(cur)) cur = NEXT_LINK(cur); - while(cur) { - add_var_desc(msft_typeinfo, idx, cur); - idx++; - cur = PREV_LINK(cur); - } + if (enumeration->fields) + LIST_FOR_EACH_ENTRY( cur, enumeration->fields, var_t, entry ) + add_var_desc(msft_typeinfo, idx++, cur); } -static void add_typedef_typeinfo(msft_typelib_t *typelib, var_t *tdef) +static void add_typedef_typeinfo(msft_typelib_t *typelib, type_t *tdef) { msft_typeinfo_t *msft_typeinfo; int alignment; - const attr_t *attrs; - if (-1 < tdef->type->typelib_idx) + if (-1 < tdef->typelib_idx) return; - tdef->type->typelib_idx = typelib->typelib_header.nrtypeinfos; - msft_typeinfo = create_msft_typeinfo(typelib, TKIND_ALIAS, tdef->name, tdef->type->attrs, - typelib->typelib_header.nrtypeinfos); - attrs = tdef->type->attrs; - tdef->type->attrs = NULL; - encode_var(typelib, tdef, &msft_typeinfo->typeinfo->datatype1, &msft_typeinfo->typeinfo->size, + tdef->typelib_idx = typelib->typelib_header.nrtypeinfos; + msft_typeinfo = create_msft_typeinfo(typelib, TKIND_ALIAS, tdef->name, tdef->attrs); + encode_type(typelib, get_type_vt(tdef->orig), tdef->orig, &msft_typeinfo->typeinfo->datatype1, &msft_typeinfo->typeinfo->size, &alignment, &msft_typeinfo->typeinfo->datatype2); - tdef->type->attrs = attrs; msft_typeinfo->typeinfo->typekind |= (alignment << 11 | alignment << 6); } @@ -2088,20 +2078,15 @@ static void add_coclass_typeinfo(msft_typelib_t *typelib, type_t *cls) return; cls->typelib_idx = typelib->typelib_header.nrtypeinfos; - msft_typeinfo = create_msft_typeinfo(typelib, TKIND_COCLASS, cls->name, cls->attrs, - typelib->typelib_header.nrtypeinfos); + msft_typeinfo = create_msft_typeinfo(typelib, TKIND_COCLASS, cls->name, cls->attrs); - if((iref = cls->ifaces)) { - num_ifaces++; - while(NEXT_LINK(iref)) { - iref = NEXT_LINK(iref); - num_ifaces++; - } - } + if (cls->ifaces) LIST_FOR_EACH_ENTRY( iref, cls->ifaces, ifref_t, entry ) num_ifaces++; offset = msft_typeinfo->typeinfo->datatype1 = ctl2_alloc_segment(typelib, MSFT_SEG_REFERENCES, num_ifaces * sizeof(*ref), 0); - for(i = 0; i < num_ifaces; i++) { + + i = 0; + if (cls->ifaces) LIST_FOR_EACH_ENTRY( iref, cls->ifaces, ifref_t, entry ) { if(iref->iface->typelib_idx == -1) add_interface_typeinfo(typelib, iref->iface); ref = (MSFT_RefRecord*) (typelib->typelib_segment_data[MSFT_SEG_REFERENCES] + offset + i * sizeof(*ref)); @@ -2112,7 +2097,7 @@ static void add_coclass_typeinfo(msft_typelib_t *typelib, type_t *cls) if(i < num_ifaces - 1) ref->onext = offset + (i + 1) * sizeof(*ref); - for(attr = iref->attrs; attr; attr = NEXT_LINK(attr)) { + if (iref->attrs) LIST_FOR_EACH_ENTRY( attr, iref->attrs, const attr_t, entry ) { switch(attr->type) { case ATTR_DEFAULT: ref->flags |= 0x1; /* IMPLTYPEFLAG_FDEFAULT */ @@ -2144,7 +2129,7 @@ static void add_coclass_typeinfo(msft_typelib_t *typelib, type_t *cls) else if(!first) first = ref; } - iref = PREV_LINK(iref); + i++; } /* If we haven't had a default interface, then set the default flags on the @@ -2162,57 +2147,54 @@ static void add_coclass_typeinfo(msft_typelib_t *typelib, type_t *cls) static void add_module_typeinfo(msft_typelib_t *typelib, type_t *module) { int idx = 0; - func_t *func; + const func_t *func; msft_typeinfo_t *msft_typeinfo; if (-1 < module->typelib_idx) return; module->typelib_idx = typelib->typelib_header.nrtypeinfos; - msft_typeinfo = create_msft_typeinfo(typelib, TKIND_MODULE, module->name, module->attrs, - typelib->typelib_header.nrtypeinfos); + msft_typeinfo = create_msft_typeinfo(typelib, TKIND_MODULE, module->name, module->attrs); msft_typeinfo->typeinfo->typekind |= 0x0a00; - if((func = module->funcs)) { - while(NEXT_LINK(func)) func = NEXT_LINK(func); - while(func) { + if (module->funcs) + LIST_FOR_EACH_ENTRY( func, module->funcs, const func_t, entry ) if(add_func_desc(msft_typeinfo, func, idx) == S_OK) idx++; - func = PREV_LINK(func); - } - } + msft_typeinfo->typeinfo->size = idx; } static void add_entry(msft_typelib_t *typelib, typelib_entry_t *entry) { - switch(entry->kind) { + switch(entry->type->kind) { case TKIND_INTERFACE: - add_interface_typeinfo(typelib, entry->u.interface); + case TKIND_DISPATCH: + add_interface_typeinfo(typelib, entry->type); break; case TKIND_RECORD: - add_structure_typeinfo(typelib, entry->u.structure); + add_structure_typeinfo(typelib, entry->type); break; case TKIND_ENUM: - add_enum_typeinfo(typelib, entry->u.enumeration); + add_enum_typeinfo(typelib, entry->type); break; case TKIND_ALIAS: - add_typedef_typeinfo(typelib, entry->u.tdef); + add_typedef_typeinfo(typelib, entry->type); break; case TKIND_COCLASS: - add_coclass_typeinfo(typelib, entry->u.class); + add_coclass_typeinfo(typelib, entry->type); break; case TKIND_MODULE: - add_module_typeinfo(typelib, entry->u.module); + add_module_typeinfo(typelib, entry->type); break; default: - error("add_entry: unhandled type %d\n", entry->kind); + error("add_entry: unhandled type %d\n", entry->type->kind); break; } } @@ -2229,39 +2211,24 @@ static void set_name(msft_typelib_t *typelib) static void set_version(msft_typelib_t *typelib) { - long version = MAKELONG(0,0); - const attr_t *attr; - - for(attr = typelib->typelib->attrs; attr; attr = NEXT_LINK(attr)) { - if(attr->type == ATTR_VERSION) { - version = attr->u.ival; - } - } - typelib->typelib_header.version = version; - return; + typelib->typelib_header.version = get_attrv( typelib->typelib->attrs, ATTR_VERSION ); } static void set_guid(msft_typelib_t *typelib) { MSFT_GuidEntry guidentry; int offset; - const attr_t *attr; + void *ptr; GUID guid = {0,0,0,{0,0,0,0,0,0}}; guidentry.guid = guid; guidentry.hreftype = -2; guidentry.next_hash = -1; - for(attr = typelib->typelib->attrs; attr; attr = NEXT_LINK(attr)) { - if(attr->type == ATTR_UUID) { - guidentry.guid = *(GUID*)(attr->u.pval); - } - } + ptr = get_attrp( typelib->typelib->attrs, ATTR_UUID ); + if (ptr) guidentry.guid = *(GUID *)ptr; offset = ctl2_alloc_guid(typelib, &guidentry); - - if (offset == -1) return; - typelib->typelib_header.posguid = offset; return; @@ -2269,71 +2236,55 @@ static void set_guid(msft_typelib_t *typelib) static void set_doc_string(msft_typelib_t *typelib) { - const attr_t *attr; - int offset; + char *str = get_attrp( typelib->typelib->attrs, ATTR_HELPSTRING ); - for(attr = typelib->typelib->attrs; attr; attr = NEXT_LINK(attr)) { - if(attr->type == ATTR_HELPSTRING) { - offset = ctl2_alloc_string(typelib, attr->u.pval); - if (offset == -1) return; - typelib->typelib_header.helpstring = offset; - } + if (str) + { + int offset = ctl2_alloc_string(typelib, str); + if (offset != -1) typelib->typelib_header.helpstring = offset; } - return; } static void set_help_file_name(msft_typelib_t *typelib) { - int offset; - const attr_t *attr; - for(attr = typelib->typelib->attrs; attr; attr = NEXT_LINK(attr)) { - if(attr->type == ATTR_HELPFILE) { - offset = ctl2_alloc_string(typelib, attr->u.pval); - if (offset == -1) return; + char *str = get_attrp( typelib->typelib->attrs, ATTR_HELPFILE ); + + if (str) + { + int offset = ctl2_alloc_string(typelib, str); + if (offset != -1) + { typelib->typelib_header.helpfile = offset; typelib->typelib_header.varflags |= 0x10; } } - return; } static void set_help_context(msft_typelib_t *typelib) { - const attr_t *attr; - for(attr = typelib->typelib->attrs; attr; attr = NEXT_LINK(attr)) { - if(attr->type == ATTR_HELPCONTEXT) { - const expr_t *expr = (expr_t *)attr->u.pval; - typelib->typelib_header.helpcontext = expr->cval; - } - } - return; + const expr_t *expr = get_attrp( typelib->typelib->attrs, ATTR_HELPCONTEXT ); + if (expr) typelib->typelib_header.helpcontext = expr->cval; } static void set_help_string_dll(msft_typelib_t *typelib) { - int offset; - const attr_t *attr; - for(attr = typelib->typelib->attrs; attr; attr = NEXT_LINK(attr)) { - if(attr->type == ATTR_HELPSTRINGDLL) { - offset = ctl2_alloc_string(typelib, attr->u.pval); - if (offset == -1) return; + char *str = get_attrp( typelib->typelib->attrs, ATTR_HELPSTRINGDLL ); + + if (str) + { + int offset = ctl2_alloc_string(typelib, str); + if (offset != -1) + { typelib->help_string_dll_offset = offset; typelib->typelib_header.varflags |= 0x100; } } - return; } static void set_help_string_context(msft_typelib_t *typelib) { - const attr_t *attr; - for(attr = typelib->typelib->attrs; attr; attr = NEXT_LINK(attr)) { - if(attr->type == ATTR_HELPSTRINGCONTEXT) { - const expr_t *expr = (expr_t *)attr->u.pval; - typelib->typelib_header.helpstringcontext = expr->cval; - } - } - return; + const expr_t *expr = get_attrp( typelib->typelib->attrs, ATTR_HELPSTRINGCONTEXT ); + if (expr) typelib->typelib_header.helpstringcontext = expr->cval; } static void set_lcid(msft_typelib_t *typelib) @@ -2347,7 +2298,9 @@ static void set_lib_flags(msft_typelib_t *typelib) const attr_t *attr; typelib->typelib_header.flags = 0; - for(attr = typelib->typelib->attrs; attr; attr = NEXT_LINK(attr)) { + if (!typelib->typelib->attrs) return; + LIST_FOR_EACH_ENTRY( attr, typelib->typelib->attrs, const attr_t, entry ) + { switch(attr->type) { case ATTR_CONTROL: typelib->typelib_header.flags |= 0x02; /* LIBFLAG_FCONTROL */ @@ -2436,7 +2389,7 @@ static void ctl2_write_typeinfos(msft_typelib_t *typelib, int fd) if (typeinfo->func_names) ctl2_write_chunk(fd, typeinfo->func_names, (typeinfo->typeinfo->cElement & 0xffff) * 4); if (typeinfo->var_names) - ctl2_write_chunk(fd, typeinfo->var_names, (typeinfo->typeinfo->cElement >> 16) * 4); + ctl2_write_chunk(fd, typeinfo->var_names, (typeinfo->typeinfo->cElement >> 16) * 4); if (typeinfo->func_offsets) ctl2_write_chunk(fd, typeinfo->func_offsets, (typeinfo->typeinfo->cElement & 0xffff) * 4); if (typeinfo->var_offsets) { @@ -2520,12 +2473,12 @@ int create_msft_typelib(typelib_t *typelib) int failed = 0; typelib_entry_t *entry; time_t cur_time; + char *time_override; unsigned int version = 5 << 24 | 1 << 16 | 164; /* 5.01.0164 */ - GUID midl_time_guid = {0xde77ba63,0x517c,0x11d1,{0xa2,0xda,0x00,0x00,0xf8,0x77,0x3c,0xe9}}; - GUID midl_version_guid = {0xde77ba64,0x517c,0x11d1,{0xa2,0xda,0x00,0x00,0xf8,0x77,0x3c,0xe9}}; + GUID midl_time_guid = {0xde77ba63,0x517c,0x11d1,{0xa2,0xda,0x00,0x00,0xf8,0x77,0x3c,0xe9}}; + GUID midl_version_guid = {0xde77ba64,0x517c,0x11d1,{0xa2,0xda,0x00,0x00,0xf8,0x77,0x3c,0xe9}}; - msft = malloc(sizeof(*msft)); - if (!msft) return 0; + msft = xmalloc(sizeof(*msft)); memset(msft, 0, sizeof(*msft)); msft->typelib = typelib; @@ -2541,7 +2494,11 @@ int create_msft_typelib(typelib_t *typelib) if (ctl2_alloc_segment(msft, MSFT_SEG_GUIDHASH, 0x80, 0x80)) { failed = 1; } if (ctl2_alloc_segment(msft, MSFT_SEG_NAMEHASH, 0x200, 0x200)) { failed = 1; } - if(failed) return 0; + if(failed) + { + free(msft); + return 0; + } msft->typelib_guidhash_segment = (int *)msft->typelib_segment_data[MSFT_SEG_GUIDHASH]; msft->typelib_namehash_segment = (int *)msft->typelib_segment_data[MSFT_SEG_NAMEHASH]; @@ -2559,19 +2516,18 @@ int create_msft_typelib(typelib_t *typelib) set_help_context(msft); set_help_string_dll(msft); set_help_string_context(msft); - + /* midl adds two sets of custom data to the library: the current unix time and midl's version number */ - cur_time = time(NULL); + time_override = getenv( "WIDL_TIME_OVERRIDE"); + cur_time = time_override ? atol( time_override) : time(NULL); set_custdata(msft, &midl_time_guid, VT_UI4, &cur_time, &msft->typelib_header.CustomDataOffset); set_custdata(msft, &midl_version_guid, VT_UI4, &version, &msft->typelib_header.CustomDataOffset); - for(entry = typelib->entry; entry && NEXT_LINK(entry); entry = NEXT_LINK(entry)) - ; - - for( ; entry; entry = PREV_LINK(entry)) + LIST_FOR_EACH_ENTRY( entry, &typelib->entries, typelib_entry_t, entry ) add_entry(msft, entry); save_all_changes(msft); + free(msft); return 1; } diff --git a/reactos/tools/widl_20080105/client.c b/reactos/tools/widl_20080105/client.c deleted file mode 100644 index 5cd2a81800b..00000000000 --- a/reactos/tools/widl_20080105/client.c +++ /dev/null @@ -1,447 +0,0 @@ -/* - * IDL Compiler - * - * Copyright 2005-2006 Eric Kohl - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" -#include "wine/port.h" - -#include -#include -#include -#include -#include -#include -#include - -#include "widl.h" -#include "utils.h" -#include "parser.h" -#include "header.h" - -#include "widltypes.h" -#include "typegen.h" - -static FILE* client; -static int indent = 0; - -static void print_client( const char *format, ... ) -{ - va_list va; - va_start(va, format); - print(client, indent, format, va); - va_end(va); -} - - -static void check_pointers(const func_t *func) -{ - const var_t *var; - - if (!func->args) - return; - - LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) - { - if (is_var_ptr(var) && cant_be_null(var)) - { - print_client("if (!%s)\n", var->name); - print_client("{\n"); - indent++; - print_client("RpcRaiseException(RPC_X_NULL_REF_POINTER);\n"); - indent--; - print_client("}\n\n"); - } - } -} - -static void write_function_stubs(type_t *iface, unsigned int *proc_offset) -{ - const func_t *func; - const char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE); - int explicit_handle = is_attr(iface->attrs, ATTR_EXPLICIT_HANDLE); - const var_t *var; - int method_count = 0; - - if (!implicit_handle) - print_client("static RPC_BINDING_HANDLE %s__MIDL_AutoBindHandle;\n\n", iface->name); - - if (iface->funcs) LIST_FOR_EACH_ENTRY( func, iface->funcs, const func_t, entry ) - { - const var_t *def = func->def; - const var_t* explicit_handle_var; - - /* check for a defined binding handle */ - explicit_handle_var = get_explicit_handle_var(func); - if (explicit_handle) - { - if (!explicit_handle_var) - { - error("%s() does not define an explicit binding handle!\n", def->name); - return; - } - } - else if (implicit_handle) - { - if (explicit_handle_var) - { - error("%s() must not define a binding handle!\n", def->name); - return; - } - } - - write_type_decl_left(client, def->type); - if (needs_space_after(def->type)) - fprintf(client, " "); - write_prefix_name(client, prefix_client, def); - fprintf(client, "(\n"); - indent++; - if (func->args) - write_args(client, func->args, iface->name, 0, TRUE); - else - print_client("void"); - fprintf(client, ")\n"); - indent--; - - /* write the functions body */ - fprintf(client, "{\n"); - indent++; - - /* declare return value '_RetVal' */ - if (!is_void(def->type)) - { - print_client(""); - write_type_decl_left(client, def->type); - fprintf(client, " _RetVal;\n"); - } - - if (implicit_handle || explicit_handle_var) - print_client("RPC_BINDING_HANDLE _Handle = 0;\n"); - - print_client("RPC_MESSAGE _RpcMessage;\n"); - print_client("MIDL_STUB_MESSAGE _StubMsg;\n"); - if (!is_void(def->type) && decl_indirect(def->type)) - { - print_client("void *_p_%s = &%s;\n", - "_RetVal", "_RetVal"); - } - fprintf(client, "\n"); - - /* check pointers */ - check_pointers(func); - - print_client("RpcTryFinally\n"); - print_client("{\n"); - indent++; - - print_client("NdrClientInitializeNew(\n"); - indent++; - print_client("(PRPC_MESSAGE)&_RpcMessage,\n"); - print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n"); - print_client("(PMIDL_STUB_DESC)&%s_StubDesc,\n", iface->name); - print_client("%d);\n", method_count); - indent--; - fprintf(client, "\n"); - - if (implicit_handle) - { - print_client("_Handle = %s;\n", implicit_handle); - fprintf(client, "\n"); - } - else if (explicit_handle_var) - { - print_client("_Handle = %s;\n", explicit_handle_var->name); - fprintf(client, "\n"); - } - - write_remoting_arguments(client, indent, func, PASS_IN, PHASE_BUFFERSIZE); - - print_client("NdrGetBuffer(\n"); - indent++; - print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n"); - print_client("_StubMsg.BufferLength,\n"); - if (implicit_handle || explicit_handle_var) - print_client("_Handle);\n"); - else - print_client("%s__MIDL_AutoBindHandle);\n", iface->name); - indent--; - fprintf(client, "\n"); - - /* marshal arguments */ - write_remoting_arguments(client, indent, func, PASS_IN, PHASE_MARSHAL); - - /* send/receive message */ - /* print_client("NdrNsSendReceive(\n"); */ - /* print_client("(unsigned char *)_StubMsg.Buffer,\n"); */ - /* print_client("(RPC_BINDING_HANDLE *) &%s__MIDL_AutoBindHandle);\n", iface->name); */ - print_client("NdrSendReceive(\n"); - indent++; - print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n"); - print_client("(unsigned char *)_StubMsg.Buffer);\n\n"); - indent--; - - print_client("_StubMsg.BufferStart = (unsigned char *)_RpcMessage.Buffer;\n"); - print_client("_StubMsg.BufferEnd = _StubMsg.BufferStart + _RpcMessage.BufferLength;\n"); - - if (has_out_arg_or_return(func)) - { - fprintf(client, "\n"); - - print_client("if ((_RpcMessage.DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION)\n"); - indent++; - print_client("NdrConvert(\n"); - indent++; - print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n"); - print_client("(PFORMAT_STRING)&__MIDL_ProcFormatString.Format[%u]);\n", *proc_offset); - indent -= 2; - } - - /* unmarshall arguments */ - fprintf(client, "\n"); - write_remoting_arguments(client, indent, func, PASS_OUT, PHASE_UNMARSHAL); - - /* unmarshal return value */ - if (!is_void(def->type)) - { - if (decl_indirect(def->type)) - print_client("MIDL_memset(&%s, 0, sizeof(%s));\n", "_RetVal", "_RetVal"); - else if (is_ptr(def->type) || is_array(def->type)) - print_client("%s = 0;\n", "_RetVal"); - write_remoting_arguments(client, indent, func, PASS_RETURN, PHASE_UNMARSHAL); - } - - /* update proc_offset */ - if (func->args) - { - LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) - *proc_offset += get_size_procformatstring_var(var); - } - if (!is_void(def->type)) - *proc_offset += get_size_procformatstring_var(def); - else - *proc_offset += 2; /* FC_END and FC_PAD */ - - indent--; - print_client("}\n"); - print_client("RpcFinally\n"); - print_client("{\n"); - indent++; - - - /* FIXME: emit client finally code */ - - print_client("NdrFreeBuffer((PMIDL_STUB_MESSAGE)&_StubMsg);\n"); - - indent--; - print_client("}\n"); - print_client("RpcEndFinally\n"); - - - /* emit return code */ - if (!is_void(def->type)) - { - fprintf(client, "\n"); - print_client("return _RetVal;\n"); - } - - indent--; - fprintf(client, "}\n"); - fprintf(client, "\n"); - - method_count++; - } -} - - -static void write_stubdescdecl(type_t *iface) -{ - print_client("static const MIDL_STUB_DESC %s_StubDesc;\n", iface->name); - fprintf(client, "\n"); -} - - -static void write_stubdescriptor(type_t *iface, int expr_eval_routines) -{ - const char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE); - - print_client("static const MIDL_STUB_DESC %s_StubDesc =\n", iface->name); - print_client("{\n"); - indent++; - print_client("(void *)& %s___RpcClientInterface,\n", iface->name); - print_client("MIDL_user_allocate,\n"); - print_client("MIDL_user_free,\n"); - print_client("{\n"); - indent++; - if (implicit_handle) - print_client("&%s,\n", implicit_handle); - else - print_client("&%s__MIDL_AutoBindHandle,\n", iface->name); - indent--; - print_client("},\n"); - print_client("0,\n"); - print_client("0,\n"); - if (expr_eval_routines) - print_client("ExprEvalRoutines,\n"); - else - print_client("0,\n"); - print_client("0,\n"); - print_client("__MIDL_TypeFormatString.Format,\n"); - print_client("1, /* -error bounds_check flag */\n"); - print_client("0x10001, /* Ndr library version */\n"); - print_client("0,\n"); - print_client("0x50100a4, /* MIDL Version 5.1.164 */\n"); - print_client("0,\n"); - print_client("%s,\n", list_empty(&user_type_list) ? "0" : "UserMarshalRoutines"); - print_client("0, /* notify & notify_flag routine table */\n"); - print_client("1, /* Flags */\n"); - print_client("0, /* Reserved3 */\n"); - print_client("0, /* Reserved4 */\n"); - print_client("0 /* Reserved5 */\n"); - indent--; - print_client("};\n"); - fprintf(client, "\n"); -} - - -static void write_clientinterfacedecl(type_t *iface) -{ - unsigned long ver = get_attrv(iface->attrs, ATTR_VERSION); - const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID); - const str_list_t *endpoints = get_attrp(iface->attrs, ATTR_ENDPOINT); - - if (endpoints) write_endpoints( client, iface->name, endpoints ); - - print_client("static const RPC_CLIENT_INTERFACE %s___RpcClientInterface =\n", iface->name ); - print_client("{\n"); - indent++; - print_client("sizeof(RPC_CLIENT_INTERFACE),\n"); - print_client("{{0x%08lx,0x%04x,0x%04x,{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x}},{%d,%d}},\n", - uuid->Data1, uuid->Data2, uuid->Data3, uuid->Data4[0], uuid->Data4[1], - uuid->Data4[2], uuid->Data4[3], uuid->Data4[4], uuid->Data4[5], uuid->Data4[6], - uuid->Data4[7], MAJORVERSION(ver), MINORVERSION(ver)); - print_client("{{0x8a885d04,0x1ceb,0x11c9,{0x9f,0xe8,0x08,0x00,0x2b,0x10,0x48,0x60}},{2,0}},\n"); /* FIXME */ - print_client("0,\n"); - if (endpoints) - { - print_client("%u,\n", list_count(endpoints)); - print_client("(PRPC_PROTSEQ_ENDPOINT)%s__RpcProtseqEndpoint,\n", iface->name); - } - else - { - print_client("0,\n"); - print_client("0,\n"); - } - print_client("0,\n"); - print_client("0,\n"); - print_client("0,\n"); - indent--; - print_client("};\n"); - if (old_names) - print_client("RPC_IF_HANDLE %s_ClientIfHandle = (RPC_IF_HANDLE)& %s___RpcClientInterface;\n", - iface->name, iface->name); - else - print_client("RPC_IF_HANDLE %s%s_v%d_%d_c_ifspec = (RPC_IF_HANDLE)& %s___RpcClientInterface;\n", - prefix_client, iface->name, MAJORVERSION(ver), MINORVERSION(ver), iface->name); - fprintf(client, "\n"); -} - - -static void write_implicithandledecl(type_t *iface) -{ - const char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE); - - if (implicit_handle) - { - fprintf(client, "handle_t %s;\n", implicit_handle); - fprintf(client, "\n"); - } -} - - -static void init_client(void) -{ - if (client) return; - if (!(client = fopen(client_name, "w"))) - error("Could not open %s for output\n", client_name); - - print_client("/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n", PACKAGE_VERSION, input_name); - print_client("#include \n"); - print_client("#ifdef _ALPHA_\n"); - print_client("#include \n"); - print_client("#endif\n"); - fprintf(client, "\n"); - print_client("#include \"%s\"\n", header_name); - fprintf(client, "\n"); -} - - -void write_client(ifref_list_t *ifaces) -{ - unsigned int proc_offset = 0; - int expr_eval_routines; - ifref_t *iface; - - if (!do_client) - return; - if (do_everything && !need_stub_files(ifaces)) - return; - - init_client(); - if (!client) - return; - - write_formatstringsdecl(client, indent, ifaces, need_stub); - expr_eval_routines = write_expr_eval_routines(client, client_token); - if (expr_eval_routines) - write_expr_eval_routine_list(client, client_token); - write_user_quad_list(client); - - if (ifaces) LIST_FOR_EACH_ENTRY( iface, ifaces, ifref_t, entry ) - { - if (!need_stub(iface->iface)) - continue; - - fprintf(client, "/*****************************************************************************\n"); - fprintf(client, " * %s interface\n", iface->iface->name); - fprintf(client, " */\n"); - fprintf(client, "\n"); - - if (iface->iface->funcs) - { - write_implicithandledecl(iface->iface); - - write_clientinterfacedecl(iface->iface); - write_stubdescdecl(iface->iface); - write_function_stubs(iface->iface, &proc_offset); - - print_client("#if !defined(__RPC_WIN32__)\n"); - print_client("#error Invalid build platform for this stub.\n"); - print_client("#endif\n"); - - fprintf(client, "\n"); - write_stubdescriptor(iface->iface, expr_eval_routines); - } - } - - fprintf(client, "\n"); - - write_procformatstring(client, ifaces, need_stub); - write_typeformatstring(client, ifaces, need_stub); - - fclose(client); -} diff --git a/reactos/tools/widl_20080105/hash.c b/reactos/tools/widl_20080105/hash.c deleted file mode 100644 index 46eafeed9fa..00000000000 --- a/reactos/tools/widl_20080105/hash.c +++ /dev/null @@ -1,622 +0,0 @@ -/* - * Oleaut32 hash functions - * - * Copyright 1999 Corel Corporation - * Copyright 2001-2003 Jon Griffiths - * - * 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 -#include - -#include "windef.h" -#include "winbase.h" -#include "winnls.h" - -#include "hash.h" - -static const unsigned char Lookup_16[128 * 3] = { - /* Common */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, - 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, - 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, - 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x00, 0x30, 0x31, 0x32, 0x33, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, - 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, - 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x56, 0x58, 0x55, 0x5A, - 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, - 0x55, 0x56, 0x56, 0x58, 0x55, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, - - /* Windows */ - 0x7F, 0x7F, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x7F, 0x89, 0x53, 0x8B, 0x8C, - 0x7F, 0x7F, 0x7F, 0x7F, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x96, 0x98, 0x99, - 0x53, 0x9B, 0x8C, 0x7F, 0x7F, 0x55, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, - 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x96, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, - 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, - 0x49, 0x49, 0x44, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0xD7, 0x4F, 0x55, 0x55, - 0x55, 0x55, 0x55, 0xDE, 0xDF, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x43, - 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0x44, 0x4E, 0x4F, 0x4F, 0x4F, - 0x4F, 0x4F, 0xF7, 0x4F, 0x55, 0x55, 0x55, 0x55, 0x55, 0xDE, 0x55, - - /* Mac */ - 0x41, 0x41, 0x43, 0x45, 0x4E, 0x4F, 0x55, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0x4E, 0x4F, 0x4F, 0x4F, - 0x4F, 0x4F, 0x55, 0x55, 0x55, 0x55, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, - 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0x41, 0x4F, 0xB0, 0xB1, 0xB2, 0xB3, - 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0x41, 0x4F, 0xBD, 0x41, 0x4F, 0xC0, - 0xC1, 0xC2, 0xC3, 0x46, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0x41, 0x41, 0x4F, - 0xCE, 0xCE, 0xD0, 0xD0, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0x55, 0x55, 0xDA, - 0xDB, 0xDC, 0xDD, 0x3F, 0x3F, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0x41, 0x45, 0x41, - 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0x4F, 0x4F, 0x3F, 0x4F, 0x55, 0x55, 0x55, - 0x49, 0x7F, 0xF7, 0x7F, 0xF9, 0xFA, 0xFB, 0x3F, 0xFD, 0xFE, 0x7F -}; - -static const unsigned char Lookup_32[128 * 3] = { - /* Common */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, - 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, - 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, - 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x00, 0x30, 0x31, 0x32, 0x33, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, - 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, - 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, - 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, - 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, - - /* Windows */ - 0x7F, 0x7F, 0x82, 0x7F, 0x84, 0x85, 0x86, 0x87, 0x7F, 0x89, 0x53, 0x8B, 0x53, - 0x54, 0x5A, 0x5A, 0x7F, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x96, 0x7F, 0x99, - 0x53, 0x9B, 0x53, 0x54, 0x5A, 0x5A, 0xA0, 0x7F, 0xA2, 0x4C, 0xA4, 0x41, 0xA6, - 0xA7, 0xA8, 0xA9, 0x53, 0xAB, 0xAC, 0x96, 0xAE, 0x5A, 0xB0, 0xB1, 0xB2, 0x4C, - 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x41, 0x53, 0xBB, 0x4C, 0xBD, 0x4C, 0x5A, 0x52, - 0x41, 0x41, 0x41, 0x41, 0x4C, 0x43, 0x43, 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, - 0x49, 0x44, 0xD0, 0x4E, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0xD7, 0x52, 0x55, 0x55, - 0x55, 0x55, 0x59, 0x54, 0xDF, 0x52, 0x41, 0x41, 0x41, 0x41, 0x4C, 0x43, 0x43, - 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x44, 0xD0, 0x4E, 0x4E, 0x4F, 0x4F, - 0x4F, 0x4F, 0xF7, 0x52, 0x55, 0x55, 0x55, 0x55, 0x59, 0x54, 0xFF, - - /* Mac */ - 0x41, 0x41, 0x41, 0x45, 0x41, 0x4F, 0x55, 0x41, 0x41, 0x43, 0x41, 0x43, 0x43, - 0x43, 0x45, 0x5A, 0x5A, 0x44, 0x49, 0x44, 0x45, 0x45, 0x45, 0x4F, 0x45, 0x4F, - 0x4F, 0x4F, 0x55, 0x45, 0x45, 0x55, 0xA0, 0xA1, 0x45, 0xA3, 0xA4, 0xA5, 0xA6, - 0xA7, 0xA8, 0xA9, 0xAA, 0x45, 0xAC, 0xAD, 0x47, 0x49, 0x49, 0x49, 0xB2, 0xB3, - 0x49, 0x4B, 0xB6, 0xB7, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4E, 0x4E, - 0x4E, 0xC2, 0xC3, 0x4E, 0x4E, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0x4E, 0x4F, 0x4F, - 0x4F, 0x4F, 0xD0, 0xD0, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0x4F, 0x52, 0x52, - 0x52, 0xDC, 0xDD, 0x52, 0x52, 0x52, 0x53, 0xE2, 0xE3, 0x53, 0x53, 0x53, 0x41, - 0x54, 0x54, 0x49, 0x5A, 0x5A, 0x55, 0x4F, 0x4F, 0x55, 0x55, 0x55, 0x55, 0x55, - 0x55, 0x55, 0x55, 0x59, 0x59, 0x4B, 0x5A, 0x4C, 0x4C, 0x47, 0xFF -}; - -static const unsigned char Lookup_48[128 * 3] = { - /* Common */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, - 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, - 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, - 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x00, 0x30, 0x31, 0x32, 0x33, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, - 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, - 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, - 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, - 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, - - /* Windows */ - 0x7F, 0x7F, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x7F, 0x89, 0x53, 0x8B, 0x8C, - 0x7F, 0x7F, 0x7F, 0x7F, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x96, 0x98, 0x99, - 0x53, 0x9B, 0x8C, 0x7F, 0x7F, 0x59, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, - 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x96, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, - 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0xC6, 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, - 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0xD7, 0x4F, 0x55, 0x55, - 0x55, 0x55, 0x59, 0xDE, 0xDF, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0xC6, 0x43, - 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0x4F, 0x4F, - 0x4F, 0x4F, 0xF7, 0x4F, 0x55, 0x55, 0x55, 0x55, 0x59, 0xDE, 0x59, - - /* Mac */ - 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, - 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, - 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, - 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAB, 0xAD, 0xAE, 0xAE, 0xB0, 0xB1, 0xB2, 0xB3, - 0xA7, 0xB5, 0xB6, 0xB7, 0xB8, 0xB8, 0xBA, 0xBA, 0xBC, 0xBC, 0xBE, 0xBE, 0xB7, - 0xC1, 0xC2, 0xC3, 0x46, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCB, 0xCD, - 0xCD, 0xC1, 0xD0, 0xD0, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD8, 0xDA, - 0xDA, 0xDC, 0xDD, 0xDD, 0x9F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, - 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F -}; - -static const unsigned char Lookup_64[128 * 3] = { - /* Common */ - 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, - 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, - 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x00, 0x30, 0x31, 0x32, 0x33, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, - 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, - 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x56, 0x58, 0x55, 0x5A, - 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, - 0x55, 0x56, 0x56, 0x58, 0x55, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, - -/* Windows */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, - 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x96, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, - 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, - 0x49, 0x49, 0x44, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0xD7, 0x4F, 0x55, 0x55, - 0x55, 0x55, 0x55, 0xDE, 0xDF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - /* Mac */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, - 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x96, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, - 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, - 0x49, 0x49, 0x44, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0xD7, 0x4F, 0x55, 0x55, - 0x55, 0x55, 0x55, 0xDE, 0xDF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - -static const unsigned char Lookup_80[128 * 3] = { - /* Common */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, - 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, - 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, - 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x00, 0x30, 0x31, 0x32, 0x33, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, - 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, - 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x56, 0x58, 0x55, 0x5A, - 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, - 0x55, 0x56, 0x56, 0x58, 0x55, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, - -/* Windows */ - 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, - - /* Mac */ - 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, -}; - -static const unsigned char Lookup_112[128 * 3] = { - /* Common */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, - 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, - 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, - 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x00, 0x30, 0x31, 0x32, 0x33, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, - 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, - 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x56, 0x58, 0x55, 0x5A, - 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, - 0x55, 0x56, 0x56, 0x58, 0x55, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, - -/* Windows */ - 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, - - /* Mac */ - 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, -}; - -static const unsigned char Lookup_128[128 * 3] = { - /* Common */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, - 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, - 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, - 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, - 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, - 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, - 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, - 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x00, - -/* Windows */ - 0x00, 0x00, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x00, 0x89, 0x00, 0x8B, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x91, 0x92, 0x93, 0x94, 0x95, 0x2D, 0x2D, 0x00, 0x99, - 0x00, 0x9B, 0x00, 0x00, 0x00, 0x00, 0x09, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, - 0xA7, 0xA8, 0xA9, 0x00, 0xAB, 0xAC, 0x2D, 0xAE, 0x2D, 0xB0, 0xB1, 0x32, 0x33, - 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xBA, - 0xA2, 0xC2, 0xC3, 0xC4, 0xB8, 0xC6, 0xB9, 0xC8, 0xBA, 0xCA, 0xCB, 0xCC, 0xCD, - 0xCE, 0xBC, 0xD0, 0xD1, 0x00, 0xD3, 0xD4, 0xBE, 0xD6, 0xD7, 0xD8, 0xBF, 0xBA, - 0xBE, 0xA2, 0xB8, 0xB9, 0xBA, 0xBE, 0xA2, 0xC2, 0xC3, 0xC4, 0xB8, 0xC6, 0xB9, - 0xC8, 0xBA, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xBC, 0xD0, 0xD1, 0xD3, 0xD3, 0xD4, - 0xBE, 0xD6, 0xD7, 0xD8, 0xBF, 0xBA, 0xBE, 0xBC, 0xBE, 0xBF, 0x00, - - /* Mac */ - 0x41, 0x31, 0x32, 0x45, 0x33, 0x4F, 0x55, 0x87, 0x41, 0x41, 0x41, 0x00, 0x8C, - 0x43, 0x45, 0x45, 0x45, 0x45, 0x92, 0x93, 0x49, 0x49, 0x96, 0x97, 0x98, 0x4F, - 0x4F, 0x9B, 0x3F, 0x55, 0x55, 0x55, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, - 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, - 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xAB, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xB0, - 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0x09, 0xBD, 0xCC, 0xB0, - 0xB6, 0xCF, 0x2D, 0x2D, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xB8, 0xAB, 0xC3, 0xBD, - 0xB6, 0xB8, 0xAB, 0xC3, 0xBF, 0xBD, 0xB0, 0xB5, 0xBE, 0xA2, 0xB6, 0xBC, 0xA1, - 0xB8, 0xAB, 0xA5, 0xBA, 0xA4, 0xBB, 0xC1, 0xC3, 0xA6, 0xBF, 0xC4, 0xAA, 0xC6, - 0xA3, 0xBF, 0xAA, 0xCC, 0xBD, 0xB7, 0xAB, 0xBD, 0xAB, 0xBD, 0x3F, -}; - -static const unsigned char Lookup_144[128 * 3] = { - /* Common */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, - 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, - 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, - 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, - 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, - 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, - 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, - 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x00, - -/* Windows */ - 0x00, 0x00, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x00, 0x89, 0x53, 0x8B, 0x8C, - 0x00, 0x00, 0x00, 0x00, 0x91, 0x92, 0x93, 0x94, 0x95, 0x2D, 0x2D, 0x98, 0x99, - 0x53, 0x9B, 0x8C, 0x00, 0x00, 0x59, 0x09, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, - 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x2D, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, - 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, - 0xC1, 0x41, 0x41, 0x41, 0x41, 0xC6, 0x43, 0x45, 0xC9, 0x45, 0x45, 0x49, 0xCD, - 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0xD3, 0x4F, 0x4F, 0xD6, 0xD7, 0xD6, 0x55, 0xDA, - 0x55, 0x55, 0xDD, 0xDE, 0xDF, 0x41, 0xC1, 0x41, 0x41, 0x41, 0x41, 0xC6, 0x43, - 0x45, 0xC9, 0x45, 0x45, 0x49, 0xCD, 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0xD3, 0x4F, - 0x4F, 0xD6, 0xF7, 0xD6, 0x55, 0xDA, 0x55, 0x55, 0xDD, 0xDE, 0x59, - - /* Mac */ - 0x00, 0x00, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x00, 0x89, 0x53, 0x8B, 0x8C, - 0x00, 0x00, 0x00, 0x00, 0x91, 0x92, 0x93, 0x94, 0x95, 0x2D, 0x2D, 0x98, 0x99, - 0x53, 0x9B, 0x8C, 0x00, 0x00, 0x59, 0x09, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, - 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x2D, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, - 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, - 0xC1, 0x41, 0x41, 0x41, 0x41, 0xC6, 0x43, 0x45, 0xC9, 0x45, 0x45, 0x49, 0xCD, - 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0xD3, 0x4F, 0x4F, 0xD6, 0xD7, 0xD6, 0x55, 0xDA, - 0x55, 0x55, 0xDD, 0xDE, 0xDF, 0x41, 0xC1, 0x41, 0x41, 0x41, 0x41, 0xC6, 0x43, - 0x45, 0xC9, 0x45, 0x45, 0x49, 0xCD, 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0xD3, 0x4F, - 0x4F, 0xD6, 0xF7, 0xD6, 0x55, 0xDA, 0x55, 0x55, 0xDD, 0xDE, 0x59, -}; - -static const unsigned char Lookup_160[128 * 3] = { - /* Common */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, - 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, - 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, - 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, - 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, - 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, - 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, - 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x00, - -/* Windows */ - 0x00, 0x00, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x00, 0x89, 0x53, 0x8B, 0x8C, - 0x00, 0x00, 0x00, 0x00, 0x91, 0x92, 0x93, 0x94, 0x95, 0x2D, 0x2D, 0x98, 0x99, - 0x53, 0x9B, 0x8C, 0x00, 0x00, 0x59, 0x09, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, - 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x2D, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, - 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0xC6, 0xC7, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, - 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0xD6, 0xD7, 0x4F, 0x55, 0x55, - 0x55, 0xDC, 0xDD, 0xDE, 0xDF, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0xC6, 0xC7, - 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0x4F, 0x4F, - 0x4F, 0xD6, 0xF7, 0x4F, 0x55, 0x55, 0x55, 0xDC, 0xDD, 0xDE, 0x59, - - /* Mac */ - 0x00, 0x00, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x00, 0x89, 0x53, 0x8B, 0x8C, - 0x00, 0x00, 0x00, 0x00, 0x91, 0x92, 0x93, 0x94, 0x95, 0x2D, 0x2D, 0x98, 0x99, - 0x53, 0x9B, 0x8C, 0x00, 0x00, 0x59, 0x09, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, - 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x2D, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, - 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0xC6, 0xC7, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, - 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0xD6, 0xD7, 0x4F, 0x55, 0x55, - 0x55, 0xDC, 0xDD, 0xDE, 0xDF, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0xC6, 0xC7, - 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0x4F, 0x4F, - 0x4F, 0xD6, 0xF7, 0x4F, 0x55, 0x55, 0x55, 0xDC, 0xDD, 0xDE, 0x59, -}; - -static const unsigned char Lookup_176[128 * 3] = { - /* Common */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, - 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, - 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, - 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, - 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, - 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, - 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, - 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x00, - - /* Windows */ - 0x00, 0x00, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x00, 0x89, 0x53, 0x8B, 0x8C, - 0x00, 0x00, 0x00, 0x00, 0x91, 0x92, 0x93, 0x94, 0x95, 0x2D, 0x2D, 0x98, 0x99, - 0x53, 0x9B, 0x8C, 0x00, 0x00, 0x59, 0x09, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, - 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x2D, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, - 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, - 0x41, 0x41, 0x41, 0xC4, 0xC5, 0xC4, 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, - 0x49, 0x49, 0x44, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0xD6, 0xD7, 0xD6, 0x55, 0x55, - 0x55, 0x59, 0x59, 0xDE, 0xDF, 0x41, 0x41, 0x41, 0x41, 0xC4, 0xC5, 0xC4, 0x43, - 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0x44, 0x4E, 0x4F, 0x4F, 0x4F, - 0x4F, 0xD6, 0xF7, 0xD6, 0x55, 0x55, 0x55, 0x59, 0x59, 0xDE, 0x59, - - /* Mac */ - 0x80, 0x81, 0x43, 0x45, 0x4E, 0x85, 0x59, 0x41, 0x41, 0x41, 0x80, 0x41, 0x81, - 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0x4E, 0x4F, 0x4F, 0x4F, - 0x85, 0x4F, 0x55, 0x55, 0x55, 0x59, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, - 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0x80, 0x85, 0xB0, 0xB1, 0xB2, 0xB3, - 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0x41, 0x4F, 0xBD, 0x80, 0x85, 0xC0, - 0xC1, 0xC2, 0xC3, 0x46, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0x09, 0x41, 0x41, 0x4F, - 0xCE, 0xCE, 0x2D, 0x2D, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0x59, 0x59, 0xDA, - 0xDB, 0xDC, 0xDD, 0x3F, 0x3F, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0x41, 0x45, 0x41, - 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0x4F, 0x4F, 0x3F, 0x4F, 0x55, 0x55, 0x55, - 0x49, 0x00, 0xF7, 0x00, 0xF9, 0xFA, 0xFB, 0x3F, 0xFD, 0xFE, 0x00 -}; - -static const unsigned char Lookup_208[128 * 3] = { - /* Common */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, - 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, - 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, - 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, - 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, - 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, - 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, - 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, - -/* Windows */ - 0x80, 0x81, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x5E, 0x89, 0x8A, 0x8B, 0x8C, - 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, - 0x9A, 0x9B, 0x8C, 0x9D, 0x00, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, - 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, - 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, - 0xC1, 0xC2, 0xC1, 0xC1, 0xC1, 0xC1, 0xC7, 0xC8, 0xC9, 0xC9, 0xCB, 0xCC, 0xCD, - 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, - 0xDB, 0x00, 0xDD, 0xDE, 0xDF, 0x41, 0xE1, 0x41, 0xE3, 0xE4, 0xE5, 0xE6, 0x43, - 0x45, 0x45, 0x45, 0x45, 0xEC, 0xEC, 0x49, 0x49, 0xF0, 0xF1, 0xF2, 0xF3, 0x4F, - 0xF5, 0xF6, 0xF7, 0xF8, 0x55, 0xFA, 0x55, 0x55, 0x00, 0x00, 0xFF, - - /* Mac */ - 0x41, 0x81, 0x43, 0x45, 0x4E, 0x4F, 0x55, 0x41, 0x41, 0x41, 0x41, 0x8B, 0x8C, - 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x93, 0x49, 0x49, 0x4E, 0x4F, 0x98, 0x4F, - 0x4F, 0x9B, 0x55, 0x55, 0x55, 0x55, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, - 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, - 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, - 0xC1, 0xC2, 0xC1, 0xC1, 0xC1, 0xC1, 0xC7, 0xC8, 0xC9, 0xC9, 0xCB, 0xCC, 0xCD, - 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, - 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0x00, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, - 0xE8, 0xE9, 0xE9, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, - 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, -}; - -static const unsigned char Lookup_224[128 * 3] = { - /* Common */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, - 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, - 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, - 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, - 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, - 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, - 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, - 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, - -/* Windows */ - 0x80, 0x81, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x5E, 0x89, 0x8A, 0x8B, 0x8C, - 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, - 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, - 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, - 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, - 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, - 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, - 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, - 0xE8, 0xE9, 0xEA, 0xEA, 0xEC, 0xED, 0xED, 0xEF, 0xEF, 0xF1, 0xF2, 0xF3, 0xF3, - 0xF5, 0xF5, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0x00, 0x00, 0xFF, - - /* Mac */ - 0x41, 0x41, 0x43, 0x45, 0x4E, 0x4F, 0x55, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0x4E, 0x4F, 0x4F, 0x4F, - 0x4F, 0x4F, 0x55, 0x55, 0x55, 0x55, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, - 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, - 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, - 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, - 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, - 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, - 0xE8, 0xE9, 0xEA, 0xEA, 0xEC, 0xED, 0xED, 0xEF, 0xEF, 0xF1, 0xF2, 0xF3, 0xF3, - 0xF5, 0xF5, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, -}; - -/*********************************************************************** - * lhash_val_of_name_sys - * - * Copy of oleaut32.LHashValOfNameSysA - * Produce a string hash value. - * - * PARAMS - * skind [I] Type of the system. - * lcid [I] Locale id for the hash. - * lpStr [I] String to hash. - * - * RETURNS - * Success: The hash value of the string. - * Failure: 0, if lpStr is NULL. - * - * NOTES - * This function produces a two part hash: The high word is based on - * skind and lcid, while the low word is based on a repeated string - * hash of skind/str. - */ -unsigned long lhash_val_of_name_sys( syskind_t skind, LCID lcid, LPCSTR lpStr) -{ - ULONG nOffset, nMask = skind == SYS_MAC ? 1 : 0; - ULONG nHiWord, nLoWord = 0x0deadbee; - const unsigned char *str = (const unsigned char *)lpStr, *pnLookup = NULL; - - if (!str) - return 0; - - switch (PRIMARYLANGID(LANGIDFROMLCID(lcid))) - { - default: - fprintf(stderr, "Unknown lcid %x, treating as latin-based, please report\n", lcid); - /* .. Fall Through .. */ - case LANG_AFRIKAANS: case LANG_ALBANIAN: case LANG_ARMENIAN: - case LANG_ASSAMESE: case LANG_AZERI: case LANG_BASQUE: - case LANG_BELARUSIAN: case LANG_BENGALI: case LANG_BULGARIAN: - case LANG_CATALAN: case LANG_DANISH: case LANG_DIVEHI: - case LANG_DUTCH: case LANG_ENGLISH: case LANG_ESTONIAN: - case LANG_FAEROESE: case LANG_FINNISH: case LANG_FRENCH: - case LANG_GALICIAN: case LANG_GEORGIAN: case LANG_GERMAN: - case LANG_GUJARATI: case LANG_HINDI: case LANG_INDONESIAN: - case LANG_ITALIAN: case LANG_KANNADA: case LANG_KASHMIRI: - case LANG_KAZAK: case LANG_KONKANI: case LANG_KYRGYZ: - case LANG_LATVIAN: case LANG_LITHUANIAN: case LANG_MACEDONIAN: - case LANG_MALAY: case LANG_MALAYALAM: case LANG_MANIPURI: - case LANG_MARATHI: case LANG_MONGOLIAN: case LANG_NEPALI: - case LANG_ORIYA: case LANG_PORTUGUESE: case LANG_PUNJABI: - case LANG_ROMANIAN: case LANG_SANSKRIT: case LANG_SERBIAN: - case LANG_SINDHI: case LANG_SLOVENIAN: case LANG_SWAHILI: - case LANG_SWEDISH: case LANG_SYRIAC: case LANG_TAMIL: - case LANG_TATAR: case LANG_TELUGU: case LANG_THAI: - case LANG_UKRAINIAN: case LANG_URDU: case LANG_UZBEK: -#ifndef __REACTOS__ - case LANG_VIETNAMESE: case LANG_GAELIC: case LANG_MALTESE: - case LANG_TAJIK: case LANG_ROMANSH: case LANG_IRISH: - case LANG_SAMI: case LANG_UPPER_SORBIAN: case LANG_SUTU: - case LANG_TSONGA: case LANG_TSWANA: case LANG_VENDA: - case LANG_XHOSA: case LANG_ZULU: case LANG_ESPERANTO: - case LANG_WALON: case LANG_CORNISH: case LANG_WELSH: - case LANG_BRETON: -#else - case LANG_VIETNAMESE: case LANG_MALTESE: case LANG_IRISH: - case LANG_SAMI: case LANG_UPPER_SORBIAN: case LANG_TSWANA: - case LANG_XHOSA: case LANG_ZULU: case LANG_WELSH: - case LANG_BRETON: -#endif - nOffset = 16; - pnLookup = Lookup_16; - break; - case LANG_CZECH: case LANG_HUNGARIAN: case LANG_POLISH: - case LANG_SLOVAK: case LANG_SPANISH: - nOffset = 32; - pnLookup = Lookup_32; - break; - case LANG_HEBREW: - nOffset = 48; - pnLookup = Lookup_48; - break; - case LANG_JAPANESE: - nOffset = 64; - pnLookup = Lookup_64; - break; - case LANG_KOREAN: - nOffset = 80; - pnLookup = Lookup_80; - break; - case LANG_CHINESE: - nOffset = 112; - pnLookup = Lookup_112; - break; - case LANG_GREEK: - nOffset = 128; - pnLookup = Lookup_128; - break; - case LANG_ICELANDIC: - nOffset = 144; - pnLookup = Lookup_144; - break; - case LANG_TURKISH: - nOffset = 160; - pnLookup = Lookup_160; - break; - case LANG_NORWEGIAN: - if (SUBLANGID(LANGIDFROMLCID(lcid)) == SUBLANG_NORWEGIAN_NYNORSK) - { - nOffset = 176; - pnLookup = Lookup_176; - } - else - { - nOffset = 16; - pnLookup = Lookup_16; - } - break; - case LANG_ARABIC: - case LANG_FARSI: - nOffset = 208; - pnLookup = Lookup_208; - break; - case LANG_RUSSIAN: - nOffset = 224; - pnLookup = Lookup_224; - break; - } - - nHiWord = (nOffset | nMask) << 16; - - while (*str) - { - nLoWord = 37 * nLoWord + pnLookup[*str > 0x7f && nMask ? *str + 0x80 : *str]; - str++; - } - /* Constrain to a prime modulo and sizeof(WORD) */ - nLoWord = (nLoWord % 65599) & 0xffff; - - return nHiWord | nLoWord; -} diff --git a/reactos/tools/widl_20080105/hash.h b/reactos/tools/widl_20080105/hash.h deleted file mode 100644 index bb787abab83..00000000000 --- a/reactos/tools/widl_20080105/hash.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Hash definitions - * - * Copyright 2005 Huw Davies - * - * 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 - * - */ - -#ifndef __WIDL_HASH_H -#define __WIDL_HASH_H - -typedef enum tag_syskind_t { - SYS_WIN16 = 0, - SYS_WIN32, - SYS_MAC -} syskind_t; - -extern unsigned long lhash_val_of_name_sys( syskind_t skind, LCID lcid, LPCSTR lpStr); - -#endif diff --git a/reactos/tools/widl_20080105/header.c b/reactos/tools/widl_20080105/header.c deleted file mode 100644 index fd895348b3a..00000000000 --- a/reactos/tools/widl_20080105/header.c +++ /dev/null @@ -1,1043 +0,0 @@ -/* - * IDL Compiler - * - * Copyright 2002 Ove Kaaven - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" - -#include -#include -#include -#ifdef HAVE_UNISTD_H -# include -#endif -#include -#include -#include -#include - -#include "widl.h" -#include "utils.h" -#include "parser.h" -#include "header.h" - -static int indentation = 0; -user_type_list_t user_type_list = LIST_INIT(user_type_list); -static context_handle_list_t context_handle_list = LIST_INIT(context_handle_list); - -static void indent(FILE *h, int delta) -{ - int c; - if (delta < 0) indentation += delta; - for (c=0; c 0) indentation += delta; -} - -int is_ptrchain_attr(const var_t *var, enum attr_type t) -{ - if (is_attr(var->attrs, t)) - return 1; - else - { - type_t *type = var->type; - for (;;) - { - if (is_attr(type->attrs, t)) - return 1; - else if (type->kind == TKIND_ALIAS) - type = type->orig; - else if (is_ptr(type)) - type = type->ref; - else return 0; - } - } -} - -int is_attr(const attr_list_t *list, enum attr_type t) -{ - const attr_t *attr; - if (list) LIST_FOR_EACH_ENTRY( attr, list, const attr_t, entry ) - if (attr->type == t) return 1; - return 0; -} - -void *get_attrp(const attr_list_t *list, enum attr_type t) -{ - const attr_t *attr; - if (list) LIST_FOR_EACH_ENTRY( attr, list, const attr_t, entry ) - if (attr->type == t) return attr->u.pval; - return NULL; -} - -unsigned long get_attrv(const attr_list_t *list, enum attr_type t) -{ - const attr_t *attr; - if (list) LIST_FOR_EACH_ENTRY( attr, list, const attr_t, entry ) - if (attr->type == t) return attr->u.ival; - return 0; -} - -int is_void(const type_t *t) -{ - if (!t->type && !t->ref) return 1; - return 0; -} - -int is_conformant_array(const type_t *t) -{ - return t->type == RPC_FC_CARRAY - || t->type == RPC_FC_CVARRAY - || (t->type == RPC_FC_BOGUS_ARRAY && t->size_is); -} - -void write_guid(FILE *f, const char *guid_prefix, const char *name, const UUID *uuid) -{ - if (!uuid) return; - fprintf(f, "DEFINE_GUID(%s_%s, 0x%08x, 0x%04x, 0x%04x, 0x%02x,0x%02x, 0x%02x," - "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x);\n", - guid_prefix, name, uuid->Data1, uuid->Data2, uuid->Data3, uuid->Data4[0], - uuid->Data4[1], uuid->Data4[2], uuid->Data4[3], uuid->Data4[4], uuid->Data4[5], - uuid->Data4[6], uuid->Data4[7]); -} - -void write_name(FILE *h, const var_t *v) -{ - if (is_attr( v->attrs, ATTR_PROPGET )) - fprintf(h, "get_" ); - else if (is_attr( v->attrs, ATTR_PROPPUT )) - fprintf(h, "put_" ); - else if (is_attr( v->attrs, ATTR_PROPPUTREF )) - fprintf(h, "putref_" ); - fprintf(h, "%s", v->name); -} - -void write_prefix_name(FILE *h, const char *prefix, const var_t *v) -{ - fprintf(h, "%s", prefix); - write_name(h, v); -} - -static void write_field(FILE *h, var_t *v) -{ - if (!v) return; - if (v->type) { - const char *name = v->name; - if (name == NULL) { - switch (v->type->type) { - case RPC_FC_STRUCT: - case RPC_FC_CVSTRUCT: - case RPC_FC_CPSTRUCT: - case RPC_FC_CSTRUCT: - case RPC_FC_PSTRUCT: - case RPC_FC_BOGUS_STRUCT: - case RPC_FC_ENCAPSULATED_UNION: - name = "DUMMYSTRUCTNAME"; - break; - case RPC_FC_NON_ENCAPSULATED_UNION: - name = "DUMMYUNIONNAME"; - break; - default: - /* ? */ - break; - } - } - indent(h, 0); - write_type_def_or_decl(h, v->type, TRUE, "%s", name); - fprintf(h, ";\n"); - } -} - -static void write_fields(FILE *h, var_list_t *fields) -{ - var_t *v; - if (!fields) return; - LIST_FOR_EACH_ENTRY( v, fields, var_t, entry ) write_field(h, v); -} - -static void write_enums(FILE *h, var_list_t *enums) -{ - var_t *v; - if (!enums) return; - LIST_FOR_EACH_ENTRY( v, enums, var_t, entry ) - { - if (v->name) { - indent(h, 0); - write_name(h, v); - if (v->eval) { - fprintf(h, " = "); - write_expr(h, v->eval, 0); - } - } - if (list_next( enums, &v->entry )) fprintf(h, ",\n"); - } - fprintf(h, "\n"); -} - -int needs_space_after(type_t *t) -{ - return (t->kind == TKIND_ALIAS - || (!is_ptr(t) && (!is_conformant_array(t) || t->declarray))); -} - -void write_type_left(FILE *h, type_t *t, int declonly) -{ - if (!h) return; - - if (t->is_const) fprintf(h, "const "); - - if (t->kind == TKIND_ALIAS) fprintf(h, "%s", t->name); - else if (t->declarray) write_type_left(h, t->ref, declonly); - else { - if (t->sign > 0) fprintf(h, "signed "); - else if (t->sign < 0) fprintf(h, "unsigned "); - switch (t->type) { - case RPC_FC_ENUM16: - case RPC_FC_ENUM32: - if (!declonly && t->defined && !t->written && !t->ignore) { - if (t->name) fprintf(h, "enum %s {\n", t->name); - else fprintf(h, "enum {\n"); - t->written = TRUE; - indentation++; - write_enums(h, t->fields); - indent(h, -1); - fprintf(h, "}"); - } - else fprintf(h, "enum %s", t->name ? t->name : ""); - break; - case RPC_FC_STRUCT: - case RPC_FC_CVSTRUCT: - case RPC_FC_CPSTRUCT: - case RPC_FC_CSTRUCT: - case RPC_FC_PSTRUCT: - case RPC_FC_BOGUS_STRUCT: - case RPC_FC_ENCAPSULATED_UNION: - if (!declonly && t->defined && !t->written && !t->ignore) { - if (t->name) fprintf(h, "struct %s {\n", t->name); - else fprintf(h, "struct {\n"); - t->written = TRUE; - indentation++; - write_fields(h, t->fields); - indent(h, -1); - fprintf(h, "}"); - } - else fprintf(h, "struct %s", t->name ? t->name : ""); - break; - case RPC_FC_NON_ENCAPSULATED_UNION: - if (!declonly && t->defined && !t->written && !t->ignore) { - if (t->name) fprintf(h, "union %s {\n", t->name); - else fprintf(h, "union {\n"); - t->written = TRUE; - indentation++; - write_fields(h, t->fields); - indent(h, -1); - fprintf(h, "}"); - } - else fprintf(h, "union %s", t->name ? t->name : ""); - break; - case RPC_FC_RP: - case RPC_FC_UP: - case RPC_FC_FP: - case RPC_FC_OP: - case RPC_FC_CARRAY: - case RPC_FC_CVARRAY: - case RPC_FC_BOGUS_ARRAY: - write_type_left(h, t->ref, declonly); - fprintf(h, "%s*", needs_space_after(t->ref) ? " " : ""); - break; - default: - fprintf(h, "%s", t->name); - } - } -} - -void write_type_right(FILE *h, type_t *t, int is_field) -{ - if (!h) return; - - if (t->declarray) { - if (is_conformant_array(t)) { - fprintf(h, "[%s]", is_field ? "1" : ""); - t = t->ref; - } - for ( ; t->declarray; t = t->ref) - fprintf(h, "[%lu]", t->dim); - } -} - -void write_type_v(FILE *h, type_t *t, int is_field, int declonly, - const char *fmt, va_list args) -{ - if (!h) return; - - write_type_left(h, t, declonly); - if (fmt) { - if (needs_space_after(t)) - fprintf(h, " "); - vfprintf(h, fmt, args); - } - write_type_right(h, t, is_field); -} - -void write_type_def_or_decl(FILE *f, type_t *t, int field, const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - write_type_v(f, t, field, FALSE, fmt, args); - va_end(args); -} - -void write_type_decl(FILE *f, type_t *t, const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - write_type_v(f, t, FALSE, TRUE, fmt, args); - va_end(args); -} - -void write_type_decl_left(FILE *f, type_t *t) -{ - write_type_left(f, t, TRUE); -} - -static int user_type_registered(const char *name) -{ - user_type_t *ut; - LIST_FOR_EACH_ENTRY(ut, &user_type_list, user_type_t, entry) - if (!strcmp(name, ut->name)) - return 1; - return 0; -} - -static int context_handle_registered(const char *name) -{ - context_handle_t *ch; - LIST_FOR_EACH_ENTRY(ch, &context_handle_list, context_handle_t, entry) - if (!strcmp(name, ch->name)) - return 1; - return 0; -} - -void check_for_user_types_and_context_handles(const var_list_t *list) -{ - const var_t *v; - - if (!list) return; - LIST_FOR_EACH_ENTRY( v, list, const var_t, entry ) - { - type_t *type; - for (type = v->type; type; type = type->kind == TKIND_ALIAS ? type->orig : type->ref) { - const char *name = type->name; - if (type->user_types_registered) continue; - type->user_types_registered = 1; - if (is_attr(type->attrs, ATTR_CONTEXTHANDLE)) { - if (!context_handle_registered(name)) - { - context_handle_t *ch = xmalloc(sizeof(*ch)); - ch->name = xstrdup(name); - list_add_tail(&context_handle_list, &ch->entry); - } - /* don't carry on parsing fields within this type */ - break; - } - if (is_attr(type->attrs, ATTR_WIREMARSHAL)) { - if (!user_type_registered(name)) - { - user_type_t *ut = xmalloc(sizeof *ut); - ut->name = xstrdup(name); - list_add_tail(&user_type_list, &ut->entry); - } - /* don't carry on parsing fields within this type as we are already - * using a wire marshaled type */ - break; - } - else - { - check_for_user_types_and_context_handles(type->fields); - } - } - } -} - -void write_user_types(void) -{ - user_type_t *ut; - LIST_FOR_EACH_ENTRY(ut, &user_type_list, user_type_t, entry) - { - const char *name = ut->name; - fprintf(header, "ULONG __RPC_USER %s_UserSize (ULONG *, ULONG, %s *);\n", name, name); - fprintf(header, "unsigned char * __RPC_USER %s_UserMarshal (ULONG *, unsigned char *, %s *);\n", name, name); - fprintf(header, "unsigned char * __RPC_USER %s_UserUnmarshal(ULONG *, unsigned char *, %s *);\n", name, name); - fprintf(header, "void __RPC_USER %s_UserFree (ULONG *, %s *);\n", name, name); - } -} - -void write_context_handle_rundowns(void) -{ - context_handle_t *ch; - LIST_FOR_EACH_ENTRY(ch, &context_handle_list, context_handle_t, entry) - { - const char *name = ch->name; - fprintf(header, "void __RPC_USER %s_rundown(%s);\n", name, name); - } -} - -void write_typedef(type_t *type) -{ - fprintf(header, "typedef "); - write_type_def_or_decl(header, type->orig, FALSE, "%s", type->name); - fprintf(header, ";\n"); -} - -void write_expr(FILE *h, const expr_t *e, int brackets) -{ - switch (e->type) { - case EXPR_VOID: - break; - case EXPR_NUM: - fprintf(h, "%lu", e->u.lval); - break; - case EXPR_HEXNUM: - fprintf(h, "0x%lx", e->u.lval); - break; - case EXPR_DOUBLE: - fprintf(h, "%#.15g", e->u.dval); - break; - case EXPR_TRUEFALSE: - if (e->u.lval == 0) - fprintf(h, "FALSE"); - else - fprintf(h, "TRUE"); - break; - case EXPR_IDENTIFIER: - fprintf(h, "%s", e->u.sval); - break; - case EXPR_NEG: - fprintf(h, "-"); - write_expr(h, e->ref, 1); - break; - case EXPR_NOT: - fprintf(h, "~"); - write_expr(h, e->ref, 1); - break; - case EXPR_PPTR: - fprintf(h, "*"); - write_expr(h, e->ref, 1); - break; - case EXPR_CAST: - fprintf(h, "("); - write_type_decl(h, e->u.tref, NULL); - fprintf(h, ")"); - write_expr(h, e->ref, 1); - break; - case EXPR_SIZEOF: - fprintf(h, "sizeof("); - write_type_decl(h, e->u.tref, NULL); - fprintf(h, ")"); - break; - case EXPR_SHL: - case EXPR_SHR: - case EXPR_MUL: - case EXPR_DIV: - case EXPR_ADD: - case EXPR_SUB: - case EXPR_AND: - case EXPR_OR: - if (brackets) fprintf(h, "("); - write_expr(h, e->ref, 1); - switch (e->type) { - case EXPR_SHL: fprintf(h, " << "); break; - case EXPR_SHR: fprintf(h, " >> "); break; - case EXPR_MUL: fprintf(h, " * "); break; - case EXPR_DIV: fprintf(h, " / "); break; - case EXPR_ADD: fprintf(h, " + "); break; - case EXPR_SUB: fprintf(h, " - "); break; - case EXPR_AND: fprintf(h, " & "); break; - case EXPR_OR: fprintf(h, " | "); break; - default: break; - } - write_expr(h, e->u.ext, 1); - if (brackets) fprintf(h, ")"); - break; - case EXPR_COND: - if (brackets) fprintf(h, "("); - write_expr(h, e->ref, 1); - fprintf(h, " ? "); - write_expr(h, e->u.ext, 1); - fprintf(h, " : "); - write_expr(h, e->ext2, 1); - if (brackets) fprintf(h, ")"); - break; - case EXPR_ADDRESSOF: - fprintf(h, "&"); - write_expr(h, e->ref, 1); - break; - } -} - -void write_constdef(const var_t *v) -{ - fprintf(header, "#define %s (", v->name); - write_expr(header, v->eval, 0); - fprintf(header, ")\n\n"); -} - -void write_externdef(const var_t *v) -{ - fprintf(header, "extern const "); - write_type_def_or_decl(header, v->type, FALSE, "%s", v->name); - fprintf(header, ";\n\n"); -} - -void write_library(const char *name, const attr_list_t *attr) -{ - const UUID *uuid = get_attrp(attr, ATTR_UUID); - fprintf(header, "\n"); - write_guid(header, "LIBID", name, uuid); - fprintf(header, "\n"); -} - - -const var_t* get_explicit_handle_var(const func_t* func) -{ - const var_t* var; - - if (!func->args) - return NULL; - - LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) - if (var->type->type == RPC_FC_BIND_PRIMITIVE) - return var; - - return NULL; -} - -int has_out_arg_or_return(const func_t *func) -{ - const var_t *var; - - if (!is_void(func->def->type)) - return 1; - - if (!func->args) - return 0; - - LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) - if (is_attr(var->attrs, ATTR_OUT)) - return 1; - - return 0; -} - - -/********** INTERFACES **********/ - -int is_object(const attr_list_t *list) -{ - const attr_t *attr; - if (list) LIST_FOR_EACH_ENTRY( attr, list, const attr_t, entry ) - if (attr->type == ATTR_OBJECT || attr->type == ATTR_ODL) return 1; - return 0; -} - -int is_local(const attr_list_t *a) -{ - return is_attr(a, ATTR_LOCAL); -} - -const var_t *is_callas(const attr_list_t *a) -{ - return get_attrp(a, ATTR_CALLAS); -} - -static void write_method_macro(const type_t *iface, const char *name) -{ - const func_t *cur; - - if (iface->ref) write_method_macro(iface->ref, name); - - if (!iface->funcs) return; - - fprintf(header, "/*** %s methods ***/\n", iface->name); - LIST_FOR_EACH_ENTRY( cur, iface->funcs, const func_t, entry ) - { - var_t *def = cur->def; - if (!is_callas(def->attrs)) { - const var_t *arg; - int argc = 0; - int c; - - if (cur->args) LIST_FOR_EACH_ENTRY( arg, cur->args, const var_t, entry ) argc++; - - fprintf(header, "#define %s_", name); - write_name(header,def); - fprintf(header, "(p"); - for (c=0; clpVtbl->"); - write_name(header, def); - fprintf(header, "(p"); - for (c=0; cargs) - { - write_type_decl_left(h, arg->type); - fprintf(h, " (STDMETHODCALLTYPE *"); - write_name(h,arg); - fprintf(h, ")("); - write_args(h, arg->args, NULL, 0, FALSE); - fprintf(h, ")"); - } - else - write_type_decl(h, arg->type, "%s", arg->name); - count++; - } - if (do_indent) indentation--; -} - -static void write_cpp_method_def(const type_t *iface) -{ - const func_t *cur; - - if (!iface->funcs) return; - - LIST_FOR_EACH_ENTRY( cur, iface->funcs, const func_t, entry ) - { - var_t *def = cur->def; - if (!is_callas(def->attrs)) { - indent(header, 0); - fprintf(header, "virtual "); - write_type_decl_left(header, def->type); - fprintf(header, " STDMETHODCALLTYPE "); - write_name(header, def); - fprintf(header, "(\n"); - write_args(header, cur->args, iface->name, 2, TRUE); - fprintf(header, ") = 0;\n"); - fprintf(header, "\n"); - } - } -} - -static void do_write_c_method_def(const type_t *iface, const char *name) -{ - const func_t *cur; - - if (iface->ref) do_write_c_method_def(iface->ref, name); - - if (!iface->funcs) return; - indent(header, 0); - fprintf(header, "/*** %s methods ***/\n", iface->name); - LIST_FOR_EACH_ENTRY( cur, iface->funcs, const func_t, entry ) - { - const var_t *def = cur->def; - if (!is_callas(def->attrs)) { - indent(header, 0); - write_type_decl_left(header, def->type); - fprintf(header, " (STDMETHODCALLTYPE *"); - write_name(header, def); - fprintf(header, ")(\n"); - write_args(header, cur->args, name, 1, TRUE); - fprintf(header, ");\n"); - fprintf(header, "\n"); - } - } -} - -static void write_c_method_def(const type_t *iface) -{ - do_write_c_method_def(iface, iface->name); -} - -static void write_c_disp_method_def(const type_t *iface) -{ - do_write_c_method_def(iface->ref, iface->name); -} - -static void write_method_proto(const type_t *iface) -{ - const func_t *cur; - - if (!iface->funcs) return; - LIST_FOR_EACH_ENTRY( cur, iface->funcs, const func_t, entry ) - { - const var_t *def = cur->def; - - if (!is_local(def->attrs)) { - /* proxy prototype */ - write_type_decl_left(header, def->type); - fprintf(header, " CALLBACK %s_", iface->name); - write_name(header, def); - fprintf(header, "_Proxy(\n"); - write_args(header, cur->args, iface->name, 1, TRUE); - fprintf(header, ");\n"); - /* stub prototype */ - fprintf(header, "void __RPC_STUB %s_", iface->name); - write_name(header,def); - fprintf(header, "_Stub(\n"); - fprintf(header, " IRpcStubBuffer* This,\n"); - fprintf(header, " IRpcChannelBuffer* pRpcChannelBuffer,\n"); - fprintf(header, " PRPC_MESSAGE pRpcMessage,\n"); - fprintf(header, " DWORD* pdwStubPhase);\n"); - } - } -} - -void write_locals(FILE *fp, const type_t *iface, int body) -{ - static const char comment[] - = "/* WIDL-generated stub. You must provide an implementation for this. */"; - const func_list_t *funcs = iface->funcs; - const func_t *cur; - - if (!is_object(iface->attrs) || !funcs) - return; - - LIST_FOR_EACH_ENTRY(cur, funcs, const func_t, entry) { - const var_t *def = cur->def; - const var_t *cas = is_callas(def->attrs); - - if (cas) { - const func_t *m; - LIST_FOR_EACH_ENTRY(m, iface->funcs, const func_t, entry) - if (!strcmp(m->def->name, cas->name)) - break; - if (&m->entry != iface->funcs) { - const var_t *mdef = m->def; - /* proxy prototype - use local prototype */ - write_type_decl_left(fp, mdef->type); - fprintf(fp, " CALLBACK %s_", iface->name); - write_name(fp, mdef); - fprintf(fp, "_Proxy(\n"); - write_args(fp, m->args, iface->name, 1, TRUE); - fprintf(fp, ")"); - if (body) { - type_t *rt = mdef->type; - fprintf(fp, "\n{\n"); - fprintf(fp, " %s\n", comment); - if (rt->name && strcmp(rt->name, "HRESULT") == 0) - fprintf(fp, " return E_NOTIMPL;\n"); - else if (rt->type) { - fprintf(fp, " "); - write_type_decl(fp, rt, "rv"); - fprintf(fp, ";\n"); - fprintf(fp, " memset(&rv, 0, sizeof rv);\n"); - fprintf(fp, " return rv;\n"); - } - fprintf(fp, "}\n\n"); - } - else - fprintf(fp, ";\n"); - /* stub prototype - use remotable prototype */ - write_type_decl_left(fp, def->type); - fprintf(fp, " __RPC_STUB %s_", iface->name); - write_name(fp, mdef); - fprintf(fp, "_Stub(\n"); - write_args(fp, cur->args, iface->name, 1, TRUE); - fprintf(fp, ")"); - if (body) - /* Remotable methods must all return HRESULTs. */ - fprintf(fp, "\n{\n %s\n return E_NOTIMPL;\n}\n\n", comment); - else - fprintf(fp, ";\n"); - } - else - error_loc("invalid call_as attribute (%s -> %s)\n", def->name, cas->name); - } - } -} - -static void write_function_proto(const type_t *iface, const func_t *fun, const char *prefix) -{ - var_t *def = fun->def; - - /* FIXME: do we need to handle call_as? */ - write_type_decl_left(header, def->type); - fprintf(header, " "); - write_prefix_name(header, prefix, def); - fprintf(header, "(\n"); - if (fun->args) - write_args(header, fun->args, iface->name, 0, TRUE); - else - fprintf(header, " void"); - fprintf(header, ");\n"); -} - -static void write_function_protos(const type_t *iface) -{ - const char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE); - int explicit_handle = is_attr(iface->attrs, ATTR_EXPLICIT_HANDLE); - const var_t* explicit_handle_var; - const func_t *cur; - int prefixes_differ = strcmp(prefix_client, prefix_server); - - if (!iface->funcs) return; - LIST_FOR_EACH_ENTRY( cur, iface->funcs, const func_t, entry ) - { - var_t *def = cur->def; - - /* check for a defined binding handle */ - explicit_handle_var = get_explicit_handle_var(cur); - if (explicit_handle) { - if (!explicit_handle_var) { - error("%s() does not define an explicit binding handle!\n", def->name); - return; - } - } else if (implicit_handle) { - if (explicit_handle_var) { - error("%s() must not define a binding handle!\n", def->name); - return; - } - } - - if (prefixes_differ) { - fprintf(header, "/* client prototype */\n"); - write_function_proto(iface, cur, prefix_client); - fprintf(header, "/* server prototype */\n"); - } - write_function_proto(iface, cur, prefix_server); - } -} - -void write_forward(type_t *iface) -{ - /* C/C++ forwards should only be written for object interfaces, so if we - * have a full definition we only write one if we find [object] among the - * attributes - however, if we don't have a full definition at this point - * (i.e. this is an IDL forward), then we also assume that it is an object - * interface, since non-object interfaces shouldn't need forwards */ - if ((!iface->defined || is_object(iface->attrs) || is_attr(iface->attrs, ATTR_DISPINTERFACE)) - && !iface->written) { - fprintf(header, "#ifndef __%s_FWD_DEFINED__\n", iface->name); - fprintf(header, "#define __%s_FWD_DEFINED__\n", iface->name); - fprintf(header, "typedef interface %s %s;\n", iface->name, iface->name); - fprintf(header, "#endif\n\n" ); - iface->written = TRUE; - } -} - -static void write_iface_guid(const type_t *iface) -{ - const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID); - write_guid(header, "IID", iface->name, uuid); -} - -static void write_dispiface_guid(const type_t *iface) -{ - const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID); - write_guid(header, "DIID", iface->name, uuid); -} - -static void write_coclass_guid(type_t *cocl) -{ - const UUID *uuid = get_attrp(cocl->attrs, ATTR_UUID); - write_guid(header, "CLSID", cocl->name, uuid); -} - -static void write_com_interface(type_t *iface) -{ - if (!iface->funcs && !iface->ref) { - parser_warning("%s has no methods\n", iface->name); - return; - } - - fprintf(header, "/*****************************************************************************\n"); - fprintf(header, " * %s interface\n", iface->name); - fprintf(header, " */\n"); - fprintf(header,"#ifndef __%s_INTERFACE_DEFINED__\n", iface->name); - fprintf(header,"#define __%s_INTERFACE_DEFINED__\n\n", iface->name); - write_iface_guid(iface); - write_forward(iface); - /* C++ interface */ - fprintf(header, "#if defined(__cplusplus) && !defined(CINTERFACE)\n"); - if (iface->ref) - { - fprintf(header, "interface %s : public %s\n", iface->name, iface->ref->name); - fprintf(header, "{\n"); - indentation++; - write_cpp_method_def(iface); - indentation--; - fprintf(header, "};\n"); - } - else - { - fprintf(header, "interface %s\n", iface->name); - fprintf(header, "{\n"); - fprintf(header, " BEGIN_INTERFACE\n"); - fprintf(header, "\n"); - indentation++; - write_cpp_method_def(iface); - indentation--; - fprintf(header, " END_INTERFACE\n"); - fprintf(header, "};\n"); - } - fprintf(header, "#else\n"); - /* C interface */ - fprintf(header, "typedef struct %sVtbl {\n", iface->name); - indentation++; - fprintf(header, " BEGIN_INTERFACE\n"); - fprintf(header, "\n"); - write_c_method_def(iface); - indentation--; - fprintf(header, " END_INTERFACE\n"); - fprintf(header, "} %sVtbl;\n", iface->name); - fprintf(header, "interface %s {\n", iface->name); - fprintf(header, " CONST_VTBL %sVtbl* lpVtbl;\n", iface->name); - fprintf(header, "};\n"); - fprintf(header, "\n"); - fprintf(header, "#ifdef COBJMACROS\n"); - write_method_macro(iface, iface->name); - fprintf(header, "#endif\n"); - fprintf(header, "\n"); - fprintf(header, "#endif\n"); - fprintf(header, "\n"); - write_method_proto(iface); - write_locals(header, iface, FALSE); - fprintf(header,"\n#endif /* __%s_INTERFACE_DEFINED__ */\n\n", iface->name); -} - -static void write_rpc_interface(const type_t *iface) -{ - unsigned int ver = get_attrv(iface->attrs, ATTR_VERSION); - const char *var = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE); - static int allocate_written = 0; - - if (!allocate_written) - { - allocate_written = 1; - fprintf(header, "void * __RPC_USER MIDL_user_allocate(size_t);\n"); - fprintf(header, "void __RPC_USER MIDL_user_free(void *);\n\n"); - } - - fprintf(header, "/*****************************************************************************\n"); - fprintf(header, " * %s interface (v%d.%d)\n", iface->name, MAJORVERSION(ver), MINORVERSION(ver)); - fprintf(header, " */\n"); - fprintf(header,"#ifndef __%s_INTERFACE_DEFINED__\n", iface->name); - fprintf(header,"#define __%s_INTERFACE_DEFINED__\n\n", iface->name); - if (iface->funcs) - { - write_iface_guid(iface); - if (var) fprintf(header, "extern handle_t %s;\n", var); - if (old_names) - { - fprintf(header, "extern RPC_IF_HANDLE %s%s_ClientIfHandle;\n", prefix_client, iface->name); - fprintf(header, "extern RPC_IF_HANDLE %s%s_ServerIfHandle;\n", prefix_server, iface->name); - } - else - { - fprintf(header, "extern RPC_IF_HANDLE %s%s_v%d_%d_c_ifspec;\n", - prefix_client, iface->name, MAJORVERSION(ver), MINORVERSION(ver)); - fprintf(header, "extern RPC_IF_HANDLE %s%s_v%d_%d_s_ifspec;\n", - prefix_server, iface->name, MAJORVERSION(ver), MINORVERSION(ver)); - } - write_function_protos(iface); - } - fprintf(header,"\n#endif /* __%s_INTERFACE_DEFINED__ */\n\n", iface->name); - - /* FIXME: server/client code */ -} - -void write_interface(type_t *iface) -{ - if (is_object(iface->attrs)) - write_com_interface(iface); - else - write_rpc_interface(iface); -} - -void write_dispinterface(type_t *iface) -{ - fprintf(header, "/*****************************************************************************\n"); - fprintf(header, " * %s dispinterface\n", iface->name); - fprintf(header, " */\n"); - fprintf(header,"#ifndef __%s_DISPINTERFACE_DEFINED__\n", iface->name); - fprintf(header,"#define __%s_DISPINTERFACE_DEFINED__\n\n", iface->name); - write_dispiface_guid(iface); - write_forward(iface); - /* C++ interface */ - fprintf(header, "#if defined(__cplusplus) && !defined(CINTERFACE)\n"); - fprintf(header, "interface %s : public %s\n", iface->name, iface->ref->name); - fprintf(header, "{\n"); - fprintf(header, "};\n"); - fprintf(header, "#else\n"); - /* C interface */ - fprintf(header, "typedef struct %sVtbl {\n", iface->name); - indentation++; - fprintf(header, " BEGIN_INTERFACE\n"); - fprintf(header, "\n"); - write_c_disp_method_def(iface); - indentation--; - fprintf(header, " END_INTERFACE\n"); - fprintf(header, "} %sVtbl;\n", iface->name); - fprintf(header, "interface %s {\n", iface->name); - fprintf(header, " CONST_VTBL %sVtbl* lpVtbl;\n", iface->name); - fprintf(header, "};\n"); - fprintf(header, "\n"); - fprintf(header, "#ifdef COBJMACROS\n"); - write_method_macro(iface->ref, iface->name); - fprintf(header, "#endif\n"); - fprintf(header, "\n"); - fprintf(header, "#endif\n"); - fprintf(header, "\n"); - fprintf(header,"#endif /* __%s_DISPINTERFACE_DEFINED__ */\n\n", iface->name); -} - -void write_coclass(type_t *cocl) -{ - fprintf(header, "/*****************************************************************************\n"); - fprintf(header, " * %s coclass\n", cocl->name); - fprintf(header, " */\n\n"); - write_coclass_guid(cocl); - fprintf(header, "\n"); -} - -void write_coclass_forward(type_t *cocl) -{ - fprintf(header, "#ifndef __%s_FWD_DEFINED__\n", cocl->name); - fprintf(header, "#define __%s_FWD_DEFINED__\n", cocl->name); - fprintf(header, "typedef struct %s %s;\n", cocl->name, cocl->name); - fprintf(header, "#endif /* defined __%s_FWD_DEFINED__ */\n\n", cocl->name ); -} diff --git a/reactos/tools/widl_20080105/header.h b/reactos/tools/widl_20080105/header.h deleted file mode 100644 index 41784a0b152..00000000000 --- a/reactos/tools/widl_20080105/header.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * IDL Compiler - * - * Copyright 2002 Ove Kaaven - * - * 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 - */ - -#ifndef __WIDL_HEADER_H -#define __WIDL_HEADER_H - -#include "widltypes.h" - -extern int is_ptrchain_attr(const var_t *var, enum attr_type t); -extern int is_attr(const attr_list_t *list, enum attr_type t); -extern void *get_attrp(const attr_list_t *list, enum attr_type t); -extern unsigned long get_attrv(const attr_list_t *list, enum attr_type t); -extern int is_void(const type_t *t); -extern int is_conformant_array(const type_t *t); -extern int is_declptr(const type_t *t); -extern void write_name(FILE *h, const var_t *v); -extern void write_prefix_name(FILE *h, const char *prefix, const var_t *v); -extern const char* get_name(const var_t *v); -extern void write_type_left(FILE *h, type_t *t, int declonly); -extern void write_type_right(FILE *h, type_t *t, int is_field); -extern void write_type_def_or_decl(FILE *h, type_t *t, int is_field, const char *fmt, ...); -extern void write_type_decl(FILE *f, type_t *t, const char *fmt, ...); -extern void write_type_decl_left(FILE *f, type_t *t); -extern int needs_space_after(type_t *t); -extern int is_object(const attr_list_t *list); -extern int is_local(const attr_list_t *list); -extern int need_stub(const type_t *iface); -extern int need_proxy(const type_t *iface); -extern int need_stub_files(const ifref_list_t *ifaces); -extern int need_proxy_file(const ifref_list_t *ifaces); -extern const var_t *is_callas(const attr_list_t *list); -extern void write_args(FILE *h, const var_list_t *arg, const char *name, int obj, int do_indent); -extern void write_array(FILE *h, array_dims_t *v, int field); -extern void write_forward(type_t *iface); -extern void write_interface(type_t *iface); -extern void write_dispinterface(type_t *iface); -extern void write_locals(FILE *fp, const type_t *iface, int body); -extern void write_coclass(type_t *cocl); -extern void write_coclass_forward(type_t *cocl); -extern void write_typedef(type_t *type); -extern void write_expr(FILE *h, const expr_t *e, int brackets); -extern void write_constdef(const var_t *v); -extern void write_externdef(const var_t *v); -extern void write_library(const char *name, const attr_list_t *attr); -extern void write_user_types(void); -extern void write_context_handle_rundowns(void); -extern const var_t* get_explicit_handle_var(const func_t* func); -extern int has_out_arg_or_return(const func_t *func); -extern void write_guid(FILE *f, const char *guid_prefix, const char *name, - const UUID *uuid); - -static inline int last_ptr(const type_t *type) -{ - return is_ptr(type) && !is_declptr(type->ref); -} - -static inline int last_array(const type_t *type) -{ - return is_array(type) && !is_array(type->ref); -} - -static inline int is_string_type(const attr_list_t *attrs, const type_t *type) -{ - return is_attr(attrs, ATTR_STRING) && (last_ptr(type) || last_array(type)); -} - -static inline int is_context_handle(const type_t *type) -{ - const type_t *t; - for (t = type; is_ptr(t); t = t->ref) - if (is_attr(t->attrs, ATTR_CONTEXTHANDLE)) - return 1; - return 0; -} - -#endif diff --git a/reactos/tools/widl_20080105/parser.h b/reactos/tools/widl_20080105/parser.h deleted file mode 100644 index c46364aee41..00000000000 --- a/reactos/tools/widl_20080105/parser.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * IDL Compiler - * - * Copyright 2002 Ove Kaaven - * - * 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 - */ - -#ifndef __WIDL_PARSER_H -#define __WIDL_PARSER_H - -typedef struct -{ - type_t *interface; - unsigned char old_pointer_default; -} interface_info_t; - -int parser_parse(void); - -extern FILE *parser_in; -extern char *parser_text; -extern int parser_debug; -extern int yy_flex_debug; - -int parser_lex(void); - -extern int import_stack_ptr; -int do_import(char *fname); -void abort_import(void); - -#define parse_only import_stack_ptr - -int is_type(const char *name); - -#endif diff --git a/reactos/tools/widl_20080105/parser.l b/reactos/tools/widl_20080105/parser.l deleted file mode 100644 index d2fd3c1248c..00000000000 --- a/reactos/tools/widl_20080105/parser.l +++ /dev/null @@ -1,443 +0,0 @@ -/* -*-C-*- - * IDL Compiler - * - * Copyright 2002 Ove Kaaven - * - * 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 - */ - -%option stack -%option nounput noyy_top_state -%option 8bit never-interactive prefix="parser_" - -nl \r?\n -ws [ \f\t\r] -cident [a-zA-Z_][0-9a-zA-Z_]* -int [0-9]+ -hexd [0-9a-fA-F] -hex 0x{hexd}+ -uuid {hexd}{8}-{hexd}{4}-{hexd}{4}-{hexd}{4}-{hexd}{12} -double [0-9]+\.[0-9]+([eE][+-]?[0-9]+)* - -%x QUOTE -%x ATTR -%x PP_LINE - -%{ - -#include "config.h" - -#include -#include -#include -#include -#include -#ifdef HAVE_UNISTD_H -# include -#endif - -#include "widl.h" -#include "utils.h" -#include "parser.h" -#include "wine/wpp.h" - -#include "parser.tab.h" - -extern char *temp_name; - -static void addcchar(char c); -static char *get_buffered_cstring(void); - -static char *cbuffer; -static int cbufidx; -static int cbufalloc = 0; - -static int kw_token(const char *kw); -static int attr_token(const char *kw); - -#define MAX_IMPORT_DEPTH 10 -struct { - YY_BUFFER_STATE state; - char *input_name; - int line_number; - char *temp_name; -} import_stack[MAX_IMPORT_DEPTH]; -int import_stack_ptr = 0; - -static void pop_import(void); - -UUID *parse_uuid(const char *u) -{ - UUID* uuid = xmalloc(sizeof(UUID)); - char b[3]; - /* it would be nice to use UuidFromStringA */ - uuid->Data1 = strtoul(u, NULL, 16); - uuid->Data2 = strtoul(u+9, NULL, 16); - uuid->Data3 = strtoul(u+14, NULL, 16); - b[2] = 0; - memcpy(b, u+19, 2); uuid->Data4[0] = strtoul(b, NULL, 16); - memcpy(b, u+21, 2); uuid->Data4[1] = strtoul(b, NULL, 16); - memcpy(b, u+24, 2); uuid->Data4[2] = strtoul(b, NULL, 16); - memcpy(b, u+26, 2); uuid->Data4[3] = strtoul(b, NULL, 16); - memcpy(b, u+28, 2); uuid->Data4[4] = strtoul(b, NULL, 16); - memcpy(b, u+30, 2); uuid->Data4[5] = strtoul(b, NULL, 16); - memcpy(b, u+32, 2); uuid->Data4[6] = strtoul(b, NULL, 16); - memcpy(b, u+34, 2); uuid->Data4[7] = strtoul(b, NULL, 16); - return uuid; -} - -%} - -/* - ************************************************************************** - * The flexer starts here - ************************************************************************** - */ -%% -^{ws}*\#{ws}* yy_push_state(PP_LINE); -[^\n]* { - int lineno; - char *cptr, *fname; - yy_pop_state(); - lineno = (int)strtol(yytext, &cptr, 10); - if(!lineno) - error_loc("Malformed '#...' line-directive; invalid linenumber\n"); - fname = strchr(cptr, '"'); - if(!fname) - error_loc("Malformed '#...' line-directive; missing filename\n"); - fname++; - cptr = strchr(fname, '"'); - if(!cptr) - error_loc("Malformed '#...' line-directive; missing terminating \"\n"); - *cptr = '\0'; - line_number = lineno - 1; /* We didn't read the newline */ - free( input_name ); - input_name = xstrdup(fname); - } -\" yy_push_state(QUOTE); cbufidx = 0; -\" { - yy_pop_state(); - parser_lval.str = get_buffered_cstring(); - return aSTRING; - } -\\\\ | -\\\" addcchar(yytext[1]); -\\. addcchar('\\'); addcchar(yytext[1]); -. addcchar(yytext[0]); -\[ yy_push_state(ATTR); return '['; -\] yy_pop_state(); return ']'; -{cident} return attr_token(yytext); -{uuid} { - parser_lval.uuid = parse_uuid(yytext); - return aUUID; - } -{hex} { - parser_lval.num = strtoul(yytext, NULL, 0); - return aHEXNUM; - } -{int} { - parser_lval.num = strtoul(yytext, NULL, 0); - return aNUM; - } -{double} { - parser_lval.dbl = strtod(yytext, NULL); - return aDOUBLE; - } -SAFEARRAY{ws}*/\( return tSAFEARRAY; -{cident} return kw_token(yytext); -\n line_number++; -{ws} -\<\< return SHL; -\>\> return SHR; -. return yytext[0]; -<> { - if (import_stack_ptr) { - pop_import(); - return aEOF; - } - else yyterminate(); - } -%% - -#ifndef parser_wrap -int parser_wrap(void) -{ - return 1; -} -#endif - -struct keyword { - const char *kw; - int token; -}; - -static const struct keyword keywords[] = { - {"FALSE", tFALSE}, - {"TRUE", tTRUE}, - {"__cdecl", tCDECL}, - {"__int64", tINT64}, - {"__stdcall", tSTDCALL}, - {"_stdcall", tSTDCALL}, - {"boolean", tBOOLEAN}, - {"byte", tBYTE}, - {"callback", tCALLBACK}, - {"case", tCASE}, - {"char", tCHAR}, - {"coclass", tCOCLASS}, - {"code", tCODE}, - {"comm_status", tCOMMSTATUS}, - {"const", tCONST}, - {"cpp_quote", tCPPQUOTE}, - {"default", tDEFAULT}, - {"dispinterface", tDISPINTERFACE}, - {"double", tDOUBLE}, - {"enum", tENUM}, - {"error_status_t", tERRORSTATUST}, - {"extern", tEXTERN}, - {"float", tFLOAT}, - {"handle_t", tHANDLET}, - {"hyper", tHYPER}, - {"import", tIMPORT}, - {"importlib", tIMPORTLIB}, - {"in_line", tINLINE}, - {"int", tINT}, - {"interface", tINTERFACE}, - {"library", tLIBRARY}, - {"long", tLONG}, - {"methods", tMETHODS}, - {"module", tMODULE}, - {"properties", tPROPERTIES}, - {"short", tSHORT}, - {"signed", tSIGNED}, - {"sizeof", tSIZEOF}, - {"small", tSMALL}, - {"struct", tSTRUCT}, - {"switch", tSWITCH}, - {"typedef", tTYPEDEF}, - {"union", tUNION}, - {"unsigned", tUNSIGNED}, - {"void", tVOID}, - {"wchar_t", tWCHAR}, -}; -#define NKEYWORDS (sizeof(keywords)/sizeof(keywords[0])) - -/* keywords only recognized in attribute lists */ -static const struct keyword attr_keywords[] = -{ - {"aggregatable", tAGGREGATABLE}, - {"allocate", tALLOCATE}, - {"appobject", tAPPOBJECT}, - {"async", tASYNC}, - {"async_uuid", tASYNCUUID}, - {"auto_handle", tAUTOHANDLE}, - {"bindable", tBINDABLE}, - {"broadcast", tBROADCAST}, - {"byte_count", tBYTECOUNT}, - {"call_as", tCALLAS}, - {"context_handle", tCONTEXTHANDLE}, - {"context_handle_noserialize", tCONTEXTHANDLENOSERIALIZE}, - {"context_handle_serialize", tCONTEXTHANDLENOSERIALIZE}, - {"control", tCONTROL}, - {"defaultcollelem", tDEFAULTCOLLELEM}, - {"defaultvalue", tDEFAULTVALUE}, - {"defaultvtable", tDEFAULTVTABLE}, - {"displaybind", tDISPLAYBIND}, - {"dllname", tDLLNAME}, - {"dual", tDUAL}, - {"endpoint", tENDPOINT}, - {"entry", tENTRY}, - {"explicit_handle", tEXPLICITHANDLE}, - {"handle", tHANDLE}, - {"helpcontext", tHELPCONTEXT}, - {"helpfile", tHELPFILE}, - {"helpstring", tHELPSTRING}, - {"helpstringcontext", tHELPSTRINGCONTEXT}, - {"helpstringdll", tHELPSTRINGDLL}, - {"hidden", tHIDDEN}, - {"id", tID}, - {"idempotent", tIDEMPOTENT}, - {"iid_is", tIIDIS}, - {"immediatebind", tIMMEDIATEBIND}, - {"implicit_handle", tIMPLICITHANDLE}, - {"in", tIN}, - {"input_sync", tINPUTSYNC}, - {"lcid", tLCID}, - {"length_is", tLENGTHIS}, - {"local", tLOCAL}, - {"nonbrowsable", tNONBROWSABLE}, - {"noncreatable", tNONCREATABLE}, - {"nonextensible", tNONEXTENSIBLE}, - {"object", tOBJECT}, - {"odl", tODL}, - {"oleautomation", tOLEAUTOMATION}, - {"optional", tOPTIONAL}, - {"out", tOUT}, - {"pointer_default", tPOINTERDEFAULT}, - {"propget", tPROPGET}, - {"propput", tPROPPUT}, - {"propputref", tPROPPUTREF}, - {"ptr", tPTR}, - {"public", tPUBLIC}, - {"range", tRANGE}, - {"readonly", tREADONLY}, - {"ref", tREF}, - {"requestedit", tREQUESTEDIT}, - {"restricted", tRESTRICTED}, - {"retval", tRETVAL}, - {"single", tSINGLE}, - {"size_is", tSIZEIS}, - {"source", tSOURCE}, - {"string", tSTRING}, - {"switch_is", tSWITCHIS}, - {"switch_type", tSWITCHTYPE}, - {"transmit_as", tTRANSMITAS}, - {"unique", tUNIQUE}, - {"uuid", tUUID}, - {"v1_enum", tV1ENUM}, - {"vararg", tVARARG}, - {"version", tVERSION}, - {"wire_marshal", tWIREMARSHAL}, -}; - - -#define KWP(p) ((const struct keyword *)(p)) - -static int kw_cmp_func(const void *s1, const void *s2) -{ - return strcmp(KWP(s1)->kw, KWP(s2)->kw); -} - -static int kw_token(const char *kw) -{ - struct keyword key, *kwp; - key.kw = kw; - kwp = bsearch(&key, keywords, NKEYWORDS, sizeof(keywords[0]), kw_cmp_func); - if (kwp) { - parser_lval.str = xstrdup(kwp->kw); - return kwp->token; - } - parser_lval.str = xstrdup(kw); - return is_type(kw) ? aKNOWNTYPE : aIDENTIFIER; -} - -static int attr_token(const char *kw) -{ - struct keyword key, *kwp; - key.kw = kw; - kwp = bsearch(&key, attr_keywords, sizeof(attr_keywords)/sizeof(attr_keywords[0]), - sizeof(attr_keywords[0]), kw_cmp_func); - if (kwp) { - parser_lval.str = xstrdup(kwp->kw); - return kwp->token; - } - return kw_token(kw); -} - -static void addcchar(char c) -{ - if(cbufidx >= cbufalloc) - { - cbufalloc += 1024; - cbuffer = xrealloc(cbuffer, cbufalloc * sizeof(cbuffer[0])); - if(cbufalloc > 65536) - parser_warning("Reallocating string buffer larger than 64kB\n"); - } - cbuffer[cbufidx++] = c; -} - -static char *get_buffered_cstring(void) -{ - addcchar(0); - return xstrdup(cbuffer); -} - -static void pop_import(void) -{ - int ptr = import_stack_ptr-1; - - fclose(yyin); - yy_delete_buffer( YY_CURRENT_BUFFER ); - yy_switch_to_buffer( import_stack[ptr].state ); - if (temp_name) { - unlink(temp_name); - free(temp_name); - } - temp_name = import_stack[ptr].temp_name; - free( input_name ); - input_name = import_stack[ptr].input_name; - line_number = import_stack[ptr].line_number; - import_stack_ptr--; -} - -struct imports { - char *name; - struct imports *next; -} *first_import; - -int do_import(char *fname) -{ - FILE *f; - char *hname, *path, *p; - struct imports *import; - int ptr = import_stack_ptr; - int ret; - - if (!parse_only && do_header) { - hname = dup_basename(fname, ".idl"); - p = hname + strlen(hname) - 2; - if (p <= hname || strcmp( p, ".h" )) strcat(hname, ".h"); - - fprintf(header, "#include <%s>\n", hname); - free(hname); - } - - import = first_import; - while (import && strcmp(import->name, fname)) - import = import->next; - if (import) return 0; /* already imported */ - - import = xmalloc(sizeof(struct imports)); - import->name = xstrdup(fname); - import->next = first_import; - first_import = import; - - if (!(path = wpp_find_include( fname, input_name ))) - error_loc("Unable to open include file %s\n", fname); - - import_stack[ptr].temp_name = temp_name; - import_stack[ptr].input_name = input_name; - import_stack[ptr].line_number = line_number; - import_stack_ptr++; - input_name = path; - line_number = 1; - - ret = wpp_parse_temp( path, NULL, &temp_name ); - if (ret) exit(1); - - if((f = fopen(temp_name, "r")) == NULL) - error_loc("Unable to open %s\n", temp_name); - - import_stack[ptr].state = YY_CURRENT_BUFFER; - yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE)); - return 1; -} - -void abort_import(void) -{ - int ptr; - - for (ptr=0; ptr -#include -#include -#include -#include -#include -#ifdef HAVE_ALLOCA_H -#include -#endif - -#include "widl.h" -#include "utils.h" -#include "parser.h" -#include "header.h" -#include "typelib.h" -#include "typegen.h" - -#if defined(YYBYACC) - /* Berkeley yacc (byacc) doesn't seem to know about these */ - /* Some *BSD supplied versions do define these though */ -# ifndef YYEMPTY -# define YYEMPTY (-1) /* Empty lookahead value of yychar */ -# endif -# ifndef YYLEX -# define YYLEX yylex() -# endif - -#elif defined(YYBISON) - /* Bison was used for original development */ - /* #define YYEMPTY -2 */ - /* #define YYLEX yylex() */ - -#else - /* No yacc we know yet */ -# if !defined(YYEMPTY) || !defined(YYLEX) -# error Yacc version/type unknown. This version needs to be verified for settings of YYEMPTY and YYLEX. -# elif defined(__GNUC__) /* gcc defines the #warning directive */ -# warning Yacc version/type unknown. It defines YYEMPTY and YYLEX, but is not tested - /* #else we just take a chance that it works... */ -# endif -#endif - -unsigned char pointer_default = RPC_FC_UP; - -typedef struct list typelist_t; -struct typenode { - type_t *type; - struct list entry; -}; - -typelist_t incomplete_types = LIST_INIT(incomplete_types); - -static void add_incomplete(type_t *t); -static void fix_incomplete(void); - -static str_list_t *append_str(str_list_t *list, char *str); -static attr_list_t *append_attr(attr_list_t *list, attr_t *attr); -static attr_t *make_attr(enum attr_type type); -static attr_t *make_attrv(enum attr_type type, unsigned long val); -static attr_t *make_attrp(enum attr_type type, void *val); -static expr_t *make_expr(enum expr_type type); -static expr_t *make_exprl(enum expr_type type, long val); -static expr_t *make_exprd(enum expr_type type, double val); -static expr_t *make_exprs(enum expr_type type, char *val); -static expr_t *make_exprt(enum expr_type type, type_t *tref, expr_t *expr); -static expr_t *make_expr1(enum expr_type type, expr_t *expr); -static expr_t *make_expr2(enum expr_type type, expr_t *exp1, expr_t *exp2); -static expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, expr_t *expr3); -static type_t *make_type(unsigned char type, type_t *ref); -static expr_list_t *append_expr(expr_list_t *list, expr_t *expr); -static array_dims_t *append_array(array_dims_t *list, expr_t *expr); -static void set_type(var_t *v, type_t *type, int ptr_level, array_dims_t *arr, int top); -static ifref_list_t *append_ifref(ifref_list_t *list, ifref_t *iface); -static ifref_t *make_ifref(type_t *iface); -static var_list_t *append_var(var_list_t *list, var_t *var); -static var_t *make_var(char *name); -static pident_list_t *append_pident(pident_list_t *list, pident_t *p); -static pident_t *make_pident(var_t *var); -static func_list_t *append_func(func_list_t *list, func_t *func); -static func_t *make_func(var_t *def, var_list_t *args); -static type_t *make_class(char *name); -static type_t *make_safearray(type_t *type); -static type_t *make_builtin(char *name); -static type_t *make_int(int sign); - -static type_t *reg_type(type_t *type, const char *name, int t); -static type_t *reg_typedefs(type_t *type, var_list_t *names, attr_list_t *attrs); -static type_t *find_type(const char *name, int t); -static type_t *find_type2(char *name, int t); -static type_t *get_type(unsigned char type, char *name, int t); -static type_t *get_typev(unsigned char type, var_t *name, int t); -static int get_struct_type(var_list_t *fields); - -static var_t *reg_const(var_t *var); -static var_t *find_const(char *name, int f); - -static void write_libid(const char *name, const attr_list_t *attr); -static void write_clsid(type_t *cls); -static void write_diid(type_t *iface); -static void write_iid(type_t *iface); - -static int compute_method_indexes(type_t *iface); -static char *gen_name(void); -static void process_typedefs(var_list_t *names); -static void check_arg(var_t *arg); -static void check_all_user_types(ifref_list_t *ifaces); - -#define tsENUM 1 -#define tsSTRUCT 2 -#define tsUNION 3 - - - -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif - -/* Enabling verbose error messages. */ -#ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 -#else -# define YYERROR_VERBOSE 0 -#endif - -/* Enabling the token table. */ -#ifndef YYTOKEN_TABLE -# define YYTOKEN_TABLE 0 -#endif - -#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) -#line 136 "parser.y" -typedef union YYSTYPE { - attr_t *attr; - attr_list_t *attr_list; - str_list_t *str_list; - expr_t *expr; - expr_list_t *expr_list; - array_dims_t *array_dims; - type_t *type; - var_t *var; - var_list_t *var_list; - pident_t *pident; - pident_list_t *pident_list; - func_t *func; - func_list_t *func_list; - ifref_t *ifref; - ifref_list_t *ifref_list; - char *str; - UUID *uuid; - unsigned int num; - double dbl; - interface_info_t ifinfo; -} YYSTYPE; -/* Line 196 of yacc.c. */ -#line 522 "parser.tab.c" -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 -#endif - - - -/* Copy the second part of user declarations. */ - - -/* Line 219 of yacc.c. */ -#line 534 "parser.tab.c" - -#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) -# define YYSIZE_T __SIZE_TYPE__ -#endif -#if ! defined (YYSIZE_T) && defined (size_t) -# define YYSIZE_T size_t -#endif -#if ! defined (YYSIZE_T) && (defined (__STDC__) || defined (__cplusplus)) -# include /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -#endif -#if ! defined (YYSIZE_T) -# define YYSIZE_T unsigned int -#endif - -#ifndef YY_ -# if YYENABLE_NLS -# if ENABLE_NLS -# include /* INFRINGES ON USER NAME SPACE */ -# define YY_(msgid) dgettext ("bison-runtime", msgid) -# endif -# endif -# ifndef YY_ -# define YY_(msgid) msgid -# endif -#endif - -#if ! defined (yyoverflow) || YYERROR_VERBOSE - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# ifdef YYSTACK_USE_ALLOCA -# if YYSTACK_USE_ALLOCA -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# else -# define YYSTACK_ALLOC alloca -# if defined (__STDC__) || defined (__cplusplus) -# include /* INFRINGES ON USER NAME SPACE */ -# define YYINCLUDED_STDLIB_H -# endif -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's `empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) -# ifndef YYSTACK_ALLOC_MAXIMUM - /* The OS might guarantee only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely - invoke alloca (N) if N exceeds 4096. Use a slightly smaller number - to allow for a few compiler-allocated temporary stack slots. */ -# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2005 */ -# endif -# else -# define YYSTACK_ALLOC YYMALLOC -# define YYSTACK_FREE YYFREE -# ifndef YYSTACK_ALLOC_MAXIMUM -# define YYSTACK_ALLOC_MAXIMUM ((YYSIZE_T) -1) -# endif -# ifdef __cplusplus -extern "C" { -# endif -# ifndef YYMALLOC -# define YYMALLOC malloc -# if (! defined (malloc) && ! defined (YYINCLUDED_STDLIB_H) \ - && (defined (__STDC__) || defined (__cplusplus))) -void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# ifndef YYFREE -# define YYFREE free -# if (! defined (free) && ! defined (YYINCLUDED_STDLIB_H) \ - && (defined (__STDC__) || defined (__cplusplus))) -void free (void *); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# ifdef __cplusplus -} -# endif -# endif -#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ - - -#if (! defined (yyoverflow) \ - && (! defined (__cplusplus) \ - || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - short int yyss; - YYSTYPE yyvs; - }; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# define YYSTACK_BYTES(N) \ - ((N) * (sizeof (short int) + sizeof (YYSTYPE)) \ - + YYSTACK_GAP_MAXIMUM) - -/* Copy COUNT objects from FROM to TO. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if defined (__GNUC__) && 1 < __GNUC__ -# define YYCOPY(To, From, Count) \ - __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -# else -# define YYCOPY(To, From, Count) \ - do \ - { \ - YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (To)[yyi] = (From)[yyi]; \ - } \ - while (0) -# endif -# endif - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack, Stack, yysize); \ - Stack = &yyptr->Stack; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (0) - -#endif - -#if defined (__STDC__) || defined (__cplusplus) - typedef signed char yysigned_char; -#else - typedef short int yysigned_char; -#endif - -/* YYFINAL -- State number of the termination state. */ -#define YYFINAL 3 -/* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 1065 - -/* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 155 -/* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 76 -/* YYNRULES -- Number of rules. */ -#define YYNRULES 271 -/* YYNRULES -- Number of states. */ -#define YYNSTATES 499 - -/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -#define YYUNDEFTOK 2 -#define YYMAXUTOK 390 - -#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) - -/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -static const unsigned char yytranslate[] = -{ - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 136, 2, - 147, 148, 139, 138, 132, 137, 154, 140, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 134, 146, - 2, 153, 2, 133, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 151, 2, 152, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 149, 135, 150, 141, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, - 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, - 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, - 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, - 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, - 125, 126, 127, 128, 129, 130, 131, 142, 143, 144, - 145 -}; - -#if YYDEBUG -/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in - YYRHS. */ -static const unsigned short int yyprhs[] = -{ - 0, 0, 3, 5, 6, 9, 12, 16, 19, 22, - 25, 28, 29, 32, 35, 39, 42, 45, 48, 51, - 52, 56, 59, 61, 64, 66, 69, 72, 74, 77, - 80, 83, 88, 92, 96, 101, 104, 108, 112, 113, - 115, 117, 119, 123, 125, 130, 134, 141, 147, 148, - 152, 156, 158, 162, 167, 168, 170, 174, 176, 180, - 185, 187, 191, 192, 194, 196, 198, 200, 202, 207, - 212, 214, 216, 218, 220, 222, 224, 229, 234, 236, - 238, 243, 245, 250, 255, 260, 262, 264, 269, 274, - 279, 284, 289, 291, 296, 298, 303, 305, 311, 313, - 315, 320, 322, 324, 326, 328, 330, 332, 334, 336, - 338, 343, 345, 347, 349, 351, 358, 360, 362, 364, - 366, 371, 373, 375, 380, 385, 390, 395, 397, 399, - 404, 409, 411, 413, 415, 416, 418, 419, 422, 427, - 431, 437, 438, 441, 443, 445, 449, 453, 455, 461, - 463, 467, 468, 470, 472, 474, 476, 478, 480, 482, - 488, 492, 496, 500, 504, 508, 512, 516, 520, 523, - 526, 529, 532, 537, 542, 546, 548, 552, 554, 559, - 560, 563, 566, 570, 573, 575, 580, 588, 589, 591, - 592, 594, 596, 598, 600, 602, 604, 606, 609, 612, - 614, 616, 618, 620, 622, 624, 626, 627, 629, 631, - 634, 636, 639, 642, 644, 646, 649, 652, 655, 660, - 661, 664, 667, 670, 673, 676, 679, 683, 686, 690, - 696, 702, 703, 706, 709, 712, 715, 721, 729, 731, - 734, 737, 740, 743, 746, 751, 754, 757, 759, 761, - 765, 767, 771, 773, 775, 777, 783, 785, 787, 789, - 792, 794, 797, 799, 802, 804, 807, 812, 817, 823, - 834, 836 -}; - -/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -static const short int yyrhs[] = -{ - 156, 0, -1, 157, -1, -1, 157, 218, -1, 157, - 217, -1, 157, 204, 146, -1, 157, 206, -1, 157, - 221, -1, 157, 167, -1, 157, 160, -1, -1, 158, - 218, -1, 158, 217, -1, 158, 204, 146, -1, 158, - 206, -1, 158, 221, -1, 158, 160, -1, 158, 164, - -1, -1, 159, 197, 146, -1, 159, 160, -1, 146, - -1, 183, 146, -1, 161, -1, 187, 146, -1, 193, - 146, -1, 163, -1, 226, 146, -1, 228, 146, -1, - 229, 146, -1, 37, 147, 8, 148, -1, 69, 8, - 146, -1, 162, 158, 10, -1, 70, 147, 8, 148, - -1, 79, 3, -1, 175, 165, 149, -1, 166, 158, - 150, -1, -1, 170, -1, 129, -1, 171, -1, 170, - 132, 171, -1, 169, -1, 175, 227, 223, 172, -1, - 227, 223, 172, -1, 175, 227, 223, 147, 168, 148, - -1, 227, 223, 147, 168, 148, -1, -1, 151, 173, - 152, -1, 151, 139, 152, -1, 189, -1, 173, 132, - 190, -1, 173, 152, 151, 190, -1, -1, 175, -1, - 151, 176, 152, -1, 178, -1, 176, 132, 178, -1, - 176, 152, 151, 178, -1, 8, -1, 177, 132, 8, - -1, -1, 13, -1, 15, -1, 16, -1, 18, -1, - 19, -1, 24, 147, 200, 148, -1, 26, 147, 191, - 148, -1, 33, -1, 34, -1, 35, -1, 36, -1, - 38, -1, 39, -1, 40, 147, 192, 148, -1, 40, - 147, 8, 148, -1, 41, -1, 42, -1, 44, 147, - 8, 148, -1, 46, -1, 47, 147, 177, 148, -1, - 48, 147, 8, 148, -1, 48, 147, 192, 148, -1, - 51, -1, 55, -1, 57, 147, 192, 148, -1, 58, - 147, 8, 148, -1, 59, 147, 8, 148, -1, 60, - 147, 192, 148, -1, 61, 147, 8, 148, -1, 62, - -1, 64, 147, 192, 148, -1, 65, -1, 66, 147, - 190, 148, -1, 67, -1, 68, 147, 56, 3, 148, - -1, 71, -1, 73, -1, 78, 147, 188, 148, -1, - 80, -1, 84, -1, 85, -1, 86, -1, 87, -1, - 88, -1, 89, -1, 90, -1, 91, -1, 92, 147, - 225, 148, -1, 94, -1, 95, -1, 96, -1, 98, - -1, 99, 147, 192, 132, 192, 148, -1, 100, -1, - 102, -1, 103, -1, 104, -1, 109, 147, 188, 148, - -1, 112, -1, 114, -1, 117, 147, 190, 148, -1, - 118, 147, 227, 148, -1, 119, 147, 227, 148, -1, - 125, 147, 179, 148, -1, 126, -1, 127, -1, 128, - 147, 230, 148, -1, 131, 147, 227, 148, -1, 225, - -1, 9, -1, 8, -1, -1, 113, -1, -1, 181, - 182, -1, 26, 190, 134, 195, -1, 38, 134, 195, - -1, 32, 227, 200, 153, 192, -1, -1, 185, 132, - -1, 185, -1, 186, -1, 185, 132, 186, -1, 200, - 153, 192, -1, 200, -1, 49, 199, 149, 184, 150, - -1, 189, -1, 188, 132, 189, -1, -1, 190, -1, - 5, -1, 6, -1, 7, -1, 53, -1, 120, -1, - 3, -1, 190, 133, 190, 134, 190, -1, 190, 135, - 190, -1, 190, 136, 190, -1, 190, 138, 190, -1, - 190, 137, 190, -1, 190, 139, 190, -1, 190, 140, - 190, -1, 190, 11, 190, -1, 190, 12, 190, -1, - 141, 190, -1, 137, 190, -1, 136, 190, -1, 139, - 190, -1, 147, 227, 148, 190, -1, 110, 147, 227, - 148, -1, 147, 190, 148, -1, 192, -1, 191, 132, - 192, -1, 190, -1, 52, 32, 227, 200, -1, -1, - 194, 195, -1, 196, 146, -1, 174, 229, 146, -1, - 175, 146, -1, 146, -1, 174, 227, 223, 172, -1, - 174, 227, 180, 223, 147, 168, 148, -1, -1, 200, - -1, -1, 3, -1, 4, -1, 3, -1, 4, -1, - 22, -1, 130, -1, 203, -1, 107, 203, -1, 124, - 203, -1, 124, -1, 54, -1, 108, -1, 45, -1, - 20, -1, 50, -1, 56, -1, -1, 74, -1, 74, - -1, 106, 202, -1, 111, -1, 81, 202, -1, 63, - 202, -1, 75, -1, 28, -1, 29, 3, -1, 29, - 4, -1, 175, 204, -1, 205, 149, 207, 150, -1, - -1, 207, 208, -1, 174, 218, -1, 43, 3, -1, - 43, 4, -1, 175, 209, -1, 93, 134, -1, 211, - 196, 146, -1, 82, 134, -1, 212, 197, 146, -1, - 210, 149, 211, 212, 150, -1, 210, 149, 215, 146, - 150, -1, -1, 134, 4, -1, 76, 3, -1, 76, - 4, -1, 175, 215, -1, 216, 214, 149, 159, 150, - -1, 216, 134, 3, 149, 163, 159, 150, -1, 213, - -1, 215, 146, -1, 209, 146, -1, 83, 3, -1, - 83, 4, -1, 175, 219, -1, 220, 149, 159, 150, - -1, 139, 223, -1, 32, 222, -1, 200, -1, 222, - -1, 147, 223, 148, -1, 223, -1, 224, 132, 223, - -1, 101, -1, 123, -1, 97, -1, 115, 199, 149, - 194, 150, -1, 129, -1, 4, -1, 201, -1, 32, - 227, -1, 187, -1, 49, 3, -1, 226, -1, 115, - 3, -1, 229, -1, 122, 3, -1, 105, 147, 227, - 148, -1, 121, 174, 227, 224, -1, 122, 199, 149, - 194, 150, -1, 122, 199, 116, 147, 196, 148, 198, - 149, 181, 150, -1, 5, -1, 5, 154, 5, -1 -}; - -/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -static const unsigned short int yyrline[] = -{ - 0, 285, 285, 294, 295, 296, 297, 301, 306, 307, - 308, 311, 312, 313, 314, 315, 319, 320, 321, 324, - 325, 326, 329, 330, 331, 332, 337, 338, 339, 344, - 345, 352, 354, 357, 360, 363, 365, 370, 373, 374, - 377, 380, 381, 382, 386, 391, 395, 401, 408, 409, - 410, 413, 414, 415, 418, 419, 423, 429, 430, 431, - 434, 435, 438, 439, 440, 441, 442, 443, 444, 445, - 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, - 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, - 486, 487, 488, 489, 490, 491, 494, 495, 496, 497, - 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, - 508, 509, 513, 514, 519, 520, 523, 524, 527, 531, - 537, 543, 544, 545, 548, 552, 561, 565, 570, 579, - 580, 593, 594, 597, 598, 599, 600, 601, 602, 603, - 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, - 614, 615, 616, 617, 618, 621, 622, 625, 631, 636, - 637, 640, 641, 642, 643, 646, 654, 666, 667, 670, - 671, 672, 675, 677, 680, 681, 682, 683, 684, 700, - 701, 702, 703, 704, 705, 706, 709, 710, 713, 714, - 715, 716, 717, 718, 719, 722, 723, 729, 738, 744, - 745, 749, 752, 753, 756, 768, 769, 772, 773, 776, - 785, 794, 795, 798, 799, 802, 813, 825, 836, 840, - 841, 844, 845, 848, 853, 859, 860, 863, 864, 865, - 869, 870, 874, 875, 876, 879, 890, 891, 892, 893, - 894, 895, 896, 897, 898, 899, 900, 903, 908, 913, - 930, 931 -}; -#endif - -#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE -/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -static const char *const yytname[] = -{ - "$end", "error", "$undefined", "aIDENTIFIER", "aKNOWNTYPE", "aNUM", - "aHEXNUM", "aDOUBLE", "aSTRING", "aUUID", "aEOF", "SHL", "SHR", - "tAGGREGATABLE", "tALLOCATE", "tAPPOBJECT", "tASYNC", "tASYNCUUID", - "tAUTOHANDLE", "tBINDABLE", "tBOOLEAN", "tBROADCAST", "tBYTE", - "tBYTECOUNT", "tCALLAS", "tCALLBACK", "tCASE", "tCDECL", "tCHAR", - "tCOCLASS", "tCODE", "tCOMMSTATUS", "tCONST", "tCONTEXTHANDLE", - "tCONTEXTHANDLENOSERIALIZE", "tCONTEXTHANDLESERIALIZE", "tCONTROL", - "tCPPQUOTE", "tDEFAULT", "tDEFAULTCOLLELEM", "tDEFAULTVALUE", - "tDEFAULTVTABLE", "tDISPLAYBIND", "tDISPINTERFACE", "tDLLNAME", - "tDOUBLE", "tDUAL", "tENDPOINT", "tENTRY", "tENUM", "tERRORSTATUST", - "tEXPLICITHANDLE", "tEXTERN", "tFALSE", "tFLOAT", "tHANDLE", "tHANDLET", - "tHELPCONTEXT", "tHELPFILE", "tHELPSTRING", "tHELPSTRINGCONTEXT", - "tHELPSTRINGDLL", "tHIDDEN", "tHYPER", "tID", "tIDEMPOTENT", "tIIDIS", - "tIMMEDIATEBIND", "tIMPLICITHANDLE", "tIMPORT", "tIMPORTLIB", "tIN", - "tINLINE", "tINPUTSYNC", "tINT", "tINT64", "tINTERFACE", "tLCID", - "tLENGTHIS", "tLIBRARY", "tLOCAL", "tLONG", "tMETHODS", "tMODULE", - "tNONBROWSABLE", "tNONCREATABLE", "tNONEXTENSIBLE", "tOBJECT", "tODL", - "tOLEAUTOMATION", "tOPTIONAL", "tOUT", "tPOINTERDEFAULT", "tPROPERTIES", - "tPROPGET", "tPROPPUT", "tPROPPUTREF", "tPTR", "tPUBLIC", "tRANGE", - "tREADONLY", "tREF", "tREQUESTEDIT", "tRESTRICTED", "tRETVAL", - "tSAFEARRAY", "tSHORT", "tSIGNED", "tSINGLE", "tSIZEIS", "tSIZEOF", - "tSMALL", "tSOURCE", "tSTDCALL", "tSTRING", "tSTRUCT", "tSWITCH", - "tSWITCHIS", "tSWITCHTYPE", "tTRANSMITAS", "tTRUE", "tTYPEDEF", "tUNION", - "tUNIQUE", "tUNSIGNED", "tUUID", "tV1ENUM", "tVARARG", "tVERSION", - "tVOID", "tWCHAR", "tWIREMARSHAL", "','", "'?'", "':'", "'|'", "'&'", - "'-'", "'+'", "'*'", "'/'", "'~'", "CAST", "PPTR", "NEG", "ADDRESSOF", - "';'", "'('", "')'", "'{'", "'}'", "'['", "']'", "'='", "'.'", "$accept", - "input", "gbl_statements", "imp_statements", "int_statements", - "statement", "cppquote", "import_start", "import", "importlib", - "libraryhdr", "library_start", "librarydef", "m_args", "no_args", "args", - "arg", "array", "array_list", "m_attributes", "attributes", - "attrib_list", "str_list", "attribute", "uuid_string", "callconv", - "cases", "case", "constdef", "enums", "enum_list", "enum", "enumdef", - "m_exprs", "m_expr", "expr", "expr_list_const", "expr_const", - "externdef", "fields", "field", "s_field", "funcdef", "m_ident", - "t_ident", "ident", "base_type", "m_int", "int_std", "coclass", - "coclasshdr", "coclassdef", "coclass_ints", "coclass_int", - "dispinterface", "dispinterfacehdr", "dispint_props", "dispint_meths", - "dispinterfacedef", "inherit", "interface", "interfacehdr", - "interfacedef", "interfacedec", "module", "modulehdr", "moduledef", - "p_ident", "pident", "pident_list", "pointer_type", "structdef", "type", - "typedef", "uniondef", "version", 0 -}; -#endif - -# ifdef YYPRINT -/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to - token YYLEX-NUM. */ -static const unsigned short int yytoknum[] = -{ - 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, - 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, - 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 44, 63, 58, 124, 38, 45, 43, 42, - 47, 126, 387, 388, 389, 390, 59, 40, 41, 123, - 125, 91, 93, 61, 46 -}; -# endif - -/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const unsigned char yyr1[] = -{ - 0, 155, 156, 157, 157, 157, 157, 157, 157, 157, - 157, 158, 158, 158, 158, 158, 158, 158, 158, 159, - 159, 159, 160, 160, 160, 160, 160, 160, 160, 160, - 160, 161, 162, 163, 164, 165, 166, 167, 168, 168, - 169, 170, 170, 170, 171, 171, 171, 171, 172, 172, - 172, 173, 173, 173, 174, 174, 175, 176, 176, 176, - 177, 177, 178, 178, 178, 178, 178, 178, 178, 178, - 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, - 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, - 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, - 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, - 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, - 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, - 178, 178, 179, 179, 180, 180, 181, 181, 182, 182, - 183, 184, 184, 184, 185, 185, 186, 186, 187, 188, - 188, 189, 189, 190, 190, 190, 190, 190, 190, 190, - 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, - 190, 190, 190, 190, 190, 191, 191, 192, 193, 194, - 194, 195, 195, 195, 195, 196, 197, 198, 198, 199, - 199, 199, 200, 200, 201, 201, 201, 201, 201, 201, - 201, 201, 201, 201, 201, 201, 202, 202, 203, 203, - 203, 203, 203, 203, 203, 204, 204, 205, 206, 207, - 207, 208, 209, 209, 210, 211, 211, 212, 212, 213, - 213, 214, 214, 215, 215, 216, 217, 217, 217, 218, - 218, 219, 219, 220, 221, 222, 222, 223, 223, 223, - 224, 224, 225, 225, 225, 226, 227, 227, 227, 227, - 227, 227, 227, 227, 227, 227, 227, 228, 229, 229, - 230, 230 -}; - -/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -static const unsigned char yyr2[] = -{ - 0, 2, 1, 0, 2, 2, 3, 2, 2, 2, - 2, 0, 2, 2, 3, 2, 2, 2, 2, 0, - 3, 2, 1, 2, 1, 2, 2, 1, 2, 2, - 2, 4, 3, 3, 4, 2, 3, 3, 0, 1, - 1, 1, 3, 1, 4, 3, 6, 5, 0, 3, - 3, 1, 3, 4, 0, 1, 3, 1, 3, 4, - 1, 3, 0, 1, 1, 1, 1, 1, 4, 4, - 1, 1, 1, 1, 1, 1, 4, 4, 1, 1, - 4, 1, 4, 4, 4, 1, 1, 4, 4, 4, - 4, 4, 1, 4, 1, 4, 1, 5, 1, 1, - 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 4, 1, 1, 1, 1, 6, 1, 1, 1, 1, - 4, 1, 1, 4, 4, 4, 4, 1, 1, 4, - 4, 1, 1, 1, 0, 1, 0, 2, 4, 3, - 5, 0, 2, 1, 1, 3, 3, 1, 5, 1, - 3, 0, 1, 1, 1, 1, 1, 1, 1, 5, - 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, - 2, 2, 4, 4, 3, 1, 3, 1, 4, 0, - 2, 2, 3, 2, 1, 4, 7, 0, 1, 0, - 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, - 1, 1, 1, 1, 1, 1, 0, 1, 1, 2, - 1, 2, 2, 1, 1, 2, 2, 2, 4, 0, - 2, 2, 2, 2, 2, 2, 3, 2, 3, 5, - 5, 0, 2, 2, 2, 2, 5, 7, 1, 2, - 2, 2, 2, 2, 4, 2, 2, 1, 1, 3, - 1, 3, 1, 1, 1, 5, 1, 1, 1, 2, - 1, 2, 1, 2, 1, 2, 4, 4, 5, 10, - 1, 3 -}; - -/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state - STATE-NUM when YYTABLE doesn't specify something else to do. Zero - means the default is an error. */ -static const unsigned short int yydefact[] = -{ - 3, 0, 2, 1, 0, 0, 0, 0, 189, 0, - 0, 0, 189, 54, 189, 22, 62, 10, 24, 11, - 27, 11, 9, 0, 0, 0, 0, 0, 0, 7, - 0, 0, 238, 0, 231, 5, 4, 0, 8, 0, - 0, 0, 215, 216, 257, 203, 194, 214, 0, 202, - 189, 204, 200, 205, 206, 208, 213, 206, 0, 206, - 0, 201, 210, 189, 189, 199, 256, 195, 260, 258, - 196, 262, 0, 264, 0, 222, 223, 190, 191, 0, - 0, 0, 233, 234, 0, 0, 55, 0, 63, 64, - 65, 66, 67, 0, 0, 70, 71, 72, 73, 74, - 75, 0, 78, 79, 0, 81, 0, 0, 85, 86, - 0, 0, 0, 0, 0, 92, 0, 94, 0, 96, - 0, 98, 99, 0, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 0, 111, 112, 113, 254, 114, 0, - 116, 252, 117, 118, 119, 0, 121, 122, 0, 0, - 0, 253, 0, 127, 128, 0, 0, 0, 57, 131, - 0, 0, 0, 0, 0, 217, 224, 235, 243, 23, - 25, 26, 6, 219, 240, 0, 239, 0, 0, 19, - 28, 29, 30, 259, 261, 207, 212, 211, 0, 209, - 197, 263, 265, 198, 192, 193, 0, 0, 141, 0, - 32, 179, 0, 0, 179, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 151, - 0, 0, 151, 0, 0, 0, 0, 0, 0, 62, - 56, 33, 0, 17, 18, 0, 0, 15, 13, 12, - 16, 37, 35, 241, 242, 36, 54, 0, 54, 0, - 0, 232, 19, 54, 0, 0, 31, 0, 143, 144, - 147, 178, 54, 0, 0, 0, 247, 248, 250, 267, - 54, 54, 0, 158, 153, 154, 155, 156, 0, 157, - 0, 0, 0, 0, 0, 177, 0, 175, 0, 0, - 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 149, 152, 0, 0, 0, 0, - 0, 0, 133, 132, 0, 270, 0, 0, 58, 62, - 0, 14, 218, 0, 220, 225, 0, 0, 0, 54, - 0, 0, 54, 244, 21, 0, 0, 266, 140, 148, - 142, 0, 184, 255, 0, 55, 180, 0, 246, 245, - 0, 0, 0, 268, 68, 0, 170, 169, 171, 168, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 69, 77, 76, 80, 0, 82, 83, 84, - 87, 88, 89, 90, 91, 93, 95, 0, 151, 100, - 110, 0, 120, 123, 124, 125, 126, 0, 129, 130, - 59, 0, 221, 227, 0, 226, 229, 0, 230, 19, - 236, 134, 20, 145, 146, 264, 183, 181, 249, 251, - 187, 0, 174, 0, 166, 167, 0, 160, 161, 163, - 162, 164, 165, 176, 61, 97, 150, 0, 271, 34, - 48, 228, 54, 135, 0, 182, 0, 188, 173, 172, - 0, 115, 151, 185, 237, 0, 136, 159, 0, 0, - 51, 38, 0, 50, 0, 49, 256, 0, 43, 39, - 41, 0, 0, 0, 0, 269, 137, 52, 0, 186, - 0, 0, 48, 0, 54, 53, 42, 48, 38, 45, - 54, 139, 38, 44, 0, 138, 0, 47, 46 -}; - -/* YYDEFGOTO[NTERM-NUM]. */ -static const short int yydefgoto[] = -{ - -1, 1, 2, 160, 253, 334, 18, 19, 20, 234, - 164, 21, 22, 467, 468, 469, 470, 453, 459, 335, - 86, 157, 292, 158, 314, 444, 462, 476, 24, 257, - 258, 259, 68, 303, 304, 285, 286, 287, 26, 262, - 346, 347, 336, 446, 79, 266, 69, 186, 70, 165, - 28, 237, 246, 324, 30, 31, 248, 329, 32, 178, - 33, 34, 238, 239, 168, 37, 240, 267, 268, 269, - 159, 71, 472, 40, 73, 316 -}; - -/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -#define YYPACT_NINF -376 -static const short int yypact[] = -{ - -376, 24, 773, -376, 86, 684, -43, 190, 193, 79, - 109, 210, 193, -28, 193, -376, 934, -376, -376, -376, - -376, -376, -376, 27, -20, -14, -7, -5, 20, -376, - 14, 40, -376, 53, 0, -376, -376, 59, -376, 77, - 89, 92, -376, -376, -376, -376, -376, -376, 684, -376, - 213, -376, -376, -376, 178, -376, -376, 178, 108, 178, - -6, -376, -376, 226, 228, -6, -376, -376, -376, -376, - -376, -376, 237, -376, 251, -376, -376, -376, -376, 115, - 684, 122, -376, -376, 123, 684, -376, -91, -376, -376, - -376, -376, -376, 128, 132, -376, -376, -376, -376, -376, - -376, 136, -376, -376, 138, -376, 143, 145, -376, -376, - 146, 147, 148, 151, 152, -376, 153, -376, 154, -376, - 155, -376, -376, 158, -376, -376, -376, -376, -376, -376, - -376, -376, -376, 159, -376, -376, -376, -376, -376, 160, - -376, -376, -376, -376, -376, 161, -376, -376, 162, 163, - 164, -376, 165, -376, -376, 167, 169, -79, -376, -376, - 615, 731, 314, 239, 170, -376, -376, -376, -376, -376, - -376, -376, -376, -376, -376, -16, -376, 241, 171, -376, - -376, -376, -376, -376, 173, -376, -376, -376, 684, -376, - -376, 173, -85, -376, -376, -376, 175, 176, 237, 237, - -376, -376, 48, 179, -376, 237, 382, 243, 310, 321, - 450, 382, 322, 324, 382, 326, 382, 382, 280, 382, - -51, 382, 382, 382, 684, 684, 217, 334, 684, 934, - 195, -376, 194, -376, -376, 16, 198, -376, -376, -376, - -376, -376, -376, -376, -376, -376, 116, 214, -63, 206, - 205, -376, -376, 605, 216, 382, -376, 215, 234, -376, - 218, -376, -32, -15, 48, 48, -376, -376, -376, 240, - -28, -30, 221, -376, -376, -376, -376, -376, 229, -376, - 382, 382, 382, 382, 502, 17, -93, -376, 225, 227, - 230, -376, -83, 233, 235, 238, 244, 245, 246, 247, - 248, 67, 374, -47, -376, 17, 249, 259, -46, 222, - 254, 255, -376, -376, 257, 252, 261, 262, -376, 934, - 399, -376, -376, -10, -376, -376, 277, 684, 266, 131, - 263, 345, 786, -376, -376, 684, 270, -376, -376, -376, - 237, 382, -376, -376, 684, 272, -376, 273, -376, -376, - 285, 48, 286, -376, -376, 684, -376, -376, -376, -376, - 542, 288, 382, 382, 382, 382, 382, 382, 382, 382, - 382, 382, -376, -376, -376, -376, 412, -376, -376, -376, - -376, -376, -376, -376, -376, -376, -376, 289, 382, -376, - -376, 382, -376, -376, -376, -376, -376, 416, -376, -376, - -376, 290, -376, -376, 48, -376, -376, 295, -376, -376, - -376, 333, -376, -376, -376, 303, -376, -376, -376, -376, - 237, 291, -376, 382, -376, -376, 292, 9, 72, -3, - -3, 276, 276, -376, -376, -376, -376, 302, -376, -376, - 300, -376, 795, -376, 48, -376, 305, -376, -376, -376, - 382, -376, 509, -376, -376, 313, -376, 17, 137, -78, - -376, 293, -12, -376, 382, 311, -41, 315, -376, 329, - -376, 684, 48, 382, 330, -376, -376, 17, 382, -376, - 420, 48, -80, 561, -104, 17, -376, 23, 293, -376, - -104, -376, 293, -376, 318, -376, 320, -376, -376 -}; - -/* YYPGOTO[NTERM-NUM]. */ -static const short int yypgoto[] = -{ - -376, -376, -376, 451, -236, 11, -376, -376, 140, -376, - -376, -376, -376, -300, -376, -376, -1, -360, -376, -9, - -2, -376, -376, -211, -376, -376, -376, -376, -376, -376, - -376, 133, 3, 258, -365, -187, -376, -173, -376, 281, - -375, -208, 168, -376, 49, -70, -376, 74, 65, 25, - -376, 475, -376, -376, -13, -376, -376, -376, -376, -376, - -8, -376, 482, 4, -376, -376, 485, 236, -253, -376, - 269, 5, -4, -376, 1, -376 -}; - -/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule which - number is the opposite. If zero, do what YYDEFACT says. - If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -191 -static const short int yytable[] = -{ - 23, 72, 196, 41, 85, 25, 36, 39, 362, 363, - 166, 349, 350, 17, 473, 167, 332, 263, 318, 326, - 362, 363, 47, 436, 3, 203, 474, 27, 362, 363, - 301, -190, 305, 7, 289, 305, 309, 294, 295, 371, - 328, 298, 342, 300, 183, 4, 137, 16, 307, 376, - 141, 194, 195, 229, 464, 372, 4, 54, 204, 7, - 11, 84, 352, 87, -190, 377, 11, 488, 55, 56, - 7, 452, 151, 230, 465, 57, 199, 247, 362, 363, - 263, 202, 338, 362, 363, 388, 388, 460, 16, 42, - 43, -40, 11, 356, 357, 358, 359, 360, 419, 163, - 59, 389, 392, 11, 74, 62, 162, -40, 400, 491, - 163, 80, 84, 87, 342, 495, 342, 81, 343, 16, - 353, 16, 489, 16, 264, 190, 169, 493, 260, 261, - 193, 187, 170, 189, 177, 272, 369, 370, 475, 171, - 273, 172, 274, 275, 276, 366, 367, 368, 369, 370, - 364, 440, 365, 366, 367, 368, 369, 370, 235, 235, - 174, 41, 41, 25, 25, 39, 39, 249, 414, 173, - 492, 233, 233, 442, 452, 424, 425, 426, 427, 428, - 429, 430, 431, 432, 254, 236, 236, 264, 494, 175, - 277, 455, 496, 75, 76, 265, 77, 78, 433, 176, - 364, 305, 365, 366, 367, 368, 369, 370, 179, 367, - 368, 369, 370, 82, 83, 386, 184, 78, 437, 482, - 310, 311, 166, 180, 317, 312, 313, 167, 487, 191, - 78, 192, 78, 362, 363, 181, 449, 323, 182, 327, - 194, 195, 243, 244, 250, 251, 273, 278, 274, 275, - 276, 288, 185, 344, 41, 188, 25, 279, 39, 197, - 345, 327, 344, 457, 198, 305, 322, 16, 200, 345, - 260, 358, 201, 280, 281, 205, 282, 477, 283, 206, - 361, 406, 16, 207, 284, 208, 483, 362, 363, 463, - 209, 485, 210, 211, 212, 213, 277, 44, 214, 215, - 216, 217, 218, 362, 363, 219, 220, 221, 222, 223, - 224, 225, 226, 45, 227, 46, 228, 242, 290, 245, - 252, 47, -190, 404, 256, 48, 270, 402, 255, 291, - 296, 411, 297, 41, 299, 25, 302, 39, 49, 315, - 404, 320, 50, 51, 321, 415, 319, 52, 325, 53, - 447, 421, 330, 278, 331, 364, 54, 365, 366, 367, - 368, 369, 370, 279, 337, 339, 340, 55, 56, 354, - 393, 341, 351, 373, 57, 374, 355, 387, 375, 280, - 281, 378, 282, 379, 283, 273, 380, 274, 275, 276, - 284, 391, 381, 382, 383, 384, 385, 390, 58, 59, - 60, 61, 394, 395, 62, 396, 397, 401, 63, 398, - 399, 403, 405, 408, 10, 64, 412, 65, 416, 417, - 434, 438, 466, 67, 44, 364, 450, 365, 366, 367, - 368, 369, 370, 418, 420, 277, 423, 435, 439, 448, - 45, 441, 46, 41, 16, 25, 443, 39, 47, 445, - 451, 452, 48, 273, 456, 274, 275, 276, 293, 471, - 461, 480, 478, 479, 484, 49, 497, 481, 498, 50, - 51, 409, 161, 413, 52, 344, 53, 29, 471, 486, - 308, 344, 345, 54, 35, 271, 471, 38, 345, 306, - 471, 0, 278, 0, 55, 56, 0, 407, 0, 348, - 0, 57, 279, 277, 0, 273, 44, 274, 275, 276, - 0, 0, 273, 0, 274, 275, 276, 0, 280, 281, - 0, 282, 45, 283, 46, 58, 59, 60, 61, 284, - 47, 62, 0, 0, 48, 63, 0, 0, 0, 0, - 0, 0, 64, 0, 65, 0, 0, 49, 0, 66, - 67, 50, 51, 362, 363, 277, 52, 0, 53, 0, - 278, 0, 277, 0, 0, 54, 0, 0, 0, 0, - 279, 16, 362, 363, 0, 0, 55, 56, 0, 0, - 0, 0, 0, 57, 0, 0, 280, 281, 0, 282, - 0, 283, 0, 0, 0, 0, 0, 284, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 58, 59, 60, - 61, 0, 278, 62, 0, 0, 0, 63, 0, 278, - 0, 0, 279, 0, 64, 231, 65, 0, 0, 279, - 0, 66, 67, 0, 0, 0, 0, 5, 280, 281, - 0, 282, 6, 283, 4, 280, 281, 5, 458, 284, - 283, 0, 6, 0, 8, 0, 284, 9, 7, 0, - 0, 0, 0, 0, 8, 0, 0, 9, 0, 0, - 0, 0, 0, 0, 10, 364, 0, 365, 366, 367, - 368, 369, 370, 0, 10, 232, 0, 0, 44, 0, - 422, 11, 0, 0, 364, 490, 365, 366, 367, 368, - 369, 370, 0, 0, 45, 0, 46, 0, 0, 0, - 0, 0, 47, 0, 0, 0, 48, 0, 0, 0, - 12, 0, 0, 0, 0, 0, 13, 14, 0, 49, - 12, 0, 0, 50, 51, 0, 13, 14, 52, 0, - 53, 0, 0, 0, 0, 0, 0, 54, 0, 0, - 0, 15, 0, 0, 0, 333, 16, 0, 55, 56, - 4, 15, 0, 5, 0, 57, 16, 0, 6, 0, - 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, - 8, 0, 0, 9, 0, 0, 0, 0, 0, 58, - 59, 60, 61, 0, 0, 62, 0, 0, 0, 63, - 10, 232, 4, 0, 0, 5, 64, 11, 65, 0, - 6, 0, 0, 66, 67, 0, 7, 0, 5, 0, - 0, 0, 8, 6, 0, 9, 0, 5, 0, 0, - 0, 0, 6, 0, 0, 8, 0, 0, 9, 0, - 0, 0, 10, 0, 8, 0, 12, 9, 0, 11, - 0, 0, 13, 14, 0, 10, 0, 0, 0, 0, - 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, - 0, 241, 16, 0, 0, 0, 0, 0, 12, 0, - 0, 0, 0, 0, 13, 14, 0, 0, 0, 0, - 0, 12, 0, 0, 0, 0, 0, 13, 14, 0, - 12, 0, 0, 0, 0, 0, 13, 14, 0, 15, - 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, - 0, 0, 15, 0, 0, 0, 410, 16, 0, 0, - 0, 15, 0, 0, 0, 454, 16, 88, 0, 89, - 90, 0, 91, 92, 0, 0, 0, 0, 93, 0, - 94, 0, 0, 0, 0, 0, 0, 95, 96, 97, - 98, 0, 99, 100, 101, 102, 103, 0, 104, 0, - 105, 106, 107, 0, 0, 108, 0, 0, 0, 109, - 0, 110, 111, 112, 113, 114, 115, 0, 116, 117, - 118, 119, 120, 0, 0, 121, 0, 122, 0, 0, - 0, 0, 123, 0, 124, 0, 0, 0, 125, 126, - 127, 128, 129, 130, 131, 132, 133, 0, 134, 135, - 136, 137, 138, 139, 140, 141, 142, 143, 144, 0, - 0, 0, 0, 145, 0, 0, 146, 0, 147, 0, - 0, 148, 149, 150, 0, 0, 0, 151, 0, 152, - 153, 154, 155, 0, 0, 156 -}; - -static const short int yycheck[] = -{ - 2, 5, 72, 2, 13, 2, 2, 2, 11, 12, - 23, 264, 265, 2, 26, 23, 252, 32, 229, 82, - 11, 12, 28, 388, 0, 116, 38, 2, 11, 12, - 217, 116, 219, 43, 207, 222, 223, 210, 211, 132, - 248, 214, 146, 216, 48, 29, 97, 151, 221, 132, - 101, 3, 4, 132, 132, 148, 29, 63, 149, 43, - 76, 12, 270, 14, 149, 148, 76, 147, 74, 75, - 43, 151, 123, 152, 152, 81, 80, 93, 11, 12, - 32, 85, 255, 11, 12, 132, 132, 452, 151, 3, - 4, 132, 76, 280, 281, 282, 283, 284, 351, 83, - 106, 148, 148, 76, 147, 111, 79, 148, 319, 484, - 83, 32, 63, 64, 146, 490, 146, 8, 150, 151, - 150, 151, 482, 151, 139, 60, 146, 487, 198, 199, - 65, 57, 146, 59, 134, 205, 139, 140, 150, 146, - 3, 146, 5, 6, 7, 136, 137, 138, 139, 140, - 133, 404, 135, 136, 137, 138, 139, 140, 160, 161, - 146, 160, 161, 160, 161, 160, 161, 175, 341, 149, - 147, 160, 161, 409, 151, 362, 363, 364, 365, 366, - 367, 368, 369, 370, 188, 160, 161, 139, 488, 149, - 53, 444, 492, 3, 4, 147, 3, 4, 371, 146, - 133, 388, 135, 136, 137, 138, 139, 140, 149, 137, - 138, 139, 140, 3, 4, 148, 3, 4, 391, 472, - 224, 225, 235, 146, 228, 8, 9, 235, 481, 3, - 4, 3, 4, 11, 12, 146, 423, 246, 146, 248, - 3, 4, 3, 4, 3, 4, 3, 110, 5, 6, - 7, 8, 74, 262, 253, 147, 253, 120, 253, 8, - 262, 270, 271, 450, 149, 452, 150, 151, 146, 271, - 340, 458, 149, 136, 137, 147, 139, 464, 141, 147, - 284, 150, 151, 147, 147, 147, 473, 11, 12, 152, - 147, 478, 147, 147, 147, 147, 53, 4, 147, 147, - 147, 147, 147, 11, 12, 147, 147, 147, 147, 147, - 147, 147, 147, 20, 147, 22, 147, 3, 8, 149, - 149, 28, 149, 327, 148, 32, 147, 323, 153, 8, - 8, 335, 8, 332, 8, 332, 56, 332, 45, 5, - 344, 147, 49, 50, 146, 344, 151, 54, 134, 56, - 420, 355, 146, 110, 149, 133, 63, 135, 136, 137, - 138, 139, 140, 120, 148, 150, 132, 74, 75, 148, - 148, 153, 132, 148, 81, 148, 147, 3, 148, 136, - 137, 148, 139, 148, 141, 3, 148, 5, 6, 7, - 147, 132, 148, 148, 148, 148, 148, 148, 105, 106, - 107, 108, 148, 148, 111, 148, 154, 8, 115, 148, - 148, 134, 146, 150, 69, 122, 146, 124, 146, 146, - 8, 5, 129, 130, 4, 133, 134, 135, 136, 137, - 138, 139, 140, 148, 148, 53, 148, 148, 148, 148, - 20, 146, 22, 442, 151, 442, 113, 442, 28, 146, - 148, 151, 32, 3, 149, 5, 6, 7, 8, 461, - 147, 132, 151, 148, 134, 45, 148, 471, 148, 49, - 50, 331, 21, 340, 54, 484, 56, 2, 480, 480, - 222, 490, 484, 63, 2, 204, 488, 2, 490, 220, - 492, -1, 110, -1, 74, 75, -1, 329, -1, 263, - -1, 81, 120, 53, -1, 3, 4, 5, 6, 7, - -1, -1, 3, -1, 5, 6, 7, -1, 136, 137, - -1, 139, 20, 141, 22, 105, 106, 107, 108, 147, - 28, 111, -1, -1, 32, 115, -1, -1, -1, -1, - -1, -1, 122, -1, 124, -1, -1, 45, -1, 129, - 130, 49, 50, 11, 12, 53, 54, -1, 56, -1, - 110, -1, 53, -1, -1, 63, -1, -1, -1, -1, - 120, 151, 11, 12, -1, -1, 74, 75, -1, -1, - -1, -1, -1, 81, -1, -1, 136, 137, -1, 139, - -1, 141, -1, -1, -1, -1, -1, 147, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 105, 106, 107, - 108, -1, 110, 111, -1, -1, -1, 115, -1, 110, - -1, -1, 120, -1, 122, 10, 124, -1, -1, 120, - -1, 129, 130, -1, -1, -1, -1, 32, 136, 137, - -1, 139, 37, 141, 29, 136, 137, 32, 139, 147, - 141, -1, 37, -1, 49, -1, 147, 52, 43, -1, - -1, -1, -1, -1, 49, -1, -1, 52, -1, -1, - -1, -1, -1, -1, 69, 133, -1, 135, 136, 137, - 138, 139, 140, -1, 69, 70, -1, -1, 4, -1, - 148, 76, -1, -1, 133, 134, 135, 136, 137, 138, - 139, 140, -1, -1, 20, -1, 22, -1, -1, -1, - -1, -1, 28, -1, -1, -1, 32, -1, -1, -1, - 115, -1, -1, -1, -1, -1, 121, 122, -1, 45, - 115, -1, -1, 49, 50, -1, 121, 122, 54, -1, - 56, -1, -1, -1, -1, -1, -1, 63, -1, -1, - -1, 146, -1, -1, -1, 150, 151, -1, 74, 75, - 29, 146, -1, 32, -1, 81, 151, -1, 37, -1, - -1, -1, -1, -1, 43, -1, -1, -1, -1, -1, - 49, -1, -1, 52, -1, -1, -1, -1, -1, 105, - 106, 107, 108, -1, -1, 111, -1, -1, -1, 115, - 69, 70, 29, -1, -1, 32, 122, 76, 124, -1, - 37, -1, -1, 129, 130, -1, 43, -1, 32, -1, - -1, -1, 49, 37, -1, 52, -1, 32, -1, -1, - -1, -1, 37, -1, -1, 49, -1, -1, 52, -1, - -1, -1, 69, -1, 49, -1, 115, 52, -1, 76, - -1, -1, 121, 122, -1, 69, -1, -1, -1, -1, - -1, -1, -1, -1, 69, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 146, -1, -1, - -1, 150, 151, -1, -1, -1, -1, -1, 115, -1, - -1, -1, -1, -1, 121, 122, -1, -1, -1, -1, - -1, 115, -1, -1, -1, -1, -1, 121, 122, -1, - 115, -1, -1, -1, -1, -1, 121, 122, -1, 146, - -1, -1, -1, -1, 151, -1, -1, -1, -1, -1, - -1, -1, 146, -1, -1, -1, 150, 151, -1, -1, - -1, 146, -1, -1, -1, 150, 151, 13, -1, 15, - 16, -1, 18, 19, -1, -1, -1, -1, 24, -1, - 26, -1, -1, -1, -1, -1, -1, 33, 34, 35, - 36, -1, 38, 39, 40, 41, 42, -1, 44, -1, - 46, 47, 48, -1, -1, 51, -1, -1, -1, 55, - -1, 57, 58, 59, 60, 61, 62, -1, 64, 65, - 66, 67, 68, -1, -1, 71, -1, 73, -1, -1, - -1, -1, 78, -1, 80, -1, -1, -1, 84, 85, - 86, 87, 88, 89, 90, 91, 92, -1, 94, 95, - 96, 97, 98, 99, 100, 101, 102, 103, 104, -1, - -1, -1, -1, 109, -1, -1, 112, -1, 114, -1, - -1, 117, 118, 119, -1, -1, -1, 123, -1, 125, - 126, 127, 128, -1, -1, 131 -}; - -/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ -static const unsigned char yystos[] = -{ - 0, 156, 157, 0, 29, 32, 37, 43, 49, 52, - 69, 76, 115, 121, 122, 146, 151, 160, 161, 162, - 163, 166, 167, 175, 183, 187, 193, 204, 205, 206, - 209, 210, 213, 215, 216, 217, 218, 220, 221, 226, - 228, 229, 3, 4, 4, 20, 22, 28, 32, 45, - 49, 50, 54, 56, 63, 74, 75, 81, 105, 106, - 107, 108, 111, 115, 122, 124, 129, 130, 187, 201, - 203, 226, 227, 229, 147, 3, 4, 3, 4, 199, - 32, 8, 3, 4, 199, 174, 175, 199, 13, 15, - 16, 18, 19, 24, 26, 33, 34, 35, 36, 38, - 39, 40, 41, 42, 44, 46, 47, 48, 51, 55, - 57, 58, 59, 60, 61, 62, 64, 65, 66, 67, - 68, 71, 73, 78, 80, 84, 85, 86, 87, 88, - 89, 90, 91, 92, 94, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 109, 112, 114, 117, 118, - 119, 123, 125, 126, 127, 128, 131, 176, 178, 225, - 158, 158, 79, 83, 165, 204, 209, 215, 219, 146, - 146, 146, 146, 149, 146, 149, 146, 134, 214, 149, - 146, 146, 146, 227, 3, 74, 202, 202, 147, 202, - 203, 3, 3, 203, 3, 4, 200, 8, 149, 227, - 146, 149, 227, 116, 149, 147, 147, 147, 147, 147, - 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, - 147, 147, 147, 147, 147, 147, 147, 147, 147, 132, - 152, 10, 70, 160, 164, 175, 204, 206, 217, 218, - 221, 150, 3, 3, 4, 149, 207, 93, 211, 215, - 3, 4, 149, 159, 227, 153, 148, 184, 185, 186, - 200, 200, 194, 32, 139, 147, 200, 222, 223, 224, - 147, 194, 200, 3, 5, 6, 7, 53, 110, 120, - 136, 137, 139, 141, 147, 190, 191, 192, 8, 192, - 8, 8, 177, 8, 192, 192, 8, 8, 192, 8, - 192, 190, 56, 188, 189, 190, 225, 192, 188, 190, - 227, 227, 8, 9, 179, 5, 230, 227, 178, 151, - 147, 146, 150, 174, 208, 134, 82, 174, 196, 212, - 146, 149, 159, 150, 160, 174, 197, 148, 192, 150, - 132, 153, 146, 150, 174, 175, 195, 196, 222, 223, - 223, 132, 196, 150, 148, 147, 190, 190, 190, 190, - 190, 227, 11, 12, 133, 135, 136, 137, 138, 139, - 140, 132, 148, 148, 148, 148, 132, 148, 148, 148, - 148, 148, 148, 148, 148, 148, 148, 3, 132, 148, - 148, 132, 148, 148, 148, 148, 148, 154, 148, 148, - 178, 8, 218, 134, 227, 146, 150, 197, 150, 163, - 150, 227, 146, 186, 192, 229, 146, 146, 148, 223, - 148, 227, 148, 148, 190, 190, 190, 190, 190, 190, - 190, 190, 190, 192, 8, 148, 189, 192, 5, 148, - 223, 146, 159, 113, 180, 146, 198, 200, 148, 190, - 134, 148, 151, 172, 150, 223, 149, 190, 139, 173, - 189, 147, 181, 152, 132, 152, 129, 168, 169, 170, - 171, 175, 227, 26, 38, 150, 182, 190, 151, 148, - 132, 227, 223, 190, 134, 190, 171, 223, 147, 172, - 134, 195, 147, 172, 168, 195, 168, 148, 148 -}; - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab - - -/* Like YYERROR except do call yyerror. This remains here temporarily - to ease the transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. */ - -#define YYFAIL goto yyerrlab - -#define YYRECOVERING() (!!yyerrstatus) - -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - yytoken = YYTRANSLATE (yychar); \ - YYPOPSTACK; \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (0) - - -#define YYTERROR 1 -#define YYERRCODE 256 - - -/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. - If N is 0, then set CURRENT to the empty location which ends - the previous symbol: RHS[0] (always defined). */ - -#define YYRHSLOC(Rhs, K) ((Rhs)[K]) -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - do \ - if (N) \ - { \ - (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ - (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ - } \ - else \ - { \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC (Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC (Rhs, 0).last_column; \ - } \ - while (0) -#endif - - -/* YY_LOCATION_PRINT -- Print the location on the stream. - This macro was not mandated originally: define only if we know - we won't break user code: when these are the locations we know. */ - -#ifndef YY_LOCATION_PRINT -# if YYLTYPE_IS_TRIVIAL -# define YY_LOCATION_PRINT(File, Loc) \ - fprintf (File, "%d.%d-%d.%d", \ - (Loc).first_line, (Loc).first_column, \ - (Loc).last_line, (Loc).last_column) -# else -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -# endif -#endif - - -/* YYLEX -- calling `yylex' with the right arguments. */ - -#ifdef YYLEX_PARAM -# define YYLEX yylex (YYLEX_PARAM) -#else -# define YYLEX yylex () -#endif - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (0) - -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yysymprint (stderr, \ - Type, Value); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (0) - -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (included). | -`------------------------------------------------------------------*/ - -#if defined (__STDC__) || defined (__cplusplus) -static void -yy_stack_print (short int *bottom, short int *top) -#else -static void -yy_stack_print (bottom, top) - short int *bottom; - short int *top; -#endif -{ - YYFPRINTF (stderr, "Stack now"); - for (/* Nothing. */; bottom <= top; ++bottom) - YYFPRINTF (stderr, " %d", *bottom); - YYFPRINTF (stderr, "\n"); -} - -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (0) - - -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ - -#if defined (__STDC__) || defined (__cplusplus) -static void -yy_reduce_print (int yyrule) -#else -static void -yy_reduce_print (yyrule) - int yyrule; -#endif -{ - int yyi; - unsigned long int yylno = yyrline[yyrule]; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu), ", - yyrule - 1, yylno); - /* Print the symbols being reduced, and their result. */ - for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) - YYFPRINTF (stderr, "%s ", yytname[yyrhs[yyi]]); - YYFPRINTF (stderr, "-> %s\n", yytname[yyr1[yyrule]]); -} - -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (Rule); \ -} while (0) - -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) -#endif /* !YYDEBUG */ - - -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 -#endif - - - -#if YYERROR_VERBOSE - -# ifndef yystrlen -# if defined (__GLIBC__) && defined (_STRING_H) -# define yystrlen strlen -# else -/* Return the length of YYSTR. */ -static YYSIZE_T -# if defined (__STDC__) || defined (__cplusplus) -yystrlen (const char *yystr) -# else -yystrlen (yystr) - const char *yystr; -# endif -{ - const char *yys = yystr; - - while (*yys++ != '\0') - continue; - - return yys - yystr - 1; -} -# endif -# endif - -# ifndef yystpcpy -# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) -# define yystpcpy stpcpy -# else -/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -static char * -# if defined (__STDC__) || defined (__cplusplus) -yystpcpy (char *yydest, const char *yysrc) -# else -yystpcpy (yydest, yysrc) - char *yydest; - const char *yysrc; -# endif -{ - char *yyd = yydest; - const char *yys = yysrc; - - while ((*yyd++ = *yys++) != '\0') - continue; - - return yyd - 1; -} -# endif -# endif - -# ifndef yytnamerr -/* Copy to YYRES the contents of YYSTR after stripping away unnecessary - quotes and backslashes, so that it's suitable for yyerror. The - heuristic is that double-quoting is unnecessary unless the string - contains an apostrophe, a comma, or backslash (other than - backslash-backslash). YYSTR is taken from yytname. If YYRES is - null, do not copy; instead, return the length of what the result - would have been. */ -static YYSIZE_T -yytnamerr (char *yyres, const char *yystr) -{ - if (*yystr == '"') - { - size_t yyn = 0; - char const *yyp = yystr; - - for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; - - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - /* Fall through. */ - default: - if (yyres) - yyres[yyn] = *yyp; - yyn++; - break; - - case '"': - if (yyres) - yyres[yyn] = '\0'; - return yyn; - } - do_not_strip_quotes: ; - } - - if (! yyres) - return yystrlen (yystr); - - return yystpcpy (yyres, yystr) - yyres; -} -# endif - -#endif /* YYERROR_VERBOSE */ - - - -#if YYDEBUG -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -#if defined (__STDC__) || defined (__cplusplus) -static void -yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) -#else -static void -yysymprint (yyoutput, yytype, yyvaluep) - FILE *yyoutput; - int yytype; - YYSTYPE *yyvaluep; -#endif -{ - /* Pacify ``unused variable'' warnings. */ - (void) yyvaluep; - - if (yytype < YYNTOKENS) - YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); - else - YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); - - -# ifdef YYPRINT - if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# endif - switch (yytype) - { - default: - break; - } - YYFPRINTF (yyoutput, ")"); -} - -#endif /* ! YYDEBUG */ -/*-----------------------------------------------. -| Release the memory associated to this symbol. | -`-----------------------------------------------*/ - -#if defined (__STDC__) || defined (__cplusplus) -static void -yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) -#else -static void -yydestruct (yymsg, yytype, yyvaluep) - const char *yymsg; - int yytype; - YYSTYPE *yyvaluep; -#endif -{ - /* Pacify ``unused variable'' warnings. */ - (void) yyvaluep; - - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - - switch (yytype) - { - - default: - break; - } -} - - -/* Prevent warnings from -Wmissing-prototypes. */ - -#ifdef YYPARSE_PARAM -# if defined (__STDC__) || defined (__cplusplus) -int yyparse (void *YYPARSE_PARAM); -# else -int yyparse (); -# endif -#else /* ! YYPARSE_PARAM */ -#if defined (__STDC__) || defined (__cplusplus) -int yyparse (void); -#else -int yyparse (); -#endif -#endif /* ! YYPARSE_PARAM */ - - - -/* The look-ahead symbol. */ -int yychar; - -/* The semantic value of the look-ahead symbol. */ -YYSTYPE yylval; - -/* Number of syntax errors so far. */ -int yynerrs; - - - -/*----------. -| yyparse. | -`----------*/ - -#ifdef YYPARSE_PARAM -# if defined (__STDC__) || defined (__cplusplus) -int yyparse (void *YYPARSE_PARAM) -# else -int yyparse (YYPARSE_PARAM) - void *YYPARSE_PARAM; -# endif -#else /* ! YYPARSE_PARAM */ -#if defined (__STDC__) || defined (__cplusplus) -int -yyparse (void) -#else -int -yyparse () - ; -#endif -#endif -{ - - int yystate; - int yyn; - int yyresult; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - /* Look-ahead token as an internal (translated) token number. */ - int yytoken = 0; - - /* Three stacks and their tools: - `yyss': related to states, - `yyvs': related to semantic values, - `yyls': related to locations. - - Refer to the stacks thru separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* The state stack. */ - short int yyssa[YYINITDEPTH]; - short int *yyss = yyssa; - short int *yyssp; - - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs = yyvsa; - YYSTYPE *yyvsp; - - - -#define YYPOPSTACK (yyvsp--, yyssp--) - - YYSIZE_T yystacksize = YYINITDEPTH; - - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; - - - /* When reducing, the number of symbols on the RHS of the reduced - rule. */ - int yylen; - - YYDPRINTF ((stderr, "Starting parse\n")); - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ - - yyssp = yyss; - yyvsp = yyvs; - - goto yysetstate; - -/*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | -`------------------------------------------------------------*/ - yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. so pushing a state here evens the stacks. - */ - yyssp++; - - yysetstate: - *yyssp = yystate; - - if (yyss + yystacksize - 1 <= yyssp) - { - /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; - -#ifdef yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - short int *yyss1 = yyss; - - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - - &yystacksize); - - yyss = yyss1; - yyvs = yyvs1; - } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyexhaustedlab; -# else - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; - - { - short int *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss); - YYSTACK_RELOCATE (yyvs); - -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif -#endif /* no yyoverflow */ - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; - - - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); - - if (yyss + yystacksize - 1 <= yyssp) - YYABORT; - } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - - goto yybackup; - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: - -/* Do appropriate processing given the current state. */ -/* Read a look-ahead token if we need one and don't already have one. */ -/* yyresume: */ - - /* First try to decide what to do without reference to look-ahead token. */ - - yyn = yypact[yystate]; - if (yyn == YYPACT_NINF) - goto yydefault; - - /* Not known => get a look-ahead token if don't already have one. */ - - /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token: ")); - yychar = YYLEX; - } - - if (yychar <= YYEOF) - { - yychar = yytoken = YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else - { - yytoken = YYTRANSLATE (yychar); - YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); - } - - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) - goto yydefault; - yyn = yytable[yyn]; - if (yyn <= 0) - { - if (yyn == 0 || yyn == YYTABLE_NINF) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - - if (yyn == YYFINAL) - YYACCEPT; - - /* Shift the look-ahead token. */ - YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - - /* Discard the token being shifted unless it is eof. */ - if (yychar != YYEOF) - yychar = YYEMPTY; - - *++yyvsp = yylval; - - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; - - yystate = yyn; - goto yynewstate; - - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; - - -/*-----------------------------. -| yyreduce -- Do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: - `$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - - - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 2: -#line 285 "parser.y" - { fix_incomplete(); - check_all_user_types((yyvsp[0].ifref_list)); - write_proxies((yyvsp[0].ifref_list)); - write_client((yyvsp[0].ifref_list)); - write_server((yyvsp[0].ifref_list)); - write_dlldata((yyvsp[0].ifref_list)); - ;} - break; - - case 3: -#line 294 "parser.y" - { (yyval.ifref_list) = NULL; ;} - break; - - case 4: -#line 295 "parser.y" - { (yyval.ifref_list) = (yyvsp[-1].ifref_list); ;} - break; - - case 5: -#line 296 "parser.y" - { (yyval.ifref_list) = append_ifref( (yyvsp[-1].ifref_list), make_ifref((yyvsp[0].type)) ); ;} - break; - - case 6: -#line 297 "parser.y" - { (yyval.ifref_list) = (yyvsp[-2].ifref_list); - reg_type((yyvsp[-1].type), (yyvsp[-1].type)->name, 0); - if (!parse_only && do_header) write_coclass_forward((yyvsp[-1].type)); - ;} - break; - - case 7: -#line 301 "parser.y" - { (yyval.ifref_list) = (yyvsp[-1].ifref_list); - add_typelib_entry((yyvsp[0].type)); - reg_type((yyvsp[0].type), (yyvsp[0].type)->name, 0); - if (!parse_only && do_header) write_coclass_forward((yyvsp[0].type)); - ;} - break; - - case 8: -#line 306 "parser.y" - { (yyval.ifref_list) = (yyvsp[-1].ifref_list); add_typelib_entry((yyvsp[0].type)); ;} - break; - - case 9: -#line 307 "parser.y" - { (yyval.ifref_list) = (yyvsp[-1].ifref_list); ;} - break; - - case 10: -#line 308 "parser.y" - { (yyval.ifref_list) = (yyvsp[-1].ifref_list); ;} - break; - - case 11: -#line 311 "parser.y" - {;} - break; - - case 12: -#line 312 "parser.y" - { if (!parse_only) add_typelib_entry((yyvsp[0].type)); ;} - break; - - case 13: -#line 313 "parser.y" - { if (!parse_only) add_typelib_entry((yyvsp[0].type)); ;} - break; - - case 14: -#line 314 "parser.y" - { reg_type((yyvsp[-1].type), (yyvsp[-1].type)->name, 0); if (!parse_only && do_header) write_coclass_forward((yyvsp[-1].type)); ;} - break; - - case 15: -#line 315 "parser.y" - { if (!parse_only) add_typelib_entry((yyvsp[0].type)); - reg_type((yyvsp[0].type), (yyvsp[0].type)->name, 0); - if (!parse_only && do_header) write_coclass_forward((yyvsp[0].type)); - ;} - break; - - case 16: -#line 319 "parser.y" - { if (!parse_only) add_typelib_entry((yyvsp[0].type)); ;} - break; - - case 17: -#line 320 "parser.y" - {;} - break; - - case 18: -#line 321 "parser.y" - {;} - break; - - case 19: -#line 324 "parser.y" - { (yyval.func_list) = NULL; ;} - break; - - case 20: -#line 325 "parser.y" - { (yyval.func_list) = append_func( (yyvsp[-2].func_list), (yyvsp[-1].func) ); ;} - break; - - case 21: -#line 326 "parser.y" - { (yyval.func_list) = (yyvsp[-1].func_list); ;} - break; - - case 22: -#line 329 "parser.y" - {;} - break; - - case 23: -#line 330 "parser.y" - { if (!parse_only && do_header) { write_constdef((yyvsp[-1].var)); } ;} - break; - - case 24: -#line 331 "parser.y" - {;} - break; - - case 25: -#line 332 "parser.y" - { if (!parse_only && do_header) { - write_type_def_or_decl(header, (yyvsp[-1].type), FALSE, NULL); - fprintf(header, ";\n\n"); - } - ;} - break; - - case 26: -#line 337 "parser.y" - { if (!parse_only && do_header) { write_externdef((yyvsp[-1].var)); } ;} - break; - - case 27: -#line 338 "parser.y" - {;} - break; - - case 28: -#line 339 "parser.y" - { if (!parse_only && do_header) { - write_type_def_or_decl(header, (yyvsp[-1].type), FALSE, NULL); - fprintf(header, ";\n\n"); - } - ;} - break; - - case 29: -#line 344 "parser.y" - {;} - break; - - case 30: -#line 345 "parser.y" - { if (!parse_only && do_header) { - write_type_def_or_decl(header, (yyvsp[-1].type), FALSE, NULL); - fprintf(header, ";\n\n"); - } - ;} - break; - - case 31: -#line 352 "parser.y" - { if (!parse_only && do_header) fprintf(header, "%s\n", (yyvsp[-1].str)); ;} - break; - - case 32: -#line 354 "parser.y" - { assert(yychar == YYEMPTY); - if (!do_import((yyvsp[-1].str))) yychar = aEOF; ;} - break; - - case 33: -#line 357 "parser.y" - {;} - break; - - case 34: -#line 360 "parser.y" - { if(!parse_only) add_importlib((yyvsp[-1].str)); ;} - break; - - case 35: -#line 363 "parser.y" - { (yyval.str) = (yyvsp[0].str); ;} - break; - - case 36: -#line 365 "parser.y" - { start_typelib((yyvsp[-1].str), (yyvsp[-2].attr_list)); - if (!parse_only && do_header) write_library((yyvsp[-1].str), (yyvsp[-2].attr_list)); - if (!parse_only && do_idfile) write_libid((yyvsp[-1].str), (yyvsp[-2].attr_list)); - ;} - break; - - case 37: -#line 370 "parser.y" - { end_typelib(); ;} - break; - - case 38: -#line 373 "parser.y" - { (yyval.var_list) = NULL; ;} - break; - - case 40: -#line 377 "parser.y" - { (yyval.var_list) = NULL; ;} - break; - - case 41: -#line 380 "parser.y" - { check_arg((yyvsp[0].var)); (yyval.var_list) = append_var( NULL, (yyvsp[0].var) ); ;} - break; - - case 42: -#line 381 "parser.y" - { check_arg((yyvsp[0].var)); (yyval.var_list) = append_var( (yyvsp[-2].var_list), (yyvsp[0].var)); ;} - break; - - case 44: -#line 386 "parser.y" - { (yyval.var) = (yyvsp[-1].pident)->var; - (yyval.var)->attrs = (yyvsp[-3].attr_list); - set_type((yyval.var), (yyvsp[-2].type), (yyvsp[-1].pident)->ptr_level, (yyvsp[0].array_dims), TRUE); - free((yyvsp[-1].pident)); - ;} - break; - - case 45: -#line 391 "parser.y" - { (yyval.var) = (yyvsp[-1].pident)->var; - set_type((yyval.var), (yyvsp[-2].type), (yyvsp[-1].pident)->ptr_level, (yyvsp[0].array_dims), TRUE); - free((yyvsp[-1].pident)); - ;} - break; - - case 46: -#line 395 "parser.y" - { (yyval.var) = (yyvsp[-3].pident)->var; - (yyval.var)->attrs = (yyvsp[-5].attr_list); - set_type((yyval.var), (yyvsp[-4].type), (yyvsp[-3].pident)->ptr_level - 1, NULL, TRUE); - free((yyvsp[-3].pident)); - (yyval.var)->args = (yyvsp[-1].var_list); - ;} - break; - - case 47: -#line 401 "parser.y" - { (yyval.var) = (yyvsp[-3].pident)->var; - set_type((yyval.var), (yyvsp[-4].type), (yyvsp[-3].pident)->ptr_level - 1, NULL, TRUE); - free((yyvsp[-3].pident)); - (yyval.var)->args = (yyvsp[-1].var_list); - ;} - break; - - case 48: -#line 408 "parser.y" - { (yyval.array_dims) = NULL; ;} - break; - - case 49: -#line 409 "parser.y" - { (yyval.array_dims) = (yyvsp[-1].array_dims); ;} - break; - - case 50: -#line 410 "parser.y" - { (yyval.array_dims) = append_array( NULL, make_expr(EXPR_VOID) ); ;} - break; - - case 51: -#line 413 "parser.y" - { (yyval.array_dims) = append_array( NULL, (yyvsp[0].expr) ); ;} - break; - - case 52: -#line 414 "parser.y" - { (yyval.array_dims) = append_array( (yyvsp[-2].array_dims), (yyvsp[0].expr) ); ;} - break; - - case 53: -#line 415 "parser.y" - { (yyval.array_dims) = append_array( (yyvsp[-3].array_dims), (yyvsp[0].expr) ); ;} - break; - - case 54: -#line 418 "parser.y" - { (yyval.attr_list) = NULL; ;} - break; - - case 56: -#line 423 "parser.y" - { (yyval.attr_list) = (yyvsp[-1].attr_list); - if (!(yyval.attr_list)) - error_loc("empty attribute lists unsupported\n"); - ;} - break; - - case 57: -#line 429 "parser.y" - { (yyval.attr_list) = append_attr( NULL, (yyvsp[0].attr) ); ;} - break; - - case 58: -#line 430 "parser.y" - { (yyval.attr_list) = append_attr( (yyvsp[-2].attr_list), (yyvsp[0].attr) ); ;} - break; - - case 59: -#line 431 "parser.y" - { (yyval.attr_list) = append_attr( (yyvsp[-3].attr_list), (yyvsp[0].attr) ); ;} - break; - - case 60: -#line 434 "parser.y" - { (yyval.str_list) = append_str( NULL, (yyvsp[0].str) ); ;} - break; - - case 61: -#line 435 "parser.y" - { (yyval.str_list) = append_str( (yyvsp[-2].str_list), (yyvsp[0].str) ); ;} - break; - - case 62: -#line 438 "parser.y" - { (yyval.attr) = NULL; ;} - break; - - case 63: -#line 439 "parser.y" - { (yyval.attr) = make_attr(ATTR_AGGREGATABLE); ;} - break; - - case 64: -#line 440 "parser.y" - { (yyval.attr) = make_attr(ATTR_APPOBJECT); ;} - break; - - case 65: -#line 441 "parser.y" - { (yyval.attr) = make_attr(ATTR_ASYNC); ;} - break; - - case 66: -#line 442 "parser.y" - { (yyval.attr) = make_attr(ATTR_AUTO_HANDLE); ;} - break; - - case 67: -#line 443 "parser.y" - { (yyval.attr) = make_attr(ATTR_BINDABLE); ;} - break; - - case 68: -#line 444 "parser.y" - { (yyval.attr) = make_attrp(ATTR_CALLAS, (yyvsp[-1].var)); ;} - break; - - case 69: -#line 445 "parser.y" - { (yyval.attr) = make_attrp(ATTR_CASE, (yyvsp[-1].expr_list)); ;} - break; - - case 70: -#line 446 "parser.y" - { (yyval.attr) = make_attrv(ATTR_CONTEXTHANDLE, 0); ;} - break; - - case 71: -#line 447 "parser.y" - { (yyval.attr) = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_DONT_SERIALIZE */ ;} - break; - - case 72: -#line 448 "parser.y" - { (yyval.attr) = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_SERIALIZE */ ;} - break; - - case 73: -#line 449 "parser.y" - { (yyval.attr) = make_attr(ATTR_CONTROL); ;} - break; - - case 74: -#line 450 "parser.y" - { (yyval.attr) = make_attr(ATTR_DEFAULT); ;} - break; - - case 75: -#line 451 "parser.y" - { (yyval.attr) = make_attr(ATTR_DEFAULTCOLLELEM); ;} - break; - - case 76: -#line 452 "parser.y" - { (yyval.attr) = make_attrp(ATTR_DEFAULTVALUE_EXPR, (yyvsp[-1].expr)); ;} - break; - - case 77: -#line 453 "parser.y" - { (yyval.attr) = make_attrp(ATTR_DEFAULTVALUE_STRING, (yyvsp[-1].str)); ;} - break; - - case 78: -#line 454 "parser.y" - { (yyval.attr) = make_attr(ATTR_DEFAULTVTABLE); ;} - break; - - case 79: -#line 455 "parser.y" - { (yyval.attr) = make_attr(ATTR_DISPLAYBIND); ;} - break; - - case 80: -#line 456 "parser.y" - { (yyval.attr) = make_attrp(ATTR_DLLNAME, (yyvsp[-1].str)); ;} - break; - - case 81: -#line 457 "parser.y" - { (yyval.attr) = make_attr(ATTR_DUAL); ;} - break; - - case 82: -#line 458 "parser.y" - { (yyval.attr) = make_attrp(ATTR_ENDPOINT, (yyvsp[-1].str_list)); ;} - break; - - case 83: -#line 459 "parser.y" - { (yyval.attr) = make_attrp(ATTR_ENTRY_STRING, (yyvsp[-1].str)); ;} - break; - - case 84: -#line 460 "parser.y" - { (yyval.attr) = make_attrp(ATTR_ENTRY_ORDINAL, (yyvsp[-1].expr)); ;} - break; - - case 85: -#line 461 "parser.y" - { (yyval.attr) = make_attr(ATTR_EXPLICIT_HANDLE); ;} - break; - - case 86: -#line 462 "parser.y" - { (yyval.attr) = make_attr(ATTR_HANDLE); ;} - break; - - case 87: -#line 463 "parser.y" - { (yyval.attr) = make_attrp(ATTR_HELPCONTEXT, (yyvsp[-1].expr)); ;} - break; - - case 88: -#line 464 "parser.y" - { (yyval.attr) = make_attrp(ATTR_HELPFILE, (yyvsp[-1].str)); ;} - break; - - case 89: -#line 465 "parser.y" - { (yyval.attr) = make_attrp(ATTR_HELPSTRING, (yyvsp[-1].str)); ;} - break; - - case 90: -#line 466 "parser.y" - { (yyval.attr) = make_attrp(ATTR_HELPSTRINGCONTEXT, (yyvsp[-1].expr)); ;} - break; - - case 91: -#line 467 "parser.y" - { (yyval.attr) = make_attrp(ATTR_HELPSTRINGDLL, (yyvsp[-1].str)); ;} - break; - - case 92: -#line 468 "parser.y" - { (yyval.attr) = make_attr(ATTR_HIDDEN); ;} - break; - - case 93: -#line 469 "parser.y" - { (yyval.attr) = make_attrp(ATTR_ID, (yyvsp[-1].expr)); ;} - break; - - case 94: -#line 470 "parser.y" - { (yyval.attr) = make_attr(ATTR_IDEMPOTENT); ;} - break; - - case 95: -#line 471 "parser.y" - { (yyval.attr) = make_attrp(ATTR_IIDIS, (yyvsp[-1].expr)); ;} - break; - - case 96: -#line 472 "parser.y" - { (yyval.attr) = make_attr(ATTR_IMMEDIATEBIND); ;} - break; - - case 97: -#line 473 "parser.y" - { (yyval.attr) = make_attrp(ATTR_IMPLICIT_HANDLE, (yyvsp[-1].str)); ;} - break; - - case 98: -#line 474 "parser.y" - { (yyval.attr) = make_attr(ATTR_IN); ;} - break; - - case 99: -#line 475 "parser.y" - { (yyval.attr) = make_attr(ATTR_INPUTSYNC); ;} - break; - - case 100: -#line 476 "parser.y" - { (yyval.attr) = make_attrp(ATTR_LENGTHIS, (yyvsp[-1].expr_list)); ;} - break; - - case 101: -#line 477 "parser.y" - { (yyval.attr) = make_attr(ATTR_LOCAL); ;} - break; - - case 102: -#line 478 "parser.y" - { (yyval.attr) = make_attr(ATTR_NONBROWSABLE); ;} - break; - - case 103: -#line 479 "parser.y" - { (yyval.attr) = make_attr(ATTR_NONCREATABLE); ;} - break; - - case 104: -#line 480 "parser.y" - { (yyval.attr) = make_attr(ATTR_NONEXTENSIBLE); ;} - break; - - case 105: -#line 481 "parser.y" - { (yyval.attr) = make_attr(ATTR_OBJECT); ;} - break; - - case 106: -#line 482 "parser.y" - { (yyval.attr) = make_attr(ATTR_ODL); ;} - break; - - case 107: -#line 483 "parser.y" - { (yyval.attr) = make_attr(ATTR_OLEAUTOMATION); ;} - break; - - case 108: -#line 484 "parser.y" - { (yyval.attr) = make_attr(ATTR_OPTIONAL); ;} - break; - - case 109: -#line 485 "parser.y" - { (yyval.attr) = make_attr(ATTR_OUT); ;} - break; - - case 110: -#line 486 "parser.y" - { (yyval.attr) = make_attrv(ATTR_POINTERDEFAULT, (yyvsp[-1].num)); ;} - break; - - case 111: -#line 487 "parser.y" - { (yyval.attr) = make_attr(ATTR_PROPGET); ;} - break; - - case 112: -#line 488 "parser.y" - { (yyval.attr) = make_attr(ATTR_PROPPUT); ;} - break; - - case 113: -#line 489 "parser.y" - { (yyval.attr) = make_attr(ATTR_PROPPUTREF); ;} - break; - - case 114: -#line 490 "parser.y" - { (yyval.attr) = make_attr(ATTR_PUBLIC); ;} - break; - - case 115: -#line 491 "parser.y" - { expr_list_t *list = append_expr( NULL, (yyvsp[-3].expr) ); - list = append_expr( list, (yyvsp[-1].expr) ); - (yyval.attr) = make_attrp(ATTR_RANGE, list); ;} - break; - - case 116: -#line 494 "parser.y" - { (yyval.attr) = make_attr(ATTR_READONLY); ;} - break; - - case 117: -#line 495 "parser.y" - { (yyval.attr) = make_attr(ATTR_REQUESTEDIT); ;} - break; - - case 118: -#line 496 "parser.y" - { (yyval.attr) = make_attr(ATTR_RESTRICTED); ;} - break; - - case 119: -#line 497 "parser.y" - { (yyval.attr) = make_attr(ATTR_RETVAL); ;} - break; - - case 120: -#line 498 "parser.y" - { (yyval.attr) = make_attrp(ATTR_SIZEIS, (yyvsp[-1].expr_list)); ;} - break; - - case 121: -#line 499 "parser.y" - { (yyval.attr) = make_attr(ATTR_SOURCE); ;} - break; - - case 122: -#line 500 "parser.y" - { (yyval.attr) = make_attr(ATTR_STRING); ;} - break; - - case 123: -#line 501 "parser.y" - { (yyval.attr) = make_attrp(ATTR_SWITCHIS, (yyvsp[-1].expr)); ;} - break; - - case 124: -#line 502 "parser.y" - { (yyval.attr) = make_attrp(ATTR_SWITCHTYPE, (yyvsp[-1].type)); ;} - break; - - case 125: -#line 503 "parser.y" - { (yyval.attr) = make_attrp(ATTR_TRANSMITAS, (yyvsp[-1].type)); ;} - break; - - case 126: -#line 504 "parser.y" - { (yyval.attr) = make_attrp(ATTR_UUID, (yyvsp[-1].uuid)); ;} - break; - - case 127: -#line 505 "parser.y" - { (yyval.attr) = make_attr(ATTR_V1ENUM); ;} - break; - - case 128: -#line 506 "parser.y" - { (yyval.attr) = make_attr(ATTR_VARARG); ;} - break; - - case 129: -#line 507 "parser.y" - { (yyval.attr) = make_attrv(ATTR_VERSION, (yyvsp[-1].num)); ;} - break; - - case 130: -#line 508 "parser.y" - { (yyval.attr) = make_attrp(ATTR_WIREMARSHAL, (yyvsp[-1].type)); ;} - break; - - case 131: -#line 509 "parser.y" - { (yyval.attr) = make_attrv(ATTR_POINTERTYPE, (yyvsp[0].num)); ;} - break; - - case 133: -#line 514 "parser.y" - { if (!is_valid_uuid((yyvsp[0].str))) - error_loc("invalid UUID: %s\n", (yyvsp[0].str)); - (yyval.uuid) = parse_uuid((yyvsp[0].str)); ;} - break; - - case 136: -#line 523 "parser.y" - { (yyval.var_list) = NULL; ;} - break; - - case 137: -#line 524 "parser.y" - { (yyval.var_list) = append_var( (yyvsp[-1].var_list), (yyvsp[0].var) ); ;} - break; - - case 138: -#line 527 "parser.y" - { attr_t *a = make_attrp(ATTR_CASE, append_expr( NULL, (yyvsp[-2].expr) )); - (yyval.var) = (yyvsp[0].var); if (!(yyval.var)) (yyval.var) = make_var(NULL); - (yyval.var)->attrs = append_attr( (yyval.var)->attrs, a ); - ;} - break; - - case 139: -#line 531 "parser.y" - { attr_t *a = make_attr(ATTR_DEFAULT); - (yyval.var) = (yyvsp[0].var); if (!(yyval.var)) (yyval.var) = make_var(NULL); - (yyval.var)->attrs = append_attr( (yyval.var)->attrs, a ); - ;} - break; - - case 140: -#line 537 "parser.y" - { (yyval.var) = reg_const((yyvsp[-2].var)); - set_type((yyval.var), (yyvsp[-3].type), 0, NULL, FALSE); - (yyval.var)->eval = (yyvsp[0].expr); - ;} - break; - - case 141: -#line 543 "parser.y" - { (yyval.var_list) = NULL; ;} - break; - - case 142: -#line 544 "parser.y" - { (yyval.var_list) = (yyvsp[-1].var_list); ;} - break; - - case 144: -#line 548 "parser.y" - { if (!(yyvsp[0].var)->eval) - (yyvsp[0].var)->eval = make_exprl(EXPR_NUM, 0 /* default for first enum entry */); - (yyval.var_list) = append_var( NULL, (yyvsp[0].var) ); - ;} - break; - - case 145: -#line 552 "parser.y" - { if (!(yyvsp[0].var)->eval) - { - var_t *last = LIST_ENTRY( list_tail((yyval.var_list)), var_t, entry ); - (yyvsp[0].var)->eval = make_exprl(EXPR_NUM, last->eval->cval + 1); - } - (yyval.var_list) = append_var( (yyvsp[-2].var_list), (yyvsp[0].var) ); - ;} - break; - - case 146: -#line 561 "parser.y" - { (yyval.var) = reg_const((yyvsp[-2].var)); - (yyval.var)->eval = (yyvsp[0].expr); - (yyval.var)->type = make_int(0); - ;} - break; - - case 147: -#line 565 "parser.y" - { (yyval.var) = reg_const((yyvsp[0].var)); - (yyval.var)->type = make_int(0); - ;} - break; - - case 148: -#line 570 "parser.y" - { (yyval.type) = get_typev(RPC_FC_ENUM16, (yyvsp[-3].var), tsENUM); - (yyval.type)->kind = TKIND_ENUM; - (yyval.type)->fields = (yyvsp[-1].var_list); - (yyval.type)->defined = TRUE; - if(in_typelib) - add_typelib_entry((yyval.type)); - ;} - break; - - case 149: -#line 579 "parser.y" - { (yyval.expr_list) = append_expr( NULL, (yyvsp[0].expr) ); ;} - break; - - case 150: -#line 580 "parser.y" - { (yyval.expr_list) = append_expr( (yyvsp[-2].expr_list), (yyvsp[0].expr) ); ;} - break; - - case 151: -#line 593 "parser.y" - { (yyval.expr) = make_expr(EXPR_VOID); ;} - break; - - case 153: -#line 597 "parser.y" - { (yyval.expr) = make_exprl(EXPR_NUM, (yyvsp[0].num)); ;} - break; - - case 154: -#line 598 "parser.y" - { (yyval.expr) = make_exprl(EXPR_HEXNUM, (yyvsp[0].num)); ;} - break; - - case 155: -#line 599 "parser.y" - { (yyval.expr) = make_exprd(EXPR_DOUBLE, (yyvsp[0].dbl)); ;} - break; - - case 156: -#line 600 "parser.y" - { (yyval.expr) = make_exprl(EXPR_TRUEFALSE, 0); ;} - break; - - case 157: -#line 601 "parser.y" - { (yyval.expr) = make_exprl(EXPR_TRUEFALSE, 1); ;} - break; - - case 158: -#line 602 "parser.y" - { (yyval.expr) = make_exprs(EXPR_IDENTIFIER, (yyvsp[0].str)); ;} - break; - - case 159: -#line 603 "parser.y" - { (yyval.expr) = make_expr3(EXPR_COND, (yyvsp[-4].expr), (yyvsp[-2].expr), (yyvsp[0].expr)); ;} - break; - - case 160: -#line 604 "parser.y" - { (yyval.expr) = make_expr2(EXPR_OR , (yyvsp[-2].expr), (yyvsp[0].expr)); ;} - break; - - case 161: -#line 605 "parser.y" - { (yyval.expr) = make_expr2(EXPR_AND, (yyvsp[-2].expr), (yyvsp[0].expr)); ;} - break; - - case 162: -#line 606 "parser.y" - { (yyval.expr) = make_expr2(EXPR_ADD, (yyvsp[-2].expr), (yyvsp[0].expr)); ;} - break; - - case 163: -#line 607 "parser.y" - { (yyval.expr) = make_expr2(EXPR_SUB, (yyvsp[-2].expr), (yyvsp[0].expr)); ;} - break; - - case 164: -#line 608 "parser.y" - { (yyval.expr) = make_expr2(EXPR_MUL, (yyvsp[-2].expr), (yyvsp[0].expr)); ;} - break; - - case 165: -#line 609 "parser.y" - { (yyval.expr) = make_expr2(EXPR_DIV, (yyvsp[-2].expr), (yyvsp[0].expr)); ;} - break; - - case 166: -#line 610 "parser.y" - { (yyval.expr) = make_expr2(EXPR_SHL, (yyvsp[-2].expr), (yyvsp[0].expr)); ;} - break; - - case 167: -#line 611 "parser.y" - { (yyval.expr) = make_expr2(EXPR_SHR, (yyvsp[-2].expr), (yyvsp[0].expr)); ;} - break; - - case 168: -#line 612 "parser.y" - { (yyval.expr) = make_expr1(EXPR_NOT, (yyvsp[0].expr)); ;} - break; - - case 169: -#line 613 "parser.y" - { (yyval.expr) = make_expr1(EXPR_NEG, (yyvsp[0].expr)); ;} - break; - - case 170: -#line 614 "parser.y" - { (yyval.expr) = make_expr1(EXPR_ADDRESSOF, (yyvsp[0].expr)); ;} - break; - - case 171: -#line 615 "parser.y" - { (yyval.expr) = make_expr1(EXPR_PPTR, (yyvsp[0].expr)); ;} - break; - - case 172: -#line 616 "parser.y" - { (yyval.expr) = make_exprt(EXPR_CAST, (yyvsp[-2].type), (yyvsp[0].expr)); ;} - break; - - case 173: -#line 617 "parser.y" - { (yyval.expr) = make_exprt(EXPR_SIZEOF, (yyvsp[-1].type), NULL); ;} - break; - - case 174: -#line 618 "parser.y" - { (yyval.expr) = (yyvsp[-1].expr); ;} - break; - - case 175: -#line 621 "parser.y" - { (yyval.expr_list) = append_expr( NULL, (yyvsp[0].expr) ); ;} - break; - - case 176: -#line 622 "parser.y" - { (yyval.expr_list) = append_expr( (yyvsp[-2].expr_list), (yyvsp[0].expr) ); ;} - break; - - case 177: -#line 625 "parser.y" - { (yyval.expr) = (yyvsp[0].expr); - if (!(yyval.expr)->is_const) - error_loc("expression is not constant\n"); - ;} - break; - - case 178: -#line 631 "parser.y" - { (yyval.var) = (yyvsp[0].var); - set_type((yyval.var), (yyvsp[-1].type), 0, NULL, FALSE); - ;} - break; - - case 179: -#line 636 "parser.y" - { (yyval.var_list) = NULL; ;} - break; - - case 180: -#line 637 "parser.y" - { (yyval.var_list) = append_var( (yyvsp[-1].var_list), (yyvsp[0].var) ); ;} - break; - - case 181: -#line 640 "parser.y" - { (yyval.var) = (yyvsp[-1].var); ;} - break; - - case 182: -#line 641 "parser.y" - { (yyval.var) = make_var(NULL); (yyval.var)->type = (yyvsp[-1].type); (yyval.var)->attrs = (yyvsp[-2].attr_list); ;} - break; - - case 183: -#line 642 "parser.y" - { (yyval.var) = make_var(NULL); (yyval.var)->attrs = (yyvsp[-1].attr_list); ;} - break; - - case 184: -#line 643 "parser.y" - { (yyval.var) = NULL; ;} - break; - - case 185: -#line 646 "parser.y" - { (yyval.var) = (yyvsp[-1].pident)->var; - (yyval.var)->attrs = (yyvsp[-3].attr_list); - set_type((yyval.var), (yyvsp[-2].type), (yyvsp[-1].pident)->ptr_level, (yyvsp[0].array_dims), FALSE); - free((yyvsp[-1].pident)); - ;} - break; - - case 186: -#line 655 "parser.y" - { var_t *v = (yyvsp[-3].pident)->var; - v->attrs = (yyvsp[-6].attr_list); - set_type(v, (yyvsp[-5].type), (yyvsp[-3].pident)->ptr_level, NULL, FALSE); - free((yyvsp[-3].pident)); - (yyval.func) = make_func(v, (yyvsp[-1].var_list)); - if (is_attr(v->attrs, ATTR_IN)) { - error_loc("inapplicable attribute [in] for function '%s'\n",(yyval.func)->def->name); - } - ;} - break; - - case 187: -#line 666 "parser.y" - { (yyval.var) = NULL; ;} - break; - - case 189: -#line 670 "parser.y" - { (yyval.var) = NULL; ;} - break; - - case 190: -#line 671 "parser.y" - { (yyval.var) = make_var((yyvsp[0].str)); ;} - break; - - case 191: -#line 672 "parser.y" - { (yyval.var) = make_var((yyvsp[0].str)); ;} - break; - - case 192: -#line 675 "parser.y" - { (yyval.var) = make_var((yyvsp[0].str)); ;} - break; - - case 193: -#line 677 "parser.y" - { (yyval.var) = make_var((yyvsp[0].str)); ;} - break; - - case 194: -#line 680 "parser.y" - { (yyval.type) = make_builtin((yyvsp[0].str)); ;} - break; - - case 195: -#line 681 "parser.y" - { (yyval.type) = make_builtin((yyvsp[0].str)); ;} - break; - - case 197: -#line 683 "parser.y" - { (yyval.type) = (yyvsp[0].type); (yyval.type)->sign = 1; ;} - break; - - case 198: -#line 684 "parser.y" - { (yyval.type) = (yyvsp[0].type); (yyval.type)->sign = -1; - switch ((yyval.type)->type) { - case RPC_FC_CHAR: break; - case RPC_FC_SMALL: (yyval.type)->type = RPC_FC_USMALL; break; - case RPC_FC_SHORT: (yyval.type)->type = RPC_FC_USHORT; break; - case RPC_FC_LONG: (yyval.type)->type = RPC_FC_ULONG; break; - case RPC_FC_HYPER: - if ((yyval.type)->name[0] == 'h') /* hyper, as opposed to __int64 */ - { - (yyval.type) = alias((yyval.type), "MIDL_uhyper"); - (yyval.type)->sign = 0; - } - break; - default: break; - } - ;} - break; - - case 199: -#line 700 "parser.y" - { (yyval.type) = make_int(-1); ;} - break; - - case 200: -#line 701 "parser.y" - { (yyval.type) = make_builtin((yyvsp[0].str)); ;} - break; - - case 201: -#line 702 "parser.y" - { (yyval.type) = duptype(find_type("float", 0), 1); ;} - break; - - case 202: -#line 703 "parser.y" - { (yyval.type) = make_builtin((yyvsp[0].str)); ;} - break; - - case 203: -#line 704 "parser.y" - { (yyval.type) = make_builtin((yyvsp[0].str)); ;} - break; - - case 204: -#line 705 "parser.y" - { (yyval.type) = make_builtin((yyvsp[0].str)); ;} - break; - - case 205: -#line 706 "parser.y" - { (yyval.type) = make_builtin((yyvsp[0].str)); ;} - break; - - case 208: -#line 713 "parser.y" - { (yyval.type) = make_builtin((yyvsp[0].str)); ;} - break; - - case 209: -#line 714 "parser.y" - { (yyval.type) = make_builtin((yyvsp[-1].str)); ;} - break; - - case 210: -#line 715 "parser.y" - { (yyval.type) = make_builtin((yyvsp[0].str)); ;} - break; - - case 211: -#line 716 "parser.y" - { (yyval.type) = make_builtin((yyvsp[-1].str)); ;} - break; - - case 212: -#line 717 "parser.y" - { (yyval.type) = make_builtin((yyvsp[-1].str)); ;} - break; - - case 213: -#line 718 "parser.y" - { (yyval.type) = make_builtin((yyvsp[0].str)); ;} - break; - - case 214: -#line 719 "parser.y" - { (yyval.type) = make_builtin((yyvsp[0].str)); ;} - break; - - case 215: -#line 722 "parser.y" - { (yyval.type) = make_class((yyvsp[0].str)); ;} - break; - - case 216: -#line 723 "parser.y" - { (yyval.type) = find_type((yyvsp[0].str), 0); - if ((yyval.type)->defined) error_loc("multiple definition error\n"); - if ((yyval.type)->kind != TKIND_COCLASS) error_loc("%s was not declared a coclass\n", (yyvsp[0].str)); - ;} - break; - - case 217: -#line 729 "parser.y" - { (yyval.type) = (yyvsp[0].type); - (yyval.type)->attrs = (yyvsp[-1].attr_list); - if (!parse_only && do_header) - write_coclass((yyval.type)); - if (!parse_only && do_idfile) - write_clsid((yyval.type)); - ;} - break; - - case 218: -#line 738 "parser.y" - { (yyval.type) = (yyvsp[-3].type); - (yyval.type)->ifaces = (yyvsp[-1].ifref_list); - (yyval.type)->defined = TRUE; - ;} - break; - - case 219: -#line 744 "parser.y" - { (yyval.ifref_list) = NULL; ;} - break; - - case 220: -#line 745 "parser.y" - { (yyval.ifref_list) = append_ifref( (yyvsp[-1].ifref_list), (yyvsp[0].ifref) ); ;} - break; - - case 221: -#line 749 "parser.y" - { (yyval.ifref) = make_ifref((yyvsp[0].type)); (yyval.ifref)->attrs = (yyvsp[-1].attr_list); ;} - break; - - case 222: -#line 752 "parser.y" - { (yyval.type) = get_type(0, (yyvsp[0].str), 0); (yyval.type)->kind = TKIND_DISPATCH; ;} - break; - - case 223: -#line 753 "parser.y" - { (yyval.type) = get_type(0, (yyvsp[0].str), 0); (yyval.type)->kind = TKIND_DISPATCH; ;} - break; - - case 224: -#line 756 "parser.y" - { attr_t *attrs; - (yyval.type) = (yyvsp[0].type); - if ((yyval.type)->defined) error_loc("multiple definition error\n"); - attrs = make_attr(ATTR_DISPINTERFACE); - (yyval.type)->attrs = append_attr( (yyvsp[-1].attr_list), attrs ); - (yyval.type)->ref = find_type("IDispatch", 0); - if (!(yyval.type)->ref) error_loc("IDispatch is undefined\n"); - (yyval.type)->defined = TRUE; - if (!parse_only && do_header) write_forward((yyval.type)); - ;} - break; - - case 225: -#line 768 "parser.y" - { (yyval.var_list) = NULL; ;} - break; - - case 226: -#line 769 "parser.y" - { (yyval.var_list) = append_var( (yyvsp[-2].var_list), (yyvsp[-1].var) ); ;} - break; - - case 227: -#line 772 "parser.y" - { (yyval.func_list) = NULL; ;} - break; - - case 228: -#line 773 "parser.y" - { (yyval.func_list) = append_func( (yyvsp[-2].func_list), (yyvsp[-1].func) ); ;} - break; - - case 229: -#line 779 "parser.y" - { (yyval.type) = (yyvsp[-4].type); - (yyval.type)->fields = (yyvsp[-2].var_list); - (yyval.type)->funcs = (yyvsp[-1].func_list); - if (!parse_only && do_header) write_dispinterface((yyval.type)); - if (!parse_only && do_idfile) write_diid((yyval.type)); - ;} - break; - - case 230: -#line 786 "parser.y" - { (yyval.type) = (yyvsp[-4].type); - (yyval.type)->fields = (yyvsp[-2].type)->fields; - (yyval.type)->funcs = (yyvsp[-2].type)->funcs; - if (!parse_only && do_header) write_dispinterface((yyval.type)); - if (!parse_only && do_idfile) write_diid((yyval.type)); - ;} - break; - - case 231: -#line 794 "parser.y" - { (yyval.type) = NULL; ;} - break; - - case 232: -#line 795 "parser.y" - { (yyval.type) = find_type2((yyvsp[0].str), 0); ;} - break; - - case 233: -#line 798 "parser.y" - { (yyval.type) = get_type(RPC_FC_IP, (yyvsp[0].str), 0); (yyval.type)->kind = TKIND_INTERFACE; ;} - break; - - case 234: -#line 799 "parser.y" - { (yyval.type) = get_type(RPC_FC_IP, (yyvsp[0].str), 0); (yyval.type)->kind = TKIND_INTERFACE; ;} - break; - - case 235: -#line 802 "parser.y" - { (yyval.ifinfo).interface = (yyvsp[0].type); - (yyval.ifinfo).old_pointer_default = pointer_default; - if (is_attr((yyvsp[-1].attr_list), ATTR_POINTERDEFAULT)) - pointer_default = get_attrv((yyvsp[-1].attr_list), ATTR_POINTERDEFAULT); - if ((yyvsp[0].type)->defined) error_loc("multiple definition error\n"); - (yyvsp[0].type)->attrs = (yyvsp[-1].attr_list); - (yyvsp[0].type)->defined = TRUE; - if (!parse_only && do_header) write_forward((yyvsp[0].type)); - ;} - break; - - case 236: -#line 814 "parser.y" - { (yyval.type) = (yyvsp[-4].ifinfo).interface; - (yyval.type)->ref = (yyvsp[-3].type); - (yyval.type)->funcs = (yyvsp[-1].func_list); - compute_method_indexes((yyval.type)); - if (!parse_only && do_header) write_interface((yyval.type)); - if (!parse_only && local_stubs) write_locals(local_stubs, (yyval.type), TRUE); - if (!parse_only && do_idfile) write_iid((yyval.type)); - pointer_default = (yyvsp[-4].ifinfo).old_pointer_default; - ;} - break; - - case 237: -#line 826 "parser.y" - { (yyval.type) = (yyvsp[-6].ifinfo).interface; - (yyval.type)->ref = find_type2((yyvsp[-4].str), 0); - if (!(yyval.type)->ref) error_loc("base class '%s' not found in import\n", (yyvsp[-4].str)); - (yyval.type)->funcs = (yyvsp[-1].func_list); - compute_method_indexes((yyval.type)); - if (!parse_only && do_header) write_interface((yyval.type)); - if (!parse_only && local_stubs) write_locals(local_stubs, (yyval.type), TRUE); - if (!parse_only && do_idfile) write_iid((yyval.type)); - pointer_default = (yyvsp[-6].ifinfo).old_pointer_default; - ;} - break; - - case 238: -#line 836 "parser.y" - { (yyval.type) = (yyvsp[0].type); ;} - break; - - case 239: -#line 840 "parser.y" - { (yyval.type) = (yyvsp[-1].type); if (!parse_only && do_header) write_forward((yyval.type)); ;} - break; - - case 240: -#line 841 "parser.y" - { (yyval.type) = (yyvsp[-1].type); if (!parse_only && do_header) write_forward((yyval.type)); ;} - break; - - case 241: -#line 844 "parser.y" - { (yyval.type) = make_type(0, NULL); (yyval.type)->name = (yyvsp[0].str); (yyval.type)->kind = TKIND_MODULE; ;} - break; - - case 242: -#line 845 "parser.y" - { (yyval.type) = make_type(0, NULL); (yyval.type)->name = (yyvsp[0].str); (yyval.type)->kind = TKIND_MODULE; ;} - break; - - case 243: -#line 848 "parser.y" - { (yyval.type) = (yyvsp[0].type); - (yyval.type)->attrs = (yyvsp[-1].attr_list); - ;} - break; - - case 244: -#line 853 "parser.y" - { (yyval.type) = (yyvsp[-3].type); - (yyval.type)->funcs = (yyvsp[-1].func_list); - /* FIXME: if (!parse_only && do_header) write_module($$); */ - ;} - break; - - case 245: -#line 859 "parser.y" - { (yyval.pident) = (yyvsp[0].pident); (yyval.pident)->ptr_level++; ;} - break; - - case 246: -#line 860 "parser.y" - { (yyval.pident) = (yyvsp[0].pident); /* FIXME */ ;} - break; - - case 247: -#line 863 "parser.y" - { (yyval.pident) = make_pident((yyvsp[0].var)); ;} - break; - - case 249: -#line 865 "parser.y" - { (yyval.pident) = (yyvsp[-1].pident); ;} - break; - - case 250: -#line 869 "parser.y" - { (yyval.pident_list) = append_pident( NULL, (yyvsp[0].pident) ); ;} - break; - - case 251: -#line 870 "parser.y" - { (yyval.pident_list) = append_pident( (yyvsp[-2].pident_list), (yyvsp[0].pident) ); ;} - break; - - case 252: -#line 874 "parser.y" - { (yyval.num) = RPC_FC_RP; ;} - break; - - case 253: -#line 875 "parser.y" - { (yyval.num) = RPC_FC_UP; ;} - break; - - case 254: -#line 876 "parser.y" - { (yyval.num) = RPC_FC_FP; ;} - break; - - case 255: -#line 879 "parser.y" - { (yyval.type) = get_typev(RPC_FC_STRUCT, (yyvsp[-3].var), tsSTRUCT); - /* overwrite RPC_FC_STRUCT with a more exact type */ - (yyval.type)->type = get_struct_type( (yyvsp[-1].var_list) ); - (yyval.type)->kind = TKIND_RECORD; - (yyval.type)->fields = (yyvsp[-1].var_list); - (yyval.type)->defined = TRUE; - if(in_typelib) - add_typelib_entry((yyval.type)); - ;} - break; - - case 256: -#line 890 "parser.y" - { (yyval.type) = duptype(find_type("void", 0), 1); ;} - break; - - case 257: -#line 891 "parser.y" - { (yyval.type) = find_type((yyvsp[0].str), 0); ;} - break; - - case 258: -#line 892 "parser.y" - { (yyval.type) = (yyvsp[0].type); ;} - break; - - case 259: -#line 893 "parser.y" - { (yyval.type) = duptype((yyvsp[0].type), 1); (yyval.type)->is_const = TRUE; ;} - break; - - case 260: -#line 894 "parser.y" - { (yyval.type) = (yyvsp[0].type); ;} - break; - - case 261: -#line 895 "parser.y" - { (yyval.type) = find_type2((yyvsp[0].str), tsENUM); ;} - break; - - case 262: -#line 896 "parser.y" - { (yyval.type) = (yyvsp[0].type); ;} - break; - - case 263: -#line 897 "parser.y" - { (yyval.type) = get_type(RPC_FC_STRUCT, (yyvsp[0].str), tsSTRUCT); ;} - break; - - case 264: -#line 898 "parser.y" - { (yyval.type) = (yyvsp[0].type); ;} - break; - - case 265: -#line 899 "parser.y" - { (yyval.type) = find_type2((yyvsp[0].str), tsUNION); ;} - break; - - case 266: -#line 900 "parser.y" - { (yyval.type) = make_safearray((yyvsp[-1].type)); ;} - break; - - case 267: -#line 903 "parser.y" - { reg_typedefs((yyvsp[-1].type), (yyvsp[0].pident_list), (yyvsp[-2].attr_list)); - process_typedefs((yyvsp[0].pident_list)); - ;} - break; - - case 268: -#line 908 "parser.y" - { (yyval.type) = get_typev(RPC_FC_NON_ENCAPSULATED_UNION, (yyvsp[-3].var), tsUNION); - (yyval.type)->kind = TKIND_UNION; - (yyval.type)->fields = (yyvsp[-1].var_list); - (yyval.type)->defined = TRUE; - ;} - break; - - case 269: -#line 915 "parser.y" - { var_t *u = (yyvsp[-3].var); - (yyval.type) = get_typev(RPC_FC_ENCAPSULATED_UNION, (yyvsp[-8].var), tsUNION); - (yyval.type)->kind = TKIND_UNION; - if (!u) u = make_var( xstrdup("tagged_union") ); - u->type = make_type(RPC_FC_NON_ENCAPSULATED_UNION, NULL); - u->type->kind = TKIND_UNION; - u->type->fields = (yyvsp[-1].var_list); - u->type->defined = TRUE; - (yyval.type)->fields = append_var( (yyval.type)->fields, (yyvsp[-5].var) ); - (yyval.type)->fields = append_var( (yyval.type)->fields, u ); - (yyval.type)->defined = TRUE; - ;} - break; - - case 270: -#line 930 "parser.y" - { (yyval.num) = MAKEVERSION((yyvsp[0].num), 0); ;} - break; - - case 271: -#line 931 "parser.y" - { (yyval.num) = MAKEVERSION((yyvsp[-2].num), (yyvsp[0].num)); ;} - break; - - - default: break; - } - -/* Line 1126 of yacc.c. */ -#line 3627 "parser.tab.c" - - yyvsp -= yylen; - yyssp -= yylen; - - - YY_STACK_PRINT (yyss, yyssp); - - *++yyvsp = yyval; - - - /* Now `shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTOKENS]; - - goto yynewstate; - - -/*------------------------------------. -| yyerrlab -- here on detecting error | -`------------------------------------*/ -yyerrlab: - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) - { - ++yynerrs; -#if YYERROR_VERBOSE - yyn = yypact[yystate]; - - if (YYPACT_NINF < yyn && yyn < YYLAST) - { - int yytype = YYTRANSLATE (yychar); - YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); - YYSIZE_T yysize = yysize0; - YYSIZE_T yysize1; - int yysize_overflow = 0; - char *yymsg = 0; -# define YYERROR_VERBOSE_ARGS_MAXIMUM 5 - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - int yyx; - -#if 0 - /* This is so xgettext sees the translatable formats that are - constructed on the fly. */ - YY_("syntax error, unexpected %s"); - YY_("syntax error, unexpected %s, expecting %s"); - YY_("syntax error, unexpected %s, expecting %s or %s"); - YY_("syntax error, unexpected %s, expecting %s or %s or %s"); - YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); -#endif - char *yyfmt; - char const *yyf; - static char const yyunexpected[] = "syntax error, unexpected %s"; - static char const yyexpecting[] = ", expecting %s"; - static char const yyor[] = " or %s"; - char yyformat[sizeof yyunexpected - + sizeof yyexpecting - 1 - + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) - * (sizeof yyor - 1))]; - char const *yyprefix = yyexpecting; - - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. */ - int yyxbegin = yyn < 0 ? -yyn : 0; - - /* Stay within bounds of both yycheck and yytname. */ - int yychecklim = YYLAST - yyn; - int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; - int yycount = 1; - - yyarg[0] = yytname[yytype]; - yyfmt = yystpcpy (yyformat, yyunexpected); - - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - { - if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) - { - yycount = 1; - yysize = yysize0; - yyformat[sizeof yyunexpected - 1] = '\0'; - break; - } - yyarg[yycount++] = yytname[yyx]; - yysize1 = yysize + yytnamerr (0, yytname[yyx]); - yysize_overflow |= yysize1 < yysize; - yysize = yysize1; - yyfmt = yystpcpy (yyfmt, yyprefix); - yyprefix = yyor; - } - - yyf = YY_(yyformat); - yysize1 = yysize + yystrlen (yyf); - yysize_overflow |= yysize1 < yysize; - yysize = yysize1; - - if (!yysize_overflow && yysize <= YYSTACK_ALLOC_MAXIMUM) - yymsg = (char *) YYSTACK_ALLOC (yysize); - if (yymsg) - { - /* Avoid sprintf, as that infringes on the user's name space. - Don't have undefined behavior even if the translation - produced a string with the wrong number of "%s"s. */ - char *yyp = yymsg; - int yyi = 0; - while ((*yyp = *yyf)) - { - if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) - { - yyp += yytnamerr (yyp, yyarg[yyi++]); - yyf += 2; - } - else - { - yyp++; - yyf++; - } - } - yyerror (yymsg); - YYSTACK_FREE (yymsg); - } - else - { - yyerror (YY_("syntax error")); - goto yyexhaustedlab; - } - } - else -#endif /* YYERROR_VERBOSE */ - yyerror (YY_("syntax error")); - } - - - - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse look-ahead token after an - error, discard it. */ - - if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } - else - { - yydestruct ("Error: discarding", yytoken, &yylval); - yychar = YYEMPTY; - } - } - - /* Else will try to reuse look-ahead token after shifting the error - token. */ - goto yyerrlab1; - - -/*---------------------------------------------------. -| yyerrorlab -- error raised explicitly by YYERROR. | -`---------------------------------------------------*/ -yyerrorlab: - - /* Pacify compilers like GCC when the user code never invokes - YYERROR and the label yyerrorlab therefore never appears in user - code. */ - if (0) - goto yyerrorlab; - -yyvsp -= yylen; - yyssp -= yylen; - yystate = *yyssp; - goto yyerrlab1; - - -/*-------------------------------------------------------------. -| yyerrlab1 -- common code for both syntax error and YYERROR. | -`-------------------------------------------------------------*/ -yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ - - for (;;) - { - yyn = yypact[yystate]; - if (yyn != YYPACT_NINF) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) - YYABORT; - - - yydestruct ("Error: popping", yystos[yystate], yyvsp); - YYPOPSTACK; - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); - } - - if (yyn == YYFINAL) - YYACCEPT; - - *++yyvsp = yylval; - - - /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); - - yystate = yyn; - goto yynewstate; - - -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturn; - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturn; - -#ifndef yyoverflow -/*-------------------------------------------------. -| yyexhaustedlab -- memory exhaustion comes here. | -`-------------------------------------------------*/ -yyexhaustedlab: - yyerror (YY_("memory exhausted")); - yyresult = 2; - /* Fall through. */ -#endif - -yyreturn: - if (yychar != YYEOF && yychar != YYEMPTY) - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval); - while (yyssp != yyss) - { - yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp); - YYPOPSTACK; - } -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif - return yyresult; -} - - -#line 934 "parser.y" - - -static void decl_builtin(const char *name, unsigned char type) -{ - type_t *t = make_type(type, NULL); - t->name = xstrdup(name); - reg_type(t, name, 0); -} - -static type_t *make_builtin(char *name) -{ - /* NAME is strdup'd in the lexer */ - type_t *t = duptype(find_type(name, 0), 0); - t->name = name; - return t; -} - -static type_t *make_int(int sign) -{ - type_t *t = duptype(find_type("int", 0), 1); - - t->sign = sign; - if (sign < 0) - t->type = t->type == RPC_FC_LONG ? RPC_FC_ULONG : RPC_FC_USHORT; - - return t; -} - -void init_types(void) -{ - decl_builtin("void", 0); - decl_builtin("byte", RPC_FC_BYTE); - decl_builtin("wchar_t", RPC_FC_WCHAR); - decl_builtin("int", RPC_FC_LONG); /* win32 */ - decl_builtin("short", RPC_FC_SHORT); - decl_builtin("small", RPC_FC_SMALL); - decl_builtin("long", RPC_FC_LONG); - decl_builtin("hyper", RPC_FC_HYPER); - decl_builtin("__int64", RPC_FC_HYPER); - decl_builtin("char", RPC_FC_CHAR); - decl_builtin("float", RPC_FC_FLOAT); - decl_builtin("double", RPC_FC_DOUBLE); - decl_builtin("boolean", RPC_FC_BYTE); - decl_builtin("error_status_t", RPC_FC_ERROR_STATUS_T); - decl_builtin("handle_t", RPC_FC_BIND_PRIMITIVE); -} - -static str_list_t *append_str(str_list_t *list, char *str) -{ - struct str_list_entry_t *entry; - - if (!str) return list; - if (!list) - { - list = xmalloc( sizeof(*list) ); - list_init( list ); - } - entry = xmalloc( sizeof(*entry) ); - entry->str = str; - list_add_tail( list, &entry->entry ); - return list; -} - -static attr_list_t *append_attr(attr_list_t *list, attr_t *attr) -{ - if (!attr) return list; - if (!list) - { - list = xmalloc( sizeof(*list) ); - list_init( list ); - } - list_add_tail( list, &attr->entry ); - return list; -} - -static attr_t *make_attr(enum attr_type type) -{ - attr_t *a = xmalloc(sizeof(attr_t)); - a->type = type; - a->u.ival = 0; - return a; -} - -static attr_t *make_attrv(enum attr_type type, unsigned long val) -{ - attr_t *a = xmalloc(sizeof(attr_t)); - a->type = type; - a->u.ival = val; - return a; -} - -static attr_t *make_attrp(enum attr_type type, void *val) -{ - attr_t *a = xmalloc(sizeof(attr_t)); - a->type = type; - a->u.pval = val; - return a; -} - -static expr_t *make_expr(enum expr_type type) -{ - expr_t *e = xmalloc(sizeof(expr_t)); - e->type = type; - e->ref = NULL; - e->u.lval = 0; - e->is_const = FALSE; - e->cval = 0; - return e; -} - -static expr_t *make_exprl(enum expr_type type, long val) -{ - expr_t *e = xmalloc(sizeof(expr_t)); - e->type = type; - e->ref = NULL; - e->u.lval = val; - e->is_const = FALSE; - /* check for numeric constant */ - if (type == EXPR_NUM || type == EXPR_HEXNUM || type == EXPR_TRUEFALSE) { - /* make sure true/false value is valid */ - assert(type != EXPR_TRUEFALSE || val == 0 || val == 1); - e->is_const = TRUE; - e->cval = val; - } - return e; -} - -static expr_t *make_exprd(enum expr_type type, double val) -{ - expr_t *e = xmalloc(sizeof(expr_t)); - e->type = type; - e->ref = NULL; - e->u.dval = val; - e->is_const = TRUE; - e->cval = val; - return e; -} - -static expr_t *make_exprs(enum expr_type type, char *val) -{ - expr_t *e; - e = xmalloc(sizeof(expr_t)); - e->type = type; - e->ref = NULL; - e->u.sval = val; - e->is_const = FALSE; - /* check for predefined constants */ - if (type == EXPR_IDENTIFIER) { - var_t *c = find_const(val, 0); - if (c) { - e->u.sval = c->name; - free(val); - e->is_const = TRUE; - e->cval = c->eval->cval; - } - } - return e; -} - -static expr_t *make_exprt(enum expr_type type, type_t *tref, expr_t *expr) -{ - expr_t *e; - e = xmalloc(sizeof(expr_t)); - e->type = type; - e->ref = expr; - e->u.tref = tref; - e->is_const = FALSE; - /* check for cast of constant expression */ - if (type == EXPR_SIZEOF) { - switch (tref->type) { - case RPC_FC_BYTE: - case RPC_FC_CHAR: - case RPC_FC_SMALL: - case RPC_FC_USMALL: - e->is_const = TRUE; - e->cval = 1; - break; - case RPC_FC_WCHAR: - case RPC_FC_USHORT: - case RPC_FC_SHORT: - e->is_const = TRUE; - e->cval = 2; - break; - case RPC_FC_LONG: - case RPC_FC_ULONG: - case RPC_FC_FLOAT: - case RPC_FC_ERROR_STATUS_T: - e->is_const = TRUE; - e->cval = 4; - break; - case RPC_FC_HYPER: - case RPC_FC_DOUBLE: - e->is_const = TRUE; - e->cval = 8; - break; - } - } - if (type == EXPR_CAST && expr->is_const) { - e->is_const = TRUE; - e->cval = expr->cval; - } - return e; -} - -static expr_t *make_expr1(enum expr_type type, expr_t *expr) -{ - expr_t *e; - if (type == EXPR_ADDRESSOF && expr->type != EXPR_IDENTIFIER) - error("address-of operator applied to invalid expression\n"); - e = xmalloc(sizeof(expr_t)); - e->type = type; - e->ref = expr; - e->u.lval = 0; - e->is_const = FALSE; - /* check for compile-time optimization */ - if (expr->is_const) { - e->is_const = TRUE; - switch (type) { - case EXPR_NEG: - e->cval = -expr->cval; - break; - case EXPR_NOT: - e->cval = ~expr->cval; - break; - default: - e->is_const = FALSE; - break; - } - } - return e; -} - -static expr_t *make_expr2(enum expr_type type, expr_t *expr1, expr_t *expr2) -{ - expr_t *e; - e = xmalloc(sizeof(expr_t)); - e->type = type; - e->ref = expr1; - e->u.ext = expr2; - e->is_const = FALSE; - /* check for compile-time optimization */ - if (expr1->is_const && expr2->is_const) { - e->is_const = TRUE; - switch (type) { - case EXPR_ADD: - e->cval = expr1->cval + expr2->cval; - break; - case EXPR_SUB: - e->cval = expr1->cval - expr2->cval; - break; - case EXPR_MUL: - e->cval = expr1->cval * expr2->cval; - break; - case EXPR_DIV: - e->cval = expr1->cval / expr2->cval; - break; - case EXPR_OR: - e->cval = expr1->cval | expr2->cval; - break; - case EXPR_AND: - e->cval = expr1->cval & expr2->cval; - break; - case EXPR_SHL: - e->cval = expr1->cval << expr2->cval; - break; - case EXPR_SHR: - e->cval = expr1->cval >> expr2->cval; - break; - default: - e->is_const = FALSE; - break; - } - } - return e; -} - -static expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, expr_t *expr3) -{ - expr_t *e; - e = xmalloc(sizeof(expr_t)); - e->type = type; - e->ref = expr1; - e->u.ext = expr2; - e->ext2 = expr3; - e->is_const = FALSE; - /* check for compile-time optimization */ - if (expr1->is_const && expr2->is_const && expr3->is_const) { - e->is_const = TRUE; - switch (type) { - case EXPR_COND: - e->cval = expr1->cval ? expr2->cval : expr3->cval; - break; - default: - e->is_const = FALSE; - break; - } - } - return e; -} - -static expr_list_t *append_expr(expr_list_t *list, expr_t *expr) -{ - if (!expr) return list; - if (!list) - { - list = xmalloc( sizeof(*list) ); - list_init( list ); - } - list_add_tail( list, &expr->entry ); - return list; -} - -static array_dims_t *append_array(array_dims_t *list, expr_t *expr) -{ - if (!expr) return list; - if (!list) - { - list = xmalloc( sizeof(*list) ); - list_init( list ); - } - list_add_tail( list, &expr->entry ); - return list; -} - -static struct list type_pool = LIST_INIT(type_pool); -typedef struct -{ - type_t data; - struct list link; -} type_pool_node_t; - -type_t *alloc_type(void) -{ - type_pool_node_t *node = xmalloc(sizeof *node); - list_add_tail(&type_pool, &node->link); - return &node->data; -} - -void set_all_tfswrite(int val) -{ - type_pool_node_t *node; - LIST_FOR_EACH_ENTRY(node, &type_pool, type_pool_node_t, link) - node->data.tfswrite = val; -} - -static type_t *make_type(unsigned char type, type_t *ref) -{ - type_t *t = alloc_type(); - t->name = NULL; - t->kind = TKIND_PRIMITIVE; - t->type = type; - t->ref = ref; - t->attrs = NULL; - t->orig = NULL; - t->funcs = NULL; - t->fields = NULL; - t->ifaces = NULL; - t->dim = 0; - t->size_is = NULL; - t->length_is = NULL; - t->typestring_offset = 0; - t->ptrdesc = 0; - t->declarray = FALSE; - t->ignore = (parse_only != 0); - t->is_const = FALSE; - t->sign = 0; - t->defined = FALSE; - t->written = FALSE; - t->user_types_registered = FALSE; - t->tfswrite = FALSE; - t->typelib_idx = -1; - return t; -} - -static void set_type(var_t *v, type_t *type, int ptr_level, array_dims_t *arr, - int top) -{ - expr_list_t *sizes = get_attrp(v->attrs, ATTR_SIZEIS); - expr_list_t *lengs = get_attrp(v->attrs, ATTR_LENGTHIS); - int ptr_attr = get_attrv(v->attrs, ATTR_POINTERTYPE); - int ptr_type = ptr_attr; - int sizeless, has_varconf; - expr_t *dim; - type_t *atype, **ptype; - - v->type = type; - - if (!ptr_type && top) - ptr_type = RPC_FC_RP; - - for ( ; 0 < ptr_level; --ptr_level) - { - v->type = make_type(pointer_default, v->type); - if (ptr_level == 1 && ptr_type && !arr) - { - v->type->type = ptr_type; - ptr_type = 0; - } - } - - if (ptr_type && !arr) - { - if (is_ptr(v->type)) - { - if (v->type->type != ptr_type) - { - v->type = duptype(v->type, 1); - v->type->type = ptr_type; - } - } - else if (!arr && ptr_attr) - error("%s: pointer attribute applied to non-pointer type\n", v->name); - } - - sizeless = FALSE; - if (arr) LIST_FOR_EACH_ENTRY_REV(dim, arr, expr_t, entry) - { - if (sizeless) - error("%s: only the first array dimension can be unspecified\n", v->name); - - if (dim->is_const) - { - unsigned int align = 0; - size_t size = type_memsize(v->type, &align); - - if (dim->cval <= 0) - error("%s: array dimension must be positive\n", v->name); - - if (0xffffffffuL / size < (unsigned long) dim->cval) - error("%s: total array size is too large\n", v->name); - else if (0xffffuL < size * dim->cval) - v->type = make_type(RPC_FC_LGFARRAY, v->type); - else - v->type = make_type(RPC_FC_SMFARRAY, v->type); - } - else - { - sizeless = TRUE; - v->type = make_type(RPC_FC_CARRAY, v->type); - } - - v->type->declarray = TRUE; - v->type->dim = dim->cval; - } - - ptype = &v->type; - has_varconf = FALSE; - if (sizes) LIST_FOR_EACH_ENTRY(dim, sizes, expr_t, entry) - { - if (dim->type != EXPR_VOID) - { - has_varconf = TRUE; - atype = *ptype = duptype(*ptype, 0); - - if (atype->type == RPC_FC_SMFARRAY || atype->type == RPC_FC_LGFARRAY) - error("%s: cannot specify size_is for a fixed sized array\n", v->name); - - if (atype->type != RPC_FC_CARRAY && !is_ptr(atype)) - error("%s: size_is attribute applied to illegal type\n", v->name); - - atype->type = RPC_FC_CARRAY; - atype->size_is = dim; - } - - ptype = &(*ptype)->ref; - if (*ptype == NULL) - error("%s: too many expressions in size_is attribute\n", v->name); - } - - ptype = &v->type; - if (lengs) LIST_FOR_EACH_ENTRY(dim, lengs, expr_t, entry) - { - if (dim->type != EXPR_VOID) - { - has_varconf = TRUE; - atype = *ptype = duptype(*ptype, 0); - - if (atype->type == RPC_FC_SMFARRAY) - atype->type = RPC_FC_SMVARRAY; - else if (atype->type == RPC_FC_LGFARRAY) - atype->type = RPC_FC_LGVARRAY; - else if (atype->type == RPC_FC_CARRAY) - atype->type = RPC_FC_CVARRAY; - else - error("%s: length_is attribute applied to illegal type\n", v->name); - - atype->length_is = dim; - } - - ptype = &(*ptype)->ref; - if (*ptype == NULL) - error("%s: too many expressions in length_is attribute\n", v->name); - } - - if (has_varconf && !last_array(v->type)) - { - ptype = &v->type; - for (ptype = &v->type; is_array(*ptype); ptype = &(*ptype)->ref) - { - *ptype = duptype(*ptype, 0); - (*ptype)->type = RPC_FC_BOGUS_ARRAY; - } - } - - if (is_array(v->type)) - { - const type_t *rt = v->type->ref; - if (is_user_type(rt)) - v->type->type = RPC_FC_BOGUS_ARRAY; - else - switch (rt->type) - { - case RPC_FC_BOGUS_STRUCT: - case RPC_FC_NON_ENCAPSULATED_UNION: - case RPC_FC_ENCAPSULATED_UNION: - case RPC_FC_ENUM16: - v->type->type = RPC_FC_BOGUS_ARRAY; - break; - /* FC_RP should be above, but widl overuses these, and will break things. */ - case RPC_FC_UP: - case RPC_FC_RP: - if (rt->ref->type == RPC_FC_IP) - v->type->type = RPC_FC_BOGUS_ARRAY; - break; - } - } -} - -static ifref_list_t *append_ifref(ifref_list_t *list, ifref_t *iface) -{ - if (!iface) return list; - if (!list) - { - list = xmalloc( sizeof(*list) ); - list_init( list ); - } - list_add_tail( list, &iface->entry ); - return list; -} - -static ifref_t *make_ifref(type_t *iface) -{ - ifref_t *l = xmalloc(sizeof(ifref_t)); - l->iface = iface; - l->attrs = NULL; - return l; -} - -static var_list_t *append_var(var_list_t *list, var_t *var) -{ - if (!var) return list; - if (!list) - { - list = xmalloc( sizeof(*list) ); - list_init( list ); - } - list_add_tail( list, &var->entry ); - return list; -} - -static var_t *make_var(char *name) -{ - var_t *v = xmalloc(sizeof(var_t)); - v->name = name; - v->type = NULL; - v->args = NULL; - v->attrs = NULL; - v->eval = NULL; - return v; -} - -static pident_list_t *append_pident(pident_list_t *list, pident_t *p) -{ - if (!p) return list; - if (!list) { - list = xmalloc(sizeof(*list)); - list_init(list); - } - list_add_tail(list, &p->entry); - return list; -} - -static pident_t *make_pident(var_t *var) -{ - pident_t *p = xmalloc(sizeof(*p)); - p->var = var; - p->ptr_level = 0; - return p; -} - -static func_list_t *append_func(func_list_t *list, func_t *func) -{ - if (!func) return list; - if (!list) - { - list = xmalloc( sizeof(*list) ); - list_init( list ); - } - list_add_tail( list, &func->entry ); - return list; -} - -static func_t *make_func(var_t *def, var_list_t *args) -{ - func_t *f = xmalloc(sizeof(func_t)); - f->def = def; - f->args = args; - f->ignore = parse_only; - f->idx = -1; - return f; -} - -static type_t *make_class(char *name) -{ - type_t *c = make_type(0, NULL); - c->name = name; - c->kind = TKIND_COCLASS; - return c; -} - -static type_t *make_safearray(type_t *type) -{ - type_t *sa = duptype(find_type("SAFEARRAY", 0), 1); - sa->ref = type; - return make_type(pointer_default, sa); -} - -#define HASHMAX 64 - -static int hash_ident(const char *name) -{ - const char *p = name; - int sum = 0; - /* a simple sum hash is probably good enough */ - while (*p) { - sum += *p; - p++; - } - return sum & (HASHMAX-1); -} - -/***** type repository *****/ - -struct rtype { - const char *name; - type_t *type; - int t; - struct rtype *next; -}; - -struct rtype *type_hash[HASHMAX]; - -static type_t *reg_type(type_t *type, const char *name, int t) -{ - struct rtype *nt; - int hash; - if (!name) { - error_loc("registering named type without name\n"); - return type; - } - hash = hash_ident(name); - nt = xmalloc(sizeof(struct rtype)); - nt->name = name; - nt->type = type; - nt->t = t; - nt->next = type_hash[hash]; - type_hash[hash] = nt; - return type; -} - -static int is_incomplete(const type_t *t) -{ - return !t->defined && (is_struct(t->type) || is_union(t->type)); -} - -static void add_incomplete(type_t *t) -{ - struct typenode *tn = xmalloc(sizeof *tn); - tn->type = t; - list_add_tail(&incomplete_types, &tn->entry); -} - -static void fix_type(type_t *t) -{ - if (t->kind == TKIND_ALIAS && is_incomplete(t)) { - type_t *ot = t->orig; - fix_type(ot); - t->fields = ot->fields; - t->defined = ot->defined; - } -} - -static void fix_incomplete(void) -{ - struct typenode *tn, *next; - - LIST_FOR_EACH_ENTRY_SAFE(tn, next, &incomplete_types, struct typenode, entry) { - fix_type(tn->type); - free(tn); - } -} - -static type_t *reg_typedefs(type_t *type, pident_list_t *pidents, attr_list_t *attrs) -{ - type_t *ptr = type; - const pident_t *pident; - int ptrc = 0; - int is_str = is_attr(attrs, ATTR_STRING); - unsigned char ptr_type = get_attrv(attrs, ATTR_POINTERTYPE); - - if (is_str) - { - type_t *t = type; - unsigned char c; - - while (is_ptr(t)) - t = t->ref; - - c = t->type; - if (c != RPC_FC_CHAR && c != RPC_FC_BYTE && c != RPC_FC_WCHAR) - { - pident = LIST_ENTRY( list_head( pidents ), const pident_t, entry ); - error_loc("'%s': [string] attribute is only valid on 'char', 'byte', or 'wchar_t' pointers and arrays\n", - pident->var->name); - } - } - - /* We must generate names for tagless enum, struct or union. - Typedef-ing a tagless enum, struct or union means we want the typedef - to be included in a library whether it has other attributes or not, - hence the public attribute. */ - if ((type->kind == TKIND_ENUM || type->kind == TKIND_RECORD - || type->kind == TKIND_UNION) && ! type->name && ! parse_only) - { - if (! is_attr(attrs, ATTR_PUBLIC)) - attrs = append_attr( attrs, make_attr(ATTR_PUBLIC) ); - type->name = gen_name(); - } - - LIST_FOR_EACH_ENTRY( pident, pidents, const pident_t, entry ) - { - var_t *name = pident->var; - - if (name->name) { - type_t *cur = ptr; - int cptr = pident->ptr_level; - if (cptr > ptrc) { - while (cptr > ptrc) { - cur = ptr = make_type(pointer_default, cur); - ptrc++; - } - } else { - while (cptr < ptrc) { - cur = cur->ref; - cptr++; - } - } - cur = alias(cur, name->name); - cur->attrs = attrs; - if (ptr_type) - { - if (is_ptr(cur)) - cur->type = ptr_type; - else - error_loc("'%s': pointer attribute applied to non-pointer type\n", - cur->name); - } - else if (is_str && ! is_ptr(cur)) - error_loc("'%s': [string] attribute applied to non-pointer type\n", - cur->name); - - if (is_incomplete(cur)) - add_incomplete(cur); - reg_type(cur, cur->name, 0); - } - } - return type; -} - -static type_t *find_type(const char *name, int t) -{ - struct rtype *cur = type_hash[hash_ident(name)]; - while (cur && (cur->t != t || strcmp(cur->name, name))) - cur = cur->next; - if (!cur) { - error_loc("type '%s' not found\n", name); - return NULL; - } - return cur->type; -} - -static type_t *find_type2(char *name, int t) -{ - type_t *tp = find_type(name, t); - free(name); - return tp; -} - -int is_type(const char *name) -{ - struct rtype *cur = type_hash[hash_ident(name)]; - while (cur && (cur->t || strcmp(cur->name, name))) - cur = cur->next; - if (cur) return TRUE; - return FALSE; -} - -static type_t *get_type(unsigned char type, char *name, int t) -{ - struct rtype *cur = NULL; - type_t *tp; - if (name) { - cur = type_hash[hash_ident(name)]; - while (cur && (cur->t != t || strcmp(cur->name, name))) - cur = cur->next; - } - if (cur) { - free(name); - return cur->type; - } - tp = make_type(type, NULL); - tp->name = name; - if (!name) return tp; - return reg_type(tp, name, t); -} - -static type_t *get_typev(unsigned char type, var_t *name, int t) -{ - char *sname = NULL; - if (name) { - sname = name->name; - free(name); - } - return get_type(type, sname, t); -} - -static int get_struct_type(var_list_t *fields) -{ - int has_pointer = 0; - int has_conformance = 0; - int has_variance = 0; - var_t *field; - - if (get_padding(fields)) - return RPC_FC_BOGUS_STRUCT; - - if (fields) LIST_FOR_EACH_ENTRY( field, fields, var_t, entry ) - { - type_t *t = field->type; - - if (is_user_type(t)) - return RPC_FC_BOGUS_STRUCT; - - if (is_ptr(t)) - { - do - t = t->ref; - while (is_ptr(t)); - - switch (t->type) - { - case RPC_FC_IP: - case RPC_FC_ENCAPSULATED_UNION: - case RPC_FC_NON_ENCAPSULATED_UNION: - case RPC_FC_BOGUS_STRUCT: - return RPC_FC_BOGUS_STRUCT; - } - - has_pointer = 1; - continue; - } - - if (field->type->declarray) - { - if (is_string_type(field->attrs, field->type)) - { - if (is_conformant_array(field->type)) - has_conformance = 1; - has_variance = 1; - continue; - } - - if (is_array(field->type->ref)) - return RPC_FC_BOGUS_STRUCT; - - if (is_conformant_array(field->type)) - { - has_conformance = 1; - if (field->type->declarray && list_next(fields, &field->entry)) - error_loc("field '%s' deriving from a conformant array must be the last field in the structure\n", - field->name); - } - if (field->type->length_is) - has_variance = 1; - - t = field->type->ref; - } - - switch (t->type) - { - /* - * RPC_FC_BYTE, RPC_FC_STRUCT, etc - * Simple types don't effect the type of struct. - * A struct containing a simple struct is still a simple struct. - * So long as we can block copy the data, we return RPC_FC_STRUCT. - */ - case 0: /* void pointer */ - case RPC_FC_BYTE: - case RPC_FC_CHAR: - case RPC_FC_SMALL: - case RPC_FC_USMALL: - case RPC_FC_WCHAR: - case RPC_FC_SHORT: - case RPC_FC_USHORT: - case RPC_FC_LONG: - case RPC_FC_ULONG: - case RPC_FC_INT3264: - case RPC_FC_UINT3264: - case RPC_FC_HYPER: - case RPC_FC_FLOAT: - case RPC_FC_DOUBLE: - case RPC_FC_STRUCT: - case RPC_FC_ENUM16: - case RPC_FC_ENUM32: - break; - - case RPC_FC_RP: - case RPC_FC_UP: - case RPC_FC_FP: - case RPC_FC_OP: - case RPC_FC_CARRAY: - case RPC_FC_CVARRAY: - case RPC_FC_BOGUS_ARRAY: - has_pointer = 1; - break; - - /* - * Propagate member attributes - * a struct should be at least as complex as its member - */ - case RPC_FC_CVSTRUCT: - has_conformance = 1; - has_variance = 1; - has_pointer = 1; - break; - - case RPC_FC_CPSTRUCT: - has_conformance = 1; - if (list_next( fields, &field->entry )) - error_loc("field '%s' deriving from a conformant array must be the last field in the structure\n", - field->name); - has_pointer = 1; - break; - - case RPC_FC_CSTRUCT: - has_conformance = 1; - if (list_next( fields, &field->entry )) - error_loc("field '%s' deriving from a conformant array must be the last field in the structure\n", - field->name); - break; - - case RPC_FC_PSTRUCT: - has_pointer = 1; - break; - - default: - error_loc("Unknown struct member %s with type (0x%02x)\n", field->name, t->type); - /* fallthru - treat it as complex */ - - /* as soon as we see one of these these members, it's bogus... */ - case RPC_FC_ENCAPSULATED_UNION: - case RPC_FC_NON_ENCAPSULATED_UNION: - case RPC_FC_BOGUS_STRUCT: - return RPC_FC_BOGUS_STRUCT; - } - } - - if( has_variance ) - { - if ( has_conformance ) - return RPC_FC_CVSTRUCT; - else - return RPC_FC_BOGUS_STRUCT; - } - if( has_conformance && has_pointer ) - return RPC_FC_CPSTRUCT; - if( has_conformance ) - return RPC_FC_CSTRUCT; - if( has_pointer ) - return RPC_FC_PSTRUCT; - return RPC_FC_STRUCT; -} - -/***** constant repository *****/ - -struct rconst { - char *name; - var_t *var; - struct rconst *next; -}; - -struct rconst *const_hash[HASHMAX]; - -static var_t *reg_const(var_t *var) -{ - struct rconst *nc; - int hash; - if (!var->name) { - error_loc("registering constant without name\n"); - return var; - } - hash = hash_ident(var->name); - nc = xmalloc(sizeof(struct rconst)); - nc->name = var->name; - nc->var = var; - nc->next = const_hash[hash]; - const_hash[hash] = nc; - return var; -} - -static var_t *find_const(char *name, int f) -{ - struct rconst *cur = const_hash[hash_ident(name)]; - while (cur && strcmp(cur->name, name)) - cur = cur->next; - if (!cur) { - if (f) error_loc("constant '%s' not found\n", name); - return NULL; - } - return cur->var; -} - -static void write_libid(const char *name, const attr_list_t *attr) -{ - const UUID *uuid = get_attrp(attr, ATTR_UUID); - write_guid(idfile, "LIBID", name, uuid); -} - -static void write_clsid(type_t *cls) -{ - const UUID *uuid = get_attrp(cls->attrs, ATTR_UUID); - write_guid(idfile, "CLSID", cls->name, uuid); -} - -static void write_diid(type_t *iface) -{ - const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID); - write_guid(idfile, "DIID", iface->name, uuid); -} - -static void write_iid(type_t *iface) -{ - const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID); - write_guid(idfile, "IID", iface->name, uuid); -} - -static int compute_method_indexes(type_t *iface) -{ - int idx; - func_t *f; - - if (iface->ref) - idx = compute_method_indexes(iface->ref); - else - idx = 0; - - if (!iface->funcs) - return idx; - - LIST_FOR_EACH_ENTRY( f, iface->funcs, func_t, entry ) - if (! is_callas(f->def->attrs)) - f->idx = idx++; - - return idx; -} - -static char *gen_name(void) -{ - static const char format[] = "__WIDL_%s_generated_name_%08lX"; - static unsigned long n = 0; - static const char *file_id; - static size_t size; - char *name; - - if (! file_id) - { - char *dst = dup_basename(input_name, ".idl"); - file_id = dst; - - for (; *dst; ++dst) - if (! isalnum((unsigned char) *dst)) - *dst = '_'; - - size = sizeof format - 7 + strlen(file_id) + 8; - } - - name = xmalloc(size); - sprintf(name, format, file_id, n++); - return name; -} - -static void process_typedefs(pident_list_t *pidents) -{ - pident_t *pident, *next; - - if (!pidents) return; - LIST_FOR_EACH_ENTRY_SAFE( pident, next, pidents, pident_t, entry ) - { - var_t *var = pident->var; - type_t *type = find_type(var->name, 0); - - if (! parse_only && do_header) - write_typedef(type); - if (in_typelib && type->attrs) - add_typelib_entry(type); - - free(pident); - free(var); - } -} - -static void check_arg(var_t *arg) -{ - type_t *t = arg->type; - - if (t->type == 0 && ! is_var_ptr(arg)) - error_loc("argument '%s' has void type\n", arg->name); -} - -static void check_all_user_types(ifref_list_t *ifrefs) -{ - const ifref_t *ifref; - const func_t *f; - - if (ifrefs) LIST_FOR_EACH_ENTRY(ifref, ifrefs, const ifref_t, entry) - { - const func_list_t *fs = ifref->iface->funcs; - if (fs) LIST_FOR_EACH_ENTRY(f, fs, const func_t, entry) - check_for_user_types_and_context_handles(f->args); - } -} - -int is_valid_uuid(const char *s) -{ - int i; - - for (i = 0; i < 36; ++i) - if (i == 8 || i == 13 || i == 18 || i == 23) - { - if (s[i] != '-') - return FALSE; - } - else - if (!isxdigit(s[i])) - return FALSE; - - return s[i] == '\0'; -} - diff --git a/reactos/tools/widl_20080105/parser.tab.h b/reactos/tools/widl_20080105/parser.tab.h deleted file mode 100644 index 33694501d63..00000000000 --- a/reactos/tools/widl_20080105/parser.tab.h +++ /dev/null @@ -1,339 +0,0 @@ -/* A Bison parser, made by GNU Bison 2.1. */ - -/* Skeleton parser for Yacc-like parsing with Bison, - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ - -/* As a special exception, when this file is copied by Bison into a - Bison output file, you may use that output file without restriction. - This special exception was added by the Free Software Foundation - in version 1.24 of Bison. */ - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - aIDENTIFIER = 258, - aKNOWNTYPE = 259, - aNUM = 260, - aHEXNUM = 261, - aDOUBLE = 262, - aSTRING = 263, - aUUID = 264, - aEOF = 265, - SHL = 266, - SHR = 267, - tAGGREGATABLE = 268, - tALLOCATE = 269, - tAPPOBJECT = 270, - tASYNC = 271, - tASYNCUUID = 272, - tAUTOHANDLE = 273, - tBINDABLE = 274, - tBOOLEAN = 275, - tBROADCAST = 276, - tBYTE = 277, - tBYTECOUNT = 278, - tCALLAS = 279, - tCALLBACK = 280, - tCASE = 281, - tCDECL = 282, - tCHAR = 283, - tCOCLASS = 284, - tCODE = 285, - tCOMMSTATUS = 286, - tCONST = 287, - tCONTEXTHANDLE = 288, - tCONTEXTHANDLENOSERIALIZE = 289, - tCONTEXTHANDLESERIALIZE = 290, - tCONTROL = 291, - tCPPQUOTE = 292, - tDEFAULT = 293, - tDEFAULTCOLLELEM = 294, - tDEFAULTVALUE = 295, - tDEFAULTVTABLE = 296, - tDISPLAYBIND = 297, - tDISPINTERFACE = 298, - tDLLNAME = 299, - tDOUBLE = 300, - tDUAL = 301, - tENDPOINT = 302, - tENTRY = 303, - tENUM = 304, - tERRORSTATUST = 305, - tEXPLICITHANDLE = 306, - tEXTERN = 307, - tFALSE = 308, - tFLOAT = 309, - tHANDLE = 310, - tHANDLET = 311, - tHELPCONTEXT = 312, - tHELPFILE = 313, - tHELPSTRING = 314, - tHELPSTRINGCONTEXT = 315, - tHELPSTRINGDLL = 316, - tHIDDEN = 317, - tHYPER = 318, - tID = 319, - tIDEMPOTENT = 320, - tIIDIS = 321, - tIMMEDIATEBIND = 322, - tIMPLICITHANDLE = 323, - tIMPORT = 324, - tIMPORTLIB = 325, - tIN = 326, - tINLINE = 327, - tINPUTSYNC = 328, - tINT = 329, - tINT64 = 330, - tINTERFACE = 331, - tLCID = 332, - tLENGTHIS = 333, - tLIBRARY = 334, - tLOCAL = 335, - tLONG = 336, - tMETHODS = 337, - tMODULE = 338, - tNONBROWSABLE = 339, - tNONCREATABLE = 340, - tNONEXTENSIBLE = 341, - tOBJECT = 342, - tODL = 343, - tOLEAUTOMATION = 344, - tOPTIONAL = 345, - tOUT = 346, - tPOINTERDEFAULT = 347, - tPROPERTIES = 348, - tPROPGET = 349, - tPROPPUT = 350, - tPROPPUTREF = 351, - tPTR = 352, - tPUBLIC = 353, - tRANGE = 354, - tREADONLY = 355, - tREF = 356, - tREQUESTEDIT = 357, - tRESTRICTED = 358, - tRETVAL = 359, - tSAFEARRAY = 360, - tSHORT = 361, - tSIGNED = 362, - tSINGLE = 363, - tSIZEIS = 364, - tSIZEOF = 365, - tSMALL = 366, - tSOURCE = 367, - tSTDCALL = 368, - tSTRING = 369, - tSTRUCT = 370, - tSWITCH = 371, - tSWITCHIS = 372, - tSWITCHTYPE = 373, - tTRANSMITAS = 374, - tTRUE = 375, - tTYPEDEF = 376, - tUNION = 377, - tUNIQUE = 378, - tUNSIGNED = 379, - tUUID = 380, - tV1ENUM = 381, - tVARARG = 382, - tVERSION = 383, - tVOID = 384, - tWCHAR = 385, - tWIREMARSHAL = 386, - CAST = 387, - PPTR = 388, - NEG = 389, - ADDRESSOF = 390 - }; -#endif -/* Tokens. */ -#define aIDENTIFIER 258 -#define aKNOWNTYPE 259 -#define aNUM 260 -#define aHEXNUM 261 -#define aDOUBLE 262 -#define aSTRING 263 -#define aUUID 264 -#define aEOF 265 -#define SHL 266 -#define SHR 267 -#define tAGGREGATABLE 268 -#define tALLOCATE 269 -#define tAPPOBJECT 270 -#define tASYNC 271 -#define tASYNCUUID 272 -#define tAUTOHANDLE 273 -#define tBINDABLE 274 -#define tBOOLEAN 275 -#define tBROADCAST 276 -#define tBYTE 277 -#define tBYTECOUNT 278 -#define tCALLAS 279 -#define tCALLBACK 280 -#define tCASE 281 -#define tCDECL 282 -#define tCHAR 283 -#define tCOCLASS 284 -#define tCODE 285 -#define tCOMMSTATUS 286 -#define tCONST 287 -#define tCONTEXTHANDLE 288 -#define tCONTEXTHANDLENOSERIALIZE 289 -#define tCONTEXTHANDLESERIALIZE 290 -#define tCONTROL 291 -#define tCPPQUOTE 292 -#define tDEFAULT 293 -#define tDEFAULTCOLLELEM 294 -#define tDEFAULTVALUE 295 -#define tDEFAULTVTABLE 296 -#define tDISPLAYBIND 297 -#define tDISPINTERFACE 298 -#define tDLLNAME 299 -#define tDOUBLE 300 -#define tDUAL 301 -#define tENDPOINT 302 -#define tENTRY 303 -#define tENUM 304 -#define tERRORSTATUST 305 -#define tEXPLICITHANDLE 306 -#define tEXTERN 307 -#define tFALSE 308 -#define tFLOAT 309 -#define tHANDLE 310 -#define tHANDLET 311 -#define tHELPCONTEXT 312 -#define tHELPFILE 313 -#define tHELPSTRING 314 -#define tHELPSTRINGCONTEXT 315 -#define tHELPSTRINGDLL 316 -#define tHIDDEN 317 -#define tHYPER 318 -#define tID 319 -#define tIDEMPOTENT 320 -#define tIIDIS 321 -#define tIMMEDIATEBIND 322 -#define tIMPLICITHANDLE 323 -#define tIMPORT 324 -#define tIMPORTLIB 325 -#define tIN 326 -#define tINLINE 327 -#define tINPUTSYNC 328 -#define tINT 329 -#define tINT64 330 -#define tINTERFACE 331 -#define tLCID 332 -#define tLENGTHIS 333 -#define tLIBRARY 334 -#define tLOCAL 335 -#define tLONG 336 -#define tMETHODS 337 -#define tMODULE 338 -#define tNONBROWSABLE 339 -#define tNONCREATABLE 340 -#define tNONEXTENSIBLE 341 -#define tOBJECT 342 -#define tODL 343 -#define tOLEAUTOMATION 344 -#define tOPTIONAL 345 -#define tOUT 346 -#define tPOINTERDEFAULT 347 -#define tPROPERTIES 348 -#define tPROPGET 349 -#define tPROPPUT 350 -#define tPROPPUTREF 351 -#define tPTR 352 -#define tPUBLIC 353 -#define tRANGE 354 -#define tREADONLY 355 -#define tREF 356 -#define tREQUESTEDIT 357 -#define tRESTRICTED 358 -#define tRETVAL 359 -#define tSAFEARRAY 360 -#define tSHORT 361 -#define tSIGNED 362 -#define tSINGLE 363 -#define tSIZEIS 364 -#define tSIZEOF 365 -#define tSMALL 366 -#define tSOURCE 367 -#define tSTDCALL 368 -#define tSTRING 369 -#define tSTRUCT 370 -#define tSWITCH 371 -#define tSWITCHIS 372 -#define tSWITCHTYPE 373 -#define tTRANSMITAS 374 -#define tTRUE 375 -#define tTYPEDEF 376 -#define tUNION 377 -#define tUNIQUE 378 -#define tUNSIGNED 379 -#define tUUID 380 -#define tV1ENUM 381 -#define tVARARG 382 -#define tVERSION 383 -#define tVOID 384 -#define tWCHAR 385 -#define tWIREMARSHAL 386 -#define CAST 387 -#define PPTR 388 -#define NEG 389 -#define ADDRESSOF 390 - - - - -#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) -#line 136 "parser.y" -typedef union YYSTYPE { - attr_t *attr; - attr_list_t *attr_list; - str_list_t *str_list; - expr_t *expr; - expr_list_t *expr_list; - array_dims_t *array_dims; - type_t *type; - var_t *var; - var_list_t *var_list; - pident_t *pident; - pident_list_t *pident_list; - func_t *func; - func_list_t *func_list; - ifref_t *ifref; - ifref_list_t *ifref_list; - char *str; - UUID *uuid; - unsigned int num; - double dbl; - interface_info_t ifinfo; -} YYSTYPE; -/* Line 1447 of yacc.c. */ -#line 331 "parser.tab.h" -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 -#endif - -extern YYSTYPE parser_lval; - - - diff --git a/reactos/tools/widl_20080105/parser.y b/reactos/tools/widl_20080105/parser.y deleted file mode 100644 index 6c8337efefc..00000000000 --- a/reactos/tools/widl_20080105/parser.y +++ /dev/null @@ -1,2091 +0,0 @@ -%{ -/* - * IDL Compiler - * - * Copyright 2002 Ove Kaaven - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" - -#include -#include -#include -#include -#include -#include -#ifdef HAVE_ALLOCA_H -#include -#endif - -#include "widl.h" -#include "utils.h" -#include "parser.h" -#include "header.h" -#include "typelib.h" -#include "typegen.h" - -#if defined(YYBYACC) - /* Berkeley yacc (byacc) doesn't seem to know about these */ - /* Some *BSD supplied versions do define these though */ -# ifndef YYEMPTY -# define YYEMPTY (-1) /* Empty lookahead value of yychar */ -# endif -# ifndef YYLEX -# define YYLEX yylex() -# endif - -#elif defined(YYBISON) - /* Bison was used for original development */ - /* #define YYEMPTY -2 */ - /* #define YYLEX yylex() */ - -#else - /* No yacc we know yet */ -# if !defined(YYEMPTY) || !defined(YYLEX) -# error Yacc version/type unknown. This version needs to be verified for settings of YYEMPTY and YYLEX. -# elif defined(__GNUC__) /* gcc defines the #warning directive */ -# warning Yacc version/type unknown. It defines YYEMPTY and YYLEX, but is not tested - /* #else we just take a chance that it works... */ -# endif -#endif - -unsigned char pointer_default = RPC_FC_UP; - -typedef struct list typelist_t; -struct typenode { - type_t *type; - struct list entry; -}; - -typelist_t incomplete_types = LIST_INIT(incomplete_types); - -static void add_incomplete(type_t *t); -static void fix_incomplete(void); - -static str_list_t *append_str(str_list_t *list, char *str); -static attr_list_t *append_attr(attr_list_t *list, attr_t *attr); -static attr_t *make_attr(enum attr_type type); -static attr_t *make_attrv(enum attr_type type, unsigned long val); -static attr_t *make_attrp(enum attr_type type, void *val); -static expr_t *make_expr(enum expr_type type); -static expr_t *make_exprl(enum expr_type type, long val); -static expr_t *make_exprd(enum expr_type type, double val); -static expr_t *make_exprs(enum expr_type type, char *val); -static expr_t *make_exprt(enum expr_type type, type_t *tref, expr_t *expr); -static expr_t *make_expr1(enum expr_type type, expr_t *expr); -static expr_t *make_expr2(enum expr_type type, expr_t *exp1, expr_t *exp2); -static expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, expr_t *expr3); -static type_t *make_type(unsigned char type, type_t *ref); -static expr_list_t *append_expr(expr_list_t *list, expr_t *expr); -static array_dims_t *append_array(array_dims_t *list, expr_t *expr); -static void set_type(var_t *v, type_t *type, int ptr_level, array_dims_t *arr, int top); -static ifref_list_t *append_ifref(ifref_list_t *list, ifref_t *iface); -static ifref_t *make_ifref(type_t *iface); -static var_list_t *append_var(var_list_t *list, var_t *var); -static var_t *make_var(char *name); -static pident_list_t *append_pident(pident_list_t *list, pident_t *p); -static pident_t *make_pident(var_t *var); -static func_list_t *append_func(func_list_t *list, func_t *func); -static func_t *make_func(var_t *def, var_list_t *args); -static type_t *make_class(char *name); -static type_t *make_safearray(type_t *type); -static type_t *make_builtin(char *name); -static type_t *make_int(int sign); - -static type_t *reg_type(type_t *type, const char *name, int t); -static type_t *reg_typedefs(type_t *type, var_list_t *names, attr_list_t *attrs); -static type_t *find_type(const char *name, int t); -static type_t *find_type2(char *name, int t); -static type_t *get_type(unsigned char type, char *name, int t); -static type_t *get_typev(unsigned char type, var_t *name, int t); -static int get_struct_type(var_list_t *fields); - -static var_t *reg_const(var_t *var); -static var_t *find_const(char *name, int f); - -static void write_libid(const char *name, const attr_list_t *attr); -static void write_clsid(type_t *cls); -static void write_diid(type_t *iface); -static void write_iid(type_t *iface); - -static int compute_method_indexes(type_t *iface); -static char *gen_name(void); -static void process_typedefs(var_list_t *names); -static void check_arg(var_t *arg); -static void check_all_user_types(ifref_list_t *ifaces); - -#define tsENUM 1 -#define tsSTRUCT 2 -#define tsUNION 3 - -%} -%union { - attr_t *attr; - attr_list_t *attr_list; - str_list_t *str_list; - expr_t *expr; - expr_list_t *expr_list; - array_dims_t *array_dims; - type_t *type; - var_t *var; - var_list_t *var_list; - pident_t *pident; - pident_list_t *pident_list; - func_t *func; - func_list_t *func_list; - ifref_t *ifref; - ifref_list_t *ifref_list; - char *str; - UUID *uuid; - unsigned int num; - double dbl; - interface_info_t ifinfo; -} - -%token aIDENTIFIER -%token aKNOWNTYPE -%token aNUM aHEXNUM -%token aDOUBLE -%token aSTRING -%token aUUID -%token aEOF -%token SHL SHR -%token tAGGREGATABLE tALLOCATE tAPPOBJECT tASYNC tASYNCUUID -%token tAUTOHANDLE tBINDABLE tBOOLEAN tBROADCAST tBYTE tBYTECOUNT -%token tCALLAS tCALLBACK tCASE tCDECL tCHAR tCOCLASS tCODE tCOMMSTATUS -%token tCONST tCONTEXTHANDLE tCONTEXTHANDLENOSERIALIZE -%token tCONTEXTHANDLESERIALIZE tCONTROL tCPPQUOTE -%token tDEFAULT -%token tDEFAULTCOLLELEM -%token tDEFAULTVALUE -%token tDEFAULTVTABLE -%token tDISPLAYBIND -%token tDISPINTERFACE -%token tDLLNAME tDOUBLE tDUAL -%token tENDPOINT -%token tENTRY tENUM tERRORSTATUST -%token tEXPLICITHANDLE tEXTERN -%token tFALSE -%token tFLOAT -%token tHANDLE -%token tHANDLET -%token tHELPCONTEXT tHELPFILE -%token tHELPSTRING tHELPSTRINGCONTEXT tHELPSTRINGDLL -%token tHIDDEN -%token tHYPER tID tIDEMPOTENT -%token tIIDIS -%token tIMMEDIATEBIND -%token tIMPLICITHANDLE -%token tIMPORT tIMPORTLIB -%token tIN tINLINE -%token tINPUTSYNC -%token tINT tINT64 -%token tINTERFACE -%token tLCID -%token tLENGTHIS tLIBRARY -%token tLOCAL -%token tLONG -%token tMETHODS -%token tMODULE -%token tNONBROWSABLE -%token tNONCREATABLE -%token tNONEXTENSIBLE -%token tOBJECT tODL tOLEAUTOMATION -%token tOPTIONAL -%token tOUT -%token tPOINTERDEFAULT -%token tPROPERTIES -%token tPROPGET tPROPPUT tPROPPUTREF -%token tPTR -%token tPUBLIC -%token tRANGE -%token tREADONLY tREF -%token tREQUESTEDIT -%token tRESTRICTED -%token tRETVAL -%token tSAFEARRAY -%token tSHORT -%token tSIGNED -%token tSINGLE -%token tSIZEIS tSIZEOF -%token tSMALL -%token tSOURCE -%token tSTDCALL -%token tSTRING tSTRUCT -%token tSWITCH tSWITCHIS tSWITCHTYPE -%token tTRANSMITAS -%token tTRUE -%token tTYPEDEF -%token tUNION -%token tUNIQUE -%token tUNSIGNED -%token tUUID -%token tV1ENUM -%token tVARARG -%token tVERSION -%token tVOID -%token tWCHAR tWIREMARSHAL - -%type attribute -%type m_attributes attributes attrib_list -%type str_list -%type m_expr expr expr_const -%type m_exprs /* exprs expr_list */ expr_list_const -%type array array_list -%type interfacehdr -%type inherit interface interfacedef interfacedec -%type dispinterface dispinterfacehdr dispinterfacedef -%type module modulehdr moduledef -%type base_type int_std -%type enumdef structdef uniondef -%type type -%type coclass_int -%type gbl_statements coclass_ints -%type arg field s_field case enum constdef externdef -%type m_args no_args args fields cases enums enum_list dispint_props -%type m_ident t_ident ident -%type p_ident pident -%type pident_list -%type funcdef -%type int_statements dispint_meths -%type coclass coclasshdr coclassdef -%type pointer_type version -%type libraryhdr -%type uuid_string - -%left ',' -%right '?' ':' -%left '|' -%left '&' -%left '-' '+' -%left '*' '/' -%left SHL SHR -%right '~' -%right CAST -%right PPTR -%right NEG -%right ADDRESSOF - -%% - -input: gbl_statements { fix_incomplete(); - check_all_user_types($1); - write_proxies($1); - write_client($1); - write_server($1); - write_dlldata($1); - } - ; - -gbl_statements: { $$ = NULL; } - | gbl_statements interfacedec { $$ = $1; } - | gbl_statements interfacedef { $$ = append_ifref( $1, make_ifref($2) ); } - | gbl_statements coclass ';' { $$ = $1; - reg_type($2, $2->name, 0); - if (!parse_only && do_header) write_coclass_forward($2); - } - | gbl_statements coclassdef { $$ = $1; - add_typelib_entry($2); - reg_type($2, $2->name, 0); - if (!parse_only && do_header) write_coclass_forward($2); - } - | gbl_statements moduledef { $$ = $1; add_typelib_entry($2); } - | gbl_statements librarydef { $$ = $1; } - | gbl_statements statement { $$ = $1; } - ; - -imp_statements: {} - | imp_statements interfacedec { if (!parse_only) add_typelib_entry($2); } - | imp_statements interfacedef { if (!parse_only) add_typelib_entry($2); } - | imp_statements coclass ';' { reg_type($2, $2->name, 0); if (!parse_only && do_header) write_coclass_forward($2); } - | imp_statements coclassdef { if (!parse_only) add_typelib_entry($2); - reg_type($2, $2->name, 0); - if (!parse_only && do_header) write_coclass_forward($2); - } - | imp_statements moduledef { if (!parse_only) add_typelib_entry($2); } - | imp_statements statement {} - | imp_statements importlib {} - ; - -int_statements: { $$ = NULL; } - | int_statements funcdef ';' { $$ = append_func( $1, $2 ); } - | int_statements statement { $$ = $1; } - ; - -statement: ';' {} - | constdef ';' { if (!parse_only && do_header) { write_constdef($1); } } - | cppquote {} - | enumdef ';' { if (!parse_only && do_header) { - write_type_def_or_decl(header, $1, FALSE, NULL); - fprintf(header, ";\n\n"); - } - } - | externdef ';' { if (!parse_only && do_header) { write_externdef($1); } } - | import {} - | structdef ';' { if (!parse_only && do_header) { - write_type_def_or_decl(header, $1, FALSE, NULL); - fprintf(header, ";\n\n"); - } - } - | typedef ';' {} - | uniondef ';' { if (!parse_only && do_header) { - write_type_def_or_decl(header, $1, FALSE, NULL); - fprintf(header, ";\n\n"); - } - } - ; - -cppquote: tCPPQUOTE '(' aSTRING ')' { if (!parse_only && do_header) fprintf(header, "%s\n", $3); } - ; -import_start: tIMPORT aSTRING ';' { assert(yychar == YYEMPTY); - if (!do_import($2)) yychar = aEOF; } - ; -import: import_start imp_statements aEOF {} - ; - -importlib: tIMPORTLIB '(' aSTRING ')' { if(!parse_only) add_importlib($3); } - ; - -libraryhdr: tLIBRARY aIDENTIFIER { $$ = $2; } - ; -library_start: attributes libraryhdr '{' { start_typelib($2, $1); - if (!parse_only && do_header) write_library($2, $1); - if (!parse_only && do_idfile) write_libid($2, $1); - } - ; -librarydef: library_start imp_statements '}' { end_typelib(); } - ; - -m_args: { $$ = NULL; } - | args - ; - -no_args: tVOID { $$ = NULL; } - ; - -args: arg { check_arg($1); $$ = append_var( NULL, $1 ); } - | args ',' arg { check_arg($3); $$ = append_var( $1, $3); } - | no_args - ; - -/* split into two rules to get bison to resolve a tVOID conflict */ -arg: attributes type pident array { $$ = $3->var; - $$->attrs = $1; - set_type($$, $2, $3->ptr_level, $4, TRUE); - free($3); - } - | type pident array { $$ = $2->var; - set_type($$, $1, $2->ptr_level, $3, TRUE); - free($2); - } - | attributes type pident '(' m_args ')' { $$ = $3->var; - $$->attrs = $1; - set_type($$, $2, $3->ptr_level - 1, NULL, TRUE); - free($3); - $$->args = $5; - } - | type pident '(' m_args ')' { $$ = $2->var; - set_type($$, $1, $2->ptr_level - 1, NULL, TRUE); - free($2); - $$->args = $4; - } - ; - -array: { $$ = NULL; } - | '[' array_list ']' { $$ = $2; } - | '[' '*' ']' { $$ = append_array( NULL, make_expr(EXPR_VOID) ); } - ; - -array_list: m_expr /* size of first dimension is optional */ { $$ = append_array( NULL, $1 ); } - | array_list ',' expr { $$ = append_array( $1, $3 ); } - | array_list ']' '[' expr { $$ = append_array( $1, $4 ); } - ; - -m_attributes: { $$ = NULL; } - | attributes - ; - -attributes: - '[' attrib_list ']' { $$ = $2; - if (!$$) - error_loc("empty attribute lists unsupported\n"); - } - ; - -attrib_list: attribute { $$ = append_attr( NULL, $1 ); } - | attrib_list ',' attribute { $$ = append_attr( $1, $3 ); } - | attrib_list ']' '[' attribute { $$ = append_attr( $1, $4 ); } - ; - -str_list: aSTRING { $$ = append_str( NULL, $1 ); } - | str_list ',' aSTRING { $$ = append_str( $1, $3 ); } - ; - -attribute: { $$ = NULL; } - | tAGGREGATABLE { $$ = make_attr(ATTR_AGGREGATABLE); } - | tAPPOBJECT { $$ = make_attr(ATTR_APPOBJECT); } - | tASYNC { $$ = make_attr(ATTR_ASYNC); } - | tAUTOHANDLE { $$ = make_attr(ATTR_AUTO_HANDLE); } - | tBINDABLE { $$ = make_attr(ATTR_BINDABLE); } - | tCALLAS '(' ident ')' { $$ = make_attrp(ATTR_CALLAS, $3); } - | tCASE '(' expr_list_const ')' { $$ = make_attrp(ATTR_CASE, $3); } - | tCONTEXTHANDLE { $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); } - | tCONTEXTHANDLENOSERIALIZE { $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_DONT_SERIALIZE */ } - | tCONTEXTHANDLESERIALIZE { $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_SERIALIZE */ } - | tCONTROL { $$ = make_attr(ATTR_CONTROL); } - | tDEFAULT { $$ = make_attr(ATTR_DEFAULT); } - | tDEFAULTCOLLELEM { $$ = make_attr(ATTR_DEFAULTCOLLELEM); } - | tDEFAULTVALUE '(' expr_const ')' { $$ = make_attrp(ATTR_DEFAULTVALUE_EXPR, $3); } - | tDEFAULTVALUE '(' aSTRING ')' { $$ = make_attrp(ATTR_DEFAULTVALUE_STRING, $3); } - | tDEFAULTVTABLE { $$ = make_attr(ATTR_DEFAULTVTABLE); } - | tDISPLAYBIND { $$ = make_attr(ATTR_DISPLAYBIND); } - | tDLLNAME '(' aSTRING ')' { $$ = make_attrp(ATTR_DLLNAME, $3); } - | tDUAL { $$ = make_attr(ATTR_DUAL); } - | tENDPOINT '(' str_list ')' { $$ = make_attrp(ATTR_ENDPOINT, $3); } - | tENTRY '(' aSTRING ')' { $$ = make_attrp(ATTR_ENTRY_STRING, $3); } - | tENTRY '(' expr_const ')' { $$ = make_attrp(ATTR_ENTRY_ORDINAL, $3); } - | tEXPLICITHANDLE { $$ = make_attr(ATTR_EXPLICIT_HANDLE); } - | tHANDLE { $$ = make_attr(ATTR_HANDLE); } - | tHELPCONTEXT '(' expr_const ')' { $$ = make_attrp(ATTR_HELPCONTEXT, $3); } - | tHELPFILE '(' aSTRING ')' { $$ = make_attrp(ATTR_HELPFILE, $3); } - | tHELPSTRING '(' aSTRING ')' { $$ = make_attrp(ATTR_HELPSTRING, $3); } - | tHELPSTRINGCONTEXT '(' expr_const ')' { $$ = make_attrp(ATTR_HELPSTRINGCONTEXT, $3); } - | tHELPSTRINGDLL '(' aSTRING ')' { $$ = make_attrp(ATTR_HELPSTRINGDLL, $3); } - | tHIDDEN { $$ = make_attr(ATTR_HIDDEN); } - | tID '(' expr_const ')' { $$ = make_attrp(ATTR_ID, $3); } - | tIDEMPOTENT { $$ = make_attr(ATTR_IDEMPOTENT); } - | tIIDIS '(' expr ')' { $$ = make_attrp(ATTR_IIDIS, $3); } - | tIMMEDIATEBIND { $$ = make_attr(ATTR_IMMEDIATEBIND); } - | tIMPLICITHANDLE '(' tHANDLET aIDENTIFIER ')' { $$ = make_attrp(ATTR_IMPLICIT_HANDLE, $4); } - | tIN { $$ = make_attr(ATTR_IN); } - | tINPUTSYNC { $$ = make_attr(ATTR_INPUTSYNC); } - | tLENGTHIS '(' m_exprs ')' { $$ = make_attrp(ATTR_LENGTHIS, $3); } - | tLOCAL { $$ = make_attr(ATTR_LOCAL); } - | tNONBROWSABLE { $$ = make_attr(ATTR_NONBROWSABLE); } - | tNONCREATABLE { $$ = make_attr(ATTR_NONCREATABLE); } - | tNONEXTENSIBLE { $$ = make_attr(ATTR_NONEXTENSIBLE); } - | tOBJECT { $$ = make_attr(ATTR_OBJECT); } - | tODL { $$ = make_attr(ATTR_ODL); } - | tOLEAUTOMATION { $$ = make_attr(ATTR_OLEAUTOMATION); } - | tOPTIONAL { $$ = make_attr(ATTR_OPTIONAL); } - | tOUT { $$ = make_attr(ATTR_OUT); } - | tPOINTERDEFAULT '(' pointer_type ')' { $$ = make_attrv(ATTR_POINTERDEFAULT, $3); } - | tPROPGET { $$ = make_attr(ATTR_PROPGET); } - | tPROPPUT { $$ = make_attr(ATTR_PROPPUT); } - | tPROPPUTREF { $$ = make_attr(ATTR_PROPPUTREF); } - | tPUBLIC { $$ = make_attr(ATTR_PUBLIC); } - | tRANGE '(' expr_const ',' expr_const ')' { expr_list_t *list = append_expr( NULL, $3 ); - list = append_expr( list, $5 ); - $$ = make_attrp(ATTR_RANGE, list); } - | tREADONLY { $$ = make_attr(ATTR_READONLY); } - | tREQUESTEDIT { $$ = make_attr(ATTR_REQUESTEDIT); } - | tRESTRICTED { $$ = make_attr(ATTR_RESTRICTED); } - | tRETVAL { $$ = make_attr(ATTR_RETVAL); } - | tSIZEIS '(' m_exprs ')' { $$ = make_attrp(ATTR_SIZEIS, $3); } - | tSOURCE { $$ = make_attr(ATTR_SOURCE); } - | tSTRING { $$ = make_attr(ATTR_STRING); } - | tSWITCHIS '(' expr ')' { $$ = make_attrp(ATTR_SWITCHIS, $3); } - | tSWITCHTYPE '(' type ')' { $$ = make_attrp(ATTR_SWITCHTYPE, $3); } - | tTRANSMITAS '(' type ')' { $$ = make_attrp(ATTR_TRANSMITAS, $3); } - | tUUID '(' uuid_string ')' { $$ = make_attrp(ATTR_UUID, $3); } - | tV1ENUM { $$ = make_attr(ATTR_V1ENUM); } - | tVARARG { $$ = make_attr(ATTR_VARARG); } - | tVERSION '(' version ')' { $$ = make_attrv(ATTR_VERSION, $3); } - | tWIREMARSHAL '(' type ')' { $$ = make_attrp(ATTR_WIREMARSHAL, $3); } - | pointer_type { $$ = make_attrv(ATTR_POINTERTYPE, $1); } - ; - -uuid_string: - aUUID - | aSTRING { if (!is_valid_uuid($1)) - error_loc("invalid UUID: %s\n", $1); - $$ = parse_uuid($1); } - ; - -callconv: - | tSTDCALL - ; - -cases: { $$ = NULL; } - | cases case { $$ = append_var( $1, $2 ); } - ; - -case: tCASE expr ':' field { attr_t *a = make_attrp(ATTR_CASE, append_expr( NULL, $2 )); - $$ = $4; if (!$$) $$ = make_var(NULL); - $$->attrs = append_attr( $$->attrs, a ); - } - | tDEFAULT ':' field { attr_t *a = make_attr(ATTR_DEFAULT); - $$ = $3; if (!$$) $$ = make_var(NULL); - $$->attrs = append_attr( $$->attrs, a ); - } - ; - -constdef: tCONST type ident '=' expr_const { $$ = reg_const($3); - set_type($$, $2, 0, NULL, FALSE); - $$->eval = $5; - } - ; - -enums: { $$ = NULL; } - | enum_list ',' { $$ = $1; } - | enum_list - ; - -enum_list: enum { if (!$1->eval) - $1->eval = make_exprl(EXPR_NUM, 0 /* default for first enum entry */); - $$ = append_var( NULL, $1 ); - } - | enum_list ',' enum { if (!$3->eval) - { - var_t *last = LIST_ENTRY( list_tail($$), var_t, entry ); - $3->eval = make_exprl(EXPR_NUM, last->eval->cval + 1); - } - $$ = append_var( $1, $3 ); - } - ; - -enum: ident '=' expr_const { $$ = reg_const($1); - $$->eval = $3; - $$->type = make_int(0); - } - | ident { $$ = reg_const($1); - $$->type = make_int(0); - } - ; - -enumdef: tENUM t_ident '{' enums '}' { $$ = get_typev(RPC_FC_ENUM16, $2, tsENUM); - $$->kind = TKIND_ENUM; - $$->fields = $4; - $$->defined = TRUE; - if(in_typelib) - add_typelib_entry($$); - } - ; - -m_exprs: m_expr { $$ = append_expr( NULL, $1 ); } - | m_exprs ',' m_expr { $$ = append_expr( $1, $3 ); } - ; - -/* -exprs: { $$ = make_expr(EXPR_VOID); } - | expr_list - ; - -expr_list: expr - | expr_list ',' expr { LINK($3, $1); $$ = $3; } - ; -*/ - -m_expr: { $$ = make_expr(EXPR_VOID); } - | expr - ; - -expr: aNUM { $$ = make_exprl(EXPR_NUM, $1); } - | aHEXNUM { $$ = make_exprl(EXPR_HEXNUM, $1); } - | aDOUBLE { $$ = make_exprd(EXPR_DOUBLE, $1); } - | tFALSE { $$ = make_exprl(EXPR_TRUEFALSE, 0); } - | tTRUE { $$ = make_exprl(EXPR_TRUEFALSE, 1); } - | aIDENTIFIER { $$ = make_exprs(EXPR_IDENTIFIER, $1); } - | expr '?' expr ':' expr { $$ = make_expr3(EXPR_COND, $1, $3, $5); } - | expr '|' expr { $$ = make_expr2(EXPR_OR , $1, $3); } - | expr '&' expr { $$ = make_expr2(EXPR_AND, $1, $3); } - | expr '+' expr { $$ = make_expr2(EXPR_ADD, $1, $3); } - | expr '-' expr { $$ = make_expr2(EXPR_SUB, $1, $3); } - | expr '*' expr { $$ = make_expr2(EXPR_MUL, $1, $3); } - | expr '/' expr { $$ = make_expr2(EXPR_DIV, $1, $3); } - | expr SHL expr { $$ = make_expr2(EXPR_SHL, $1, $3); } - | expr SHR expr { $$ = make_expr2(EXPR_SHR, $1, $3); } - | '~' expr { $$ = make_expr1(EXPR_NOT, $2); } - | '-' expr %prec NEG { $$ = make_expr1(EXPR_NEG, $2); } - | '&' expr %prec ADDRESSOF { $$ = make_expr1(EXPR_ADDRESSOF, $2); } - | '*' expr %prec PPTR { $$ = make_expr1(EXPR_PPTR, $2); } - | '(' type ')' expr %prec CAST { $$ = make_exprt(EXPR_CAST, $2, $4); } - | tSIZEOF '(' type ')' { $$ = make_exprt(EXPR_SIZEOF, $3, NULL); } - | '(' expr ')' { $$ = $2; } - ; - -expr_list_const: expr_const { $$ = append_expr( NULL, $1 ); } - | expr_list_const ',' expr_const { $$ = append_expr( $1, $3 ); } - ; - -expr_const: expr { $$ = $1; - if (!$$->is_const) - error_loc("expression is not constant\n"); - } - ; - -externdef: tEXTERN tCONST type ident { $$ = $4; - set_type($$, $3, 0, NULL, FALSE); - } - ; - -fields: { $$ = NULL; } - | fields field { $$ = append_var( $1, $2 ); } - ; - -field: s_field ';' { $$ = $1; } - | m_attributes uniondef ';' { $$ = make_var(NULL); $$->type = $2; $$->attrs = $1; } - | attributes ';' { $$ = make_var(NULL); $$->attrs = $1; } - | ';' { $$ = NULL; } - ; - -s_field: m_attributes type pident array { $$ = $3->var; - $$->attrs = $1; - set_type($$, $2, $3->ptr_level, $4, FALSE); - free($3); - } - ; - -funcdef: - m_attributes type callconv pident - '(' m_args ')' { var_t *v = $4->var; - v->attrs = $1; - set_type(v, $2, $4->ptr_level, NULL, FALSE); - free($4); - $$ = make_func(v, $6); - if (is_attr(v->attrs, ATTR_IN)) { - error_loc("inapplicable attribute [in] for function '%s'\n",$$->def->name); - } - } - ; - -m_ident: { $$ = NULL; } - | ident - ; - -t_ident: { $$ = NULL; } - | aIDENTIFIER { $$ = make_var($1); } - | aKNOWNTYPE { $$ = make_var($1); } - ; - -ident: aIDENTIFIER { $$ = make_var($1); } -/* some "reserved words" used in attributes are also used as field names in some MS IDL files */ - | aKNOWNTYPE { $$ = make_var($1); } - ; - -base_type: tBYTE { $$ = make_builtin($1); } - | tWCHAR { $$ = make_builtin($1); } - | int_std - | tSIGNED int_std { $$ = $2; $$->sign = 1; } - | tUNSIGNED int_std { $$ = $2; $$->sign = -1; - switch ($$->type) { - case RPC_FC_CHAR: break; - case RPC_FC_SMALL: $$->type = RPC_FC_USMALL; break; - case RPC_FC_SHORT: $$->type = RPC_FC_USHORT; break; - case RPC_FC_LONG: $$->type = RPC_FC_ULONG; break; - case RPC_FC_HYPER: - if ($$->name[0] == 'h') /* hyper, as opposed to __int64 */ - { - $$ = alias($$, "MIDL_uhyper"); - $$->sign = 0; - } - break; - default: break; - } - } - | tUNSIGNED { $$ = make_int(-1); } - | tFLOAT { $$ = make_builtin($1); } - | tSINGLE { $$ = duptype(find_type("float", 0), 1); } - | tDOUBLE { $$ = make_builtin($1); } - | tBOOLEAN { $$ = make_builtin($1); } - | tERRORSTATUST { $$ = make_builtin($1); } - | tHANDLET { $$ = make_builtin($1); } - ; - -m_int: - | tINT - ; - -int_std: tINT { $$ = make_builtin($1); } - | tSHORT m_int { $$ = make_builtin($1); } - | tSMALL { $$ = make_builtin($1); } - | tLONG m_int { $$ = make_builtin($1); } - | tHYPER m_int { $$ = make_builtin($1); } - | tINT64 { $$ = make_builtin($1); } - | tCHAR { $$ = make_builtin($1); } - ; - -coclass: tCOCLASS aIDENTIFIER { $$ = make_class($2); } - | tCOCLASS aKNOWNTYPE { $$ = find_type($2, 0); - if ($$->defined) error_loc("multiple definition error\n"); - if ($$->kind != TKIND_COCLASS) error_loc("%s was not declared a coclass\n", $2); - } - ; - -coclasshdr: attributes coclass { $$ = $2; - $$->attrs = $1; - if (!parse_only && do_header) - write_coclass($$); - if (!parse_only && do_idfile) - write_clsid($$); - } - ; - -coclassdef: coclasshdr '{' coclass_ints '}' { $$ = $1; - $$->ifaces = $3; - $$->defined = TRUE; - } - ; - -coclass_ints: { $$ = NULL; } - | coclass_ints coclass_int { $$ = append_ifref( $1, $2 ); } - ; - -coclass_int: - m_attributes interfacedec { $$ = make_ifref($2); $$->attrs = $1; } - ; - -dispinterface: tDISPINTERFACE aIDENTIFIER { $$ = get_type(0, $2, 0); $$->kind = TKIND_DISPATCH; } - | tDISPINTERFACE aKNOWNTYPE { $$ = get_type(0, $2, 0); $$->kind = TKIND_DISPATCH; } - ; - -dispinterfacehdr: attributes dispinterface { attr_t *attrs; - $$ = $2; - if ($$->defined) error_loc("multiple definition error\n"); - attrs = make_attr(ATTR_DISPINTERFACE); - $$->attrs = append_attr( $1, attrs ); - $$->ref = find_type("IDispatch", 0); - if (!$$->ref) error_loc("IDispatch is undefined\n"); - $$->defined = TRUE; - if (!parse_only && do_header) write_forward($$); - } - ; - -dispint_props: tPROPERTIES ':' { $$ = NULL; } - | dispint_props s_field ';' { $$ = append_var( $1, $2 ); } - ; - -dispint_meths: tMETHODS ':' { $$ = NULL; } - | dispint_meths funcdef ';' { $$ = append_func( $1, $2 ); } - ; - -dispinterfacedef: dispinterfacehdr '{' - dispint_props - dispint_meths - '}' { $$ = $1; - $$->fields = $3; - $$->funcs = $4; - if (!parse_only && do_header) write_dispinterface($$); - if (!parse_only && do_idfile) write_diid($$); - } - | dispinterfacehdr - '{' interface ';' '}' { $$ = $1; - $$->fields = $3->fields; - $$->funcs = $3->funcs; - if (!parse_only && do_header) write_dispinterface($$); - if (!parse_only && do_idfile) write_diid($$); - } - ; - -inherit: { $$ = NULL; } - | ':' aKNOWNTYPE { $$ = find_type2($2, 0); } - ; - -interface: tINTERFACE aIDENTIFIER { $$ = get_type(RPC_FC_IP, $2, 0); $$->kind = TKIND_INTERFACE; } - | tINTERFACE aKNOWNTYPE { $$ = get_type(RPC_FC_IP, $2, 0); $$->kind = TKIND_INTERFACE; } - ; - -interfacehdr: attributes interface { $$.interface = $2; - $$.old_pointer_default = pointer_default; - if (is_attr($1, ATTR_POINTERDEFAULT)) - pointer_default = get_attrv($1, ATTR_POINTERDEFAULT); - if ($2->defined) error_loc("multiple definition error\n"); - $2->attrs = $1; - $2->defined = TRUE; - if (!parse_only && do_header) write_forward($2); - } - ; - -interfacedef: interfacehdr inherit - '{' int_statements '}' { $$ = $1.interface; - $$->ref = $2; - $$->funcs = $4; - compute_method_indexes($$); - if (!parse_only && do_header) write_interface($$); - if (!parse_only && local_stubs) write_locals(local_stubs, $$, TRUE); - if (!parse_only && do_idfile) write_iid($$); - pointer_default = $1.old_pointer_default; - } -/* MIDL is able to import the definition of a base class from inside the - * definition of a derived class, I'll try to support it with this rule */ - | interfacehdr ':' aIDENTIFIER - '{' import int_statements '}' { $$ = $1.interface; - $$->ref = find_type2($3, 0); - if (!$$->ref) error_loc("base class '%s' not found in import\n", $3); - $$->funcs = $6; - compute_method_indexes($$); - if (!parse_only && do_header) write_interface($$); - if (!parse_only && local_stubs) write_locals(local_stubs, $$, TRUE); - if (!parse_only && do_idfile) write_iid($$); - pointer_default = $1.old_pointer_default; - } - | dispinterfacedef { $$ = $1; } - ; - -interfacedec: - interface ';' { $$ = $1; if (!parse_only && do_header) write_forward($$); } - | dispinterface ';' { $$ = $1; if (!parse_only && do_header) write_forward($$); } - ; - -module: tMODULE aIDENTIFIER { $$ = make_type(0, NULL); $$->name = $2; $$->kind = TKIND_MODULE; } - | tMODULE aKNOWNTYPE { $$ = make_type(0, NULL); $$->name = $2; $$->kind = TKIND_MODULE; } - ; - -modulehdr: attributes module { $$ = $2; - $$->attrs = $1; - } - ; - -moduledef: modulehdr '{' int_statements '}' { $$ = $1; - $$->funcs = $3; - /* FIXME: if (!parse_only && do_header) write_module($$); */ - } - ; - -p_ident: '*' pident %prec PPTR { $$ = $2; $$->ptr_level++; } - | tCONST p_ident { $$ = $2; /* FIXME */ } - ; - -pident: ident { $$ = make_pident($1); } - | p_ident - | '(' pident ')' { $$ = $2; } - ; - -pident_list: - pident { $$ = append_pident( NULL, $1 ); } - | pident_list ',' pident { $$ = append_pident( $1, $3 ); } - ; - -pointer_type: - tREF { $$ = RPC_FC_RP; } - | tUNIQUE { $$ = RPC_FC_UP; } - | tPTR { $$ = RPC_FC_FP; } - ; - -structdef: tSTRUCT t_ident '{' fields '}' { $$ = get_typev(RPC_FC_STRUCT, $2, tsSTRUCT); - /* overwrite RPC_FC_STRUCT with a more exact type */ - $$->type = get_struct_type( $4 ); - $$->kind = TKIND_RECORD; - $$->fields = $4; - $$->defined = TRUE; - if(in_typelib) - add_typelib_entry($$); - } - ; - -type: tVOID { $$ = duptype(find_type("void", 0), 1); } - | aKNOWNTYPE { $$ = find_type($1, 0); } - | base_type { $$ = $1; } - | tCONST type { $$ = duptype($2, 1); $$->is_const = TRUE; } - | enumdef { $$ = $1; } - | tENUM aIDENTIFIER { $$ = find_type2($2, tsENUM); } - | structdef { $$ = $1; } - | tSTRUCT aIDENTIFIER { $$ = get_type(RPC_FC_STRUCT, $2, tsSTRUCT); } - | uniondef { $$ = $1; } - | tUNION aIDENTIFIER { $$ = find_type2($2, tsUNION); } - | tSAFEARRAY '(' type ')' { $$ = make_safearray($3); } - ; - -typedef: tTYPEDEF m_attributes type pident_list { reg_typedefs($3, $4, $2); - process_typedefs($4); - } - ; - -uniondef: tUNION t_ident '{' fields '}' { $$ = get_typev(RPC_FC_NON_ENCAPSULATED_UNION, $2, tsUNION); - $$->kind = TKIND_UNION; - $$->fields = $4; - $$->defined = TRUE; - } - | tUNION t_ident - tSWITCH '(' s_field ')' - m_ident '{' cases '}' { var_t *u = $7; - $$ = get_typev(RPC_FC_ENCAPSULATED_UNION, $2, tsUNION); - $$->kind = TKIND_UNION; - if (!u) u = make_var( xstrdup("tagged_union") ); - u->type = make_type(RPC_FC_NON_ENCAPSULATED_UNION, NULL); - u->type->kind = TKIND_UNION; - u->type->fields = $9; - u->type->defined = TRUE; - $$->fields = append_var( $$->fields, $5 ); - $$->fields = append_var( $$->fields, u ); - $$->defined = TRUE; - } - ; - -version: - aNUM { $$ = MAKEVERSION($1, 0); } - | aNUM '.' aNUM { $$ = MAKEVERSION($1, $3); } - ; - -%% - -static void decl_builtin(const char *name, unsigned char type) -{ - type_t *t = make_type(type, NULL); - t->name = xstrdup(name); - reg_type(t, name, 0); -} - -static type_t *make_builtin(char *name) -{ - /* NAME is strdup'd in the lexer */ - type_t *t = duptype(find_type(name, 0), 0); - t->name = name; - return t; -} - -static type_t *make_int(int sign) -{ - type_t *t = duptype(find_type("int", 0), 1); - - t->sign = sign; - if (sign < 0) - t->type = t->type == RPC_FC_LONG ? RPC_FC_ULONG : RPC_FC_USHORT; - - return t; -} - -void init_types(void) -{ - decl_builtin("void", 0); - decl_builtin("byte", RPC_FC_BYTE); - decl_builtin("wchar_t", RPC_FC_WCHAR); - decl_builtin("int", RPC_FC_LONG); /* win32 */ - decl_builtin("short", RPC_FC_SHORT); - decl_builtin("small", RPC_FC_SMALL); - decl_builtin("long", RPC_FC_LONG); - decl_builtin("hyper", RPC_FC_HYPER); - decl_builtin("__int64", RPC_FC_HYPER); - decl_builtin("char", RPC_FC_CHAR); - decl_builtin("float", RPC_FC_FLOAT); - decl_builtin("double", RPC_FC_DOUBLE); - decl_builtin("boolean", RPC_FC_BYTE); - decl_builtin("error_status_t", RPC_FC_ERROR_STATUS_T); - decl_builtin("handle_t", RPC_FC_BIND_PRIMITIVE); -} - -static str_list_t *append_str(str_list_t *list, char *str) -{ - struct str_list_entry_t *entry; - - if (!str) return list; - if (!list) - { - list = xmalloc( sizeof(*list) ); - list_init( list ); - } - entry = xmalloc( sizeof(*entry) ); - entry->str = str; - list_add_tail( list, &entry->entry ); - return list; -} - -static attr_list_t *append_attr(attr_list_t *list, attr_t *attr) -{ - if (!attr) return list; - if (!list) - { - list = xmalloc( sizeof(*list) ); - list_init( list ); - } - list_add_tail( list, &attr->entry ); - return list; -} - -static attr_t *make_attr(enum attr_type type) -{ - attr_t *a = xmalloc(sizeof(attr_t)); - a->type = type; - a->u.ival = 0; - return a; -} - -static attr_t *make_attrv(enum attr_type type, unsigned long val) -{ - attr_t *a = xmalloc(sizeof(attr_t)); - a->type = type; - a->u.ival = val; - return a; -} - -static attr_t *make_attrp(enum attr_type type, void *val) -{ - attr_t *a = xmalloc(sizeof(attr_t)); - a->type = type; - a->u.pval = val; - return a; -} - -static expr_t *make_expr(enum expr_type type) -{ - expr_t *e = xmalloc(sizeof(expr_t)); - e->type = type; - e->ref = NULL; - e->u.lval = 0; - e->is_const = FALSE; - e->cval = 0; - return e; -} - -static expr_t *make_exprl(enum expr_type type, long val) -{ - expr_t *e = xmalloc(sizeof(expr_t)); - e->type = type; - e->ref = NULL; - e->u.lval = val; - e->is_const = FALSE; - /* check for numeric constant */ - if (type == EXPR_NUM || type == EXPR_HEXNUM || type == EXPR_TRUEFALSE) { - /* make sure true/false value is valid */ - assert(type != EXPR_TRUEFALSE || val == 0 || val == 1); - e->is_const = TRUE; - e->cval = val; - } - return e; -} - -static expr_t *make_exprd(enum expr_type type, double val) -{ - expr_t *e = xmalloc(sizeof(expr_t)); - e->type = type; - e->ref = NULL; - e->u.dval = val; - e->is_const = TRUE; - e->cval = val; - return e; -} - -static expr_t *make_exprs(enum expr_type type, char *val) -{ - expr_t *e; - e = xmalloc(sizeof(expr_t)); - e->type = type; - e->ref = NULL; - e->u.sval = val; - e->is_const = FALSE; - /* check for predefined constants */ - if (type == EXPR_IDENTIFIER) { - var_t *c = find_const(val, 0); - if (c) { - e->u.sval = c->name; - free(val); - e->is_const = TRUE; - e->cval = c->eval->cval; - } - } - return e; -} - -static expr_t *make_exprt(enum expr_type type, type_t *tref, expr_t *expr) -{ - expr_t *e; - e = xmalloc(sizeof(expr_t)); - e->type = type; - e->ref = expr; - e->u.tref = tref; - e->is_const = FALSE; - /* check for cast of constant expression */ - if (type == EXPR_SIZEOF) { - switch (tref->type) { - case RPC_FC_BYTE: - case RPC_FC_CHAR: - case RPC_FC_SMALL: - case RPC_FC_USMALL: - e->is_const = TRUE; - e->cval = 1; - break; - case RPC_FC_WCHAR: - case RPC_FC_USHORT: - case RPC_FC_SHORT: - e->is_const = TRUE; - e->cval = 2; - break; - case RPC_FC_LONG: - case RPC_FC_ULONG: - case RPC_FC_FLOAT: - case RPC_FC_ERROR_STATUS_T: - e->is_const = TRUE; - e->cval = 4; - break; - case RPC_FC_HYPER: - case RPC_FC_DOUBLE: - e->is_const = TRUE; - e->cval = 8; - break; - } - } - if (type == EXPR_CAST && expr->is_const) { - e->is_const = TRUE; - e->cval = expr->cval; - } - return e; -} - -static expr_t *make_expr1(enum expr_type type, expr_t *expr) -{ - expr_t *e; - if (type == EXPR_ADDRESSOF && expr->type != EXPR_IDENTIFIER) - error("address-of operator applied to invalid expression\n"); - e = xmalloc(sizeof(expr_t)); - e->type = type; - e->ref = expr; - e->u.lval = 0; - e->is_const = FALSE; - /* check for compile-time optimization */ - if (expr->is_const) { - e->is_const = TRUE; - switch (type) { - case EXPR_NEG: - e->cval = -expr->cval; - break; - case EXPR_NOT: - e->cval = ~expr->cval; - break; - default: - e->is_const = FALSE; - break; - } - } - return e; -} - -static expr_t *make_expr2(enum expr_type type, expr_t *expr1, expr_t *expr2) -{ - expr_t *e; - e = xmalloc(sizeof(expr_t)); - e->type = type; - e->ref = expr1; - e->u.ext = expr2; - e->is_const = FALSE; - /* check for compile-time optimization */ - if (expr1->is_const && expr2->is_const) { - e->is_const = TRUE; - switch (type) { - case EXPR_ADD: - e->cval = expr1->cval + expr2->cval; - break; - case EXPR_SUB: - e->cval = expr1->cval - expr2->cval; - break; - case EXPR_MUL: - e->cval = expr1->cval * expr2->cval; - break; - case EXPR_DIV: - e->cval = expr1->cval / expr2->cval; - break; - case EXPR_OR: - e->cval = expr1->cval | expr2->cval; - break; - case EXPR_AND: - e->cval = expr1->cval & expr2->cval; - break; - case EXPR_SHL: - e->cval = expr1->cval << expr2->cval; - break; - case EXPR_SHR: - e->cval = expr1->cval >> expr2->cval; - break; - default: - e->is_const = FALSE; - break; - } - } - return e; -} - -static expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, expr_t *expr3) -{ - expr_t *e; - e = xmalloc(sizeof(expr_t)); - e->type = type; - e->ref = expr1; - e->u.ext = expr2; - e->ext2 = expr3; - e->is_const = FALSE; - /* check for compile-time optimization */ - if (expr1->is_const && expr2->is_const && expr3->is_const) { - e->is_const = TRUE; - switch (type) { - case EXPR_COND: - e->cval = expr1->cval ? expr2->cval : expr3->cval; - break; - default: - e->is_const = FALSE; - break; - } - } - return e; -} - -static expr_list_t *append_expr(expr_list_t *list, expr_t *expr) -{ - if (!expr) return list; - if (!list) - { - list = xmalloc( sizeof(*list) ); - list_init( list ); - } - list_add_tail( list, &expr->entry ); - return list; -} - -static array_dims_t *append_array(array_dims_t *list, expr_t *expr) -{ - if (!expr) return list; - if (!list) - { - list = xmalloc( sizeof(*list) ); - list_init( list ); - } - list_add_tail( list, &expr->entry ); - return list; -} - -static struct list type_pool = LIST_INIT(type_pool); -typedef struct -{ - type_t data; - struct list link; -} type_pool_node_t; - -type_t *alloc_type(void) -{ - type_pool_node_t *node = xmalloc(sizeof *node); - list_add_tail(&type_pool, &node->link); - return &node->data; -} - -void set_all_tfswrite(int val) -{ - type_pool_node_t *node; - LIST_FOR_EACH_ENTRY(node, &type_pool, type_pool_node_t, link) - node->data.tfswrite = val; -} - -static type_t *make_type(unsigned char type, type_t *ref) -{ - type_t *t = alloc_type(); - t->name = NULL; - t->kind = TKIND_PRIMITIVE; - t->type = type; - t->ref = ref; - t->attrs = NULL; - t->orig = NULL; - t->funcs = NULL; - t->fields = NULL; - t->ifaces = NULL; - t->dim = 0; - t->size_is = NULL; - t->length_is = NULL; - t->typestring_offset = 0; - t->ptrdesc = 0; - t->declarray = FALSE; - t->ignore = (parse_only != 0); - t->is_const = FALSE; - t->sign = 0; - t->defined = FALSE; - t->written = FALSE; - t->user_types_registered = FALSE; - t->tfswrite = FALSE; - t->typelib_idx = -1; - return t; -} - -static void set_type(var_t *v, type_t *type, int ptr_level, array_dims_t *arr, - int top) -{ - expr_list_t *sizes = get_attrp(v->attrs, ATTR_SIZEIS); - expr_list_t *lengs = get_attrp(v->attrs, ATTR_LENGTHIS); - int ptr_attr = get_attrv(v->attrs, ATTR_POINTERTYPE); - int ptr_type = ptr_attr; - int sizeless, has_varconf; - expr_t *dim; - type_t *atype, **ptype; - - v->type = type; - - if (!ptr_type && top) - ptr_type = RPC_FC_RP; - - for ( ; 0 < ptr_level; --ptr_level) - { - v->type = make_type(pointer_default, v->type); - if (ptr_level == 1 && ptr_type && !arr) - { - v->type->type = ptr_type; - ptr_type = 0; - } - } - - if (ptr_type && !arr) - { - if (is_ptr(v->type)) - { - if (v->type->type != ptr_type) - { - v->type = duptype(v->type, 1); - v->type->type = ptr_type; - } - } - else if (!arr && ptr_attr) - error("%s: pointer attribute applied to non-pointer type\n", v->name); - } - - sizeless = FALSE; - if (arr) LIST_FOR_EACH_ENTRY_REV(dim, arr, expr_t, entry) - { - if (sizeless) - error("%s: only the first array dimension can be unspecified\n", v->name); - - if (dim->is_const) - { - unsigned int align = 0; - size_t size = type_memsize(v->type, &align); - - if (dim->cval <= 0) - error("%s: array dimension must be positive\n", v->name); - - if (0xffffffffuL / size < (unsigned long) dim->cval) - error("%s: total array size is too large\n", v->name); - else if (0xffffuL < size * dim->cval) - v->type = make_type(RPC_FC_LGFARRAY, v->type); - else - v->type = make_type(RPC_FC_SMFARRAY, v->type); - } - else - { - sizeless = TRUE; - v->type = make_type(RPC_FC_CARRAY, v->type); - } - - v->type->declarray = TRUE; - v->type->dim = dim->cval; - } - - ptype = &v->type; - has_varconf = FALSE; - if (sizes) LIST_FOR_EACH_ENTRY(dim, sizes, expr_t, entry) - { - if (dim->type != EXPR_VOID) - { - has_varconf = TRUE; - atype = *ptype = duptype(*ptype, 0); - - if (atype->type == RPC_FC_SMFARRAY || atype->type == RPC_FC_LGFARRAY) - error("%s: cannot specify size_is for a fixed sized array\n", v->name); - - if (atype->type != RPC_FC_CARRAY && !is_ptr(atype)) - error("%s: size_is attribute applied to illegal type\n", v->name); - - atype->type = RPC_FC_CARRAY; - atype->size_is = dim; - } - - ptype = &(*ptype)->ref; - if (*ptype == NULL) - error("%s: too many expressions in size_is attribute\n", v->name); - } - - ptype = &v->type; - if (lengs) LIST_FOR_EACH_ENTRY(dim, lengs, expr_t, entry) - { - if (dim->type != EXPR_VOID) - { - has_varconf = TRUE; - atype = *ptype = duptype(*ptype, 0); - - if (atype->type == RPC_FC_SMFARRAY) - atype->type = RPC_FC_SMVARRAY; - else if (atype->type == RPC_FC_LGFARRAY) - atype->type = RPC_FC_LGVARRAY; - else if (atype->type == RPC_FC_CARRAY) - atype->type = RPC_FC_CVARRAY; - else - error("%s: length_is attribute applied to illegal type\n", v->name); - - atype->length_is = dim; - } - - ptype = &(*ptype)->ref; - if (*ptype == NULL) - error("%s: too many expressions in length_is attribute\n", v->name); - } - - if (has_varconf && !last_array(v->type)) - { - ptype = &v->type; - for (ptype = &v->type; is_array(*ptype); ptype = &(*ptype)->ref) - { - *ptype = duptype(*ptype, 0); - (*ptype)->type = RPC_FC_BOGUS_ARRAY; - } - } - - if (is_array(v->type)) - { - const type_t *rt = v->type->ref; - if (is_user_type(rt)) - v->type->type = RPC_FC_BOGUS_ARRAY; - else - switch (rt->type) - { - case RPC_FC_BOGUS_STRUCT: - case RPC_FC_NON_ENCAPSULATED_UNION: - case RPC_FC_ENCAPSULATED_UNION: - case RPC_FC_ENUM16: - v->type->type = RPC_FC_BOGUS_ARRAY; - break; - /* FC_RP should be above, but widl overuses these, and will break things. */ - case RPC_FC_UP: - case RPC_FC_RP: - if (rt->ref->type == RPC_FC_IP) - v->type->type = RPC_FC_BOGUS_ARRAY; - break; - } - } -} - -static ifref_list_t *append_ifref(ifref_list_t *list, ifref_t *iface) -{ - if (!iface) return list; - if (!list) - { - list = xmalloc( sizeof(*list) ); - list_init( list ); - } - list_add_tail( list, &iface->entry ); - return list; -} - -static ifref_t *make_ifref(type_t *iface) -{ - ifref_t *l = xmalloc(sizeof(ifref_t)); - l->iface = iface; - l->attrs = NULL; - return l; -} - -static var_list_t *append_var(var_list_t *list, var_t *var) -{ - if (!var) return list; - if (!list) - { - list = xmalloc( sizeof(*list) ); - list_init( list ); - } - list_add_tail( list, &var->entry ); - return list; -} - -static var_t *make_var(char *name) -{ - var_t *v = xmalloc(sizeof(var_t)); - v->name = name; - v->type = NULL; - v->args = NULL; - v->attrs = NULL; - v->eval = NULL; - return v; -} - -static pident_list_t *append_pident(pident_list_t *list, pident_t *p) -{ - if (!p) return list; - if (!list) { - list = xmalloc(sizeof(*list)); - list_init(list); - } - list_add_tail(list, &p->entry); - return list; -} - -static pident_t *make_pident(var_t *var) -{ - pident_t *p = xmalloc(sizeof(*p)); - p->var = var; - p->ptr_level = 0; - return p; -} - -static func_list_t *append_func(func_list_t *list, func_t *func) -{ - if (!func) return list; - if (!list) - { - list = xmalloc( sizeof(*list) ); - list_init( list ); - } - list_add_tail( list, &func->entry ); - return list; -} - -static func_t *make_func(var_t *def, var_list_t *args) -{ - func_t *f = xmalloc(sizeof(func_t)); - f->def = def; - f->args = args; - f->ignore = parse_only; - f->idx = -1; - return f; -} - -static type_t *make_class(char *name) -{ - type_t *c = make_type(0, NULL); - c->name = name; - c->kind = TKIND_COCLASS; - return c; -} - -static type_t *make_safearray(type_t *type) -{ - type_t *sa = duptype(find_type("SAFEARRAY", 0), 1); - sa->ref = type; - return make_type(pointer_default, sa); -} - -#define HASHMAX 64 - -static int hash_ident(const char *name) -{ - const char *p = name; - int sum = 0; - /* a simple sum hash is probably good enough */ - while (*p) { - sum += *p; - p++; - } - return sum & (HASHMAX-1); -} - -/***** type repository *****/ - -struct rtype { - const char *name; - type_t *type; - int t; - struct rtype *next; -}; - -struct rtype *type_hash[HASHMAX]; - -static type_t *reg_type(type_t *type, const char *name, int t) -{ - struct rtype *nt; - int hash; - if (!name) { - error_loc("registering named type without name\n"); - return type; - } - hash = hash_ident(name); - nt = xmalloc(sizeof(struct rtype)); - nt->name = name; - nt->type = type; - nt->t = t; - nt->next = type_hash[hash]; - type_hash[hash] = nt; - return type; -} - -static int is_incomplete(const type_t *t) -{ - return !t->defined && (is_struct(t->type) || is_union(t->type)); -} - -static void add_incomplete(type_t *t) -{ - struct typenode *tn = xmalloc(sizeof *tn); - tn->type = t; - list_add_tail(&incomplete_types, &tn->entry); -} - -static void fix_type(type_t *t) -{ - if (t->kind == TKIND_ALIAS && is_incomplete(t)) { - type_t *ot = t->orig; - fix_type(ot); - t->fields = ot->fields; - t->defined = ot->defined; - } -} - -static void fix_incomplete(void) -{ - struct typenode *tn, *next; - - LIST_FOR_EACH_ENTRY_SAFE(tn, next, &incomplete_types, struct typenode, entry) { - fix_type(tn->type); - free(tn); - } -} - -static type_t *reg_typedefs(type_t *type, pident_list_t *pidents, attr_list_t *attrs) -{ - type_t *ptr = type; - const pident_t *pident; - int ptrc = 0; - int is_str = is_attr(attrs, ATTR_STRING); - unsigned char ptr_type = get_attrv(attrs, ATTR_POINTERTYPE); - - if (is_str) - { - type_t *t = type; - unsigned char c; - - while (is_ptr(t)) - t = t->ref; - - c = t->type; - if (c != RPC_FC_CHAR && c != RPC_FC_BYTE && c != RPC_FC_WCHAR) - { - pident = LIST_ENTRY( list_head( pidents ), const pident_t, entry ); - error_loc("'%s': [string] attribute is only valid on 'char', 'byte', or 'wchar_t' pointers and arrays\n", - pident->var->name); - } - } - - /* We must generate names for tagless enum, struct or union. - Typedef-ing a tagless enum, struct or union means we want the typedef - to be included in a library whether it has other attributes or not, - hence the public attribute. */ - if ((type->kind == TKIND_ENUM || type->kind == TKIND_RECORD - || type->kind == TKIND_UNION) && ! type->name && ! parse_only) - { - if (! is_attr(attrs, ATTR_PUBLIC)) - attrs = append_attr( attrs, make_attr(ATTR_PUBLIC) ); - type->name = gen_name(); - } - - LIST_FOR_EACH_ENTRY( pident, pidents, const pident_t, entry ) - { - var_t *name = pident->var; - - if (name->name) { - type_t *cur = ptr; - int cptr = pident->ptr_level; - if (cptr > ptrc) { - while (cptr > ptrc) { - cur = ptr = make_type(pointer_default, cur); - ptrc++; - } - } else { - while (cptr < ptrc) { - cur = cur->ref; - cptr++; - } - } - cur = alias(cur, name->name); - cur->attrs = attrs; - if (ptr_type) - { - if (is_ptr(cur)) - cur->type = ptr_type; - else - error_loc("'%s': pointer attribute applied to non-pointer type\n", - cur->name); - } - else if (is_str && ! is_ptr(cur)) - error_loc("'%s': [string] attribute applied to non-pointer type\n", - cur->name); - - if (is_incomplete(cur)) - add_incomplete(cur); - reg_type(cur, cur->name, 0); - } - } - return type; -} - -static type_t *find_type(const char *name, int t) -{ - struct rtype *cur = type_hash[hash_ident(name)]; - while (cur && (cur->t != t || strcmp(cur->name, name))) - cur = cur->next; - if (!cur) { - error_loc("type '%s' not found\n", name); - return NULL; - } - return cur->type; -} - -static type_t *find_type2(char *name, int t) -{ - type_t *tp = find_type(name, t); - free(name); - return tp; -} - -int is_type(const char *name) -{ - struct rtype *cur = type_hash[hash_ident(name)]; - while (cur && (cur->t || strcmp(cur->name, name))) - cur = cur->next; - if (cur) return TRUE; - return FALSE; -} - -static type_t *get_type(unsigned char type, char *name, int t) -{ - struct rtype *cur = NULL; - type_t *tp; - if (name) { - cur = type_hash[hash_ident(name)]; - while (cur && (cur->t != t || strcmp(cur->name, name))) - cur = cur->next; - } - if (cur) { - free(name); - return cur->type; - } - tp = make_type(type, NULL); - tp->name = name; - if (!name) return tp; - return reg_type(tp, name, t); -} - -static type_t *get_typev(unsigned char type, var_t *name, int t) -{ - char *sname = NULL; - if (name) { - sname = name->name; - free(name); - } - return get_type(type, sname, t); -} - -static int get_struct_type(var_list_t *fields) -{ - int has_pointer = 0; - int has_conformance = 0; - int has_variance = 0; - var_t *field; - - if (get_padding(fields)) - return RPC_FC_BOGUS_STRUCT; - - if (fields) LIST_FOR_EACH_ENTRY( field, fields, var_t, entry ) - { - type_t *t = field->type; - - if (is_user_type(t)) - return RPC_FC_BOGUS_STRUCT; - - if (is_ptr(t)) - { - do - t = t->ref; - while (is_ptr(t)); - - switch (t->type) - { - case RPC_FC_IP: - case RPC_FC_ENCAPSULATED_UNION: - case RPC_FC_NON_ENCAPSULATED_UNION: - case RPC_FC_BOGUS_STRUCT: - return RPC_FC_BOGUS_STRUCT; - } - - has_pointer = 1; - continue; - } - - if (field->type->declarray) - { - if (is_string_type(field->attrs, field->type)) - { - if (is_conformant_array(field->type)) - has_conformance = 1; - has_variance = 1; - continue; - } - - if (is_array(field->type->ref)) - return RPC_FC_BOGUS_STRUCT; - - if (is_conformant_array(field->type)) - { - has_conformance = 1; - if (field->type->declarray && list_next(fields, &field->entry)) - error_loc("field '%s' deriving from a conformant array must be the last field in the structure\n", - field->name); - } - if (field->type->length_is) - has_variance = 1; - - t = field->type->ref; - } - - switch (t->type) - { - /* - * RPC_FC_BYTE, RPC_FC_STRUCT, etc - * Simple types don't effect the type of struct. - * A struct containing a simple struct is still a simple struct. - * So long as we can block copy the data, we return RPC_FC_STRUCT. - */ - case 0: /* void pointer */ - case RPC_FC_BYTE: - case RPC_FC_CHAR: - case RPC_FC_SMALL: - case RPC_FC_USMALL: - case RPC_FC_WCHAR: - case RPC_FC_SHORT: - case RPC_FC_USHORT: - case RPC_FC_LONG: - case RPC_FC_ULONG: - case RPC_FC_INT3264: - case RPC_FC_UINT3264: - case RPC_FC_HYPER: - case RPC_FC_FLOAT: - case RPC_FC_DOUBLE: - case RPC_FC_STRUCT: - case RPC_FC_ENUM16: - case RPC_FC_ENUM32: - break; - - case RPC_FC_RP: - case RPC_FC_UP: - case RPC_FC_FP: - case RPC_FC_OP: - case RPC_FC_CARRAY: - case RPC_FC_CVARRAY: - case RPC_FC_BOGUS_ARRAY: - has_pointer = 1; - break; - - /* - * Propagate member attributes - * a struct should be at least as complex as its member - */ - case RPC_FC_CVSTRUCT: - has_conformance = 1; - has_variance = 1; - has_pointer = 1; - break; - - case RPC_FC_CPSTRUCT: - has_conformance = 1; - if (list_next( fields, &field->entry )) - error_loc("field '%s' deriving from a conformant array must be the last field in the structure\n", - field->name); - has_pointer = 1; - break; - - case RPC_FC_CSTRUCT: - has_conformance = 1; - if (list_next( fields, &field->entry )) - error_loc("field '%s' deriving from a conformant array must be the last field in the structure\n", - field->name); - break; - - case RPC_FC_PSTRUCT: - has_pointer = 1; - break; - - default: - error_loc("Unknown struct member %s with type (0x%02x)\n", field->name, t->type); - /* fallthru - treat it as complex */ - - /* as soon as we see one of these these members, it's bogus... */ - case RPC_FC_ENCAPSULATED_UNION: - case RPC_FC_NON_ENCAPSULATED_UNION: - case RPC_FC_BOGUS_STRUCT: - return RPC_FC_BOGUS_STRUCT; - } - } - - if( has_variance ) - { - if ( has_conformance ) - return RPC_FC_CVSTRUCT; - else - return RPC_FC_BOGUS_STRUCT; - } - if( has_conformance && has_pointer ) - return RPC_FC_CPSTRUCT; - if( has_conformance ) - return RPC_FC_CSTRUCT; - if( has_pointer ) - return RPC_FC_PSTRUCT; - return RPC_FC_STRUCT; -} - -/***** constant repository *****/ - -struct rconst { - char *name; - var_t *var; - struct rconst *next; -}; - -struct rconst *const_hash[HASHMAX]; - -static var_t *reg_const(var_t *var) -{ - struct rconst *nc; - int hash; - if (!var->name) { - error_loc("registering constant without name\n"); - return var; - } - hash = hash_ident(var->name); - nc = xmalloc(sizeof(struct rconst)); - nc->name = var->name; - nc->var = var; - nc->next = const_hash[hash]; - const_hash[hash] = nc; - return var; -} - -static var_t *find_const(char *name, int f) -{ - struct rconst *cur = const_hash[hash_ident(name)]; - while (cur && strcmp(cur->name, name)) - cur = cur->next; - if (!cur) { - if (f) error_loc("constant '%s' not found\n", name); - return NULL; - } - return cur->var; -} - -static void write_libid(const char *name, const attr_list_t *attr) -{ - const UUID *uuid = get_attrp(attr, ATTR_UUID); - write_guid(idfile, "LIBID", name, uuid); -} - -static void write_clsid(type_t *cls) -{ - const UUID *uuid = get_attrp(cls->attrs, ATTR_UUID); - write_guid(idfile, "CLSID", cls->name, uuid); -} - -static void write_diid(type_t *iface) -{ - const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID); - write_guid(idfile, "DIID", iface->name, uuid); -} - -static void write_iid(type_t *iface) -{ - const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID); - write_guid(idfile, "IID", iface->name, uuid); -} - -static int compute_method_indexes(type_t *iface) -{ - int idx; - func_t *f; - - if (iface->ref) - idx = compute_method_indexes(iface->ref); - else - idx = 0; - - if (!iface->funcs) - return idx; - - LIST_FOR_EACH_ENTRY( f, iface->funcs, func_t, entry ) - if (! is_callas(f->def->attrs)) - f->idx = idx++; - - return idx; -} - -static char *gen_name(void) -{ - static const char format[] = "__WIDL_%s_generated_name_%08lX"; - static unsigned long n = 0; - static const char *file_id; - static size_t size; - char *name; - - if (! file_id) - { - char *dst = dup_basename(input_name, ".idl"); - file_id = dst; - - for (; *dst; ++dst) - if (! isalnum((unsigned char) *dst)) - *dst = '_'; - - size = sizeof format - 7 + strlen(file_id) + 8; - } - - name = xmalloc(size); - sprintf(name, format, file_id, n++); - return name; -} - -static void process_typedefs(pident_list_t *pidents) -{ - pident_t *pident, *next; - - if (!pidents) return; - LIST_FOR_EACH_ENTRY_SAFE( pident, next, pidents, pident_t, entry ) - { - var_t *var = pident->var; - type_t *type = find_type(var->name, 0); - - if (! parse_only && do_header) - write_typedef(type); - if (in_typelib && type->attrs) - add_typelib_entry(type); - - free(pident); - free(var); - } -} - -static void check_arg(var_t *arg) -{ - type_t *t = arg->type; - - if (t->type == 0 && ! is_var_ptr(arg)) - error_loc("argument '%s' has void type\n", arg->name); -} - -static void check_all_user_types(ifref_list_t *ifrefs) -{ - const ifref_t *ifref; - const func_t *f; - - if (ifrefs) LIST_FOR_EACH_ENTRY(ifref, ifrefs, const ifref_t, entry) - { - const func_list_t *fs = ifref->iface->funcs; - if (fs) LIST_FOR_EACH_ENTRY(f, fs, const func_t, entry) - check_for_user_types_and_context_handles(f->args); - } -} - -int is_valid_uuid(const char *s) -{ - int i; - - for (i = 0; i < 36; ++i) - if (i == 8 || i == 13 || i == 18 || i == 23) - { - if (s[i] != '-') - return FALSE; - } - else - if (!isxdigit(s[i])) - return FALSE; - - return s[i] == '\0'; -} diff --git a/reactos/tools/widl_20080105/port/mkstemps.c b/reactos/tools/widl_20080105/port/mkstemps.c deleted file mode 100644 index 9919eac949f..00000000000 --- a/reactos/tools/widl_20080105/port/mkstemps.c +++ /dev/null @@ -1,138 +0,0 @@ -/* Copyright (C) 1991, 1992, 1996, 1998 Free Software Foundation, Inc. - This file is derived from mkstemp.c from the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The GNU C 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "config.h" - -#include -#include -#include -#include -#include -#include -#ifdef HAVE_UNISTD_H -#include -#endif -#ifdef HAVE_SYS_TIME_H -#include -#endif -#ifdef HAVE_PROCESS_H -#include -#endif - -/* We need to provide a type for gcc_uint64_t. */ -#ifdef __GNUC__ -__extension__ typedef unsigned long long gcc_uint64_t; -#else -typedef unsigned long gcc_uint64_t; -#endif - -#ifndef TMP_MAX -#define TMP_MAX 16384 -#endif - -/* - -@deftypefn Replacement int mkstemps (char *@var{template}, int @var{suffix_len}) - -Generate a unique temporary file name from @var{template}. -@var{template} has the form: - -@example - @var{path}/ccXXXXXX@var{suffix} -@end example - -@var{suffix_len} tells us how long @var{suffix} is (it can be zero -length). The last six characters of @var{template} before @var{suffix} -must be @samp{XXXXXX}; they are replaced with a string that makes the -filename unique. Returns a file descriptor open on the file for -reading and writing. - -@end deftypefn - -*/ - -int -mkstemps ( - char *template, - int suffix_len) -{ - static const char letters[] - = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; - static gcc_uint64_t value; -#ifdef HAVE_GETTIMEOFDAY - struct timeval tv; -#endif - char *XXXXXX; - size_t len; - int count; - - len = strlen (template); - - if ((int) len < 6 + suffix_len - || strncmp (&template[len - 6 - suffix_len], "XXXXXX", 6)) - { - return -1; - } - - XXXXXX = &template[len - 6 - suffix_len]; - -#ifdef HAVE_GETTIMEOFDAY - /* Get some more or less random data. */ - gettimeofday (&tv, NULL); - value += ((gcc_uint64_t) tv.tv_usec << 16) ^ tv.tv_sec ^ getpid (); -#else - value += getpid (); -#endif - - for (count = 0; count < TMP_MAX; ++count) - { - gcc_uint64_t v = value; - int fd; - - /* Fill in the random bits. */ - XXXXXX[0] = letters[v % 62]; - v /= 62; - XXXXXX[1] = letters[v % 62]; - v /= 62; - XXXXXX[2] = letters[v % 62]; - v /= 62; - XXXXXX[3] = letters[v % 62]; - v /= 62; - XXXXXX[4] = letters[v % 62]; - v /= 62; - XXXXXX[5] = letters[v % 62]; - -#ifdef VMS - fd = open (template, O_RDWR|O_CREAT|O_EXCL, 0600, "fop=tmd"); -#else - fd = open (template, O_RDWR|O_CREAT|O_EXCL, 0600); -#endif - if (fd >= 0) - /* The file does not exist. */ - return fd; - - /* This is a random value. It is only necessary that the next - TMP_MAX values generated by adding 7777 to VALUE are different - with (module 2^32). */ - value += 7777; - } - - /* We return the null string if we can't find a unique file name. */ - template[0] = '\0'; - return -1; -} diff --git a/reactos/tools/widl_20080105/proxy.c b/reactos/tools/widl_20080105/proxy.c deleted file mode 100644 index 731629f732c..00000000000 --- a/reactos/tools/widl_20080105/proxy.c +++ /dev/null @@ -1,709 +0,0 @@ -/* - * IDL Compiler - * - * Copyright 2002 Ove Kaaven - * Copyright 2004 Mike McCormack - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" -#include "wine/port.h" - -#include -#include -#ifdef HAVE_UNISTD_H -# include -#endif -#include -#include -#include -#include - -#include "widl.h" -#include "utils.h" -#include "parser.h" -#include "header.h" -#include "typegen.h" - -#define END_OF_LIST(list) \ - do { \ - if (list) { \ - while (NEXT_LINK(list)) \ - list = NEXT_LINK(list); \ - } \ - } while(0) - -static FILE* proxy; -static int indent = 0; - -/* FIXME: support generation of stubless proxies */ - -static void print_proxy( const char *format, ... ) -{ - va_list va; - va_start( va, format ); - print( proxy, indent, format, va ); - va_end( va ); -} - -static void write_stubdescproto(void) -{ - print_proxy( "static const MIDL_STUB_DESC Object_StubDesc;\n"); - print_proxy( "\n"); -} - -static void write_stubdesc(int expr_eval_routines) -{ - print_proxy( "static const MIDL_STUB_DESC Object_StubDesc =\n{\n"); - indent++; - print_proxy( "0,\n"); - print_proxy( "NdrOleAllocate,\n"); - print_proxy( "NdrOleFree,\n"); - print_proxy( "{0}, 0, 0, %s, 0,\n", expr_eval_routines ? "ExprEvalRoutines" : "0"); - print_proxy( "__MIDL_TypeFormatString.Format,\n"); - print_proxy( "1, /* -error bounds_check flag */\n"); - print_proxy( "0x10001, /* Ndr library version */\n"); - print_proxy( "0,\n"); - print_proxy( "0x50100a4, /* MIDL Version 5.1.164 */\n"); - print_proxy( "0,\n"); - print_proxy("%s,\n", list_empty(&user_type_list) ? "0" : "UserMarshalRoutines"); - print_proxy( "0, /* notify & notify_flag routine table */\n"); - print_proxy( "1, /* Flags */\n"); - print_proxy( "0, /* Reserved3 */\n"); - print_proxy( "0, /* Reserved4 */\n"); - print_proxy( "0 /* Reserved5 */\n"); - indent--; - print_proxy( "};\n"); - print_proxy( "\n"); -} - -static void init_proxy(ifref_list_t *ifaces) -{ - if (proxy) return; - if(!(proxy = fopen(proxy_name, "w"))) - error("Could not open %s for output\n", proxy_name); - print_proxy( "/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n", PACKAGE_VERSION, input_name); - print_proxy( "\n"); - print_proxy( "#ifndef __REDQ_RPCPROXY_H_VERSION__\n"); - print_proxy( "#define __REQUIRED_RPCPROXY_H_VERSION__ 440\n"); - print_proxy( "#endif /* __REDQ_RPCPROXY_H_VERSION__ */\n"); - print_proxy( "\n"); - print_proxy( "#define __midl_proxy\n"); - print_proxy( "#include \"objbase.h\"\n"); - print_proxy( "#include \"rpcproxy.h\"\n"); - print_proxy( "#ifndef __RPCPROXY_H_VERSION__\n"); - print_proxy( "#error This code needs a newer version of rpcproxy.h\n"); - print_proxy( "#endif /* __RPCPROXY_H_VERSION__ */\n"); - print_proxy( "\n"); - print_proxy( "#include \"%s\"\n", header_name); - print_proxy( "\n"); - write_formatstringsdecl(proxy, indent, ifaces, need_proxy); - write_stubdescproto(); -} - -static void clear_output_vars( const var_list_t *args ) -{ - const var_t *arg; - - if (!args) return; - LIST_FOR_EACH_ENTRY( arg, args, const var_t, entry ) - { - if (is_attr(arg->attrs, ATTR_OUT) && !is_attr(arg->attrs, ATTR_IN)) { - print_proxy( "if(%s)\n", arg->name ); - indent++; - print_proxy( "MIDL_memset( %s, 0, sizeof( *%s ));\n", arg->name, arg->name ); - indent--; - } - } -} - -int is_var_ptr(const var_t *v) -{ - return is_ptr(v->type); -} - -int cant_be_null(const var_t *v) -{ - /* Search backwards for the most recent pointer attribute. */ - const attr_list_t *attrs = v->attrs; - const type_t *type = v->type; - - if (! attrs && type) - { - attrs = type->attrs; - type = type->ref; - } - - while (attrs) - { - int t = get_attrv(attrs, ATTR_POINTERTYPE); - - if (t == RPC_FC_FP || t == RPC_FC_OP || t == RPC_FC_UP) - return 0; - - if (t == RPC_FC_RP) - return 1; - - if (type) - { - attrs = type->attrs; - type = type->ref; - } - else - attrs = NULL; - } - - return 1; /* Default is RPC_FC_RP. */ -} - -static void proxy_check_pointers( const var_list_t *args ) -{ - const var_t *arg; - - if (!args) return; - LIST_FOR_EACH_ENTRY( arg, args, const var_t, entry ) - { - if (is_var_ptr(arg) && cant_be_null(arg)) { - print_proxy( "if(!%s)\n", arg->name ); - indent++; - print_proxy( "RpcRaiseException(RPC_X_NULL_REF_POINTER);\n"); - indent--; - } - } -} - -static void free_variable( const var_t *arg ) -{ - unsigned int type_offset = arg->type->typestring_offset; - expr_t *iid; - type_t *type = arg->type; - expr_t *size = get_size_is_expr(type, arg->name); - - if (size) - { - print_proxy( "_StubMsg.MaxCount = " ); - write_expr(proxy, size, 0); - fprintf(proxy, ";\n\n"); - print_proxy( "NdrClearOutParameters( &_StubMsg, "); - fprintf(proxy, "&__MIDL_TypeFormatString.Format[%u], ", type_offset ); - fprintf(proxy, "(void*)%s );\n", arg->name ); - return; - } - - switch( type->type ) - { - case RPC_FC_BYTE: - case RPC_FC_CHAR: - case RPC_FC_WCHAR: - case RPC_FC_SHORT: - case RPC_FC_USHORT: - case RPC_FC_ENUM16: - case RPC_FC_LONG: - case RPC_FC_ULONG: - case RPC_FC_ENUM32: - case RPC_FC_STRUCT: - break; - - case RPC_FC_FP: - case RPC_FC_IP: - iid = get_attrp( arg->attrs, ATTR_IIDIS ); - if( iid ) - { - print_proxy( "_StubMsg.MaxCount = (unsigned long) " ); - write_expr(proxy, iid, 1); - print_proxy( ";\n\n" ); - } - print_proxy( "NdrClearOutParameters( &_StubMsg, "); - fprintf(proxy, "&__MIDL_TypeFormatString.Format[%u], ", type_offset ); - fprintf(proxy, "(void*)%s );\n", arg->name ); - break; - - default: - print_proxy("/* FIXME: %s code for %s type %d missing */\n", __FUNCTION__, arg->name, type->type ); - } -} - -static void proxy_free_variables( var_list_t *args ) -{ - const var_t *arg; - - if (!args) return; - LIST_FOR_EACH_ENTRY( arg, args, const var_t, entry ) - if (is_attr(arg->attrs, ATTR_OUT)) - { - free_variable( arg ); - fprintf(proxy, "\n"); - } -} - -static void gen_proxy(type_t *iface, const func_t *cur, int idx, - unsigned int proc_offset) -{ - var_t *def = cur->def; - int has_ret = !is_void(def->type); - - indent = 0; - write_type_decl_left(proxy, def->type); - print_proxy( " STDMETHODCALLTYPE %s_", iface->name); - write_name(proxy, def); - print_proxy( "_Proxy(\n"); - write_args(proxy, cur->args, iface->name, 1, TRUE); - print_proxy( ")\n"); - print_proxy( "{\n"); - indent ++; - /* local variables */ - if (has_ret) { - print_proxy( "" ); - write_type_decl_left(proxy, def->type); - print_proxy( " _RetVal;\n"); - } - print_proxy( "RPC_MESSAGE _RpcMessage;\n" ); - print_proxy( "MIDL_STUB_MESSAGE _StubMsg;\n" ); - if (has_ret) { - if (decl_indirect(def->type)) - print_proxy("void *_p_%s = &%s;\n", - "_RetVal", "_RetVal"); - } - print_proxy( "\n"); - - /* FIXME: trace */ - clear_output_vars( cur->args ); - - print_proxy( "RpcTryExcept\n" ); - print_proxy( "{\n" ); - indent++; - print_proxy( "NdrProxyInitialize(This, &_RpcMessage, &_StubMsg, &Object_StubDesc, %d);\n", idx); - proxy_check_pointers( cur->args ); - - print_proxy( "RpcTryFinally\n" ); - print_proxy( "{\n" ); - indent++; - - write_remoting_arguments(proxy, indent, cur, PASS_IN, PHASE_BUFFERSIZE); - - print_proxy( "NdrProxyGetBuffer(This, &_StubMsg);\n" ); - - write_remoting_arguments(proxy, indent, cur, PASS_IN, PHASE_MARSHAL); - - print_proxy( "NdrProxySendReceive(This, &_StubMsg);\n" ); - fprintf(proxy, "\n"); - print_proxy( "_StubMsg.BufferStart = _RpcMessage.Buffer;\n" ); - print_proxy( "_StubMsg.BufferEnd = _StubMsg.BufferStart + _RpcMessage.BufferLength;\n\n" ); - - print_proxy("if ((_RpcMessage.DataRepresentation & 0xffff) != NDR_LOCAL_DATA_REPRESENTATION)\n"); - indent++; - print_proxy("NdrConvert( &_StubMsg, &__MIDL_ProcFormatString.Format[%u]);\n", proc_offset ); - indent--; - fprintf(proxy, "\n"); - - write_remoting_arguments(proxy, indent, cur, PASS_OUT, PHASE_UNMARSHAL); - - if (has_ret) - { - if (decl_indirect(def->type)) - print_proxy("MIDL_memset(&%s, 0, sizeof(%s));\n", "_RetVal", "_RetVal"); - else if (is_ptr(def->type) || is_array(def->type)) - print_proxy("%s = 0;\n", "_RetVal"); - write_remoting_arguments(proxy, indent, cur, PASS_RETURN, PHASE_UNMARSHAL); - } - - indent--; - print_proxy( "}\n"); - print_proxy( "RpcFinally\n" ); - print_proxy( "{\n" ); - indent++; - print_proxy( "NdrProxyFreeBuffer(This, &_StubMsg);\n" ); - indent--; - print_proxy( "}\n"); - print_proxy( "RpcEndFinally\n" ); - indent--; - print_proxy( "}\n" ); - print_proxy( "RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE)\n" ); - print_proxy( "{\n" ); - if (has_ret) { - indent++; - proxy_free_variables( cur->args ); - print_proxy( "_RetVal = NdrProxyErrorHandler(RpcExceptionCode());\n" ); - indent--; - } - print_proxy( "}\n" ); - print_proxy( "RpcEndExcept\n" ); - - if (has_ret) { - print_proxy( "return _RetVal;\n" ); - } - indent--; - print_proxy( "}\n"); - print_proxy( "\n"); -} - -static void gen_stub(type_t *iface, const func_t *cur, const char *cas, - unsigned int proc_offset) -{ - var_t *def = cur->def; - const var_t *arg; - int has_ret = !is_void(def->type); - - indent = 0; - print_proxy( "void __RPC_STUB %s_", iface->name); - write_name(proxy, def); - print_proxy( "_Stub(\n"); - indent++; - print_proxy( "IRpcStubBuffer* This,\n"); - print_proxy( "IRpcChannelBuffer *_pRpcChannelBuffer,\n"); - print_proxy( "PRPC_MESSAGE _pRpcMessage,\n"); - print_proxy( "DWORD* _pdwStubPhase)\n"); - indent--; - print_proxy( "{\n"); - indent++; - print_proxy("%s * _This = (%s*)((CStdStubBuffer*)This)->pvServerObject;\n", iface->name, iface->name); - print_proxy("MIDL_STUB_MESSAGE _StubMsg;\n"); - declare_stub_args( proxy, indent, cur ); - fprintf(proxy, "\n"); - - /* FIXME: trace */ - - print_proxy("NdrStubInitialize(_pRpcMessage, &_StubMsg, &Object_StubDesc, _pRpcChannelBuffer);\n"); - fprintf(proxy, "\n"); - - write_parameters_init(proxy, indent, cur); - - print_proxy("RpcTryFinally\n"); - print_proxy("{\n"); - indent++; - print_proxy("if ((_pRpcMessage->DataRepresentation & 0xffff) != NDR_LOCAL_DATA_REPRESENTATION)\n"); - indent++; - print_proxy("NdrConvert( &_StubMsg, &__MIDL_ProcFormatString.Format[%u]);\n", proc_offset ); - indent--; - fprintf(proxy, "\n"); - - write_remoting_arguments(proxy, indent, cur, PASS_IN, PHASE_UNMARSHAL); - fprintf(proxy, "\n"); - - assign_stub_out_args( proxy, indent, cur ); - - print_proxy("*_pdwStubPhase = STUB_CALL_SERVER;\n"); - fprintf(proxy, "\n"); - print_proxy(""); - if (has_ret) fprintf(proxy, "_RetVal = "); - if (cas) fprintf(proxy, "%s_%s_Stub", iface->name, cas); - else - { - fprintf(proxy, "_This->lpVtbl->"); - write_name(proxy, def); - } - fprintf(proxy, "(_This"); - - if (cur->args) - { - LIST_FOR_EACH_ENTRY( arg, cur->args, const var_t, entry ) - { - fprintf(proxy, ", "); - if (arg->type->declarray) - fprintf(proxy, "*"); - write_name(proxy, arg); - } - } - fprintf(proxy, ");\n"); - fprintf(proxy, "\n"); - print_proxy("*_pdwStubPhase = STUB_MARSHAL;\n"); - fprintf(proxy, "\n"); - - write_remoting_arguments(proxy, indent, cur, PASS_OUT, PHASE_BUFFERSIZE); - - print_proxy("NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg);\n"); - - write_remoting_arguments(proxy, indent, cur, PASS_OUT, PHASE_MARSHAL); - fprintf(proxy, "\n"); - - if (has_ret) - print_phase_basetype(proxy, indent, PHASE_MARSHAL, PASS_RETURN, def, "_RetVal"); - - indent--; - print_proxy("}\n"); - print_proxy("RpcFinally\n"); - print_proxy("{\n"); - - write_remoting_arguments(proxy, indent+1, cur, PASS_OUT, PHASE_FREE); - - print_proxy("}\n"); - print_proxy("RpcEndFinally\n"); - - print_proxy("_pRpcMessage->BufferLength = _StubMsg.Buffer - (unsigned char *)_pRpcMessage->Buffer;\n"); - indent--; - - print_proxy("}\n"); - print_proxy("\n"); -} - -static int write_proxy_methods(type_t *iface) -{ - const func_t *cur; - int i = 0; - - if (iface->ref) i = write_proxy_methods(iface->ref); - if (iface->funcs) LIST_FOR_EACH_ENTRY( cur, iface->funcs, const func_t, entry ) { - var_t *def = cur->def; - if (!is_callas(def->attrs)) { - if (i) fprintf(proxy, ",\n"); - print_proxy( "%s_", iface->name); - write_name(proxy, def); - fprintf(proxy, "_Proxy"); - i++; - } - } - return i; -} - -static int write_stub_methods(type_t *iface) -{ - const func_t *cur; - int i = 0; - - if (iface->ref) i = write_stub_methods(iface->ref); - else return i; /* skip IUnknown */ - - if (iface->funcs) LIST_FOR_EACH_ENTRY( cur, iface->funcs, const func_t, entry ) { - var_t *def = cur->def; - if (!is_local(def->attrs)) { - if (i) fprintf(proxy,",\n"); - print_proxy( "%s_", iface->name); - write_name(proxy, def); - fprintf(proxy, "_Stub"); - i++; - } - } - return i; -} - -static void write_proxy(type_t *iface, unsigned int *proc_offset) -{ - int midx = -1, stubs; - const func_t *cur; - - if (!iface->funcs) return; - - /* FIXME: check for [oleautomation], shouldn't generate proxies/stubs if specified */ - - fprintf(proxy, "/*****************************************************************************\n"); - fprintf(proxy, " * %s interface\n", iface->name); - fprintf(proxy, " */\n"); - LIST_FOR_EACH_ENTRY( cur, iface->funcs, const func_t, entry ) - { - const var_t *def = cur->def; - if (!is_local(def->attrs)) { - const var_t *cas = is_callas(def->attrs); - const char *cname = cas ? cas->name : NULL; - int idx = cur->idx; - if (cname) { - const func_t *m; - LIST_FOR_EACH_ENTRY( m, iface->funcs, const func_t, entry ) - if (!strcmp(m->def->name, cname)) - { - idx = m->idx; - break; - } - } - gen_proxy(iface, cur, idx, *proc_offset); - gen_stub(iface, cur, cname, *proc_offset); - *proc_offset += get_size_procformatstring_func( cur ); - if (midx == -1) midx = idx; - else if (midx != idx) error("method index mismatch in write_proxy\n"); - midx++; - } - } - - /* proxy vtable */ - print_proxy( "static const CINTERFACE_PROXY_VTABLE(%d) _%sProxyVtbl =\n", midx, iface->name); - print_proxy( "{\n"); - indent++; - print_proxy( "{\n", iface->name); - indent++; - print_proxy( "&IID_%s,\n", iface->name); - indent--; - print_proxy( "},\n"); - print_proxy( "{\n"); - indent++; - write_proxy_methods(iface); - fprintf(proxy, "\n"); - indent--; - print_proxy( "}\n"); - indent--; - print_proxy( "};\n"); - fprintf(proxy, "\n\n"); - - /* stub vtable */ - print_proxy( "static const PRPC_STUB_FUNCTION %s_table[] =\n", iface->name); - print_proxy( "{\n"); - indent++; - stubs = write_stub_methods(iface); - fprintf(proxy, "\n"); - indent--; - fprintf(proxy, "};\n"); - print_proxy( "\n"); - print_proxy( "static const CInterfaceStubVtbl _%sStubVtbl =\n", iface->name); - print_proxy( "{\n"); - indent++; - print_proxy( "{\n"); - indent++; - print_proxy( "&IID_%s,\n", iface->name); - print_proxy( "0,\n"); - print_proxy( "%d,\n", stubs+3); - print_proxy( "&%s_table[-3],\n", iface->name); - indent--; - print_proxy( "},\n", iface->name); - print_proxy( "{\n"); - indent++; - print_proxy( "CStdStubBuffer_METHODS\n"); - indent--; - print_proxy( "}\n"); - indent--; - print_proxy( "};\n"); - print_proxy( "\n"); -} - -static int does_any_iface(const ifref_list_t *ifaces, type_pred_t pred) -{ - ifref_t *ir; - - if (ifaces) - LIST_FOR_EACH_ENTRY(ir, ifaces, ifref_t, entry) - if (pred(ir->iface)) - return TRUE; - - return FALSE; -} - -int need_proxy(const type_t *iface) -{ - return is_object(iface->attrs) && !is_local(iface->attrs); -} - -int need_stub(const type_t *iface) -{ - return !is_object(iface->attrs) && !is_local(iface->attrs); -} - -int need_proxy_file(const ifref_list_t *ifaces) -{ - return does_any_iface(ifaces, need_proxy); -} - -int need_stub_files(const ifref_list_t *ifaces) -{ - return does_any_iface(ifaces, need_stub); -} - -void write_proxies(ifref_list_t *ifaces) -{ - ifref_t *cur; - int expr_eval_routines; - char *file_id = proxy_token; - int c; - unsigned int proc_offset = 0; - - if (!do_proxies) return; - if (do_everything && !need_proxy_file(ifaces)) return; - - init_proxy(ifaces); - if(!proxy) return; - - if (ifaces) - LIST_FOR_EACH_ENTRY( cur, ifaces, ifref_t, entry ) - if (need_proxy(cur->iface)) - write_proxy(cur->iface, &proc_offset); - - expr_eval_routines = write_expr_eval_routines(proxy, proxy_token); - if (expr_eval_routines) - write_expr_eval_routine_list(proxy, proxy_token); - write_user_quad_list(proxy); - write_stubdesc(expr_eval_routines); - - print_proxy( "#if !defined(__RPC_WIN32__)\n"); - print_proxy( "#error Currently only Wine and WIN32 are supported.\n"); - print_proxy( "#endif\n"); - print_proxy( "\n"); - write_procformatstring(proxy, ifaces, need_proxy); - write_typeformatstring(proxy, ifaces, need_proxy); - - fprintf(proxy, "static const CInterfaceProxyVtbl* const _%s_ProxyVtblList[] =\n", file_id); - fprintf(proxy, "{\n"); - if (ifaces) - LIST_FOR_EACH_ENTRY( cur, ifaces, ifref_t, entry ) - if(cur->iface->ref && cur->iface->funcs && need_proxy(cur->iface)) - fprintf(proxy, " (const CInterfaceProxyVtbl*)&_%sProxyVtbl,\n", cur->iface->name); - - fprintf(proxy, " 0\n"); - fprintf(proxy, "};\n"); - fprintf(proxy, "\n"); - - fprintf(proxy, "static const CInterfaceStubVtbl* const _%s_StubVtblList[] =\n", file_id); - fprintf(proxy, "{\n"); - if (ifaces) - LIST_FOR_EACH_ENTRY( cur, ifaces, ifref_t, entry ) - if(cur->iface->ref && cur->iface->funcs && need_proxy(cur->iface)) - fprintf(proxy, " (const CInterfaceStubVtbl*)&_%sStubVtbl,\n", cur->iface->name); - fprintf(proxy, " 0\n"); - fprintf(proxy, "};\n"); - fprintf(proxy, "\n"); - - fprintf(proxy, "static PCInterfaceName const _%s_InterfaceNamesList[] =\n", file_id); - fprintf(proxy, "{\n"); - if (ifaces) - LIST_FOR_EACH_ENTRY( cur, ifaces, ifref_t, entry ) - if(cur->iface->ref && cur->iface->funcs && need_proxy(cur->iface)) - fprintf(proxy, " \"%s\",\n", cur->iface->name); - fprintf(proxy, " 0\n"); - fprintf(proxy, "};\n"); - fprintf(proxy, "\n"); - - fprintf(proxy, "#define _%s_CHECK_IID(n) IID_GENERIC_CHECK_IID(_%s, pIID, n)\n", file_id, file_id); - fprintf(proxy, "\n"); - fprintf(proxy, "int __stdcall _%s_IID_Lookup(const IID* pIID, int* pIndex)\n", file_id); - fprintf(proxy, "{\n"); - c = 0; - if (ifaces) - LIST_FOR_EACH_ENTRY( cur, ifaces, ifref_t, entry ) - if(cur->iface->ref && cur->iface->funcs && need_proxy(cur->iface)) - { - fprintf(proxy, " if (!_%s_CHECK_IID(%d))\n", file_id, c); - fprintf(proxy, " {\n"); - fprintf(proxy, " *pIndex = %d;\n", c); - fprintf(proxy, " return 1;\n"); - fprintf(proxy, " }\n"); - c++; - } - fprintf(proxy, " return 0;\n"); - fprintf(proxy, "}\n"); - fprintf(proxy, "\n"); - - fprintf(proxy, "const ExtendedProxyFileInfo %s_ProxyFileInfo =\n", file_id); - fprintf(proxy, "{\n"); - fprintf(proxy, " (const PCInterfaceProxyVtblList*)&_%s_ProxyVtblList,\n", file_id); - fprintf(proxy, " (const PCInterfaceStubVtblList*)&_%s_StubVtblList,\n", file_id); - fprintf(proxy, " _%s_InterfaceNamesList,\n", file_id); - fprintf(proxy, " 0,\n"); - fprintf(proxy, " &_%s_IID_Lookup,\n", file_id); - fprintf(proxy, " %d,\n", c); - fprintf(proxy, " 1,\n"); - fprintf(proxy, " 0,\n"); - fprintf(proxy, " 0,\n"); - fprintf(proxy, " 0,\n"); - fprintf(proxy, " 0\n"); - fprintf(proxy, "};\n"); - - fclose(proxy); -} diff --git a/reactos/tools/widl_20080105/server.c b/reactos/tools/widl_20080105/server.c deleted file mode 100644 index 3fc6dd80053..00000000000 --- a/reactos/tools/widl_20080105/server.c +++ /dev/null @@ -1,453 +0,0 @@ -/* - * IDL Compiler - * - * Copyright 2005-2006 Eric Kohl - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" -#include "wine/port.h" - -#include -#include -#ifdef HAVE_UNISTD_H -# include -#endif -#include -#include -#include -#include - -#include "widl.h" -#include "utils.h" -#include "parser.h" -#include "header.h" - -#include "typegen.h" - -static FILE* server; -static int indent = 0; - - -static void print_server(const char *format, ...) -{ - va_list va; - va_start(va, format); - print(server, indent, format, va); - va_end(va); -} - -static void write_function_stubs(type_t *iface, unsigned int *proc_offset) -{ - char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE); - int explicit_handle = is_attr(iface->attrs, ATTR_EXPLICIT_HANDLE); - const func_t *func; - const var_t *var; - const var_t* explicit_handle_var; - - if (!iface->funcs) return; - LIST_FOR_EACH_ENTRY( func, iface->funcs, const func_t, entry ) - { - const var_t *def = func->def; - - /* check for a defined binding handle */ - explicit_handle_var = get_explicit_handle_var(func); - if (explicit_handle) - { - if (!explicit_handle_var) - { - error("%s() does not define an explicit binding handle!\n", def->name); - return; - } - } - else if (implicit_handle) - { - if (explicit_handle_var) - { - error("%s() must not define a binding handle!\n", def->name); - return; - } - } - - fprintf(server, "void __RPC_STUB\n"); - fprintf(server, "%s_", iface->name); - write_name(server, def); - fprintf(server, "(\n"); - indent++; - print_server("PRPC_MESSAGE _pRpcMessage)\n"); - indent--; - - /* write the functions body */ - fprintf(server, "{\n"); - indent++; - - /* Declare arguments */ - declare_stub_args(server, indent, func); - - print_server("MIDL_STUB_MESSAGE _StubMsg;\n"); - print_server("RPC_STATUS _Status;\n"); - fprintf(server, "\n"); - - - print_server("((void)(_Status));\n"); - print_server("NdrServerInitializeNew(\n"); - indent++; - print_server("_pRpcMessage,\n"); - print_server("&_StubMsg,\n"); - print_server("&%s_StubDesc);\n", iface->name); - indent--; - fprintf(server, "\n"); - - write_parameters_init(server, indent, func); - - if (explicit_handle_var) - { - print_server("%s = _pRpcMessage->Handle;\n", explicit_handle_var->name); - fprintf(server, "\n"); - } - - print_server("RpcTryFinally\n"); - print_server("{\n"); - indent++; - print_server("RpcTryExcept\n"); - print_server("{\n"); - indent++; - - if (func->args) - { - print_server("if ((_pRpcMessage->DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION)\n"); - indent++; - print_server("NdrConvert(\n"); - indent++; - print_server("(PMIDL_STUB_MESSAGE)&_StubMsg,\n"); - print_server("(PFORMAT_STRING)&__MIDL_ProcFormatString.Format[%u]);\n", *proc_offset); - indent -= 2; - fprintf(server, "\n"); - - /* unmarshall arguments */ - write_remoting_arguments(server, indent, func, PASS_IN, PHASE_UNMARSHAL); - } - - print_server("if (_StubMsg.Buffer > _StubMsg.BufferEnd)\n"); - print_server("{\n"); - indent++; - print_server("RpcRaiseException(RPC_X_BAD_STUB_DATA);\n"); - indent--; - print_server("}\n"); - indent--; - print_server("}\n"); - print_server("RpcExcept(RPC_BAD_STUB_DATA_EXCEPTION_FILTER)\n"); - print_server("{\n"); - indent++; - print_server("RpcRaiseException(RPC_X_BAD_STUB_DATA);\n"); - indent--; - print_server("}\n"); - print_server("RpcEndExcept\n"); - fprintf(server, "\n"); - - /* Assign 'out' arguments */ - assign_stub_out_args(server, indent, func); - - /* Call the real server function */ - if (!is_void(def->type)) - print_server("_RetVal = "); - else - print_server(""); - write_prefix_name(server, prefix_server, def); - - if (func->args) - { - int first_arg = 1; - - fprintf(server, "(\n"); - indent++; - LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) - { - if (first_arg) - first_arg = 0; - else - fprintf(server, ",\n"); - if (is_context_handle(var->type)) - { - print_server("("); - write_type_decl_left(server, var->type); - fprintf(server, ")%sNDRSContextValue(%s)", is_ptr(var->type) ? "" : "*", var->name); - } - else - { - print_server(""); - if (var->type->declarray) - fprintf(server, "*"); - write_name(server, var); - } - } - fprintf(server, ");\n"); - indent--; - } - else - { - fprintf(server, "();\n"); - } - - if (has_out_arg_or_return(func)) - { - write_remoting_arguments(server, indent, func, PASS_OUT, PHASE_BUFFERSIZE); - - if (!is_void(def->type)) - write_remoting_arguments(server, indent, func, PASS_RETURN, PHASE_BUFFERSIZE); - - print_server("_pRpcMessage->BufferLength = _StubMsg.BufferLength;\n"); - fprintf(server, "\n"); - print_server("_Status = I_RpcGetBuffer(_pRpcMessage);\n"); - print_server("if (_Status)\n"); - indent++; - print_server("RpcRaiseException(_Status);\n"); - indent--; - fprintf(server, "\n"); - print_server("_StubMsg.Buffer = (unsigned char *)_pRpcMessage->Buffer;\n"); - fprintf(server, "\n"); - } - - /* marshall arguments */ - write_remoting_arguments(server, indent, func, PASS_OUT, PHASE_MARSHAL); - - /* marshall the return value */ - if (!is_void(def->type)) - write_remoting_arguments(server, indent, func, PASS_RETURN, PHASE_MARSHAL); - - indent--; - print_server("}\n"); - print_server("RpcFinally\n"); - print_server("{\n"); - indent++; - - write_remoting_arguments(server, indent, func, PASS_OUT, PHASE_FREE); - - indent--; - print_server("}\n"); - print_server("RpcEndFinally\n"); - - /* calculate buffer length */ - fprintf(server, "\n"); - print_server("_pRpcMessage->BufferLength =\n"); - indent++; - print_server("(unsigned int)(_StubMsg.Buffer - (unsigned char *)_pRpcMessage->Buffer);\n"); - indent--; - indent--; - fprintf(server, "}\n"); - fprintf(server, "\n"); - - /* update proc_offset */ - *proc_offset += get_size_procformatstring_func( func ); - } -} - - -static void write_dispatchtable(type_t *iface) -{ - unsigned long ver = get_attrv(iface->attrs, ATTR_VERSION); - unsigned long method_count = 0; - const func_t *func; - - print_server("static RPC_DISPATCH_FUNCTION %s_table[] =\n", iface->name); - print_server("{\n"); - indent++; - - if (iface->funcs) LIST_FOR_EACH_ENTRY( func, iface->funcs, const func_t, entry ) - { - var_t *def = func->def; - - print_server("%s_", iface->name); - write_name(server, def); - fprintf(server, ",\n"); - - method_count++; - } - print_server("0\n"); - indent--; - print_server("};\n"); - print_server("RPC_DISPATCH_TABLE %s_v%d_%d_DispatchTable =\n", iface->name, MAJORVERSION(ver), MINORVERSION(ver)); - print_server("{\n"); - indent++; - print_server("%u,\n", method_count); - print_server("%s_table\n", iface->name); - indent--; - print_server("};\n"); - fprintf(server, "\n"); -} - - -static void write_stubdescdecl(type_t *iface) -{ - print_server("static const MIDL_STUB_DESC %s_StubDesc;\n", iface->name); - fprintf(server, "\n"); -} - - -static void write_stubdescriptor(type_t *iface, int expr_eval_routines) -{ - print_server("static const MIDL_STUB_DESC %s_StubDesc =\n", iface->name); - print_server("{\n"); - indent++; - print_server("(void *)& %s___RpcServerInterface,\n", iface->name); - print_server("MIDL_user_allocate,\n"); - print_server("MIDL_user_free,\n"); - print_server("{\n"); - indent++; - print_server("0,\n"); - indent--; - print_server("},\n"); - print_server("0,\n"); - print_server("0,\n"); - if (expr_eval_routines) - print_server("ExprEvalRoutines,\n"); - else - print_server("0,\n"); - print_server("0,\n"); - print_server("__MIDL_TypeFormatString.Format,\n"); - print_server("1, /* -error bounds_check flag */\n"); - print_server("0x10001, /* Ndr library version */\n"); - print_server("0,\n"); - print_server("0x50100a4, /* MIDL Version 5.1.164 */\n"); - print_server("0,\n"); - print_server("%s,\n", list_empty(&user_type_list) ? "0" : "UserMarshalRoutines"); - print_server("0, /* notify & notify_flag routine table */\n"); - print_server("1, /* Flags */\n"); - print_server("0, /* Reserved3 */\n"); - print_server("0, /* Reserved4 */\n"); - print_server("0 /* Reserved5 */\n"); - indent--; - print_server("};\n"); - fprintf(server, "\n"); -} - - -static void write_serverinterfacedecl(type_t *iface) -{ - unsigned long ver = get_attrv(iface->attrs, ATTR_VERSION); - UUID *uuid = get_attrp(iface->attrs, ATTR_UUID); - const str_list_t *endpoints = get_attrp(iface->attrs, ATTR_ENDPOINT); - - if (endpoints) write_endpoints( server, iface->name, endpoints ); - - print_server("extern RPC_DISPATCH_TABLE %s_v%d_%d_DispatchTable;\n", iface->name, MAJORVERSION(ver), MINORVERSION(ver)); - fprintf(server, "\n"); - print_server("static const RPC_SERVER_INTERFACE %s___RpcServerInterface =\n", iface->name ); - print_server("{\n"); - indent++; - print_server("sizeof(RPC_SERVER_INTERFACE),\n"); - print_server("{{0x%08lx,0x%04x,0x%04x,{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x}},{%d,%d}},\n", - uuid->Data1, uuid->Data2, uuid->Data3, uuid->Data4[0], uuid->Data4[1], - uuid->Data4[2], uuid->Data4[3], uuid->Data4[4], uuid->Data4[5], uuid->Data4[6], - uuid->Data4[7], MAJORVERSION(ver), MINORVERSION(ver)); - print_server("{{0x8a885d04,0x1ceb,0x11c9,{0x9f,0xe8,0x08,0x00,0x2b,0x10,0x48,0x60}},{2,0}},\n"); /* FIXME */ - print_server("&%s_v%d_%d_DispatchTable,\n", iface->name, MAJORVERSION(ver), MINORVERSION(ver)); - if (endpoints) - { - print_server("%u,\n", list_count(endpoints)); - print_server("(PRPC_PROTSEQ_ENDPOINT)%s__RpcProtseqEndpoint,\n", iface->name); - } - else - { - print_server("0,\n"); - print_server("0,\n"); - } - print_server("0,\n"); - print_server("0,\n"); - print_server("0,\n"); - indent--; - print_server("};\n"); - if (old_names) - print_server("RPC_IF_HANDLE %s_ServerIfHandle = (RPC_IF_HANDLE)& %s___RpcServerInterface;\n", - iface->name, iface->name); - else - print_server("RPC_IF_HANDLE %s%s_v%d_%d_s_ifspec = (RPC_IF_HANDLE)& %s___RpcServerInterface;\n", - prefix_server, iface->name, MAJORVERSION(ver), MINORVERSION(ver), iface->name); - fprintf(server, "\n"); -} - - -static void init_server(void) -{ - if (server) - return; - if (!(server = fopen(server_name, "w"))) - error("Could not open %s for output\n", server_name); - - print_server("/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n", PACKAGE_VERSION, input_name); - print_server("#include \n"); - fprintf(server, "\n"); - print_server("#define _SEH_NO_NATIVE_NLG\n"); - print_server("#include \"%s\"\n", header_name); - fprintf(server, "\n"); -} - - -void write_server(ifref_list_t *ifaces) -{ - unsigned int proc_offset = 0; - int expr_eval_routines; - ifref_t *iface; - - if (!do_server) - return; - if (do_everything && !need_stub_files(ifaces)) - return; - - init_server(); - if (!server) - return; - - write_formatstringsdecl(server, indent, ifaces, need_stub); - expr_eval_routines = write_expr_eval_routines(server, server_token); - if (expr_eval_routines) - write_expr_eval_routine_list(server, server_token); - write_user_quad_list(server); - - if (ifaces) LIST_FOR_EACH_ENTRY( iface, ifaces, ifref_t, entry ) - { - if (!need_stub(iface->iface)) - continue; - - fprintf(server, "/*****************************************************************************\n"); - fprintf(server, " * %s interface\n", iface->iface->name); - fprintf(server, " */\n"); - fprintf(server, "\n"); - - if (iface->iface->funcs) - { - write_serverinterfacedecl(iface->iface); - write_stubdescdecl(iface->iface); - - write_function_stubs(iface->iface, &proc_offset); - - print_server("#if !defined(__RPC_WIN32__)\n"); - print_server("#error Invalid build platform for this stub.\n"); - print_server("#endif\n"); - - fprintf(server, "\n"); - write_stubdescriptor(iface->iface, expr_eval_routines); - write_dispatchtable(iface->iface); - } - } - - fprintf(server, "\n"); - - write_procformatstring(server, ifaces, need_stub); - write_typeformatstring(server, ifaces, need_stub); - - fclose(server); -} diff --git a/reactos/tools/widl_20080105/typegen.c b/reactos/tools/widl_20080105/typegen.c deleted file mode 100644 index f40399f16b2..00000000000 --- a/reactos/tools/widl_20080105/typegen.c +++ /dev/null @@ -1,3309 +0,0 @@ -/* - * Format String Generator for IDL Compiler - * - * Copyright 2005-2006 Eric Kohl - * Copyright 2005-2006 Robert Shearman - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" -#include "wine/port.h" - -#include -#include -#ifdef HAVE_UNISTD_H -# include -#endif -#include -#include -#include -#include -#include - -#include "widl.h" -#include "utils.h" -#include "parser.h" -#include "header.h" -#include "wine/list.h" - -#include "typegen.h" - -static const func_t *current_func; -static const type_t *current_structure; - -static struct list expr_eval_routines = LIST_INIT(expr_eval_routines); -struct expr_eval_routine -{ - struct list entry; - const type_t *structure; - unsigned int baseoff; - const expr_t *expr; -}; - -static size_t fields_memsize(const var_list_t *fields, unsigned int *align); -static size_t write_struct_tfs(FILE *file, type_t *type, const char *name, unsigned int *tfsoff); -static int write_embedded_types(FILE *file, const attr_list_t *attrs, type_t *type, - const char *name, int write_ptr, unsigned int *tfsoff); -static const var_t *find_array_or_string_in_struct(const type_t *type); - -const char *string_of_type(unsigned char type) -{ - switch (type) - { - case RPC_FC_BYTE: return "FC_BYTE"; - case RPC_FC_CHAR: return "FC_CHAR"; - case RPC_FC_SMALL: return "FC_SMALL"; - case RPC_FC_USMALL: return "FC_USMALL"; - case RPC_FC_WCHAR: return "FC_WCHAR"; - case RPC_FC_SHORT: return "FC_SHORT"; - case RPC_FC_USHORT: return "FC_USHORT"; - case RPC_FC_LONG: return "FC_LONG"; - case RPC_FC_ULONG: return "FC_ULONG"; - case RPC_FC_FLOAT: return "FC_FLOAT"; - case RPC_FC_HYPER: return "FC_HYPER"; - case RPC_FC_DOUBLE: return "FC_DOUBLE"; - case RPC_FC_ENUM16: return "FC_ENUM16"; - case RPC_FC_ENUM32: return "FC_ENUM32"; - case RPC_FC_IGNORE: return "FC_IGNORE"; - case RPC_FC_ERROR_STATUS_T: return "FC_ERROR_STATUS_T"; - case RPC_FC_RP: return "FC_RP"; - case RPC_FC_UP: return "FC_UP"; - case RPC_FC_OP: return "FC_OP"; - case RPC_FC_FP: return "FC_FP"; - case RPC_FC_ENCAPSULATED_UNION: return "FC_ENCAPSULATED_UNION"; - case RPC_FC_NON_ENCAPSULATED_UNION: return "FC_NON_ENCAPSULATED_UNION"; - case RPC_FC_STRUCT: return "FC_STRUCT"; - case RPC_FC_PSTRUCT: return "FC_PSTRUCT"; - case RPC_FC_CSTRUCT: return "FC_CSTRUCT"; - case RPC_FC_CPSTRUCT: return "FC_CPSTRUCT"; - case RPC_FC_CVSTRUCT: return "FC_CVSTRUCT"; - case RPC_FC_BOGUS_STRUCT: return "FC_BOGUS_STRUCT"; - case RPC_FC_SMFARRAY: return "FC_SMFARRAY"; - case RPC_FC_LGFARRAY: return "FC_LGFARRAY"; - case RPC_FC_SMVARRAY: return "FC_SMVARRAY"; - case RPC_FC_LGVARRAY: return "FC_LGVARRAY"; - case RPC_FC_CARRAY: return "FC_CARRAY"; - case RPC_FC_CVARRAY: return "FC_CVARRAY"; - case RPC_FC_BOGUS_ARRAY: return "FC_BOGUS_ARRAY"; - case RPC_FC_ALIGNM4: return "FC_ALIGNM4"; - case RPC_FC_ALIGNM8: return "FC_ALIGNM8"; - case RPC_FC_POINTER: return "FC_POINTER"; - case RPC_FC_C_CSTRING: return "FC_C_CSTRING"; - case RPC_FC_C_WSTRING: return "FC_C_WSTRING"; - case RPC_FC_CSTRING: return "FC_CSTRING"; - case RPC_FC_WSTRING: return "FC_WSTRING"; - default: - error("string_of_type: unknown type 0x%02x\n", type); - return NULL; - } -} - -int is_struct(unsigned char type) -{ - switch (type) - { - case RPC_FC_STRUCT: - case RPC_FC_PSTRUCT: - case RPC_FC_CSTRUCT: - case RPC_FC_CPSTRUCT: - case RPC_FC_CVSTRUCT: - case RPC_FC_BOGUS_STRUCT: - return 1; - default: - return 0; - } -} - -static int is_non_complex_struct(const type_t *type) -{ - switch (type->type) - { - case RPC_FC_STRUCT: - case RPC_FC_PSTRUCT: - case RPC_FC_CSTRUCT: - case RPC_FC_CPSTRUCT: - case RPC_FC_CVSTRUCT: - return 1; - default: - return 0; - } -} - -int is_union(unsigned char type) -{ - switch (type) - { - case RPC_FC_ENCAPSULATED_UNION: - case RPC_FC_NON_ENCAPSULATED_UNION: - return 1; - default: - return 0; - } -} - -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; - unsigned short off = 0; - LIST_FOR_EACH_ENTRY(ut, &user_type_list, user_type_t, entry) - { - if (strcmp(name, ut->name) == 0) - return off; - ++off; - } - error("user_type_offset: couldn't find type (%s)\n", name); - return 0; -} - -static void update_tfsoff(type_t *type, unsigned int offset, FILE *file) -{ - type->typestring_offset = offset; - if (file) type->tfswrite = FALSE; -} - -static void guard_rec(type_t *type) -{ - /* types that contain references to themselves (like a linked list), - need to be shielded from infinite recursion when writing embedded - types */ - if (type->typestring_offset) - type->tfswrite = FALSE; - else - type->typestring_offset = 1; -} - -static type_t *get_user_type(const type_t *t, const char **pname) -{ - for (;;) - { - type_t *ut = get_attrp(t->attrs, ATTR_WIREMARSHAL); - if (ut) - { - if (pname) - *pname = t->name; - return ut; - } - - if (t->kind == TKIND_ALIAS) - t = t->orig; - else - return 0; - } -} - -int is_user_type(const type_t *t) -{ - return get_user_type(t, NULL) != NULL; -} - -static int is_embedded_complex(const type_t *type) -{ - unsigned char tc = type->type; - return is_struct(tc) || is_union(tc) || is_array(type) || is_user_type(type) - || (is_ptr(type) && type->ref->type == RPC_FC_IP); -} - -static const char *get_context_handle_type_name(const type_t *type) -{ - const type_t *t; - for (t = type; is_ptr(t); t = t->ref) - if (is_attr(t->attrs, ATTR_CONTEXTHANDLE)) - return t->name; - assert(0); - return NULL; -} - -/* This is actually fairly involved to implement precisely, due to the - effects attributes may have and things like that. Right now this is - only used for optimization, so just check for a very small set of - criteria that guarantee the types are equivalent; assume every thing - else is different. */ -static int compare_type(const type_t *a, const type_t *b) -{ - if (a == b - || (a->name - && b->name - && strcmp(a->name, b->name) == 0)) - return 0; - /* Ordering doesn't need to be implemented yet. */ - return 1; -} - -static int compare_expr(const expr_t *a, const expr_t *b) -{ - int ret; - - if (a->type != b->type) - return a->type - b->type; - - switch (a->type) - { - case EXPR_NUM: - case EXPR_HEXNUM: - case EXPR_TRUEFALSE: - return a->u.lval - b->u.lval; - case EXPR_DOUBLE: - return a->u.dval - b->u.dval; - case EXPR_IDENTIFIER: - return strcmp(a->u.sval, b->u.sval); - case EXPR_COND: - ret = compare_expr(a->ref, b->ref); - if (ret != 0) - return ret; - ret = compare_expr(a->u.ext, b->u.ext); - if (ret != 0) - return ret; - return compare_expr(a->ext2, b->ext2); - case EXPR_OR: - case EXPR_AND: - case EXPR_ADD: - case EXPR_SUB: - case EXPR_MUL: - case EXPR_DIV: - case EXPR_SHL: - case EXPR_SHR: - ret = compare_expr(a->ref, b->ref); - if (ret != 0) - return ret; - return compare_expr(a->u.ext, b->u.ext); - case EXPR_CAST: - ret = compare_type(a->u.tref, b->u.tref); - if (ret != 0) - return ret; - /* Fall through. */ - case EXPR_NOT: - case EXPR_NEG: - case EXPR_PPTR: - case EXPR_ADDRESSOF: - return compare_expr(a->ref, b->ref); - case EXPR_SIZEOF: - return compare_type(a->u.tref, b->u.tref); - case EXPR_VOID: - return 0; - } - return -1; -} - -#define WRITE_FCTYPE(file, fctype, typestring_offset) \ - do { \ - if (file) \ - fprintf(file, "/* %2u */\n", typestring_offset); \ - print_file((file), 2, "0x%02x, /* " #fctype " */\n", RPC_##fctype); \ - } \ - while (0) - -static void print_file(FILE *file, int indent, const char *format, ...) -{ - va_list va; - va_start(va, format); - print(file, indent, format, va); - va_end(va); -} - -void print(FILE *file, int indent, const char *format, va_list va) -{ - if (file) - { - if (format[0] != '\n') - while (0 < indent--) - fprintf(file, " "); - vfprintf(file, format, va); - } -} - - -static void write_var_init(FILE *file, int indent, const type_t *t, const char *n) -{ - if (decl_indirect(t)) - print_file(file, indent, "MIDL_memset(&%s, 0, sizeof(%s));\n", n, n); - else if (is_ptr(t) || is_array(t)) - print_file(file, indent, "%s = 0;\n", n); -} - -void write_parameters_init(FILE *file, int indent, const func_t *func) -{ - const var_t *var; - - if (!is_void(func->def->type)) - write_var_init(file, indent, func->def->type, "_RetVal"); - - if (!func->args) - return; - - LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) - write_var_init(file, indent, var->type, var->name); - - fprintf(file, "\n"); -} - -static void write_formatdesc(FILE *f, int indent, const char *str) -{ - print_file(f, indent, "typedef struct _MIDL_%s_FORMAT_STRING\n", str); - print_file(f, indent, "{\n"); - print_file(f, indent + 1, "short Pad;\n"); - print_file(f, indent + 1, "unsigned char Format[%s_FORMAT_STRING_SIZE];\n", str); - print_file(f, indent, "} MIDL_%s_FORMAT_STRING;\n", str); - print_file(f, indent, "\n"); -} - -void write_formatstringsdecl(FILE *f, int indent, ifref_list_t *ifaces, type_pred_t pred) -{ - print_file(f, indent, "#define TYPE_FORMAT_STRING_SIZE %d\n", - get_size_typeformatstring(ifaces, pred)); - - print_file(f, indent, "#define PROC_FORMAT_STRING_SIZE %d\n", - get_size_procformatstring(ifaces, pred)); - - fprintf(f, "\n"); - write_formatdesc(f, indent, "TYPE"); - write_formatdesc(f, indent, "PROC"); - fprintf(f, "\n"); - print_file(f, indent, "static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString;\n"); - print_file(f, indent, "static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString;\n"); - print_file(f, indent, "\n"); -} - -static inline int is_base_type(unsigned char type) -{ - switch (type) - { - case RPC_FC_BYTE: - case RPC_FC_CHAR: - case RPC_FC_USMALL: - case RPC_FC_SMALL: - case RPC_FC_WCHAR: - case RPC_FC_USHORT: - case RPC_FC_SHORT: - case RPC_FC_ULONG: - case RPC_FC_LONG: - case RPC_FC_HYPER: - case RPC_FC_IGNORE: - case RPC_FC_FLOAT: - case RPC_FC_DOUBLE: - case RPC_FC_ENUM16: - case RPC_FC_ENUM32: - case RPC_FC_ERROR_STATUS_T: - case RPC_FC_BIND_PRIMITIVE: - return TRUE; - - default: - return FALSE; - } -} - -int decl_indirect(const type_t *t) -{ - return is_user_type(t) - || (!is_base_type(t->type) - && !is_ptr(t) - && !is_array(t)); -} - -static size_t write_procformatstring_var(FILE *file, int indent, - const var_t *var, int is_return) -{ - size_t size; - const type_t *type = var->type; - - int is_in = is_attr(var->attrs, ATTR_IN); - int is_out = is_attr(var->attrs, ATTR_OUT); - - if (!is_in && !is_out) is_in = TRUE; - - if (!type->declarray && is_base_type(type->type)) - { - if (is_return) - print_file(file, indent, "0x53, /* FC_RETURN_PARAM_BASETYPE */\n"); - else - print_file(file, indent, "0x4e, /* FC_IN_PARAM_BASETYPE */\n"); - - if (type->type == RPC_FC_BIND_PRIMITIVE) - { - print_file(file, indent, "0x%02x, /* FC_IGNORE */\n", RPC_FC_IGNORE); - size = 2; /* includes param type prefix */ - } - else if (is_base_type(type->type)) - { - print_file(file, indent, "0x%02x, /* %s */\n", type->type, string_of_type(type->type)); - size = 2; /* includes param type prefix */ - } - else - { - error("Unknown/unsupported type: %s (0x%02x)\n", var->name, type->type); - size = 0; - } - } - else - { - if (is_return) - print_file(file, indent, "0x52, /* FC_RETURN_PARAM */\n"); - else if (is_in && is_out) - print_file(file, indent, "0x50, /* FC_IN_OUT_PARAM */\n"); - else if (is_out) - print_file(file, indent, "0x51, /* FC_OUT_PARAM */\n"); - else - print_file(file, indent, "0x4d, /* FC_IN_PARAM */\n"); - - print_file(file, indent, "0x01,\n"); - print_file(file, indent, "NdrFcShort(0x%x),\n", type->typestring_offset); - size = 4; /* includes param type prefix */ - } - return size; -} - -void write_procformatstring(FILE *file, const ifref_list_t *ifaces, type_pred_t pred) -{ - const ifref_t *iface; - int indent = 0; - const var_t *var; - - print_file(file, indent, "static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString =\n"); - print_file(file, indent, "{\n"); - indent++; - print_file(file, indent, "0,\n"); - print_file(file, indent, "{\n"); - indent++; - - if (ifaces) LIST_FOR_EACH_ENTRY( iface, ifaces, const ifref_t, entry ) - { - if (!pred(iface->iface)) - continue; - - if (iface->iface->funcs) - { - const func_t *func; - LIST_FOR_EACH_ENTRY( func, iface->iface->funcs, const func_t, entry ) - { - if (is_local(func->def->attrs)) continue; - /* emit argument data */ - if (func->args) - { - LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) - write_procformatstring_var(file, indent, var, FALSE); - } - - /* emit return value data */ - var = func->def; - if (is_void(var->type)) - { - print_file(file, indent, "0x5b, /* FC_END */\n"); - print_file(file, indent, "0x5c, /* FC_PAD */\n"); - } - else - write_procformatstring_var(file, indent, var, TRUE); - } - } - } - - print_file(file, indent, "0x0\n"); - indent--; - print_file(file, indent, "}\n"); - indent--; - print_file(file, indent, "};\n"); - print_file(file, indent, "\n"); -} - -static int write_base_type(FILE *file, const type_t *type, unsigned int *typestring_offset) -{ - if (is_base_type(type->type)) - { - print_file(file, 2, "0x%02x,\t/* %s */\n", type->type, string_of_type(type->type)); - *typestring_offset += 1; - return 1; - } - - return 0; -} - -/* write conformance / variance descriptor */ -static size_t write_conf_or_var_desc(FILE *file, const type_t *structure, - unsigned int baseoff, const type_t *type, - const expr_t *expr) -{ - unsigned char operator_type = 0; - unsigned char conftype = RPC_FC_NORMAL_CONFORMANCE; - const char *conftype_string = ""; - const char *operator_string = "no operators"; - const expr_t *subexpr; - - if (!expr) - { - print_file(file, 2, "NdrFcLong(0xffffffff),\t/* -1 */\n"); - return 4; - } - - if (!structure) - { - /* Top-level conformance calculations are done inline. */ - print_file (file, 2, "0x%x,\t/* Corr desc: parameter */\n", - RPC_FC_TOP_LEVEL_CONFORMANCE); - print_file (file, 2, "0x0,\n"); - print_file (file, 2, "NdrFcShort(0x0),\n"); - return 4; - } - - if (expr->is_const) - { - if (expr->cval > UCHAR_MAX * (USHRT_MAX + 1) + USHRT_MAX) - error("write_conf_or_var_desc: constant value %ld is greater than " - "the maximum constant size of %d\n", expr->cval, - UCHAR_MAX * (USHRT_MAX + 1) + USHRT_MAX); - - print_file(file, 2, "0x%x, /* Corr desc: constant, val = %ld */\n", - RPC_FC_CONSTANT_CONFORMANCE, expr->cval); - print_file(file, 2, "0x%x,\n", expr->cval & ~USHRT_MAX); - print_file(file, 2, "NdrFcShort(0x%x),\n", expr->cval & USHRT_MAX); - - return 4; - } - - if (is_ptr(type) || (is_array(type) && !type->declarray)) - { - conftype = RPC_FC_POINTER_CONFORMANCE; - conftype_string = "field pointer, "; - } - - subexpr = expr; - switch (subexpr->type) - { - case EXPR_PPTR: - subexpr = subexpr->ref; - operator_type = RPC_FC_DEREFERENCE; - operator_string = "FC_DEREFERENCE"; - break; - case EXPR_DIV: - if (subexpr->u.ext->is_const && (subexpr->u.ext->cval == 2)) - { - subexpr = subexpr->ref; - operator_type = RPC_FC_DIV_2; - operator_string = "FC_DIV_2"; - } - break; - case EXPR_MUL: - if (subexpr->u.ext->is_const && (subexpr->u.ext->cval == 2)) - { - subexpr = subexpr->ref; - operator_type = RPC_FC_MULT_2; - operator_string = "FC_MULT_2"; - } - break; - case EXPR_SUB: - if (subexpr->u.ext->is_const && (subexpr->u.ext->cval == 1)) - { - subexpr = subexpr->ref; - operator_type = RPC_FC_SUB_1; - operator_string = "FC_SUB_1"; - } - break; - case EXPR_ADD: - if (subexpr->u.ext->is_const && (subexpr->u.ext->cval == 1)) - { - subexpr = subexpr->ref; - operator_type = RPC_FC_ADD_1; - operator_string = "FC_ADD_1"; - } - break; - default: - break; - } - - if (subexpr->type == EXPR_IDENTIFIER) - { - const type_t *correlation_variable = NULL; - unsigned char correlation_variable_type; - unsigned char param_type = 0; - size_t offset = 0; - const var_t *var; - - if (structure->fields) LIST_FOR_EACH_ENTRY( var, structure->fields, const var_t, entry ) - { - unsigned int align = 0; - /* FIXME: take alignment into account */ - if (var->name && !strcmp(var->name, subexpr->u.sval)) - { - correlation_variable = var->type; - break; - } - offset += type_memsize(var->type, &align); - } - if (!correlation_variable) - error("write_conf_or_var_desc: couldn't find variable %s in structure\n", - subexpr->u.sval); - - offset -= baseoff; - correlation_variable_type = correlation_variable->type; - - switch (correlation_variable_type) - { - case RPC_FC_CHAR: - case RPC_FC_SMALL: - param_type = RPC_FC_SMALL; - break; - case RPC_FC_BYTE: - case RPC_FC_USMALL: - param_type = RPC_FC_USMALL; - break; - case RPC_FC_WCHAR: - case RPC_FC_SHORT: - case RPC_FC_ENUM16: - param_type = RPC_FC_SHORT; - break; - case RPC_FC_USHORT: - param_type = RPC_FC_USHORT; - break; - case RPC_FC_LONG: - case RPC_FC_ENUM32: - param_type = RPC_FC_LONG; - break; - case RPC_FC_ULONG: - param_type = RPC_FC_ULONG; - break; - case RPC_FC_RP: - case RPC_FC_UP: - case RPC_FC_OP: - case RPC_FC_FP: - if (sizeof(void *) == 4) /* FIXME */ - param_type = RPC_FC_LONG; - else - param_type = RPC_FC_HYPER; - break; - default: - error("write_conf_or_var_desc: conformance variable type not supported 0x%x\n", - correlation_variable_type); - } - - print_file(file, 2, "0x%x, /* Corr desc: %s%s */\n", - conftype | param_type, conftype_string, string_of_type(param_type)); - print_file(file, 2, "0x%x, /* %s */\n", operator_type, operator_string); - print_file(file, 2, "NdrFcShort(0x%x), /* offset = %d */\n", - offset, offset); - } - else - { - unsigned int callback_offset = 0; - struct expr_eval_routine *eval; - int found = 0; - - LIST_FOR_EACH_ENTRY(eval, &expr_eval_routines, struct expr_eval_routine, entry) - { - if (!strcmp (eval->structure->name, structure->name) - && !compare_expr (eval->expr, expr)) - { - found = 1; - break; - } - callback_offset++; - } - - if (!found) - { - eval = xmalloc (sizeof(*eval)); - eval->structure = structure; - eval->baseoff = baseoff; - eval->expr = expr; - list_add_tail (&expr_eval_routines, &eval->entry); - } - - if (callback_offset > USHRT_MAX) - error("Maximum number of callback routines reached\n"); - - print_file(file, 2, "0x%x, /* Corr desc: %s */\n", conftype, conftype_string); - print_file(file, 2, "0x%x, /* %s */\n", RPC_FC_CALLBACK, "FC_CALLBACK"); - print_file(file, 2, "NdrFcShort(0x%x), /* %u */\n", callback_offset, callback_offset); - } - return 4; -} - -static size_t fields_memsize(const var_list_t *fields, unsigned int *align) -{ - int have_align = FALSE; - size_t size = 0; - const var_t *v; - - if (!fields) return 0; - LIST_FOR_EACH_ENTRY( v, fields, const var_t, entry ) - { - unsigned int falign = 0; - size_t fsize = type_memsize(v->type, &falign); - if (!have_align) - { - *align = falign; - have_align = TRUE; - } - size = (size + (falign - 1)) & ~(falign - 1); - size += fsize; - } - - size = (size + (*align - 1)) & ~(*align - 1); - return size; -} - -static size_t union_memsize(const var_list_t *fields, unsigned int *pmaxa) -{ - size_t size, maxs = 0; - unsigned int align = *pmaxa; - const var_t *v; - - if (fields) LIST_FOR_EACH_ENTRY( v, fields, const var_t, entry ) - { - /* we could have an empty default field with NULL type */ - if (v->type) - { - size = type_memsize(v->type, &align); - if (maxs < size) maxs = size; - if (*pmaxa < align) *pmaxa = align; - } - } - - return maxs; -} - -int get_padding(const var_list_t *fields) -{ - unsigned short offset = 0; - int salign = -1; - const var_t *f; - - if (!fields) - return 0; - - LIST_FOR_EACH_ENTRY(f, fields, const var_t, entry) - { - type_t *ft = f->type; - unsigned int align = 0; - size_t size = type_memsize(ft, &align); - if (salign == -1) - salign = align; - offset = (offset + (align - 1)) & ~(align - 1); - offset += size; - } - - return ((offset + (salign - 1)) & ~(salign - 1)) - offset; -} - -size_t type_memsize(const type_t *t, unsigned int *align) -{ - size_t size = 0; - - if (t->declarray && is_conformant_array(t)) - { - type_memsize(t->ref, align); - size = 0; - } - else if (is_ptr(t) || is_conformant_array(t)) - { - size = sizeof(void *); - if (size > *align) *align = size; - } - else switch (t->type) - { - case RPC_FC_BYTE: - case RPC_FC_CHAR: - case RPC_FC_USMALL: - case RPC_FC_SMALL: - size = 1; - if (size > *align) *align = size; - break; - case RPC_FC_WCHAR: - case RPC_FC_USHORT: - case RPC_FC_SHORT: - case RPC_FC_ENUM16: - size = 2; - if (size > *align) *align = size; - break; - case RPC_FC_ULONG: - case RPC_FC_LONG: - case RPC_FC_ERROR_STATUS_T: - case RPC_FC_ENUM32: - case RPC_FC_FLOAT: - size = 4; - if (size > *align) *align = size; - break; - case RPC_FC_HYPER: - case RPC_FC_DOUBLE: - size = 8; - if (size > *align) *align = size; - break; - case RPC_FC_STRUCT: - case RPC_FC_CVSTRUCT: - case RPC_FC_CPSTRUCT: - case RPC_FC_CSTRUCT: - case RPC_FC_PSTRUCT: - case RPC_FC_BOGUS_STRUCT: - size = fields_memsize(t->fields, align); - break; - case RPC_FC_ENCAPSULATED_UNION: - case RPC_FC_NON_ENCAPSULATED_UNION: - size = union_memsize(t->fields, align); - break; - case RPC_FC_SMFARRAY: - case RPC_FC_LGFARRAY: - case RPC_FC_SMVARRAY: - case RPC_FC_LGVARRAY: - case RPC_FC_BOGUS_ARRAY: - size = t->dim * type_memsize(t->ref, align); - break; - default: - error("type_memsize: Unknown type %d\n", t->type); - size = 0; - } - - return size; -} - -static unsigned int write_nonsimple_pointer(FILE *file, const type_t *type, size_t offset) -{ - short absoff = type->ref->typestring_offset; - short reloff = absoff - (offset + 2); - int ptr_attr = is_ptr(type->ref) ? 0x10 : 0x0; - - print_file(file, 2, "0x%02x, 0x%x,\t/* %s */\n", - type->type, ptr_attr, string_of_type(type->type)); - print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%hd) */\n", - reloff, reloff, absoff); - return 4; -} - -static unsigned char conf_string_type_of_char_type(unsigned char t) -{ - switch (t) - { - case RPC_FC_BYTE: - case RPC_FC_CHAR: - return RPC_FC_C_CSTRING; - case RPC_FC_WCHAR: - return RPC_FC_C_WSTRING; - } - - error("string_type_of_char_type: unrecognized type %d\n", t); - return 0; -} - -static unsigned int write_simple_pointer(FILE *file, const type_t *type) -{ - unsigned char fc - = is_string_type(type->attrs, type) - ? conf_string_type_of_char_type(type->ref->type) - : type->ref->type; - print_file(file, 2, "0x%02x, 0x8,\t/* %s [simple_pointer] */\n", - type->type, string_of_type(type->type)); - print_file(file, 2, "0x%02x,\t/* %s */\n", fc, string_of_type(fc)); - print_file(file, 2, "0x5c,\t/* FC_PAD */\n"); - return 4; -} - -static void print_start_tfs_comment(FILE *file, type_t *t, unsigned int tfsoff) -{ - print_file(file, 0, "/* %u (", tfsoff); - write_type_decl(file, t, NULL); - print_file(file, 0, ") */\n"); -} - -static size_t write_pointer_tfs(FILE *file, type_t *type, unsigned int *typestring_offset) -{ - unsigned int offset = *typestring_offset; - - print_start_tfs_comment(file, type, offset); - update_tfsoff(type, offset, file); - - if (type->ref->typestring_offset) - *typestring_offset += write_nonsimple_pointer(file, type, offset); - else if (is_base_type(type->ref->type)) - *typestring_offset += write_simple_pointer(file, type); - - return offset; -} - -static int processed(const type_t *type) -{ - return type->typestring_offset && !type->tfswrite; -} - -static int user_type_has_variable_size(const type_t *t) -{ - if (is_ptr(t)) - return TRUE; - else - switch (t->type) - { - case RPC_FC_PSTRUCT: - case RPC_FC_CSTRUCT: - case RPC_FC_CPSTRUCT: - case RPC_FC_CVSTRUCT: - return TRUE; - } - /* Note: Since this only applies to user types, we can't have a conformant - array here, and strings should get filed under pointer in this case. */ - return FALSE; -} - -static void write_user_tfs(FILE *file, type_t *type, unsigned int *tfsoff) -{ - unsigned int start, absoff, flags; - unsigned int align = 0, ualign = 0; - const char *name; - type_t *utype = get_user_type(type, &name); - size_t usize = user_type_has_variable_size(utype) ? 0 : type_memsize(utype, &ualign); - size_t size = type_memsize(type, &align); - unsigned short funoff = user_type_offset(name); - short reloff; - - guard_rec(type); - - if (is_base_type(utype->type)) - { - absoff = *tfsoff; - print_start_tfs_comment(file, utype, absoff); - print_file(file, 2, "0x%x,\t/* %s */\n", utype->type, string_of_type(utype->type)); - print_file(file, 2, "0x5c,\t/* FC_PAD */\n"); - *tfsoff += 2; - } - else - { - if (!processed(utype)) - write_embedded_types(file, NULL, utype, utype->name, TRUE, tfsoff); - absoff = utype->typestring_offset; - } - - if (utype->type == RPC_FC_RP) - flags = 0x40; - else if (utype->type == RPC_FC_UP) - flags = 0x80; - else - flags = 0; - - start = *tfsoff; - update_tfsoff(type, start, file); - print_start_tfs_comment(file, type, start); - print_file(file, 2, "0x%x,\t/* FC_USER_MARSHAL */\n", RPC_FC_USER_MARSHAL); - print_file(file, 2, "0x%x,\t/* Alignment= %d, Flags= %02x */\n", - flags | (align - 1), align - 1, flags); - print_file(file, 2, "NdrFcShort(0x%hx),\t/* Function offset= %hu */\n", funoff, funoff); - print_file(file, 2, "NdrFcShort(0x%lx),\t/* %lu */\n", size, size); - print_file(file, 2, "NdrFcShort(0x%lx),\t/* %lu */\n", usize, usize); - *tfsoff += 8; - reloff = absoff - *tfsoff; - print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%lu) */\n", reloff, reloff, absoff); - *tfsoff += 2; -} - -static void write_member_type(FILE *file, const type_t *cont, - const attr_list_t *attrs, const type_t *type, - unsigned int *corroff, unsigned int *tfsoff) -{ - if (is_embedded_complex(type) && !is_conformant_array(type)) - { - size_t absoff; - short reloff; - - if (is_union(type->type) && is_attr(attrs, ATTR_SWITCHIS)) - { - absoff = *corroff; - *corroff += 8; - } - else - { - absoff = type->typestring_offset; - } - reloff = absoff - (*tfsoff + 2); - - print_file(file, 2, "0x4c,\t/* FC_EMBEDDED_COMPLEX */\n"); - /* FIXME: actually compute necessary padding */ - print_file(file, 2, "0x0,\t/* FIXME: padding */\n"); - print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%lu) */\n", - reloff, reloff, absoff); - *tfsoff += 4; - } - else if (is_ptr(type) || is_conformant_array(type)) - { - unsigned char fc = (cont->type == RPC_FC_BOGUS_STRUCT - ? RPC_FC_POINTER - : RPC_FC_LONG); - print_file(file, 2, "0x%x,\t/* %s */\n", fc, string_of_type(fc)); - *tfsoff += 1; - } - else if (!write_base_type(file, type, tfsoff)) - error("Unsupported member type 0x%x\n", type->type); -} - -static void write_end(FILE *file, unsigned int *tfsoff) -{ - if (*tfsoff % 2 == 0) - { - print_file(file, 2, "0x%x,\t\t/* FC_PAD */\n", RPC_FC_PAD); - *tfsoff += 1; - } - print_file(file, 2, "0x%x,\t\t/* FC_END */\n", RPC_FC_END); - *tfsoff += 1; -} - -static void write_descriptors(FILE *file, type_t *type, unsigned int *tfsoff) -{ - unsigned int offset = 0; - var_list_t *fs = type->fields; - var_t *f; - - if (fs) LIST_FOR_EACH_ENTRY(f, fs, var_t, entry) - { - unsigned int align = 0; - type_t *ft = f->type; - if (is_union(ft->type) && is_attr(f->attrs, ATTR_SWITCHIS)) - { - unsigned int absoff = ft->typestring_offset; - short reloff = absoff - (*tfsoff + 6); - print_file(file, 0, "/* %d */\n", *tfsoff); - print_file(file, 2, "0x%x,\t/* %s */\n", ft->type, string_of_type(ft->type)); - print_file(file, 2, "0x%x,\t/* FIXME: always FC_LONG */\n", RPC_FC_LONG); - write_conf_or_var_desc(file, current_structure, offset, ft, - get_attrp(f->attrs, ATTR_SWITCHIS)); - print_file(file, 2, "NdrFcShort(%hd),\t/* Offset= %hd (%u) */\n", - reloff, reloff, absoff); - *tfsoff += 8; - } - - /* FIXME: take alignment into account */ - offset += type_memsize(ft, &align); - } -} - -static int write_no_repeat_pointer_descriptions( - FILE *file, type_t *type, - size_t *offset_in_memory, size_t *offset_in_buffer, - unsigned int *typestring_offset) -{ - int written = 0; - unsigned int align; - - if (is_ptr(type) || (!type->declarray && is_conformant_array(type))) - { - print_file(file, 2, "0x%02x, /* FC_NO_REPEAT */\n", RPC_FC_NO_REPEAT); - print_file(file, 2, "0x%02x, /* FC_PAD */\n", RPC_FC_PAD); - - /* pointer instance */ - print_file(file, 2, "NdrFcShort(0x%x), /* Memory offset = %d */\n", *offset_in_memory, *offset_in_memory); - print_file(file, 2, "NdrFcShort(0x%x), /* Buffer offset = %d */\n", *offset_in_buffer, *offset_in_buffer); - *typestring_offset += 6; - - if (is_ptr(type)) - write_pointer_tfs(file, type, typestring_offset); - else - { - unsigned absoff = type->typestring_offset; - short reloff = absoff - (*typestring_offset + 2); - /* FIXME: get pointer attributes from field */ - print_file(file, 2, "0x%02x, 0x0,\t/* %s */\n", RPC_FC_UP, "FC_UP"); - print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%u) */\n", - reloff, reloff, absoff); - *typestring_offset += 4; - } - - align = 0; - *offset_in_memory += type_memsize(type, &align); - /* FIXME: is there a case where these two are different? */ - align = 0; - *offset_in_buffer += type_memsize(type, &align); - - return 1; - } - - if (is_non_complex_struct(type)) - { - const var_t *v; - LIST_FOR_EACH_ENTRY( v, type->fields, const var_t, entry ) - written += write_no_repeat_pointer_descriptions( - file, v->type, - offset_in_memory, offset_in_buffer, typestring_offset); - } - else - { - align = 0; - *offset_in_memory += type_memsize(type, &align); - /* FIXME: is there a case where these two are different? */ - align = 0; - *offset_in_buffer += type_memsize(type, &align); - } - - return written; -} - -static int write_pointer_description_offsets( - FILE *file, const attr_list_t *attrs, type_t *type, - size_t *offset_in_memory, size_t *offset_in_buffer, - unsigned int *typestring_offset) -{ - int written = 0; - unsigned int align; - - if (is_ptr(type) && type->ref->type != RPC_FC_IP) - { - if (offset_in_memory && offset_in_buffer) - { - /* pointer instance */ - /* FIXME: sometimes from end of structure, sometimes from beginning */ - print_file(file, 2, "NdrFcShort(0x%x), /* Memory offset = %d */\n", *offset_in_memory, *offset_in_memory); - print_file(file, 2, "NdrFcShort(0x%x), /* Buffer offset = %d */\n", *offset_in_buffer, *offset_in_buffer); - - align = 0; - *offset_in_memory += type_memsize(type, &align); - /* FIXME: is there a case where these two are different? */ - align = 0; - *offset_in_buffer += type_memsize(type, &align); - } - *typestring_offset += 4; - - if (processed(type->ref) || is_base_type(type->ref->type)) - write_pointer_tfs(file, type, typestring_offset); - else - error("write_pointer_description_offsets: type format string unknown\n"); - - return 1; - } - - if (is_array(type)) - { - return write_pointer_description_offsets( - file, attrs, type->ref, offset_in_memory, offset_in_buffer, - typestring_offset); - } - else if (is_non_complex_struct(type)) - { - /* otherwise search for interesting fields to parse */ - const var_t *v; - LIST_FOR_EACH_ENTRY( v, type->fields, const var_t, entry ) - { - written += write_pointer_description_offsets( - file, v->attrs, v->type, offset_in_memory, offset_in_buffer, - typestring_offset); - } - } - else - { - align = 0; - if (offset_in_memory) - *offset_in_memory += type_memsize(type, &align); - /* FIXME: is there a case where these two are different? */ - align = 0; - if (offset_in_buffer) - *offset_in_buffer += type_memsize(type, &align); - } - - return written; -} - -/* Note: if file is NULL return value is number of pointers to write, else - * it is the number of type format characters written */ -static int write_fixed_array_pointer_descriptions( - FILE *file, const attr_list_t *attrs, type_t *type, - size_t *offset_in_memory, size_t *offset_in_buffer, - unsigned int *typestring_offset) -{ - unsigned int align; - int pointer_count = 0; - - if (type->type == RPC_FC_SMFARRAY || type->type == RPC_FC_LGFARRAY) - { - unsigned int temp = 0; - /* unfortunately, this needs to be done in two passes to avoid - * writing out redundant FC_FIXED_REPEAT descriptions */ - pointer_count = write_pointer_description_offsets( - NULL, attrs, type->ref, NULL, NULL, &temp); - if (pointer_count > 0) - { - unsigned int increment_size; - size_t offset_of_array_pointer_mem = 0; - size_t offset_of_array_pointer_buf = 0; - - align = 0; - increment_size = type_memsize(type->ref, &align); - - print_file(file, 2, "0x%02x, /* FC_FIXED_REPEAT */\n", RPC_FC_FIXED_REPEAT); - print_file(file, 2, "0x%02x, /* FC_PAD */\n", RPC_FC_PAD); - print_file(file, 2, "NdrFcShort(0x%x), /* Iterations = %d */\n", type->dim, type->dim); - print_file(file, 2, "NdrFcShort(0x%x), /* Increment = %d */\n", increment_size, increment_size); - print_file(file, 2, "NdrFcShort(0x%x), /* Offset to array = %d */\n", *offset_in_memory, *offset_in_memory); - print_file(file, 2, "NdrFcShort(0x%x), /* Number of pointers = %d */\n", pointer_count, pointer_count); - *typestring_offset += 10; - - pointer_count = write_pointer_description_offsets( - file, attrs, type, &offset_of_array_pointer_mem, - &offset_of_array_pointer_buf, typestring_offset); - } - } - else if (is_struct(type->type)) - { - const var_t *v; - LIST_FOR_EACH_ENTRY( v, type->fields, const var_t, entry ) - { - pointer_count += write_fixed_array_pointer_descriptions( - file, v->attrs, v->type, offset_in_memory, offset_in_buffer, - typestring_offset); - } - } - else - { - align = 0; - if (offset_in_memory) - *offset_in_memory += type_memsize(type, &align); - /* FIXME: is there a case where these two are different? */ - align = 0; - if (offset_in_buffer) - *offset_in_buffer += type_memsize(type, &align); - } - - return pointer_count; -} - -/* Note: if file is NULL return value is number of pointers to write, else - * it is the number of type format characters written */ -static int write_conformant_array_pointer_descriptions( - FILE *file, const attr_list_t *attrs, type_t *type, - size_t offset_in_memory, unsigned int *typestring_offset) -{ - unsigned int align; - int pointer_count = 0; - - if (is_conformant_array(type) && !type->length_is) - { - unsigned int temp = 0; - /* unfortunately, this needs to be done in two passes to avoid - * writing out redundant FC_VARIABLE_REPEAT descriptions */ - pointer_count = write_pointer_description_offsets( - NULL, attrs, type->ref, NULL, NULL, &temp); - if (pointer_count > 0) - { - unsigned int increment_size; - size_t offset_of_array_pointer_mem = offset_in_memory; - size_t offset_of_array_pointer_buf = offset_in_memory; - - align = 0; - increment_size = type_memsize(type->ref, &align); - - if (increment_size > USHRT_MAX) - error("array size of %u bytes is too large\n", increment_size); - - print_file(file, 2, "0x%02x, /* FC_VARIABLE_REPEAT */\n", RPC_FC_VARIABLE_REPEAT); - print_file(file, 2, "0x%02x, /* FC_FIXED_OFFSET */\n", RPC_FC_FIXED_OFFSET); - print_file(file, 2, "NdrFcShort(0x%x), /* Increment = %d */\n", increment_size, increment_size); - print_file(file, 2, "NdrFcShort(0x%x), /* Offset to array = %d */\n", offset_in_memory, offset_in_memory); - print_file(file, 2, "NdrFcShort(0x%x), /* Number of pointers = %d */\n", pointer_count, pointer_count); - *typestring_offset += 8; - - pointer_count = write_pointer_description_offsets( - file, attrs, type->ref, &offset_of_array_pointer_mem, - &offset_of_array_pointer_buf, typestring_offset); - } - } - - return pointer_count; -} - -/* Note: if file is NULL return value is number of pointers to write, else - * it is the number of type format characters written */ -static int write_varying_array_pointer_descriptions( - FILE *file, const attr_list_t *attrs, type_t *type, - size_t *offset_in_memory, size_t *offset_in_buffer, - unsigned int *typestring_offset) -{ - unsigned int align; - int pointer_count = 0; - - /* FIXME: do varying array searching here, but pointer searching in write_pointer_description_offsets */ - - if (is_array(type) && type->length_is) - { - unsigned int temp = 0; - /* unfortunately, this needs to be done in two passes to avoid - * writing out redundant FC_VARIABLE_REPEAT descriptions */ - pointer_count = write_pointer_description_offsets( - NULL, attrs, type->ref, NULL, NULL, &temp); - if (pointer_count > 0) - { - unsigned int increment_size; - size_t offset_of_array_pointer_mem = 0; - size_t offset_of_array_pointer_buf = 0; - - align = 0; - increment_size = type_memsize(type->ref, &align); - - if (increment_size > USHRT_MAX) - error("array size of %u bytes is too large\n", increment_size); - - print_file(file, 2, "0x%02x, /* FC_VARIABLE_REPEAT */\n", RPC_FC_VARIABLE_REPEAT); - print_file(file, 2, "0x%02x, /* FC_VARIABLE_OFFSET */\n", RPC_FC_VARIABLE_OFFSET); - print_file(file, 2, "NdrFcShort(0x%x), /* Increment = %d */\n", increment_size, increment_size); - print_file(file, 2, "NdrFcShort(0x%x), /* Offset to array = %d */\n", *offset_in_memory, *offset_in_memory); - print_file(file, 2, "NdrFcShort(0x%x), /* Number of pointers = %d */\n", pointer_count, pointer_count); - *typestring_offset += 8; - - pointer_count = write_pointer_description_offsets( - file, attrs, type, &offset_of_array_pointer_mem, - &offset_of_array_pointer_buf, typestring_offset); - } - } - else if (is_struct(type->type)) - { - const var_t *v; - LIST_FOR_EACH_ENTRY( v, type->fields, const var_t, entry ) - { - pointer_count += write_varying_array_pointer_descriptions( - file, v->attrs, v->type, offset_in_memory, offset_in_buffer, - typestring_offset); - } - } - else - { - align = 0; - if (offset_in_memory) - *offset_in_memory += type_memsize(type, &align); - /* FIXME: is there a case where these two are different? */ - align = 0; - if (offset_in_buffer) - *offset_in_buffer += type_memsize(type, &align); - } - - return pointer_count; -} - -static void write_pointer_description(FILE *file, type_t *type, - unsigned int *typestring_offset) -{ - size_t offset_in_buffer; - size_t offset_in_memory; - - /* pass 1: search for single instance of a pointer (i.e. don't descend - * into arrays) */ - if (!is_array(type)) - { - offset_in_memory = 0; - offset_in_buffer = 0; - write_no_repeat_pointer_descriptions( - file, type, - &offset_in_memory, &offset_in_buffer, typestring_offset); - } - - /* pass 2: search for pointers in fixed arrays */ - offset_in_memory = 0; - offset_in_buffer = 0; - write_fixed_array_pointer_descriptions( - file, NULL, type, - &offset_in_memory, &offset_in_buffer, typestring_offset); - - /* pass 3: search for pointers in conformant only arrays (but don't descend - * into conformant varying or varying arrays) */ - if ((!type->declarray || !current_structure) && is_conformant_array(type)) - write_conformant_array_pointer_descriptions( - file, NULL, type, 0, typestring_offset); - else if (type->type == RPC_FC_CPSTRUCT) - { - unsigned int align = 0; - type_t *carray = find_array_or_string_in_struct(type)->type; - write_conformant_array_pointer_descriptions( - file, NULL, carray, - type_memsize(type, &align), - typestring_offset); - } - - /* pass 4: search for pointers in varying arrays */ - offset_in_memory = 0; - offset_in_buffer = 0; - write_varying_array_pointer_descriptions( - file, NULL, type, - &offset_in_memory, &offset_in_buffer, typestring_offset); -} - -int is_declptr(const type_t *t) -{ - return is_ptr(t) || (is_conformant_array(t) && !t->declarray); -} - -static size_t write_string_tfs(FILE *file, const attr_list_t *attrs, - type_t *type, - const char *name, unsigned int *typestring_offset, - int toplevel) -{ - size_t start_offset = *typestring_offset; - unsigned char rtype; - - update_tfsoff(type, start_offset, file); - - if (toplevel && is_declptr(type)) - { - unsigned char flag = is_conformant_array(type) ? 0 : RPC_FC_P_SIMPLEPOINTER; - int pointer_type = is_ptr(type) ? type->type : get_attrv(attrs, ATTR_POINTERTYPE); - if (!pointer_type) - pointer_type = RPC_FC_RP; - print_file(file, 2,"0x%x, 0x%x,\t/* %s%s */\n", - pointer_type, flag, string_of_type(pointer_type), - flag ? " [simple_pointer]" : ""); - *typestring_offset += 2; - if (!flag) - { - print_file(file, 2, "NdrFcShort(0x2),\n"); - *typestring_offset += 2; - } - } - - rtype = type->ref->type; - - if ((rtype != RPC_FC_BYTE) && (rtype != RPC_FC_CHAR) && (rtype != RPC_FC_WCHAR)) - { - error("write_string_tfs: Unimplemented for type 0x%x of name: %s\n", rtype, name); - return start_offset; - } - - if (type->declarray && !is_conformant_array(type)) - { - /* FIXME: multi-dimensional array */ - if (0xffffuL < type->dim) - error("array size for parameter %s exceeds %u bytes by %lu bytes\n", - name, 0xffffu, type->dim - 0xffffu); - - if (rtype == RPC_FC_CHAR) - WRITE_FCTYPE(file, FC_CSTRING, *typestring_offset); - else - WRITE_FCTYPE(file, FC_WSTRING, *typestring_offset); - print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD); - *typestring_offset += 2; - - print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", type->dim, type->dim); - *typestring_offset += 2; - - return start_offset; - } - else if (type->size_is) - { - unsigned int align = 0; - - if (rtype == RPC_FC_CHAR) - WRITE_FCTYPE(file, FC_C_CSTRING, *typestring_offset); - else - WRITE_FCTYPE(file, FC_C_WSTRING, *typestring_offset); - print_file(file, 2, "0x%x, /* FC_STRING_SIZED */\n", RPC_FC_STRING_SIZED); - *typestring_offset += 2; - - *typestring_offset += write_conf_or_var_desc( - file, current_structure, - (type->declarray && current_structure - ? type_memsize(current_structure, &align) - : 0), - type, type->size_is); - - return start_offset; - } - else - { - if (rtype == RPC_FC_WCHAR) - WRITE_FCTYPE(file, FC_C_WSTRING, *typestring_offset); - else - WRITE_FCTYPE(file, FC_C_CSTRING, *typestring_offset); - print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD); - *typestring_offset += 2; - - return start_offset; - } -} - -static size_t write_array_tfs(FILE *file, const attr_list_t *attrs, type_t *type, - const char *name, unsigned int *typestring_offset) -{ - const expr_t *length_is = type->length_is; - const expr_t *size_is = type->size_is; - unsigned int align = 0; - size_t size; - size_t start_offset; - int has_pointer; - int pointer_type = get_attrv(attrs, ATTR_POINTERTYPE); - unsigned int baseoff - = type->declarray && current_structure - ? type_memsize(current_structure, &align) - : 0; - - if (!pointer_type) - pointer_type = RPC_FC_RP; - - 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); - - start_offset = *typestring_offset; - update_tfsoff(type, start_offset, file); - print_start_tfs_comment(file, type, start_offset); - print_file(file, 2, "0x%02x,\t/* %s */\n", type->type, string_of_type(type->type)); - print_file(file, 2, "0x%x,\t/* %d */\n", align - 1, align - 1); - *typestring_offset += 2; - - align = 0; - if (type->type != RPC_FC_BOGUS_ARRAY) - { - unsigned char tc = type->type; - - if (tc == RPC_FC_LGFARRAY || tc == RPC_FC_LGVARRAY) - { - print_file(file, 2, "NdrFcLong(0x%x),\t/* %lu */\n", size, size); - *typestring_offset += 4; - } - else - { - print_file(file, 2, "NdrFcShort(0x%x),\t/* %lu */\n", size, size); - *typestring_offset += 2; - } - - if (is_conformant_array(type)) - *typestring_offset - += write_conf_or_var_desc(file, current_structure, baseoff, - type, size_is); - - if (type->type == RPC_FC_SMVARRAY || type->type == RPC_FC_LGVARRAY) - { - unsigned int elalign = 0; - size_t elsize = type_memsize(type->ref, &elalign); - - if (type->type == RPC_FC_LGVARRAY) - { - print_file(file, 2, "NdrFcLong(0x%x),\t/* %lu */\n", type->dim, type->dim); - *typestring_offset += 4; - } - else - { - print_file(file, 2, "NdrFcShort(0x%x),\t/* %lu */\n", type->dim, type->dim); - *typestring_offset += 2; - } - - print_file(file, 2, "NdrFcShort(0x%x),\t/* %lu */\n", elsize, elsize); - *typestring_offset += 2; - } - - if (length_is) - *typestring_offset - += write_conf_or_var_desc(file, current_structure, baseoff, - type, length_is); - - if (has_pointer && (!type->declarray || !current_structure)) - { - print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP); - print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD); - *typestring_offset += 2; - write_pointer_description(file, type, typestring_offset); - print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END); - *typestring_offset += 1; - } - - write_member_type(file, type, NULL, type->ref, NULL, typestring_offset); - write_end(file, typestring_offset); - } - else - { - unsigned int dim = size_is ? 0 : type->dim; - print_file(file, 2, "NdrFcShort(0x%x),\t/* %u */\n", dim, dim); - *typestring_offset += 2; - *typestring_offset - += write_conf_or_var_desc(file, current_structure, baseoff, - type, size_is); - *typestring_offset - += write_conf_or_var_desc(file, current_structure, baseoff, - type, length_is); - write_member_type(file, type, NULL, type->ref, NULL, typestring_offset); - write_end(file, typestring_offset); - } - - return start_offset; -} - -static const var_t *find_array_or_string_in_struct(const type_t *type) -{ - const var_t *last_field = LIST_ENTRY( list_tail(type->fields), const var_t, entry ); - const type_t *ft = last_field->type; - - if (ft->declarray && is_conformant_array(ft)) - return last_field; - - if (ft->type == RPC_FC_CSTRUCT || ft->type == RPC_FC_CPSTRUCT || ft->type == RPC_FC_CVSTRUCT) - return find_array_or_string_in_struct(last_field->type); - else - return NULL; -} - -static void write_struct_members(FILE *file, const type_t *type, - unsigned int *corroff, unsigned int *typestring_offset) -{ - const var_t *field; - unsigned short offset = 0; - int salign = -1; - int padding; - - if (type->fields) LIST_FOR_EACH_ENTRY( field, type->fields, const var_t, entry ) - { - type_t *ft = field->type; - if (!ft->declarray || !is_conformant_array(ft)) - { - unsigned int align = 0; - size_t size = type_memsize(ft, &align); - if (salign == -1) - salign = align; - if ((align - 1) & offset) - { - unsigned char fc = 0; - switch (align) - { - case 4: - fc = RPC_FC_ALIGNM4; - break; - case 8: - fc = RPC_FC_ALIGNM8; - break; - default: - error("write_struct_members: cannot align type %d\n", ft->type); - } - print_file(file, 2, "0x%x,\t/* %s */\n", fc, string_of_type(fc)); - offset = (offset + (align - 1)) & ~(align - 1); - *typestring_offset += 1; - } - write_member_type(file, type, field->attrs, field->type, corroff, - typestring_offset); - offset += size; - } - } - - padding = ((offset + (salign - 1)) & ~(salign - 1)) - offset; - if (padding) - { - print_file(file, 2, "0x%x,\t/* FC_STRUCTPAD%d */\n", - RPC_FC_STRUCTPAD1 + padding - 1, - padding); - *typestring_offset += 1; - } - - write_end(file, typestring_offset); -} - -static size_t write_struct_tfs(FILE *file, type_t *type, - const char *name, unsigned int *tfsoff) -{ - const type_t *save_current_structure = current_structure; - unsigned int total_size; - const var_t *array; - size_t start_offset; - size_t array_offset; - int has_pointers = 0; - unsigned int align = 0; - unsigned int corroff; - var_t *f; - - guard_rec(type); - current_structure = type; - - total_size = type_memsize(type, &align); - if (total_size > USHRT_MAX) - error("structure size for %s exceeds %d bytes by %d bytes\n", - name, USHRT_MAX, total_size - USHRT_MAX); - - 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)) - array_offset - = is_attr(array->attrs, ATTR_STRING) - ? write_string_tfs(file, array->attrs, array->type, array->name, tfsoff, FALSE) - : write_array_tfs(file, array->attrs, array->type, array->name, tfsoff); - - corroff = *tfsoff; - write_descriptors(file, type, tfsoff); - - start_offset = *tfsoff; - update_tfsoff(type, start_offset, file); - print_start_tfs_comment(file, type, start_offset); - print_file(file, 2, "0x%x,\t/* %s */\n", type->type, string_of_type(type->type)); - print_file(file, 2, "0x%x,\t/* %d */\n", align - 1, align - 1); - print_file(file, 2, "NdrFcShort(0x%x),\t/* %d */\n", total_size, total_size); - *tfsoff += 4; - - if (array) - { - unsigned int absoff = array->type->typestring_offset; - short reloff = absoff - *tfsoff; - print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%lu) */\n", - reloff, reloff, absoff); - *tfsoff += 2; - } - else if (type->type == RPC_FC_BOGUS_STRUCT) - { - print_file(file, 2, "NdrFcShort(0x0),\n"); - *tfsoff += 2; - } - - if (type->type == RPC_FC_BOGUS_STRUCT) - { - /* On the sizing pass, type->ptrdesc may be zero, but it's ok as - nothing is written to file yet. On the actual writing pass, - this will have been updated. */ - unsigned int absoff = type->ptrdesc ? type->ptrdesc : *tfsoff; - short reloff = absoff - *tfsoff; - print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%u) */\n", - reloff, reloff, absoff); - *tfsoff += 2; - } - else if ((type->type == RPC_FC_PSTRUCT) || - (type->type == RPC_FC_CPSTRUCT) || - (type->type == RPC_FC_CVSTRUCT && has_pointers)) - { - print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP); - print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD); - *tfsoff += 2; - write_pointer_description(file, type, tfsoff); - print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END); - *tfsoff += 1; - } - - write_struct_members(file, type, &corroff, tfsoff); - - if (type->type == RPC_FC_BOGUS_STRUCT) - { - const var_list_t *fs = type->fields; - const var_t *f; - - type->ptrdesc = *tfsoff; - if (fs) LIST_FOR_EACH_ENTRY(f, fs, const var_t, entry) - { - type_t *ft = f->type; - if (is_ptr(ft)) - write_pointer_tfs(file, ft, tfsoff); - else if (!ft->declarray && is_conformant_array(ft)) - { - unsigned int absoff = ft->typestring_offset; - short reloff = absoff - (*tfsoff + 2); - int ptr_type = get_attrv(f->attrs, ATTR_POINTERTYPE); - /* FIXME: We need to store pointer attributes for arrays - so we don't lose pointer_default info. */ - if (ptr_type == 0) - ptr_type = RPC_FC_UP; - print_file(file, 0, "/* %d */\n", *tfsoff); - print_file(file, 2, "0x%x, 0x0,\t/* %s */\n", ptr_type, - string_of_type(ptr_type)); - print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%u) */\n", - reloff, reloff, absoff); - *tfsoff += 4; - } - } - if (type->ptrdesc == *tfsoff) - type->ptrdesc = 0; - } - - current_structure = save_current_structure; - return start_offset; -} - -static size_t write_pointer_only_tfs(FILE *file, const attr_list_t *attrs, int pointer_type, - unsigned char flags, size_t offset, - unsigned int *typeformat_offset) -{ - size_t start_offset = *typeformat_offset; - short reloff = offset - (*typeformat_offset + 2); - int in_attr, out_attr; - in_attr = is_attr(attrs, ATTR_IN); - out_attr = is_attr(attrs, ATTR_OUT); - if (!in_attr && !out_attr) in_attr = 1; - - if (out_attr && !in_attr && pointer_type == RPC_FC_RP) - flags |= 0x04; - - print_file(file, 2, "0x%x, 0x%x,\t\t/* %s", - pointer_type, - flags, - string_of_type(pointer_type)); - if (file) - { - if (flags & 0x04) - fprintf(file, " [allocated_on_stack]"); - if (flags & 0x10) - fprintf(file, " [pointer_deref]"); - fprintf(file, " */\n"); - } - - print_file(file, 2, "NdrFcShort(0x%x),\t/* %d */\n", reloff, offset); - *typeformat_offset += 4; - - return start_offset; -} - -static void write_branch_type(FILE *file, const type_t *t, unsigned int *tfsoff) -{ - if (t == NULL) - { - print_file(file, 2, "NdrFcShort(0x0),\t/* No type */\n"); - } - else if (is_base_type(t->type)) - { - print_file(file, 2, "NdrFcShort(0x80%02x),\t/* Simple arm type: %s */\n", - t->type, string_of_type(t->type)); - } - else if (t->typestring_offset) - { - short reloff = t->typestring_offset - *tfsoff; - print_file(file, 2, "NdrFcShort(0x%x),\t/* Offset= %d (%d) */\n", - reloff, reloff, t->typestring_offset); - } - else - error("write_branch_type: type unimplemented (0x%x)\n", t->type); - - *tfsoff += 2; -} - -static size_t write_union_tfs(FILE *file, type_t *type, unsigned int *tfsoff) -{ - unsigned int align = 0; - unsigned int start_offset; - size_t size = type_memsize(type, &align); - var_list_t *fields; - size_t nbranch = 0; - type_t *deftype = NULL; - short nodeftype = 0xffff; - var_t *f; - - guard_rec(type); - - 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(f, fields, var_t, entry) - { - expr_list_t *cases = get_attrp(f->attrs, ATTR_CASE); - if (cases) - nbranch += list_count(cases); - if (f->type) - write_embedded_types(file, f->attrs, f->type, f->name, TRUE, tfsoff); - } - - start_offset = *tfsoff; - update_tfsoff(type, start_offset, file); - print_start_tfs_comment(file, type, start_offset); - if (type->type == RPC_FC_ENCAPSULATED_UNION) - { - const var_t *sv = LIST_ENTRY(list_head(type->fields), const var_t, entry); - const type_t *st = sv->type; - - switch (st->type) - { - case RPC_FC_CHAR: - case RPC_FC_SMALL: - case RPC_FC_USMALL: - case RPC_FC_SHORT: - case RPC_FC_USHORT: - case RPC_FC_LONG: - case RPC_FC_ULONG: - case RPC_FC_ENUM16: - case RPC_FC_ENUM32: - print_file(file, 2, "0x%x,\t/* %s */\n", type->type, string_of_type(type->type)); - print_file(file, 2, "0x%x,\t/* Switch type= %s */\n", - 0x40 | st->type, string_of_type(st->type)); - *tfsoff += 2; - break; - default: - error("union switch type must be an integer, char, or enum\n"); - } - } - print_file(file, 2, "NdrFcShort(0x%x),\t/* %d */\n", size, size); - print_file(file, 2, "NdrFcShort(0x%x),\t/* %d */\n", nbranch, nbranch); - *tfsoff += 4; - - if (fields) LIST_FOR_EACH_ENTRY(f, fields, var_t, entry) - { - type_t *ft = f->type; - expr_list_t *cases = get_attrp(f->attrs, ATTR_CASE); - int deflt = is_attr(f->attrs, ATTR_DEFAULT); - expr_t *c; - - if (cases == NULL && !deflt) - error("union field %s with neither case nor default attribute\n", f->name); - - if (cases) LIST_FOR_EACH_ENTRY(c, cases, expr_t, entry) - { - /* MIDL doesn't check for duplicate cases, even though that seems - like a reasonable thing to do, it just dumps them to the TFS - like we're going to do here. */ - print_file(file, 2, "NdrFcLong(0x%x),\t/* %d */\n", c->cval, c->cval); - *tfsoff += 4; - write_branch_type(file, ft, tfsoff); - } - - /* MIDL allows multiple default branches, even though that seems - illogical, it just chooses the last one, which is what we will - do. */ - if (deflt) - { - deftype = ft; - nodeftype = 0; - } - } - - if (deftype) - { - write_branch_type(file, deftype, tfsoff); - } - else - { - print_file(file, 2, "NdrFcShort(0x%x),\n", nodeftype); - *tfsoff += 2; - } - - return start_offset; -} - -static size_t write_ip_tfs(FILE *file, const attr_list_t *attrs, type_t *type, - unsigned int *typeformat_offset) -{ - size_t i; - size_t start_offset = *typeformat_offset; - expr_t *iid = get_attrp(attrs, ATTR_IIDIS); - - if (iid) - { - print_file(file, 2, "0x2f, /* FC_IP */\n"); - print_file(file, 2, "0x5c, /* FC_PAD */\n"); - *typeformat_offset - += write_conf_or_var_desc(file, NULL, 0, type, iid) + 2; - } - else - { - const type_t *base = is_ptr(type) ? type->ref : type; - const UUID *uuid = get_attrp(base->attrs, ATTR_UUID); - - if (! uuid) - error("%s: interface %s missing UUID\n", __FUNCTION__, base->name); - - update_tfsoff(type, start_offset, file); - print_start_tfs_comment(file, type, start_offset); - print_file(file, 2, "0x2f,\t/* FC_IP */\n"); - print_file(file, 2, "0x5a,\t/* FC_CONSTANT_IID */\n"); - print_file(file, 2, "NdrFcLong(0x%08lx),\n", uuid->Data1); - print_file(file, 2, "NdrFcShort(0x%04x),\n", uuid->Data2); - print_file(file, 2, "NdrFcShort(0x%04x),\n", uuid->Data3); - for (i = 0; i < 8; ++i) - print_file(file, 2, "0x%02x,\n", uuid->Data4[i]); - - if (file) - fprintf(file, "\n"); - - *typeformat_offset += 18; - } - return start_offset; -} - -static size_t write_contexthandle_tfs(FILE *file, const type_t *type, - const var_t *var, - unsigned int *typeformat_offset) -{ - size_t start_offset = *typeformat_offset; - unsigned char flags = 0x08 /* strict */; - - if (is_ptr(type)) - { - flags |= 0x80; - if (type->type != RPC_FC_RP) - flags |= 0x01; - } - if (is_attr(var->attrs, ATTR_IN)) - flags |= 0x40; - if (is_attr(var->attrs, ATTR_OUT)) - flags |= 0x20; - - WRITE_FCTYPE(file, FC_BIND_CONTEXT, *typeformat_offset); - print_file(file, 2, "0x%x,\t/* Context flags: ", flags); - if (((flags & 0x21) != 0x21) && (flags & 0x01)) - print_file(file, 0, "can't be null, "); - if (flags & 0x02) - print_file(file, 0, "serialize, "); - if (flags & 0x04) - print_file(file, 0, "no serialize, "); - if (flags & 0x08) - print_file(file, 0, "strict, "); - if ((flags & 0x21) == 0x20) - print_file(file, 0, "out, "); - if ((flags & 0x21) == 0x21) - print_file(file, 0, "return, "); - if (flags & 0x40) - print_file(file, 0, "in, "); - if (flags & 0x80) - print_file(file, 0, "via ptr, "); - print_file(file, 0, "*/\n"); - print_file(file, 2, "0, /* FIXME: rundown routine index*/\n"); - print_file(file, 2, "0, /* FIXME: param num */\n"); - *typeformat_offset += 4; - - return start_offset; -} - -static size_t write_typeformatstring_var(FILE *file, int indent, const func_t *func, - type_t *type, const var_t *var, - unsigned int *typeformat_offset) -{ - size_t offset; - - if (is_context_handle(type)) - return write_contexthandle_tfs(file, type, var, typeformat_offset); - - if (is_user_type(type)) - { - write_user_tfs(file, type, typeformat_offset); - return type->typestring_offset; - } - - if ((last_ptr(type) || last_array(type)) && is_ptrchain_attr(var, ATTR_STRING)) - return write_string_tfs(file, var->attrs, type, var->name, typeformat_offset, TRUE); - - if (is_array(type)) - { - int ptr_type; - size_t off; - off = write_array_tfs(file, var->attrs, type, var->name, typeformat_offset); - ptr_type = get_attrv(var->attrs, ATTR_POINTERTYPE); - /* Top level pointers to conformant arrays may be handled specially - since we can bypass the pointer, but if the array is burried - beneath another pointer (e.g., "[size_is(,n)] int **p" then we - always need to write the pointer. */ - if (!ptr_type && var->type != type) - /* FIXME: This should use pointer_default, but the information - isn't kept around for arrays. */ - ptr_type = RPC_FC_UP; - if (ptr_type && ptr_type != RPC_FC_RP) - { - unsigned int absoff = type->typestring_offset; - short reloff = absoff - (*typeformat_offset + 2); - off = *typeformat_offset; - print_file(file, 0, "/* %d */\n", off); - print_file(file, 2, "0x%x, 0x0,\t/* %s */\n", ptr_type, - string_of_type(ptr_type)); - print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%u) */\n", - reloff, reloff, absoff); - *typeformat_offset += 4; - } - return off; - } - - if (!is_ptr(type)) - { - /* basic types don't need a type format string */ - if (is_base_type(type->type)) - return 0; - - switch (type->type) - { - case RPC_FC_STRUCT: - case RPC_FC_PSTRUCT: - case RPC_FC_CSTRUCT: - case RPC_FC_CPSTRUCT: - case RPC_FC_CVSTRUCT: - case RPC_FC_BOGUS_STRUCT: - return write_struct_tfs(file, type, var->name, typeformat_offset); - case RPC_FC_ENCAPSULATED_UNION: - case RPC_FC_NON_ENCAPSULATED_UNION: - return write_union_tfs(file, type, typeformat_offset); - case RPC_FC_IGNORE: - case RPC_FC_BIND_PRIMITIVE: - /* nothing to do */ - return 0; - default: - error("write_typeformatstring_var: Unsupported type 0x%x for variable %s\n", type->type, var->name); - } - } - else if (last_ptr(type)) - { - size_t start_offset = *typeformat_offset; - int in_attr = is_attr(var->attrs, ATTR_IN); - int out_attr = is_attr(var->attrs, ATTR_OUT); - const type_t *base = type->ref; - - if (base->type == RPC_FC_IP - || (base->type == 0 - && is_attr(var->attrs, ATTR_IIDIS))) - { - return write_ip_tfs(file, var->attrs, type, typeformat_offset); - } - - /* special case for pointers to base types */ - if (is_base_type(base->type)) - { - print_file(file, indent, "0x%x, 0x%x, /* %s %s[simple_pointer] */\n", - type->type, (!in_attr && out_attr) ? 0x0C : 0x08, - string_of_type(type->type), - (!in_attr && out_attr) ? "[allocated_on_stack] " : ""); - print_file(file, indent, "0x%02x, /* %s */\n", base->type, string_of_type(base->type)); - print_file(file, indent, "0x5c, /* FC_PAD */\n"); - *typeformat_offset += 4; - return start_offset; - } - } - - assert(is_ptr(type)); - - offset = write_typeformatstring_var(file, indent, func, type->ref, var, typeformat_offset); - if (file) - fprintf(file, "/* %2u */\n", *typeformat_offset); - return write_pointer_only_tfs(file, var->attrs, type->type, - !last_ptr(type) ? 0x10 : 0, - offset, typeformat_offset); -} - -static int write_embedded_types(FILE *file, const attr_list_t *attrs, type_t *type, - const char *name, int write_ptr, unsigned int *tfsoff) -{ - int retmask = 0; - - if (is_user_type(type)) - { - write_user_tfs(file, type, tfsoff); - } - else if (is_ptr(type)) - { - type_t *ref = type->ref; - - if (ref->type == RPC_FC_IP - || (ref->type == 0 - && is_attr(attrs, ATTR_IIDIS))) - { - write_ip_tfs(file, attrs, type, tfsoff); - } - else - { - if (!processed(ref) && !is_base_type(ref->type)) - retmask |= write_embedded_types(file, NULL, ref, name, TRUE, tfsoff); - - if (write_ptr) - write_pointer_tfs(file, type, tfsoff); - - retmask |= 1; - } - } - else if (last_array(type) && is_attr(attrs, ATTR_STRING)) - { - write_string_tfs(file, attrs, type, name, tfsoff, FALSE); - } - else if (type->declarray && is_conformant_array(type)) - ; /* conformant arrays and strings are handled specially */ - else if (is_array(type)) - { - write_array_tfs(file, attrs, type, name, tfsoff); - if (is_conformant_array(type)) - retmask |= 1; - } - else if (is_struct(type->type)) - { - if (!processed(type)) - write_struct_tfs(file, type, name, tfsoff); - } - else if (is_union(type->type)) - { - if (!processed(type)) - write_union_tfs(file, type, tfsoff); - } - else if (!is_base_type(type->type)) - error("write_embedded_types: unknown embedded type for %s (0x%x)\n", - name, type->type); - - return retmask; -} - -static size_t process_tfs(FILE *file, const ifref_list_t *ifaces, type_pred_t pred) -{ - const var_t *var; - const ifref_t *iface; - unsigned int typeformat_offset = 2; - - if (ifaces) LIST_FOR_EACH_ENTRY( iface, ifaces, const ifref_t, entry ) - { - if (!pred(iface->iface)) - continue; - - if (iface->iface->funcs) - { - const func_t *func; - LIST_FOR_EACH_ENTRY( func, iface->iface->funcs, const func_t, entry ) - { - if (is_local(func->def->attrs)) continue; - - current_func = func; - if (func->args) - LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) - update_tfsoff( - var->type, - write_typeformatstring_var( - file, 2, func, var->type, var, - &typeformat_offset), - file); - } - } - } - - return typeformat_offset + 1; -} - - -void write_typeformatstring(FILE *file, const ifref_list_t *ifaces, type_pred_t pred) -{ - int indent = 0; - - print_file(file, indent, "static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString =\n"); - print_file(file, indent, "{\n"); - indent++; - print_file(file, indent, "0,\n"); - print_file(file, indent, "{\n"); - indent++; - print_file(file, indent, "NdrFcShort(0x0),\n"); - - set_all_tfswrite(TRUE); - process_tfs(file, ifaces, pred); - - print_file(file, indent, "0x0\n"); - indent--; - print_file(file, indent, "}\n"); - indent--; - print_file(file, indent, "};\n"); - print_file(file, indent, "\n"); -} - -static unsigned int get_required_buffer_size_type( - const type_t *type, const char *name, unsigned int *alignment) -{ - *alignment = 0; - if (is_user_type(type)) - { - const char *uname; - const type_t *utype = get_user_type(type, &uname); - return get_required_buffer_size_type(utype, uname, alignment); - } - else - { - switch (type->type) - { - case RPC_FC_BYTE: - case RPC_FC_CHAR: - case RPC_FC_USMALL: - case RPC_FC_SMALL: - *alignment = 4; - return 1; - - case RPC_FC_WCHAR: - case RPC_FC_USHORT: - case RPC_FC_SHORT: - case RPC_FC_ENUM16: - *alignment = 4; - return 2; - - case RPC_FC_ULONG: - case RPC_FC_LONG: - case RPC_FC_ENUM32: - case RPC_FC_FLOAT: - case RPC_FC_ERROR_STATUS_T: - *alignment = 4; - return 4; - - case RPC_FC_HYPER: - case RPC_FC_DOUBLE: - *alignment = 8; - return 8; - - case RPC_FC_IGNORE: - case RPC_FC_BIND_PRIMITIVE: - return 0; - - case RPC_FC_STRUCT: - case RPC_FC_PSTRUCT: - { - size_t size = 0; - const var_t *field; - if (!type->fields) return 0; - LIST_FOR_EACH_ENTRY( field, type->fields, const var_t, entry ) - { - unsigned int alignment; - size += get_required_buffer_size_type(field->type, field->name, - &alignment); - } - return size; - } - - case RPC_FC_RP: - return - is_base_type( type->ref->type ) || type->ref->type == RPC_FC_STRUCT - ? get_required_buffer_size_type( type->ref, name, alignment ) - : 0; - - case RPC_FC_SMFARRAY: - case RPC_FC_LGFARRAY: - return type->dim * get_required_buffer_size_type(type->ref, name, alignment); - - default: - return 0; - } - } -} - -static unsigned int get_required_buffer_size(const var_t *var, unsigned int *alignment, enum pass pass) -{ - int in_attr = is_attr(var->attrs, ATTR_IN); - int out_attr = is_attr(var->attrs, ATTR_OUT); - const type_t *t; - - if (!in_attr && !out_attr) - in_attr = 1; - - *alignment = 0; - - for (t = var->type; is_ptr(t); t = t->ref) - if (is_attr(t->attrs, ATTR_CONTEXTHANDLE)) - { - *alignment = 4; - return 20; - } - - if (pass == PASS_OUT) - { - if (out_attr && is_ptr(var->type)) - { - type_t *type = var->type; - - if (type->type == RPC_FC_STRUCT) - { - const var_t *field; - unsigned int size = 36; - - if (!type->fields) return size; - LIST_FOR_EACH_ENTRY( field, type->fields, const var_t, entry ) - { - unsigned int align; - size += get_required_buffer_size_type( - field->type, field->name, &align); - } - return size; - } - } - return 0; - } - else - { - if ((!out_attr || in_attr) && !var->type->size_is - && !is_attr(var->attrs, ATTR_STRING) && !var->type->declarray) - { - if (is_ptr(var->type)) - { - type_t *type = var->type; - - if (is_base_type(type->type)) - { - return 25; - } - else if (type->type == RPC_FC_STRUCT) - { - unsigned int size = 36; - const var_t *field; - - if (!type->fields) return size; - LIST_FOR_EACH_ENTRY( field, type->fields, const var_t, entry ) - { - unsigned int align; - size += get_required_buffer_size_type( - field->type, field->name, &align); - } - return size; - } - } - } - - return get_required_buffer_size_type(var->type, var->name, alignment); - } -} - -static unsigned int get_function_buffer_size( const func_t *func, enum pass pass ) -{ - const var_t *var; - unsigned int total_size = 0, alignment; - - if (func->args) - { - LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) - { - total_size += get_required_buffer_size(var, &alignment, pass); - total_size += alignment; - } - } - - if (pass == PASS_OUT && !is_void(func->def->type)) - { - total_size += get_required_buffer_size(func->def, &alignment, PASS_RETURN); - total_size += alignment; - } - return total_size; -} - -static void print_phase_function(FILE *file, int indent, const char *type, - enum remoting_phase phase, - const var_t *var, unsigned int type_offset) -{ - const char *function; - switch (phase) - { - case PHASE_BUFFERSIZE: - function = "BufferSize"; - break; - case PHASE_MARSHAL: - function = "Marshall"; - break; - case PHASE_UNMARSHAL: - function = "Unmarshall"; - break; - case PHASE_FREE: - function = "Free"; - break; - default: - assert(0); - return; - } - - print_file(file, indent, "Ndr%s%s(\n", type, function); - indent++; - print_file(file, indent, "&_StubMsg,\n"); - print_file(file, indent, "%s%s%s%s,\n", - (phase == PHASE_UNMARSHAL) ? "(unsigned char **)" : "(unsigned char *)", - (phase == PHASE_UNMARSHAL || decl_indirect(var->type)) ? "&" : "", - (phase == PHASE_UNMARSHAL && decl_indirect(var->type)) ? "_p_" : "", - var->name); - print_file(file, indent, "(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%d]%s\n", - type_offset, (phase == PHASE_UNMARSHAL) ? "," : ");"); - if (phase == PHASE_UNMARSHAL) - print_file(file, indent, "0);\n"); - indent--; -} - -void print_phase_basetype(FILE *file, int indent, enum remoting_phase phase, - enum pass pass, const var_t *var, - const char *varname) -{ - type_t *type = var->type; - unsigned int size; - unsigned int alignment = 0; - unsigned char rtype; - - /* no work to do for other phases, buffer sizing is done elsewhere */ - if (phase != PHASE_MARSHAL && phase != PHASE_UNMARSHAL) - return; - - rtype = is_ptr(type) ? type->ref->type : type->type; - - switch (rtype) - { - case RPC_FC_BYTE: - case RPC_FC_CHAR: - case RPC_FC_SMALL: - case RPC_FC_USMALL: - size = 1; - alignment = 1; - break; - - case RPC_FC_WCHAR: - case RPC_FC_USHORT: - case RPC_FC_SHORT: - case RPC_FC_ENUM16: - size = 2; - alignment = 2; - break; - - case RPC_FC_ULONG: - case RPC_FC_LONG: - case RPC_FC_ENUM32: - case RPC_FC_FLOAT: - case RPC_FC_ERROR_STATUS_T: - size = 4; - alignment = 4; - break; - - case RPC_FC_HYPER: - case RPC_FC_DOUBLE: - size = 8; - alignment = 8; - break; - - case RPC_FC_IGNORE: - case RPC_FC_BIND_PRIMITIVE: - /* no marshalling needed */ - return; - - default: - error("print_phase_basetype: Unsupported type: %s (0x%02x, ptr_level: 0)\n", var->name, rtype); - size = 0; - } - - if (phase == PHASE_MARSHAL) - print_file(file, indent, "MIDL_memset(_StubMsg.Buffer, 0, (0x%x - (long)_StubMsg.Buffer) & 0x%x);\n", alignment, alignment - 1); - print_file(file, indent, "_StubMsg.Buffer = (unsigned char *)(((long)_StubMsg.Buffer + %u) & ~0x%x);\n", - alignment - 1, alignment - 1); - - if (phase == PHASE_MARSHAL) - { - print_file(file, indent, "*("); - write_type_decl(file, is_ptr(type) ? type->ref : type, NULL); - if (is_ptr(type)) - fprintf(file, " *)_StubMsg.Buffer = *"); - else - fprintf(file, " *)_StubMsg.Buffer = "); - fprintf(file, "%s", varname); - fprintf(file, ";\n"); - } - else if (phase == PHASE_UNMARSHAL) - { - print_file(file, indent, "if (_StubMsg.Buffer + sizeof("); - write_type_decl(file, is_ptr(type) ? type->ref : type, NULL); - fprintf(file, ") > _StubMsg.BufferEnd)\n"); - print_file(file, indent, "{\n"); - print_file(file, indent + 1, "RpcRaiseException(RPC_X_BAD_STUB_DATA);\n"); - print_file(file, indent, "}\n"); - if (pass == PASS_IN || pass == PASS_RETURN) - print_file(file, indent, ""); - else - print_file(file, indent, "*"); - fprintf(file, "%s", varname); - if (pass == PASS_IN && is_ptr(type)) - fprintf(file, " = ("); - else - fprintf(file, " = *("); - write_type_decl(file, is_ptr(type) ? type->ref : type, NULL); - fprintf(file, " *)_StubMsg.Buffer;\n"); - } - - print_file(file, indent, "_StubMsg.Buffer += sizeof("); - write_type_decl(file, var->type, NULL); - fprintf(file, ");\n"); -} - -/* returns whether the MaxCount, Offset or ActualCount members need to be - * filled in for the specified phase */ -static inline int is_size_needed_for_phase(enum remoting_phase phase) -{ - return (phase != PHASE_UNMARSHAL); -} - -expr_t *get_size_is_expr(const type_t *t, const char *name) -{ - expr_t *x = NULL; - - for ( ; is_ptr(t) || is_array(t); t = t->ref) - if (t->size_is) - { - if (!x) - x = t->size_is; - else - error("%s: multidimensional conformant" - " arrays not supported at the top level\n", - name); - } - - return x; -} - -static void write_remoting_arg(FILE *file, int indent, const func_t *func, - enum pass pass, enum remoting_phase phase, - const var_t *var) -{ - int in_attr, out_attr, pointer_type; - const type_t *type = var->type; - unsigned char rtype; - size_t start_offset = type->typestring_offset; - - pointer_type = get_attrv(var->attrs, ATTR_POINTERTYPE); - if (!pointer_type) - pointer_type = RPC_FC_RP; - - in_attr = is_attr(var->attrs, ATTR_IN); - out_attr = is_attr(var->attrs, ATTR_OUT); - if (!in_attr && !out_attr) - in_attr = 1; - - if (phase != PHASE_FREE) - switch (pass) - { - case PASS_IN: - if (!in_attr) return; - break; - case PASS_OUT: - if (!out_attr) return; - break; - case PASS_RETURN: - break; - } - - rtype = type->type; - - if (is_context_handle(type)) - { - if (phase == PHASE_MARSHAL) - { - if (pass == PASS_IN) - { - print_file(file, indent, "NdrClientContextMarshall(\n"); - print_file(file, indent + 1, "&_StubMsg,\n"); - print_file(file, indent + 1, "(NDR_CCONTEXT)%s%s,\n", is_ptr(type) ? "*" : "", var->name); - print_file(file, indent + 1, "%s);\n", in_attr && out_attr ? "1" : "0"); - } - else - { - print_file(file, indent, "NdrServerContextMarshall(\n"); - print_file(file, indent + 1, "&_StubMsg,\n"); - print_file(file, indent + 1, "(NDR_SCONTEXT)%s,\n", var->name); - print_file(file, indent + 1, "(NDR_RUNDOWN)%s_rundown);\n", get_context_handle_type_name(var->type)); - } - } - else if (phase == PHASE_UNMARSHAL) - { - if (pass == PASS_OUT) - { - print_file(file, indent, "NdrClientContextUnmarshall(\n"); - print_file(file, indent + 1, "&_StubMsg,\n"); - print_file(file, indent + 1, "(NDR_CCONTEXT *)%s,\n", var->name); - print_file(file, indent + 1, "_Handle);\n"); - } - else - print_file(file, indent, "%s = NdrServerContextUnmarshall(&_StubMsg);\n", var->name); - } - } - else if (is_user_type(var->type)) - { - print_phase_function(file, indent, "UserMarshal", phase, var, start_offset); - } - else if (is_string_type(var->attrs, var->type)) - { - if (is_array(type) && !is_conformant_array(type)) - print_phase_function(file, indent, "NonConformantString", phase, var, start_offset); - else - { - if (type->size_is && is_size_needed_for_phase(phase)) - { - print_file(file, indent, "_StubMsg.MaxCount = (unsigned long)"); - write_expr(file, type->size_is, 1); - fprintf(file, ";\n"); - } - - if ((phase == PHASE_FREE) || (pointer_type == RPC_FC_UP)) - print_phase_function(file, indent, "Pointer", phase, var, start_offset); - else - print_phase_function(file, indent, "ConformantString", phase, var, - start_offset + (type->size_is ? 4 : 2)); - } - } - else if (is_array(type)) - { - unsigned char tc = type->type; - const char *array_type = "FixedArray"; - - /* We already have the size_is expression since it's at the - top level, but do checks for multidimensional conformant - arrays. When we handle them, we'll need to extend this - function to return a list, and then we'll actually use - the return value. */ - get_size_is_expr(type, var->name); - - if (tc == RPC_FC_SMVARRAY || tc == RPC_FC_LGVARRAY) - { - if (is_size_needed_for_phase(phase)) - { - print_file(file, indent, "_StubMsg.Offset = (unsigned long)0;\n"); /* FIXME */ - print_file(file, indent, "_StubMsg.ActualCount = (unsigned long)"); - write_expr(file, type->length_is, 1); - fprintf(file, ";\n\n"); - } - array_type = "VaryingArray"; - } - else if (tc == RPC_FC_CARRAY) - { - if (is_size_needed_for_phase(phase)) - { - print_file(file, indent, "_StubMsg.MaxCount = (unsigned long)"); - write_expr(file, type->size_is, 1); - fprintf(file, ";\n\n"); - } - array_type = "ConformantArray"; - } - else if (tc == RPC_FC_CVARRAY || tc == RPC_FC_BOGUS_ARRAY) - { - if (is_size_needed_for_phase(phase)) - { - if (type->size_is) - { - print_file(file, indent, "_StubMsg.MaxCount = (unsigned long)"); - write_expr(file, type->size_is, 1); - fprintf(file, ";\n"); - } - if (type->length_is) - { - print_file(file, indent, "_StubMsg.Offset = (unsigned long)0;\n"); /* FIXME */ - print_file(file, indent, "_StubMsg.ActualCount = (unsigned long)"); - write_expr(file, type->length_is, 1); - fprintf(file, ";\n\n"); - } - } - array_type = (tc == RPC_FC_BOGUS_ARRAY - ? "ComplexArray" - : "ConformantVaryingArray"); - } - - if (pointer_type != RPC_FC_RP) array_type = "Pointer"; - print_phase_function(file, indent, array_type, phase, var, start_offset); - if (phase == PHASE_FREE && type->declarray && pointer_type == RPC_FC_RP) - { - /* these are all unmarshalled by pointing into the buffer on the - * server side */ - if (type->type == RPC_FC_BOGUS_ARRAY || - type->type == RPC_FC_CVARRAY || - (type->type == RPC_FC_SMVARRAY && type->type == RPC_FC_LGVARRAY && in_attr) || - (type->type == RPC_FC_CARRAY && type->type == RPC_FC_CARRAY && !in_attr)) - { - print_file(file, indent, "if (%s)\n", var->name); - indent++; - print_file(file, indent, "_StubMsg.pfnFree(%s);\n", var->name); - } - } - } - else if (!is_ptr(var->type) && is_base_type(rtype)) - { - if (phase != PHASE_FREE) - print_phase_basetype(file, indent, phase, pass, var, var->name); - } - else if (!is_ptr(var->type)) - { - switch (rtype) - { - case RPC_FC_STRUCT: - case RPC_FC_PSTRUCT: - print_phase_function(file, indent, "SimpleStruct", phase, var, start_offset); - break; - case RPC_FC_CSTRUCT: - case RPC_FC_CPSTRUCT: - print_phase_function(file, indent, "ConformantStruct", phase, var, start_offset); - break; - case RPC_FC_CVSTRUCT: - print_phase_function(file, indent, "ConformantVaryingStruct", phase, var, start_offset); - break; - case RPC_FC_BOGUS_STRUCT: - print_phase_function(file, indent, "ComplexStruct", phase, var, start_offset); - break; - case RPC_FC_RP: - if (is_base_type( var->type->ref->type )) - { - print_phase_basetype(file, indent, phase, pass, var, var->name); - } - else if (var->type->ref->type == RPC_FC_STRUCT) - { - if (phase != PHASE_BUFFERSIZE && phase != PHASE_FREE) - print_phase_function(file, indent, "SimpleStruct", phase, var, start_offset + 4); - } - else - { - expr_t *iid; - if ((iid = get_attrp( var->attrs, ATTR_IIDIS ))) - { - print_file( file, indent, "_StubMsg.MaxCount = (unsigned long) " ); - write_expr( file, iid, 1 ); - fprintf( file, ";\n\n" ); - } - print_phase_function(file, indent, "Pointer", phase, var, start_offset); - } - break; - default: - error("write_remoting_arguments: Unsupported type: %s (0x%02x)\n", var->name, rtype); - } - } - else - { - if (last_ptr(var->type) && (pointer_type == RPC_FC_RP) && is_base_type(rtype)) - { - if (phase != PHASE_FREE) - print_phase_basetype(file, indent, phase, pass, var, var->name); - } - else if (last_ptr(var->type) && (pointer_type == RPC_FC_RP) && (rtype == RPC_FC_STRUCT)) - { - if (phase != PHASE_BUFFERSIZE && phase != PHASE_FREE) - print_phase_function(file, indent, "SimpleStruct", phase, var, start_offset + 4); - } - else - { - expr_t *iid; - expr_t *sx = get_size_is_expr(type, var->name); - - if ((iid = get_attrp( var->attrs, ATTR_IIDIS ))) - { - print_file( file, indent, "_StubMsg.MaxCount = (unsigned long) " ); - write_expr( file, iid, 1 ); - fprintf( file, ";\n\n" ); - } - else if (sx) - { - print_file(file, indent, "_StubMsg.MaxCount = (unsigned long) "); - write_expr(file, sx, 1); - fprintf(file, ";\n\n"); - } - if (var->type->ref->type == RPC_FC_IP) - print_phase_function(file, indent, "InterfacePointer", phase, var, start_offset); - else - print_phase_function(file, indent, "Pointer", phase, var, start_offset); - } - } - fprintf(file, "\n"); -} - -void write_remoting_arguments(FILE *file, int indent, const func_t *func, - enum pass pass, enum remoting_phase phase) -{ - if (phase == PHASE_BUFFERSIZE && pass != PASS_RETURN) - { - unsigned int size = get_function_buffer_size( func, pass ); - print_file(file, indent, "_StubMsg.BufferLength = %u;\n", size); - } - - if (pass == PASS_RETURN) - { - var_t var; - var = *func->def; - var.name = xstrdup( "_RetVal" ); - write_remoting_arg( file, indent, func, pass, phase, &var ); - free( var.name ); - } - else - { - const var_t *var; - if (!func->args) - return; - LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) - write_remoting_arg( file, indent, func, pass, phase, var ); - } -} - - -size_t get_size_procformatstring_var(const var_t *var) -{ - return write_procformatstring_var(NULL, 0, var, FALSE); -} - - -size_t get_size_procformatstring_func(const func_t *func) -{ - const var_t *var; - size_t size = 0; - - /* argument list size */ - if (func->args) - LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) - size += get_size_procformatstring_var(var); - - /* return value size */ - if (is_void(func->def->type)) - size += 2; /* FC_END and FC_PAD */ - else - size += get_size_procformatstring_var(func->def); - - return size; -} - -size_t get_size_procformatstring(const ifref_list_t *ifaces, type_pred_t pred) -{ - const ifref_t *iface; - size_t size = 1; - const func_t *func; - - if (ifaces) LIST_FOR_EACH_ENTRY( iface, ifaces, const ifref_t, entry ) - { - if (!pred(iface->iface)) - continue; - - if (iface->iface->funcs) - LIST_FOR_EACH_ENTRY( func, iface->iface->funcs, const func_t, entry ) - if (!is_local(func->def->attrs)) - size += get_size_procformatstring_func( func ); - } - return size; -} - -size_t get_size_typeformatstring(const ifref_list_t *ifaces, type_pred_t pred) -{ - set_all_tfswrite(FALSE); - return process_tfs(NULL, ifaces, pred); -} - -static void write_struct_expr(FILE *h, const expr_t *e, int brackets, - const var_list_t *fields, const char *structvar) -{ - switch (e->type) { - case EXPR_VOID: - break; - case EXPR_NUM: - fprintf(h, "%lu", e->u.lval); - break; - case EXPR_HEXNUM: - fprintf(h, "0x%lx", e->u.lval); - break; - case EXPR_DOUBLE: - fprintf(h, "%#.15g", e->u.dval); - break; - case EXPR_TRUEFALSE: - if (e->u.lval == 0) - fprintf(h, "FALSE"); - else - fprintf(h, "TRUE"); - break; - case EXPR_IDENTIFIER: - { - const var_t *field; - LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry ) - if (!strcmp(e->u.sval, field->name)) - { - fprintf(h, "%s->%s", structvar, e->u.sval); - break; - } - - if (&field->entry == fields) error("no field found for identifier %s\n", e->u.sval); - break; - } - case EXPR_NEG: - fprintf(h, "-"); - write_struct_expr(h, e->ref, 1, fields, structvar); - break; - case EXPR_NOT: - fprintf(h, "~"); - write_struct_expr(h, e->ref, 1, fields, structvar); - break; - case EXPR_PPTR: - fprintf(h, "*"); - write_struct_expr(h, e->ref, 1, fields, structvar); - break; - case EXPR_CAST: - fprintf(h, "("); - write_type_decl(h, e->u.tref, NULL); - fprintf(h, ")"); - write_struct_expr(h, e->ref, 1, fields, structvar); - break; - case EXPR_SIZEOF: - fprintf(h, "sizeof("); - write_type_decl(h, e->u.tref, NULL); - fprintf(h, ")"); - break; - case EXPR_SHL: - case EXPR_SHR: - case EXPR_MUL: - case EXPR_DIV: - case EXPR_ADD: - case EXPR_SUB: - case EXPR_AND: - case EXPR_OR: - if (brackets) fprintf(h, "("); - write_struct_expr(h, e->ref, 1, fields, structvar); - switch (e->type) { - case EXPR_SHL: fprintf(h, " << "); break; - case EXPR_SHR: fprintf(h, " >> "); break; - case EXPR_MUL: fprintf(h, " * "); break; - case EXPR_DIV: fprintf(h, " / "); break; - case EXPR_ADD: fprintf(h, " + "); break; - case EXPR_SUB: fprintf(h, " - "); break; - case EXPR_AND: fprintf(h, " & "); break; - case EXPR_OR: fprintf(h, " | "); break; - default: break; - } - write_struct_expr(h, e->u.ext, 1, fields, structvar); - if (brackets) fprintf(h, ")"); - break; - case EXPR_COND: - if (brackets) fprintf(h, "("); - write_struct_expr(h, e->ref, 1, fields, structvar); - fprintf(h, " ? "); - write_struct_expr(h, e->u.ext, 1, fields, structvar); - fprintf(h, " : "); - write_struct_expr(h, e->ext2, 1, fields, structvar); - if (brackets) fprintf(h, ")"); - break; - case EXPR_ADDRESSOF: - fprintf(h, "&"); - write_struct_expr(h, e->ref, 1, fields, structvar); - break; - } -} - - -void declare_stub_args( FILE *file, int indent, const func_t *func ) -{ - int in_attr, out_attr; - int i = 0; - const var_t *def = func->def; - const var_t *var; - - /* declare return value '_RetVal' */ - if (!is_void(def->type)) - { - print_file(file, indent, ""); - write_type_decl_left(file, def->type); - fprintf(file, " _RetVal;\n"); - } - - if (!func->args) - return; - - LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) - { - int is_string = is_attr(var->attrs, ATTR_STRING); - - in_attr = is_attr(var->attrs, ATTR_IN); - out_attr = is_attr(var->attrs, ATTR_OUT); - if (!out_attr && !in_attr) - in_attr = 1; - - if (is_context_handle(var->type)) - print_file(file, indent, "NDR_SCONTEXT %s;\n", var->name); - else - { - if (!in_attr && !var->type->size_is && !is_string) - { - print_file(file, indent, ""); - write_type_decl(file, var->type->declarray ? var->type : var->type->ref, - "_W%u", i++); - fprintf(file, ";\n"); - } - - print_file(file, indent, ""); - write_type_decl_left(file, var->type); - fprintf(file, " "); - if (var->type->declarray) { - fprintf(file, "( *"); - write_name(file, var); - fprintf(file, " )"); - } else - write_name(file, var); - write_type_right(file, var->type, FALSE); - fprintf(file, ";\n"); - - if (decl_indirect(var->type)) - print_file(file, indent, "void *_p_%s = &%s;\n", - var->name, var->name); - } - } -} - - -void assign_stub_out_args( FILE *file, int indent, const func_t *func ) -{ - int in_attr, out_attr; - int i = 0, sep = 0; - const var_t *var; - - if (!func->args) - return; - - LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) - { - int is_string = is_attr(var->attrs, ATTR_STRING); - in_attr = is_attr(var->attrs, ATTR_IN); - out_attr = is_attr(var->attrs, ATTR_OUT); - if (!out_attr && !in_attr) - in_attr = 1; - - if (!in_attr) - { - print_file(file, indent, ""); - write_name(file, var); - - 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; - - fprintf(file, " = NdrAllocate(&_StubMsg, "); - for ( ; type->size_is ; type = type->ref) - { - write_expr(file, type->size_is, TRUE); - fprintf(file, " * "); - } - size = type_memsize(type, &align); - fprintf(file, "%u);\n", size); - } - else if (!is_string) - { - fprintf(file, " = &_W%u;\n", i); - if (is_ptr(var->type) && !last_ptr(var->type)) - print_file(file, indent, "_W%u = 0;\n", i); - i++; - } - - sep = 1; - } - } - if (sep) - fprintf(file, "\n"); -} - - -int write_expr_eval_routines(FILE *file, const char *iface) -{ - static const char *var_name = "pS"; - int result = 0; - struct expr_eval_routine *eval; - unsigned short callback_offset = 0; - - LIST_FOR_EACH_ENTRY(eval, &expr_eval_routines, struct expr_eval_routine, entry) - { - const char *name = eval->structure->name; - const var_list_t *fields = eval->structure->fields; - result = 1; - - print_file(file, 0, "static void __RPC_USER %s_%sExprEval_%04u(PMIDL_STUB_MESSAGE pStubMsg)\n", - iface, name, callback_offset); - print_file(file, 0, "{\n"); - print_file (file, 1, "%s *%s = (%s *)(pStubMsg->StackTop - %u);\n", - name, var_name, name, eval->baseoff); - print_file(file, 1, "pStubMsg->Offset = 0;\n"); /* FIXME */ - print_file(file, 1, "pStubMsg->MaxCount = (unsigned long)"); - write_struct_expr(file, eval->expr, 1, fields, var_name); - fprintf(file, ";\n"); - print_file(file, 0, "}\n\n"); - callback_offset++; - } - return result; -} - -void write_expr_eval_routine_list(FILE *file, const char *iface) -{ - struct expr_eval_routine *eval; - struct expr_eval_routine *cursor; - unsigned short callback_offset = 0; - - fprintf(file, "static const EXPR_EVAL ExprEvalRoutines[] =\n"); - fprintf(file, "{\n"); - - LIST_FOR_EACH_ENTRY_SAFE(eval, cursor, &expr_eval_routines, struct expr_eval_routine, entry) - { - const char *name = eval->structure->name; - print_file(file, 1, "%s_%sExprEval_%04u,\n", iface, name, callback_offset); - callback_offset++; - list_remove(&eval->entry); - free(eval); - } - - fprintf(file, "};\n\n"); -} - -void write_user_quad_list(FILE *file) -{ - user_type_t *ut; - - if (list_empty(&user_type_list)) - return; - - fprintf(file, "static const USER_MARSHAL_ROUTINE_QUADRUPLE UserMarshalRoutines[] =\n"); - fprintf(file, "{\n"); - LIST_FOR_EACH_ENTRY(ut, &user_type_list, user_type_t, entry) - { - const char *sep = &ut->entry == list_tail(&user_type_list) ? "" : ","; - print_file(file, 1, "{\n"); - print_file(file, 2, "(USER_MARSHAL_SIZING_ROUTINE)%s_UserSize,\n", ut->name); - print_file(file, 2, "(USER_MARSHAL_MARSHALLING_ROUTINE)%s_UserMarshal,\n", ut->name); - print_file(file, 2, "(USER_MARSHAL_UNMARSHALLING_ROUTINE)%s_UserUnmarshal,\n", ut->name); - print_file(file, 2, "(USER_MARSHAL_FREEING_ROUTINE)%s_UserFree\n", ut->name); - print_file(file, 1, "}%s\n", sep); - } - fprintf(file, "};\n\n"); -} - -void write_endpoints( FILE *f, const char *prefix, const str_list_t *list ) -{ - const struct str_list_entry_t *endpoint; - const char *p; - - /* this should be an array of RPC_PROTSEQ_ENDPOINT but we want const strings */ - print_file( f, 0, "static const unsigned char * %s__RpcProtseqEndpoint[][2] =\n{\n", prefix ); - LIST_FOR_EACH_ENTRY( endpoint, list, const struct str_list_entry_t, entry ) - { - print_file( f, 1, "{ (const unsigned char *)\"" ); - for (p = endpoint->str; *p && *p != ':'; p++) - { - if (*p == '"' || *p == '\\') fputc( '\\', f ); - fputc( *p, f ); - } - if (!*p) goto error; - if (p[1] != '[') goto error; - - fprintf( f, "\", (const unsigned char *)\"" ); - for (p += 2; *p && *p != ']'; p++) - { - if (*p == '"' || *p == '\\') fputc( '\\', f ); - fputc( *p, f ); - } - if (*p != ']') goto error; - fprintf( f, "\" },\n" ); - } - print_file( f, 0, "};\n\n" ); - return; - -error: - error("Invalid endpoint syntax '%s'\n", endpoint->str); -} diff --git a/reactos/tools/widl_20080105/typegen.h b/reactos/tools/widl_20080105/typegen.h deleted file mode 100644 index c9a5148290f..00000000000 --- a/reactos/tools/widl_20080105/typegen.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Format String Generator for IDL Compiler - * - * Copyright 2005-2006 Eric Kohl - * Copyright 2005 Robert Shearman - * - * 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 - -enum pass -{ - PASS_IN, - PASS_OUT, - PASS_RETURN -}; - -enum remoting_phase -{ - PHASE_BUFFERSIZE, - PHASE_MARSHAL, - PHASE_UNMARSHAL, - PHASE_FREE -}; - -typedef int (*type_pred_t)(const type_t *); - -void write_formatstringsdecl(FILE *f, int indent, ifref_list_t *ifaces, type_pred_t pred); -void write_procformatstring(FILE *file, const ifref_list_t *ifaces, type_pred_t pred); -void write_typeformatstring(FILE *file, const ifref_list_t *ifaces, type_pred_t pred); -void print_phase_basetype(FILE *file, int indent, enum remoting_phase phase, enum pass pass, const var_t *var, const char *varname); -void write_remoting_arguments(FILE *file, int indent, const func_t *func, enum pass pass, enum remoting_phase phase); -size_t get_size_procformatstring_var(const var_t *var); -size_t get_size_procformatstring_func(const func_t *func); -size_t get_size_procformatstring(const ifref_list_t *ifaces, type_pred_t pred); -size_t get_size_typeformatstring(const ifref_list_t *ifaces, type_pred_t pred); -void assign_stub_out_args( FILE *file, int indent, const func_t *func ); -void declare_stub_args( FILE *file, int indent, const func_t *func ); -int write_expr_eval_routines(FILE *file, const char *iface); -void write_expr_eval_routine_list(FILE *file, const char *iface); -void write_user_quad_list(FILE *file); -void write_endpoints( FILE *f, const char *prefix, const str_list_t *list ); -size_t type_memsize(const type_t *t, unsigned int *align); -int decl_indirect(const type_t *t); -void write_parameters_init(FILE *file, int indent, const func_t *func); -void print(FILE *file, int indent, const char *format, va_list ap); -int get_padding(const var_list_t *fields); -int is_user_type(const type_t *t); -expr_t *get_size_is_expr(const type_t *t, const char *name); diff --git a/reactos/tools/widl_20080105/typelib.c b/reactos/tools/widl_20080105/typelib.c deleted file mode 100644 index 7130e506d77..00000000000 --- a/reactos/tools/widl_20080105/typelib.c +++ /dev/null @@ -1,403 +0,0 @@ -/* - * IDL Compiler - * - * Copyright 2004 Ove Kaaven - * Copyright 2006 Jacek Caban 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 "config.h" -#include "wine/port.h" -#include "wine/wpp.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#define NONAMELESSUNION -#define NONAMELESSSTRUCT - -#include "windef.h" -#include "winbase.h" - -#include "widl.h" -#include "utils.h" -#include "parser.h" -#include "header.h" -#include "typelib.h" -#include "widltypes.h" -#include "typelib_struct.h" - -int in_typelib = 0; - -static typelib_t *typelib; - -type_t *duptype(type_t *t, int dupname) -{ - type_t *d = alloc_type(); - - *d = *t; - if (dupname && t->name) - d->name = xstrdup(t->name); - - d->orig = t; - return d; -} - -type_t *alias(type_t *t, const char *name) -{ - type_t *a = duptype(t, 0); - - a->name = xstrdup(name); - a->kind = TKIND_ALIAS; - a->attrs = NULL; - a->declarray = FALSE; - - return a; -} - -int is_ptr(const type_t *t) -{ - unsigned char c = t->type; - return c == RPC_FC_RP - || c == RPC_FC_UP - || c == RPC_FC_FP - || c == RPC_FC_OP; -} - -int is_array(const type_t *t) -{ - switch (t->type) - { - case RPC_FC_SMFARRAY: - case RPC_FC_LGFARRAY: - case RPC_FC_SMVARRAY: - case RPC_FC_LGVARRAY: - case RPC_FC_CARRAY: - case RPC_FC_CVARRAY: - case RPC_FC_BOGUS_ARRAY: - return TRUE; - default: - return FALSE; - } -} - -/* List of oleauto types that should be recognized by name. - * (most of) these seem to be intrinsic types in mktyplib. */ - -static const struct oatype { - const char *kw; - unsigned short vt; -} oatypes[] = { - {"BSTR", VT_BSTR}, - {"CURRENCY", VT_CY}, - {"DATE", VT_DATE}, - {"DECIMAL", VT_DECIMAL}, - {"HRESULT", VT_HRESULT}, - {"LPSTR", VT_LPSTR}, - {"LPWSTR", VT_LPWSTR}, - {"SCODE", VT_ERROR}, - {"VARIANT", VT_VARIANT}, - {"VARIANT_BOOL", VT_BOOL} -}; -#define NTYPES (sizeof(oatypes)/sizeof(oatypes[0])) -#define KWP(p) ((const struct oatype *)(p)) - -static int kw_cmp_func(const void *s1, const void *s2) -{ - return strcmp(KWP(s1)->kw, KWP(s2)->kw); -} - -static unsigned short builtin_vt(const type_t *t) -{ - const char *kw = t->name; - struct oatype key; - const struct oatype *kwp; - key.kw = kw; -#ifdef KW_BSEARCH - kwp = bsearch(&key, oatypes, NTYPES, sizeof(oatypes[0]), kw_cmp_func); -#else - { - unsigned int i; - for (kwp=NULL, i=0; i < NTYPES; i++) - if (!kw_cmp_func(&key, &oatypes[i])) { - kwp = &oatypes[i]; - break; - } - } -#endif - if (kwp) { - return kwp->vt; - } - if (is_string_type (t->attrs, t)) - switch (t->ref->type) - { - case RPC_FC_CHAR: return VT_LPSTR; - case RPC_FC_WCHAR: return VT_LPWSTR; - default: break; - } - return 0; -} - -static int match(const char*n, const char*m) -{ - if (!n) return 0; - return !strcmp(n, m); -} - -unsigned short get_type_vt(type_t *t) -{ - unsigned short vt; - - chat("get_type_vt: %p type->name %s\n", t, t->name); - if (t->name) { - vt = builtin_vt(t); - if (vt) return vt; - } - - if (t->kind == TKIND_ALIAS && t->attrs) - return VT_USERDEFINED; - - switch (t->type) { - case RPC_FC_BYTE: - case RPC_FC_USMALL: - return VT_UI1; - case RPC_FC_CHAR: - case RPC_FC_SMALL: - return VT_I1; - case RPC_FC_WCHAR: - return VT_I2; /* mktyplib seems to parse wchar_t as short */ - case RPC_FC_SHORT: - return VT_I2; - case RPC_FC_USHORT: - return VT_UI2; - case RPC_FC_LONG: - if (match(t->name, "int")) return VT_INT; - return VT_I4; - case RPC_FC_ULONG: - if (match(t->name, "int")) return VT_UINT; - return VT_UI4; - case RPC_FC_HYPER: - if (t->sign < 0) return VT_UI8; - if (match(t->name, "MIDL_uhyper")) return VT_UI8; - return VT_I8; - case RPC_FC_FLOAT: - return VT_R4; - case RPC_FC_DOUBLE: - return VT_R8; - case RPC_FC_RP: - case RPC_FC_UP: - case RPC_FC_OP: - case RPC_FC_FP: - case RPC_FC_CARRAY: - case RPC_FC_CVARRAY: - if(t->ref) - { - if (match(t->ref->name, "SAFEARRAY")) - return VT_SAFEARRAY; - return VT_PTR; - } - - error("get_type_vt: unknown-deref-type: %d\n", t->ref->type); - break; - case RPC_FC_IP: - if(match(t->name, "IUnknown")) - return VT_UNKNOWN; - if(match(t->name, "IDispatch")) - return VT_DISPATCH; - return VT_USERDEFINED; - - case RPC_FC_ENUM16: - case RPC_FC_STRUCT: - case RPC_FC_PSTRUCT: - case RPC_FC_CSTRUCT: - case RPC_FC_CPSTRUCT: - case RPC_FC_CVSTRUCT: - case RPC_FC_BOGUS_STRUCT: - return VT_USERDEFINED; - case 0: - return t->kind == TKIND_PRIMITIVE ? VT_VOID : VT_USERDEFINED; - default: - error("get_type_vt: unknown type: 0x%02x\n", t->type); - } - return 0; -} - -void start_typelib(char *name, attr_list_t *attrs) -{ - in_typelib++; - if (!do_typelib) return; - - typelib = xmalloc(sizeof(*typelib)); - typelib->name = xstrdup(name); - typelib->filename = xstrdup(typelib_name); - typelib->attrs = attrs; - list_init( &typelib->entries ); - list_init( &typelib->importlibs ); - - if (is_attr(attrs, ATTR_POINTERDEFAULT)) - pointer_default = get_attrv(attrs, ATTR_POINTERDEFAULT); -} - -void end_typelib(void) -{ - in_typelib--; - if (!typelib) return; - - create_msft_typelib(typelib); - pointer_default = RPC_FC_UP; - return; -} - -void add_typelib_entry(type_t *t) -{ - typelib_entry_t *entry; - if (!typelib) return; - - chat("add kind %i: %s\n", t->kind, t->name); - entry = xmalloc(sizeof(*entry)); - entry->type = t; - list_add_tail( &typelib->entries, &entry->entry ); -} - -static void tlb_read(int fd, void *buf, int count) -{ - if(read(fd, buf, count) < count) - error("error while reading importlib.\n"); -} - -static void tlb_lseek(int fd, off_t offset) -{ - if(lseek(fd, offset, SEEK_SET) == -1) - error("lseek failed\n"); -} - -static void msft_read_guid(int fd, MSFT_SegDir *segdir, int offset, GUID *guid) -{ - tlb_lseek(fd, segdir->pGuidTab.offset+offset); - tlb_read(fd, guid, sizeof(GUID)); -} - -static void read_msft_importlib(importlib_t *importlib, int fd) -{ - MSFT_Header header; - MSFT_SegDir segdir; - int *typeinfo_offs; - int i; - - importlib->allocated = 0; - - tlb_lseek(fd, 0); - tlb_read(fd, &header, sizeof(header)); - - importlib->version = header.version; - - typeinfo_offs = xmalloc(header.nrtypeinfos*sizeof(INT)); - tlb_read(fd, typeinfo_offs, header.nrtypeinfos*sizeof(INT)); - tlb_read(fd, &segdir, sizeof(segdir)); - - msft_read_guid(fd, &segdir, header.posguid, &importlib->guid); - - importlib->ntypeinfos = header.nrtypeinfos; - importlib->importinfos = xmalloc(importlib->ntypeinfos*sizeof(importinfo_t)); - - for(i=0; i < importlib->ntypeinfos; i++) { - MSFT_TypeInfoBase base; - MSFT_NameIntro nameintro; - int len; - - tlb_lseek(fd, sizeof(MSFT_Header) + header.nrtypeinfos*sizeof(INT) + sizeof(MSFT_SegDir) - + typeinfo_offs[i]); - tlb_read(fd, &base, sizeof(base)); - - importlib->importinfos[i].importlib = importlib; - importlib->importinfos[i].flags = (base.typekind&0xf)<<24; - importlib->importinfos[i].offset = -1; - importlib->importinfos[i].id = i; - - if(base.posguid != -1) { - importlib->importinfos[i].flags |= MSFT_IMPINFO_OFFSET_IS_GUID; - msft_read_guid(fd, &segdir, base.posguid, &importlib->importinfos[i].guid); - } - else memset( &importlib->importinfos[i].guid, 0, sizeof(importlib->importinfos[i].guid)); - - tlb_lseek(fd, segdir.pNametab.offset + base.NameOffset); - tlb_read(fd, &nameintro, sizeof(nameintro)); - - len = nameintro.namelen & 0xff; - - importlib->importinfos[i].name = xmalloc(len+1); - tlb_read(fd, importlib->importinfos[i].name, len); - importlib->importinfos[i].name[len] = 0; - } - - free(typeinfo_offs); -} - -static void read_importlib(importlib_t *importlib) -{ - int fd; - INT magic; - char *file_name; - - file_name = wpp_find_include(importlib->name, NULL); - if(file_name) { - fd = open(file_name, O_RDONLY); - free(file_name); - }else { - fd = open(importlib->name, O_RDONLY); - } - - if(fd < 0) - error("Could not open importlib %s.\n", importlib->name); - - tlb_read(fd, &magic, sizeof(magic)); - - switch(magic) { - case MSFT_MAGIC: - read_msft_importlib(importlib, fd); - break; - default: - error("Wrong or unsupported typelib magic %x\n", magic); - }; - - close(fd); -} - -void add_importlib(const char *name) -{ - importlib_t *importlib; - - if(!typelib) return; - - LIST_FOR_EACH_ENTRY( importlib, &typelib->importlibs, importlib_t, entry ) - if(!strcmp(name, importlib->name)) - return; - - chat("add_importlib: %s\n", name); - - importlib = xmalloc(sizeof(*importlib)); - memset( importlib, 0, sizeof(*importlib) ); - importlib->name = xstrdup(name); - - read_importlib(importlib); - list_add_head( &typelib->importlibs, &importlib->entry ); -} diff --git a/reactos/tools/widl_20080105/typelib.h b/reactos/tools/widl_20080105/typelib.h deleted file mode 100644 index b17387dfc39..00000000000 --- a/reactos/tools/widl_20080105/typelib.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * IDL Compiler - * - * Copyright 2004 Ove Kaaven - * - * 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 - */ - -#ifndef __WIDL_TYPELIB_H -#define __WIDL_TYPELIB_H - -extern int in_typelib; -extern void start_typelib(char *name, attr_list_t *attrs); -extern void end_typelib(void); -extern void add_typelib_entry(type_t *t); -extern void add_importlib(const char *name); - -/* Copied from wtypes.h. Not included directly because that would create a - * circular dependency (after all, wtypes.h is generated by widl...) */ - -enum VARENUM { - VT_EMPTY = 0, - VT_NULL = 1, - VT_I2 = 2, - VT_I4 = 3, - VT_R4 = 4, - VT_R8 = 5, - VT_CY = 6, - VT_DATE = 7, - VT_BSTR = 8, - VT_DISPATCH = 9, - VT_ERROR = 10, - VT_BOOL = 11, - VT_VARIANT = 12, - VT_UNKNOWN = 13, - VT_DECIMAL = 14, - VT_I1 = 16, - VT_UI1 = 17, - VT_UI2 = 18, - VT_UI4 = 19, - VT_I8 = 20, - VT_UI8 = 21, - VT_INT = 22, - VT_UINT = 23, - VT_VOID = 24, - VT_HRESULT = 25, - VT_PTR = 26, - VT_SAFEARRAY = 27, - VT_CARRAY = 28, - VT_USERDEFINED = 29, - VT_LPSTR = 30, - VT_LPWSTR = 31, - VT_RECORD = 36, - VT_FILETIME = 64, - VT_BLOB = 65, - VT_STREAM = 66, - VT_STORAGE = 67, - VT_STREAMED_OBJECT = 68, - VT_STORED_OBJECT = 69, - VT_BLOB_OBJECT = 70, - VT_CF = 71, - VT_CLSID = 72, - VT_BSTR_BLOB = 0xfff, - VT_VECTOR = 0x1000, - VT_ARRAY = 0x2000, - VT_BYREF = 0x4000, - VT_RESERVED = 0x8000, - VT_ILLEGAL = 0xffff, - VT_ILLEGALMASKED = 0xfff, - VT_TYPEMASK = 0xfff -}; -extern unsigned short get_type_vt(type_t *t); - -extern int create_msft_typelib(typelib_t *typelib); -#endif diff --git a/reactos/tools/widl_20080105/typelib_struct.h b/reactos/tools/widl_20080105/typelib_struct.h deleted file mode 100644 index e16387c8dcd..00000000000 --- a/reactos/tools/widl_20080105/typelib_struct.h +++ /dev/null @@ -1,605 +0,0 @@ -/* - * typelib_struct.h internal wine data structures - * used to decode typelib's - * - * Copyright 1999 Rein KLazes - * - * 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 - */ -#ifndef _WIDL_TYPELIB_STRUCT_H -#define _WIDL_TYPELIB_STRUCT_H - -#define HELPDLLFLAG (0x0100) -#define DO_NOT_SEEK (-1) - -#define MSFT_HREFTYPE_INTHISFILE(href) (!((href) & 3)) -#define MSFT_HREFTYPE_INDEX(href) ((href) /sizeof(MSFT_TypeInfoBase)) - -/*-------------------------FILE STRUCTURES-----------------------------------*/ - -/* There are two known file formats, those created with ICreateTypeLib - * have the signature "SLTG" as their first four bytes, while those created - * with ICreateTypeLib2 have "MSFT". - */ - -#define MSFT_MAGIC 0x5446534d - -/***************************************************** - * MSFT typelibs - * - * These are TypeLibs created with ICreateTypeLib2 - * - */ - -/* - * structure of the typelib type2 header - * it is at the beginning of a type lib file - * - */ -typedef struct tagMSFT_Header { -/*0x00*/INT magic1; /* 0x5446534D "MSFT" */ - INT magic2; /* 0x00010002 version nr? */ - INT posguid; /* position of libid in guid table */ - /* (should be, else -1) */ - INT lcid; /* locale id */ -/*0x10*/INT lcid2; - INT varflags; /* (largely) unknown flags */ - /* the lower nibble is syskind */ - /* 0x40 always seems to be set */ - /* 0x10 set with a helpfile defined */ - /* 0x100 set with a helpstringdll defined - in this - case the offset to the name in the stringtable - appears right after this struct, before the - typeinfo offsets */ - INT version; /* set with SetVersion() */ - INT flags; /* set with SetFlags() */ -/*0x20*/INT nrtypeinfos; /* number of typeinfo's (till so far) */ - INT helpstring; /* position of help string in stringtable */ - INT helpstringcontext; - INT helpcontext; -/*0x30*/INT nametablecount; /* number of names in name table */ - INT nametablechars; /* nr of characters in name table */ - INT NameOffset; /* offset of name in name table */ - INT helpfile; /* position of helpfile in stringtable */ -/*0x40*/INT CustomDataOffset; /* if -1 no custom data, else it is offset */ - /* in customer data/guid offset table */ - INT res44; /* unknown always: 0x20 (guid hash size?) */ - INT res48; /* unknown always: 0x80 (name hash size?) */ - INT dispatchpos; /* HREFTYPE to IDispatch, or -1 if no IDispatch */ -/*0x50*/INT nimpinfos; /* number of impinfos */ -} MSFT_Header; - -/* segments in the type lib file have a structure like this: */ -typedef struct tagMSFT_pSeg { - INT offset; /* absolute offset in file */ - INT length; /* length of segment */ - INT res08; /* unknown always -1 */ - INT res0c; /* unknown always 0x0f in the header */ - /* 0x03 in the typeinfo_data */ -} MSFT_pSeg; - -/* layout of the main segment directory */ -typedef struct tagMSFT_SegDir { -/*1*/MSFT_pSeg pTypeInfoTab; /* each type info get an entry of 0x64 bytes */ - /* (25 ints) */ -/*2*/MSFT_pSeg pImpInfo; /* table with info for imported types */ -/*3*/MSFT_pSeg pImpFiles; /* import libaries */ -/*4*/MSFT_pSeg pRefTab; /* References table */ -/*5*/MSFT_pSeg pLibtab; /* always exists, alway same size (0x80) */ - /* hash table w offsets to guid????? */ -/*6*/MSFT_pSeg pGuidTab; /* all guids are stored here together with */ - /* offset in some table???? */ -/*7*/MSFT_pSeg res07; /* always created, alway same size (0x200) */ - /* purpose largely unknown */ -/*8*/MSFT_pSeg pNametab; /* name tables */ -/*9*/MSFT_pSeg pStringtab; /* string table */ -/*A*/MSFT_pSeg pTypdescTab; /* table with type descriptors */ -/*B*/MSFT_pSeg pArrayDescriptions; -/*C*/MSFT_pSeg pCustData; /* data table, used for custom data and default */ - /* parameter values */ -/*D*/MSFT_pSeg pCDGuids; /* table with offsets for the guids and into */ - /* the customer data table */ -/*E*/MSFT_pSeg res0e; /* unknown */ -/*F*/MSFT_pSeg res0f; /* unknown */ -} MSFT_SegDir; - - -/* base type info data */ -typedef struct tagMSFT_TypeInfoBase { -/*000*/ INT typekind; /* it is the TKIND_xxx */ - /* some byte alignment stuf */ - INT memoffset; /* points past the file, if no elements */ - INT res2; /* zero if no element, N*0x40 */ - INT res3; /* -1 if no lement, (N-1)*0x38 */ -/*010*/ INT res4; /* always? 3 */ - INT res5; /* always? zero */ - INT cElement; /* counts elements, HI=cVars, LO=cFuncs */ - INT res7; /* always? zero */ -/*020*/ INT res8; /* always? zero */ - INT res9; /* always? zero */ - INT resA; /* always? zero */ - INT posguid; /* position in guid table */ -/*030*/ INT flags; /* Typeflags */ - INT NameOffset; /* offset in name table */ - INT version; /* element version */ - INT docstringoffs; /* offset of docstring in string tab */ -/*040*/ INT helpstringcontext; /* */ - INT helpcontext; /* */ - INT oCustData; /* offset in customer data table */ -#ifdef WORDS_BIGENDIAN - INT16 cbSizeVft; /* virtual table size, including inherits */ - INT16 cImplTypes; /* nr of implemented interfaces */ -#else - INT16 cImplTypes; /* nr of implemented interfaces */ - INT16 cbSizeVft; /* virtual table size, including inherits */ -#endif -/*050*/ INT size; /* size in bytes, at least for structures */ - /* FIXME: name of this field */ - INT datatype1; /* position in type description table */ - /* or in base interfaces */ - /* if coclass: offset in reftable */ - /* if interface: reference to inherited if */ - INT datatype2; /* for interfaces: hiword is num of inherited funcs */ - /* loword is num of inherited interfaces */ - INT res18; /* always? 0 */ -/*060*/ INT res19; /* always? -1 */ -} MSFT_TypeInfoBase; - -/* layout of an entry with information on imported types */ -typedef struct tagMSFT_ImpInfo { - INT flags; /* bits 0 - 15: count */ - /* bit 16: if set oGuid is an offset to Guid */ - /* if clear oGuid is a typeinfo index in the specified typelib */ - /* bits 24 - 31: TKIND of reference */ - INT oImpFile; /* offset in the Import File table */ - INT oGuid; /* offset in Guid table or typeinfo index (see bit 16 of flags) */ -} MSFT_ImpInfo; - -#define MSFT_IMPINFO_OFFSET_IS_GUID 0x00010000 - -/* function description data */ -typedef struct { -/* INT recsize; record size including some xtra stuff */ - INT DataType; /* data type of the member, eg return of function */ - INT Flags; /* something to do with attribute flags (LOWORD) */ -#ifdef WORDS_BIGENDIAN - INT16 funcdescsize; /* size of reconstituted FUNCDESC and related structs */ - INT16 VtableOffset; /* offset in vtable */ -#else - INT16 VtableOffset; /* offset in vtable */ - INT16 funcdescsize; /* size of reconstituted FUNCDESC and related structs */ -#endif - INT FKCCIC; /* bit string with the following */ - /* meaning (bit 0 is the lsb): */ - /* bits 0 - 2: FUNCKIND */ - /* bits 3 - 6: INVOKEKIND */ - /* bit 7: custom data present */ - /* bits 8 - 11: CALLCONV */ - /* bit 12: parameters have default values */ - /* bit 13: oEntry is numeric */ - /* bit 14: has retval param */ - /* bits 16 - 31: index of next function with same id */ -#ifdef WORDS_BIGENDIAN - INT16 nroargs; /* nr of optional arguments */ - INT16 nrargs; /* number of arguments (including optional ????) */ -#else - INT16 nrargs; /* number of arguments (including optional ????) */ - INT16 nroargs; /* nr of optional arguments */ -#endif - /* optional attribute fields, the number of them is variable */ - INT OptAttr[1]; -/* -0* INT helpcontext; -1* INT oHelpString; -2* INT oEntry; // either offset in string table or numeric as it is (see bit 13 of FKCCIC) // -3* INT res9; // unknown (-1) // -4* INT resA; // unknown (-1) // -5* INT HelpStringContext; - // these are controlled by a bit set in the FKCCIC field // -6* INT oCustData; // custom data for function // -7* INT oArgCustData[1]; // custom data per argument // -*/ -} MSFT_FuncRecord; - -/* after this may follow an array with default value pointers if the - * appropriate bit in the FKCCIC field has been set: - * INT oDefautlValue[nrargs]; - */ - - /* Parameter info one per argument*/ -typedef struct { - INT DataType; - INT oName; - INT Flags; - } MSFT_ParameterInfo; - -/* Variable description data */ -typedef struct { -/* INT recsize; // record size including some xtra stuff */ - INT DataType; /* data type of the variable */ - INT Flags; /* VarFlags (LOWORD) */ -#ifdef WORDS_BIGENDIAN - INT16 vardescsize; /* size of reconstituted VARDESC and related structs */ - INT16 VarKind; /* VarKind */ -#else - INT16 VarKind; /* VarKind */ - INT16 vardescsize; /* size of reconstituted VARDESC and related structs */ -#endif - INT OffsValue; /* value of the variable or the offset */ - /* in the data structure */ - /* optional attribute fields, the number of them is variable */ - /* controlled by record length */ - INT HelpContext; - INT oHelpString; - INT res9; /* unknown (-1) */ - INT oCustData; /* custom data for variable */ - INT HelpStringContext; - -} MSFT_VarRecord; - -/* Structure of the reference data */ -typedef struct { - INT reftype; /* either offset in type info table, then it's */ - /* a multiple of 64 */ - /* or offset in the external reference table */ - /* with an offset of 1 */ - INT flags; - INT oCustData; /* custom data */ - INT onext; /* next offset, -1 if last */ -} MSFT_RefRecord; - -/* this is how a guid is stored */ -typedef struct { - GUID guid; - INT hreftype; /* -2 for the typelib guid, typeinfo offset - for typeinfo guid, low two bits are 01 if - this is an imported typeinfo, low two bits - are 10 if this is an imported typelib (used - by imported typeinfos) */ - INT next_hash; /* offset to next guid in the hash bucket */ -} MSFT_GuidEntry; -/* some data preceding entries in the name table */ -typedef struct { - INT hreftype; /* is -1 if name is for neither a typeinfo, - a variable, or a function (that is, name - is for a typelib or a function parameter). - otherwise is the offset of the first - typeinfo that this name refers to (either - to the typeinfo itself or to a member of - the typeinfo */ - INT next_hash; /* offset to next name in the hash bucket */ - INT namelen; /* only lower 8 bits are valid */ - /* 0x1000 if name is only used once as a variable name */ - /* 0x2000 if name is a variable in an enumeration */ - /* 0x3800 if name is typeinfo name */ - /* upper 16 bits are hash code */ -} MSFT_NameIntro; -/* the custom data table directory has entries like this */ -typedef struct { - INT GuidOffset; - INT DataOffset; - INT next; /* next offset in the table, -1 if it's the last */ -} MSFT_CDGuid; - - -/*********************************************************** - * - * SLTG typelibs. - * - * These are created with ICreateTypeLib - * - */ - -#include "pshpack1.h" - -typedef struct { -/*00*/ DWORD SLTG_magic; /* 0x47544c53 == "SLTG" */ -/*04*/ WORD nrOfFileBlks; /* no of SLTG_BlkEntry's + 1 */ -/*06*/ WORD res06; /* ?? always 9 */ -/*08*/ WORD res08; /* some kind of len/offset ?? */ -/*0a*/ WORD first_blk; /* 1 based index into blk entries that - corresponds to first block in file */ -/*0c*/ DWORD res0c; /* always 0x000204ff */ -/*10*/ DWORD res10; /* always 0x00000000 */ -/*14*/ DWORD res14; /* always 0x000000c0 */ -/*18*/ DWORD res18; /* always 0x46000000 */ -/*1c*/ DWORD res1c; /* always 0x00000044 */ -/*20*/ DWORD res20; /* always 0xffff0000 */ -} SLTG_Header; - -/* This gets followed by a list of block entries */ -typedef struct { -/*00*/ DWORD len; -/*04*/ WORD index_string; /* offs from start of SLTG_Magic to index string */ -/*06*/ WORD next; -} SLTG_BlkEntry; - -/* The order of the blocks in the file is given by starting at Block - entry firt_blk and stepping through using the next pointer */ - -/* These then get followed by this magic */ -typedef struct { -/*00*/ BYTE res00; /* always 0x01 */ -/*01*/ CHAR CompObj_magic[8]; /* always "CompObj" */ -/*09*/ CHAR dir_magic[4]; /* always "dir" */ -} SLTG_Magic; - -#define SLTG_COMPOBJ_MAGIC "CompObj" -#define SLTG_DIR_MAGIC "dir" - -/* Next we have SLTG_Header.nrOfFileBlks - 2 of Index strings. These -are presumably unique to within the file and look something like -"AAAAAAAAAA" with the first character incremented from 'A' to ensure -uniqueness. I guess successive chars increment when we need to wrap -the first one. */ - -typedef struct { -/*00*/ CHAR string[11]; -} SLTG_Index; - - -/* This is followed by SLTG_pad9 */ -typedef struct { -/*00*/ CHAR pad[9]; /* 9 '\0's */ -} SLTG_Pad9; - - -/* Now we have the noOfFileBlks - 1 worth of blocks. The length of -each block is given by its entry in SLTG_BlkEntry. */ - -/* type SLTG_NAME in rather like a BSTR except that the length in -bytes is given by the first WORD and the string contains 8bit chars */ - -typedef WORD SLTG_Name; - -/* The main library block looks like this. This one seems to come last */ - -typedef struct { -/*00*/ WORD magic; /* 0x51cc */ -/*02*/ WORD res02; /* 0x0003, 0x0004 */ -/*04*/ WORD name; /* offset to name in name table */ -/*06*/ SLTG_Name res06; /* maybe this is just WORD == 0xffff */ - SLTG_Name helpstring; - SLTG_Name helpfile; - DWORD helpcontext; - WORD syskind; /* == 1 for win32, 0 for win16 */ - WORD lcid; /* == 0x409, 0x809 etc */ - DWORD res12; /* == 0 */ - WORD libflags; /* LIBFLAG_* */ - WORD maj_vers; - WORD min_vers; - GUID uuid; -} SLTG_LibBlk; - -#define SLTG_LIBBLK_MAGIC 0x51cc - -/* we then get 0x40 bytes worth of 0xffff or small numbers followed by - nrOfFileBlks - 2 of these */ -typedef struct { - WORD small_no; - SLTG_Name index_name; /* This refers to a name in the directory */ - SLTG_Name other_name; /* Another one of these weird names */ - WORD res1a; /* 0xffff */ - WORD name_offs; /* offset to name in name table */ - WORD more_bytes; /* if this is non-zero we get this many - bytes before the next element, which seem - to reference the docstring of the type ? */ - WORD res20; /* 0xffff */ - DWORD helpcontext; - WORD res26; /* 0xffff */ - GUID uuid; -} SLTG_OtherTypeInfo; - -/* Next we get WORD 0x0003 followed by a DWORD which if we add to -0x216 gives the offset to the name table from the start of the LibBlk -struct */ - -typedef struct { -/*00*/ WORD magic; /* 0x0501 */ -/*02*/ DWORD href_table; /* if not 0xffffffff, then byte offset from - beginning of struct to href table */ -/*06*/ DWORD res06; /* 0xffffffff */ -/*0a*/ DWORD elem_table; /* offset to members */ -/*0e*/ DWORD res0e; /* 0xffffffff */ -/*12*/ WORD major_version; /* major version number */ -/*14*/ WORD minor_version; /* minor version number */ -/*16*/ DWORD res16; /* 0xfffe0000 */ -/*1a*/ BYTE typeflags1;/* 0x02 | top 5 bits hold l5sbs of TYPEFLAGS */ -/*1b*/ BYTE typeflags2;/* TYPEFLAGS >> 5 */ -/*1c*/ BYTE typeflags3;/* 0x02*/ -/*1d*/ BYTE typekind; /* 0x03 == TKIND_INTERFACE etc. */ -/*1e*/ DWORD res1e; /* 0x00000000 or 0xffffffff */ -} SLTG_TypeInfoHeader; - -#define SLTG_TIHEADER_MAGIC 0x0501 - -typedef struct { -/*00*/ WORD cFuncs; -/*02*/ WORD cVars; -/*04*/ WORD cImplTypes; -/*06*/ WORD res06; -/*08*/ WORD res08; -/*0a*/ WORD res0a; -/*0c*/ WORD res0c; -/*0e*/ WORD res0e; -/*10*/ WORD res10; -/*12*/ WORD res12; -/*14*/ WORD tdescalias_vt; /* for TKIND_ALIAS */ -/*16*/ WORD res16; -/*18*/ WORD res18; -/*1a*/ WORD res1a; -/*1c*/ WORD res1c; -/*1e*/ WORD res1e; -/*20*/ WORD cbSizeInstance; -/*22*/ WORD cbAlignment; -/*24*/ WORD res24; -/*26*/ WORD res26; -/*28*/ WORD cbSizeVft; -/*2a*/ WORD res2a; -/*2c*/ WORD res2c; -/*2e*/ WORD res2e; -/*30*/ WORD res30; -/*32*/ WORD res32; -/*34*/ WORD res34; -} SLTG_TypeInfoTail; - -typedef struct { -/*00*/ WORD res00; /* 0x0001 sometimes 0x0003 ?? */ -/*02*/ WORD res02; /* 0xffff */ -/*04*/ BYTE res04; /* 0x01 */ -/*05*/ DWORD cbExtra; /* No of bytes that follow */ -} SLTG_MemberHeader; - -typedef struct { -/*00*/ WORD magic; /* 0x120a */ -/*02*/ WORD next; /* offset in bytes to next block from start of block - group, 0xffff if last item */ -/*04*/ WORD name; /* offset to name within name table */ -/*06*/ WORD value; /* offset to value from start of block group */ -/*08*/ WORD res08; /* 0x56 */ -/*0a*/ DWORD memid; /* memid */ -/*0e*/ WORD helpcontext;/* 0xfffe == no context, 0x0001 == stored in EnumInfo struct, else offset - to value from start of block group */ -/*10*/ WORD helpstring;/* offset from start of block group to string offset */ -} SLTG_EnumItem; - -#define SLTG_ENUMITEM_MAGIC 0x120a - -typedef struct { -/*00*/ WORD vt; /* vartype, 0xffff marks end. */ -/*02*/ WORD res02; /* ?, 0xffff marks end */ -} SLTG_AliasItem; - -#define SLTG_ALIASITEM_MAGIC 0x001d - - -typedef struct { - BYTE magic; /* 0x4c or 0x6c */ - BYTE inv; /* high nibble is INVOKE_KIND, low nibble = 2 */ - WORD next; /* byte offset from beginning of group to next fn */ - WORD name; /* Offset within name table to name */ - DWORD dispid; /* dispid */ - WORD helpcontext; /* helpcontext (again 1 is special) */ - WORD helpstring;/* helpstring offset to offset */ - WORD arg_off; /* offset to args from start of block */ - BYTE nacc; /* lowest 3bits are CALLCONV, rest are no of args */ - BYTE retnextopt;/* if 0x80 bit set ret type follows else next WORD - is offset to ret type. No of optional args is - middle 6 bits */ - WORD rettype; /* return type VT_?? or offset to ret type */ - WORD vtblpos; /* position in vtbl? */ - WORD funcflags; /* present if magic == 0x6c */ -/* Param list starts, repeat next two as required */ -#if 0 - WORD name; /* offset to 2nd letter of name */ - WORD+ type; /* VT_ of param */ -#endif -} SLTG_Function; - -#define SLTG_FUNCTION_MAGIC 0x4c -#define SLTG_FUNCTION_WITH_FLAGS_MAGIC 0x6c - -typedef struct { -/*00*/ BYTE magic; /* 0xdf */ -/*01*/ BYTE res01; /* 0x00 */ -/*02*/ DWORD res02; /* 0xffffffff */ -/*06*/ DWORD res06; /* 0xffffffff */ -/*0a*/ DWORD res0a; /* 0xffffffff */ -/*0e*/ DWORD res0e; /* 0xffffffff */ -/*12*/ DWORD res12; /* 0xffffffff */ -/*16*/ DWORD res16; /* 0xffffffff */ -/*1a*/ DWORD res1a; /* 0xffffffff */ -/*1e*/ DWORD res1e; /* 0xffffffff */ -/*22*/ DWORD res22; /* 0xffffffff */ -/*26*/ DWORD res26; /* 0xffffffff */ -/*2a*/ DWORD res2a; /* 0xffffffff */ -/*2e*/ DWORD res2e; /* 0xffffffff */ -/*32*/ DWORD res32; /* 0xffffffff */ -/*36*/ DWORD res36; /* 0xffffffff */ -/*3a*/ DWORD res3a; /* 0xffffffff */ -/*3e*/ DWORD res3e; /* 0xffffffff */ -/*42*/ WORD res42; /* 0xffff */ -/*44*/ DWORD number; /* this is 8 times the number of refs */ -/*48*/ /* Now we have number bytes (8 for each ref) of SLTG_UnknownRefInfo */ - -/*50*/ WORD res50; /* 0xffff */ -/*52*/ BYTE res52; /* 0x01 */ -/*53*/ DWORD res53; /* 0x00000000 */ -/*57*/ SLTG_Name names[1]; - /* Now we have number/8 SLTG_Names (first WORD is no of bytes in the ascii - * string). Strings look like "*\Rxxxx*#n". If xxxx == ffff then the - * ref refers to the nth type listed in this library (0 based). Else - * the xxxx (which maybe fewer than 4 digits) is the offset into the name - * table to a string "*\G{}#1.0#0#C:\WINNT\System32\stdole32.tlb#" - * The guid is the typelib guid; the ref again refers to the nth type of - * the imported typelib. - */ - -/*xx*/ BYTE resxx; /* 0xdf */ - -} SLTG_RefInfo; - -#define SLTG_REF_MAGIC 0xdf - -typedef struct { - WORD res00; /* 0x0001 */ - BYTE res02; /* 0x02 */ - BYTE res03; /* 0x40 if internal ref, 0x00 if external ? */ - WORD res04; /* 0xffff */ - WORD res06; /* 0x0000, 0x0013 or 0xffff ?? */ -} SLTG_UnknownRefInfo; - -typedef struct { - WORD res00; /* 0x004a */ - WORD next; /* byte offs to next interface */ - WORD res04; /* 0xffff */ - BYTE impltypeflags; /* IMPLTYPEFLAG_* */ - BYTE res07; /* 0x80 */ - WORD res08; /* 0x0012, 0x0028 ?? */ - WORD ref; /* number in ref table ? */ - WORD res0c; /* 0x4000 */ - WORD res0e; /* 0xfffe */ - WORD res10; /* 0xffff */ - WORD res12; /* 0x001d */ - WORD pos_in_table; /* 0x0, 0x4, ? */ -} SLTG_ImplInfo; - -#define SLTG_IMPL_MAGIC 0x004a - -typedef struct { - BYTE magic; /* 0x0a */ - BYTE typepos; - WORD next; - WORD name; - WORD byte_offs; /* pos in struct */ - WORD type; /* if typepos == 0x02 this is the type, else offset to type */ - DWORD memid; - WORD helpcontext; /* ?? */ - WORD helpstring; /* ?? */ -} SLTG_RecordItem; - -#define SLTG_RECORD_MAGIC 0x0a - - -/* CARRAYs look like this -WORD type == VT_CARRAY -WORD offset from start of block to SAFEARRAY -WORD typeofarray -*/ - -#include "poppack.h" - -/*---------------------------END--------------------------------------------*/ -#endif diff --git a/reactos/tools/widl_20080105/utils.c b/reactos/tools/widl_20080105/utils.c deleted file mode 100644 index e77361ce339..00000000000 --- a/reactos/tools/widl_20080105/utils.c +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Utility routines - * - * Copyright 1998 Bertho A. Stultiens - * Copyright 2002 Ove Kaaven - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" -#include "wine/port.h" - -#include -#include -#include -#include -#include -#include - -#include "widl.h" -#include "utils.h" -#include "parser.h" - -static const int want_near_indication = 0; - -static void make_print(char *str) -{ - while(*str) - { - if(!isprint(*str)) - *str = ' '; - str++; - } -} - -static void generic_msg(const char *s, const char *t, const char *n, va_list ap) -{ - fprintf(stderr, "%s:%d: %s: ", input_name ? input_name : "stdin", line_number, t); - vfprintf(stderr, s, ap); - - if (want_near_indication) - { - char *cpy; - if(n) - { - cpy = xstrdup(n); - make_print(cpy); - fprintf(stderr, " near '%s'", cpy); - free(cpy); - } - } -} - - -/* yyerror: yacc assumes this is not newline terminated. */ -int parser_error(const char *s, ...) -{ - va_list ap; - va_start(ap, s); - generic_msg(s, "Error", parser_text, ap); - fprintf(stderr, "\n"); - va_end(ap); - exit(1); - return 1; -} - -void error_loc(const char *s, ...) -{ - va_list ap; - va_start(ap, s); - generic_msg(s, "Error", parser_text, ap); - va_end(ap); - exit(1); -} - -int parser_warning(const char *s, ...) -{ - va_list ap; - va_start(ap, s); - generic_msg(s, "Warning", parser_text, ap); - va_end(ap); - return 0; -} - -void error(const char *s, ...) -{ - va_list ap; - va_start(ap, s); - fprintf(stderr, "error: "); - vfprintf(stderr, s, ap); - va_end(ap); - exit(2); -} - -void warning(const char *s, ...) -{ - va_list ap; - va_start(ap, s); - fprintf(stderr, "warning: "); - vfprintf(stderr, s, ap); - va_end(ap); -} - -void chat(const char *s, ...) -{ - if(debuglevel & DEBUGLEVEL_CHAT) - { - va_list ap; - va_start(ap, s); - fprintf(stderr, "chat: "); - vfprintf(stderr, s, ap); - va_end(ap); - } -} - -char *dup_basename(const char *name, const char *ext) -{ - int namelen; - int extlen = strlen(ext); - char *base; - char *slash; - - if(!name) - name = "widl.tab"; - - slash = strrchr(name, '/'); - if (slash) - name = slash + 1; - - namelen = strlen(name); - - /* +4 for later extension and +1 for '\0' */ - base = xmalloc(namelen +4 +1); - strcpy(base, name); - if(!strcasecmp(name + namelen-extlen, ext)) - { - base[namelen - extlen] = '\0'; - } - return base; -} - -size_t widl_getline(char **linep, size_t *lenp, FILE *fp) -{ - char *line = *linep; - size_t len = *lenp; - size_t n = 0; - - if (!line) - { - len = 64; - line = xmalloc(len); - } - - while (fgets(&line[n], len - n, fp)) - { - n += strlen(&line[n]); - if (line[n - 1] == '\n') - break; - else if (n == len - 1) - { - len *= 2; - line = xrealloc(line, len); - } - } - - *linep = line; - *lenp = len; - return n; -} - -void *xmalloc(size_t size) -{ - void *res; - - assert(size > 0); - res = malloc(size); - if(res == NULL) - { - error("Virtual memory exhausted.\n"); - } - memset(res, 0x55, size); - return res; -} - - -void *xrealloc(void *p, size_t size) -{ - void *res; - - assert(size > 0); - res = realloc(p, size); - if(res == NULL) - { - error("Virtual memory exhausted.\n"); - } - return res; -} - -char *xstrdup(const char *str) -{ - char *s; - - assert(str != NULL); - s = xmalloc(strlen(str)+1); - return strcpy(s, str); -} diff --git a/reactos/tools/widl_20080105/utils.h b/reactos/tools/widl_20080105/utils.h deleted file mode 100644 index 7d6ce5c5f30..00000000000 --- a/reactos/tools/widl_20080105/utils.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Utility routines' prototypes etc. - * - * Copyright 1998 Bertho A. Stultiens (BS) - * - * 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 - */ - -#ifndef __WIDL_UTILS_H -#define __WIDL_UTILS_H - -#include "widltypes.h" - -#include /* size_t */ - -void *xmalloc(size_t); -void *xrealloc(void *, size_t); -char *xstrdup(const char *str); - -#ifndef __GNUC__ -#define __attribute__(X) -#endif - -int parser_error(const char *s, ...) __attribute__((format (printf, 1, 2))); -int parser_warning(const char *s, ...) __attribute__((format (printf, 1, 2))); -void error_loc(const char *s, ...) __attribute__((format (printf, 1, 2))); -void error(const char *s, ...) __attribute__((format (printf, 1, 2))); -void warning(const char *s, ...) __attribute__((format (printf, 1, 2))); -void chat(const char *s, ...) __attribute__((format (printf, 1, 2))); - -char *dup_basename(const char *name, const char *ext); -size_t widl_getline(char **linep, size_t *lenp, FILE *fp); - -UUID *parse_uuid(const char *u); -int is_valid_uuid(const char *s); - -/* typelibs expect the minor version to be stored in the higher bits and - * major to be stored in the lower bits */ -#define MAKEVERSION(major, minor) ((((minor) & 0xffff) << 16) | ((major) & 0xffff)) -#define MAJORVERSION(version) ((version) & 0xffff) -#define MINORVERSION(version) (((version) >> 16) & 0xffff) - -#endif diff --git a/reactos/tools/widl_20080105/widl.c b/reactos/tools/widl_20080105/widl.c deleted file mode 100644 index dc5ee2c6a35..00000000000 --- a/reactos/tools/widl_20080105/widl.c +++ /dev/null @@ -1,658 +0,0 @@ -/* - * IDL Compiler - * - * Copyright 2002 Ove Kaaven - * based on WRC code by Bertho Stultiens - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" -#include "wine/port.h" - -#include -#include -#include -#include -#ifdef HAVE_UNISTD_H -# include -#endif -#include -#include -#include -#include -#ifdef HAVE_GETOPT_H -# include -#endif - -#include "widl.h" -#include "utils.h" -#include "parser.h" -#include "wine/wpp.h" -#include "header.h" - -/* future options to reserve characters for: */ -/* a = alignment of structures */ -/* A = ACF input filename */ -/* J = do not search standard include path */ -/* O = generate interpreted stubs */ -/* w = select win16/win32 output (?) */ - -static const char usage[] = -"Usage: widl [options...] infile.idl\n" -" or: widl [options...] --dlldata-only name1 [name2...]\n" -" -c Generate client stub\n" -" -C file Name of client stub file (default is infile_c.c)\n" -" -d n Set debug level to 'n'\n" -" -D id[=val] Define preprocessor identifier id=val\n" -" --dlldata=file Name of the dlldata file (default is dlldata.c)\n" -" -E Preprocess only\n" -" -h Generate headers\n" -" -H file Name of header file (default is infile.h)\n" -" -I path Set include search dir to path (multiple -I allowed)\n" -" --local-stubs=file Write empty stubs for call_as/local methods to file\n" -" -N Do not preprocess input\n" -" --oldnames Use old naming conventions\n" -" -p Generate proxy\n" -" -P file Name of proxy file (default is infile_p.c)\n" -" --prefix-all=p Prefix names of client stubs / server functions with 'p'\n" -" --prefix-client=p Prefix names of client stubs with 'p'\n" -" --prefix-server=p Prefix names of server functions with 'p'\n" -" -s Generate server stub\n" -" -S file Name of server stub file (default is infile_s.c)\n" -" -t Generate typelib\n" -" -T file Name of typelib file (default is infile.tlb)\n" -" -u Generate interface identifiers file\n" -" -U file Name of interface identifiers file (default is infile_i.c)\n" -" -V Print version and exit\n" -" -W Enable pedantic warnings\n" -"Debug level 'n' is a bitmask with following meaning:\n" -" * 0x01 Tell which resource is parsed (verbose mode)\n" -" * 0x02 Dump internal structures\n" -" * 0x04 Create a parser trace (yydebug=1)\n" -" * 0x08 Preprocessor messages\n" -" * 0x10 Preprocessor lex messages\n" -" * 0x20 Preprocessor yacc trace\n" -; - -static const char version_string[] = "Wine IDL Compiler version " PACKAGE_VERSION "\n" - "Copyright 2002 Ove Kaaven\n"; - -int win32 = 1; -int debuglevel = DEBUGLEVEL_NONE; -int parser_debug, yy_flex_debug; - -int pedantic = 0; -int do_everything = 1; -int preprocess_only = 0; -int do_header = 0; -int do_typelib = 0; -int do_proxies = 0; -int do_client = 0; -int do_server = 0; -int do_idfile = 0; -int do_dlldata = 0; -int no_preprocess = 0; -int old_names = 0; - -char *input_name; -char *header_name; -char *local_stubs_name; -char *header_token; -char *typelib_name; -char *dlldata_name; -char *proxy_name; -char *proxy_token; -char *client_name; -char *client_token; -char *server_name; -char *server_token; -char *idfile_name; -char *idfile_token; -char *temp_name; -const char *prefix_client = ""; -const char *prefix_server = ""; - -int line_number = 1; - -FILE *header; -FILE *local_stubs; -FILE *proxy; -FILE *idfile; - -time_t now; - -enum { - OLDNAMES_OPTION = CHAR_MAX + 1, - DLLDATA_OPTION, - DLLDATA_ONLY_OPTION, - LOCAL_STUBS_OPTION, - PREFIX_ALL_OPTION, - PREFIX_CLIENT_OPTION, - PREFIX_SERVER_OPTION -}; - -static const char short_options[] = - "cC:d:D:EhH:I:NpP:sS:tT:uU:VW"; -static const struct option long_options[] = { - { "dlldata", required_argument, 0, DLLDATA_OPTION }, - { "dlldata-only", no_argument, 0, DLLDATA_ONLY_OPTION }, - { "local-stubs", required_argument, 0, LOCAL_STUBS_OPTION }, - { "oldnames", no_argument, 0, OLDNAMES_OPTION }, - { "prefix-all", required_argument, 0, PREFIX_ALL_OPTION }, - { "prefix-client", required_argument, 0, PREFIX_CLIENT_OPTION }, - { "prefix-server", required_argument, 0, PREFIX_SERVER_OPTION }, - { 0, 0, 0, 0 } -}; - -static void rm_tempfile(void); - -static char *make_token(const char *name) -{ - char *token; - char *slash; - int i; - - slash = strrchr(name, '/'); - if (slash) name = slash + 1; - - token = xstrdup(name); - for (i=0; token[i]; i++) { - if (!isalnum(token[i])) token[i] = '_'; - else token[i] = toupper(token[i]); - } - return token; -} - -/* duplicate a basename into a valid C token */ -static char *dup_basename_token(const char *name, const char *ext) -{ - char *p, *ret = dup_basename( name, ext ); - /* map invalid characters to '_' */ - for (p = ret; *p; p++) if (!isalnum(*p)) *p = '_'; - return ret; -} - -/* clean things up when aborting on a signal */ -static void exit_on_signal( int sig ) -{ - exit(1); /* this will call the atexit functions */ -} - -static void set_everything(int x) -{ - do_header = x; - do_typelib = x; - do_proxies = x; - do_client = x; - do_server = x; - do_idfile = x; - do_dlldata = x; -} - -static void start_cplusplus_guard(FILE *fp) -{ - fprintf(fp, "#ifdef __cplusplus\n"); - fprintf(fp, "extern \"C\" {\n"); - fprintf(fp, "#endif\n\n"); -} - -static void end_cplusplus_guard(FILE *fp) -{ - fprintf(fp, "#ifdef __cplusplus\n"); - fprintf(fp, "}\n"); - fprintf(fp, "#endif\n\n"); -} - -typedef struct -{ - char *filename; - struct list link; -} filename_node_t; - -static void add_filename_node(struct list *list, const char *name) -{ - filename_node_t *node = xmalloc(sizeof *node); - node->filename = dup_basename( name, ".idl" ); - list_add_tail(list, &node->link); -} - -static void free_filename_nodes(struct list *list) -{ - filename_node_t *node, *next; - LIST_FOR_EACH_ENTRY_SAFE(node, next, list, filename_node_t, link) { - list_remove(&node->link); - free(node->filename); - free(node); - } -} - -static void write_dlldata_list(struct list *filenames) -{ - FILE *dlldata; - filename_node_t *node; - - dlldata = fopen(dlldata_name, "w"); - if (!dlldata) - error("couldn't open %s: %s\n", dlldata_name, strerror(errno)); - - fprintf(dlldata, "/*** Autogenerated by WIDL %s ", PACKAGE_VERSION); - fprintf(dlldata, "- Do not edit ***/\n\n"); - fprintf(dlldata, "#include \n"); - fprintf(dlldata, "#include \n\n"); - start_cplusplus_guard(dlldata); - - LIST_FOR_EACH_ENTRY(node, filenames, filename_node_t, link) - fprintf(dlldata, "EXTERN_PROXY_FILE(%s)\n", node->filename); - - fprintf(dlldata, "\nPROXYFILE_LIST_START\n"); - fprintf(dlldata, "/* Start of list */\n"); - LIST_FOR_EACH_ENTRY(node, filenames, filename_node_t, link) - fprintf(dlldata, " REFERENCE_PROXY_FILE(%s),\n", node->filename); - fprintf(dlldata, "/* End of list */\n"); - fprintf(dlldata, "PROXYFILE_LIST_END\n\n"); - - fprintf(dlldata, "DLLDATA_ROUTINES(aProxyFileList, GET_DLL_CLSID)\n\n"); - end_cplusplus_guard(dlldata); - fclose(dlldata); -} - -static char *eat_space(char *s) -{ - while (isspace((unsigned char) *s)) - ++s; - return s; -} - -void write_dlldata(ifref_list_t *ifaces) -{ - struct list filenames = LIST_INIT(filenames); - filename_node_t *node; - FILE *dlldata; - - if (!do_dlldata || !need_proxy_file(ifaces)) - return; - - dlldata = fopen(dlldata_name, "r"); - if (dlldata) { - static char marker[] = "REFERENCE_PROXY_FILE"; - char *line = NULL; - size_t len = 0; - - while (widl_getline(&line, &len, dlldata)) { - char *start, *end; - start = eat_space(line); - if (strncmp(start, marker, sizeof marker - 1) == 0) { - start = eat_space(start + sizeof marker - 1); - if (*start != '(') - continue; - end = start = eat_space(start + 1); - while (*end && *end != ')') - ++end; - if (*end != ')') - continue; - while (isspace((unsigned char) end[-1])) - --end; - *end = '\0'; - if (start < end) - add_filename_node(&filenames, start); - } - } - - if (ferror(dlldata)) - error("couldn't read from %s: %s\n", dlldata_name, strerror(errno)); - - free(line); - fclose(dlldata); - } - - LIST_FOR_EACH_ENTRY(node, &filenames, filename_node_t, link) - if (strcmp(proxy_token, node->filename) == 0) { - /* We're already in the list, no need to regenerate this file. */ - free_filename_nodes(&filenames); - return; - } - - add_filename_node(&filenames, proxy_token); - write_dlldata_list(&filenames); - free_filename_nodes(&filenames); -} - -int main(int argc,char *argv[]) -{ - extern char* optarg; - extern int optind; - int optc; - int ret = 0; - int opti = 0; - - signal( SIGTERM, exit_on_signal ); - signal( SIGINT, exit_on_signal ); -#ifdef SIGHUP - signal( SIGHUP, exit_on_signal ); -#endif - - now = time(NULL); - - while((optc = getopt_long(argc, argv, short_options, long_options, &opti)) != EOF) { - switch(optc) { - case DLLDATA_OPTION: - dlldata_name = xstrdup(optarg); - break; - case DLLDATA_ONLY_OPTION: - do_everything = 0; - do_dlldata = 1; - break; - case LOCAL_STUBS_OPTION: - do_everything = 0; - local_stubs_name = xstrdup(optarg); - break; - case OLDNAMES_OPTION: - old_names = 1; - break; - case PREFIX_ALL_OPTION: - prefix_client = xstrdup(optarg); - prefix_server = xstrdup(optarg); - break; - case PREFIX_CLIENT_OPTION: - prefix_client = xstrdup(optarg); - break; - case PREFIX_SERVER_OPTION: - prefix_server = xstrdup(optarg); - break; - case 'c': - do_everything = 0; - do_client = 1; - break; - case 'C': - client_name = xstrdup(optarg); - break; - case 'd': - debuglevel = strtol(optarg, NULL, 0); - break; - case 'D': - wpp_add_cmdline_define(optarg); - break; - case 'E': - do_everything = 0; - preprocess_only = 1; - break; - case 'h': - do_everything = 0; - do_header = 1; - break; - case 'H': - header_name = xstrdup(optarg); - break; - case 'I': - wpp_add_include_path(optarg); - break; - case 'N': - no_preprocess = 1; - break; - case 'p': - do_everything = 0; - do_proxies = 1; - break; - case 'P': - proxy_name = xstrdup(optarg); - break; - case 's': - do_everything = 0; - do_server = 1; - break; - case 'S': - server_name = xstrdup(optarg); - break; - case 't': - do_everything = 0; - do_typelib = 1; - break; - case 'T': - typelib_name = xstrdup(optarg); - break; - case 'u': - do_everything = 0; - do_idfile = 1; - break; - case 'U': - idfile_name = xstrdup(optarg); - break; - case 'V': - printf("%s", version_string); - return 0; - case 'W': - pedantic = 1; - break; - default: - fprintf(stderr, "%s", usage); - return 1; - } - } - - if(do_everything) { - set_everything(TRUE); - } - - if (!dlldata_name && do_dlldata) - dlldata_name = xstrdup("dlldata.c"); - - if(optind < argc) { - if (do_dlldata && !do_everything) { - struct list filenames = LIST_INIT(filenames); - for ( ; optind < argc; ++optind) - add_filename_node(&filenames, argv[optind]); - - write_dlldata_list(&filenames); - free_filename_nodes(&filenames); - return 0; - } - else if (optind != argc - 1) { - fprintf(stderr, "%s", usage); - return 1; - } - else - input_name = xstrdup(argv[optind]); - } - else { - fprintf(stderr, "%s", usage); - return 1; - } - - if(debuglevel) - { - setbuf(stdout,0); - setbuf(stderr,0); - } - - parser_debug = debuglevel & DEBUGLEVEL_TRACE ? 1 : 0; - yy_flex_debug = debuglevel & DEBUGLEVEL_TRACE ? 1 : 0; - - wpp_set_debug( (debuglevel & DEBUGLEVEL_PPLEX) != 0, - (debuglevel & DEBUGLEVEL_PPTRACE) != 0, - (debuglevel & DEBUGLEVEL_PPMSG) != 0 ); - - if (!header_name) { - header_name = dup_basename(input_name, ".idl"); - strcat(header_name, ".h"); - } - - if (!typelib_name && do_typelib) { - typelib_name = dup_basename(input_name, ".idl"); - strcat(typelib_name, ".tlb"); - } - - if (!proxy_name && do_proxies) { - proxy_name = dup_basename(input_name, ".idl"); - strcat(proxy_name, "_p.c"); - } - - if (!client_name && do_client) { - client_name = dup_basename(input_name, ".idl"); - strcat(client_name, "_c.c"); - } - - if (!server_name && do_server) { - server_name = dup_basename(input_name, ".idl"); - strcat(server_name, "_s.c"); - } - - if (!idfile_name && do_idfile) { - idfile_name = dup_basename(input_name, ".idl"); - strcat(idfile_name, "_i.c"); - } - - if (do_proxies) proxy_token = dup_basename_token(proxy_name,"_p.c"); - if (do_client) client_token = dup_basename_token(client_name,"_c.c"); - if (do_server) server_token = dup_basename_token(server_name,"_s.c"); - - wpp_add_cmdline_define("__WIDL__"); - - atexit(rm_tempfile); - if (!no_preprocess) - { - chat("Starting preprocess\n"); - - if (!preprocess_only) - { - ret = wpp_parse_temp( input_name, header_name, &temp_name ); - } - else - { - ret = wpp_parse( input_name, stdout ); - } - - if(ret) exit(1); - if(preprocess_only) exit(0); - if(!(parser_in = fopen(temp_name, "r"))) { - fprintf(stderr, "Could not open %s for input\n", temp_name); - return 1; - } - } - else { - if(!(parser_in = fopen(input_name, "r"))) { - fprintf(stderr, "Could not open %s for input\n", input_name); - return 1; - } - } - - if(do_header) { - if (strrchr(header_name, '\\')) - header_token = make_token(strrchr(header_name, '\\') + 1); - else if (strrchr(header_name, '/')) - header_token = make_token(strrchr(header_name, '/') + 1); - else - header_token = make_token(header_name); - - if(!(header = fopen(header_name, "w"))) { - fprintf(stderr, "Could not open %s for output\n", header_name); - return 1; - } - fprintf(header, "/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n", PACKAGE_VERSION, input_name); - fprintf(header, "#include \n" ); - fprintf(header, "#include \n\n" ); - fprintf(header, "#ifndef __WIDL_%s\n", header_token); - fprintf(header, "#define __WIDL_%s\n", header_token); - start_cplusplus_guard(header); - } - - if (local_stubs_name) { - local_stubs = fopen(local_stubs_name, "w"); - if (!local_stubs) { - fprintf(stderr, "Could not open %s for output\n", local_stubs_name); - return 1; - } - fprintf(local_stubs, "/* call_as/local stubs for %s */\n\n", input_name); - fprintf(local_stubs, "#include \n"); - fprintf(local_stubs, "#include \"%s\"\n\n", header_name); - } - - if (do_idfile) { - idfile_token = make_token(idfile_name); - - idfile = fopen(idfile_name, "w"); - if (! idfile) { - fprintf(stderr, "Could not open %s for output\n", idfile_name); - return 1; - } - - fprintf(idfile, "/*** Autogenerated by WIDL %s ", PACKAGE_VERSION); - fprintf(idfile, "from %s - Do not edit ***/\n\n", input_name); - fprintf(idfile, "#include \n"); - fprintf(idfile, "#include \n\n"); - fprintf(idfile, "#include \n\n"); - start_cplusplus_guard(idfile); - } - - init_types(); - ret = parser_parse(); - - if(do_header) { - fprintf(header, "/* Begin additional prototypes for all interfaces */\n"); - fprintf(header, "\n"); - write_user_types(); - write_context_handle_rundowns(); - fprintf(header, "\n"); - fprintf(header, "/* End additional prototypes */\n"); - fprintf(header, "\n"); - end_cplusplus_guard(header); - fprintf(header, "#endif /* __WIDL_%s */\n", header_token); - fclose(header); - } - - if (local_stubs) { - fclose(local_stubs); - } - - if (do_idfile) { - fprintf(idfile, "\n"); - end_cplusplus_guard(idfile); - - fclose(idfile); - } - - fclose(parser_in); - - if(ret) { - exit(1); - } - - /* Everything has been done successfully, don't delete any files. */ - set_everything(FALSE); - local_stubs_name = NULL; - - return 0; -} - -static void rm_tempfile(void) -{ - abort_import(); - if(temp_name) - unlink(temp_name); - if (do_header) - unlink(header_name); - if (local_stubs_name) - unlink(local_stubs_name); - if (do_client) - unlink(client_name); - if (do_server) - unlink(server_name); - if (do_idfile) - unlink(idfile_name); - if (do_proxies) - unlink(proxy_name); - if (do_typelib) - unlink(typelib_name); -} diff --git a/reactos/tools/widl_20080105/widl.h b/reactos/tools/widl_20080105/widl.h deleted file mode 100644 index 924b67a3d88..00000000000 --- a/reactos/tools/widl_20080105/widl.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * IDL Compiler - * - * Copyright 2002 Ove Kaaven - * - * 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 - */ - -#ifndef __WIDL_WIDL_H -#define __WIDL_WIDL_H - -#include "widltypes.h" - -#include - -extern int debuglevel; -#define DEBUGLEVEL_NONE 0x0000 -#define DEBUGLEVEL_CHAT 0x0001 -#define DEBUGLEVEL_DUMP 0x0002 -#define DEBUGLEVEL_TRACE 0x0004 -#define DEBUGLEVEL_PPMSG 0x0008 -#define DEBUGLEVEL_PPLEX 0x0010 -#define DEBUGLEVEL_PPTRACE 0x0020 - -extern int win32; -extern int pedantic; -extern int do_everything; -extern int do_header; -extern int do_typelib; -extern int do_proxies; -extern int do_client; -extern int do_server; -extern int do_idfile; -extern int do_dlldata; -extern int old_names; - -extern char *input_name; -extern char *header_name; -extern char *local_stubs_name; -extern char *typelib_name; -extern char *dlldata_name; -extern char *proxy_name; -extern char *proxy_token; -extern char *client_name; -extern char *client_token; -extern char *server_name; -extern char *server_token; -extern const char *prefix_client; -extern const char *prefix_server; -extern time_t now; - -extern int line_number; -extern int char_number; - -extern FILE* header; -extern FILE* local_stubs; -extern FILE* idfile; - -extern void write_proxies(ifref_list_t *ifaces); -extern void write_client(ifref_list_t *ifaces); -extern void write_server(ifref_list_t *ifaces); -extern void write_dlldata(ifref_list_t *ifaces); - -#endif diff --git a/reactos/tools/widl_20080105/widl.mak b/reactos/tools/widl_20080105/widl.mak deleted file mode 100644 index de6813ac536..00000000000 --- a/reactos/tools/widl_20080105/widl.mak +++ /dev/null @@ -1,131 +0,0 @@ -WIDL_BASE = $(TOOLS_BASE)$(SEP)widl -WIDL_BASE_ = $(WIDL_BASE)$(SEP) -WIDL_INT = $(INTERMEDIATE_)$(WIDL_BASE) -WIDL_INT_ = $(WIDL_INT)$(SEP) -WIDL_OUT = $(OUTPUT_)$(WIDL_BASE) -WIDL_OUT_ = $(WIDL_OUT)$(SEP) - -$(WIDL_INT): | $(TOOLS_INT) - $(ECHO_MKDIR) - ${mkdir} $@ - -ifneq ($(INTERMEDIATE),$(OUTPUT)) -$(WIDL_OUT): | $(TOOLS_OUT) - $(ECHO_MKDIR) - ${mkdir} $@ -endif - -WIDL_PORT_BASE = $(WIDL_BASE)$(SEP)port -WIDL_PORT_BASE_ = $(WIDL_PORT_BASE)$(SEP) -WIDL_PORT_INT = $(INTERMEDIATE_)$(WIDL_PORT_BASE) -WIDL_PORT_INT_ = $(WIDL_PORT_INT)$(SEP) -WIDL_PORT_OUT = $(OUTPUT_)$(WIDL_PORT_BASE) -WIDL_PORT_OUT_ = $(WIDL_PORT_OUT)$(SEP) - -$(WIDL_PORT_INT): | $(WIDL_INT) - $(ECHO_MKDIR) - ${mkdir} $@ - -ifneq ($(INTERMEDIATE),$(OUTPUT)) -$(WIDL_PORT_OUT): | $(WIDL_OUT) - $(ECHO_MKDIR) - ${mkdir} $@ -endif - -WIDL_TARGET = \ - $(WIDL_OUT_)widl$(EXEPOSTFIX) - -WIDL_DEPENDS = $(BUILDNO_H) - -WIDL_SOURCES = $(addprefix $(WIDL_BASE_), \ - client.c \ - hash.c \ - header.c \ - proxy.c \ - server.c \ - typegen.c \ - typelib.c \ - utils.c \ - widl.c \ - write_msft.c \ - parser.yy.c \ - parser.tab.c \ - port$(SEP)mkstemps.c \ - ) - -WIDL_OBJECTS = \ - $(addprefix $(INTERMEDIATE_), $(WIDL_SOURCES:.c=.o)) - -WIDL_HOST_CFLAGS = $(TOOLS_CFLAGS) \ - -DINT16=SHORT -D__USE_W32API -DYYDEBUG=1 -D__REACTOS__=1 \ - -I$(WIDL_BASE) -I$(WPP_BASE) \ - -Iinclude/reactos/wine -Iinclude/reactos -Iinclude -Iinclude/psdk \ - -I$(INTERMEDIATE_)include - -WIDL_HOST_LFLAGS = $(TOOLS_LFLAGS) - -WIDL_LIBS = $(WPP_TARGET) - -.PHONY: widl -widl: $(WIDL_TARGET) - -$(WIDL_TARGET): $(WIDL_OBJECTS) $(WIDL_LIBS) | $(WIDL_OUT) - $(ECHO_LD) - ${host_gcc} $(WIDL_OBJECTS) $(WIDL_LIBS) $(WIDL_HOST_LFLAGS) -o $@ - -$(WIDL_INT_)client.o: $(WIDL_BASE_)client.c $(WIDL_DEPENDS) | $(WIDL_INT) - $(ECHO_CC) - ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ - -$(WIDL_INT_)hash.o: $(WIDL_BASE_)hash.c $(WIDL_DEPENDS) | $(WIDL_INT) - $(ECHO_CC) - ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ - -$(WIDL_INT_)header.o: $(WIDL_BASE_)header.c $(WIDL_DEPENDS) | $(WIDL_INT) - $(ECHO_CC) - ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ - -$(WIDL_INT_)proxy.o: $(WIDL_BASE_)proxy.c $(WIDL_DEPENDS) | $(WIDL_INT) - $(ECHO_CC) - ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ - -$(WIDL_INT_)server.o: $(WIDL_BASE_)server.c $(WIDL_DEPENDS) | $(WIDL_INT) - $(ECHO_CC) - ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ - -$(WIDL_INT_)typegen.o: $(WIDL_BASE_)typegen.c $(WIDL_DEPENDS) | $(WIDL_INT) - $(ECHO_CC) - ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ - -$(WIDL_INT_)typelib.o: $(WIDL_BASE_)typelib.c $(WIDL_DEPENDS) | $(WIDL_INT) - $(ECHO_CC) - ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ - -$(WIDL_INT_)utils.o: $(WIDL_BASE_)utils.c $(WIDL_DEPENDS) | $(WIDL_INT) - $(ECHO_CC) - ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ - -$(WIDL_INT_)widl.o: $(WIDL_BASE_)widl.c $(WIDL_DEPENDS) | $(WIDL_INT) - $(ECHO_CC) - ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ - -$(WIDL_INT_)write_msft.o: $(WIDL_BASE_)write_msft.c $(WIDL_DEPENDS) | $(WIDL_INT) - $(ECHO_CC) - ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ - -$(WIDL_INT_)parser.yy.o: $(WIDL_BASE_)parser.yy.c $(WIDL_DEPENDS) | $(WIDL_INT) - $(ECHO_CC) - ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ - -$(WIDL_INT_)parser.tab.o: $(WIDL_BASE_)parser.tab.c $(WIDL_DEPENDS) | $(WIDL_INT) - $(ECHO_CC) - ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ - -$(WIDL_PORT_INT_)mkstemps.o: $(WIDL_PORT_BASE_)mkstemps.c $(WIDL_DEPENDS) | $(WIDL_PORT_INT) - $(ECHO_CC) - ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ - -.PHONY: widl_clean -widl_clean: - -@$(rm) $(WIDL_TARGET) $(WIDL_OBJECTS) 2>$(NUL) -clean: widl_clean diff --git a/reactos/tools/widl_20080105/widltypes.h b/reactos/tools/widl_20080105/widltypes.h deleted file mode 100644 index 6930f711719..00000000000 --- a/reactos/tools/widl_20080105/widltypes.h +++ /dev/null @@ -1,330 +0,0 @@ -/* - * IDL Compiler - * - * Copyright 2002 Ove Kaaven - * - * 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 - */ - -#ifndef __WIDL_WIDLTYPES_H -#define __WIDL_WIDLTYPES_H - -#include -#include "guiddef.h" -#include "wine/rpcfc.h" -#include "wine/list.h" - -#ifndef UUID_DEFINED -#define UUID_DEFINED -typedef GUID UUID; -#endif - -#define TRUE 1 -#define FALSE 0 - -typedef struct _attr_t attr_t; -typedef struct _expr_t expr_t; -typedef struct _type_t type_t; -typedef struct _typeref_t typeref_t; -typedef struct _var_t var_t; -typedef struct _pident_t pident_t; -typedef struct _func_t func_t; -typedef struct _ifref_t ifref_t; -typedef struct _typelib_entry_t typelib_entry_t; -typedef struct _importlib_t importlib_t; -typedef struct _importinfo_t importinfo_t; -typedef struct _typelib_t typelib_t; -typedef struct _user_type_t user_type_t; -typedef struct _user_type_t context_handle_t; - -typedef struct list attr_list_t; -typedef struct list str_list_t; -typedef struct list func_list_t; -typedef struct list expr_list_t; -typedef struct list var_list_t; -typedef struct list pident_list_t; -typedef struct list ifref_list_t; -typedef struct list array_dims_t; -typedef struct list user_type_list_t; -typedef struct list context_handle_list_t; - -enum attr_type -{ - ATTR_AGGREGATABLE, - ATTR_APPOBJECT, - ATTR_ASYNC, - ATTR_AUTO_HANDLE, - ATTR_BINDABLE, - ATTR_CALLAS, - ATTR_CASE, - ATTR_CONTEXTHANDLE, - ATTR_CONTROL, - ATTR_DEFAULT, - ATTR_DEFAULTCOLLELEM, - ATTR_DEFAULTVALUE_EXPR, - ATTR_DEFAULTVALUE_STRING, - ATTR_DEFAULTVTABLE, - ATTR_DISPINTERFACE, - ATTR_DISPLAYBIND, - ATTR_DLLNAME, - ATTR_DUAL, - ATTR_ENDPOINT, - ATTR_ENTRY_ORDINAL, - ATTR_ENTRY_STRING, - ATTR_EXPLICIT_HANDLE, - ATTR_HANDLE, - ATTR_HELPCONTEXT, - ATTR_HELPFILE, - ATTR_HELPSTRING, - ATTR_HELPSTRINGCONTEXT, - ATTR_HELPSTRINGDLL, - ATTR_HIDDEN, - ATTR_ID, - ATTR_IDEMPOTENT, - ATTR_IIDIS, - ATTR_IMMEDIATEBIND, - ATTR_IMPLICIT_HANDLE, - ATTR_IN, - ATTR_INPUTSYNC, - ATTR_LENGTHIS, - ATTR_LOCAL, - ATTR_NONBROWSABLE, - ATTR_NONCREATABLE, - ATTR_NONEXTENSIBLE, - ATTR_OBJECT, - ATTR_ODL, - ATTR_OLEAUTOMATION, - ATTR_OPTIONAL, - ATTR_OUT, - ATTR_POINTERDEFAULT, - ATTR_POINTERTYPE, - ATTR_PROPGET, - ATTR_PROPPUT, - ATTR_PROPPUTREF, - ATTR_PUBLIC, - ATTR_RANGE, - ATTR_READONLY, - ATTR_REQUESTEDIT, - ATTR_RESTRICTED, - ATTR_RETVAL, - ATTR_SIZEIS, - ATTR_SOURCE, - ATTR_STRING, - ATTR_SWITCHIS, - ATTR_SWITCHTYPE, - ATTR_TRANSMITAS, - ATTR_UUID, - ATTR_V1ENUM, - ATTR_VARARG, - ATTR_VERSION, - ATTR_WIREMARSHAL -}; - -enum expr_type -{ - EXPR_VOID, - EXPR_NUM, - EXPR_HEXNUM, - EXPR_DOUBLE, - EXPR_IDENTIFIER, - EXPR_NEG, - EXPR_NOT, - EXPR_PPTR, - EXPR_CAST, - EXPR_SIZEOF, - EXPR_SHL, - EXPR_SHR, - EXPR_MUL, - EXPR_DIV, - EXPR_ADD, - EXPR_SUB, - EXPR_AND, - EXPR_OR, - EXPR_COND, - EXPR_TRUEFALSE, - EXPR_ADDRESSOF, -}; - -enum type_kind -{ - TKIND_PRIMITIVE = -1, - TKIND_ENUM, - TKIND_RECORD, - TKIND_MODULE, - TKIND_INTERFACE, - TKIND_DISPATCH, - TKIND_COCLASS, - TKIND_ALIAS, - TKIND_UNION, - TKIND_MAX -}; - -struct str_list_entry_t -{ - char *str; - struct list entry; -}; - -struct _attr_t { - enum attr_type type; - union { - unsigned long ival; - void *pval; - } u; - /* parser-internal */ - struct list entry; -}; - -struct _expr_t { - enum expr_type type; - const expr_t *ref; - union { - long lval; - double dval; - const char *sval; - const expr_t *ext; - type_t *tref; - } u; - const expr_t *ext2; - int is_const; - long cval; - /* parser-internal */ - struct list entry; -}; - -struct _type_t { - const char *name; - enum type_kind kind; - unsigned char type; - struct _type_t *ref; - const attr_list_t *attrs; - func_list_t *funcs; /* interfaces and modules */ - var_list_t *fields; /* interfaces, structures and enumerations */ - ifref_list_t *ifaces; /* coclasses */ - unsigned long dim; /* array dimension */ - expr_t *size_is, *length_is; - type_t *orig; /* dup'd types */ - unsigned int typestring_offset; - unsigned int ptrdesc; /* used for complex structs */ - int typelib_idx; - unsigned int declarray : 1; /* if declared as an array */ - unsigned int ignore : 1; - unsigned int is_const : 1; - unsigned int defined : 1; - unsigned int written : 1; - unsigned int user_types_registered : 1; - unsigned int tfswrite : 1; /* if the type needs to be written to the TFS */ - int sign : 2; -}; - -struct _var_t { - char *name; - type_t *type; - var_list_t *args; /* for function pointers */ - attr_list_t *attrs; - expr_t *eval; - - /* parser-internal */ - struct list entry; -}; - -struct _pident_t { - var_t *var; - int ptr_level; - - /* parser-internal */ - struct list entry; -}; - -struct _func_t { - var_t *def; - var_list_t *args; - int ignore, idx; - - /* parser-internal */ - struct list entry; -}; - -struct _ifref_t { - type_t *iface; - attr_list_t *attrs; - - /* parser-internal */ - struct list entry; -}; - -struct _typelib_entry_t { - type_t *type; - struct list entry; -}; - -struct _importinfo_t { - int offset; - GUID guid; - int flags; - int id; - - char *name; - - importlib_t *importlib; -}; - -struct _importlib_t { - char *name; - - int version; - GUID guid; - - importinfo_t *importinfos; - int ntypeinfos; - - int allocated; - - struct list entry; -}; - -struct _typelib_t { - char *name; - char *filename; - attr_list_t *attrs; - struct list entries; - struct list importlibs; -}; - -struct _user_type_t { - struct list entry; - const char *name; -}; - -extern unsigned char pointer_default; - -extern user_type_list_t user_type_list; -void check_for_user_types_and_context_handles(const var_list_t *list); - -void init_types(void); -type_t *alloc_type(void); -void set_all_tfswrite(int val); - -type_t *duptype(type_t *t, int dupname); -type_t *alias(type_t *t, const char *name); - -int is_ptr(const type_t *t); -int is_array(const type_t *t); -int is_var_ptr(const var_t *v); -int cant_be_null(const var_t *v); -int is_struct(unsigned char tc); -int is_union(unsigned char tc); - -#endif diff --git a/reactos/tools/widl_20080105/write_msft.c b/reactos/tools/widl_20080105/write_msft.c deleted file mode 100644 index f5ea2f7f27b..00000000000 --- a/reactos/tools/widl_20080105/write_msft.c +++ /dev/null @@ -1,2533 +0,0 @@ -/* - * Typelib v2 (MSFT) generation - * - * Copyright 2004 Alastair Bridgewater - * 2004, 2005 Huw Davies - * - * 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 - * - * -------------------------------------------------------------------------------------- - * Known problems: - * - * Badly incomplete. - * - * Only works on little-endian systems. - * - */ - -#include "config.h" -#include "wine/port.h" - -#include -#include -#include -#include -#include -#include - -#define NONAMELESSUNION -#define NONAMELESSSTRUCT - -#include "winerror.h" -#include "windef.h" -#include "winbase.h" -#include "winnls.h" - -#include "widltypes.h" -#include "typelib.h" -#include "typelib_struct.h" -#include "utils.h" -#include "header.h" -#include "hash.h" - -enum MSFT_segment_index { - MSFT_SEG_TYPEINFO = 0, /* type information */ - MSFT_SEG_IMPORTINFO, /* import information */ - MSFT_SEG_IMPORTFILES, /* import filenames */ - MSFT_SEG_REFERENCES, /* references (?) */ - MSFT_SEG_GUIDHASH, /* hash table for guids? */ - MSFT_SEG_GUID, /* guid storage */ - MSFT_SEG_NAMEHASH, /* hash table for names */ - MSFT_SEG_NAME, /* name storage */ - MSFT_SEG_STRING, /* string storage */ - MSFT_SEG_TYPEDESC, /* type descriptions */ - MSFT_SEG_ARRAYDESC, /* array descriptions */ - MSFT_SEG_CUSTDATA, /* custom data */ - MSFT_SEG_CUSTDATAGUID, /* custom data guids */ - MSFT_SEG_UNKNOWN, /* ??? */ - MSFT_SEG_UNKNOWN2, /* ??? */ - MSFT_SEG_MAX /* total number of segments */ -}; - -typedef struct tagMSFT_ImpFile { - int guid; - LCID lcid; - int version; - char filename[0]; /* preceded by two bytes of encoded (length << 2) + flags in the low two bits. */ -} MSFT_ImpFile; - -typedef struct _msft_typelib_t -{ - typelib_t *typelib; - MSFT_Header typelib_header; - MSFT_pSeg typelib_segdir[MSFT_SEG_MAX]; - char *typelib_segment_data[MSFT_SEG_MAX]; - int typelib_segment_block_length[MSFT_SEG_MAX]; - - INT typelib_typeinfo_offsets[0x200]; /* Hope that's enough. */ - - INT *typelib_namehash_segment; - INT *typelib_guidhash_segment; - - INT help_string_dll_offset; - - struct _msft_typeinfo_t *typeinfos; - struct _msft_typeinfo_t *last_typeinfo; -} msft_typelib_t; - -typedef struct _msft_typeinfo_t -{ - msft_typelib_t *typelib; - MSFT_TypeInfoBase *typeinfo; - - int typekind; - - unsigned int var_data_allocated; - int *var_data; - - unsigned int func_data_allocated; - int *func_data; - - int vars_allocated; - int *var_indices; - int *var_names; - int *var_offsets; - - int funcs_allocated; - int *func_indices; - int *func_names; - int *func_offsets; - - int datawidth; - - struct _msft_typeinfo_t *next_typeinfo; -} msft_typeinfo_t; - - - -/*================== Internal functions ===================================*/ - -/**************************************************************************** - * ctl2_init_header - * - * Initializes the type library header of a new typelib. - */ -static void ctl2_init_header( - msft_typelib_t *typelib) /* [I] The typelib to initialize. */ -{ - typelib->typelib_header.magic1 = 0x5446534d; - typelib->typelib_header.magic2 = 0x00010002; - typelib->typelib_header.posguid = -1; - typelib->typelib_header.lcid = 0x0409; /* or do we use the current one? */ - typelib->typelib_header.lcid2 = 0x0; - typelib->typelib_header.varflags = 0x40; - typelib->typelib_header.version = 0; - typelib->typelib_header.flags = 0; - typelib->typelib_header.nrtypeinfos = 0; - typelib->typelib_header.helpstring = -1; - typelib->typelib_header.helpstringcontext = 0; - typelib->typelib_header.helpcontext = 0; - typelib->typelib_header.nametablecount = 0; - typelib->typelib_header.nametablechars = 0; - typelib->typelib_header.NameOffset = -1; - typelib->typelib_header.helpfile = -1; - typelib->typelib_header.CustomDataOffset = -1; - typelib->typelib_header.res44 = 0x20; - typelib->typelib_header.res48 = 0x80; - typelib->typelib_header.dispatchpos = -1; - typelib->typelib_header.nimpinfos = 0; -} - -/**************************************************************************** - * ctl2_init_segdir - * - * Initializes the segment directory of a new typelib. - */ -static void ctl2_init_segdir( - msft_typelib_t *typelib) /* [I] The typelib to initialize. */ -{ - int i; - MSFT_pSeg *segdir; - - segdir = &typelib->typelib_segdir[MSFT_SEG_TYPEINFO]; - - for (i = 0; i < 15; i++) { - segdir[i].offset = -1; - segdir[i].length = 0; - segdir[i].res08 = -1; - segdir[i].res0c = 0x0f; - } -} - -/**************************************************************************** - * ctl2_hash_guid - * - * Generates a hash key from a GUID. - * - * RETURNS - * - * The hash key for the GUID. - */ -static int ctl2_hash_guid( - REFGUID guid) /* [I] The guid to hash. */ -{ - int hash; - int i; - - hash = 0; - for (i = 0; i < 8; i ++) { - hash ^= ((const short *)guid)[i]; - } - - return hash & 0x1f; -} - -/**************************************************************************** - * ctl2_find_guid - * - * Locates a guid in a type library. - * - * RETURNS - * - * The offset into the GUID segment of the guid, or -1 if not found. - */ -static int ctl2_find_guid( - msft_typelib_t *typelib, /* [I] The typelib to operate against. */ - int hash_key, /* [I] The hash key for the guid. */ - REFGUID guid) /* [I] The guid to find. */ -{ - int offset; - MSFT_GuidEntry *guidentry; - - offset = typelib->typelib_guidhash_segment[hash_key]; - while (offset != -1) { - guidentry = (MSFT_GuidEntry *)&typelib->typelib_segment_data[MSFT_SEG_GUID][offset]; - - if (!memcmp(guidentry, guid, sizeof(GUID))) return offset; - - offset = guidentry->next_hash; - } - - return offset; -} - -/**************************************************************************** - * ctl2_find_name - * - * Locates a name in a type library. - * - * RETURNS - * - * The offset into the NAME segment of the name, or -1 if not found. - * - * NOTES - * - * The name must be encoded as with ctl2_encode_name(). - */ -static int ctl2_find_name( - msft_typelib_t *typelib, /* [I] The typelib to operate against. */ - char *name) /* [I] The encoded name to find. */ -{ - int offset; - int *namestruct; - - offset = typelib->typelib_namehash_segment[name[2] & 0x7f]; - while (offset != -1) { - namestruct = (int *)&typelib->typelib_segment_data[MSFT_SEG_NAME][offset]; - - if (!((namestruct[2] ^ *((int *)name)) & 0xffff00ff)) { - /* hash codes and lengths match, final test */ - if (!strncasecmp(name+4, (void *)(namestruct+3), name[0])) break; - } - - /* move to next item in hash bucket */ - offset = namestruct[1]; - } - - return offset; -} - -/**************************************************************************** - * ctl2_encode_name - * - * Encodes a name string to a form suitable for storing into a type library - * or comparing to a name stored in a type library. - * - * RETURNS - * - * The length of the encoded name, including padding and length+hash fields. - * - * NOTES - * - * Will throw an exception if name or result are NULL. Is not multithread - * safe in the slightest. - */ -static int ctl2_encode_name( - msft_typelib_t *typelib, /* [I] The typelib to operate against (used for LCID only). */ - const char *name, /* [I] The name string to encode. */ - char **result) /* [O] A pointer to a pointer to receive the encoded name. */ -{ - int length; - static char converted_name[0x104]; - int offset; - int value; - - length = strlen(name); - memcpy(converted_name + 4, name, length); - converted_name[0] = length & 0xff; - - converted_name[length + 4] = 0; - - converted_name[1] = 0x00; - - value = lhash_val_of_name_sys(typelib->typelib_header.varflags & 0x0f, typelib->typelib_header.lcid, converted_name + 4); - - converted_name[2] = value; - converted_name[3] = value >> 8; - - for (offset = (4 - length) & 3; offset; offset--) converted_name[length + offset + 3] = 0x57; - - *result = converted_name; - - return (length + 7) & ~3; -} - -/**************************************************************************** - * ctl2_encode_string - * - * Encodes a string to a form suitable for storing into a type library or - * comparing to a string stored in a type library. - * - * RETURNS - * - * The length of the encoded string, including padding and length fields. - * - * NOTES - * - * Will throw an exception if string or result are NULL. Is not multithread - * safe in the slightest. - */ -static int ctl2_encode_string( - const char *string, /* [I] The string to encode. */ - char **result) /* [O] A pointer to a pointer to receive the encoded string. */ -{ - int length; - static char converted_string[0x104]; - int offset; - - length = strlen(string); - memcpy(converted_string + 2, string, length); - converted_string[0] = length & 0xff; - converted_string[1] = (length >> 8) & 0xff; - - if(length < 3) { /* strings of this length are padded with up to 8 bytes incl the 2 byte length */ - for(offset = 0; offset < 4; offset++) - converted_string[length + offset + 2] = 0x57; - length += 4; - } - for (offset = (4 - (length + 2)) & 3; offset; offset--) converted_string[length + offset + 1] = 0x57; - - *result = converted_string; - - return (length + 5) & ~3; -} - -/**************************************************************************** - * ctl2_alloc_segment - * - * Allocates memory from a segment in a type library. - * - * RETURNS - * - * Success: The offset within the segment of the new data area. - * - * BUGS - * - * Does not (yet) handle the case where the allocated segment memory needs to grow. - */ -static int ctl2_alloc_segment( - msft_typelib_t *typelib, /* [I] The type library in which to allocate. */ - enum MSFT_segment_index segment, /* [I] The segment in which to allocate. */ - int size, /* [I] The amount to allocate. */ - int block_size) /* [I] Initial allocation block size, or 0 for default. */ -{ - int offset; - - if(!typelib->typelib_segment_data[segment]) { - if (!block_size) block_size = 0x2000; - - typelib->typelib_segment_block_length[segment] = block_size; - typelib->typelib_segment_data[segment] = xmalloc(block_size); - if (!typelib->typelib_segment_data[segment]) return -1; - memset(typelib->typelib_segment_data[segment], 0x57, block_size); - } - - while ((typelib->typelib_segdir[segment].length + size) > typelib->typelib_segment_block_length[segment]) { - char *block; - - block_size = typelib->typelib_segment_block_length[segment]; - block = xrealloc(typelib->typelib_segment_data[segment], block_size << 1); - - if (segment == MSFT_SEG_TYPEINFO) { - /* TypeInfos have a direct pointer to their memory space, so we have to fix them up. */ - msft_typeinfo_t *typeinfo; - - for (typeinfo = typelib->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) { - typeinfo->typeinfo = (void *)&block[((char *)typeinfo->typeinfo) - typelib->typelib_segment_data[segment]]; - } - } - - memset(block + block_size, 0x57, block_size); - typelib->typelib_segment_block_length[segment] = block_size << 1; - typelib->typelib_segment_data[segment] = block; - } - - offset = typelib->typelib_segdir[segment].length; - typelib->typelib_segdir[segment].length += size; - - return offset; -} - -/**************************************************************************** - * ctl2_alloc_typeinfo - * - * Allocates and initializes a typeinfo structure in a type library. - * - * RETURNS - * - * Success: The offset of the new typeinfo. - * Failure: -1 (this is invariably an out of memory condition). - */ -static int ctl2_alloc_typeinfo( - msft_typelib_t *typelib, /* [I] The type library to allocate in. */ - int nameoffset) /* [I] The offset of the name for this typeinfo. */ -{ - int offset; - MSFT_TypeInfoBase *typeinfo; - - offset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEINFO, sizeof(MSFT_TypeInfoBase), 0); - - typelib->typelib_typeinfo_offsets[typelib->typelib_header.nrtypeinfos++] = offset; - - typeinfo = (void *)(typelib->typelib_segment_data[MSFT_SEG_TYPEINFO] + offset); - - typeinfo->typekind = (typelib->typelib_header.nrtypeinfos - 1) << 16; - typeinfo->memoffset = -1; /* should be EOF if no elements */ - typeinfo->res2 = 0; - typeinfo->res3 = -1; - typeinfo->res4 = 3; - typeinfo->res5 = 0; - typeinfo->cElement = 0; - typeinfo->res7 = 0; - typeinfo->res8 = 0; - typeinfo->res9 = 0; - typeinfo->resA = 0; - typeinfo->posguid = -1; - typeinfo->flags = 0; - typeinfo->NameOffset = nameoffset; - typeinfo->version = 0; - typeinfo->docstringoffs = -1; - typeinfo->helpstringcontext = 0; - typeinfo->helpcontext = 0; - typeinfo->oCustData = -1; - typeinfo->cbSizeVft = 0; - typeinfo->cImplTypes = 0; - typeinfo->size = 0; - typeinfo->datatype1 = -1; - typeinfo->datatype2 = 0; - typeinfo->res18 = 0; - typeinfo->res19 = -1; - - return offset; -} - -/**************************************************************************** - * ctl2_alloc_guid - * - * Allocates and initializes a GUID structure in a type library. Also updates - * the GUID hash table as needed. - * - * RETURNS - * - * Success: The offset of the new GUID. - */ -static int ctl2_alloc_guid( - msft_typelib_t *typelib, /* [I] The type library to allocate in. */ - MSFT_GuidEntry *guid) /* [I] The GUID to store. */ -{ - int offset; - MSFT_GuidEntry *guid_space; - int hash_key; - - hash_key = ctl2_hash_guid(&guid->guid); - - offset = ctl2_find_guid(typelib, hash_key, &guid->guid); - if (offset != -1) return offset; - - offset = ctl2_alloc_segment(typelib, MSFT_SEG_GUID, sizeof(MSFT_GuidEntry), 0); - - guid_space = (void *)(typelib->typelib_segment_data[MSFT_SEG_GUID] + offset); - *guid_space = *guid; - - guid_space->next_hash = typelib->typelib_guidhash_segment[hash_key]; - typelib->typelib_guidhash_segment[hash_key] = offset; - - return offset; -} - -/**************************************************************************** - * ctl2_alloc_name - * - * Allocates and initializes a name within a type library. Also updates the - * name hash table as needed. - * - * RETURNS - * - * Success: The offset within the segment of the new name. - * Failure: -1 (this is invariably an out of memory condition). - */ -static int ctl2_alloc_name( - msft_typelib_t *typelib, /* [I] The type library to allocate in. */ - const char *name) /* [I] The name to store. */ -{ - int length; - int offset; - MSFT_NameIntro *name_space; - char *encoded_name; - - length = ctl2_encode_name(typelib, name, &encoded_name); - - offset = ctl2_find_name(typelib, encoded_name); - if (offset != -1) return offset; - - offset = ctl2_alloc_segment(typelib, MSFT_SEG_NAME, length + 8, 0); - - name_space = (void *)(typelib->typelib_segment_data[MSFT_SEG_NAME] + offset); - name_space->hreftype = -1; - name_space->next_hash = -1; - memcpy(&name_space->namelen, encoded_name, length); - - if (typelib->typelib_namehash_segment[encoded_name[2] & 0x7f] != -1) - name_space->next_hash = typelib->typelib_namehash_segment[encoded_name[2] & 0x7f]; - - typelib->typelib_namehash_segment[encoded_name[2] & 0x7f] = offset; - - typelib->typelib_header.nametablecount += 1; - typelib->typelib_header.nametablechars += *encoded_name; - - return offset; -} - -/**************************************************************************** - * ctl2_alloc_string - * - * Allocates and initializes a string in a type library. - * - * RETURNS - * - * Success: The offset within the segment of the new string. - * Failure: -1 (this is invariably an out of memory condition). - */ -static int ctl2_alloc_string( - msft_typelib_t *typelib, /* [I] The type library to allocate in. */ - const char *string) /* [I] The string to store. */ -{ - int length; - int offset; - char *string_space; - char *encoded_string; - - length = ctl2_encode_string(string, &encoded_string); - - for (offset = 0; offset < typelib->typelib_segdir[MSFT_SEG_STRING].length; - offset += ((((typelib->typelib_segment_data[MSFT_SEG_STRING][offset + 1] << 8) & 0xff) - | (typelib->typelib_segment_data[MSFT_SEG_STRING][offset + 0] & 0xff)) + 5) & ~3) { - if (!memcmp(encoded_string, typelib->typelib_segment_data[MSFT_SEG_STRING] + offset, length)) return offset; - } - - offset = ctl2_alloc_segment(typelib, MSFT_SEG_STRING, length, 0); - - string_space = typelib->typelib_segment_data[MSFT_SEG_STRING] + offset; - memcpy(string_space, encoded_string, length); - - return offset; -} - -/**************************************************************************** - * alloc_msft_importinfo - * - * Allocates and initializes an import information structure in a type library. - * - * RETURNS - * - * Success: The offset of the new importinfo. - * Failure: -1 (this is invariably an out of memory condition). - */ -static int alloc_msft_importinfo( - msft_typelib_t *typelib, /* [I] The type library to allocate in. */ - MSFT_ImpInfo *impinfo) /* [I] The import information to store. */ -{ - int offset; - MSFT_ImpInfo *impinfo_space; - - for (offset = 0; - offset < typelib->typelib_segdir[MSFT_SEG_IMPORTINFO].length; - offset += sizeof(MSFT_ImpInfo)) { - if (!memcmp(&(typelib->typelib_segment_data[MSFT_SEG_IMPORTINFO][offset]), - impinfo, sizeof(MSFT_ImpInfo))) { - return offset; - } - } - - impinfo->flags |= typelib->typelib_header.nimpinfos++; - - offset = ctl2_alloc_segment(typelib, MSFT_SEG_IMPORTINFO, sizeof(MSFT_ImpInfo), 0); - - impinfo_space = (void *)(typelib->typelib_segment_data[MSFT_SEG_IMPORTINFO] + offset); - *impinfo_space = *impinfo; - - return offset; -} - -/**************************************************************************** - * alloc_importfile - * - * Allocates and initializes an import file definition in a type library. - * - * RETURNS - * - * Success: The offset of the new importinfo. - * Failure: -1 (this is invariably an out of memory condition). - */ -static int alloc_importfile( - msft_typelib_t *typelib, /* [I] The type library to allocate in. */ - int guidoffset, /* [I] The offset to the GUID for the imported library. */ - int major_version, /* [I] The major version number of the imported library. */ - int minor_version, /* [I] The minor version number of the imported library. */ - const char *filename) /* [I] The filename of the imported library. */ -{ - int length; - int offset; - MSFT_ImpFile *importfile; - char *encoded_string; - - length = ctl2_encode_string(filename, &encoded_string); - - encoded_string[0] <<= 2; - encoded_string[0] |= 1; - - for (offset = 0; offset < typelib->typelib_segdir[MSFT_SEG_IMPORTFILES].length; - offset += ((((typelib->typelib_segment_data[MSFT_SEG_IMPORTFILES][offset + 0xd] << 8) & 0xff) - | (typelib->typelib_segment_data[MSFT_SEG_IMPORTFILES][offset + 0xc] & 0xff)) >> 2) + 0xc) { - if (!memcmp(encoded_string, typelib->typelib_segment_data[MSFT_SEG_IMPORTFILES] + offset + 0xc, length)) return offset; - } - - offset = ctl2_alloc_segment(typelib, MSFT_SEG_IMPORTFILES, length + 0xc, 0); - - importfile = (MSFT_ImpFile *)&typelib->typelib_segment_data[MSFT_SEG_IMPORTFILES][offset]; - importfile->guid = guidoffset; - importfile->lcid = typelib->typelib_header.lcid2; - importfile->version = major_version | (minor_version << 16); - memcpy(&importfile->filename, encoded_string, length); - - return offset; -} - -static void alloc_importinfo(msft_typelib_t *typelib, importinfo_t *importinfo) -{ - importlib_t *importlib = importinfo->importlib; - - chat("alloc_importinfo: %s\n", importinfo->name); - - if(!importlib->allocated) { - MSFT_GuidEntry guid; - int guid_idx; - - chat("allocating importlib %s\n", importlib->name); - - importlib->allocated = -1; - - memcpy(&guid.guid, &importlib->guid, sizeof(GUID)); - guid.hreftype = 2; - - guid_idx = ctl2_alloc_guid(typelib, &guid); - - alloc_importfile(typelib, guid_idx, importlib->version&0xffff, - importlib->version>>16, importlib->name); - } - - if(importinfo->offset == -1 || !(importinfo->flags & MSFT_IMPINFO_OFFSET_IS_GUID)) { - MSFT_ImpInfo impinfo; - - impinfo.flags = importinfo->flags; - impinfo.oImpFile = 0; - - if(importinfo->flags & MSFT_IMPINFO_OFFSET_IS_GUID) { - MSFT_GuidEntry guid; - - guid.hreftype = 0; - memcpy(&guid.guid, &importinfo->guid, sizeof(GUID)); - - impinfo.oGuid = ctl2_alloc_guid(typelib, &guid); - - importinfo->offset = alloc_msft_importinfo(typelib, &impinfo); - - typelib->typelib_segment_data[MSFT_SEG_GUID][impinfo.oGuid+sizeof(GUID)] - = importinfo->offset+1; - - if(!strcmp(importinfo->name, "IDispatch")) - typelib->typelib_header.dispatchpos = importinfo->offset+1; - }else { - impinfo.oGuid = importinfo->id; - importinfo->offset = alloc_msft_importinfo(typelib, &impinfo); - } - } -} - -static importinfo_t *find_importinfo(msft_typelib_t *typelib, const char *name) -{ - importlib_t *importlib; - int i; - - chat("search importlib %s\n", name); - - if(!name) - return NULL; - - LIST_FOR_EACH_ENTRY( importlib, &typelib->typelib->importlibs, importlib_t, entry ) - { - for(i=0; i < importlib->ntypeinfos; i++) { - if(!strcmp(name, importlib->importinfos[i].name)) { - chat("Found %s in importlib.\n", name); - return importlib->importinfos+i; - } - } - } - - return NULL; -} - -static void add_structure_typeinfo(msft_typelib_t *typelib, type_t *structure); -static void add_interface_typeinfo(msft_typelib_t *typelib, type_t *interface); -static void add_enum_typeinfo(msft_typelib_t *typelib, type_t *enumeration); -static void add_coclass_typeinfo(msft_typelib_t *typelib, type_t *cls); -static void add_dispinterface_typeinfo(msft_typelib_t *typelib, type_t *dispinterface); - - -/**************************************************************************** - * encode_type - * - * Encodes a type, storing information in the TYPEDESC and ARRAYDESC - * segments as needed. - * - * RETURNS - * - * Success: 0. - * Failure: -1. - */ -static int encode_type( - msft_typelib_t *typelib, /* [I] The type library in which to encode the TYPEDESC. */ - int vt, /* [I] vt to encode */ - type_t *type, /* [I] type */ - int *encoded_type, /* [O] The encoded type description. */ - int *width, /* [O] The width of the type, or NULL. */ - int *alignment, /* [O] The alignment of the type, or NULL. */ - int *decoded_size) /* [O] The total size of the unencoded TYPEDESCs, including nested descs. */ -{ - int default_type; - int scratch; - int typeoffset; - int *typedata; - int target_type; - int child_size = 0; - - chat("encode_type vt %d type %p\n", vt, type); - - default_type = 0x80000000 | (vt << 16) | vt; - if (!width) width = &scratch; - if (!alignment) alignment = &scratch; - if (!decoded_size) decoded_size = &scratch; - - - switch (vt) { - case VT_I1: - case VT_UI1: - *encoded_type = default_type; - *width = 1; - *alignment = 1; - break; - - case VT_INT: - *encoded_type = 0x80000000 | (VT_I4 << 16) | VT_INT; - if ((typelib->typelib_header.varflags & 0x0f) == SYS_WIN16) { - *width = 2; - *alignment = 2; - } else { - *width = 4; - *alignment = 4; - } - break; - - case VT_UINT: - *encoded_type = 0x80000000 | (VT_UI4 << 16) | VT_UINT; - if ((typelib->typelib_header.varflags & 0x0f) == SYS_WIN16) { - *width = 2; - *alignment = 2; - } else { - *width = 4; - *alignment = 4; - } - break; - - case VT_UI2: - case VT_I2: - case VT_BOOL: - *encoded_type = default_type; - *width = 2; - *alignment = 2; - break; - - case VT_I4: - case VT_UI4: - case VT_R4: - case VT_ERROR: - case VT_BSTR: - case VT_HRESULT: - *encoded_type = default_type; - *width = 4; - *alignment = 4; - break; - - case VT_R8: - case VT_I8: - case VT_UI8: - *encoded_type = default_type; - *width = 8; - *alignment = 8; - break; - - case VT_CY: - case VT_DATE: - *encoded_type = default_type; - *width = 8; - *alignment = 8; - break; - - case VT_VOID: - *encoded_type = 0x80000000 | (VT_EMPTY << 16) | vt; - *width = 0; - *alignment = 1; - break; - - case VT_UNKNOWN: - case VT_DISPATCH: - *encoded_type = default_type; - *width = 4; - *alignment = 4; - break; - - case VT_VARIANT: - *encoded_type = default_type; - break; - - case VT_LPSTR: - case VT_LPWSTR: - *encoded_type = 0xfffe0000 | vt; - *width = 4; - *alignment = 4; - break; - - case VT_PTR: - { - int next_vt; - for(next_vt = 0; type->ref; type = type->ref) { - next_vt = get_type_vt(type->ref); - if (next_vt != 0) - break; - } - /* if no type found then it must be void */ - if (next_vt == 0) - next_vt = VT_VOID; - - encode_type(typelib, next_vt, type->ref, &target_type, NULL, NULL, &child_size); - if(type->ref && (type->ref->type == RPC_FC_IP)) { - chat("encode_type: skipping ptr\n"); - *encoded_type = target_type; - *width = 4; - *alignment = 4; - *decoded_size = child_size; - break; - } - - for (typeoffset = 0; typeoffset < typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) { - typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; - if (((typedata[0] & 0xffff) == VT_PTR) && (typedata[1] == target_type)) break; - } - - if (typeoffset == typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length) { - int mix_field; - - if (target_type & 0x80000000) { - mix_field = ((target_type >> 16) & 0x3fff) | VT_BYREF; - } else { - typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][target_type]; - mix_field = ((typedata[0] >> 16) == 0x7fff)? 0x7fff: 0x7ffe; - } - - typeoffset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEDESC, 8, 0); - typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; - - typedata[0] = (mix_field << 16) | VT_PTR; - typedata[1] = target_type; - } - - *encoded_type = typeoffset; - - *width = 4; - *alignment = 4; - *decoded_size = 8 /*sizeof(TYPEDESC)*/ + child_size; - break; - } - - - case VT_SAFEARRAY: - { - int next_vt; - - /* skip over SAFEARRAY type straight to element type */ - type = type->ref; - - for(next_vt = 0; type->ref; type = type->ref) { - next_vt = get_type_vt(type->ref); - if (next_vt != 0) - break; - } - - encode_type(typelib, next_vt, type->ref, &target_type, NULL, NULL, &child_size); - - for (typeoffset = 0; typeoffset < typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) { - typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; - if (((typedata[0] & 0xffff) == VT_SAFEARRAY) && (typedata[1] == target_type)) break; - } - - if (typeoffset == typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length) { - int mix_field; - - if (target_type & 0x80000000) { - mix_field = ((target_type >> 16) & VT_TYPEMASK) | VT_ARRAY; - } else { - typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][target_type]; - mix_field = ((typedata[0] >> 16) == 0x7fff)? 0x7fff: 0x7ffe; - } - - typeoffset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEDESC, 8, 0); - typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; - - typedata[0] = (mix_field << 16) | VT_SAFEARRAY; - typedata[1] = target_type; - } - - *encoded_type = typeoffset; - - *width = 4; - *alignment = 4; - *decoded_size = 8 /*sizeof(TYPEDESC)*/ + child_size; - break; - } - - - case VT_USERDEFINED: - { - int typeinfo_offset; - - /* typedef'd types without attributes aren't included in the typelib */ - while (type->typelib_idx < 0 && type->kind == TKIND_ALIAS && ! type->attrs) - type = type->orig; - - chat("encode_type: VT_USERDEFINED - type %p name = %s type->type %d idx %d\n", type, - type->name, type->type, type->typelib_idx); - - if(type->typelib_idx == -1) { - chat("encode_type: trying to ref not added type\n"); - switch(type->type) { - case RPC_FC_STRUCT: - case RPC_FC_PSTRUCT: - case RPC_FC_CSTRUCT: - case RPC_FC_CPSTRUCT: - case RPC_FC_CVSTRUCT: - case RPC_FC_BOGUS_STRUCT: - add_structure_typeinfo(typelib, type); - break; - case RPC_FC_IP: - add_interface_typeinfo(typelib, type); - break; - case RPC_FC_ENUM16: - add_enum_typeinfo(typelib, type); - break; - case 0: - if (type->kind == TKIND_COCLASS) - add_coclass_typeinfo(typelib, type); - else if (type->kind == TKIND_DISPATCH) - add_dispinterface_typeinfo(typelib, type); - else - error("encode_type: VT_USERDEFINED - can't yet add typedef's on the fly\n"); - break; - default: - error("encode_type: VT_USERDEFINED - unhandled type %d\n", type->type); - } - } - - typeinfo_offset = typelib->typelib_typeinfo_offsets[type->typelib_idx]; - for (typeoffset = 0; typeoffset < typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) { - typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; - if ((typedata[0] == ((0x7fff << 16) | VT_USERDEFINED)) && (typedata[1] == typeinfo_offset)) break; - } - - if (typeoffset == typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length) { - typeoffset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEDESC, 8, 0); - typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; - - typedata[0] = (0x7fff << 16) | VT_USERDEFINED; - typedata[1] = typeinfo_offset; - } - - *encoded_type = typeoffset; - *width = 0; - *alignment = 1; - - if(type->type == RPC_FC_IP) { - for (typeoffset = 0; typeoffset < typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) { - typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; - if ((typedata[0] == ((0x7fff << 16) | VT_PTR)) && (typedata[1] == *encoded_type)) break; - } - if (typeoffset == typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length) { - typeoffset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEDESC, 8, 0); - typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; - - typedata[0] = (0x7fff << 16) | VT_PTR; - typedata[1] = *encoded_type; - } - *encoded_type = typeoffset; - *width = 4; - *alignment = 4; - *decoded_size += 8; - } - break; - } - - default: - error("encode_type: unrecognized type %d.\n", vt); - *encoded_type = default_type; - *width = 0; - *alignment = 1; - break; - } - - return 0; -} - -static void dump_type(type_t *t) -{ - chat("dump_type: %p name %s type %d ref %p attrs %p\n", t, t->name, t->type, t->ref, t->attrs); - if(t->ref) dump_type(t->ref); -} - -static int encode_var( - msft_typelib_t *typelib, /* [I] The type library in which to encode the TYPEDESC. */ - type_t *type, /* [I] The type description to encode. */ - var_t *var, /* [I] The var to encode. */ - int *encoded_type, /* [O] The encoded type description. */ - int *width, /* [O] The width of the type, or NULL. */ - int *alignment, /* [O] The alignment of the type, or NULL. */ - int *decoded_size) /* [O] The total size of the unencoded TYPEDESCs, including nested descs. */ -{ - int typeoffset; - int *typedata; - int target_type; - int child_size; - int vt; - int scratch; - - if (!width) width = &scratch; - if (!alignment) alignment = &scratch; - if (!decoded_size) decoded_size = &scratch; - *decoded_size = 0; - - chat("encode_var: var %p type %p type->name %s type->ref %p\n", - var, type, type->name ? type->name : "NULL", type->ref); - - if (type->declarray) { - int num_dims, elements = 1, arrayoffset; - type_t *atype; - int *arraydata; - - num_dims = 0; - for (atype = type; atype->declarray; atype = atype->ref) - ++num_dims; - - chat("array with %d dimensions\n", num_dims); - encode_var(typelib, atype, var, &target_type, width, alignment, NULL); - arrayoffset = ctl2_alloc_segment(typelib, MSFT_SEG_ARRAYDESC, (2 + 2 * num_dims) * sizeof(long), 0); - arraydata = (void *)&typelib->typelib_segment_data[MSFT_SEG_ARRAYDESC][arrayoffset]; - - arraydata[0] = target_type; - arraydata[1] = num_dims; - arraydata[1] |= ((num_dims * 2 * sizeof(long)) << 16); - - arraydata += 2; - for (atype = type; atype->declarray; atype = atype->ref) - { - arraydata[0] = atype->dim; - arraydata[1] = 0; - arraydata += 2; - elements *= atype->dim; - } - - typeoffset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEDESC, 8, 0); - typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; - - typedata[0] = (0x7ffe << 16) | VT_CARRAY; - typedata[1] = arrayoffset; - - *encoded_type = typeoffset; - *width = *width * elements; - *decoded_size = 20 /*sizeof(ARRAYDESC)*/ + (num_dims - 1) * 8 /*sizeof(SAFEARRAYBOUND)*/; - return 0; - } - - vt = get_type_vt(type); - if (vt == VT_PTR) { - int skip_ptr = encode_var(typelib, type->ref, var, &target_type, NULL, NULL, &child_size); - - if(skip_ptr == 2) { - chat("encode_var: skipping ptr\n"); - *encoded_type = target_type; - *decoded_size = child_size; - *width = 4; - *alignment = 4; - return 0; - } - - for (typeoffset = 0; typeoffset < typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) { - typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; - if (((typedata[0] & 0xffff) == VT_PTR) && (typedata[1] == target_type)) break; - } - - if (typeoffset == typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length) { - int mix_field; - - if (target_type & 0x80000000) { - mix_field = ((target_type >> 16) & 0x3fff) | VT_BYREF; - } else { - typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][target_type]; - mix_field = ((typedata[0] >> 16) == 0x7fff)? 0x7fff: 0x7ffe; - } - - typeoffset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEDESC, 8, 0); - typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; - - typedata[0] = (mix_field << 16) | VT_PTR; - typedata[1] = target_type; - } - - *encoded_type = typeoffset; - - *width = 4; - *alignment = 4; - *decoded_size = 8 /*sizeof(TYPEDESC)*/ + child_size; - return 0; - } - - dump_type(type); - - encode_type(typelib, vt, type, encoded_type, width, alignment, decoded_size); - if(type->type == RPC_FC_IP) return 2; - return 0; -} - -static unsigned long get_ulong_val(unsigned long val, int vt) -{ - switch(vt) { - case VT_I2: - case VT_BOOL: - case VT_UI2: - return val & 0xffff; - case VT_I1: - case VT_UI1: - return val & 0xff; - } - - return val; -} - -static void write_value(msft_typelib_t* typelib, int *out, int vt, void *value) -{ - switch(vt) { - case VT_I2: - case VT_I4: - case VT_R4: - case VT_BOOL: - case VT_I1: - case VT_UI1: - case VT_UI2: - case VT_UI4: - case VT_INT: - case VT_UINT: - case VT_HRESULT: - case VT_PTR: - { - const unsigned long lv = get_ulong_val(*(unsigned long*)value, vt); - if((lv & 0x3ffffff) == lv) { - *out = 0x80000000; - *out |= vt << 26; - *out |= lv; - } else { - int offset = ctl2_alloc_segment(typelib, MSFT_SEG_CUSTDATA, 8, 0); - *((unsigned short *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset]) = vt; - memcpy(&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset+2], value, 4); - *((unsigned short *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset+6]) = 0x5757; - *out = offset; - } - return; - } - case VT_BSTR: - { - char *s = (char *) value; - int len = strlen(s), seg_len = (len + 6 + 3) & ~0x3; - int offset = ctl2_alloc_segment(typelib, MSFT_SEG_CUSTDATA, seg_len, 0); - *((unsigned short *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset]) = vt; - *((unsigned int *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset+2]) = len; - memcpy(&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset+6], value, len); - len += 6; - while(len < seg_len) { - *((char *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset+len]) = 0x57; - len++; - } - *out = offset; - return; - } - - default: - warning("can't write value of type %d yet\n", vt); - } - return; -} - -static HRESULT set_custdata(msft_typelib_t *typelib, REFGUID guid, - int vt, void *value, int *offset) -{ - MSFT_GuidEntry guidentry; - int guidoffset; - int custoffset; - int *custdata; - int data_out; - - guidentry.guid = *guid; - - guidentry.hreftype = -1; - guidentry.next_hash = -1; - - guidoffset = ctl2_alloc_guid(typelib, &guidentry); - write_value(typelib, &data_out, vt, value); - - custoffset = ctl2_alloc_segment(typelib, MSFT_SEG_CUSTDATAGUID, 12, 0); - - custdata = (int *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATAGUID][custoffset]; - custdata[0] = guidoffset; - custdata[1] = data_out; - custdata[2] = *offset; - *offset = custoffset; - - return S_OK; -} - -static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, const func_t *func, int index) -{ - int offset, name_offset; - int *typedata, typedata_size; - int i, id, next_idx; - int decoded_size, extra_attr = 0; - int num_params = 0, num_optional = 0, num_defaults = 0; - var_t *arg; - char *namedata; - const attr_t *attr; - unsigned int funcflags = 0, callconv = 4 /* CC_STDCALL */; - unsigned int funckind, invokekind = 1 /* INVOKE_FUNC */; - int help_context = 0, help_string_context = 0, help_string_offset = -1; - int entry = -1, entry_is_ord = 0; - - chat("add_func_desc(%p,%d)\n", typeinfo, index); - - id = ((0x6000 | (typeinfo->typeinfo->datatype2 & 0xffff)) << 16) | index; - - switch(typeinfo->typekind) { - case TKIND_DISPATCH: - funckind = 0x4; /* FUNC_DISPATCH */ - break; - case TKIND_MODULE: - funckind = 0x3; /* FUNC_STATIC */ - break; - default: - funckind = 0x1; /* FUNC_PUREVIRTUAL */ - break; - } - - if (is_local( func->def->attrs )) { - chat("add_func_desc: skipping local function\n"); - return S_FALSE; - } - - if (func->args) - LIST_FOR_EACH_ENTRY( arg, func->args, var_t, entry ) - { - num_params++; - if (arg->attrs) LIST_FOR_EACH_ENTRY( attr, arg->attrs, const attr_t, entry ) { - if(attr->type == ATTR_DEFAULTVALUE_EXPR || attr->type == ATTR_DEFAULTVALUE_STRING) - num_defaults++; - else if(attr->type == ATTR_OPTIONAL) - num_optional++; - } - } - - chat("add_func_desc: num of params %d\n", num_params); - - name_offset = ctl2_alloc_name(typeinfo->typelib, func->def->name); - - if (func->def->attrs) LIST_FOR_EACH_ENTRY( attr, func->def->attrs, const attr_t, entry ) { - expr_t *expr = attr->u.pval; - switch(attr->type) { - case ATTR_BINDABLE: - funcflags |= 0x4; /* FUNCFLAG_BINDABLE */ - break; - case ATTR_DISPLAYBIND: - funcflags |= 0x10; /* FUNCFLAG_DISPLAYBIND */ - break; - case ATTR_ENTRY_ORDINAL: - extra_attr = max(extra_attr, 3); - entry = expr->cval; - entry_is_ord = 1; - break; - case ATTR_ENTRY_STRING: - extra_attr = max(extra_attr, 3); - entry = ctl2_alloc_string(typeinfo->typelib, attr->u.pval); - break; - case ATTR_HELPCONTEXT: - extra_attr = max(extra_attr, 1); - help_context = expr->u.lval; - break; - case ATTR_HELPSTRING: - extra_attr = max(extra_attr, 2); - help_string_offset = ctl2_alloc_string(typeinfo->typelib, attr->u.pval); - break; - case ATTR_HELPSTRINGCONTEXT: - extra_attr = max(extra_attr, 6); - help_string_context = expr->u.lval; - break; - case ATTR_HIDDEN: - funcflags |= 0x40; /* FUNCFLAG_FHIDDEN */ - break; - case ATTR_ID: - id = expr->cval; - break; - case ATTR_NONBROWSABLE: - funcflags |= 0x400; /* FUNCFLAG_NONBROWSABLE */ - break; - case ATTR_OUT: - break; - case ATTR_PROPGET: - invokekind = 0x2; /* INVOKE_PROPERTYGET */ - break; - case ATTR_PROPPUT: - invokekind = 0x4; /* INVOKE_PROPERTYPUT */ - break; - case ATTR_PROPPUTREF: - invokekind = 0x8; /* INVOKE_PROPERTYPUTREF */ - break; - case ATTR_RESTRICTED: - funcflags |= 0x1; /* FUNCFLAG_FRESTRICTED */ - break; - case ATTR_VARARG: - if (num_optional || num_defaults) - warning("add_func_desc: ignoring vararg in function with optional or defaultvalue params\n"); - else - num_optional = -1; - break; - default: - warning("add_func_desc: ignoring attr %d\n", attr->type); - break; - } - } - - /* allocate type data space for us */ - typedata_size = 0x18 + extra_attr * sizeof(int) + (num_params * (num_defaults ? 16 : 12)); - - if (!typeinfo->func_data) { - typeinfo->func_data = xmalloc(0x100); - typeinfo->func_data_allocated = 0x100; - typeinfo->func_data[0] = 0; - } - - if(typeinfo->func_data[0] + typedata_size + sizeof(int) > typeinfo->func_data_allocated) { - typeinfo->func_data_allocated = max(typeinfo->func_data_allocated * 2, - typeinfo->func_data[0] + typedata_size + sizeof(int)); - typeinfo->func_data = xrealloc(typeinfo->func_data, typeinfo->func_data_allocated); - } - - offset = typeinfo->func_data[0]; - typeinfo->func_data[0] += typedata_size; - typedata = typeinfo->func_data + (offset >> 2) + 1; - - - /* find func with the same name - if it exists use its id */ - for(i = 0; i < (typeinfo->typeinfo->cElement & 0xffff); i++) { - if(name_offset == typeinfo->func_names[i]) { - id = typeinfo->func_indices[i]; - break; - } - } - - /* find the first func with the same id and link via the hiword of typedata[4] */ - next_idx = index; - for(i = 0; i < (typeinfo->typeinfo->cElement & 0xffff); i++) { - if(id == typeinfo->func_indices[i]) { - next_idx = typeinfo->func_data[(typeinfo->func_offsets[i] >> 2) + 1 + 4] >> 16; - typeinfo->func_data[(typeinfo->func_offsets[i] >> 2) + 1 + 4] &= 0xffff; - typeinfo->func_data[(typeinfo->func_offsets[i] >> 2) + 1 + 4] |= (index << 16); - break; - } - } - - /* fill out the basic type information */ - typedata[0] = typedata_size | (index << 16); - encode_var(typeinfo->typelib, func->def->type, func->def, &typedata[1], NULL, NULL, &decoded_size); - typedata[2] = funcflags; - typedata[3] = ((52 /*sizeof(FUNCDESC)*/ + decoded_size) << 16) | typeinfo->typeinfo->cbSizeVft; - typedata[4] = (next_idx << 16) | (callconv << 8) | (invokekind << 3) | funckind; - if(num_defaults) typedata[4] |= 0x1000; - if(entry_is_ord) typedata[4] |= 0x2000; - typedata[5] = (num_optional << 16) | num_params; - - /* NOTE: High word of typedata[3] is total size of FUNCDESC + size of all ELEMDESCs for params + TYPEDESCs for pointer params and return types. */ - /* That is, total memory allocation required to reconstitute the FUNCDESC in its entirety. */ - typedata[3] += (16 /*sizeof(ELEMDESC)*/ * num_params) << 16; - typedata[3] += (24 /*sizeof(PARAMDESCEX)*/ * num_defaults) << 16; - - switch(extra_attr) { - case 6: typedata[11] = help_string_context; - case 5: typedata[10] = -1; - case 4: typedata[9] = -1; - case 3: typedata[8] = entry; - case 2: typedata[7] = help_string_offset; - case 1: typedata[6] = help_context; - case 0: - break; - default: - warning("unknown number of optional attrs\n"); - } - - if (func->args) - { - i = 0; - LIST_FOR_EACH_ENTRY( arg, func->args, var_t, entry ) - { - const attr_t *attr; - int paramflags = 0; - int *paramdata = typedata + 6 + extra_attr + (num_defaults ? num_params : 0) + i * 3; - int *defaultdata = num_defaults ? typedata + 6 + extra_attr + i : NULL; - - if(defaultdata) *defaultdata = -1; - - encode_var(typeinfo->typelib, arg->type, arg, paramdata, NULL, NULL, &decoded_size); - if (arg->attrs) LIST_FOR_EACH_ENTRY( attr, arg->attrs, const attr_t, entry ) { - switch(attr->type) { - case ATTR_DEFAULTVALUE_EXPR: - { - int vt; - expr_t *expr = (expr_t *)attr->u.pval; - if (arg->type->type == RPC_FC_ENUM16) - vt = VT_INT; - else - vt = get_type_vt(arg->type); - paramflags |= 0x30; /* PARAMFLAG_FHASDEFAULT | PARAMFLAG_FOPT */ - chat("default value %ld\n", expr->cval); - write_value(typeinfo->typelib, defaultdata, vt, &expr->cval); - break; - } - case ATTR_DEFAULTVALUE_STRING: - { - char *s = (char *)attr->u.pval; - int vt; - if (arg->type->type == RPC_FC_ENUM16) - vt = VT_INT; - else - vt = get_type_vt(arg->type); - paramflags |= 0x30; /* PARAMFLAG_FHASDEFAULT | PARAMFLAG_FOPT */ - chat("default value '%s'\n", s); - write_value(typeinfo->typelib, defaultdata, vt, s); - break; - } - case ATTR_IN: - paramflags |= 0x01; /* PARAMFLAG_FIN */ - break; - case ATTR_OPTIONAL: - paramflags |= 0x10; /* PARAMFLAG_FOPT */ - break; - case ATTR_OUT: - paramflags |= 0x02; /* PARAMFLAG_FOUT */ - break; - case ATTR_RETVAL: - paramflags |= 0x08; /* PARAMFLAG_FRETVAL */ - typedata[4] |= 0x4000; - break; - default: - chat("unhandled param attr %d\n", attr->type); - break; - } - } - paramdata[1] = -1; - paramdata[2] = paramflags; - typedata[3] += decoded_size << 16; - i++; - } - } - - if(typeinfo->funcs_allocated == 0) { - typeinfo->funcs_allocated = 10; - typeinfo->func_indices = xmalloc(typeinfo->funcs_allocated * sizeof(int)); - typeinfo->func_names = xmalloc(typeinfo->funcs_allocated * sizeof(int)); - typeinfo->func_offsets = xmalloc(typeinfo->funcs_allocated * sizeof(int)); - } - if(typeinfo->funcs_allocated == (typeinfo->typeinfo->cElement & 0xffff)) { - typeinfo->funcs_allocated *= 2; - typeinfo->func_indices = xrealloc(typeinfo->func_indices, typeinfo->funcs_allocated * sizeof(int)); - typeinfo->func_names = xrealloc(typeinfo->func_names, typeinfo->funcs_allocated * sizeof(int)); - typeinfo->func_offsets = xrealloc(typeinfo->func_offsets, typeinfo->funcs_allocated * sizeof(int)); - } - - /* update the index data */ - typeinfo->func_indices[typeinfo->typeinfo->cElement & 0xffff] = id; - typeinfo->func_offsets[typeinfo->typeinfo->cElement & 0xffff] = offset; - typeinfo->func_names[typeinfo->typeinfo->cElement & 0xffff] = name_offset; - - /* ??? */ - if (!typeinfo->typeinfo->res2) typeinfo->typeinfo->res2 = 0x20; - typeinfo->typeinfo->res2 <<= 1; - /* ??? */ - if (index < 2) typeinfo->typeinfo->res2 += num_params << 4; - - if (typeinfo->typeinfo->res3 == -1) typeinfo->typeinfo->res3 = 0; - typeinfo->typeinfo->res3 += 0x38 + num_params * 0x10; - if(num_defaults) typeinfo->typeinfo->res3 += num_params * 0x4; - - /* adjust size of VTBL */ - if(funckind != 0x3 /* FUNC_STATIC */) - typeinfo->typeinfo->cbSizeVft += 4; - - /* Increment the number of function elements */ - typeinfo->typeinfo->cElement += 1; - - namedata = typeinfo->typelib->typelib_segment_data[MSFT_SEG_NAME] + name_offset; - if (*((INT *)namedata) == -1) { - *((INT *)namedata) = typeinfo->typelib->typelib_typeinfo_offsets[typeinfo->typeinfo->typekind >> 16]; - if(typeinfo->typekind == TKIND_MODULE) - namedata[9] |= 0x10; - } else - namedata[9] &= ~0x10; - - if(typeinfo->typekind == TKIND_MODULE) - namedata[9] |= 0x20; - - if (func->args) - { - i = 0; - LIST_FOR_EACH_ENTRY( arg, func->args, var_t, entry ) - { - /* don't give the last arg of a [propput*] func a name */ - if(i != num_params - 1 || (invokekind != 0x4 /* INVOKE_PROPERTYPUT */ && invokekind != 0x8 /* INVOKE_PROPERTYPUTREF */)) - { - int *paramdata = typedata + 6 + extra_attr + (num_defaults ? num_params : 0) + i * 3; - offset = ctl2_alloc_name(typeinfo->typelib, arg->name); - paramdata[1] = offset; - } - i++; - } - } - return S_OK; -} - -static HRESULT add_var_desc(msft_typeinfo_t *typeinfo, UINT index, var_t* var) -{ - int offset, id; - unsigned int typedata_size; - INT *typedata; - int var_datawidth; - int var_alignment; - int var_type_size, var_kind = 0 /* VAR_PERINSTANCE */; - int alignment; - int varflags = 0; - const attr_t *attr; - char *namedata; - int var_num = (typeinfo->typeinfo->cElement >> 16) & 0xffff; - - chat("add_var_desc(%d, %s)\n", index, var->name); - - id = 0x40000000 + index; - - if (var->attrs) LIST_FOR_EACH_ENTRY( attr, var->attrs, const attr_t, entry ) { - expr_t *expr = attr->u.pval; - switch(attr->type) { - case ATTR_HIDDEN: - varflags |= 0x40; /* VARFLAG_FHIDDEN */ - break; - case ATTR_ID: - id = expr->cval; - break; - case ATTR_READONLY: - varflags |= 0x01; /* VARFLAG_FREADONLY */ - break; - case ATTR_RESTRICTED: - varflags |= 0x80; /* VARFLAG_FRESTRICTED */ - break; - case ATTR_SOURCE: - varflags |= 0x02; /* VARFLAG_FSOURCE */ - break; - default: - warning("AddVarDesc: unhandled attr type %d\n", attr->type); - break; - } - } - - /* allocate type data space for us */ - typedata_size = 0x14; - - if (!typeinfo->var_data) { - typeinfo->var_data = xmalloc(0x100); - typeinfo->var_data_allocated = 0x100; - typeinfo->var_data[0] = 0; - } - - if(typeinfo->var_data[0] + typedata_size + sizeof(int) > typeinfo->var_data_allocated) { - typeinfo->var_data_allocated = max(typeinfo->var_data_allocated * 2, - typeinfo->var_data[0] + typedata_size + sizeof(int)); - typeinfo->var_data = xrealloc(typeinfo->var_data, typeinfo->var_data_allocated); - } - - offset = typeinfo->var_data[0]; - typeinfo->var_data[0] += typedata_size; - typedata = typeinfo->var_data + (offset >> 2) + 1; - - /* fill out the basic type information */ - typedata[0] = typedata_size | (index << 16); - typedata[2] = varflags; - typedata[3] = (36 /*sizeof(VARDESC)*/ << 16) | 0; - - if(typeinfo->vars_allocated == 0) { - typeinfo->vars_allocated = 10; - typeinfo->var_indices = xmalloc(typeinfo->vars_allocated * sizeof(int)); - typeinfo->var_names = xmalloc(typeinfo->vars_allocated * sizeof(int)); - typeinfo->var_offsets = xmalloc(typeinfo->vars_allocated * sizeof(int)); - } - if(typeinfo->vars_allocated == var_num) { - typeinfo->vars_allocated *= 2; - typeinfo->var_indices = xrealloc(typeinfo->var_indices, typeinfo->vars_allocated * sizeof(int)); - typeinfo->var_names = xrealloc(typeinfo->var_names, typeinfo->vars_allocated * sizeof(int)); - typeinfo->var_offsets = xrealloc(typeinfo->var_offsets, typeinfo->vars_allocated * sizeof(int)); - } - /* update the index data */ - typeinfo->var_indices[var_num] = id; - typeinfo->var_names[var_num] = -1; - typeinfo->var_offsets[var_num] = offset; - - /* figure out type widths and whatnot */ - encode_var(typeinfo->typelib, var->type, var, &typedata[1], &var_datawidth, - &var_alignment, &var_type_size); - - /* pad out starting position to data width */ - typeinfo->datawidth += var_alignment - 1; - typeinfo->datawidth &= ~(var_alignment - 1); - - switch(typeinfo->typekind) { - case TKIND_ENUM: - write_value(typeinfo->typelib, &typedata[4], VT_I4, &var->eval->cval); - var_kind = 2; /* VAR_CONST */ - var_type_size += 16; /* sizeof(VARIANT) */ - typeinfo->datawidth = var_datawidth; - break; - case TKIND_RECORD: - typedata[4] = typeinfo->datawidth; - typeinfo->datawidth += var_datawidth; - break; - case TKIND_DISPATCH: - var_kind = 3; /* VAR_DISPATCH */ - typeinfo->datawidth = 4; - var_alignment = 4; - break; - default: - error("add_var_desc: unhandled type kind %d\n", typeinfo->typekind); - break; - } - - /* add type description size to total required allocation */ - typedata[3] += var_type_size << 16 | var_kind; - - /* fix type alignment */ - alignment = (typeinfo->typeinfo->typekind >> 11) & 0x1f; - if (alignment < var_alignment) { - alignment = var_alignment; - typeinfo->typeinfo->typekind &= ~0xffc0; - typeinfo->typeinfo->typekind |= alignment << 11 | alignment << 6; - } - - /* ??? */ - if (!typeinfo->typeinfo->res2) typeinfo->typeinfo->res2 = 0x1a; - if ((index == 0) || (index == 1) || (index == 2) || (index == 4) || (index == 9)) { - typeinfo->typeinfo->res2 <<= 1; - } - - /* ??? */ - if (typeinfo->typeinfo->res3 == -1) typeinfo->typeinfo->res3 = 0; - typeinfo->typeinfo->res3 += 0x2c; - - /* increment the number of variable elements */ - typeinfo->typeinfo->cElement += 0x10000; - - /* pad data width to alignment */ - typeinfo->typeinfo->size = (typeinfo->datawidth + (alignment - 1)) & ~(alignment - 1); - - offset = ctl2_alloc_name(typeinfo->typelib, var->name); - if (offset == -1) return E_OUTOFMEMORY; - - namedata = typeinfo->typelib->typelib_segment_data[MSFT_SEG_NAME] + offset; - if (*((INT *)namedata) == -1) { - *((INT *)namedata) = typeinfo->typelib->typelib_typeinfo_offsets[typeinfo->typeinfo->typekind >> 16]; - if(typeinfo->typekind != TKIND_DISPATCH) - namedata[9] |= 0x10; - } else - namedata[9] &= ~0x10; - - if (typeinfo->typekind == TKIND_ENUM) { - namedata[9] |= 0x20; - } - typeinfo->var_names[var_num] = offset; - - return S_OK; -} - -static HRESULT add_impl_type(msft_typeinfo_t *typeinfo, type_t *ref, importinfo_t *importinfo) -{ - if(importinfo) { - alloc_importinfo(typeinfo->typelib, importinfo); - typeinfo->typeinfo->datatype1 = importinfo->offset+1; - }else { - if(ref->typelib_idx == -1) - add_interface_typeinfo(typeinfo->typelib, ref); - if(ref->typelib_idx == -1) - error("add_impl_type: unable to add inherited interface\n"); - - typeinfo->typeinfo->datatype1 = typeinfo->typelib->typelib_typeinfo_offsets[ref->typelib_idx]; - } - - typeinfo->typeinfo->cImplTypes++; - return S_OK; -} - -static msft_typeinfo_t *create_msft_typeinfo(msft_typelib_t *typelib, enum type_kind kind, - const char *name, const attr_list_t *attrs) -{ - const attr_t *attr; - msft_typeinfo_t *msft_typeinfo; - int nameoffset; - int typeinfo_offset; - MSFT_TypeInfoBase *typeinfo; - MSFT_GuidEntry guidentry; - - chat("create_msft_typeinfo: name %s kind %d\n", name, kind); - - msft_typeinfo = xmalloc(sizeof(*msft_typeinfo)); - memset( msft_typeinfo, 0, sizeof(*msft_typeinfo) ); - - msft_typeinfo->typelib = typelib; - - nameoffset = ctl2_alloc_name(typelib, name); - typeinfo_offset = ctl2_alloc_typeinfo(typelib, nameoffset); - typeinfo = (MSFT_TypeInfoBase *)&typelib->typelib_segment_data[MSFT_SEG_TYPEINFO][typeinfo_offset]; - - typelib->typelib_segment_data[MSFT_SEG_NAME][nameoffset + 9] = 0x38; - *((int *)&typelib->typelib_segment_data[MSFT_SEG_NAME][nameoffset]) = typeinfo_offset; - - msft_typeinfo->typekind = kind; - msft_typeinfo->typeinfo = typeinfo; - - typeinfo->typekind |= kind | 0x20; - - if(kind == TKIND_COCLASS) - typeinfo->flags |= 0x2; /* TYPEFLAG_FCANCREATE */ - - if (attrs) LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry ) { - switch(attr->type) { - case ATTR_AGGREGATABLE: - if (kind == TKIND_COCLASS) - typeinfo->flags |= 0x400; /* TYPEFLAG_FAGGREGATABLE */ - break; - - case ATTR_APPOBJECT: - if (kind == TKIND_COCLASS) - typeinfo->flags |= 0x1; /* TYPEFLAG_FAPPOBJECT */ - break; - - case ATTR_CONTROL: - if (kind == TKIND_COCLASS) - typeinfo->flags |= 0x20; /* TYPEFLAG_FCONTROL */ - break; - - case ATTR_DISPINTERFACE: - break; - - case ATTR_DLLNAME: - { - int offset = ctl2_alloc_string(typelib, attr->u.pval); - typeinfo->datatype1 = offset; - break; - } - - case ATTR_DUAL: - /* FIXME: check interface is compatible */ - typeinfo->typekind = (typeinfo->typekind & ~0xff) | 0x34; - typeinfo->flags |= 0x140; /* TYPEFLAG_FDUAL | TYPEFLAG_FOLEAUTOMATION */ - break; - - case ATTR_HELPCONTEXT: - { - expr_t *expr = (expr_t*)attr->u.pval; - typeinfo->helpcontext = expr->cval; - break; - } - case ATTR_HELPSTRING: - { - int offset = ctl2_alloc_string(typelib, attr->u.pval); - if (offset == -1) break; - typeinfo->docstringoffs = offset; - break; - } - case ATTR_HELPSTRINGCONTEXT: - { - expr_t *expr = (expr_t*)attr->u.pval; - typeinfo->helpstringcontext = expr->cval; - break; - } - case ATTR_HIDDEN: - typeinfo->flags |= 0x10; /* TYPEFLAG_FHIDDEN */ - break; - - case ATTR_NONCREATABLE: - typeinfo->flags &= ~0x2; /* TYPEFLAG_FCANCREATE */ - break; - - case ATTR_NONEXTENSIBLE: - typeinfo->flags |= 0x80; /* TYPEFLAG_FNONEXTENSIBLE */ - break; - - case ATTR_OBJECT: - break; - - case ATTR_ODL: - break; - - case ATTR_OLEAUTOMATION: - typeinfo->flags |= 0x100; /* TYPEFLAG_FOLEAUTOMATION */ - break; - - case ATTR_PUBLIC: - break; - - case ATTR_RESTRICTED: - typeinfo->flags |= 0x200; /* TYPEFLAG_FRESTRICTED */ - break; - - case ATTR_UUID: - guidentry.guid = *(GUID*)attr->u.pval; - guidentry.hreftype = typelib->typelib_typeinfo_offsets[typeinfo->typekind >> 16]; - guidentry.next_hash = -1; - typeinfo->posguid = ctl2_alloc_guid(typelib, &guidentry); -#if 0 - if (IsEqualIID(guid, &IID_IDispatch)) { - typelib->typelib_header.dispatchpos = typelib->typelib_typeinfo_offsets[typeinfo->typekind >> 16]; - } -#endif - break; - - case ATTR_VERSION: - typeinfo->version = attr->u.ival; - break; - - default: - warning("create_msft_typeinfo: ignoring attr %d\n", attr->type); - break; - } - } - - if (typelib->last_typeinfo) typelib->last_typeinfo->next_typeinfo = msft_typeinfo; - typelib->last_typeinfo = msft_typeinfo; - if (!typelib->typeinfos) typelib->typeinfos = msft_typeinfo; - - - return msft_typeinfo; -} - -static void add_dispatch(msft_typelib_t *typelib) -{ - int guid_offset, impfile_offset; - MSFT_GuidEntry guidentry; - MSFT_ImpInfo impinfo; - GUID stdole = {0x00020430,0x0000,0x0000,{0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}}; - GUID iid_idispatch = {0x00020400,0x0000,0x0000,{0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}}; - - if(typelib->typelib_header.dispatchpos != -1) return; - - guidentry.guid = stdole; - guidentry.hreftype = 2; - guidentry.next_hash = -1; - guid_offset = ctl2_alloc_guid(typelib, &guidentry); - impfile_offset = alloc_importfile(typelib, guid_offset, 2, 0, "stdole2.tlb"); - - guidentry.guid = iid_idispatch; - guidentry.hreftype = 1; - guidentry.next_hash = -1; - impinfo.flags = TKIND_INTERFACE << 24 | MSFT_IMPINFO_OFFSET_IS_GUID; - impinfo.oImpFile = impfile_offset; - impinfo.oGuid = ctl2_alloc_guid(typelib, &guidentry); - typelib->typelib_header.dispatchpos = alloc_msft_importinfo(typelib, &impinfo) | 0x01; -} - -static void add_dispinterface_typeinfo(msft_typelib_t *typelib, type_t *dispinterface) -{ - int idx = 0; - const func_t *func; - var_t *var; - msft_typeinfo_t *msft_typeinfo; - - if (-1 < dispinterface->typelib_idx) - return; - - dispinterface->typelib_idx = typelib->typelib_header.nrtypeinfos; - msft_typeinfo = create_msft_typeinfo(typelib, TKIND_DISPATCH, dispinterface->name, - dispinterface->attrs); - - msft_typeinfo->typeinfo->size = 4; - msft_typeinfo->typeinfo->typekind |= 0x2100; - - msft_typeinfo->typeinfo->flags |= 0x1000; /* TYPEFLAG_FDISPATCHABLE */ - add_dispatch(typelib); - msft_typeinfo->typeinfo->cImplTypes = 1; - - /* count the no of funcs, as the variable indices come after the funcs */ - if (dispinterface->funcs) - LIST_FOR_EACH_ENTRY( func, dispinterface->funcs, const func_t, entry ) idx++; - - if (dispinterface->fields) - LIST_FOR_EACH_ENTRY( var, dispinterface->fields, var_t, entry ) - add_var_desc(msft_typeinfo, idx++, var); - - if (dispinterface->funcs) - { - idx = 0; - LIST_FOR_EACH_ENTRY( func, dispinterface->funcs, const func_t, entry ) - if(add_func_desc(msft_typeinfo, func, idx) == S_OK) - idx++; - } -} - -static void add_interface_typeinfo(msft_typelib_t *typelib, type_t *interface) -{ - int idx = 0; - const func_t *func; - type_t *ref; - msft_typeinfo_t *msft_typeinfo; - importinfo_t *ref_importinfo = NULL; - int num_parents = 0, num_funcs = 0; - const type_t *derived; - - if (-1 < interface->typelib_idx) - return; - - if (is_attr(interface->attrs, ATTR_DISPINTERFACE)) - return add_dispinterface_typeinfo(typelib, interface); - - /* midl adds the parent interface first, unless the parent itself - has no parent (i.e. it stops before IUnknown). */ - - if(interface->ref) { - ref_importinfo = find_importinfo(typelib, interface->ref->name); - - if(!ref_importinfo && interface->ref->ref && interface->ref->typelib_idx == -1) - add_interface_typeinfo(typelib, interface->ref); - } - - interface->typelib_idx = typelib->typelib_header.nrtypeinfos; - msft_typeinfo = create_msft_typeinfo(typelib, TKIND_INTERFACE, interface->name, interface->attrs); - msft_typeinfo->typeinfo->size = 4; - msft_typeinfo->typeinfo->typekind |= 0x2200; - - for (derived = interface->ref; derived; derived = derived->ref) - if (derived->name && !strcmp(derived->name, "IDispatch")) - msft_typeinfo->typeinfo->flags |= 0x1000; /* TYPEFLAG_FDISPATCHABLE */ - - /* can't be dual if it doesn't derive from IDispatch */ - if (!(msft_typeinfo->typeinfo->flags & 0x1000)) /* TYPEFLAG_FDISPATCHABLE */ - msft_typeinfo->typeinfo->flags &= ~0x40; /* TYPEFLAG_FDUAL */ - - if(interface->ref) - add_impl_type(msft_typeinfo, interface->ref, ref_importinfo); - - /* count the number of inherited interfaces and non-local functions */ - for(ref = interface->ref; ref; ref = ref->ref) { - num_parents++; - if (ref->funcs) - LIST_FOR_EACH_ENTRY( func, ref->funcs, const func_t, entry ) - if (!is_local(func->def->attrs)) num_funcs++; - } - msft_typeinfo->typeinfo->datatype2 = num_funcs << 16 | num_parents; - msft_typeinfo->typeinfo->cbSizeVft = num_funcs * 4; - - if (interface->funcs) - LIST_FOR_EACH_ENTRY( func, interface->funcs, const func_t, entry ) - if(add_func_desc(msft_typeinfo, func, idx) == S_OK) - idx++; -} - -static void add_structure_typeinfo(msft_typelib_t *typelib, type_t *structure) -{ - int idx = 0; - var_t *cur; - msft_typeinfo_t *msft_typeinfo; - - if (-1 < structure->typelib_idx) - return; - - structure->typelib_idx = typelib->typelib_header.nrtypeinfos; - msft_typeinfo = create_msft_typeinfo(typelib, TKIND_RECORD, structure->name, structure->attrs); - msft_typeinfo->typeinfo->size = 0; - - if (structure->fields) - LIST_FOR_EACH_ENTRY( cur, structure->fields, var_t, entry ) - add_var_desc(msft_typeinfo, idx++, cur); -} - -static void add_enum_typeinfo(msft_typelib_t *typelib, type_t *enumeration) -{ - int idx = 0; - var_t *cur; - msft_typeinfo_t *msft_typeinfo; - - enumeration->typelib_idx = typelib->typelib_header.nrtypeinfos; - msft_typeinfo = create_msft_typeinfo(typelib, TKIND_ENUM, enumeration->name, enumeration->attrs); - msft_typeinfo->typeinfo->size = 0; - - if (enumeration->fields) - LIST_FOR_EACH_ENTRY( cur, enumeration->fields, var_t, entry ) - add_var_desc(msft_typeinfo, idx++, cur); -} - -static void add_typedef_typeinfo(msft_typelib_t *typelib, type_t *tdef) -{ - msft_typeinfo_t *msft_typeinfo; - int alignment; - - if (-1 < tdef->typelib_idx) - return; - - tdef->typelib_idx = typelib->typelib_header.nrtypeinfos; - msft_typeinfo = create_msft_typeinfo(typelib, TKIND_ALIAS, tdef->name, tdef->attrs); - encode_type(typelib, get_type_vt(tdef->orig), tdef->orig, &msft_typeinfo->typeinfo->datatype1, &msft_typeinfo->typeinfo->size, - &alignment, &msft_typeinfo->typeinfo->datatype2); - msft_typeinfo->typeinfo->typekind |= (alignment << 11 | alignment << 6); -} - -static void add_coclass_typeinfo(msft_typelib_t *typelib, type_t *cls) -{ - msft_typeinfo_t *msft_typeinfo; - ifref_t *iref; - int num_ifaces = 0, offset, i; - MSFT_RefRecord *ref, *first = NULL, *first_source = NULL; - int have_default = 0, have_default_source = 0; - const attr_t *attr; - - if (-1 < cls->typelib_idx) - return; - - cls->typelib_idx = typelib->typelib_header.nrtypeinfos; - msft_typeinfo = create_msft_typeinfo(typelib, TKIND_COCLASS, cls->name, cls->attrs); - - if (cls->ifaces) LIST_FOR_EACH_ENTRY( iref, cls->ifaces, ifref_t, entry ) num_ifaces++; - - offset = msft_typeinfo->typeinfo->datatype1 = ctl2_alloc_segment(typelib, MSFT_SEG_REFERENCES, - num_ifaces * sizeof(*ref), 0); - - i = 0; - if (cls->ifaces) LIST_FOR_EACH_ENTRY( iref, cls->ifaces, ifref_t, entry ) { - if(iref->iface->typelib_idx == -1) - add_interface_typeinfo(typelib, iref->iface); - ref = (MSFT_RefRecord*) (typelib->typelib_segment_data[MSFT_SEG_REFERENCES] + offset + i * sizeof(*ref)); - ref->reftype = typelib->typelib_typeinfo_offsets[iref->iface->typelib_idx]; - ref->flags = 0; - ref->oCustData = -1; - ref->onext = -1; - if(i < num_ifaces - 1) - ref->onext = offset + (i + 1) * sizeof(*ref); - - if (iref->attrs) LIST_FOR_EACH_ENTRY( attr, iref->attrs, const attr_t, entry ) { - switch(attr->type) { - case ATTR_DEFAULT: - ref->flags |= 0x1; /* IMPLTYPEFLAG_FDEFAULT */ - break; - case ATTR_RESTRICTED: - ref->flags |= 0x4; /* IMPLTYPEFLAG_FRESTRICTED */ - break; - case ATTR_SOURCE: - ref->flags |= 0x2; /* IMPLTYPEFLAG_FSOURCE */ - break; - default: - warning("add_coclass_typeinfo: unhandled attr %d\n", attr->type); - } - } - if(ref->flags & 0x1) { /* IMPLTYPEFLAG_FDEFAULT */ - if(ref->flags & 0x2) /* IMPLTYPEFLAG_SOURCE */ - have_default_source = 1; - else - have_default = 1; - } - - /* If the interface is non-restricted and we haven't already had one then - remember it so that we can use it as a default later */ - if((ref->flags & 0x4) == 0) { /* IMPLTYPEFLAG_FRESTRICTED */ - if(ref->flags & 0x2) { /* IMPLTYPEFLAG_FSOURCE */ - if(!first_source) - first_source = ref; - } - else if(!first) - first = ref; - } - i++; - } - - /* If we haven't had a default interface, then set the default flags on the - first ones */ - if(!have_default && first) - first->flags |= 0x1; - if(!have_default_source && first_source) - first_source->flags |= 0x1; - - msft_typeinfo->typeinfo->cImplTypes = num_ifaces; - msft_typeinfo->typeinfo->size = 4; - msft_typeinfo->typeinfo->typekind |= 0x2200; -} - -static void add_module_typeinfo(msft_typelib_t *typelib, type_t *module) -{ - int idx = 0; - const func_t *func; - msft_typeinfo_t *msft_typeinfo; - - if (-1 < module->typelib_idx) - return; - - module->typelib_idx = typelib->typelib_header.nrtypeinfos; - msft_typeinfo = create_msft_typeinfo(typelib, TKIND_MODULE, module->name, module->attrs); - msft_typeinfo->typeinfo->typekind |= 0x0a00; - - if (module->funcs) - LIST_FOR_EACH_ENTRY( func, module->funcs, const func_t, entry ) - if(add_func_desc(msft_typeinfo, func, idx) == S_OK) - idx++; - - msft_typeinfo->typeinfo->size = idx; -} - -static void add_entry(msft_typelib_t *typelib, typelib_entry_t *entry) -{ - switch(entry->type->kind) { - case TKIND_INTERFACE: - case TKIND_DISPATCH: - add_interface_typeinfo(typelib, entry->type); - break; - - case TKIND_RECORD: - add_structure_typeinfo(typelib, entry->type); - break; - - case TKIND_ENUM: - add_enum_typeinfo(typelib, entry->type); - break; - - case TKIND_ALIAS: - add_typedef_typeinfo(typelib, entry->type); - break; - - case TKIND_COCLASS: - add_coclass_typeinfo(typelib, entry->type); - break; - - case TKIND_MODULE: - add_module_typeinfo(typelib, entry->type); - break; - - default: - error("add_entry: unhandled type %d\n", entry->type->kind); - break; - } -} - -static void set_name(msft_typelib_t *typelib) -{ - int offset; - - offset = ctl2_alloc_name(typelib, typelib->typelib->name); - if (offset == -1) return; - typelib->typelib_header.NameOffset = offset; - return; -} - -static void set_version(msft_typelib_t *typelib) -{ - typelib->typelib_header.version = get_attrv( typelib->typelib->attrs, ATTR_VERSION ); -} - -static void set_guid(msft_typelib_t *typelib) -{ - MSFT_GuidEntry guidentry; - int offset; - void *ptr; - GUID guid = {0,0,0,{0,0,0,0,0,0}}; - - guidentry.guid = guid; - guidentry.hreftype = -2; - guidentry.next_hash = -1; - - ptr = get_attrp( typelib->typelib->attrs, ATTR_UUID ); - if (ptr) guidentry.guid = *(GUID *)ptr; - - offset = ctl2_alloc_guid(typelib, &guidentry); - typelib->typelib_header.posguid = offset; - - return; -} - -static void set_doc_string(msft_typelib_t *typelib) -{ - char *str = get_attrp( typelib->typelib->attrs, ATTR_HELPSTRING ); - - if (str) - { - int offset = ctl2_alloc_string(typelib, str); - if (offset != -1) typelib->typelib_header.helpstring = offset; - } -} - -static void set_help_file_name(msft_typelib_t *typelib) -{ - char *str = get_attrp( typelib->typelib->attrs, ATTR_HELPFILE ); - - if (str) - { - int offset = ctl2_alloc_string(typelib, str); - if (offset != -1) - { - typelib->typelib_header.helpfile = offset; - typelib->typelib_header.varflags |= 0x10; - } - } -} - -static void set_help_context(msft_typelib_t *typelib) -{ - const expr_t *expr = get_attrp( typelib->typelib->attrs, ATTR_HELPCONTEXT ); - if (expr) typelib->typelib_header.helpcontext = expr->cval; -} - -static void set_help_string_dll(msft_typelib_t *typelib) -{ - char *str = get_attrp( typelib->typelib->attrs, ATTR_HELPSTRINGDLL ); - - if (str) - { - int offset = ctl2_alloc_string(typelib, str); - if (offset != -1) - { - typelib->help_string_dll_offset = offset; - typelib->typelib_header.varflags |= 0x100; - } - } -} - -static void set_help_string_context(msft_typelib_t *typelib) -{ - const expr_t *expr = get_attrp( typelib->typelib->attrs, ATTR_HELPSTRINGCONTEXT ); - if (expr) typelib->typelib_header.helpstringcontext = expr->cval; -} - -static void set_lcid(msft_typelib_t *typelib) -{ - typelib->typelib_header.lcid2 = 0x0; - return; -} - -static void set_lib_flags(msft_typelib_t *typelib) -{ - const attr_t *attr; - - typelib->typelib_header.flags = 0; - if (!typelib->typelib->attrs) return; - LIST_FOR_EACH_ENTRY( attr, typelib->typelib->attrs, const attr_t, entry ) - { - switch(attr->type) { - case ATTR_CONTROL: - typelib->typelib_header.flags |= 0x02; /* LIBFLAG_FCONTROL */ - break; - case ATTR_HIDDEN: - typelib->typelib_header.flags |= 0x04; /* LIBFLAG_FHIDDEN */ - break; - case ATTR_RESTRICTED: - typelib->typelib_header.flags |= 0x01; /* LIBFLAG_FRESTRICTED */ - break; - default: - break; - } - } - return; -} - -static int ctl2_write_chunk(int fd, void *segment, int length) -{ - if (write(fd, segment, length) != length) { - close(fd); - return 0; - } - return -1; -} - -static int ctl2_write_segment(msft_typelib_t *typelib, int fd, int segment) -{ - if (write(fd, typelib->typelib_segment_data[segment], typelib->typelib_segdir[segment].length) - != typelib->typelib_segdir[segment].length) { - close(fd); - return 0; - } - - return -1; -} - -static void ctl2_finalize_typeinfos(msft_typelib_t *typelib, int filesize) -{ - msft_typeinfo_t *typeinfo; - - for (typeinfo = typelib->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) { - typeinfo->typeinfo->memoffset = filesize; - if (typeinfo->func_data) - filesize += typeinfo->func_data[0] + ((typeinfo->typeinfo->cElement & 0xffff) * 12); - if (typeinfo->var_data) - filesize += typeinfo->var_data[0] + (((typeinfo->typeinfo->cElement >> 16) & 0xffff) * 12); - if (typeinfo->func_data || typeinfo->var_data) - filesize += 4; - } -} - -static int ctl2_finalize_segment(msft_typelib_t *typelib, int filepos, int segment) -{ - if (typelib->typelib_segdir[segment].length) { - typelib->typelib_segdir[segment].offset = filepos; - } else { - typelib->typelib_segdir[segment].offset = -1; - } - - return typelib->typelib_segdir[segment].length; -} - - -static void ctl2_write_typeinfos(msft_typelib_t *typelib, int fd) -{ - msft_typeinfo_t *typeinfo; - int typedata_size; - - for (typeinfo = typelib->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) { - if (!typeinfo->func_data && !typeinfo->var_data) continue; - typedata_size = 0; - if (typeinfo->func_data) - typedata_size = typeinfo->func_data[0]; - if (typeinfo->var_data) - typedata_size += typeinfo->var_data[0]; - ctl2_write_chunk(fd, &typedata_size, sizeof(int)); - if (typeinfo->func_data) - ctl2_write_chunk(fd, typeinfo->func_data + 1, typeinfo->func_data[0]); - if (typeinfo->var_data) - ctl2_write_chunk(fd, typeinfo->var_data + 1, typeinfo->var_data[0]); - if (typeinfo->func_indices) - ctl2_write_chunk(fd, typeinfo->func_indices, (typeinfo->typeinfo->cElement & 0xffff) * 4); - if (typeinfo->var_indices) - ctl2_write_chunk(fd, typeinfo->var_indices, (typeinfo->typeinfo->cElement >> 16) * 4); - if (typeinfo->func_names) - ctl2_write_chunk(fd, typeinfo->func_names, (typeinfo->typeinfo->cElement & 0xffff) * 4); - if (typeinfo->var_names) - ctl2_write_chunk(fd, typeinfo->var_names, (typeinfo->typeinfo->cElement >> 16) * 4); - if (typeinfo->func_offsets) - ctl2_write_chunk(fd, typeinfo->func_offsets, (typeinfo->typeinfo->cElement & 0xffff) * 4); - if (typeinfo->var_offsets) { - int add = 0, i, offset; - if(typeinfo->func_data) - add = typeinfo->func_data[0]; - for(i = 0; i < (typeinfo->typeinfo->cElement >> 16); i++) { - offset = typeinfo->var_offsets[i]; - offset += add; - ctl2_write_chunk(fd, &offset, 4); - } - } - } -} - -static int save_all_changes(msft_typelib_t *typelib) -{ - int retval; - int filepos; - int fd; - - chat("save_all_changes(%p)\n", typelib); - - retval = TYPE_E_IOERROR; - - fd = creat(typelib->typelib->filename, 0666); - if (fd == -1) return retval; - - filepos = sizeof(MSFT_Header) + sizeof(MSFT_SegDir); - if(typelib->typelib_header.varflags & 0x100) filepos += 4; /* helpstringdll */ - filepos += typelib->typelib_header.nrtypeinfos * 4; - - filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_TYPEINFO); - filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_GUIDHASH); - filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_GUID); - filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_REFERENCES); - filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_IMPORTINFO); - filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_IMPORTFILES); - filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_NAMEHASH); - filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_NAME); - filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_STRING); - filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_TYPEDESC); - filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_ARRAYDESC); - filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_CUSTDATA); - filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_CUSTDATAGUID); - - ctl2_finalize_typeinfos(typelib, filepos); - - if (!ctl2_write_chunk(fd, &typelib->typelib_header, sizeof(typelib->typelib_header))) return retval; - if(typelib->typelib_header.varflags & 0x100) - if (!ctl2_write_chunk(fd, &typelib->help_string_dll_offset, sizeof(typelib->help_string_dll_offset))) - return retval; - - if (!ctl2_write_chunk(fd, typelib->typelib_typeinfo_offsets, typelib->typelib_header.nrtypeinfos * 4)) return retval; - if (!ctl2_write_chunk(fd, &typelib->typelib_segdir, sizeof(typelib->typelib_segdir))) return retval; - if (!ctl2_write_segment(typelib, fd, MSFT_SEG_TYPEINFO )) return retval; - if (!ctl2_write_segment(typelib, fd, MSFT_SEG_GUIDHASH )) return retval; - if (!ctl2_write_segment(typelib, fd, MSFT_SEG_GUID )) return retval; - if (!ctl2_write_segment(typelib, fd, MSFT_SEG_REFERENCES )) return retval; - if (!ctl2_write_segment(typelib, fd, MSFT_SEG_IMPORTINFO )) return retval; - if (!ctl2_write_segment(typelib, fd, MSFT_SEG_IMPORTFILES )) return retval; - if (!ctl2_write_segment(typelib, fd, MSFT_SEG_NAMEHASH )) return retval; - if (!ctl2_write_segment(typelib, fd, MSFT_SEG_NAME )) return retval; - if (!ctl2_write_segment(typelib, fd, MSFT_SEG_STRING )) return retval; - if (!ctl2_write_segment(typelib, fd, MSFT_SEG_TYPEDESC )) return retval; - if (!ctl2_write_segment(typelib, fd, MSFT_SEG_ARRAYDESC )) return retval; - if (!ctl2_write_segment(typelib, fd, MSFT_SEG_CUSTDATA )) return retval; - if (!ctl2_write_segment(typelib, fd, MSFT_SEG_CUSTDATAGUID)) return retval; - - ctl2_write_typeinfos(typelib, fd); - - if (close(fd) == -1) return retval; - - retval = S_OK; - return retval; -} - -int create_msft_typelib(typelib_t *typelib) -{ - msft_typelib_t *msft; - int failed = 0; - typelib_entry_t *entry; - time_t cur_time; - char *time_override; - unsigned int version = 5 << 24 | 1 << 16 | 164; /* 5.01.0164 */ - GUID midl_time_guid = {0xde77ba63,0x517c,0x11d1,{0xa2,0xda,0x00,0x00,0xf8,0x77,0x3c,0xe9}}; - GUID midl_version_guid = {0xde77ba64,0x517c,0x11d1,{0xa2,0xda,0x00,0x00,0xf8,0x77,0x3c,0xe9}}; - - msft = xmalloc(sizeof(*msft)); - memset(msft, 0, sizeof(*msft)); - msft->typelib = typelib; - - ctl2_init_header(msft); - ctl2_init_segdir(msft); - - msft->typelib_header.varflags |= SYS_WIN32; - - /* - * The following two calls return an offset or -1 if out of memory. We - * specifically need an offset of 0, however, so... - */ - if (ctl2_alloc_segment(msft, MSFT_SEG_GUIDHASH, 0x80, 0x80)) { failed = 1; } - if (ctl2_alloc_segment(msft, MSFT_SEG_NAMEHASH, 0x200, 0x200)) { failed = 1; } - - if(failed) - { - free(msft); - return 0; - } - - msft->typelib_guidhash_segment = (int *)msft->typelib_segment_data[MSFT_SEG_GUIDHASH]; - msft->typelib_namehash_segment = (int *)msft->typelib_segment_data[MSFT_SEG_NAMEHASH]; - - memset(msft->typelib_guidhash_segment, 0xff, 0x80); - memset(msft->typelib_namehash_segment, 0xff, 0x200); - - set_lib_flags(msft); - set_lcid(msft); - set_help_file_name(msft); - set_doc_string(msft); - set_guid(msft); - set_version(msft); - set_name(msft); - set_help_context(msft); - set_help_string_dll(msft); - set_help_string_context(msft); - - /* midl adds two sets of custom data to the library: the current unix time - and midl's version number */ - time_override = getenv( "WIDL_TIME_OVERRIDE"); - cur_time = time_override ? atol( time_override) : time(NULL); - set_custdata(msft, &midl_time_guid, VT_UI4, &cur_time, &msft->typelib_header.CustomDataOffset); - set_custdata(msft, &midl_version_guid, VT_UI4, &version, &msft->typelib_header.CustomDataOffset); - - LIST_FOR_EACH_ENTRY( entry, &typelib->entries, typelib_entry_t, entry ) - add_entry(msft, entry); - - save_all_changes(msft); - free(msft); - return 1; -} diff --git a/reactos/tools/widl_new/0.9.44.1 - Handle LPSTR in typelibs.diff b/reactos/tools/widl_new/0.9.44.1 - Handle LPSTR in typelibs.diff deleted file mode 100644 index e305eb1cf3c..00000000000 --- a/reactos/tools/widl_new/0.9.44.1 - Handle LPSTR in typelibs.diff +++ /dev/null @@ -1,53 +0,0 @@ ---- typelib.c Fri Aug 24 16:34:34 2007 -+++ typelib.c Wed Sep 05 09:39:09 2007 -@@ -126,8 +126,9 @@ - return strcmp(KWP(s1)->kw, KWP(s2)->kw); - } - --static unsigned short builtin_vt(const char *kw) -+static unsigned short builtin_vt(const type_t *t) - { -+ const char *kw = t->name; - struct oatype key, *kwp; - key.kw = kw; - #ifdef KW_BSEARCH -@@ -145,6 +146,13 @@ - if (kwp) { - return kwp->vt; - } -+ if (is_string_type (t->attrs, t)) -+ switch (t->ref->type) -+ { -+ case RPC_FC_CHAR: return VT_LPSTR; -+ case RPC_FC_WCHAR: return VT_LPWSTR; -+ default: break; -+ } - return 0; - } - -@@ -160,7 +168,7 @@ - - chat("get_type_vt: %p type->name %s\n", t, t->name); - if (t->name) { -- vt = builtin_vt(t->name); -+ vt = builtin_vt(t); - if (vt) return vt; - } - ---- write_msft.c Fri Aug 24 16:34:34 2007 -+++ write_msft.c Wed Sep 05 09:40:02 2007 -@@ -852,6 +852,13 @@ - *encoded_type = default_type; - break; - -+ case VT_LPSTR: -+ case VT_LPWSTR: -+ *encoded_type = 0xfffe0000 | vt; -+ *width = 4; -+ *alignment = 4; -+ break; -+ - case VT_PTR: - { - int next_vt; - diff --git a/reactos/tools/widl_new/0.9.44.2 - Handle the size_is attribute on pointers.diff b/reactos/tools/widl_new/0.9.44.2 - Handle the size_is attribute on pointers.diff deleted file mode 100644 index 224b1f2cd99..00000000000 --- a/reactos/tools/widl_new/0.9.44.2 - Handle the size_is attribute on pointers.diff +++ /dev/null @@ -1,11 +0,0 @@ ---- typelib.c Wed Sep 05 09:44:46 2007 -+++ typelib.c Wed Sep 05 09:45:29 2007 -@@ -206,6 +206,8 @@ - case RPC_FC_UP: - case RPC_FC_OP: - case RPC_FC_FP: -+ case RPC_FC_CARRAY: -+ case RPC_FC_CVARRAY: - if(t->ref) - { - if (match(t->ref->name, "SAFEARRAY")) diff --git a/reactos/tools/widl_new/0.9.44.3 - Constify some data.diff b/reactos/tools/widl_new/0.9.44.3 - Constify some data.diff deleted file mode 100644 index b7463f6f963..00000000000 --- a/reactos/tools/widl_new/0.9.44.3 - Constify some data.diff +++ /dev/null @@ -1,44 +0,0 @@ ---- typelib.c Wed Sep 05 09:46:05 2007 -+++ typelib.c Wed Sep 05 09:47:36 2007 -@@ -103,7 +103,7 @@ - /* List of oleauto types that should be recognized by name. - * (most of) these seem to be intrinsic types in mktyplib. */ - --static struct oatype { -+static const struct oatype { - const char *kw; - unsigned short vt; - } oatypes[] = { -@@ -129,7 +129,8 @@ - static unsigned short builtin_vt(const type_t *t) - { - const char *kw = t->name; -- struct oatype key, *kwp; -+ struct oatype key; -+ const struct oatype *kwp; - key.kw = kw; - #ifdef KW_BSEARCH - kwp = bsearch(&key, oatypes, NTYPES, sizeof(oatypes[0]), kw_cmp_func); ---- widl.c Fri Aug 24 16:34:34 2007 -+++ widl.c Wed Sep 05 09:47:20 2007 -@@ -49,7 +49,7 @@ - /* O = generate interpreted stubs */ - /* w = select win16/win32 output (?) */ - --static char usage[] = -+static const char usage[] = - "Usage: widl [options...] infile.idl\n" - " -c Generate client stub\n" - " -C file Name of client stub file (default is infile_c.c)\n" -@@ -133,9 +133,9 @@ - PREFIX_SERVER_OPTION - }; - --static const char *short_options = -+static const char short_options[] = - "cC:d:D:EhH:I:NpP:sS:tT:uU:VW"; --static struct option long_options[] = { -+static const struct option long_options[] = { - { "oldnames", no_argument, 0, OLDNAMES_OPTION }, - { "prefix-all", required_argument, 0, PREFIX_ALL_OPTION }, - { "prefix-client", required_argument, 0, PREFIX_CLIENT_OPTION }, diff --git a/reactos/tools/widl_new/0.9.44.4 - Fix top-level and callback conformances.diff b/reactos/tools/widl_new/0.9.44.4 - Fix top-level and callback conformances.diff deleted file mode 100644 index 5f0701a21e5..00000000000 --- a/reactos/tools/widl_new/0.9.44.4 - Fix top-level and callback conformances.diff +++ /dev/null @@ -1,238 +0,0 @@ ---- typegen.c Fri Aug 24 16:34:34 2007 -+++ typegen.c Wed Sep 05 09:59:19 2007 -@@ -46,16 +46,11 @@ - static const func_t *current_func; - static const type_t *current_structure; - --/* name of the structure variable for structure callbacks */ --#define STRUCT_EXPR_EVAL_VAR "pS" -- - static struct list expr_eval_routines = LIST_INIT(expr_eval_routines); -- - struct expr_eval_routine - { - struct list entry; - const type_t *structure; -- size_t structure_size; - const expr_t *expr; - }; - -@@ -496,9 +491,16 @@ - unsigned char operator_type = 0; - const char *operator_string = "no operators"; - const expr_t *subexpr; -- unsigned char correlation_type; - -- if (!file) return 4; /* optimisation for sizing pass */ -+ if (!structure) -+ { -+ /* Top-level conformance calculations are done inline. */ -+ print_file (file, 2, "0x%x,\t/* Corr desc: parameter */\n", -+ RPC_FC_TOP_LEVEL_CONFORMANCE); -+ print_file (file, 2, "0x0,\n"); -+ print_file (file, 2, "NdrFcShort(0x0),\n"); -+ return 4; -+ } - - if (expr->is_const) - { -@@ -565,53 +567,25 @@ - unsigned char correlation_variable_type; - unsigned char param_type = 0; - const char *param_type_string = NULL; -- size_t offset; -- -- if (structure) -- { -- const var_t *var; -- -- offset = 0; -- if (structure->fields) LIST_FOR_EACH_ENTRY( var, structure->fields, const var_t, entry ) -- { -- unsigned int align = 0; -- /* FIXME: take alignment into account */ -- if (var->name && !strcmp(var->name, subexpr->u.sval)) -- { -- correlation_variable = var->type; -- break; -- } -- offset += type_memsize(var->type, &align); -- } -- if (!correlation_variable) -- error("write_conf_or_var_desc: couldn't find variable %s in structure\n", -- subexpr->u.sval); -+ size_t offset = 0; -+ const var_t *var; - -- offset -= baseoff; -- correlation_type = RPC_FC_NORMAL_CONFORMANCE; -- } -- else -+ if (structure->fields) LIST_FOR_EACH_ENTRY( var, structure->fields, const var_t, entry ) - { -- const var_t *var; -- -- offset = sizeof(void *); -- if (func->args) LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) -+ unsigned int align = 0; -+ /* FIXME: take alignment into account */ -+ if (var->name && !strcmp(var->name, subexpr->u.sval)) - { -- if (!strcmp(var->name, subexpr->u.sval)) -- { -- correlation_variable = var->type; -- break; -- } -- /* FIXME: not all stack variables are sizeof(void *) */ -- offset += sizeof(void *); -+ correlation_variable = var->type; -+ break; - } -- if (!correlation_variable) -- error("write_conf_or_var_desc: couldn't find variable %s in function\n", -- subexpr->u.sval); -- -- correlation_type = RPC_FC_TOP_LEVEL_CONFORMANCE; -+ offset += type_memsize(var->type, &align); - } -+ if (!correlation_variable) -+ error("write_conf_or_var_desc: couldn't find variable %s in structure\n", -+ subexpr->u.sval); - -+ offset -= baseoff; - correlation_variable_type = correlation_variable->type; - - switch (correlation_variable_type) -@@ -665,60 +639,41 @@ - correlation_variable_type); - } - -- print_file(file, 2, "0x%x, /* Corr desc: %s%s */\n", -- correlation_type | param_type, -- correlation_type == RPC_FC_TOP_LEVEL_CONFORMANCE ? "parameter, " : "", -- param_type_string); -+ print_file(file, 2, "0x%x, /* Corr desc: %s */\n", -+ RPC_FC_NORMAL_CONFORMANCE | param_type, param_type_string); - print_file(file, 2, "0x%x, /* %s */\n", operator_type, operator_string); -- print_file(file, 2, "NdrFcShort(0x%x), /* %soffset = %d */\n", -- offset, -- correlation_type == RPC_FC_TOP_LEVEL_CONFORMANCE ? "x86 stack size / " : "", -- offset); -+ print_file(file, 2, "NdrFcShort(0x%x), /* offset = %d */\n", -+ offset, offset); - } - else - { - unsigned int callback_offset = 0; -+ struct expr_eval_routine *eval; -+ int found = 0; - -- if (structure) -+ LIST_FOR_EACH_ENTRY(eval, &expr_eval_routines, struct expr_eval_routine, entry) - { -- struct expr_eval_routine *eval; -- int found = 0; -- -- LIST_FOR_EACH_ENTRY(eval, &expr_eval_routines, struct expr_eval_routine, entry) -- { -- if (!strcmp(eval->structure->name, structure->name) && -- !compare_expr(eval->expr, expr)) -- { -- found = 1; -- break; -- } -- callback_offset++; -- } -- -- if (!found) -+ if (!strcmp (eval->structure->name, structure->name) -+ && !compare_expr (eval->expr, expr)) - { -- unsigned int align = 0; -- eval = xmalloc(sizeof(*eval)); -- eval->structure = structure; -- eval->structure_size = fields_memsize(structure->fields, &align); -- eval->expr = expr; -- list_add_tail(&expr_eval_routines, &eval->entry); -+ found = 1; -+ break; - } -- -- correlation_type = RPC_FC_NORMAL_CONFORMANCE; -+ callback_offset++; - } -- else -+ -+ if (!found) - { -- error("write_conf_or_var_desc: top-level callback conformance unimplemented\n"); -- correlation_type = RPC_FC_TOP_LEVEL_CONFORMANCE; -+ eval = xmalloc (sizeof(*eval)); -+ eval->structure = structure; -+ eval->expr = expr; -+ list_add_tail (&expr_eval_routines, &eval->entry); - } - - if (callback_offset > USHRT_MAX) - error("Maximum number of callback routines reached\n"); - -- print_file(file, 2, "0x%x, /* Corr desc: %s */\n", -- correlation_type, -- correlation_type == RPC_FC_TOP_LEVEL_CONFORMANCE ? "parameter" : ""); -+ print_file(file, 2, "0x%x, /* Corr desc: */\n", RPC_FC_NORMAL_CONFORMANCE); - print_file(file, 2, "0x%x, /* %s */\n", RPC_FC_CALLBACK, "FC_CALLBACK"); - print_file(file, 2, "NdrFcShort(0x%x), /* %u */\n", callback_offset, callback_offset); - } -@@ -2881,27 +2836,27 @@ - - int write_expr_eval_routines(FILE *file, const char *iface) - { -+ static const char *var_name = "pS"; - int result = 0; - struct expr_eval_routine *eval; - unsigned short callback_offset = 0; - - LIST_FOR_EACH_ENTRY(eval, &expr_eval_routines, struct expr_eval_routine, entry) - { -- int indent = 0; -+ const char *name = eval->structure->name; -+ const var_list_t *fields = eval->structure->fields; -+ unsigned align = 0; - result = 1; -- print_file(file, indent, "static void __RPC_USER %s_%sExprEval_%04u(PMIDL_STUB_MESSAGE pStubMsg)\n", -- iface, eval->structure->name, callback_offset); -- print_file(file, indent, "{\n"); -- indent++; -- print_file(file, indent, "struct %s *" STRUCT_EXPR_EVAL_VAR " = (struct %s *)(pStubMsg->StackTop - %u);\n", -- eval->structure->name, eval->structure->name, eval->structure_size); -- fprintf(file, "\n"); -- print_file(file, indent, "pStubMsg->Offset = 0;\n"); /* FIXME */ -- print_file(file, indent, "pStubMsg->MaxCount = (unsigned long)"); -- write_struct_expr(file, eval->expr, 1, eval->structure->fields, STRUCT_EXPR_EVAL_VAR); -+ print_file(file, 0, "static void __RPC_USER %s_%sExprEval_%04u(PMIDL_STUB_MESSAGE pStubMsg)\n", -+ iface, name, callback_offset); -+ print_file(file, 0, "{\n"); -+ print_file (file, 1, "%s *%s = (%s *)(pStubMsg->StackTop - %u);\n", -+ name, var_name, name, type_memsize (eval->structure, &align)); -+ print_file(file, 1, "pStubMsg->Offset = 0;\n"); /* FIXME */ -+ print_file(file, 1, "pStubMsg->MaxCount = (unsigned long)"); -+ write_struct_expr(file, eval->expr, 1, fields, var_name); - fprintf(file, ";\n"); -- indent--; -- print_file(file, indent, "}\n\n"); -+ print_file(file, 0, "}\n\n"); - callback_offset++; - } - return result; -@@ -2918,9 +2873,8 @@ - - LIST_FOR_EACH_ENTRY_SAFE(eval, cursor, &expr_eval_routines, struct expr_eval_routine, entry) - { -- print_file(file, 1, "%s_%sExprEval_%04u,\n", -- iface, eval->structure->name, callback_offset); -- -+ const char *name = eval->structure->name; -+ print_file(file, 1, "%s_%sExprEval_%04u,\n", iface, name, callback_offset); - callback_offset++; - list_remove(&eval->entry); - free(eval); diff --git a/reactos/tools/widl_new/0.9.44.5 - Implement NDR for struct field alignment.diff b/reactos/tools/widl_new/0.9.44.5 - Implement NDR for struct field alignment.diff deleted file mode 100644 index 8c46cc8215e..00000000000 --- a/reactos/tools/widl_new/0.9.44.5 - Implement NDR for struct field alignment.diff +++ /dev/null @@ -1,75 +0,0 @@ ---- typegen.c Wed Sep 05 10:00:03 2007 -+++ typegen.c Wed Sep 05 10:01:43 2007 -@@ -98,6 +98,8 @@ - case RPC_FC_CARRAY: return "FC_CARRAY"; - case RPC_FC_CVARRAY: return "FC_CVARRAY"; - case RPC_FC_BOGUS_ARRAY: return "FC_BOGUS_ARRAY"; -+ case RPC_FC_ALIGNM4: return "RPC_FC_ALIGNM4"; -+ case RPC_FC_ALIGNM8: return "RPC_FC_ALIGNM8"; - default: - error("string_of_type: unknown type 0x%02x\n", type); - return NULL; -@@ -682,13 +684,25 @@ - - static size_t fields_memsize(const var_list_t *fields, unsigned int *align) - { -+ int have_align = FALSE; - size_t size = 0; - const var_t *v; - - if (!fields) return 0; - LIST_FOR_EACH_ENTRY( v, fields, const var_t, entry ) -- size += type_memsize(v->type, align); -+ { -+ unsigned int falign = 0; -+ size_t fsize = type_memsize(v->type, &falign); -+ if (!have_align) -+ { -+ *align = falign; -+ have_align = TRUE; -+ } -+ size = (size + (falign - 1)) & ~(falign - 1); -+ size += fsize; -+ } - -+ size = (size + (*align - 1)) & ~(*align - 1); - return size; - } - -@@ -1508,12 +1522,36 @@ - unsigned int *corroff, unsigned int *typestring_offset) - { - const var_t *field; -+ unsigned short offset = 0; - - if (type->fields) LIST_FOR_EACH_ENTRY( field, type->fields, const var_t, entry ) - { - type_t *ft = field->type; - if (!ft->declarray || !is_conformant_array(ft)) -+ { -+ unsigned int align = 0; -+ size_t size = type_memsize(ft, &align); -+ if ((align - 1) & offset) -+ { -+ unsigned char fc = 0; -+ switch (align) -+ { -+ case 4: -+ fc = RPC_FC_ALIGNM4; -+ break; -+ case 8: -+ fc = RPC_FC_ALIGNM8; -+ break; -+ default: -+ error("write_struct_members: cannot align type %d", ft->type); -+ } -+ print_file(file, 2, "0x%x,\t/* %s */\n", fc, string_of_type(fc)); -+ offset = (offset + (align - 1)) & ~(align - 1); -+ *typestring_offset += 1; -+ } - write_member_type(file, ft, field, corroff, typestring_offset); -+ offset += size; -+ } - } - - write_end(file, typestring_offset); diff --git a/reactos/tools/widl_new/0.9.44.6 - Allow size_is on strings.diff b/reactos/tools/widl_new/0.9.44.6 - Allow size_is on strings.diff deleted file mode 100644 index 602d88bb9e9..00000000000 --- a/reactos/tools/widl_new/0.9.44.6 - Allow size_is on strings.diff +++ /dev/null @@ -1,87 +0,0 @@ ---- typegen.c Wed Sep 05 10:05:10 2007 -+++ typegen.c Wed Sep 05 10:04:52 2007 -@@ -1312,30 +1312,37 @@ - &offset_in_memory, &offset_in_buffer, typestring_offset); - } - -+static int is_declptr(const type_t *t) -+{ -+ return is_ptr(t) || (is_conformant_array(t) && !t->declarray); -+} -+ - static size_t write_string_tfs(FILE *file, const attr_list_t *attrs, - const type_t *type, - const char *name, unsigned int *typestring_offset) - { - size_t start_offset = *typestring_offset; -- unsigned char flags = 0; -- int pointer_type; - unsigned char rtype; - -- if (is_ptr(type)) -+ if (is_declptr(type)) - { -- pointer_type = type->type; -- type = type->ref; -+ unsigned char flag = is_conformant_array(type) ? 0 : RPC_FC_P_SIMPLEPOINTER; -+ int pointer_type = is_ptr(type) ? type->type : get_attrv(attrs, ATTR_POINTERTYPE); -+ if (!pointer_type) -+ pointer_type = RPC_FC_RP; -+ print_file(file, 2,"0x%x, 0x%x,\t/* %s%s */\n", -+ pointer_type, flag, string_of_type(pointer_type), -+ flag ? " [simple_pointer]" : ""); -+ *typestring_offset += 2; -+ if (!flag) -+ { -+ print_file(file, 2, "NdrFcShort(0x2),\n"); -+ *typestring_offset += 2; -+ } -+ rtype = type->ref->type; - } - else -- pointer_type = get_attrv(attrs, ATTR_POINTERTYPE); -- -- if (!pointer_type) -- pointer_type = RPC_FC_RP; -- -- if (!get_attrp(attrs, ATTR_SIZEIS)) -- flags |= RPC_FC_P_SIMPLEPOINTER; -- -- rtype = type->type; -+ rtype = type->type; - - if ((rtype != RPC_FC_BYTE) && (rtype != RPC_FC_CHAR) && (rtype != RPC_FC_WCHAR)) - { -@@ -1343,18 +1350,6 @@ - return start_offset; - } - -- print_file(file, 2,"0x%x, 0x%x, /* %s%s */\n", -- pointer_type, flags, -- pointer_type == RPC_FC_FP ? "FC_FP" : (pointer_type == RPC_FC_UP ? "FC_UP" : "FC_RP"), -- (flags & RPC_FC_P_SIMPLEPOINTER) ? " [simple_pointer]" : ""); -- *typestring_offset += 2; -- -- if (!(flags & RPC_FC_P_SIMPLEPOINTER)) -- { -- print_file(file, 2, "NdrFcShort(0x2),\n"); -- *typestring_offset += 2; -- } -- - if (type->declarray && !is_conformant_array(type)) - { - /* FIXME: multi-dimensional array */ -@@ -1396,10 +1391,10 @@ - } - else - { -- if (rtype == RPC_FC_CHAR) -- WRITE_FCTYPE(file, FC_C_CSTRING, *typestring_offset); -- else -+ if (rtype == RPC_FC_WCHAR) - WRITE_FCTYPE(file, FC_C_WSTRING, *typestring_offset); -+ else -+ WRITE_FCTYPE(file, FC_C_CSTRING, *typestring_offset); - print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD); - *typestring_offset += 2; - diff --git a/reactos/tools/widl_new/0.9.44.7 - ReactOS hack.diff b/reactos/tools/widl_new/0.9.44.7 - ReactOS hack.diff deleted file mode 100644 index c4d1e6c185b..00000000000 --- a/reactos/tools/widl_new/0.9.44.7 - ReactOS hack.diff +++ /dev/null @@ -1,10 +0,0 @@ ---- server.c Fri Aug 24 16:34:34 2007 -+++ server.c Wed Sep 05 10:18:03 2007 -@@ -382,6 +382,7 @@ - print_server("/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n", PACKAGE_VERSION, input_name); - print_server("#include \n"); - fprintf(server, "\n"); -+ print_server("#define _SEH_NO_NATIVE_NLG\n"); - print_server("#include \"%s\"\n", header_name); - fprintf(server, "\n"); - } diff --git a/reactos/tools/widl_new/ChangeLog b/reactos/tools/widl_new/ChangeLog deleted file mode 100644 index 048260631ec..00000000000 --- a/reactos/tools/widl_new/ChangeLog +++ /dev/null @@ -1,307 +0,0 @@ -ChangeLog - -2007-09-05 hpoussin - -- Synchronized with WINE widl 0.9.44 -- parser.tab.c/h were generated with: - bison -p parser_ -d parser.y -- parser.yy.c was generated with: - flex -t parser.l >parser.yy.c - - -2007-05-17 ekohl - - tools/widl/lex.yy.c - tools/widl/parser.l - tools/widl/typelib.c - -- Update wpp and fix the wpp_find_include issue! - - -2006-07-30 ekohl - -- Synchronized with WINE widl 20060729. - - The only difference is one call to wpp_find_include in parser.l. - We'll need to fix this issue! - - -2006-02-27 ekohl - - tools/widl/client.c - tools/widl/server.c - -- Dereference type declarations properly. - -2006-02-27 ekohl - - tools/widl/client.c - tools/widl/server.c - -- Move proc string offset calculation to a separate function. -- Replace all __FUNCTION__ by __FILE__. - -2006-01-01 ekohl - - tools/widl/client.c - tools/widl/server.c - -- Generate static MIDL_PROC_FORMAT_STRING, MIDL_TYPE_FORMAT_STRING and - MIDL_STUB_DESC variables. - -2005-12-05 ekohl - - tools/widl/widl.c - tools/widl/widl.man - -- Change oldnames option from '-o' to '--oldnames'. - -2005-11-26 ekohl - - tools/widl/client.c - tools/widl/server.c - -- Allocate another 4 bytes for unique pointers to simple types. - -2005-10-16 ekohl - - tools/widl/client.c - tools/widl/server.c - -- Fix [out, size_is, unique] parameter issues. - -2005-10-09 ekohl - - tools/widl/client.c - tools/widl/server.c - -- Support [out, unique] base type parameters. - -2005-08-07 ekohl - - tools/widl/server.c - -- Support size_is(*Length) attributes for strings. - -2005-07-30 ekohl - - tools/widl/client.c - tools/widl/server.c - -- Support conformant arrays as in and out parameters. -- Fix message buffer size calculation for client and server. - -2005-07-25 ekohl - - tools/widl/client.c - tools/widl/lex.yy.c - tools/widl/parser.y - tools/widl/proxy.c - tools/widl/server.c - tools/widl/y.tab.c - tools/widl/y.tab.h - -- Fix grammar of the size_is attribute so that size_is(*Length) gets accepted. - -2005-07-23 ekohl - - tools/widl/client.c - tools/widl/server.c - -- Fix offset calculation bug in the ProcFormatString. -- Fix offset calculation bug in the marshalling and unmarshalling code. -- Fix typos in the TypeFormatString. -This makes the [string, out, size_is()] parameters work properly. - -2005-07-17 ekohl - - tools/widl/client.c - tools/widl/server.c - -Fix bugs for in-string parameters. -Implement out-string parameters (untested). - -2005-05-08 weiden - - tools/widl/server.c - -Don't generate lvalue assignment code. - -2005-05-08 weiden - - tools/widl/client.c - tools/widl/proxy.c - tools/widl/server.c - -Generate code GCC4.x accepts. - -2005-04-18 navaraf - - tools/widl/parser.y - -Don't use pointer to freed memory. - -2005-04-17 ekohl - - tools/widl/server.c - -Support out-pointers to structs. - -2005-04-15 ekohl - - tools/widl/client.c - tools/widl/parser.y - tools/widl/server.c - -Support in-pointers to structs. - -2005-04-03 ekohl - - tools/widl/client.c - tools/widl/parser.l - tools/widl/parser.y - tools/widl/server.c - tools/widl/widltypes.h - -Support 'ref' and 'unique' attributes for pointers. - -2005-03-27 Jacek Caban (from WINE) - - tools/widl/parser.y - tools/widl/y.tab.c - -Added handling of unsigned type - -2005-03-25 ekohl - - tools/widl/client.c - tools/widl/server.c - -Generate code without L-value casts. Fix remaining issues. - -2005-03-21 navaraf - - tools/widl/client.c - -Fix a typo in write_function_stubs. - -2005-03-20 navaraf - - tools/widl/client.c - tools/widl/server.c - -Generate code without L-value casts. - -2005-03-20 ekohl - - tools/widl/client.c - tools/widl/server.c - -Improve error messages. -Don't start counting the type_offset for each new fuction. It is a global offset. -Use only basic types in type- and proc-strings (e.g. unsigned long -> long). - - -2005-03-13 ekohl - - tools/widl/server.c - -Remove debug printf(). - - -2005-03-13 jimtabor - - tools/widl/write_msft.c - -Fixup *nix port, added include fcntl.h and unistd.h. - - -2005-03-13 royce3 - - tools/widl/hash.c - tools/widl/Makefile - tools/widl/write_msft.c - --Wall -Werror and fix warnings - - -2005-03-13 ekohl - - tools/widl/client.c - tools/widl/server.c - -Implement [string] attribute for pointers to char and wchar_t. - - -2005-03-12 ekohl - - tools/widl/client.c - tools/widl/server.c - -Implement [in], [out] and [in, out] support for pointers to basic types. - - -2005-03-10 ekohl - - tools/widl/client.c - tools/widl/header.c - tools/widl/server.c - tools/widl/widl.c - tools/widl/widl.h - -Implement '-o' option. This is equivalent to MIDLs '/oldnames' option. - - -2005-03-06 ekohl - - tools/widl/client.c - tools/widl/header.c - tools/widl/header.h - tools/widl/server.c - -Support pointers to simple types as input arguments. - - -2005-02-27 sedwards - - tools/widl/y.tab.c - tools/widl/parser.y - tools/widl/widl.c - tools/widl/widl.h - tools/widl/server.c - tools/widl/typelib.c - -Merge in Winehq changes to reduce noise. - - tools/widl/server.h - tools/widl/client.h - tools/widl/proxy.h - -Deleted unneeded headers. - -2005-02-26 ekohl - tools/widl/server.c - -Server stubs are void functions. -Fix a warning in the server stub descriptor. - - -2005-02-25 ekohl - tools/widl/client.c - tools/widl/header.c - tools/widl/header.h - tools/widl/server.c - -Support multiple interfaces per idl file. -Support explicit binding handles. - - -2005-02-24 ekohl - include/wine/rpcfc.h - tools/widl/client.c - tools/widl/header.c - tools/widl/parser.l - tools/widl/parser.y - tools/widl/server.c - -Support remaining basic types (float, double, small, wchar_t and handle_t). diff --git a/reactos/tools/widl_new/Makefile.in b/reactos/tools/widl_new/Makefile.in deleted file mode 100644 index a3145b2eeb0..00000000000 --- a/reactos/tools/widl_new/Makefile.in +++ /dev/null @@ -1,46 +0,0 @@ -TOPSRCDIR = @top_srcdir@ -TOPOBJDIR = ../.. -SRCDIR = @srcdir@ -VPATH = @srcdir@ -EXEEXT = @EXEEXT@ - -PROGRAMS = widl$(EXEEXT) -MANPAGES = widl.man -MODULE = none - -C_SRCS = \ - client.c \ - hash.c \ - header.c \ - proxy.c \ - server.c \ - typegen.c \ - typelib.c \ - utils.c \ - widl.c \ - write_msft.c - -LEX_SRCS = parser.l -BISON_SRCS = parser.y - -INSTALLDIRS = $(DESTDIR)$(bindir) $(DESTDIR)$(mandir)/man$(prog_manext) - -all: $(PROGRAMS) $(MANPAGES) - -@MAKE_RULES@ - -widl$(EXEEXT): $(OBJS) $(LIBWPP) - $(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBWPP) $(LIBPORT) $(LDFLAGS) - -install:: $(PROGRAMS) $(MANPAGES) $(INSTALLDIRS) - $(INSTALL_PROGRAM) widl$(EXEEXT) $(DESTDIR)$(bindir)/widl$(EXEEXT) - $(INSTALL_DATA) widl.man $(DESTDIR)$(mandir)/man$(prog_manext)/widl.$(prog_manext) - -uninstall:: - $(RM) $(DESTDIR)$(bindir)/widl$(EXEEXT) $(DESTDIR)$(mandir)/man$(prog_manext)/widl.$(prog_manext) - -parser.tab.c: parser.tab.h # for parallel makes - -@DEPENDENCIES@ # everything below this line is overwritten by make depend - -parser.yy.o: parser.tab.h diff --git a/reactos/tools/widl_new/client.c b/reactos/tools/widl_new/client.c deleted file mode 100644 index bd3ca035e6d..00000000000 --- a/reactos/tools/widl_new/client.c +++ /dev/null @@ -1,442 +0,0 @@ -/* - * IDL Compiler - * - * Copyright 2005-2006 Eric Kohl - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" -#include "wine/port.h" - -#include -#include -#include -#include -#include -#include -#include - -#include "windef.h" - -#include "widl.h" -#include "utils.h" -#include "parser.h" -#include "header.h" - -#include "widltypes.h" -#include "typelib.h" -#include "typelib_struct.h" -#include "typegen.h" - -static FILE* client; -static int indent = 0; - -static void print_client( const char *format, ... ) -{ - va_list va; - va_start(va, format); - print(client, indent, format, va); - va_end(va); -} - - -static void check_pointers(const func_t *func) -{ - const var_t *var; - - if (!func->args) - return; - - LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) - { - if (is_var_ptr(var) && cant_be_null(var)) - { - print_client("if (!%s)\n", var->name); - print_client("{\n"); - indent++; - print_client("RpcRaiseException(RPC_X_NULL_REF_POINTER);\n"); - indent--; - print_client("}\n\n"); - } - } -} - -static void write_function_stubs(type_t *iface, unsigned int *proc_offset) -{ - const func_t *func; - const char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE); - int explicit_handle = is_attr(iface->attrs, ATTR_EXPLICIT_HANDLE); - const var_t *var; - int method_count = 0; - - if (!implicit_handle) - print_client("static RPC_BINDING_HANDLE %s__MIDL_AutoBindHandle;\n\n", iface->name); - - if (iface->funcs) LIST_FOR_EACH_ENTRY( func, iface->funcs, const func_t, entry ) - { - const var_t *def = func->def; - const var_t* explicit_handle_var; - - /* check for a defined binding handle */ - explicit_handle_var = get_explicit_handle_var(func); - if (explicit_handle) - { - if (!explicit_handle_var) - { - error("%s() does not define an explicit binding handle!\n", def->name); - return; - } - } - else if (implicit_handle) - { - if (explicit_handle_var) - { - error("%s() must not define a binding handle!\n", def->name); - return; - } - } - - write_type_left(client, def->type); - if (needs_space_after(def->type)) - fprintf(client, " "); - write_prefix_name(client, prefix_client, def); - fprintf(client, "(\n"); - indent++; - if (func->args) - write_args(client, func->args, iface->name, 0, TRUE); - else - print_client("void"); - fprintf(client, ")\n"); - indent--; - - /* write the functions body */ - fprintf(client, "{\n"); - indent++; - - /* declare return value '_RetVal' */ - if (!is_void(def->type)) - { - print_client(""); - write_type_left(client, def->type); - fprintf(client, " _RetVal;\n"); - } - - if (implicit_handle || explicit_handle_var) - print_client("RPC_BINDING_HANDLE _Handle = 0;\n"); - - print_client("RPC_MESSAGE _RpcMessage;\n"); - print_client("MIDL_STUB_MESSAGE _StubMsg;\n"); - fprintf(client, "\n"); - - /* check pointers */ - check_pointers(func); - - print_client("RpcTryFinally\n"); - print_client("{\n"); - indent++; - - print_client("NdrClientInitializeNew(\n"); - indent++; - print_client("(PRPC_MESSAGE)&_RpcMessage,\n"); - print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n"); - print_client("(PMIDL_STUB_DESC)&%s_StubDesc,\n", iface->name); - print_client("%d);\n", method_count); - indent--; - fprintf(client, "\n"); - - if (implicit_handle) - { - print_client("_Handle = %s;\n", implicit_handle); - fprintf(client, "\n"); - } - else if (explicit_handle_var) - { - print_client("_Handle = %s;\n", explicit_handle_var->name); - fprintf(client, "\n"); - } - - write_remoting_arguments(client, indent, func, PASS_IN, PHASE_BUFFERSIZE); - - print_client("NdrGetBuffer(\n"); - indent++; - print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n"); - print_client("_StubMsg.BufferLength,\n"); - if (implicit_handle || explicit_handle_var) - print_client("_Handle);\n"); - else - print_client("%s__MIDL_AutoBindHandle);\n", iface->name); - indent--; - fprintf(client, "\n"); - - /* marshal arguments */ - write_remoting_arguments(client, indent, func, PASS_IN, PHASE_MARSHAL); - - /* send/receive message */ - /* print_client("NdrNsSendReceive(\n"); */ - /* print_client("(unsigned char *)_StubMsg.Buffer,\n"); */ - /* print_client("(RPC_BINDING_HANDLE *) &%s__MIDL_AutoBindHandle);\n", iface->name); */ - print_client("NdrSendReceive(\n"); - indent++; - print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n"); - print_client("(unsigned char *)_StubMsg.Buffer);\n\n"); - indent--; - - print_client("_StubMsg.BufferStart = (unsigned char *)_RpcMessage.Buffer;\n"); - print_client("_StubMsg.BufferEnd = _StubMsg.BufferStart + _RpcMessage.BufferLength;\n"); - - if (has_out_arg_or_return(func)) - { - fprintf(client, "\n"); - - print_client("if ((_RpcMessage.DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION)\n"); - indent++; - print_client("NdrConvert(\n"); - indent++; - print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n"); - print_client("(PFORMAT_STRING)&__MIDL_ProcFormatString.Format[%u]);\n", *proc_offset); - indent -= 2; - } - - /* unmarshall arguments */ - fprintf(client, "\n"); - write_remoting_arguments(client, indent, func, PASS_OUT, PHASE_UNMARSHAL); - - /* unmarshal return value */ - if (!is_void(def->type)) - print_phase_basetype(client, indent, PHASE_UNMARSHAL, PASS_RETURN, def, "_RetVal"); - - /* update proc_offset */ - if (func->args) - { - LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) - *proc_offset += get_size_procformatstring_var(var); - } - if (!is_void(def->type)) - *proc_offset += get_size_procformatstring_var(def); - else - *proc_offset += 2; /* FC_END and FC_PAD */ - - indent--; - print_client("}\n"); - print_client("RpcFinally\n"); - print_client("{\n"); - indent++; - - - /* FIXME: emit client finally code */ - - print_client("NdrFreeBuffer((PMIDL_STUB_MESSAGE)&_StubMsg);\n"); - - indent--; - print_client("}\n"); - print_client("RpcEndFinally\n"); - - - /* emit return code */ - if (!is_void(def->type)) - { - fprintf(client, "\n"); - print_client("return _RetVal;\n"); - } - - indent--; - fprintf(client, "}\n"); - fprintf(client, "\n"); - - method_count++; - } -} - - -static void write_stubdescdecl(type_t *iface) -{ - print_client("static const MIDL_STUB_DESC %s_StubDesc;\n", iface->name); - fprintf(client, "\n"); -} - - -static void write_stubdescriptor(type_t *iface, int expr_eval_routines) -{ - const char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE); - - print_client("static const MIDL_STUB_DESC %s_StubDesc =\n", iface->name); - print_client("{\n"); - indent++; - print_client("(void *)& %s___RpcClientInterface,\n", iface->name); - print_client("MIDL_user_allocate,\n"); - print_client("MIDL_user_free,\n"); - print_client("{\n"); - indent++; - if (implicit_handle) - print_client("&%s,\n", implicit_handle); - else - print_client("&%s__MIDL_AutoBindHandle,\n", iface->name); - indent--; - print_client("},\n"); - print_client("0,\n"); - print_client("0,\n"); - if (expr_eval_routines) - print_client("ExprEvalRoutines,\n"); - else - print_client("0,\n"); - print_client("0,\n"); - print_client("__MIDL_TypeFormatString.Format,\n"); - print_client("1, /* -error bounds_check flag */\n"); - print_client("0x10001, /* Ndr library version */\n"); - print_client("0,\n"); - print_client("0x50100a4, /* MIDL Version 5.1.164 */\n"); - print_client("0,\n"); - print_client("%s,\n", list_empty(&user_type_list) ? "0" : "UserMarshalRoutines"); - print_client("0, /* notify & notify_flag routine table */\n"); - print_client("1, /* Flags */\n"); - print_client("0, /* Reserved3 */\n"); - print_client("0, /* Reserved4 */\n"); - print_client("0 /* Reserved5 */\n"); - indent--; - print_client("};\n"); - fprintf(client, "\n"); -} - - -static void write_clientinterfacedecl(type_t *iface) -{ - unsigned long ver = get_attrv(iface->attrs, ATTR_VERSION); - const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID); - const str_list_t *endpoints = get_attrp(iface->attrs, ATTR_ENDPOINT); - - if (endpoints) write_endpoints( client, iface->name, endpoints ); - - print_client("static const RPC_CLIENT_INTERFACE %s___RpcClientInterface =\n", iface->name ); - print_client("{\n"); - indent++; - print_client("sizeof(RPC_CLIENT_INTERFACE),\n"); - print_client("{{0x%08lx,0x%04x,0x%04x,{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x}},{%d,%d}},\n", - uuid->Data1, uuid->Data2, uuid->Data3, uuid->Data4[0], uuid->Data4[1], - uuid->Data4[2], uuid->Data4[3], uuid->Data4[4], uuid->Data4[5], uuid->Data4[6], - uuid->Data4[7], LOWORD(ver), HIWORD(ver)); - print_client("{{0x8a885d04,0x1ceb,0x11c9,{0x9f,0xe8,0x08,0x00,0x2b,0x10,0x48,0x60}},{2,0}},\n"); /* FIXME */ - print_client("0,\n"); - if (endpoints) - { - print_client("%u,\n", list_count(endpoints)); - print_client("(PRPC_PROTSEQ_ENDPOINT)%s__RpcProtseqEndpoint,\n", iface->name); - } - else - { - print_client("0,\n"); - print_client("0,\n"); - } - print_client("0,\n"); - print_client("0,\n"); - print_client("0,\n"); - indent--; - print_client("};\n"); - if (old_names) - print_client("RPC_IF_HANDLE %s_ClientIfHandle = (RPC_IF_HANDLE)& %s___RpcClientInterface;\n", - iface->name, iface->name); - else - print_client("RPC_IF_HANDLE %s%s_v%d_%d_c_ifspec = (RPC_IF_HANDLE)& %s___RpcClientInterface;\n", - prefix_client, iface->name, LOWORD(ver), HIWORD(ver), iface->name); - fprintf(client, "\n"); -} - - -static void write_implicithandledecl(type_t *iface) -{ - const char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE); - - if (implicit_handle) - { - fprintf(client, "handle_t %s;\n", implicit_handle); - fprintf(client, "\n"); - } -} - - -static void init_client(void) -{ - if (client) return; - if (!(client = fopen(client_name, "w"))) - error("Could not open %s for output\n", client_name); - - print_client("/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n", PACKAGE_VERSION, input_name); - print_client("#include \n"); - print_client("#ifdef _ALPHA_\n"); - print_client("#include \n"); - print_client("#endif\n"); - fprintf(client, "\n"); - print_client("#include \"%s\"\n", header_name); - fprintf(client, "\n"); -} - - -void write_client(ifref_list_t *ifaces) -{ - unsigned int proc_offset = 0; - ifref_t *iface; - - if (!do_client) - return; - if (do_everything && !ifaces) - return; - - init_client(); - if (!client) - return; - - write_formatstringsdecl(client, indent, ifaces, 0); - - if (ifaces) LIST_FOR_EACH_ENTRY( iface, ifaces, ifref_t, entry ) - { - if (is_object(iface->iface->attrs) || is_local(iface->iface->attrs)) - continue; - - fprintf(client, "/*****************************************************************************\n"); - fprintf(client, " * %s interface\n", iface->iface->name); - fprintf(client, " */\n"); - fprintf(client, "\n"); - - if (iface->iface->funcs) - { - int expr_eval_routines; - - write_implicithandledecl(iface->iface); - - write_clientinterfacedecl(iface->iface); - write_stubdescdecl(iface->iface); - write_function_stubs(iface->iface, &proc_offset); - - print_client("#if !defined(__RPC_WIN32__)\n"); - print_client("#error Invalid build platform for this stub.\n"); - print_client("#endif\n"); - - fprintf(client, "\n"); - - expr_eval_routines = write_expr_eval_routines(client, iface->iface->name); - if (expr_eval_routines) - write_expr_eval_routine_list(client, iface->iface->name); - write_user_quad_list(client); - write_stubdescriptor(iface->iface, expr_eval_routines); - } - } - - fprintf(client, "\n"); - - write_procformatstring(client, ifaces, 0); - write_typeformatstring(client, ifaces, 0); - - fclose(client); -} diff --git a/reactos/tools/widl_new/hash.c b/reactos/tools/widl_new/hash.c deleted file mode 100644 index 547c0b1825f..00000000000 --- a/reactos/tools/widl_new/hash.c +++ /dev/null @@ -1,615 +0,0 @@ -/* - * Oleaut32 hash functions - * - * Copyright 1999 Corel Corporation - * Copyright 2001-2003 Jon Griffiths - * - * 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 -#include - -#include "windef.h" -#include "winbase.h" -#include "winnls.h" - -#include "hash.h" - -static const unsigned char Lookup_16[128 * 3] = { - /* Common */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, - 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, - 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, - 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x00, 0x30, 0x31, 0x32, 0x33, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, - 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, - 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x56, 0x58, 0x55, 0x5A, - 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, - 0x55, 0x56, 0x56, 0x58, 0x55, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, - - /* Windows */ - 0x7F, 0x7F, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x7F, 0x89, 0x53, 0x8B, 0x8C, - 0x7F, 0x7F, 0x7F, 0x7F, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x96, 0x98, 0x99, - 0x53, 0x9B, 0x8C, 0x7F, 0x7F, 0x55, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, - 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x96, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, - 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, - 0x49, 0x49, 0x44, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0xD7, 0x4F, 0x55, 0x55, - 0x55, 0x55, 0x55, 0xDE, 0xDF, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x43, - 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0x44, 0x4E, 0x4F, 0x4F, 0x4F, - 0x4F, 0x4F, 0xF7, 0x4F, 0x55, 0x55, 0x55, 0x55, 0x55, 0xDE, 0x55, - - /* Mac */ - 0x41, 0x41, 0x43, 0x45, 0x4E, 0x4F, 0x55, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0x4E, 0x4F, 0x4F, 0x4F, - 0x4F, 0x4F, 0x55, 0x55, 0x55, 0x55, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, - 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0x41, 0x4F, 0xB0, 0xB1, 0xB2, 0xB3, - 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0x41, 0x4F, 0xBD, 0x41, 0x4F, 0xC0, - 0xC1, 0xC2, 0xC3, 0x46, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0x41, 0x41, 0x4F, - 0xCE, 0xCE, 0xD0, 0xD0, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0x55, 0x55, 0xDA, - 0xDB, 0xDC, 0xDD, 0x3F, 0x3F, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0x41, 0x45, 0x41, - 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0x4F, 0x4F, 0x3F, 0x4F, 0x55, 0x55, 0x55, - 0x49, 0x7F, 0xF7, 0x7F, 0xF9, 0xFA, 0xFB, 0x3F, 0xFD, 0xFE, 0x7F -}; - -static const unsigned char Lookup_32[128 * 3] = { - /* Common */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, - 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, - 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, - 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x00, 0x30, 0x31, 0x32, 0x33, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, - 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, - 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, - 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, - 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, - - /* Windows */ - 0x7F, 0x7F, 0x82, 0x7F, 0x84, 0x85, 0x86, 0x87, 0x7F, 0x89, 0x53, 0x8B, 0x53, - 0x54, 0x5A, 0x5A, 0x7F, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x96, 0x7F, 0x99, - 0x53, 0x9B, 0x53, 0x54, 0x5A, 0x5A, 0xA0, 0x7F, 0xA2, 0x4C, 0xA4, 0x41, 0xA6, - 0xA7, 0xA8, 0xA9, 0x53, 0xAB, 0xAC, 0x96, 0xAE, 0x5A, 0xB0, 0xB1, 0xB2, 0x4C, - 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x41, 0x53, 0xBB, 0x4C, 0xBD, 0x4C, 0x5A, 0x52, - 0x41, 0x41, 0x41, 0x41, 0x4C, 0x43, 0x43, 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, - 0x49, 0x44, 0xD0, 0x4E, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0xD7, 0x52, 0x55, 0x55, - 0x55, 0x55, 0x59, 0x54, 0xDF, 0x52, 0x41, 0x41, 0x41, 0x41, 0x4C, 0x43, 0x43, - 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x44, 0xD0, 0x4E, 0x4E, 0x4F, 0x4F, - 0x4F, 0x4F, 0xF7, 0x52, 0x55, 0x55, 0x55, 0x55, 0x59, 0x54, 0xFF, - - /* Mac */ - 0x41, 0x41, 0x41, 0x45, 0x41, 0x4F, 0x55, 0x41, 0x41, 0x43, 0x41, 0x43, 0x43, - 0x43, 0x45, 0x5A, 0x5A, 0x44, 0x49, 0x44, 0x45, 0x45, 0x45, 0x4F, 0x45, 0x4F, - 0x4F, 0x4F, 0x55, 0x45, 0x45, 0x55, 0xA0, 0xA1, 0x45, 0xA3, 0xA4, 0xA5, 0xA6, - 0xA7, 0xA8, 0xA9, 0xAA, 0x45, 0xAC, 0xAD, 0x47, 0x49, 0x49, 0x49, 0xB2, 0xB3, - 0x49, 0x4B, 0xB6, 0xB7, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4E, 0x4E, - 0x4E, 0xC2, 0xC3, 0x4E, 0x4E, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0x4E, 0x4F, 0x4F, - 0x4F, 0x4F, 0xD0, 0xD0, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0x4F, 0x52, 0x52, - 0x52, 0xDC, 0xDD, 0x52, 0x52, 0x52, 0x53, 0xE2, 0xE3, 0x53, 0x53, 0x53, 0x41, - 0x54, 0x54, 0x49, 0x5A, 0x5A, 0x55, 0x4F, 0x4F, 0x55, 0x55, 0x55, 0x55, 0x55, - 0x55, 0x55, 0x55, 0x59, 0x59, 0x4B, 0x5A, 0x4C, 0x4C, 0x47, 0xFF -}; - -static const unsigned char Lookup_48[128 * 3] = { - /* Common */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, - 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, - 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, - 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x00, 0x30, 0x31, 0x32, 0x33, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, - 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, - 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, - 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, - 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, - - /* Windows */ - 0x7F, 0x7F, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x7F, 0x89, 0x53, 0x8B, 0x8C, - 0x7F, 0x7F, 0x7F, 0x7F, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x96, 0x98, 0x99, - 0x53, 0x9B, 0x8C, 0x7F, 0x7F, 0x59, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, - 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x96, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, - 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0xC6, 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, - 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0xD7, 0x4F, 0x55, 0x55, - 0x55, 0x55, 0x59, 0xDE, 0xDF, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0xC6, 0x43, - 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0x4F, 0x4F, - 0x4F, 0x4F, 0xF7, 0x4F, 0x55, 0x55, 0x55, 0x55, 0x59, 0xDE, 0x59, - - /* Mac */ - 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, - 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, - 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, - 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAB, 0xAD, 0xAE, 0xAE, 0xB0, 0xB1, 0xB2, 0xB3, - 0xA7, 0xB5, 0xB6, 0xB7, 0xB8, 0xB8, 0xBA, 0xBA, 0xBC, 0xBC, 0xBE, 0xBE, 0xB7, - 0xC1, 0xC2, 0xC3, 0x46, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCB, 0xCD, - 0xCD, 0xC1, 0xD0, 0xD0, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD8, 0xDA, - 0xDA, 0xDC, 0xDD, 0xDD, 0x9F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, - 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F -}; - -static const unsigned char Lookup_64[128 * 3] = { - /* Common */ - 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, - 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, - 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x00, 0x30, 0x31, 0x32, 0x33, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, - 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, - 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x56, 0x58, 0x55, 0x5A, - 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, - 0x55, 0x56, 0x56, 0x58, 0x55, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, - -/* Windows */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, - 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x96, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, - 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, - 0x49, 0x49, 0x44, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0xD7, 0x4F, 0x55, 0x55, - 0x55, 0x55, 0x55, 0xDE, 0xDF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - /* Mac */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, - 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x96, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, - 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, - 0x49, 0x49, 0x44, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0xD7, 0x4F, 0x55, 0x55, - 0x55, 0x55, 0x55, 0xDE, 0xDF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - -static const unsigned char Lookup_80[128 * 3] = { - /* Common */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, - 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, - 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, - 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x00, 0x30, 0x31, 0x32, 0x33, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, - 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, - 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x56, 0x58, 0x55, 0x5A, - 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, - 0x55, 0x56, 0x56, 0x58, 0x55, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, - -/* Windows */ - 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, - - /* Mac */ - 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, -}; - -static const unsigned char Lookup_112[128 * 3] = { - /* Common */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, - 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, - 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, - 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x00, 0x30, 0x31, 0x32, 0x33, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, - 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, - 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x56, 0x58, 0x55, 0x5A, - 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, - 0x55, 0x56, 0x56, 0x58, 0x55, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, - -/* Windows */ - 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, - - /* Mac */ - 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, -}; - -static const unsigned char Lookup_128[128 * 3] = { - /* Common */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, - 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, - 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, - 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, - 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, - 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, - 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, - 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x00, - -/* Windows */ - 0x00, 0x00, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x00, 0x89, 0x00, 0x8B, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x91, 0x92, 0x93, 0x94, 0x95, 0x2D, 0x2D, 0x00, 0x99, - 0x00, 0x9B, 0x00, 0x00, 0x00, 0x00, 0x09, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, - 0xA7, 0xA8, 0xA9, 0x00, 0xAB, 0xAC, 0x2D, 0xAE, 0x2D, 0xB0, 0xB1, 0x32, 0x33, - 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xBA, - 0xA2, 0xC2, 0xC3, 0xC4, 0xB8, 0xC6, 0xB9, 0xC8, 0xBA, 0xCA, 0xCB, 0xCC, 0xCD, - 0xCE, 0xBC, 0xD0, 0xD1, 0x00, 0xD3, 0xD4, 0xBE, 0xD6, 0xD7, 0xD8, 0xBF, 0xBA, - 0xBE, 0xA2, 0xB8, 0xB9, 0xBA, 0xBE, 0xA2, 0xC2, 0xC3, 0xC4, 0xB8, 0xC6, 0xB9, - 0xC8, 0xBA, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xBC, 0xD0, 0xD1, 0xD3, 0xD3, 0xD4, - 0xBE, 0xD6, 0xD7, 0xD8, 0xBF, 0xBA, 0xBE, 0xBC, 0xBE, 0xBF, 0x00, - - /* Mac */ - 0x41, 0x31, 0x32, 0x45, 0x33, 0x4F, 0x55, 0x87, 0x41, 0x41, 0x41, 0x00, 0x8C, - 0x43, 0x45, 0x45, 0x45, 0x45, 0x92, 0x93, 0x49, 0x49, 0x96, 0x97, 0x98, 0x4F, - 0x4F, 0x9B, 0x3F, 0x55, 0x55, 0x55, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, - 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, - 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xAB, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xB0, - 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0x09, 0xBD, 0xCC, 0xB0, - 0xB6, 0xCF, 0x2D, 0x2D, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xB8, 0xAB, 0xC3, 0xBD, - 0xB6, 0xB8, 0xAB, 0xC3, 0xBF, 0xBD, 0xB0, 0xB5, 0xBE, 0xA2, 0xB6, 0xBC, 0xA1, - 0xB8, 0xAB, 0xA5, 0xBA, 0xA4, 0xBB, 0xC1, 0xC3, 0xA6, 0xBF, 0xC4, 0xAA, 0xC6, - 0xA3, 0xBF, 0xAA, 0xCC, 0xBD, 0xB7, 0xAB, 0xBD, 0xAB, 0xBD, 0x3F, -}; - -static const unsigned char Lookup_144[128 * 3] = { - /* Common */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, - 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, - 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, - 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, - 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, - 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, - 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, - 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x00, - -/* Windows */ - 0x00, 0x00, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x00, 0x89, 0x53, 0x8B, 0x8C, - 0x00, 0x00, 0x00, 0x00, 0x91, 0x92, 0x93, 0x94, 0x95, 0x2D, 0x2D, 0x98, 0x99, - 0x53, 0x9B, 0x8C, 0x00, 0x00, 0x59, 0x09, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, - 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x2D, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, - 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, - 0xC1, 0x41, 0x41, 0x41, 0x41, 0xC6, 0x43, 0x45, 0xC9, 0x45, 0x45, 0x49, 0xCD, - 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0xD3, 0x4F, 0x4F, 0xD6, 0xD7, 0xD6, 0x55, 0xDA, - 0x55, 0x55, 0xDD, 0xDE, 0xDF, 0x41, 0xC1, 0x41, 0x41, 0x41, 0x41, 0xC6, 0x43, - 0x45, 0xC9, 0x45, 0x45, 0x49, 0xCD, 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0xD3, 0x4F, - 0x4F, 0xD6, 0xF7, 0xD6, 0x55, 0xDA, 0x55, 0x55, 0xDD, 0xDE, 0x59, - - /* Mac */ - 0x00, 0x00, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x00, 0x89, 0x53, 0x8B, 0x8C, - 0x00, 0x00, 0x00, 0x00, 0x91, 0x92, 0x93, 0x94, 0x95, 0x2D, 0x2D, 0x98, 0x99, - 0x53, 0x9B, 0x8C, 0x00, 0x00, 0x59, 0x09, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, - 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x2D, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, - 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, - 0xC1, 0x41, 0x41, 0x41, 0x41, 0xC6, 0x43, 0x45, 0xC9, 0x45, 0x45, 0x49, 0xCD, - 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0xD3, 0x4F, 0x4F, 0xD6, 0xD7, 0xD6, 0x55, 0xDA, - 0x55, 0x55, 0xDD, 0xDE, 0xDF, 0x41, 0xC1, 0x41, 0x41, 0x41, 0x41, 0xC6, 0x43, - 0x45, 0xC9, 0x45, 0x45, 0x49, 0xCD, 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0xD3, 0x4F, - 0x4F, 0xD6, 0xF7, 0xD6, 0x55, 0xDA, 0x55, 0x55, 0xDD, 0xDE, 0x59, -}; - -static const unsigned char Lookup_160[128 * 3] = { - /* Common */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, - 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, - 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, - 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, - 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, - 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, - 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, - 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x00, - -/* Windows */ - 0x00, 0x00, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x00, 0x89, 0x53, 0x8B, 0x8C, - 0x00, 0x00, 0x00, 0x00, 0x91, 0x92, 0x93, 0x94, 0x95, 0x2D, 0x2D, 0x98, 0x99, - 0x53, 0x9B, 0x8C, 0x00, 0x00, 0x59, 0x09, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, - 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x2D, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, - 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0xC6, 0xC7, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, - 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0xD6, 0xD7, 0x4F, 0x55, 0x55, - 0x55, 0xDC, 0xDD, 0xDE, 0xDF, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0xC6, 0xC7, - 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0x4F, 0x4F, - 0x4F, 0xD6, 0xF7, 0x4F, 0x55, 0x55, 0x55, 0xDC, 0xDD, 0xDE, 0x59, - - /* Mac */ - 0x00, 0x00, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x00, 0x89, 0x53, 0x8B, 0x8C, - 0x00, 0x00, 0x00, 0x00, 0x91, 0x92, 0x93, 0x94, 0x95, 0x2D, 0x2D, 0x98, 0x99, - 0x53, 0x9B, 0x8C, 0x00, 0x00, 0x59, 0x09, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, - 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x2D, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, - 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x41, 0xC6, 0xC7, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, - 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0xD6, 0xD7, 0x4F, 0x55, 0x55, - 0x55, 0xDC, 0xDD, 0xDE, 0xDF, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0xC6, 0xC7, - 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0xD0, 0x4E, 0x4F, 0x4F, 0x4F, - 0x4F, 0xD6, 0xF7, 0x4F, 0x55, 0x55, 0x55, 0xDC, 0xDD, 0xDE, 0x59, -}; - -static const unsigned char Lookup_176[128 * 3] = { - /* Common */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, - 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, - 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, - 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, - 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, - 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, - 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, - 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x00, - - /* Windows */ - 0x00, 0x00, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x00, 0x89, 0x53, 0x8B, 0x8C, - 0x00, 0x00, 0x00, 0x00, 0x91, 0x92, 0x93, 0x94, 0x95, 0x2D, 0x2D, 0x98, 0x99, - 0x53, 0x9B, 0x8C, 0x00, 0x00, 0x59, 0x09, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, - 0xA7, 0xA8, 0xA9, 0x41, 0xAB, 0xAC, 0x2D, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, - 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0x4F, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x41, - 0x41, 0x41, 0x41, 0xC4, 0xC5, 0xC4, 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, - 0x49, 0x49, 0x44, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0xD6, 0xD7, 0xD6, 0x55, 0x55, - 0x55, 0x59, 0x59, 0xDE, 0xDF, 0x41, 0x41, 0x41, 0x41, 0xC4, 0xC5, 0xC4, 0x43, - 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0x44, 0x4E, 0x4F, 0x4F, 0x4F, - 0x4F, 0xD6, 0xF7, 0xD6, 0x55, 0x55, 0x55, 0x59, 0x59, 0xDE, 0x59, - - /* Mac */ - 0x80, 0x81, 0x43, 0x45, 0x4E, 0x85, 0x59, 0x41, 0x41, 0x41, 0x80, 0x41, 0x81, - 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0x4E, 0x4F, 0x4F, 0x4F, - 0x85, 0x4F, 0x55, 0x55, 0x55, 0x59, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, - 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0x80, 0x85, 0xB0, 0xB1, 0xB2, 0xB3, - 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0x41, 0x4F, 0xBD, 0x80, 0x85, 0xC0, - 0xC1, 0xC2, 0xC3, 0x46, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0x09, 0x41, 0x41, 0x4F, - 0xCE, 0xCE, 0x2D, 0x2D, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0x59, 0x59, 0xDA, - 0xDB, 0xDC, 0xDD, 0x3F, 0x3F, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0x41, 0x45, 0x41, - 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0x4F, 0x4F, 0x3F, 0x4F, 0x55, 0x55, 0x55, - 0x49, 0x00, 0xF7, 0x00, 0xF9, 0xFA, 0xFB, 0x3F, 0xFD, 0xFE, 0x00 -}; - -static const unsigned char Lookup_208[128 * 3] = { - /* Common */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, - 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, - 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, - 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, - 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, - 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, - 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, - 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, - -/* Windows */ - 0x80, 0x81, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x5E, 0x89, 0x8A, 0x8B, 0x8C, - 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, - 0x9A, 0x9B, 0x8C, 0x9D, 0x00, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, - 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, - 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, - 0xC1, 0xC2, 0xC1, 0xC1, 0xC1, 0xC1, 0xC7, 0xC8, 0xC9, 0xC9, 0xCB, 0xCC, 0xCD, - 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, - 0xDB, 0x00, 0xDD, 0xDE, 0xDF, 0x41, 0xE1, 0x41, 0xE3, 0xE4, 0xE5, 0xE6, 0x43, - 0x45, 0x45, 0x45, 0x45, 0xEC, 0xEC, 0x49, 0x49, 0xF0, 0xF1, 0xF2, 0xF3, 0x4F, - 0xF5, 0xF6, 0xF7, 0xF8, 0x55, 0xFA, 0x55, 0x55, 0x00, 0x00, 0xFF, - - /* Mac */ - 0x41, 0x81, 0x43, 0x45, 0x4E, 0x4F, 0x55, 0x41, 0x41, 0x41, 0x41, 0x8B, 0x8C, - 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x93, 0x49, 0x49, 0x4E, 0x4F, 0x98, 0x4F, - 0x4F, 0x9B, 0x55, 0x55, 0x55, 0x55, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, - 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, - 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, - 0xC1, 0xC2, 0xC1, 0xC1, 0xC1, 0xC1, 0xC7, 0xC8, 0xC9, 0xC9, 0xCB, 0xCC, 0xCD, - 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, - 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0x00, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, - 0xE8, 0xE9, 0xE9, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, - 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, -}; - -static const unsigned char Lookup_224[128 * 3] = { - /* Common */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, - 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, - 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, - 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, - 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, - 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, - 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, - 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, - -/* Windows */ - 0x80, 0x81, 0x82, 0x46, 0x84, 0x85, 0x86, 0x87, 0x5E, 0x89, 0x8A, 0x8B, 0x8C, - 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, - 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, - 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0x32, 0x33, - 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0x31, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, - 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, - 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, - 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, - 0xE8, 0xE9, 0xEA, 0xEA, 0xEC, 0xED, 0xED, 0xEF, 0xEF, 0xF1, 0xF2, 0xF3, 0xF3, - 0xF5, 0xF5, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0x00, 0x00, 0xFF, - - /* Mac */ - 0x41, 0x41, 0x43, 0x45, 0x4E, 0x4F, 0x55, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, - 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0x4E, 0x4F, 0x4F, 0x4F, - 0x4F, 0x4F, 0x55, 0x55, 0x55, 0x55, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, - 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, - 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, - 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, - 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, - 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, - 0xE8, 0xE9, 0xEA, 0xEA, 0xEC, 0xED, 0xED, 0xEF, 0xEF, 0xF1, 0xF2, 0xF3, 0xF3, - 0xF5, 0xF5, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, -}; - -/*********************************************************************** - * lhash_val_of_name_sys - * - * Copy of oleaut32.LHashValOfNameSysA - * Produce a string hash value. - * - * PARAMS - * skind [I] Type of the system. - * lcid [I] Locale id for the hash. - * lpStr [I] String to hash. - * - * RETURNS - * Success: The hash value of the string. - * Failure: 0, if lpStr is NULL. - * - * NOTES - * This function produces a two part hash: The high word is based on - * skind and lcid, while the low word is based on a repeated string - * hash of skind/str. - */ -unsigned long lhash_val_of_name_sys( syskind_t skind, LCID lcid, LPCSTR lpStr) -{ - ULONG nOffset, nMask = skind == SYS_MAC ? 1 : 0; - ULONG nHiWord, nLoWord = 0x0deadbee; - const unsigned char *str = (const unsigned char *)lpStr, *pnLookup = NULL; - - if (!str) - return 0; - - switch (PRIMARYLANGID(LANGIDFROMLCID(lcid))) - { - default: - fprintf(stderr, "Unknown lcid %x, treating as latin-based, please report\n", lcid); - /* .. Fall Through .. */ - case LANG_AFRIKAANS: case LANG_ALBANIAN: case LANG_ARMENIAN: - case LANG_ASSAMESE: case LANG_AZERI: case LANG_BASQUE: - case LANG_BELARUSIAN: case LANG_BENGALI: case LANG_BULGARIAN: - case LANG_CATALAN: case LANG_DANISH: case LANG_DIVEHI: - case LANG_DUTCH: case LANG_ENGLISH: case LANG_ESTONIAN: - case LANG_FAEROESE: case LANG_FINNISH: case LANG_FRENCH: - case LANG_GALICIAN: case LANG_GEORGIAN: case LANG_GERMAN: - case LANG_GUJARATI: case LANG_HINDI: case LANG_INDONESIAN: - case LANG_ITALIAN: case LANG_KANNADA: case LANG_KASHMIRI: - case LANG_KAZAK: case LANG_KONKANI: case LANG_KYRGYZ: - case LANG_LATVIAN: case LANG_LITHUANIAN: case LANG_MACEDONIAN: - case LANG_MALAY: case LANG_MALAYALAM: case LANG_MANIPURI: - case LANG_MARATHI: case LANG_MONGOLIAN: case LANG_NEPALI: - case LANG_ORIYA: case LANG_PORTUGUESE: case LANG_PUNJABI: - case LANG_ROMANIAN: case LANG_SANSKRIT: case LANG_SERBIAN: - case LANG_SINDHI: case LANG_SLOVENIAN: case LANG_SWAHILI: - case LANG_SWEDISH: case LANG_SYRIAC: case LANG_TAMIL: - case LANG_TATAR: case LANG_TELUGU: case LANG_THAI: - case LANG_UKRAINIAN: case LANG_URDU: case LANG_UZBEK: - case LANG_VIETNAMESE: case LANG_GAELIC: case LANG_MALTESE: - case LANG_TAJIK: case LANG_ROMANSH: case LANG_IRISH: - case LANG_SAMI: case LANG_UPPER_SORBIAN: case LANG_SUTU: - case LANG_TSONGA: case LANG_TSWANA: case LANG_VENDA: - case LANG_XHOSA: case LANG_ZULU: case LANG_ESPERANTO: - case LANG_WALON: case LANG_CORNISH: case LANG_WELSH: - case LANG_BRETON: - nOffset = 16; - pnLookup = Lookup_16; - break; - case LANG_CZECH: case LANG_HUNGARIAN: case LANG_POLISH: - case LANG_SLOVAK: case LANG_SPANISH: - nOffset = 32; - pnLookup = Lookup_32; - break; - case LANG_HEBREW: - nOffset = 48; - pnLookup = Lookup_48; - break; - case LANG_JAPANESE: - nOffset = 64; - pnLookup = Lookup_64; - break; - case LANG_KOREAN: - nOffset = 80; - pnLookup = Lookup_80; - break; - case LANG_CHINESE: - nOffset = 112; - pnLookup = Lookup_112; - break; - case LANG_GREEK: - nOffset = 128; - pnLookup = Lookup_128; - break; - case LANG_ICELANDIC: - nOffset = 144; - pnLookup = Lookup_144; - break; - case LANG_TURKISH: - nOffset = 160; - pnLookup = Lookup_160; - break; - case LANG_NORWEGIAN: - if (SUBLANGID(LANGIDFROMLCID(lcid)) == SUBLANG_NORWEGIAN_NYNORSK) - { - nOffset = 176; - pnLookup = Lookup_176; - } - else - { - nOffset = 16; - pnLookup = Lookup_16; - } - break; - case LANG_ARABIC: - case LANG_FARSI: - nOffset = 208; - pnLookup = Lookup_208; - break; - case LANG_RUSSIAN: - nOffset = 224; - pnLookup = Lookup_224; - break; - } - - nHiWord = (nOffset | nMask) << 16; - - while (*str) - { - nLoWord = 37 * nLoWord + pnLookup[*str > 0x7f && nMask ? *str + 0x80 : *str]; - str++; - } - /* Constrain to a prime modulo and sizeof(WORD) */ - nLoWord = (nLoWord % 65599) & 0xffff; - - return nHiWord | nLoWord; -} diff --git a/reactos/tools/widl_new/hash.h b/reactos/tools/widl_new/hash.h deleted file mode 100644 index bb787abab83..00000000000 --- a/reactos/tools/widl_new/hash.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Hash definitions - * - * Copyright 2005 Huw Davies - * - * 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 - * - */ - -#ifndef __WIDL_HASH_H -#define __WIDL_HASH_H - -typedef enum tag_syskind_t { - SYS_WIN16 = 0, - SYS_WIN32, - SYS_MAC -} syskind_t; - -extern unsigned long lhash_val_of_name_sys( syskind_t skind, LCID lcid, LPCSTR lpStr); - -#endif diff --git a/reactos/tools/widl_new/header.c b/reactos/tools/widl_new/header.c deleted file mode 100644 index d4bce464d79..00000000000 --- a/reactos/tools/widl_new/header.c +++ /dev/null @@ -1,944 +0,0 @@ -/* - * IDL Compiler - * - * Copyright 2002 Ove Kaaven - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" - -#include -#include -#include -#ifdef HAVE_UNISTD_H -# include -#endif -#include -#include -#include -#include - -#include "windef.h" -#include "widl.h" -#include "utils.h" -#include "parser.h" -#include "header.h" - -static int indentation = 0; - -static void indent(FILE *h, int delta) -{ - int c; - if (delta < 0) indentation += delta; - for (c=0; c 0) indentation += delta; -} - -int is_ptrchain_attr(const var_t *var, enum attr_type t) -{ - if (is_attr(var->attrs, t)) - return 1; - else - { - type_t *type = var->type; - for (;;) - { - if (is_attr(type->attrs, t)) - return 1; - else if (type->kind == TKIND_ALIAS) - type = type->orig; - else if (is_ptr(type)) - type = type->ref; - else return 0; - } - } -} - -int is_attr(const attr_list_t *list, enum attr_type t) -{ - const attr_t *attr; - if (list) LIST_FOR_EACH_ENTRY( attr, list, const attr_t, entry ) - if (attr->type == t) return 1; - return 0; -} - -void *get_attrp(const attr_list_t *list, enum attr_type t) -{ - const attr_t *attr; - if (list) LIST_FOR_EACH_ENTRY( attr, list, const attr_t, entry ) - if (attr->type == t) return attr->u.pval; - return NULL; -} - -unsigned long get_attrv(const attr_list_t *list, enum attr_type t) -{ - const attr_t *attr; - if (list) LIST_FOR_EACH_ENTRY( attr, list, const attr_t, entry ) - if (attr->type == t) return attr->u.ival; - return 0; -} - -int is_void(const type_t *t) -{ - if (!t->type && !t->ref) return 1; - return 0; -} - -int is_conformant_array(const type_t *t) -{ - return t->type == RPC_FC_CARRAY || t->type == RPC_FC_CVARRAY; -} - -void write_guid(FILE *f, const char *guid_prefix, const char *name, const UUID *uuid) -{ - if (!uuid) return; - fprintf(f, "DEFINE_GUID(%s_%s, 0x%08x, 0x%04x, 0x%04x, 0x%02x,0x%02x, 0x%02x," - "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x);\n", - guid_prefix, name, uuid->Data1, uuid->Data2, uuid->Data3, uuid->Data4[0], - uuid->Data4[1], uuid->Data4[2], uuid->Data4[3], uuid->Data4[4], uuid->Data4[5], - uuid->Data4[6], uuid->Data4[7]); -} - -void write_name(FILE *h, const var_t *v) -{ - if (is_attr( v->attrs, ATTR_PROPGET )) - fprintf(h, "get_" ); - else if (is_attr( v->attrs, ATTR_PROPPUT )) - fprintf(h, "put_" ); - else if (is_attr( v->attrs, ATTR_PROPPUTREF )) - fprintf(h, "putref_" ); - fprintf(h, "%s", v->name); -} - -void write_prefix_name(FILE *h, const char *prefix, const var_t *v) -{ - fprintf(h, "%s", prefix); - write_name(h, v); -} - -static void write_field(FILE *h, var_t *v) -{ - if (!v) return; - if (v->type) { - const char *name = v->name; - if (name == NULL) { - switch (v->type->type) { - case RPC_FC_STRUCT: - case RPC_FC_CVSTRUCT: - case RPC_FC_CPSTRUCT: - case RPC_FC_CSTRUCT: - case RPC_FC_PSTRUCT: - case RPC_FC_BOGUS_STRUCT: - case RPC_FC_ENCAPSULATED_UNION: - name = "DUMMYSTRUCTNAME"; - break; - case RPC_FC_NON_ENCAPSULATED_UNION: - name = "DUMMYUNIONNAME"; - break; - default: - /* ? */ - break; - } - } - indent(h, 0); - write_type(h, v->type, TRUE, "%s", name); - fprintf(h, ";\n"); - } -} - -static void write_fields(FILE *h, var_list_t *fields) -{ - var_t *v; - if (!fields) return; - LIST_FOR_EACH_ENTRY( v, fields, var_t, entry ) write_field(h, v); -} - -static void write_enums(FILE *h, var_list_t *enums) -{ - var_t *v; - if (!enums) return; - LIST_FOR_EACH_ENTRY( v, enums, var_t, entry ) - { - if (v->name) { - indent(h, 0); - write_name(h, v); - if (v->eval) { - fprintf(h, " = "); - write_expr(h, v->eval, 0); - } - } - if (list_next( enums, &v->entry )) fprintf(h, ",\n"); - } - fprintf(h, "\n"); -} - -int needs_space_after(type_t *t) -{ - return (t->kind == TKIND_ALIAS - || (!is_ptr(t) && (!is_conformant_array(t) || t->declarray))); -} - -void write_type_left(FILE *h, type_t *t) -{ - if (t->is_const) fprintf(h, "const "); - - if (t->kind == TKIND_ALIAS) fprintf(h, "%s", t->name); - else if (t->declarray) write_type_left(h, t->ref); - else { - if (t->sign > 0) fprintf(h, "signed "); - else if (t->sign < 0) fprintf(h, "unsigned "); - switch (t->type) { - case RPC_FC_ENUM16: - case RPC_FC_ENUM32: - if (t->defined && !t->written && !t->ignore) { - if (t->name) fprintf(h, "enum %s {\n", t->name); - else fprintf(h, "enum {\n"); - t->written = TRUE; - indentation++; - write_enums(h, t->fields); - indent(h, -1); - fprintf(h, "}"); - } - else fprintf(h, "enum %s", t->name); - break; - case RPC_FC_STRUCT: - case RPC_FC_CVSTRUCT: - case RPC_FC_CPSTRUCT: - case RPC_FC_CSTRUCT: - case RPC_FC_PSTRUCT: - case RPC_FC_BOGUS_STRUCT: - case RPC_FC_ENCAPSULATED_UNION: - if (t->defined && !t->written && !t->ignore) { - if (t->name) fprintf(h, "struct %s {\n", t->name); - else fprintf(h, "struct {\n"); - t->written = TRUE; - indentation++; - write_fields(h, t->fields); - indent(h, -1); - fprintf(h, "}"); - } - else fprintf(h, "struct %s", t->name); - break; - case RPC_FC_NON_ENCAPSULATED_UNION: - if (t->defined && !t->written && !t->ignore) { - if (t->name) fprintf(h, "union %s {\n", t->name); - else fprintf(h, "union {\n"); - t->written = TRUE; - indentation++; - write_fields(h, t->fields); - indent(h, -1); - fprintf(h, "}"); - } - else fprintf(h, "union %s", t->name); - break; - case RPC_FC_RP: - case RPC_FC_UP: - case RPC_FC_FP: - case RPC_FC_OP: - case RPC_FC_CARRAY: - case RPC_FC_CVARRAY: - write_type_left(h, t->ref); - fprintf(h, "%s*", needs_space_after(t->ref) ? " " : ""); - break; - default: - fprintf(h, "%s", t->name); - } - } -} - -void write_type_right(FILE *h, type_t *t, int is_field) -{ - if (t->declarray) { - if (is_conformant_array(t)) { - fprintf(h, "[%s]", is_field ? "1" : ""); - t = t->ref; - } - for ( ; t->declarray; t = t->ref) - fprintf(h, "[%lu]", t->dim); - } -} - -void write_type(FILE *h, type_t *t, int is_field, const char *fmt, ...) -{ - write_type_left(h, t); - if (fmt) { - va_list args; - va_start(args, fmt); - if (needs_space_after(t)) - fprintf(h, " "); - vfprintf(h, fmt, args); - va_end(args); - } - write_type_right(h, t, is_field); -} - -user_type_list_t user_type_list = LIST_INIT(user_type_list); - -static int user_type_registered(const char *name) -{ - user_type_t *ut; - LIST_FOR_EACH_ENTRY(ut, &user_type_list, user_type_t, entry) - if (!strcmp(name, ut->name)) - return 1; - return 0; -} - -void check_for_user_types(const var_list_t *list) -{ - const var_t *v; - - if (!list) return; - LIST_FOR_EACH_ENTRY( v, list, const var_t, entry ) - { - type_t *type; - for (type = v->type; type; type = type->kind == TKIND_ALIAS ? type->orig : type->ref) { - const char *name = type->name; - if (type->user_types_registered) continue; - type->user_types_registered = 1; - if (is_attr(type->attrs, ATTR_WIREMARSHAL)) { - if (!user_type_registered(name)) - { - user_type_t *ut = xmalloc(sizeof *ut); - ut->name = xstrdup(name); - list_add_tail(&user_type_list, &ut->entry); - } - /* don't carry on parsing fields within this type as we are already - * using a wire marshaled type */ - break; - } - else - { - check_for_user_types(type->fields); - } - } - } -} - -void write_user_types(void) -{ - user_type_t *ut; - LIST_FOR_EACH_ENTRY(ut, &user_type_list, user_type_t, entry) - { - const char *name = ut->name; - fprintf(header, "ULONG __RPC_USER %s_UserSize (ULONG *, ULONG, %s *);\n", name, name); - fprintf(header, "unsigned char * __RPC_USER %s_UserMarshal (ULONG *, unsigned char *, %s *);\n", name, name); - fprintf(header, "unsigned char * __RPC_USER %s_UserUnmarshal(ULONG *, unsigned char *, %s *);\n", name, name); - fprintf(header, "void __RPC_USER %s_UserFree (ULONG *, %s *);\n", name, name); - } -} - -void write_typedef(type_t *type) -{ - fprintf(header, "typedef "); - write_type(header, type->orig, FALSE, "%s", type->name); - fprintf(header, ";\n"); -} - -void write_expr(FILE *h, const expr_t *e, int brackets) -{ - switch (e->type) { - case EXPR_VOID: - break; - case EXPR_NUM: - fprintf(h, "%lu", e->u.lval); - break; - case EXPR_HEXNUM: - fprintf(h, "0x%lx", e->u.lval); - break; - case EXPR_DOUBLE: - fprintf(h, "%#.15g", e->u.dval); - break; - case EXPR_TRUEFALSE: - if (e->u.lval == 0) - fprintf(h, "FALSE"); - else - fprintf(h, "TRUE"); - break; - case EXPR_IDENTIFIER: - fprintf(h, "%s", e->u.sval); - break; - case EXPR_NEG: - fprintf(h, "-"); - write_expr(h, e->ref, 1); - break; - case EXPR_NOT: - fprintf(h, "~"); - write_expr(h, e->ref, 1); - break; - case EXPR_PPTR: - fprintf(h, "*"); - write_expr(h, e->ref, 1); - break; - case EXPR_CAST: - fprintf(h, "("); - write_type(h, e->u.tref, FALSE, NULL); - fprintf(h, ")"); - write_expr(h, e->ref, 1); - break; - case EXPR_SIZEOF: - fprintf(h, "sizeof("); - write_type(h, e->u.tref, FALSE, NULL); - fprintf(h, ")"); - break; - case EXPR_SHL: - case EXPR_SHR: - case EXPR_MUL: - case EXPR_DIV: - case EXPR_ADD: - case EXPR_SUB: - case EXPR_AND: - case EXPR_OR: - if (brackets) fprintf(h, "("); - write_expr(h, e->ref, 1); - switch (e->type) { - case EXPR_SHL: fprintf(h, " << "); break; - case EXPR_SHR: fprintf(h, " >> "); break; - case EXPR_MUL: fprintf(h, " * "); break; - case EXPR_DIV: fprintf(h, " / "); break; - case EXPR_ADD: fprintf(h, " + "); break; - case EXPR_SUB: fprintf(h, " - "); break; - case EXPR_AND: fprintf(h, " & "); break; - case EXPR_OR: fprintf(h, " | "); break; - default: break; - } - write_expr(h, e->u.ext, 1); - if (brackets) fprintf(h, ")"); - break; - case EXPR_COND: - if (brackets) fprintf(h, "("); - write_expr(h, e->ref, 1); - fprintf(h, " ? "); - write_expr(h, e->u.ext, 1); - fprintf(h, " : "); - write_expr(h, e->ext2, 1); - if (brackets) fprintf(h, ")"); - break; - } -} - -void write_constdef(const var_t *v) -{ - fprintf(header, "#define %s (", v->name); - write_expr(header, v->eval, 0); - fprintf(header, ")\n\n"); -} - -void write_externdef(const var_t *v) -{ - fprintf(header, "extern const "); - write_type(header, v->type, FALSE, "%s", v->name); - fprintf(header, ";\n\n"); -} - -void write_library(const char *name, const attr_list_t *attr) -{ - const UUID *uuid = get_attrp(attr, ATTR_UUID); - fprintf(header, "\n"); - write_guid(header, "LIBID", name, uuid); - fprintf(header, "\n"); -} - - -const var_t* get_explicit_handle_var(const func_t* func) -{ - const var_t* var; - - if (!func->args) - return NULL; - - LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) - if (var->type->type == RPC_FC_BIND_PRIMITIVE) - return var; - - return NULL; -} - -int has_out_arg_or_return(const func_t *func) -{ - const var_t *var; - - if (!is_void(func->def->type)) - return 1; - - if (!func->args) - return 0; - - LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) - if (is_attr(var->attrs, ATTR_OUT)) - return 1; - - return 0; -} - - -/********** INTERFACES **********/ - -int is_object(const attr_list_t *list) -{ - const attr_t *attr; - if (list) LIST_FOR_EACH_ENTRY( attr, list, const attr_t, entry ) - if (attr->type == ATTR_OBJECT || attr->type == ATTR_ODL) return 1; - return 0; -} - -int is_local(const attr_list_t *a) -{ - return is_attr(a, ATTR_LOCAL); -} - -const var_t *is_callas(const attr_list_t *a) -{ - return get_attrp(a, ATTR_CALLAS); -} - -static void write_method_macro(const type_t *iface, const char *name) -{ - const func_t *cur; - - if (iface->ref) write_method_macro(iface->ref, name); - - if (!iface->funcs) return; - - fprintf(header, "/*** %s methods ***/\n", iface->name); - LIST_FOR_EACH_ENTRY( cur, iface->funcs, const func_t, entry ) - { - var_t *def = cur->def; - if (!is_callas(def->attrs)) { - const var_t *arg; - int argc = 0; - int c; - - if (cur->args) LIST_FOR_EACH_ENTRY( arg, cur->args, const var_t, entry ) argc++; - - fprintf(header, "#define %s_", name); - write_name(header,def); - fprintf(header, "(p"); - for (c=0; clpVtbl->"); - write_name(header, def); - fprintf(header, "(p"); - for (c=0; cargs) - { - write_type_left(h, arg->type); - fprintf(h, " (STDMETHODCALLTYPE *"); - write_name(h,arg); - fprintf(h, ")("); - write_args(h, arg->args, NULL, 0, FALSE); - fprintf(h, ")"); - } - else - write_type(h, arg->type, FALSE, "%s", arg->name); - count++; - } - if (do_indent) indentation--; -} - -static void write_cpp_method_def(const type_t *iface) -{ - const func_t *cur; - - if (!iface->funcs) return; - - LIST_FOR_EACH_ENTRY( cur, iface->funcs, const func_t, entry ) - { - var_t *def = cur->def; - if (!is_callas(def->attrs)) { - indent(header, 0); - fprintf(header, "virtual "); - write_type_left(header, def->type); - fprintf(header, " STDMETHODCALLTYPE "); - write_name(header, def); - fprintf(header, "(\n"); - write_args(header, cur->args, iface->name, 2, TRUE); - fprintf(header, ") = 0;\n"); - fprintf(header, "\n"); - } - } -} - -static void do_write_c_method_def(const type_t *iface, const char *name) -{ - const func_t *cur; - - if (iface->ref) do_write_c_method_def(iface->ref, name); - - if (!iface->funcs) return; - indent(header, 0); - fprintf(header, "/*** %s methods ***/\n", iface->name); - LIST_FOR_EACH_ENTRY( cur, iface->funcs, const func_t, entry ) - { - const var_t *def = cur->def; - if (!is_callas(def->attrs)) { - indent(header, 0); - write_type_left(header, def->type); - fprintf(header, " (STDMETHODCALLTYPE *"); - write_name(header, def); - fprintf(header, ")(\n"); - write_args(header, cur->args, name, 1, TRUE); - fprintf(header, ");\n"); - fprintf(header, "\n"); - } - } -} - -static void write_c_method_def(const type_t *iface) -{ - do_write_c_method_def(iface, iface->name); -} - -static void write_c_disp_method_def(const type_t *iface) -{ - do_write_c_method_def(iface->ref, iface->name); -} - -static void write_method_proto(const type_t *iface) -{ - const func_t *cur; - - if (!iface->funcs) return; - LIST_FOR_EACH_ENTRY( cur, iface->funcs, const func_t, entry ) - { - const var_t *def = cur->def; - const var_t *cas = is_callas(def->attrs); - - if (!is_local(def->attrs)) { - /* proxy prototype */ - write_type_left(header, def->type); - fprintf(header, " CALLBACK %s_", iface->name); - write_name(header, def); - fprintf(header, "_Proxy(\n"); - write_args(header, cur->args, iface->name, 1, TRUE); - fprintf(header, ");\n"); - /* stub prototype */ - fprintf(header, "void __RPC_STUB %s_", iface->name); - write_name(header,def); - fprintf(header, "_Stub(\n"); - fprintf(header, " IRpcStubBuffer* This,\n"); - fprintf(header, " IRpcChannelBuffer* pRpcChannelBuffer,\n"); - fprintf(header, " PRPC_MESSAGE pRpcMessage,\n"); - fprintf(header, " DWORD* pdwStubPhase);\n"); - } - if (cas) { - const func_t *m; - LIST_FOR_EACH_ENTRY( m, iface->funcs, const func_t, entry ) - if (!strcmp(m->def->name, cas->name)) break; - if (&m->entry != iface->funcs) { - const var_t *mdef = m->def; - /* proxy prototype - use local prototype */ - write_type_left(header, mdef->type); - fprintf(header, " CALLBACK %s_", iface->name); - write_name(header, mdef); - fprintf(header, "_Proxy(\n"); - write_args(header, m->args, iface->name, 1, TRUE); - fprintf(header, ");\n"); - /* stub prototype - use remotable prototype */ - write_type_left(header, def->type); - fprintf(header, " __RPC_STUB %s_", iface->name); - write_name(header, mdef); - fprintf(header, "_Stub(\n"); - write_args(header, cur->args, iface->name, 1, TRUE); - fprintf(header, ");\n"); - } - else { - parser_warning("invalid call_as attribute (%s -> %s)\n", def->name, cas->name); - } - } - } -} - -static void write_function_proto(const type_t *iface, const func_t *fun, const char *prefix) -{ - var_t *def = fun->def; - - /* FIXME: do we need to handle call_as? */ - write_type_left(header, def->type); - fprintf(header, " "); - write_prefix_name(header, prefix, def); - fprintf(header, "(\n"); - if (fun->args) - write_args(header, fun->args, iface->name, 0, TRUE); - else - fprintf(header, " void"); - fprintf(header, ");\n"); -} - -static void write_function_protos(const type_t *iface) -{ - const char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE); - int explicit_handle = is_attr(iface->attrs, ATTR_EXPLICIT_HANDLE); - const var_t* explicit_handle_var; - const func_t *cur; - int prefixes_differ = strcmp(prefix_client, prefix_server); - - if (!iface->funcs) return; - LIST_FOR_EACH_ENTRY( cur, iface->funcs, const func_t, entry ) - { - var_t *def = cur->def; - - /* check for a defined binding handle */ - explicit_handle_var = get_explicit_handle_var(cur); - if (explicit_handle) { - if (!explicit_handle_var) { - error("%s() does not define an explicit binding handle!\n", def->name); - return; - } - } else if (implicit_handle) { - if (explicit_handle_var) { - error("%s() must not define a binding handle!\n", def->name); - return; - } - } - - if (prefixes_differ) { - fprintf(header, "/* client prototype */\n"); - write_function_proto(iface, cur, prefix_client); - fprintf(header, "/* server prototype */\n"); - } - write_function_proto(iface, cur, prefix_server); - } -} - -void write_forward(type_t *iface) -{ - /* C/C++ forwards should only be written for object interfaces, so if we - * have a full definition we only write one if we find [object] among the - * attributes - however, if we don't have a full definition at this point - * (i.e. this is an IDL forward), then we also assume that it is an object - * interface, since non-object interfaces shouldn't need forwards */ - if ((!iface->defined || is_object(iface->attrs) || is_attr(iface->attrs, ATTR_DISPINTERFACE)) - && !iface->written) { - fprintf(header, "#ifndef __%s_FWD_DEFINED__\n", iface->name); - fprintf(header, "#define __%s_FWD_DEFINED__\n", iface->name); - fprintf(header, "typedef interface %s %s;\n", iface->name, iface->name); - fprintf(header, "#endif\n\n" ); - iface->written = TRUE; - } -} - -static void write_iface_guid(const type_t *iface) -{ - const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID); - write_guid(header, "IID", iface->name, uuid); -} - -static void write_dispiface_guid(const type_t *iface) -{ - const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID); - write_guid(header, "DIID", iface->name, uuid); -} - -static void write_coclass_guid(type_t *cocl) -{ - const UUID *uuid = get_attrp(cocl->attrs, ATTR_UUID); - write_guid(header, "CLSID", cocl->name, uuid); -} - -static void write_com_interface(type_t *iface) -{ - if (!iface->funcs && !iface->ref) { - parser_warning("%s has no methods", iface->name); - return; - } - - fprintf(header, "/*****************************************************************************\n"); - fprintf(header, " * %s interface\n", iface->name); - fprintf(header, " */\n"); - fprintf(header,"#ifndef __%s_INTERFACE_DEFINED__\n", iface->name); - fprintf(header,"#define __%s_INTERFACE_DEFINED__\n\n", iface->name); - write_iface_guid(iface); - write_forward(iface); - /* C++ interface */ - fprintf(header, "#if defined(__cplusplus) && !defined(CINTERFACE)\n"); - if (iface->ref) - { - fprintf(header, "interface %s : public %s\n", iface->name, iface->ref->name); - fprintf(header, "{\n"); - indentation++; - write_cpp_method_def(iface); - indentation--; - fprintf(header, "};\n"); - } - else - { - fprintf(header, "interface %s\n", iface->name); - fprintf(header, "{\n"); - fprintf(header, " BEGIN_INTERFACE\n"); - fprintf(header, "\n"); - indentation++; - write_cpp_method_def(iface); - indentation--; - fprintf(header, " END_INTERFACE\n"); - fprintf(header, "};\n"); - } - fprintf(header, "#else\n"); - /* C interface */ - fprintf(header, "typedef struct %sVtbl {\n", iface->name); - indentation++; - fprintf(header, " BEGIN_INTERFACE\n"); - fprintf(header, "\n"); - write_c_method_def(iface); - indentation--; - fprintf(header, " END_INTERFACE\n"); - fprintf(header, "} %sVtbl;\n", iface->name); - fprintf(header, "interface %s {\n", iface->name); - fprintf(header, " CONST_VTBL %sVtbl* lpVtbl;\n", iface->name); - fprintf(header, "};\n"); - fprintf(header, "\n"); - fprintf(header, "#ifdef COBJMACROS\n"); - write_method_macro(iface, iface->name); - fprintf(header, "#endif\n"); - fprintf(header, "\n"); - fprintf(header, "#endif\n"); - fprintf(header, "\n"); - write_method_proto(iface); - fprintf(header,"\n#endif /* __%s_INTERFACE_DEFINED__ */\n\n", iface->name); -} - -static void write_rpc_interface(const type_t *iface) -{ - unsigned long ver = get_attrv(iface->attrs, ATTR_VERSION); - const char *var = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE); - static int allocate_written = 0; - - if (!allocate_written) - { - allocate_written = 1; - fprintf(header, "void * __RPC_USER MIDL_user_allocate(size_t);\n"); - fprintf(header, "void __RPC_USER MIDL_user_free(void *);\n\n"); - } - - fprintf(header, "/*****************************************************************************\n"); - fprintf(header, " * %s interface (v%d.%d)\n", iface->name, LOWORD(ver), HIWORD(ver)); - fprintf(header, " */\n"); - fprintf(header,"#ifndef __%s_INTERFACE_DEFINED__\n", iface->name); - fprintf(header,"#define __%s_INTERFACE_DEFINED__\n\n", iface->name); - if (iface->funcs) - { - write_iface_guid(iface); - if (var) fprintf(header, "extern handle_t %s;\n", var); - if (old_names) - { - fprintf(header, "extern RPC_IF_HANDLE %s%s_ClientIfHandle;\n", prefix_client, iface->name); - fprintf(header, "extern RPC_IF_HANDLE %s%s_ServerIfHandle;\n", prefix_server, iface->name); - } - else - { - fprintf(header, "extern RPC_IF_HANDLE %s%s_v%d_%d_c_ifspec;\n", - prefix_client, iface->name, LOWORD(ver), HIWORD(ver)); - fprintf(header, "extern RPC_IF_HANDLE %s%s_v%d_%d_s_ifspec;\n", - prefix_server, iface->name, LOWORD(ver), HIWORD(ver)); - } - write_function_protos(iface); - } - fprintf(header,"\n#endif /* __%s_INTERFACE_DEFINED__ */\n\n", iface->name); - - /* FIXME: server/client code */ -} - -void write_interface(type_t *iface) -{ - if (is_object(iface->attrs)) - write_com_interface(iface); - else - write_rpc_interface(iface); -} - -void write_dispinterface(type_t *iface) -{ - fprintf(header, "/*****************************************************************************\n"); - fprintf(header, " * %s dispinterface\n", iface->name); - fprintf(header, " */\n"); - fprintf(header,"#ifndef __%s_DISPINTERFACE_DEFINED__\n", iface->name); - fprintf(header,"#define __%s_DISPINTERFACE_DEFINED__\n\n", iface->name); - write_dispiface_guid(iface); - write_forward(iface); - /* C++ interface */ - fprintf(header, "#if defined(__cplusplus) && !defined(CINTERFACE)\n"); - fprintf(header, "interface %s : public %s\n", iface->name, iface->ref->name); - fprintf(header, "{\n"); - fprintf(header, "};\n"); - fprintf(header, "#else\n"); - /* C interface */ - fprintf(header, "typedef struct %sVtbl {\n", iface->name); - indentation++; - fprintf(header, " BEGIN_INTERFACE\n"); - fprintf(header, "\n"); - write_c_disp_method_def(iface); - indentation--; - fprintf(header, " END_INTERFACE\n"); - fprintf(header, "} %sVtbl;\n", iface->name); - fprintf(header, "interface %s {\n", iface->name); - fprintf(header, " CONST_VTBL %sVtbl* lpVtbl;\n", iface->name); - fprintf(header, "};\n"); - fprintf(header, "\n"); - fprintf(header, "#ifdef COBJMACROS\n"); - write_method_macro(iface->ref, iface->name); - fprintf(header, "#endif\n"); - fprintf(header, "\n"); - fprintf(header, "#endif\n"); - fprintf(header, "\n"); - fprintf(header,"#endif /* __%s_DISPINTERFACE_DEFINED__ */\n\n", iface->name); -} - -void write_coclass(type_t *cocl) -{ - fprintf(header, "/*****************************************************************************\n"); - fprintf(header, " * %s coclass\n", cocl->name); - fprintf(header, " */\n\n"); - write_coclass_guid(cocl); - fprintf(header, "\n"); -} - -void write_coclass_forward(type_t *cocl) -{ - fprintf(header, "#ifndef __%s_FWD_DEFINED__\n", cocl->name); - fprintf(header, "#define __%s_FWD_DEFINED__\n", cocl->name); - fprintf(header, "typedef struct %s %s;\n", cocl->name, cocl->name); - fprintf(header, "#endif /* defined __%s_FWD_DEFINED__ */\n\n", cocl->name ); -} diff --git a/reactos/tools/widl_new/header.h b/reactos/tools/widl_new/header.h deleted file mode 100644 index 54655a29b59..00000000000 --- a/reactos/tools/widl_new/header.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * IDL Compiler - * - * Copyright 2002 Ove Kaaven - * - * 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 - */ - -#ifndef __WIDL_HEADER_H -#define __WIDL_HEADER_H - -#include "widltypes.h" - -extern int is_ptrchain_attr(const var_t *var, enum attr_type t); -extern int is_attr(const attr_list_t *list, enum attr_type t); -extern void *get_attrp(const attr_list_t *list, enum attr_type t); -extern unsigned long get_attrv(const attr_list_t *list, enum attr_type t); -extern int is_void(const type_t *t); -extern int is_conformant_array(const type_t *t); -extern void write_name(FILE *h, const var_t *v); -extern void write_prefix_name(FILE *h, const char *prefix, const var_t *v); -extern const char* get_name(const var_t *v); -extern void write_type_left(FILE *h, type_t *t); -extern void write_type_right(FILE *h, type_t *t, int is_field); -extern void write_type(FILE *h, type_t *t, int is_field, const char *fmt, ...); -extern int needs_space_after(type_t *t); -extern int is_object(const attr_list_t *list); -extern int is_local(const attr_list_t *list); -extern const var_t *is_callas(const attr_list_t *list); -extern void write_args(FILE *h, const var_list_t *arg, const char *name, int obj, int do_indent); -extern void write_array(FILE *h, array_dims_t *v, int field); -extern void write_forward(type_t *iface); -extern void write_interface(type_t *iface); -extern void write_dispinterface(type_t *iface); -extern void write_coclass(type_t *cocl); -extern void write_coclass_forward(type_t *cocl); -extern void write_typedef(type_t *type); -extern void write_expr(FILE *h, const expr_t *e, int brackets); -extern void write_constdef(const var_t *v); -extern void write_externdef(const var_t *v); -extern void write_library(const char *name, const attr_list_t *attr); -extern void write_user_types(void); -extern const var_t* get_explicit_handle_var(const func_t* func); -extern int has_out_arg_or_return(const func_t *func); -extern void write_guid(FILE *f, const char *guid_prefix, const char *name, - const UUID *uuid); - -static inline int last_ptr(const type_t *type) -{ - return is_ptr(type) && !is_ptr(type->ref); -} - -static inline int last_array(const type_t *type) -{ - return is_array(type) && !is_array(type->ref); -} - -static inline int is_string_type(const attr_list_t *attrs, const type_t *type) -{ - return is_attr(attrs, ATTR_STRING) && (last_ptr(type) || last_array(type)); -} - -#endif diff --git a/reactos/tools/widl_new/parser.h b/reactos/tools/widl_new/parser.h deleted file mode 100644 index 5baf655c64e..00000000000 --- a/reactos/tools/widl_new/parser.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * IDL Compiler - * - * Copyright 2002 Ove Kaaven - * - * 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 - */ - -#ifndef __WIDL_PARSER_H -#define __WIDL_PARSER_H - -int parser_parse(void); - -extern FILE *parser_in; -extern char *parser_text; -extern int parser_debug; -extern int yy_flex_debug; - -int parser_lex(void); - -extern int import_stack_ptr; -int do_import(char *fname); -void abort_import(void); - -#define parse_only import_stack_ptr - -int is_type(const char *name); - -#endif diff --git a/reactos/tools/widl_new/parser.l b/reactos/tools/widl_new/parser.l deleted file mode 100644 index 4cd98bb2aff..00000000000 --- a/reactos/tools/widl_new/parser.l +++ /dev/null @@ -1,443 +0,0 @@ -/* -*-C-*- - * IDL Compiler - * - * Copyright 2002 Ove Kaaven - * - * 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 - */ - -%option stack -%option nounput noyy_top_state -%option 8bit never-interactive prefix="parser_" - -nl \r?\n -ws [ \f\t\r] -cident [a-zA-Z_][0-9a-zA-Z_]* -int [0-9]+ -hexd [0-9a-fA-F] -hex 0x{hexd}+ -uuid {hexd}{8}-{hexd}{4}-{hexd}{4}-{hexd}{4}-{hexd}{12} -double [0-9]+\.[0-9]+([eE][+-]?[0-9]+)* - -%x QUOTE -%x ATTR -%x PP_LINE - -%{ - -#include "config.h" - -#include -#include -#include -#include -#include -#ifdef HAVE_UNISTD_H -# include -#endif - -#include "widl.h" -#include "utils.h" -#include "parser.h" -#include "wine/wpp.h" - -#include "parser.tab.h" - -extern char *temp_name; - -static void addcchar(char c); -static char *get_buffered_cstring(void); - -static char *cbuffer; -static int cbufidx; -static int cbufalloc = 0; - -static int kw_token(const char *kw); -static int attr_token(const char *kw); - -#define MAX_IMPORT_DEPTH 10 -struct { - YY_BUFFER_STATE state; - char *input_name; - int line_number; - char *temp_name; -} import_stack[MAX_IMPORT_DEPTH]; -int import_stack_ptr = 0; - -static void pop_import(void); - -static UUID* parse_uuid(const char*u) -{ - UUID* uuid = xmalloc(sizeof(UUID)); - char b[3]; - /* it would be nice to use UuidFromStringA */ - uuid->Data1 = strtoul(u, NULL, 16); - uuid->Data2 = strtoul(u+9, NULL, 16); - uuid->Data3 = strtoul(u+14, NULL, 16); - b[2] = 0; - memcpy(b, u+19, 2); uuid->Data4[0] = strtoul(b, NULL, 16); - memcpy(b, u+21, 2); uuid->Data4[1] = strtoul(b, NULL, 16); - memcpy(b, u+24, 2); uuid->Data4[2] = strtoul(b, NULL, 16); - memcpy(b, u+26, 2); uuid->Data4[3] = strtoul(b, NULL, 16); - memcpy(b, u+28, 2); uuid->Data4[4] = strtoul(b, NULL, 16); - memcpy(b, u+30, 2); uuid->Data4[5] = strtoul(b, NULL, 16); - memcpy(b, u+32, 2); uuid->Data4[6] = strtoul(b, NULL, 16); - memcpy(b, u+34, 2); uuid->Data4[7] = strtoul(b, NULL, 16); - return uuid; -} - -%} - -/* - ************************************************************************** - * The flexer starts here - ************************************************************************** - */ -%% -^{ws}*\#{ws}* yy_push_state(PP_LINE); -[^\n]* { - int lineno; - char *cptr, *fname; - yy_pop_state(); - lineno = (int)strtol(yytext, &cptr, 10); - if(!lineno) - parser_error("Malformed '#...' line-directive; invalid linenumber"); - fname = strchr(cptr, '"'); - if(!fname) - parser_error("Malformed '#...' line-directive; missing filename"); - fname++; - cptr = strchr(fname, '"'); - if(!cptr) - parser_error("Malformed '#...' line-directive; missing terminating \""); - *cptr = '\0'; - line_number = lineno - 1; /* We didn't read the newline */ - free( input_name ); - input_name = xstrdup(fname); - } -\" yy_push_state(QUOTE); cbufidx = 0; -\" { - yy_pop_state(); - parser_lval.str = get_buffered_cstring(); - return aSTRING; - } -\\\\ | -\\\" addcchar(yytext[1]); -\\. addcchar('\\'); addcchar(yytext[1]); -. addcchar(yytext[0]); -\[ yy_push_state(ATTR); return '['; -\] yy_pop_state(); return ']'; -{cident} return attr_token(yytext); -{uuid} { - parser_lval.uuid = parse_uuid(yytext); - return aUUID; - } -{hex} { - parser_lval.num = strtoul(yytext, NULL, 0); - return aHEXNUM; - } -{int} { - parser_lval.num = strtoul(yytext, NULL, 0); - return aNUM; - } -{double} { - parser_lval.dbl = strtod(yytext, NULL); - return aDOUBLE; - } -SAFEARRAY{ws}*/\( return tSAFEARRAY; -{cident} return kw_token(yytext); -\n line_number++; -{ws} -\<\< return SHL; -\>\> return SHR; -. return yytext[0]; -<> { - if (import_stack_ptr) { - pop_import(); - return aEOF; - } - else yyterminate(); - } -%% - -#ifndef parser_wrap -int parser_wrap(void) -{ - return 1; -} -#endif - -struct keyword { - const char *kw; - int token; -}; - -static const struct keyword keywords[] = { - {"FALSE", tFALSE}, - {"TRUE", tTRUE}, - {"__cdecl", tCDECL}, - {"__int64", tINT64}, - {"__stdcall", tSTDCALL}, - {"_stdcall", tSTDCALL}, - {"boolean", tBOOLEAN}, - {"byte", tBYTE}, - {"callback", tCALLBACK}, - {"case", tCASE}, - {"char", tCHAR}, - {"coclass", tCOCLASS}, - {"code", tCODE}, - {"comm_status", tCOMMSTATUS}, - {"const", tCONST}, - {"cpp_quote", tCPPQUOTE}, - {"default", tDEFAULT}, - {"dispinterface", tDISPINTERFACE}, - {"double", tDOUBLE}, - {"enum", tENUM}, - {"error_status_t", tERRORSTATUST}, - {"extern", tEXTERN}, - {"float", tFLOAT}, - {"handle_t", tHANDLET}, - {"hyper", tHYPER}, - {"import", tIMPORT}, - {"importlib", tIMPORTLIB}, - {"in_line", tINLINE}, - {"int", tINT}, - {"interface", tINTERFACE}, - {"library", tLIBRARY}, - {"long", tLONG}, - {"methods", tMETHODS}, - {"module", tMODULE}, - {"properties", tPROPERTIES}, - {"short", tSHORT}, - {"signed", tSIGNED}, - {"sizeof", tSIZEOF}, - {"small", tSMALL}, - {"struct", tSTRUCT}, - {"switch", tSWITCH}, - {"typedef", tTYPEDEF}, - {"union", tUNION}, - {"unsigned", tUNSIGNED}, - {"void", tVOID}, - {"wchar_t", tWCHAR}, -}; -#define NKEYWORDS (sizeof(keywords)/sizeof(keywords[0])) - -/* keywords only recognized in attribute lists */ -static const struct keyword attr_keywords[] = -{ - {"aggregatable", tAGGREGATABLE}, - {"allocate", tALLOCATE}, - {"appobject", tAPPOBJECT}, - {"async", tASYNC}, - {"async_uuid", tASYNCUUID}, - {"auto_handle", tAUTOHANDLE}, - {"bindable", tBINDABLE}, - {"broadcast", tBROADCAST}, - {"byte_count", tBYTECOUNT}, - {"call_as", tCALLAS}, - {"context_handle", tCONTEXTHANDLE}, - {"context_handle_noserialize", tCONTEXTHANDLENOSERIALIZE}, - {"context_handle_serialize", tCONTEXTHANDLENOSERIALIZE}, - {"control", tCONTROL}, - {"defaultcollelem", tDEFAULTCOLLELEM}, - {"defaultvalue", tDEFAULTVALUE}, - {"defaultvtable", tDEFAULTVTABLE}, - {"displaybind", tDISPLAYBIND}, - {"dllname", tDLLNAME}, - {"dual", tDUAL}, - {"endpoint", tENDPOINT}, - {"entry", tENTRY}, - {"explicit_handle", tEXPLICITHANDLE}, - {"handle", tHANDLE}, - {"helpcontext", tHELPCONTEXT}, - {"helpfile", tHELPFILE}, - {"helpstring", tHELPSTRING}, - {"helpstringcontext", tHELPSTRINGCONTEXT}, - {"helpstringdll", tHELPSTRINGDLL}, - {"hidden", tHIDDEN}, - {"id", tID}, - {"idempotent", tIDEMPOTENT}, - {"iid_is", tIIDIS}, - {"immediatebind", tIMMEDIATEBIND}, - {"implicit_handle", tIMPLICITHANDLE}, - {"in", tIN}, - {"input_sync", tINPUTSYNC}, - {"lcid", tLCID}, - {"length_is", tLENGTHIS}, - {"local", tLOCAL}, - {"nonbrowsable", tNONBROWSABLE}, - {"noncreatable", tNONCREATABLE}, - {"nonextensible", tNONEXTENSIBLE}, - {"object", tOBJECT}, - {"odl", tODL}, - {"oleautomation", tOLEAUTOMATION}, - {"optional", tOPTIONAL}, - {"out", tOUT}, - {"pointer_default", tPOINTERDEFAULT}, - {"propget", tPROPGET}, - {"propput", tPROPPUT}, - {"propputref", tPROPPUTREF}, - {"ptr", tPTR}, - {"public", tPUBLIC}, - {"range", tRANGE}, - {"readonly", tREADONLY}, - {"ref", tREF}, - {"requestedit", tREQUESTEDIT}, - {"restricted", tRESTRICTED}, - {"retval", tRETVAL}, - {"single", tSINGLE}, - {"size_is", tSIZEIS}, - {"source", tSOURCE}, - {"string", tSTRING}, - {"switch_is", tSWITCHIS}, - {"switch_type", tSWITCHTYPE}, - {"transmit_as", tTRANSMITAS}, - {"unique", tUNIQUE}, - {"uuid", tUUID}, - {"v1_enum", tV1ENUM}, - {"vararg", tVARARG}, - {"version", tVERSION}, - {"wire_marshal", tWIREMARSHAL}, -}; - - -#define KWP(p) ((const struct keyword *)(p)) - -static int kw_cmp_func(const void *s1, const void *s2) -{ - return strcmp(KWP(s1)->kw, KWP(s2)->kw); -} - -static int kw_token(const char *kw) -{ - struct keyword key, *kwp; - key.kw = kw; - kwp = bsearch(&key, keywords, NKEYWORDS, sizeof(keywords[0]), kw_cmp_func); - if (kwp) { - parser_lval.str = xstrdup(kwp->kw); - return kwp->token; - } - parser_lval.str = xstrdup(kw); - return is_type(kw) ? aKNOWNTYPE : aIDENTIFIER; -} - -static int attr_token(const char *kw) -{ - struct keyword key, *kwp; - key.kw = kw; - kwp = bsearch(&key, attr_keywords, sizeof(attr_keywords)/sizeof(attr_keywords[0]), - sizeof(attr_keywords[0]), kw_cmp_func); - if (kwp) { - parser_lval.str = xstrdup(kwp->kw); - return kwp->token; - } - return kw_token(kw); -} - -static void addcchar(char c) -{ - if(cbufidx >= cbufalloc) - { - cbufalloc += 1024; - cbuffer = xrealloc(cbuffer, cbufalloc * sizeof(cbuffer[0])); - if(cbufalloc > 65536) - parser_warning("Reallocating string buffer larger than 64kB"); - } - cbuffer[cbufidx++] = c; -} - -static char *get_buffered_cstring(void) -{ - addcchar(0); - return xstrdup(cbuffer); -} - -static void pop_import(void) -{ - int ptr = import_stack_ptr-1; - - fclose(yyin); - yy_delete_buffer( YY_CURRENT_BUFFER ); - yy_switch_to_buffer( import_stack[ptr].state ); - if (temp_name) { - unlink(temp_name); - free(temp_name); - } - temp_name = import_stack[ptr].temp_name; - free( input_name ); - input_name = import_stack[ptr].input_name; - line_number = import_stack[ptr].line_number; - import_stack_ptr--; -} - -struct imports { - char *name; - struct imports *next; -} *first_import; - -int do_import(char *fname) -{ - FILE *f; - char *hname, *path, *p; - struct imports *import; - int ptr = import_stack_ptr; - int ret; - - if (!parse_only && do_header) { - hname = dup_basename(fname, ".idl"); - p = hname + strlen(hname) - 2; - if (p <= hname || strcmp( p, ".h" )) strcat(hname, ".h"); - - fprintf(header, "#include <%s>\n", hname); - free(hname); - } - - import = first_import; - while (import && strcmp(import->name, fname)) - import = import->next; - if (import) return 0; /* already imported */ - - import = xmalloc(sizeof(struct imports)); - import->name = xstrdup(fname); - import->next = first_import; - first_import = import; - - if (!(path = wpp_find_include( fname, input_name ))) - parser_error("Unable to open include file %s", fname); - - import_stack[ptr].temp_name = temp_name; - import_stack[ptr].input_name = input_name; - import_stack[ptr].line_number = line_number; - import_stack_ptr++; - input_name = path; - line_number = 1; - - ret = wpp_parse_temp( path, NULL, &temp_name ); - if (ret) exit(1); - - if((f = fopen(temp_name, "r")) == NULL) - parser_error("Unable to open %s", temp_name); - - import_stack[ptr].state = YY_CURRENT_BUFFER; - yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE)); - return 1; -} - -void abort_import(void) -{ - int ptr; - - for (ptr=0; ptr -#include -#include -#include -#include -#include -#ifdef HAVE_ALLOCA_H -#include -#endif - -#include "windef.h" - -#include "widl.h" -#include "utils.h" -#include "parser.h" -#include "header.h" -#include "typelib.h" -#include "typegen.h" - -#if defined(YYBYACC) - /* Berkeley yacc (byacc) doesn't seem to know about these */ - /* Some *BSD supplied versions do define these though */ -# ifndef YYEMPTY -# define YYEMPTY (-1) /* Empty lookahead value of yychar */ -# endif -# ifndef YYLEX -# define YYLEX yylex() -# endif - -#elif defined(YYBISON) - /* Bison was used for original development */ - /* #define YYEMPTY -2 */ - /* #define YYLEX yylex() */ - -#else - /* No yacc we know yet */ -# if !defined(YYEMPTY) || !defined(YYLEX) -# error Yacc version/type unknown. This version needs to be verified for settings of YYEMPTY and YYLEX. -# elif defined(__GNUC__) /* gcc defines the #warning directive */ -# warning Yacc version/type unknown. It defines YYEMPTY and YYLEX, but is not tested - /* #else we just take a chance that it works... */ -# endif -#endif - -typedef struct list typelist_t; -struct typenode { - type_t *type; - struct list entry; -}; - -typelist_t incomplete_types = LIST_INIT(incomplete_types); - -static void add_incomplete(type_t *t); -static void fix_incomplete(void); - -static str_list_t *append_str(str_list_t *list, char *str); -static attr_list_t *append_attr(attr_list_t *list, attr_t *attr); -static attr_t *make_attr(enum attr_type type); -static attr_t *make_attrv(enum attr_type type, unsigned long val); -static attr_t *make_attrp(enum attr_type type, void *val); -static expr_t *make_expr(enum expr_type type); -static expr_t *make_exprl(enum expr_type type, long val); -static expr_t *make_exprd(enum expr_type type, double val); -static expr_t *make_exprs(enum expr_type type, char *val); -static expr_t *make_exprt(enum expr_type type, type_t *tref, expr_t *expr); -static expr_t *make_expr1(enum expr_type type, expr_t *expr); -static expr_t *make_expr2(enum expr_type type, expr_t *exp1, expr_t *exp2); -static expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, expr_t *expr3); -static type_t *make_type(unsigned char type, type_t *ref); -static expr_list_t *append_expr(expr_list_t *list, expr_t *expr); -static array_dims_t *append_array(array_dims_t *list, expr_t *expr); -static void set_type(var_t *v, type_t *type, int ptr_level, array_dims_t *arr); -static ifref_list_t *append_ifref(ifref_list_t *list, ifref_t *iface); -static ifref_t *make_ifref(type_t *iface); -static var_list_t *append_var(var_list_t *list, var_t *var); -static var_t *make_var(char *name); -static pident_list_t *append_pident(pident_list_t *list, pident_t *p); -static pident_t *make_pident(var_t *var); -static func_list_t *append_func(func_list_t *list, func_t *func); -static func_t *make_func(var_t *def, var_list_t *args); -static type_t *make_class(char *name); -static type_t *make_safearray(type_t *type); -static type_t *make_builtin(char *name); -static type_t *make_int(int sign); - -static type_t *reg_type(type_t *type, const char *name, int t); -static type_t *reg_typedefs(type_t *type, var_list_t *names, attr_list_t *attrs); -static type_t *find_type(const char *name, int t); -static type_t *find_type2(char *name, int t); -static type_t *get_type(unsigned char type, char *name, int t); -static type_t *get_typev(unsigned char type, var_t *name, int t); -static int get_struct_type(var_list_t *fields); - -static var_t *reg_const(var_t *var); -static var_t *find_const(char *name, int f); - -static void write_libid(const char *name, const attr_list_t *attr); -static void write_clsid(type_t *cls); -static void write_diid(type_t *iface); -static void write_iid(type_t *iface); - -static int compute_method_indexes(type_t *iface); -static char *gen_name(void); -static void process_typedefs(var_list_t *names); -static void check_arg(var_t *arg); -static void check_all_user_types(ifref_list_t *ifaces); - -#define tsENUM 1 -#define tsSTRUCT 2 -#define tsUNION 3 - - - -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif - -/* Enabling verbose error messages. */ -#ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 -#else -# define YYERROR_VERBOSE 0 -#endif - -/* Enabling the token table. */ -#ifndef YYTOKEN_TABLE -# define YYTOKEN_TABLE 0 -#endif - -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE -#line 136 "parser.y" -{ - attr_t *attr; - attr_list_t *attr_list; - str_list_t *str_list; - expr_t *expr; - expr_list_t *expr_list; - array_dims_t *array_dims; - type_t *type; - var_t *var; - var_list_t *var_list; - pident_t *pident; - pident_list_t *pident_list; - func_t *func; - func_list_t *func_list; - ifref_t *ifref; - ifref_list_t *ifref_list; - char *str; - UUID *uuid; - unsigned int num; - double dbl; -} -/* Line 187 of yacc.c. */ -#line 530 "parser.tab.c" - YYSTYPE; -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 -#endif - - - -/* Copy the second part of user declarations. */ - - -/* Line 216 of yacc.c. */ -#line 543 "parser.tab.c" - -#ifdef short -# undef short -#endif - -#ifdef YYTYPE_UINT8 -typedef YYTYPE_UINT8 yytype_uint8; -#else -typedef unsigned char yytype_uint8; -#endif - -#ifdef YYTYPE_INT8 -typedef YYTYPE_INT8 yytype_int8; -#elif (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -typedef signed char yytype_int8; -#else -typedef short int yytype_int8; -#endif - -#ifdef YYTYPE_UINT16 -typedef YYTYPE_UINT16 yytype_uint16; -#else -typedef unsigned short int yytype_uint16; -#endif - -#ifdef YYTYPE_INT16 -typedef YYTYPE_INT16 yytype_int16; -#else -typedef short int yytype_int16; -#endif - -#ifndef YYSIZE_T -# ifdef __SIZE_TYPE__ -# define YYSIZE_T __SIZE_TYPE__ -# elif defined size_t -# define YYSIZE_T size_t -# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# else -# define YYSIZE_T unsigned int -# endif -#endif - -#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) - -#ifndef YY_ -# if YYENABLE_NLS -# if ENABLE_NLS -# include /* INFRINGES ON USER NAME SPACE */ -# define YY_(msgid) dgettext ("bison-runtime", msgid) -# endif -# endif -# ifndef YY_ -# define YY_(msgid) msgid -# endif -#endif - -/* Suppress unused-variable warnings by "using" E. */ -#if ! defined lint || defined __GNUC__ -# define YYUSE(e) ((void) (e)) -#else -# define YYUSE(e) /* empty */ -#endif - -/* Identity function, used to suppress warnings about constant conditions. */ -#ifndef lint -# define YYID(n) (n) -#else -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static int -YYID (int i) -#else -static int -YYID (i) - int i; -#endif -{ - return i; -} -#endif - -#if ! defined yyoverflow || YYERROR_VERBOSE - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# ifdef YYSTACK_USE_ALLOCA -# if YYSTACK_USE_ALLOCA -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# elif defined __BUILTIN_VA_ARG_INCR -# include /* INFRINGES ON USER NAME SPACE */ -# elif defined _AIX -# define YYSTACK_ALLOC __alloca -# elif defined _MSC_VER -# include /* INFRINGES ON USER NAME SPACE */ -# define alloca _alloca -# else -# define YYSTACK_ALLOC alloca -# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include /* INFRINGES ON USER NAME SPACE */ -# ifndef _STDLIB_H -# define _STDLIB_H 1 -# endif -# endif -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's `empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) -# ifndef YYSTACK_ALLOC_MAXIMUM - /* The OS might guarantee only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely - invoke alloca (N) if N exceeds 4096. Use a slightly smaller number - to allow for a few compiler-allocated temporary stack slots. */ -# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ -# endif -# else -# define YYSTACK_ALLOC YYMALLOC -# define YYSTACK_FREE YYFREE -# ifndef YYSTACK_ALLOC_MAXIMUM -# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM -# endif -# if (defined __cplusplus && ! defined _STDLIB_H \ - && ! ((defined YYMALLOC || defined malloc) \ - && (defined YYFREE || defined free))) -# include /* INFRINGES ON USER NAME SPACE */ -# ifndef _STDLIB_H -# define _STDLIB_H 1 -# endif -# endif -# ifndef YYMALLOC -# define YYMALLOC malloc -# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# ifndef YYFREE -# define YYFREE free -# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -void free (void *); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# endif -#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ - - -#if (! defined yyoverflow \ - && (! defined __cplusplus \ - || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - yytype_int16 yyss; - YYSTYPE yyvs; - }; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# define YYSTACK_BYTES(N) \ - ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ - + YYSTACK_GAP_MAXIMUM) - -/* Copy COUNT objects from FROM to TO. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if defined __GNUC__ && 1 < __GNUC__ -# define YYCOPY(To, From, Count) \ - __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -# else -# define YYCOPY(To, From, Count) \ - do \ - { \ - YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (To)[yyi] = (From)[yyi]; \ - } \ - while (YYID (0)) -# endif -# endif - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack, Stack, yysize); \ - Stack = &yyptr->Stack; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (YYID (0)) - -#endif - -/* YYFINAL -- State number of the termination state. */ -#define YYFINAL 3 -/* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 1091 - -/* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 154 -/* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 75 -/* YYNRULES -- Number of rules. */ -#define YYNRULES 268 -/* YYNRULES -- Number of states. */ -#define YYNSTATES 495 - -/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -#define YYUNDEFTOK 2 -#define YYMAXUTOK 389 - -#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) - -/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -static const yytype_uint8 yytranslate[] = -{ - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 136, 2, - 146, 147, 139, 138, 132, 137, 153, 140, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 134, 145, - 2, 152, 2, 133, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 150, 2, 151, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 148, 135, 149, 141, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, - 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, - 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, - 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, - 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, - 125, 126, 127, 128, 129, 130, 131, 142, 143, 144 -}; - -#if YYDEBUG -/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in - YYRHS. */ -static const yytype_uint16 yyprhs[] = -{ - 0, 0, 3, 5, 6, 9, 12, 16, 19, 22, - 25, 28, 29, 32, 35, 39, 42, 45, 48, 51, - 52, 56, 59, 61, 64, 66, 69, 72, 74, 77, - 80, 83, 88, 92, 96, 101, 104, 108, 112, 113, - 115, 117, 119, 123, 125, 130, 134, 141, 147, 148, - 152, 156, 158, 162, 167, 168, 170, 174, 176, 180, - 185, 187, 191, 192, 194, 196, 198, 200, 202, 207, - 212, 214, 216, 218, 220, 222, 224, 229, 234, 236, - 238, 243, 245, 250, 255, 260, 262, 264, 269, 274, - 279, 284, 289, 291, 296, 298, 303, 305, 311, 313, - 315, 320, 322, 324, 326, 328, 330, 332, 334, 336, - 338, 343, 345, 347, 349, 351, 358, 360, 362, 364, - 366, 371, 373, 375, 380, 385, 390, 395, 397, 399, - 404, 409, 411, 412, 414, 415, 418, 423, 427, 433, - 434, 437, 439, 441, 445, 449, 451, 457, 459, 463, - 464, 466, 468, 470, 472, 474, 476, 478, 484, 488, - 492, 496, 500, 504, 508, 512, 516, 519, 522, 525, - 530, 535, 539, 541, 545, 547, 552, 553, 556, 559, - 563, 566, 568, 573, 581, 582, 584, 585, 587, 589, - 591, 593, 595, 597, 599, 602, 605, 607, 609, 611, - 613, 615, 617, 619, 620, 622, 624, 627, 629, 632, - 635, 637, 639, 642, 645, 648, 653, 654, 657, 660, - 663, 666, 669, 672, 676, 679, 683, 689, 695, 696, - 699, 702, 705, 708, 714, 722, 724, 727, 730, 733, - 736, 739, 744, 747, 750, 752, 754, 758, 760, 764, - 766, 768, 770, 776, 778, 780, 782, 785, 787, 790, - 792, 795, 797, 800, 805, 810, 816, 827, 829 -}; - -/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -static const yytype_int16 yyrhs[] = -{ - 155, 0, -1, 156, -1, -1, 156, 216, -1, 156, - 215, -1, 156, 202, 145, -1, 156, 204, -1, 156, - 219, -1, 156, 166, -1, 156, 159, -1, -1, 157, - 216, -1, 157, 215, -1, 157, 202, 145, -1, 157, - 204, -1, 157, 219, -1, 157, 159, -1, 157, 163, - -1, -1, 158, 195, 145, -1, 158, 159, -1, 145, - -1, 181, 145, -1, 160, -1, 185, 145, -1, 191, - 145, -1, 162, -1, 224, 145, -1, 226, 145, -1, - 227, 145, -1, 37, 146, 8, 147, -1, 69, 8, - 145, -1, 161, 157, 10, -1, 70, 146, 8, 147, - -1, 79, 3, -1, 174, 164, 148, -1, 165, 157, - 149, -1, -1, 169, -1, 129, -1, 170, -1, 169, - 132, 170, -1, 168, -1, 174, 225, 221, 171, -1, - 225, 221, 171, -1, 174, 225, 221, 146, 167, 147, - -1, 225, 221, 146, 167, 147, -1, -1, 150, 172, - 151, -1, 150, 139, 151, -1, 187, -1, 172, 132, - 188, -1, 172, 151, 150, 188, -1, -1, 174, -1, - 150, 175, 151, -1, 177, -1, 175, 132, 177, -1, - 175, 151, 150, 177, -1, 8, -1, 176, 132, 8, - -1, -1, 13, -1, 15, -1, 16, -1, 18, -1, - 19, -1, 24, 146, 198, 147, -1, 26, 146, 189, - 147, -1, 33, -1, 34, -1, 35, -1, 36, -1, - 38, -1, 39, -1, 40, 146, 190, 147, -1, 40, - 146, 8, 147, -1, 41, -1, 42, -1, 44, 146, - 8, 147, -1, 46, -1, 47, 146, 176, 147, -1, - 48, 146, 8, 147, -1, 48, 146, 190, 147, -1, - 51, -1, 55, -1, 57, 146, 190, 147, -1, 58, - 146, 8, 147, -1, 59, 146, 8, 147, -1, 60, - 146, 190, 147, -1, 61, 146, 8, 147, -1, 62, - -1, 64, 146, 190, 147, -1, 65, -1, 66, 146, - 198, 147, -1, 67, -1, 68, 146, 56, 3, 147, - -1, 71, -1, 73, -1, 78, 146, 186, 147, -1, - 80, -1, 84, -1, 85, -1, 86, -1, 87, -1, - 88, -1, 89, -1, 90, -1, 91, -1, 92, 146, - 223, 147, -1, 94, -1, 95, -1, 96, -1, 98, - -1, 99, 146, 190, 132, 190, 147, -1, 100, -1, - 102, -1, 103, -1, 104, -1, 109, 146, 186, 147, - -1, 112, -1, 114, -1, 117, 146, 188, 147, -1, - 118, 146, 225, 147, -1, 119, 146, 225, 147, -1, - 125, 146, 9, 147, -1, 126, -1, 127, -1, 128, - 146, 228, 147, -1, 131, 146, 225, 147, -1, 223, - -1, -1, 113, -1, -1, 179, 180, -1, 26, 188, - 134, 193, -1, 38, 134, 193, -1, 32, 225, 198, - 152, 190, -1, -1, 183, 132, -1, 183, -1, 184, - -1, 183, 132, 184, -1, 198, 152, 190, -1, 198, - -1, 49, 197, 148, 182, 149, -1, 187, -1, 186, - 132, 187, -1, -1, 188, -1, 5, -1, 6, -1, - 7, -1, 53, -1, 120, -1, 3, -1, 188, 133, - 188, 134, 188, -1, 188, 135, 188, -1, 188, 136, - 188, -1, 188, 138, 188, -1, 188, 137, 188, -1, - 188, 139, 188, -1, 188, 140, 188, -1, 188, 11, - 188, -1, 188, 12, 188, -1, 141, 188, -1, 137, - 188, -1, 139, 188, -1, 146, 225, 147, 188, -1, - 110, 146, 225, 147, -1, 146, 188, 147, -1, 190, - -1, 189, 132, 190, -1, 188, -1, 52, 32, 225, - 198, -1, -1, 192, 193, -1, 194, 145, -1, 173, - 227, 145, -1, 174, 145, -1, 145, -1, 173, 225, - 221, 171, -1, 173, 225, 178, 221, 146, 167, 147, - -1, -1, 198, -1, -1, 3, -1, 4, -1, 3, - -1, 4, -1, 22, -1, 130, -1, 201, -1, 107, - 201, -1, 124, 201, -1, 124, -1, 54, -1, 108, - -1, 45, -1, 20, -1, 50, -1, 56, -1, -1, - 74, -1, 74, -1, 106, 200, -1, 111, -1, 81, - 200, -1, 63, 200, -1, 75, -1, 28, -1, 29, - 3, -1, 29, 4, -1, 174, 202, -1, 203, 148, - 205, 149, -1, -1, 205, 206, -1, 173, 216, -1, - 43, 3, -1, 43, 4, -1, 174, 207, -1, 93, - 134, -1, 209, 194, 145, -1, 82, 134, -1, 210, - 195, 145, -1, 208, 148, 209, 210, 149, -1, 208, - 148, 213, 145, 149, -1, -1, 134, 4, -1, 76, - 3, -1, 76, 4, -1, 174, 213, -1, 214, 212, - 148, 158, 149, -1, 214, 134, 3, 148, 162, 158, - 149, -1, 211, -1, 213, 145, -1, 207, 145, -1, - 83, 3, -1, 83, 4, -1, 174, 217, -1, 218, - 148, 158, 149, -1, 139, 221, -1, 32, 220, -1, - 198, -1, 220, -1, 146, 221, 147, -1, 221, -1, - 222, 132, 221, -1, 101, -1, 123, -1, 97, -1, - 115, 197, 148, 192, 149, -1, 129, -1, 4, -1, - 199, -1, 32, 225, -1, 185, -1, 49, 3, -1, - 224, -1, 115, 3, -1, 227, -1, 122, 3, -1, - 105, 146, 225, 147, -1, 121, 173, 225, 222, -1, - 122, 197, 148, 192, 149, -1, 122, 197, 116, 146, - 194, 147, 196, 148, 179, 149, -1, 5, -1, 5, - 153, 5, -1 -}; - -/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -static const yytype_uint16 yyrline[] = -{ - 0, 281, 281, 289, 290, 291, 292, 296, 301, 302, - 303, 306, 307, 308, 309, 310, 314, 315, 316, 319, - 320, 321, 324, 325, 326, 327, 332, 333, 334, 339, - 340, 347, 349, 352, 355, 358, 360, 365, 368, 369, - 372, 375, 376, 377, 381, 386, 390, 396, 403, 404, - 405, 408, 409, 410, 413, 414, 418, 424, 425, 426, - 429, 430, 433, 434, 435, 436, 437, 438, 439, 440, - 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, - 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, - 481, 482, 483, 484, 485, 486, 489, 490, 491, 492, - 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, - 503, 504, 507, 508, 511, 512, 515, 519, 525, 531, - 532, 533, 536, 540, 549, 553, 558, 567, 568, 581, - 582, 585, 586, 587, 588, 589, 590, 591, 592, 593, - 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, - 604, 605, 608, 609, 612, 618, 623, 624, 627, 628, - 629, 630, 633, 641, 653, 654, 657, 658, 659, 662, - 664, 667, 668, 669, 670, 671, 687, 688, 689, 690, - 691, 692, 693, 696, 697, 700, 701, 702, 703, 704, - 705, 706, 709, 710, 716, 725, 731, 732, 736, 739, - 740, 743, 755, 756, 759, 760, 763, 772, 781, 782, - 785, 786, 789, 797, 807, 816, 820, 821, 824, 825, - 828, 833, 839, 840, 843, 844, 845, 849, 850, 854, - 855, 856, 859, 870, 871, 872, 873, 874, 875, 876, - 877, 878, 879, 880, 883, 888, 893, 910, 911 -}; -#endif - -#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE -/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -static const char *const yytname[] = -{ - "$end", "error", "$undefined", "aIDENTIFIER", "aKNOWNTYPE", "aNUM", - "aHEXNUM", "aDOUBLE", "aSTRING", "aUUID", "aEOF", "SHL", "SHR", - "tAGGREGATABLE", "tALLOCATE", "tAPPOBJECT", "tASYNC", "tASYNCUUID", - "tAUTOHANDLE", "tBINDABLE", "tBOOLEAN", "tBROADCAST", "tBYTE", - "tBYTECOUNT", "tCALLAS", "tCALLBACK", "tCASE", "tCDECL", "tCHAR", - "tCOCLASS", "tCODE", "tCOMMSTATUS", "tCONST", "tCONTEXTHANDLE", - "tCONTEXTHANDLENOSERIALIZE", "tCONTEXTHANDLESERIALIZE", "tCONTROL", - "tCPPQUOTE", "tDEFAULT", "tDEFAULTCOLLELEM", "tDEFAULTVALUE", - "tDEFAULTVTABLE", "tDISPLAYBIND", "tDISPINTERFACE", "tDLLNAME", - "tDOUBLE", "tDUAL", "tENDPOINT", "tENTRY", "tENUM", "tERRORSTATUST", - "tEXPLICITHANDLE", "tEXTERN", "tFALSE", "tFLOAT", "tHANDLE", "tHANDLET", - "tHELPCONTEXT", "tHELPFILE", "tHELPSTRING", "tHELPSTRINGCONTEXT", - "tHELPSTRINGDLL", "tHIDDEN", "tHYPER", "tID", "tIDEMPOTENT", "tIIDIS", - "tIMMEDIATEBIND", "tIMPLICITHANDLE", "tIMPORT", "tIMPORTLIB", "tIN", - "tINLINE", "tINPUTSYNC", "tINT", "tINT64", "tINTERFACE", "tLCID", - "tLENGTHIS", "tLIBRARY", "tLOCAL", "tLONG", "tMETHODS", "tMODULE", - "tNONBROWSABLE", "tNONCREATABLE", "tNONEXTENSIBLE", "tOBJECT", "tODL", - "tOLEAUTOMATION", "tOPTIONAL", "tOUT", "tPOINTERDEFAULT", "tPROPERTIES", - "tPROPGET", "tPROPPUT", "tPROPPUTREF", "tPTR", "tPUBLIC", "tRANGE", - "tREADONLY", "tREF", "tREQUESTEDIT", "tRESTRICTED", "tRETVAL", - "tSAFEARRAY", "tSHORT", "tSIGNED", "tSINGLE", "tSIZEIS", "tSIZEOF", - "tSMALL", "tSOURCE", "tSTDCALL", "tSTRING", "tSTRUCT", "tSWITCH", - "tSWITCHIS", "tSWITCHTYPE", "tTRANSMITAS", "tTRUE", "tTYPEDEF", "tUNION", - "tUNIQUE", "tUNSIGNED", "tUUID", "tV1ENUM", "tVARARG", "tVERSION", - "tVOID", "tWCHAR", "tWIREMARSHAL", "','", "'?'", "':'", "'|'", "'&'", - "'-'", "'+'", "'*'", "'/'", "'~'", "CAST", "PPTR", "NEG", "';'", "'('", - "')'", "'{'", "'}'", "'['", "']'", "'='", "'.'", "$accept", "input", - "gbl_statements", "imp_statements", "int_statements", "statement", - "cppquote", "import_start", "import", "importlib", "libraryhdr", - "library_start", "librarydef", "m_args", "no_args", "args", "arg", - "array", "array_list", "m_attributes", "attributes", "attrib_list", - "str_list", "attribute", "callconv", "cases", "case", "constdef", - "enums", "enum_list", "enum", "enumdef", "m_exprs", "m_expr", "expr", - "expr_list_const", "expr_const", "externdef", "fields", "field", - "s_field", "funcdef", "m_ident", "t_ident", "ident", "base_type", - "m_int", "int_std", "coclass", "coclasshdr", "coclassdef", - "coclass_ints", "coclass_int", "dispinterface", "dispinterfacehdr", - "dispint_props", "dispint_meths", "dispinterfacedef", "inherit", - "interface", "interfacehdr", "interfacedef", "interfacedec", "module", - "modulehdr", "moduledef", "p_ident", "pident", "pident_list", - "pointer_type", "structdef", "type", "typedef", "uniondef", "version", 0 -}; -#endif - -# ifdef YYPRINT -/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to - token YYLEX-NUM. */ -static const yytype_uint16 yytoknum[] = -{ - 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, - 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, - 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 44, 63, 58, 124, 38, 45, 43, 42, - 47, 126, 387, 388, 389, 59, 40, 41, 123, 125, - 91, 93, 61, 46 -}; -# endif - -/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const yytype_uint8 yyr1[] = -{ - 0, 154, 155, 156, 156, 156, 156, 156, 156, 156, - 156, 157, 157, 157, 157, 157, 157, 157, 157, 158, - 158, 158, 159, 159, 159, 159, 159, 159, 159, 159, - 159, 160, 161, 162, 163, 164, 165, 166, 167, 167, - 168, 169, 169, 169, 170, 170, 170, 170, 171, 171, - 171, 172, 172, 172, 173, 173, 174, 175, 175, 175, - 176, 176, 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 178, 178, 179, 179, 180, 180, 181, 182, - 182, 182, 183, 183, 184, 184, 185, 186, 186, 187, - 187, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 189, 189, 190, 191, 192, 192, 193, 193, - 193, 193, 194, 195, 196, 196, 197, 197, 197, 198, - 198, 199, 199, 199, 199, 199, 199, 199, 199, 199, - 199, 199, 199, 200, 200, 201, 201, 201, 201, 201, - 201, 201, 202, 202, 203, 204, 205, 205, 206, 207, - 207, 208, 209, 209, 210, 210, 211, 211, 212, 212, - 213, 213, 214, 215, 215, 215, 216, 216, 217, 217, - 218, 219, 220, 220, 221, 221, 221, 222, 222, 223, - 223, 223, 224, 225, 225, 225, 225, 225, 225, 225, - 225, 225, 225, 225, 226, 227, 227, 228, 228 -}; - -/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -static const yytype_uint8 yyr2[] = -{ - 0, 2, 1, 0, 2, 2, 3, 2, 2, 2, - 2, 0, 2, 2, 3, 2, 2, 2, 2, 0, - 3, 2, 1, 2, 1, 2, 2, 1, 2, 2, - 2, 4, 3, 3, 4, 2, 3, 3, 0, 1, - 1, 1, 3, 1, 4, 3, 6, 5, 0, 3, - 3, 1, 3, 4, 0, 1, 3, 1, 3, 4, - 1, 3, 0, 1, 1, 1, 1, 1, 4, 4, - 1, 1, 1, 1, 1, 1, 4, 4, 1, 1, - 4, 1, 4, 4, 4, 1, 1, 4, 4, 4, - 4, 4, 1, 4, 1, 4, 1, 5, 1, 1, - 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 4, 1, 1, 1, 1, 6, 1, 1, 1, 1, - 4, 1, 1, 4, 4, 4, 4, 1, 1, 4, - 4, 1, 0, 1, 0, 2, 4, 3, 5, 0, - 2, 1, 1, 3, 3, 1, 5, 1, 3, 0, - 1, 1, 1, 1, 1, 1, 1, 5, 3, 3, - 3, 3, 3, 3, 3, 3, 2, 2, 2, 4, - 4, 3, 1, 3, 1, 4, 0, 2, 2, 3, - 2, 1, 4, 7, 0, 1, 0, 1, 1, 1, - 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, - 1, 1, 1, 0, 1, 1, 2, 1, 2, 2, - 1, 1, 2, 2, 2, 4, 0, 2, 2, 2, - 2, 2, 2, 3, 2, 3, 5, 5, 0, 2, - 2, 2, 2, 5, 7, 1, 2, 2, 2, 2, - 2, 4, 2, 2, 1, 1, 3, 1, 3, 1, - 1, 1, 5, 1, 1, 1, 2, 1, 2, 1, - 2, 1, 2, 4, 4, 5, 10, 1, 3 -}; - -/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state - STATE-NUM when YYTABLE doesn't specify something else to do. Zero - means the default is an error. */ -static const yytype_uint16 yydefact[] = -{ - 3, 0, 2, 1, 0, 0, 0, 0, 186, 0, - 0, 0, 186, 54, 186, 22, 62, 10, 24, 11, - 27, 11, 9, 0, 0, 0, 0, 0, 0, 7, - 0, 0, 235, 0, 228, 5, 4, 0, 8, 0, - 0, 0, 212, 213, 254, 200, 191, 211, 0, 199, - 186, 201, 197, 202, 203, 205, 210, 203, 0, 203, - 0, 198, 207, 186, 186, 196, 253, 192, 257, 255, - 193, 259, 0, 261, 0, 219, 220, 187, 188, 0, - 0, 0, 230, 231, 0, 0, 55, 0, 63, 64, - 65, 66, 67, 0, 0, 70, 71, 72, 73, 74, - 75, 0, 78, 79, 0, 81, 0, 0, 85, 86, - 0, 0, 0, 0, 0, 92, 0, 94, 0, 96, - 0, 98, 99, 0, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 0, 111, 112, 113, 251, 114, 0, - 116, 249, 117, 118, 119, 0, 121, 122, 0, 0, - 0, 250, 0, 127, 128, 0, 0, 0, 57, 131, - 0, 0, 0, 0, 0, 214, 221, 232, 240, 23, - 25, 26, 6, 216, 237, 0, 236, 0, 0, 19, - 28, 29, 30, 256, 258, 204, 209, 208, 0, 206, - 194, 260, 262, 195, 189, 190, 0, 0, 139, 0, - 32, 176, 0, 0, 176, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 149, - 0, 0, 149, 0, 0, 0, 0, 0, 0, 62, - 56, 33, 0, 17, 18, 0, 0, 15, 13, 12, - 16, 37, 35, 238, 239, 36, 54, 0, 54, 0, - 0, 229, 19, 54, 0, 0, 31, 0, 141, 142, - 145, 175, 54, 0, 0, 0, 244, 245, 247, 264, - 54, 54, 0, 156, 151, 152, 153, 154, 0, 155, - 0, 0, 0, 0, 174, 0, 172, 0, 0, 0, - 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 147, 150, 0, 0, 0, 0, 0, - 0, 0, 267, 0, 0, 58, 62, 0, 14, 215, - 0, 217, 222, 0, 0, 0, 54, 0, 0, 54, - 241, 21, 0, 0, 263, 138, 146, 140, 0, 181, - 252, 0, 55, 177, 0, 243, 242, 0, 0, 0, - 265, 68, 0, 167, 168, 166, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 69, 77, - 76, 80, 0, 82, 83, 84, 87, 88, 89, 90, - 91, 93, 95, 0, 149, 100, 110, 0, 120, 123, - 124, 125, 126, 0, 129, 130, 59, 0, 218, 224, - 0, 223, 226, 0, 227, 19, 233, 132, 20, 143, - 144, 261, 180, 178, 246, 248, 184, 0, 171, 0, - 164, 165, 0, 158, 159, 161, 160, 162, 163, 173, - 61, 97, 148, 0, 268, 34, 48, 225, 54, 133, - 0, 179, 0, 185, 170, 169, 0, 115, 149, 182, - 234, 0, 134, 157, 0, 0, 51, 38, 0, 50, - 0, 49, 253, 0, 43, 39, 41, 0, 0, 0, - 0, 266, 135, 52, 0, 183, 0, 0, 48, 0, - 54, 53, 42, 48, 38, 45, 54, 137, 38, 44, - 0, 136, 0, 47, 46 -}; - -/* YYDEFGOTO[NTERM-NUM]. */ -static const yytype_int16 yydefgoto[] = -{ - -1, 1, 2, 160, 253, 331, 18, 19, 20, 234, - 164, 21, 22, 463, 464, 465, 466, 449, 455, 332, - 86, 157, 291, 158, 440, 458, 472, 24, 257, 258, - 259, 68, 302, 303, 284, 285, 286, 26, 262, 343, - 344, 333, 442, 79, 266, 69, 186, 70, 165, 28, - 237, 246, 321, 30, 31, 248, 326, 32, 178, 33, - 34, 238, 239, 168, 37, 240, 267, 268, 269, 159, - 71, 468, 40, 73, 313 -}; - -/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -#define YYPACT_NINF -454 -static const yytype_int16 yypact[] = -{ - -454, 32, 736, -454, 176, 695, -103, 190, 207, 51, - 77, 209, 207, -37, 207, -454, 849, -454, -454, -454, - -454, -454, -454, 19, -29, -22, 0, 38, -15, -454, - 43, 9, -454, 45, 7, -454, -454, 29, -454, 72, - 74, 104, -454, -454, -454, -454, -454, -454, 695, -454, - 212, -454, -454, -454, 126, -454, -454, 126, 76, 126, - 26, -454, -454, 222, 231, 26, -454, -454, -454, -454, - -454, -454, 237, -454, 243, -454, -454, -454, -454, 107, - 695, 112, -454, -454, 115, 695, -454, -88, -454, -454, - -454, -454, -454, 127, 128, -454, -454, -454, -454, -454, - -454, 129, -454, -454, 131, -454, 132, 135, -454, -454, - 136, 137, 138, 140, 145, -454, 146, -454, 148, -454, - 149, -454, -454, 153, -454, -454, -454, -454, -454, -454, - -454, -454, -454, 154, -454, -454, -454, -454, -454, 166, - -454, -454, -454, -454, -454, 168, -454, -454, 169, 172, - 173, -454, 175, -454, -454, 179, 180, -93, -454, -454, - 611, 705, 324, 239, 183, -454, -454, -454, -454, -454, - -454, -454, -454, -454, -454, 6, -454, 242, 188, -454, - -454, -454, -454, -454, 191, -454, -454, -454, 695, -454, - -454, 191, -80, -454, -454, -454, 186, 193, 237, 237, - -454, -454, 46, 195, -454, 237, 446, 58, 335, 336, - 282, 446, 337, 339, 446, 341, 446, 237, 294, 446, - 13, 446, 446, 446, 695, 695, 342, 347, 695, 849, - 208, -454, 211, -454, -454, 8, 215, -454, -454, -454, - -454, -454, -454, -454, -454, -454, 98, 227, -60, 217, - 216, -454, -454, 264, 219, 446, -454, 218, 236, -454, - 221, -454, -115, -13, 46, 46, -454, -454, -454, 244, - -37, -57, 224, -454, -454, -454, -454, -454, 223, -454, - 446, 446, 446, 490, 556, -107, -454, 228, 233, 235, - -454, -35, 240, 241, 247, 249, 250, 252, 253, 254, - 258, 371, -26, -454, 556, 261, 259, -23, 170, 265, - 269, 271, 267, 275, 278, -454, 849, 376, -454, -454, - -17, -454, -454, 256, 695, 262, 116, 246, 357, 932, - -454, -454, 695, 284, -454, -454, -454, 237, 446, -454, - -454, 695, 285, -454, 286, -454, -454, 280, 46, 290, - -454, -454, 695, -454, -454, -454, 422, 291, 446, 446, - 446, 446, 446, 446, 446, 446, 446, 446, -454, -454, - -454, -454, 424, -454, -454, -454, -454, -454, -454, -454, - -454, -454, -454, 293, 446, -454, -454, 446, -454, -454, - -454, -454, -454, 439, -454, -454, -454, 298, -454, -454, - 46, -454, -454, 301, -454, -454, -454, 334, -454, -454, - -454, 303, -454, -454, -454, -454, 237, 307, -454, 446, - -454, -454, 392, 93, 68, 63, 63, 260, 260, -454, - -454, -454, -454, 309, -454, -454, 300, -454, 941, -454, - 46, -454, 310, -454, -454, -454, 446, -454, 498, -454, - -454, 311, -454, 556, 50, -55, -454, 248, -18, -454, - 446, 312, -5, 313, -454, 327, -454, 695, 46, 446, - 330, -454, -454, 556, 446, -454, 361, 46, -12, 536, - -30, 556, -454, -6, 248, -454, -30, -454, 248, -454, - 314, -454, 318, -454, -454 -}; - -/* YYPGOTO[NTERM-NUM]. */ -static const yytype_int16 yypgoto[] = -{ - -454, -454, -454, 449, -234, 12, -454, -454, 147, -454, - -454, -454, -454, -345, -454, -454, -3, -353, -454, -9, - -2, -454, -454, -208, -454, -454, -454, -454, -454, -454, - 142, 3, 266, -361, -210, -454, -169, -454, 276, -453, - -224, 155, -454, 55, -70, -454, -28, 57, 15, -454, - 485, -454, -454, -7, -454, -454, -454, -454, -454, -8, - -454, 487, 4, -454, -454, 496, 229, -254, -454, 287, - 5, -4, -454, 1, -454 -}; - -/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule which - number is the opposite. If zero, do what YYDEFACT says. - If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -188 -static const yytype_int16 yytable[] = -{ - 23, 72, 196, 41, 85, 25, 36, 39, 469, 304, - 346, 347, 304, 308, 17, 167, 166, 27, 329, 263, - 470, 315, 323, 432, 325, 367, 7, 487, 203, 187, - 339, 189, 3, 491, 340, 16, -187, 4, 288, 229, - 368, 293, 294, 74, 183, 297, 349, 299, 4, 194, - 195, 7, 306, 273, 47, 274, 275, 276, 230, 11, - 204, 273, 7, 274, 275, 276, 287, 84, -187, 87, - 353, 354, 355, 356, 358, 359, 199, 460, 263, 358, - 359, 202, 11, 80, 11, 81, 335, 456, 339, 54, - 16, 163, 350, 16, 415, 11, 461, 372, 162, 247, - 55, 56, 163, 277, 358, 359, 384, 57, 396, 384, - 137, 277, 373, 16, 141, 339, 169, 190, 84, 87, - 16, 385, 193, 170, 388, 485, 264, -40, 260, 261, - 489, 471, 59, 173, 484, 272, 151, 62, 448, 490, - 488, 177, -40, 492, 448, 171, 436, 300, 420, 421, - 422, 423, 424, 425, 426, 427, 428, 175, 235, 235, - 278, 41, 41, 25, 25, 39, 39, 249, 278, 410, - 279, 438, 233, 233, 304, 236, 236, 179, 279, 42, - 43, 358, 359, 172, 254, 264, 451, 280, 174, 281, - 176, 282, 265, 75, 76, 280, 283, 281, 429, 282, - 185, 459, 365, 366, 283, 363, 364, 365, 366, 445, - 77, 78, 82, 83, 478, 184, 78, 180, 433, 181, - 309, 310, 188, 483, 314, 191, 78, 167, 166, 362, - 363, 364, 365, 366, 192, 78, 453, 320, 304, 324, - 194, 195, 243, 244, 354, 250, 251, 319, 16, 182, - 473, 197, 44, 341, 41, 198, 25, 200, 39, 479, - 342, 324, 341, 201, 481, 402, 16, 260, 45, 342, - 46, 358, 359, 205, 206, 207, 47, 208, 209, 357, - 48, 210, 211, 212, 213, 273, 214, 274, 275, 276, - 292, 215, 216, 49, 217, 218, 5, 50, 51, 219, - 220, 6, 52, 360, 53, 361, 362, 363, 364, 365, - 366, 54, 221, 8, 222, 223, 9, 389, 224, 225, - 400, 226, 55, 56, 398, 227, 228, 242, 407, 57, - 41, 245, 25, 10, 39, 277, 252, 400, 255, -187, - 256, 270, 411, 289, 290, 295, 443, 296, 417, 298, - 301, 311, 312, 58, 59, 60, 61, 317, 316, 62, - 318, 322, 327, 63, 328, 44, 334, 336, 337, 352, - 64, 351, 65, 338, 383, 369, 348, 462, 67, 12, - 370, 45, 371, 46, 397, 13, 14, 374, 375, 47, - 399, 387, 278, 48, 376, 404, 377, 378, 16, 379, - 380, 381, 279, 358, 359, 382, 49, 401, 386, 15, - 50, 51, 390, 330, 16, 52, 391, 53, 392, 280, - 393, 281, 394, 282, 54, 395, 10, 414, 283, 408, - 412, 413, 430, 358, 359, 55, 56, 416, 419, 41, - 431, 25, 57, 39, 434, 435, 437, 439, 441, 273, - 448, 274, 275, 276, 444, 467, 447, 457, 452, 476, - 475, 493, 474, 477, 480, 494, 58, 59, 60, 61, - 161, 341, 62, 482, 467, 405, 63, 341, 342, 409, - 271, 403, 467, 64, 342, 65, 467, 29, 307, 35, - 66, 67, 345, 273, 44, 274, 275, 276, 38, 277, - 0, 273, 0, 274, 275, 276, 0, 305, 0, 0, - 45, 16, 46, 0, 0, 0, 0, 0, 47, 0, - 0, 0, 48, 0, 0, 360, 446, 361, 362, 363, - 364, 365, 366, 0, 0, 49, 0, 0, 0, 50, - 51, 0, 0, 277, 52, 0, 53, 358, 359, 0, - 0, 277, 0, 54, 0, 360, 278, 361, 362, 363, - 364, 365, 366, 0, 55, 56, 279, 358, 359, 418, - 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 280, 0, 281, 0, 282, 0, 0, - 0, 0, 283, 0, 0, 58, 59, 60, 61, 0, - 278, 62, 0, 0, 0, 63, 0, 0, 278, 0, - 279, 0, 64, 0, 65, 0, 0, 0, 279, 66, - 67, 231, 0, 0, 0, 0, 0, 280, 0, 281, - 0, 282, 0, 0, 0, 280, 283, 454, 0, 282, - 4, 0, 0, 5, 283, 0, 0, 0, 6, 0, - 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, - 8, 0, 0, 9, 0, 0, 0, 0, 0, 360, - 486, 361, 362, 363, 364, 365, 366, 0, 0, 0, - 10, 232, 0, 0, 0, 0, 0, 11, 0, 360, - 0, 361, 362, 363, 364, 365, 366, 0, 0, 44, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 45, 0, 46, 0, 0, - 0, 0, 0, 47, 0, 0, 12, 48, 0, 0, - 0, 0, 13, 14, 4, 0, 0, 5, 0, 0, - 49, 0, 6, 0, 50, 51, 0, 0, 7, 52, - 0, 53, 0, 0, 8, 0, 15, 9, 54, 0, - 0, 16, 0, 0, 0, 4, 0, 0, 5, 55, - 56, 0, 0, 6, 10, 232, 57, 0, 0, 7, - 0, 11, 0, 0, 0, 8, 0, 0, 9, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 58, 59, 60, 61, 0, 10, 62, 0, 0, 0, - 63, 0, 11, 0, 0, 0, 0, 64, 0, 65, - 12, 0, 0, 0, 66, 67, 13, 14, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 15, 12, 0, 0, 241, 16, 0, 13, 14, 0, - 0, 0, 88, 0, 89, 90, 0, 91, 92, 0, - 0, 0, 0, 93, 0, 94, 0, 0, 0, 0, - 0, 15, 95, 96, 97, 98, 16, 99, 100, 101, - 102, 103, 0, 104, 0, 105, 106, 107, 0, 0, - 108, 0, 0, 0, 109, 0, 110, 111, 112, 113, - 114, 115, 0, 116, 117, 118, 119, 120, 0, 0, - 121, 0, 122, 0, 0, 0, 0, 123, 0, 124, - 0, 0, 0, 125, 126, 127, 128, 129, 130, 131, - 132, 133, 0, 134, 135, 136, 137, 138, 139, 140, - 141, 142, 143, 144, 0, 0, 0, 0, 145, 0, - 0, 146, 0, 147, 5, 0, 148, 149, 150, 6, - 0, 0, 151, 5, 152, 153, 154, 155, 6, 0, - 156, 8, 0, 0, 9, 0, 0, 0, 0, 0, - 8, 0, 0, 9, 0, 0, 0, 0, 0, 0, - 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, - 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, - 0, 0, 0, 13, 14, 0, 12, 0, 0, 0, - 0, 0, 13, 14, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, - 0, 406, 16, 0, 0, 0, 15, 0, 0, 0, - 450, 16 -}; - -static const yytype_int16 yycheck[] = -{ - 2, 5, 72, 2, 13, 2, 2, 2, 26, 219, - 264, 265, 222, 223, 2, 23, 23, 2, 252, 32, - 38, 229, 82, 384, 248, 132, 43, 480, 116, 57, - 145, 59, 0, 486, 149, 150, 116, 29, 207, 132, - 147, 210, 211, 146, 48, 214, 270, 216, 29, 3, - 4, 43, 221, 3, 28, 5, 6, 7, 151, 76, - 148, 3, 43, 5, 6, 7, 8, 12, 148, 14, - 280, 281, 282, 283, 11, 12, 80, 132, 32, 11, - 12, 85, 76, 32, 76, 8, 255, 448, 145, 63, - 150, 83, 149, 150, 348, 76, 151, 132, 79, 93, - 74, 75, 83, 53, 11, 12, 132, 81, 316, 132, - 97, 53, 147, 150, 101, 145, 145, 60, 63, 64, - 150, 147, 65, 145, 147, 478, 139, 132, 198, 199, - 483, 149, 106, 148, 146, 205, 123, 111, 150, 484, - 146, 134, 147, 488, 150, 145, 400, 217, 358, 359, - 360, 361, 362, 363, 364, 365, 366, 148, 160, 161, - 110, 160, 161, 160, 161, 160, 161, 175, 110, 338, - 120, 405, 160, 161, 384, 160, 161, 148, 120, 3, - 4, 11, 12, 145, 188, 139, 440, 137, 145, 139, - 145, 141, 146, 3, 4, 137, 146, 139, 367, 141, - 74, 151, 139, 140, 146, 137, 138, 139, 140, 419, - 3, 4, 3, 4, 468, 3, 4, 145, 387, 145, - 224, 225, 146, 477, 228, 3, 4, 235, 235, 136, - 137, 138, 139, 140, 3, 4, 446, 246, 448, 248, - 3, 4, 3, 4, 454, 3, 4, 149, 150, 145, - 460, 8, 4, 262, 253, 148, 253, 145, 253, 469, - 262, 270, 271, 148, 474, 149, 150, 337, 20, 271, - 22, 11, 12, 146, 146, 146, 28, 146, 146, 283, - 32, 146, 146, 146, 146, 3, 146, 5, 6, 7, - 8, 146, 146, 45, 146, 146, 32, 49, 50, 146, - 146, 37, 54, 133, 56, 135, 136, 137, 138, 139, - 140, 63, 146, 49, 146, 146, 52, 147, 146, 146, - 324, 146, 74, 75, 320, 146, 146, 3, 332, 81, - 329, 148, 329, 69, 329, 53, 148, 341, 152, 148, - 147, 146, 341, 8, 8, 8, 416, 8, 352, 8, - 56, 9, 5, 105, 106, 107, 108, 146, 150, 111, - 145, 134, 145, 115, 148, 4, 147, 149, 132, 146, - 122, 147, 124, 152, 3, 147, 132, 129, 130, 115, - 147, 20, 147, 22, 8, 121, 122, 147, 147, 28, - 134, 132, 110, 32, 147, 149, 147, 147, 150, 147, - 147, 147, 120, 11, 12, 147, 45, 145, 147, 145, - 49, 50, 147, 149, 150, 54, 147, 56, 147, 137, - 153, 139, 147, 141, 63, 147, 69, 147, 146, 145, - 145, 145, 8, 11, 12, 74, 75, 147, 147, 438, - 147, 438, 81, 438, 5, 147, 145, 113, 145, 3, - 150, 5, 6, 7, 147, 457, 147, 146, 148, 132, - 147, 147, 150, 467, 134, 147, 105, 106, 107, 108, - 21, 480, 111, 476, 476, 328, 115, 486, 480, 337, - 204, 326, 484, 122, 486, 124, 488, 2, 222, 2, - 129, 130, 263, 3, 4, 5, 6, 7, 2, 53, - -1, 3, -1, 5, 6, 7, -1, 220, -1, -1, - 20, 150, 22, -1, -1, -1, -1, -1, 28, -1, - -1, -1, 32, -1, -1, 133, 134, 135, 136, 137, - 138, 139, 140, -1, -1, 45, -1, -1, -1, 49, - 50, -1, -1, 53, 54, -1, 56, 11, 12, -1, - -1, 53, -1, 63, -1, 133, 110, 135, 136, 137, - 138, 139, 140, -1, 74, 75, 120, 11, 12, 147, - -1, 81, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 137, -1, 139, -1, 141, -1, -1, - -1, -1, 146, -1, -1, 105, 106, 107, 108, -1, - 110, 111, -1, -1, -1, 115, -1, -1, 110, -1, - 120, -1, 122, -1, 124, -1, -1, -1, 120, 129, - 130, 10, -1, -1, -1, -1, -1, 137, -1, 139, - -1, 141, -1, -1, -1, 137, 146, 139, -1, 141, - 29, -1, -1, 32, 146, -1, -1, -1, 37, -1, - -1, -1, -1, -1, 43, -1, -1, -1, -1, -1, - 49, -1, -1, 52, -1, -1, -1, -1, -1, 133, - 134, 135, 136, 137, 138, 139, 140, -1, -1, -1, - 69, 70, -1, -1, -1, -1, -1, 76, -1, 133, - -1, 135, 136, 137, 138, 139, 140, -1, -1, 4, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 20, -1, 22, -1, -1, - -1, -1, -1, 28, -1, -1, 115, 32, -1, -1, - -1, -1, 121, 122, 29, -1, -1, 32, -1, -1, - 45, -1, 37, -1, 49, 50, -1, -1, 43, 54, - -1, 56, -1, -1, 49, -1, 145, 52, 63, -1, - -1, 150, -1, -1, -1, 29, -1, -1, 32, 74, - 75, -1, -1, 37, 69, 70, 81, -1, -1, 43, - -1, 76, -1, -1, -1, 49, -1, -1, 52, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 105, 106, 107, 108, -1, 69, 111, -1, -1, -1, - 115, -1, 76, -1, -1, -1, -1, 122, -1, 124, - 115, -1, -1, -1, 129, 130, 121, 122, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 145, 115, -1, -1, 149, 150, -1, 121, 122, -1, - -1, -1, 13, -1, 15, 16, -1, 18, 19, -1, - -1, -1, -1, 24, -1, 26, -1, -1, -1, -1, - -1, 145, 33, 34, 35, 36, 150, 38, 39, 40, - 41, 42, -1, 44, -1, 46, 47, 48, -1, -1, - 51, -1, -1, -1, 55, -1, 57, 58, 59, 60, - 61, 62, -1, 64, 65, 66, 67, 68, -1, -1, - 71, -1, 73, -1, -1, -1, -1, 78, -1, 80, - -1, -1, -1, 84, 85, 86, 87, 88, 89, 90, - 91, 92, -1, 94, 95, 96, 97, 98, 99, 100, - 101, 102, 103, 104, -1, -1, -1, -1, 109, -1, - -1, 112, -1, 114, 32, -1, 117, 118, 119, 37, - -1, -1, 123, 32, 125, 126, 127, 128, 37, -1, - 131, 49, -1, -1, 52, -1, -1, -1, -1, -1, - 49, -1, -1, 52, -1, -1, -1, -1, -1, -1, - -1, 69, -1, -1, -1, -1, -1, -1, -1, -1, - 69, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 115, -1, -1, - -1, -1, -1, 121, 122, -1, 115, -1, -1, -1, - -1, -1, 121, 122, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 145, -1, -1, - -1, 149, 150, -1, -1, -1, 145, -1, -1, -1, - 149, 150 -}; - -/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ -static const yytype_uint8 yystos[] = -{ - 0, 155, 156, 0, 29, 32, 37, 43, 49, 52, - 69, 76, 115, 121, 122, 145, 150, 159, 160, 161, - 162, 165, 166, 174, 181, 185, 191, 202, 203, 204, - 207, 208, 211, 213, 214, 215, 216, 218, 219, 224, - 226, 227, 3, 4, 4, 20, 22, 28, 32, 45, - 49, 50, 54, 56, 63, 74, 75, 81, 105, 106, - 107, 108, 111, 115, 122, 124, 129, 130, 185, 199, - 201, 224, 225, 227, 146, 3, 4, 3, 4, 197, - 32, 8, 3, 4, 197, 173, 174, 197, 13, 15, - 16, 18, 19, 24, 26, 33, 34, 35, 36, 38, - 39, 40, 41, 42, 44, 46, 47, 48, 51, 55, - 57, 58, 59, 60, 61, 62, 64, 65, 66, 67, - 68, 71, 73, 78, 80, 84, 85, 86, 87, 88, - 89, 90, 91, 92, 94, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 109, 112, 114, 117, 118, - 119, 123, 125, 126, 127, 128, 131, 175, 177, 223, - 157, 157, 79, 83, 164, 202, 207, 213, 217, 145, - 145, 145, 145, 148, 145, 148, 145, 134, 212, 148, - 145, 145, 145, 225, 3, 74, 200, 200, 146, 200, - 201, 3, 3, 201, 3, 4, 198, 8, 148, 225, - 145, 148, 225, 116, 148, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 132, - 151, 10, 70, 159, 163, 174, 202, 204, 215, 216, - 219, 149, 3, 3, 4, 148, 205, 93, 209, 213, - 3, 4, 148, 158, 225, 152, 147, 182, 183, 184, - 198, 198, 192, 32, 139, 146, 198, 220, 221, 222, - 146, 192, 198, 3, 5, 6, 7, 53, 110, 120, - 137, 139, 141, 146, 188, 189, 190, 8, 190, 8, - 8, 176, 8, 190, 190, 8, 8, 190, 8, 190, - 198, 56, 186, 187, 188, 223, 190, 186, 188, 225, - 225, 9, 5, 228, 225, 177, 150, 146, 145, 149, - 173, 206, 134, 82, 173, 194, 210, 145, 148, 158, - 149, 159, 173, 195, 147, 190, 149, 132, 152, 145, - 149, 173, 174, 193, 194, 220, 221, 221, 132, 194, - 149, 147, 146, 188, 188, 188, 188, 225, 11, 12, - 133, 135, 136, 137, 138, 139, 140, 132, 147, 147, - 147, 147, 132, 147, 147, 147, 147, 147, 147, 147, - 147, 147, 147, 3, 132, 147, 147, 132, 147, 147, - 147, 147, 147, 153, 147, 147, 177, 8, 216, 134, - 225, 145, 149, 195, 149, 162, 149, 225, 145, 184, - 190, 227, 145, 145, 147, 221, 147, 225, 147, 147, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 190, - 8, 147, 187, 190, 5, 147, 221, 145, 158, 113, - 178, 145, 196, 198, 147, 188, 134, 147, 150, 171, - 149, 221, 148, 188, 139, 172, 187, 146, 179, 151, - 132, 151, 129, 167, 168, 169, 170, 174, 225, 26, - 38, 149, 180, 188, 150, 147, 132, 225, 221, 188, - 134, 188, 170, 221, 146, 171, 134, 193, 146, 171, - 167, 193, 167, 147, 147 -}; - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab - - -/* Like YYERROR except do call yyerror. This remains here temporarily - to ease the transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. */ - -#define YYFAIL goto yyerrlab - -#define YYRECOVERING() (!!yyerrstatus) - -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - yytoken = YYTRANSLATE (yychar); \ - YYPOPSTACK (1); \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (YYID (0)) - - -#define YYTERROR 1 -#define YYERRCODE 256 - - -/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. - If N is 0, then set CURRENT to the empty location which ends - the previous symbol: RHS[0] (always defined). */ - -#define YYRHSLOC(Rhs, K) ((Rhs)[K]) -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - do \ - if (YYID (N)) \ - { \ - (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ - (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ - } \ - else \ - { \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC (Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC (Rhs, 0).last_column; \ - } \ - while (YYID (0)) -#endif - - -/* YY_LOCATION_PRINT -- Print the location on the stream. - This macro was not mandated originally: define only if we know - we won't break user code: when these are the locations we know. */ - -#ifndef YY_LOCATION_PRINT -# if YYLTYPE_IS_TRIVIAL -# define YY_LOCATION_PRINT(File, Loc) \ - fprintf (File, "%d.%d-%d.%d", \ - (Loc).first_line, (Loc).first_column, \ - (Loc).last_line, (Loc).last_column) -# else -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -# endif -#endif - - -/* YYLEX -- calling `yylex' with the right arguments. */ - -#ifdef YYLEX_PARAM -# define YYLEX yylex (YYLEX_PARAM) -#else -# define YYLEX yylex () -#endif - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (YYID (0)) - -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Type, Value); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (YYID (0)) - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) -#else -static void -yy_symbol_value_print (yyoutput, yytype, yyvaluep) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; -#endif -{ - if (!yyvaluep) - return; -# ifdef YYPRINT - if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# else - YYUSE (yyoutput); -# endif - switch (yytype) - { - default: - break; - } -} - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) -#else -static void -yy_symbol_print (yyoutput, yytype, yyvaluep) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; -#endif -{ - if (yytype < YYNTOKENS) - YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); - else - YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); - - yy_symbol_value_print (yyoutput, yytype, yyvaluep); - YYFPRINTF (yyoutput, ")"); -} - -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (included). | -`------------------------------------------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) -#else -static void -yy_stack_print (bottom, top) - yytype_int16 *bottom; - yytype_int16 *top; -#endif -{ - YYFPRINTF (stderr, "Stack now"); - for (; bottom <= top; ++bottom) - YYFPRINTF (stderr, " %d", *bottom); - YYFPRINTF (stderr, "\n"); -} - -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (YYID (0)) - - -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_reduce_print (YYSTYPE *yyvsp, int yyrule) -#else -static void -yy_reduce_print (yyvsp, yyrule) - YYSTYPE *yyvsp; - int yyrule; -#endif -{ - int yynrhs = yyr2[yyrule]; - int yyi; - unsigned long int yylno = yyrline[yyrule]; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", - yyrule - 1, yylno); - /* The symbols being reduced. */ - for (yyi = 0; yyi < yynrhs; yyi++) - { - fprintf (stderr, " $%d = ", yyi + 1); - yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], - &(yyvsp[(yyi + 1) - (yynrhs)]) - ); - fprintf (stderr, "\n"); - } -} - -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyvsp, Rule); \ -} while (YYID (0)) - -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) -#endif /* !YYDEBUG */ - - -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 -#endif - - - -#if YYERROR_VERBOSE - -# ifndef yystrlen -# if defined __GLIBC__ && defined _STRING_H -# define yystrlen strlen -# else -/* Return the length of YYSTR. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static YYSIZE_T -yystrlen (const char *yystr) -#else -static YYSIZE_T -yystrlen (yystr) - const char *yystr; -#endif -{ - YYSIZE_T yylen; - for (yylen = 0; yystr[yylen]; yylen++) - continue; - return yylen; -} -# endif -# endif - -# ifndef yystpcpy -# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE -# define yystpcpy stpcpy -# else -/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static char * -yystpcpy (char *yydest, const char *yysrc) -#else -static char * -yystpcpy (yydest, yysrc) - char *yydest; - const char *yysrc; -#endif -{ - char *yyd = yydest; - const char *yys = yysrc; - - while ((*yyd++ = *yys++) != '\0') - continue; - - return yyd - 1; -} -# endif -# endif - -# ifndef yytnamerr -/* Copy to YYRES the contents of YYSTR after stripping away unnecessary - quotes and backslashes, so that it's suitable for yyerror. The - heuristic is that double-quoting is unnecessary unless the string - contains an apostrophe, a comma, or backslash (other than - backslash-backslash). YYSTR is taken from yytname. If YYRES is - null, do not copy; instead, return the length of what the result - would have been. */ -static YYSIZE_T -yytnamerr (char *yyres, const char *yystr) -{ - if (*yystr == '"') - { - YYSIZE_T yyn = 0; - char const *yyp = yystr; - - for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; - - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - /* Fall through. */ - default: - if (yyres) - yyres[yyn] = *yyp; - yyn++; - break; - - case '"': - if (yyres) - yyres[yyn] = '\0'; - return yyn; - } - do_not_strip_quotes: ; - } - - if (! yyres) - return yystrlen (yystr); - - return yystpcpy (yyres, yystr) - yyres; -} -# endif - -/* Copy into YYRESULT an error message about the unexpected token - YYCHAR while in state YYSTATE. Return the number of bytes copied, - including the terminating null byte. If YYRESULT is null, do not - copy anything; just return the number of bytes that would be - copied. As a special case, return 0 if an ordinary "syntax error" - message will do. Return YYSIZE_MAXIMUM if overflow occurs during - size calculation. */ -static YYSIZE_T -yysyntax_error (char *yyresult, int yystate, int yychar) -{ - int yyn = yypact[yystate]; - - if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) - return 0; - else - { - int yytype = YYTRANSLATE (yychar); - YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); - YYSIZE_T yysize = yysize0; - YYSIZE_T yysize1; - int yysize_overflow = 0; - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - int yyx; - -# if 0 - /* This is so xgettext sees the translatable formats that are - constructed on the fly. */ - YY_("syntax error, unexpected %s"); - YY_("syntax error, unexpected %s, expecting %s"); - YY_("syntax error, unexpected %s, expecting %s or %s"); - YY_("syntax error, unexpected %s, expecting %s or %s or %s"); - YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); -# endif - char *yyfmt; - char const *yyf; - static char const yyunexpected[] = "syntax error, unexpected %s"; - static char const yyexpecting[] = ", expecting %s"; - static char const yyor[] = " or %s"; - char yyformat[sizeof yyunexpected - + sizeof yyexpecting - 1 - + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) - * (sizeof yyor - 1))]; - char const *yyprefix = yyexpecting; - - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. */ - int yyxbegin = yyn < 0 ? -yyn : 0; - - /* Stay within bounds of both yycheck and yytname. */ - int yychecklim = YYLAST - yyn + 1; - int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; - int yycount = 1; - - yyarg[0] = yytname[yytype]; - yyfmt = yystpcpy (yyformat, yyunexpected); - - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - { - if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) - { - yycount = 1; - yysize = yysize0; - yyformat[sizeof yyunexpected - 1] = '\0'; - break; - } - yyarg[yycount++] = yytname[yyx]; - yysize1 = yysize + yytnamerr (0, yytname[yyx]); - yysize_overflow |= (yysize1 < yysize); - yysize = yysize1; - yyfmt = yystpcpy (yyfmt, yyprefix); - yyprefix = yyor; - } - - yyf = YY_(yyformat); - yysize1 = yysize + yystrlen (yyf); - yysize_overflow |= (yysize1 < yysize); - yysize = yysize1; - - if (yysize_overflow) - return YYSIZE_MAXIMUM; - - if (yyresult) - { - /* Avoid sprintf, as that infringes on the user's name space. - Don't have undefined behavior even if the translation - produced a string with the wrong number of "%s"s. */ - char *yyp = yyresult; - int yyi = 0; - while ((*yyp = *yyf) != '\0') - { - if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) - { - yyp += yytnamerr (yyp, yyarg[yyi++]); - yyf += 2; - } - else - { - yyp++; - yyf++; - } - } - } - return yysize; - } -} -#endif /* YYERROR_VERBOSE */ - - -/*-----------------------------------------------. -| Release the memory associated to this symbol. | -`-----------------------------------------------*/ - -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) -#else -static void -yydestruct (yymsg, yytype, yyvaluep) - const char *yymsg; - int yytype; - YYSTYPE *yyvaluep; -#endif -{ - YYUSE (yyvaluep); - - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - - switch (yytype) - { - - default: - break; - } -} - - -/* Prevent warnings from -Wmissing-prototypes. */ - -#ifdef YYPARSE_PARAM -#if defined __STDC__ || defined __cplusplus -int yyparse (void *YYPARSE_PARAM); -#else -int yyparse (); -#endif -#else /* ! YYPARSE_PARAM */ -#if defined __STDC__ || defined __cplusplus -int yyparse (void); -#else -int yyparse (); -#endif -#endif /* ! YYPARSE_PARAM */ - - - -/* The look-ahead symbol. */ -int yychar; - -/* The semantic value of the look-ahead symbol. */ -YYSTYPE yylval; - -/* Number of syntax errors so far. */ -int yynerrs; - - - -/*----------. -| yyparse. | -`----------*/ - -#ifdef YYPARSE_PARAM -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (void *YYPARSE_PARAM) -#else -int -yyparse (YYPARSE_PARAM) - void *YYPARSE_PARAM; -#endif -#else /* ! YYPARSE_PARAM */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (void) -#else -int -yyparse () - -#endif -#endif -{ - - int yystate; - int yyn; - int yyresult; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - /* Look-ahead token as an internal (translated) token number. */ - int yytoken = 0; -#if YYERROR_VERBOSE - /* Buffer for error messages, and its allocated size. */ - char yymsgbuf[128]; - char *yymsg = yymsgbuf; - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; -#endif - - /* Three stacks and their tools: - `yyss': related to states, - `yyvs': related to semantic values, - `yyls': related to locations. - - Refer to the stacks thru separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss = yyssa; - yytype_int16 *yyssp; - - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs = yyvsa; - YYSTYPE *yyvsp; - - - -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) - - YYSIZE_T yystacksize = YYINITDEPTH; - - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; - - - /* The number of symbols on the RHS of the reduced rule. - Keep to zero when no symbol should be popped. */ - int yylen = 0; - - YYDPRINTF ((stderr, "Starting parse\n")); - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ - - yyssp = yyss; - yyvsp = yyvs; - - goto yysetstate; - -/*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | -`------------------------------------------------------------*/ - yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. So pushing a state here evens the stacks. */ - yyssp++; - - yysetstate: - *yyssp = yystate; - - if (yyss + yystacksize - 1 <= yyssp) - { - /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; - -#ifdef yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - yytype_int16 *yyss1 = yyss; - - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - - &yystacksize); - - yyss = yyss1; - yyvs = yyvs1; - } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyexhaustedlab; -# else - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; - - { - yytype_int16 *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss); - YYSTACK_RELOCATE (yyvs); - -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif -#endif /* no yyoverflow */ - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; - - - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); - - if (yyss + yystacksize - 1 <= yyssp) - YYABORT; - } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - - goto yybackup; - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: - - /* Do appropriate processing given the current state. Read a - look-ahead token if we need one and don't already have one. */ - - /* First try to decide what to do without reference to look-ahead token. */ - yyn = yypact[yystate]; - if (yyn == YYPACT_NINF) - goto yydefault; - - /* Not known => get a look-ahead token if don't already have one. */ - - /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token: ")); - yychar = YYLEX; - } - - if (yychar <= YYEOF) - { - yychar = yytoken = YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else - { - yytoken = YYTRANSLATE (yychar); - YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); - } - - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) - goto yydefault; - yyn = yytable[yyn]; - if (yyn <= 0) - { - if (yyn == 0 || yyn == YYTABLE_NINF) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - - if (yyn == YYFINAL) - YYACCEPT; - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; - - /* Shift the look-ahead token. */ - YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - - /* Discard the shifted token unless it is eof. */ - if (yychar != YYEOF) - yychar = YYEMPTY; - - yystate = yyn; - *++yyvsp = yylval; - - goto yynewstate; - - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; - - -/*-----------------------------. -| yyreduce -- Do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: - `$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - - - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 2: -#line 281 "parser.y" - { fix_incomplete(); - check_all_user_types((yyvsp[(1) - (1)].ifref_list)); - write_proxies((yyvsp[(1) - (1)].ifref_list)); - write_client((yyvsp[(1) - (1)].ifref_list)); - write_server((yyvsp[(1) - (1)].ifref_list)); - ;} - break; - - case 3: -#line 289 "parser.y" - { (yyval.ifref_list) = NULL; ;} - break; - - case 4: -#line 290 "parser.y" - { (yyval.ifref_list) = (yyvsp[(1) - (2)].ifref_list); ;} - break; - - case 5: -#line 291 "parser.y" - { (yyval.ifref_list) = append_ifref( (yyvsp[(1) - (2)].ifref_list), make_ifref((yyvsp[(2) - (2)].type)) ); ;} - break; - - case 6: -#line 292 "parser.y" - { (yyval.ifref_list) = (yyvsp[(1) - (3)].ifref_list); - reg_type((yyvsp[(2) - (3)].type), (yyvsp[(2) - (3)].type)->name, 0); - if (!parse_only && do_header) write_coclass_forward((yyvsp[(2) - (3)].type)); - ;} - break; - - case 7: -#line 296 "parser.y" - { (yyval.ifref_list) = (yyvsp[(1) - (2)].ifref_list); - add_typelib_entry((yyvsp[(2) - (2)].type)); - reg_type((yyvsp[(2) - (2)].type), (yyvsp[(2) - (2)].type)->name, 0); - if (!parse_only && do_header) write_coclass_forward((yyvsp[(2) - (2)].type)); - ;} - break; - - case 8: -#line 301 "parser.y" - { (yyval.ifref_list) = (yyvsp[(1) - (2)].ifref_list); add_typelib_entry((yyvsp[(2) - (2)].type)); ;} - break; - - case 9: -#line 302 "parser.y" - { (yyval.ifref_list) = (yyvsp[(1) - (2)].ifref_list); ;} - break; - - case 10: -#line 303 "parser.y" - { (yyval.ifref_list) = (yyvsp[(1) - (2)].ifref_list); ;} - break; - - case 11: -#line 306 "parser.y" - {;} - break; - - case 12: -#line 307 "parser.y" - { if (!parse_only) add_typelib_entry((yyvsp[(2) - (2)].type)); ;} - break; - - case 13: -#line 308 "parser.y" - { if (!parse_only) add_typelib_entry((yyvsp[(2) - (2)].type)); ;} - break; - - case 14: -#line 309 "parser.y" - { reg_type((yyvsp[(2) - (3)].type), (yyvsp[(2) - (3)].type)->name, 0); if (!parse_only && do_header) write_coclass_forward((yyvsp[(2) - (3)].type)); ;} - break; - - case 15: -#line 310 "parser.y" - { if (!parse_only) add_typelib_entry((yyvsp[(2) - (2)].type)); - reg_type((yyvsp[(2) - (2)].type), (yyvsp[(2) - (2)].type)->name, 0); - if (!parse_only && do_header) write_coclass_forward((yyvsp[(2) - (2)].type)); - ;} - break; - - case 16: -#line 314 "parser.y" - { if (!parse_only) add_typelib_entry((yyvsp[(2) - (2)].type)); ;} - break; - - case 17: -#line 315 "parser.y" - {;} - break; - - case 18: -#line 316 "parser.y" - {;} - break; - - case 19: -#line 319 "parser.y" - { (yyval.func_list) = NULL; ;} - break; - - case 20: -#line 320 "parser.y" - { (yyval.func_list) = append_func( (yyvsp[(1) - (3)].func_list), (yyvsp[(2) - (3)].func) ); ;} - break; - - case 21: -#line 321 "parser.y" - { (yyval.func_list) = (yyvsp[(1) - (2)].func_list); ;} - break; - - case 22: -#line 324 "parser.y" - {;} - break; - - case 23: -#line 325 "parser.y" - { if (!parse_only && do_header) { write_constdef((yyvsp[(1) - (2)].var)); } ;} - break; - - case 24: -#line 326 "parser.y" - {;} - break; - - case 25: -#line 327 "parser.y" - { if (!parse_only && do_header) { - write_type(header, (yyvsp[(1) - (2)].type), FALSE, NULL); - fprintf(header, ";\n\n"); - } - ;} - break; - - case 26: -#line 332 "parser.y" - { if (!parse_only && do_header) { write_externdef((yyvsp[(1) - (2)].var)); } ;} - break; - - case 27: -#line 333 "parser.y" - {;} - break; - - case 28: -#line 334 "parser.y" - { if (!parse_only && do_header) { - write_type(header, (yyvsp[(1) - (2)].type), FALSE, NULL); - fprintf(header, ";\n\n"); - } - ;} - break; - - case 29: -#line 339 "parser.y" - {;} - break; - - case 30: -#line 340 "parser.y" - { if (!parse_only && do_header) { - write_type(header, (yyvsp[(1) - (2)].type), FALSE, NULL); - fprintf(header, ";\n\n"); - } - ;} - break; - - case 31: -#line 347 "parser.y" - { if (!parse_only && do_header) fprintf(header, "%s\n", (yyvsp[(3) - (4)].str)); ;} - break; - - case 32: -#line 349 "parser.y" - { assert(yychar == YYEMPTY); - if (!do_import((yyvsp[(2) - (3)].str))) yychar = aEOF; ;} - break; - - case 33: -#line 352 "parser.y" - {;} - break; - - case 34: -#line 355 "parser.y" - { if(!parse_only) add_importlib((yyvsp[(3) - (4)].str)); ;} - break; - - case 35: -#line 358 "parser.y" - { (yyval.str) = (yyvsp[(2) - (2)].str); ;} - break; - - case 36: -#line 360 "parser.y" - { start_typelib((yyvsp[(2) - (3)].str), (yyvsp[(1) - (3)].attr_list)); - if (!parse_only && do_header) write_library((yyvsp[(2) - (3)].str), (yyvsp[(1) - (3)].attr_list)); - if (!parse_only && do_idfile) write_libid((yyvsp[(2) - (3)].str), (yyvsp[(1) - (3)].attr_list)); - ;} - break; - - case 37: -#line 365 "parser.y" - { end_typelib(); ;} - break; - - case 38: -#line 368 "parser.y" - { (yyval.var_list) = NULL; ;} - break; - - case 40: -#line 372 "parser.y" - { (yyval.var_list) = NULL; ;} - break; - - case 41: -#line 375 "parser.y" - { check_arg((yyvsp[(1) - (1)].var)); (yyval.var_list) = append_var( NULL, (yyvsp[(1) - (1)].var) ); ;} - break; - - case 42: -#line 376 "parser.y" - { check_arg((yyvsp[(3) - (3)].var)); (yyval.var_list) = append_var( (yyvsp[(1) - (3)].var_list), (yyvsp[(3) - (3)].var)); ;} - break; - - case 44: -#line 381 "parser.y" - { (yyval.var) = (yyvsp[(3) - (4)].pident)->var; - (yyval.var)->attrs = (yyvsp[(1) - (4)].attr_list); - set_type((yyval.var), (yyvsp[(2) - (4)].type), (yyvsp[(3) - (4)].pident)->ptr_level, (yyvsp[(4) - (4)].array_dims)); - free((yyvsp[(3) - (4)].pident)); - ;} - break; - - case 45: -#line 386 "parser.y" - { (yyval.var) = (yyvsp[(2) - (3)].pident)->var; - set_type((yyval.var), (yyvsp[(1) - (3)].type), (yyvsp[(2) - (3)].pident)->ptr_level, (yyvsp[(3) - (3)].array_dims)); - free((yyvsp[(2) - (3)].pident)); - ;} - break; - - case 46: -#line 390 "parser.y" - { (yyval.var) = (yyvsp[(3) - (6)].pident)->var; - (yyval.var)->attrs = (yyvsp[(1) - (6)].attr_list); - set_type((yyval.var), (yyvsp[(2) - (6)].type), (yyvsp[(3) - (6)].pident)->ptr_level - 1, NULL); - free((yyvsp[(3) - (6)].pident)); - (yyval.var)->args = (yyvsp[(5) - (6)].var_list); - ;} - break; - - case 47: -#line 396 "parser.y" - { (yyval.var) = (yyvsp[(2) - (5)].pident)->var; - set_type((yyval.var), (yyvsp[(1) - (5)].type), (yyvsp[(2) - (5)].pident)->ptr_level - 1, NULL); - free((yyvsp[(2) - (5)].pident)); - (yyval.var)->args = (yyvsp[(4) - (5)].var_list); - ;} - break; - - case 48: -#line 403 "parser.y" - { (yyval.array_dims) = NULL; ;} - break; - - case 49: -#line 404 "parser.y" - { (yyval.array_dims) = (yyvsp[(2) - (3)].array_dims); ;} - break; - - case 50: -#line 405 "parser.y" - { (yyval.array_dims) = append_array( NULL, make_expr(EXPR_VOID) ); ;} - break; - - case 51: -#line 408 "parser.y" - { (yyval.array_dims) = append_array( NULL, (yyvsp[(1) - (1)].expr) ); ;} - break; - - case 52: -#line 409 "parser.y" - { (yyval.array_dims) = append_array( (yyvsp[(1) - (3)].array_dims), (yyvsp[(3) - (3)].expr) ); ;} - break; - - case 53: -#line 410 "parser.y" - { (yyval.array_dims) = append_array( (yyvsp[(1) - (4)].array_dims), (yyvsp[(4) - (4)].expr) ); ;} - break; - - case 54: -#line 413 "parser.y" - { (yyval.attr_list) = NULL; ;} - break; - - case 56: -#line 418 "parser.y" - { (yyval.attr_list) = (yyvsp[(2) - (3)].attr_list); - if (!(yyval.attr_list)) - yyerror("empty attribute lists unsupported"); - ;} - break; - - case 57: -#line 424 "parser.y" - { (yyval.attr_list) = append_attr( NULL, (yyvsp[(1) - (1)].attr) ); ;} - break; - - case 58: -#line 425 "parser.y" - { (yyval.attr_list) = append_attr( (yyvsp[(1) - (3)].attr_list), (yyvsp[(3) - (3)].attr) ); ;} - break; - - case 59: -#line 426 "parser.y" - { (yyval.attr_list) = append_attr( (yyvsp[(1) - (4)].attr_list), (yyvsp[(4) - (4)].attr) ); ;} - break; - - case 60: -#line 429 "parser.y" - { (yyval.str_list) = append_str( NULL, (yyvsp[(1) - (1)].str) ); ;} - break; - - case 61: -#line 430 "parser.y" - { (yyval.str_list) = append_str( (yyvsp[(1) - (3)].str_list), (yyvsp[(3) - (3)].str) ); ;} - break; - - case 62: -#line 433 "parser.y" - { (yyval.attr) = NULL; ;} - break; - - case 63: -#line 434 "parser.y" - { (yyval.attr) = make_attr(ATTR_AGGREGATABLE); ;} - break; - - case 64: -#line 435 "parser.y" - { (yyval.attr) = make_attr(ATTR_APPOBJECT); ;} - break; - - case 65: -#line 436 "parser.y" - { (yyval.attr) = make_attr(ATTR_ASYNC); ;} - break; - - case 66: -#line 437 "parser.y" - { (yyval.attr) = make_attr(ATTR_AUTO_HANDLE); ;} - break; - - case 67: -#line 438 "parser.y" - { (yyval.attr) = make_attr(ATTR_BINDABLE); ;} - break; - - case 68: -#line 439 "parser.y" - { (yyval.attr) = make_attrp(ATTR_CALLAS, (yyvsp[(3) - (4)].var)); ;} - break; - - case 69: -#line 440 "parser.y" - { (yyval.attr) = make_attrp(ATTR_CASE, (yyvsp[(3) - (4)].expr_list)); ;} - break; - - case 70: -#line 441 "parser.y" - { (yyval.attr) = make_attrv(ATTR_CONTEXTHANDLE, 0); ;} - break; - - case 71: -#line 442 "parser.y" - { (yyval.attr) = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_DONT_SERIALIZE */ ;} - break; - - case 72: -#line 443 "parser.y" - { (yyval.attr) = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_SERIALIZE */ ;} - break; - - case 73: -#line 444 "parser.y" - { (yyval.attr) = make_attr(ATTR_CONTROL); ;} - break; - - case 74: -#line 445 "parser.y" - { (yyval.attr) = make_attr(ATTR_DEFAULT); ;} - break; - - case 75: -#line 446 "parser.y" - { (yyval.attr) = make_attr(ATTR_DEFAULTCOLLELEM); ;} - break; - - case 76: -#line 447 "parser.y" - { (yyval.attr) = make_attrp(ATTR_DEFAULTVALUE_EXPR, (yyvsp[(3) - (4)].expr)); ;} - break; - - case 77: -#line 448 "parser.y" - { (yyval.attr) = make_attrp(ATTR_DEFAULTVALUE_STRING, (yyvsp[(3) - (4)].str)); ;} - break; - - case 78: -#line 449 "parser.y" - { (yyval.attr) = make_attr(ATTR_DEFAULTVTABLE); ;} - break; - - case 79: -#line 450 "parser.y" - { (yyval.attr) = make_attr(ATTR_DISPLAYBIND); ;} - break; - - case 80: -#line 451 "parser.y" - { (yyval.attr) = make_attrp(ATTR_DLLNAME, (yyvsp[(3) - (4)].str)); ;} - break; - - case 81: -#line 452 "parser.y" - { (yyval.attr) = make_attr(ATTR_DUAL); ;} - break; - - case 82: -#line 453 "parser.y" - { (yyval.attr) = make_attrp(ATTR_ENDPOINT, (yyvsp[(3) - (4)].str_list)); ;} - break; - - case 83: -#line 454 "parser.y" - { (yyval.attr) = make_attrp(ATTR_ENTRY_STRING, (yyvsp[(3) - (4)].str)); ;} - break; - - case 84: -#line 455 "parser.y" - { (yyval.attr) = make_attrp(ATTR_ENTRY_ORDINAL, (yyvsp[(3) - (4)].expr)); ;} - break; - - case 85: -#line 456 "parser.y" - { (yyval.attr) = make_attr(ATTR_EXPLICIT_HANDLE); ;} - break; - - case 86: -#line 457 "parser.y" - { (yyval.attr) = make_attr(ATTR_HANDLE); ;} - break; - - case 87: -#line 458 "parser.y" - { (yyval.attr) = make_attrp(ATTR_HELPCONTEXT, (yyvsp[(3) - (4)].expr)); ;} - break; - - case 88: -#line 459 "parser.y" - { (yyval.attr) = make_attrp(ATTR_HELPFILE, (yyvsp[(3) - (4)].str)); ;} - break; - - case 89: -#line 460 "parser.y" - { (yyval.attr) = make_attrp(ATTR_HELPSTRING, (yyvsp[(3) - (4)].str)); ;} - break; - - case 90: -#line 461 "parser.y" - { (yyval.attr) = make_attrp(ATTR_HELPSTRINGCONTEXT, (yyvsp[(3) - (4)].expr)); ;} - break; - - case 91: -#line 462 "parser.y" - { (yyval.attr) = make_attrp(ATTR_HELPSTRINGDLL, (yyvsp[(3) - (4)].str)); ;} - break; - - case 92: -#line 463 "parser.y" - { (yyval.attr) = make_attr(ATTR_HIDDEN); ;} - break; - - case 93: -#line 464 "parser.y" - { (yyval.attr) = make_attrp(ATTR_ID, (yyvsp[(3) - (4)].expr)); ;} - break; - - case 94: -#line 465 "parser.y" - { (yyval.attr) = make_attr(ATTR_IDEMPOTENT); ;} - break; - - case 95: -#line 466 "parser.y" - { (yyval.attr) = make_attrp(ATTR_IIDIS, (yyvsp[(3) - (4)].var)); ;} - break; - - case 96: -#line 467 "parser.y" - { (yyval.attr) = make_attr(ATTR_IMMEDIATEBIND); ;} - break; - - case 97: -#line 468 "parser.y" - { (yyval.attr) = make_attrp(ATTR_IMPLICIT_HANDLE, (yyvsp[(4) - (5)].str)); ;} - break; - - case 98: -#line 469 "parser.y" - { (yyval.attr) = make_attr(ATTR_IN); ;} - break; - - case 99: -#line 470 "parser.y" - { (yyval.attr) = make_attr(ATTR_INPUTSYNC); ;} - break; - - case 100: -#line 471 "parser.y" - { (yyval.attr) = make_attrp(ATTR_LENGTHIS, (yyvsp[(3) - (4)].expr_list)); ;} - break; - - case 101: -#line 472 "parser.y" - { (yyval.attr) = make_attr(ATTR_LOCAL); ;} - break; - - case 102: -#line 473 "parser.y" - { (yyval.attr) = make_attr(ATTR_NONBROWSABLE); ;} - break; - - case 103: -#line 474 "parser.y" - { (yyval.attr) = make_attr(ATTR_NONCREATABLE); ;} - break; - - case 104: -#line 475 "parser.y" - { (yyval.attr) = make_attr(ATTR_NONEXTENSIBLE); ;} - break; - - case 105: -#line 476 "parser.y" - { (yyval.attr) = make_attr(ATTR_OBJECT); ;} - break; - - case 106: -#line 477 "parser.y" - { (yyval.attr) = make_attr(ATTR_ODL); ;} - break; - - case 107: -#line 478 "parser.y" - { (yyval.attr) = make_attr(ATTR_OLEAUTOMATION); ;} - break; - - case 108: -#line 479 "parser.y" - { (yyval.attr) = make_attr(ATTR_OPTIONAL); ;} - break; - - case 109: -#line 480 "parser.y" - { (yyval.attr) = make_attr(ATTR_OUT); ;} - break; - - case 110: -#line 481 "parser.y" - { (yyval.attr) = make_attrv(ATTR_POINTERDEFAULT, (yyvsp[(3) - (4)].num)); ;} - break; - - case 111: -#line 482 "parser.y" - { (yyval.attr) = make_attr(ATTR_PROPGET); ;} - break; - - case 112: -#line 483 "parser.y" - { (yyval.attr) = make_attr(ATTR_PROPPUT); ;} - break; - - case 113: -#line 484 "parser.y" - { (yyval.attr) = make_attr(ATTR_PROPPUTREF); ;} - break; - - case 114: -#line 485 "parser.y" - { (yyval.attr) = make_attr(ATTR_PUBLIC); ;} - break; - - case 115: -#line 486 "parser.y" - { expr_list_t *list = append_expr( NULL, (yyvsp[(3) - (6)].expr) ); - list = append_expr( list, (yyvsp[(5) - (6)].expr) ); - (yyval.attr) = make_attrp(ATTR_RANGE, list); ;} - break; - - case 116: -#line 489 "parser.y" - { (yyval.attr) = make_attr(ATTR_READONLY); ;} - break; - - case 117: -#line 490 "parser.y" - { (yyval.attr) = make_attr(ATTR_REQUESTEDIT); ;} - break; - - case 118: -#line 491 "parser.y" - { (yyval.attr) = make_attr(ATTR_RESTRICTED); ;} - break; - - case 119: -#line 492 "parser.y" - { (yyval.attr) = make_attr(ATTR_RETVAL); ;} - break; - - case 120: -#line 493 "parser.y" - { (yyval.attr) = make_attrp(ATTR_SIZEIS, (yyvsp[(3) - (4)].expr_list)); ;} - break; - - case 121: -#line 494 "parser.y" - { (yyval.attr) = make_attr(ATTR_SOURCE); ;} - break; - - case 122: -#line 495 "parser.y" - { (yyval.attr) = make_attr(ATTR_STRING); ;} - break; - - case 123: -#line 496 "parser.y" - { (yyval.attr) = make_attrp(ATTR_SWITCHIS, (yyvsp[(3) - (4)].expr)); ;} - break; - - case 124: -#line 497 "parser.y" - { (yyval.attr) = make_attrp(ATTR_SWITCHTYPE, (yyvsp[(3) - (4)].type)); ;} - break; - - case 125: -#line 498 "parser.y" - { (yyval.attr) = make_attrp(ATTR_TRANSMITAS, (yyvsp[(3) - (4)].type)); ;} - break; - - case 126: -#line 499 "parser.y" - { (yyval.attr) = make_attrp(ATTR_UUID, (yyvsp[(3) - (4)].uuid)); ;} - break; - - case 127: -#line 500 "parser.y" - { (yyval.attr) = make_attr(ATTR_V1ENUM); ;} - break; - - case 128: -#line 501 "parser.y" - { (yyval.attr) = make_attr(ATTR_VARARG); ;} - break; - - case 129: -#line 502 "parser.y" - { (yyval.attr) = make_attrv(ATTR_VERSION, (yyvsp[(3) - (4)].num)); ;} - break; - - case 130: -#line 503 "parser.y" - { (yyval.attr) = make_attrp(ATTR_WIREMARSHAL, (yyvsp[(3) - (4)].type)); ;} - break; - - case 131: -#line 504 "parser.y" - { (yyval.attr) = make_attrv(ATTR_POINTERTYPE, (yyvsp[(1) - (1)].num)); ;} - break; - - case 134: -#line 511 "parser.y" - { (yyval.var_list) = NULL; ;} - break; - - case 135: -#line 512 "parser.y" - { (yyval.var_list) = append_var( (yyvsp[(1) - (2)].var_list), (yyvsp[(2) - (2)].var) ); ;} - break; - - case 136: -#line 515 "parser.y" - { attr_t *a = make_attrp(ATTR_CASE, append_expr( NULL, (yyvsp[(2) - (4)].expr) )); - (yyval.var) = (yyvsp[(4) - (4)].var); if (!(yyval.var)) (yyval.var) = make_var(NULL); - (yyval.var)->attrs = append_attr( (yyval.var)->attrs, a ); - ;} - break; - - case 137: -#line 519 "parser.y" - { attr_t *a = make_attr(ATTR_DEFAULT); - (yyval.var) = (yyvsp[(3) - (3)].var); if (!(yyval.var)) (yyval.var) = make_var(NULL); - (yyval.var)->attrs = append_attr( (yyval.var)->attrs, a ); - ;} - break; - - case 138: -#line 525 "parser.y" - { (yyval.var) = reg_const((yyvsp[(3) - (5)].var)); - set_type((yyval.var), (yyvsp[(2) - (5)].type), 0, NULL); - (yyval.var)->eval = (yyvsp[(5) - (5)].expr); - ;} - break; - - case 139: -#line 531 "parser.y" - { (yyval.var_list) = NULL; ;} - break; - - case 140: -#line 532 "parser.y" - { (yyval.var_list) = (yyvsp[(1) - (2)].var_list); ;} - break; - - case 142: -#line 536 "parser.y" - { if (!(yyvsp[(1) - (1)].var)->eval) - (yyvsp[(1) - (1)].var)->eval = make_exprl(EXPR_NUM, 0 /* default for first enum entry */); - (yyval.var_list) = append_var( NULL, (yyvsp[(1) - (1)].var) ); - ;} - break; - - case 143: -#line 540 "parser.y" - { if (!(yyvsp[(3) - (3)].var)->eval) - { - var_t *last = LIST_ENTRY( list_tail((yyval.var_list)), var_t, entry ); - (yyvsp[(3) - (3)].var)->eval = make_exprl(EXPR_NUM, last->eval->cval + 1); - } - (yyval.var_list) = append_var( (yyvsp[(1) - (3)].var_list), (yyvsp[(3) - (3)].var) ); - ;} - break; - - case 144: -#line 549 "parser.y" - { (yyval.var) = reg_const((yyvsp[(1) - (3)].var)); - (yyval.var)->eval = (yyvsp[(3) - (3)].expr); - (yyval.var)->type = make_int(0); - ;} - break; - - case 145: -#line 553 "parser.y" - { (yyval.var) = reg_const((yyvsp[(1) - (1)].var)); - (yyval.var)->type = make_int(0); - ;} - break; - - case 146: -#line 558 "parser.y" - { (yyval.type) = get_typev(RPC_FC_ENUM16, (yyvsp[(2) - (5)].var), tsENUM); - (yyval.type)->kind = TKIND_ENUM; - (yyval.type)->fields = (yyvsp[(4) - (5)].var_list); - (yyval.type)->defined = TRUE; - if(in_typelib) - add_typelib_entry((yyval.type)); - ;} - break; - - case 147: -#line 567 "parser.y" - { (yyval.expr_list) = append_expr( NULL, (yyvsp[(1) - (1)].expr) ); ;} - break; - - case 148: -#line 568 "parser.y" - { (yyval.expr_list) = append_expr( (yyvsp[(1) - (3)].expr_list), (yyvsp[(3) - (3)].expr) ); ;} - break; - - case 149: -#line 581 "parser.y" - { (yyval.expr) = make_expr(EXPR_VOID); ;} - break; - - case 151: -#line 585 "parser.y" - { (yyval.expr) = make_exprl(EXPR_NUM, (yyvsp[(1) - (1)].num)); ;} - break; - - case 152: -#line 586 "parser.y" - { (yyval.expr) = make_exprl(EXPR_HEXNUM, (yyvsp[(1) - (1)].num)); ;} - break; - - case 153: -#line 587 "parser.y" - { (yyval.expr) = make_exprd(EXPR_DOUBLE, (yyvsp[(1) - (1)].dbl)); ;} - break; - - case 154: -#line 588 "parser.y" - { (yyval.expr) = make_exprl(EXPR_TRUEFALSE, 0); ;} - break; - - case 155: -#line 589 "parser.y" - { (yyval.expr) = make_exprl(EXPR_TRUEFALSE, 1); ;} - break; - - case 156: -#line 590 "parser.y" - { (yyval.expr) = make_exprs(EXPR_IDENTIFIER, (yyvsp[(1) - (1)].str)); ;} - break; - - case 157: -#line 591 "parser.y" - { (yyval.expr) = make_expr3(EXPR_COND, (yyvsp[(1) - (5)].expr), (yyvsp[(3) - (5)].expr), (yyvsp[(5) - (5)].expr)); ;} - break; - - case 158: -#line 592 "parser.y" - { (yyval.expr) = make_expr2(EXPR_OR , (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} - break; - - case 159: -#line 593 "parser.y" - { (yyval.expr) = make_expr2(EXPR_AND, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} - break; - - case 160: -#line 594 "parser.y" - { (yyval.expr) = make_expr2(EXPR_ADD, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} - break; - - case 161: -#line 595 "parser.y" - { (yyval.expr) = make_expr2(EXPR_SUB, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} - break; - - case 162: -#line 596 "parser.y" - { (yyval.expr) = make_expr2(EXPR_MUL, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} - break; - - case 163: -#line 597 "parser.y" - { (yyval.expr) = make_expr2(EXPR_DIV, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} - break; - - case 164: -#line 598 "parser.y" - { (yyval.expr) = make_expr2(EXPR_SHL, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} - break; - - case 165: -#line 599 "parser.y" - { (yyval.expr) = make_expr2(EXPR_SHR, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} - break; - - case 166: -#line 600 "parser.y" - { (yyval.expr) = make_expr1(EXPR_NOT, (yyvsp[(2) - (2)].expr)); ;} - break; - - case 167: -#line 601 "parser.y" - { (yyval.expr) = make_expr1(EXPR_NEG, (yyvsp[(2) - (2)].expr)); ;} - break; - - case 168: -#line 602 "parser.y" - { (yyval.expr) = make_expr1(EXPR_PPTR, (yyvsp[(2) - (2)].expr)); ;} - break; - - case 169: -#line 603 "parser.y" - { (yyval.expr) = make_exprt(EXPR_CAST, (yyvsp[(2) - (4)].type), (yyvsp[(4) - (4)].expr)); ;} - break; - - case 170: -#line 604 "parser.y" - { (yyval.expr) = make_exprt(EXPR_SIZEOF, (yyvsp[(3) - (4)].type), NULL); ;} - break; - - case 171: -#line 605 "parser.y" - { (yyval.expr) = (yyvsp[(2) - (3)].expr); ;} - break; - - case 172: -#line 608 "parser.y" - { (yyval.expr_list) = append_expr( NULL, (yyvsp[(1) - (1)].expr) ); ;} - break; - - case 173: -#line 609 "parser.y" - { (yyval.expr_list) = append_expr( (yyvsp[(1) - (3)].expr_list), (yyvsp[(3) - (3)].expr) ); ;} - break; - - case 174: -#line 612 "parser.y" - { (yyval.expr) = (yyvsp[(1) - (1)].expr); - if (!(yyval.expr)->is_const) - yyerror("expression is not constant"); - ;} - break; - - case 175: -#line 618 "parser.y" - { (yyval.var) = (yyvsp[(4) - (4)].var); - set_type((yyval.var), (yyvsp[(3) - (4)].type), 0, NULL); - ;} - break; - - case 176: -#line 623 "parser.y" - { (yyval.var_list) = NULL; ;} - break; - - case 177: -#line 624 "parser.y" - { (yyval.var_list) = append_var( (yyvsp[(1) - (2)].var_list), (yyvsp[(2) - (2)].var) ); ;} - break; - - case 178: -#line 627 "parser.y" - { (yyval.var) = (yyvsp[(1) - (2)].var); ;} - break; - - case 179: -#line 628 "parser.y" - { (yyval.var) = make_var(NULL); (yyval.var)->type = (yyvsp[(2) - (3)].type); (yyval.var)->attrs = (yyvsp[(1) - (3)].attr_list); ;} - break; - - case 180: -#line 629 "parser.y" - { (yyval.var) = make_var(NULL); (yyval.var)->attrs = (yyvsp[(1) - (2)].attr_list); ;} - break; - - case 181: -#line 630 "parser.y" - { (yyval.var) = NULL; ;} - break; - - case 182: -#line 633 "parser.y" - { (yyval.var) = (yyvsp[(3) - (4)].pident)->var; - (yyval.var)->attrs = (yyvsp[(1) - (4)].attr_list); - set_type((yyval.var), (yyvsp[(2) - (4)].type), (yyvsp[(3) - (4)].pident)->ptr_level, (yyvsp[(4) - (4)].array_dims)); - free((yyvsp[(3) - (4)].pident)); - ;} - break; - - case 183: -#line 642 "parser.y" - { var_t *v = (yyvsp[(4) - (7)].pident)->var; - v->attrs = (yyvsp[(1) - (7)].attr_list); - set_type(v, (yyvsp[(2) - (7)].type), (yyvsp[(4) - (7)].pident)->ptr_level, NULL); - free((yyvsp[(4) - (7)].pident)); - (yyval.func) = make_func(v, (yyvsp[(6) - (7)].var_list)); - if (is_attr(v->attrs, ATTR_IN)) { - yyerror("inapplicable attribute [in] for function '%s'",(yyval.func)->def->name); - } - ;} - break; - - case 184: -#line 653 "parser.y" - { (yyval.var) = NULL; ;} - break; - - case 186: -#line 657 "parser.y" - { (yyval.var) = NULL; ;} - break; - - case 187: -#line 658 "parser.y" - { (yyval.var) = make_var((yyvsp[(1) - (1)].str)); ;} - break; - - case 188: -#line 659 "parser.y" - { (yyval.var) = make_var((yyvsp[(1) - (1)].str)); ;} - break; - - case 189: -#line 662 "parser.y" - { (yyval.var) = make_var((yyvsp[(1) - (1)].str)); ;} - break; - - case 190: -#line 664 "parser.y" - { (yyval.var) = make_var((yyvsp[(1) - (1)].str)); ;} - break; - - case 191: -#line 667 "parser.y" - { (yyval.type) = make_builtin((yyvsp[(1) - (1)].str)); ;} - break; - - case 192: -#line 668 "parser.y" - { (yyval.type) = make_builtin((yyvsp[(1) - (1)].str)); ;} - break; - - case 194: -#line 670 "parser.y" - { (yyval.type) = (yyvsp[(2) - (2)].type); (yyval.type)->sign = 1; ;} - break; - - case 195: -#line 671 "parser.y" - { (yyval.type) = (yyvsp[(2) - (2)].type); (yyval.type)->sign = -1; - switch ((yyval.type)->type) { - case RPC_FC_CHAR: break; - case RPC_FC_SMALL: (yyval.type)->type = RPC_FC_USMALL; break; - case RPC_FC_SHORT: (yyval.type)->type = RPC_FC_USHORT; break; - case RPC_FC_LONG: (yyval.type)->type = RPC_FC_ULONG; break; - case RPC_FC_HYPER: - if ((yyval.type)->name[0] == 'h') /* hyper, as opposed to __int64 */ - { - (yyval.type) = alias((yyval.type), "MIDL_uhyper"); - (yyval.type)->sign = 0; - } - break; - default: break; - } - ;} - break; - - case 196: -#line 687 "parser.y" - { (yyval.type) = make_int(-1); ;} - break; - - case 197: -#line 688 "parser.y" - { (yyval.type) = make_builtin((yyvsp[(1) - (1)].str)); ;} - break; - - case 198: -#line 689 "parser.y" - { (yyval.type) = duptype(find_type("float", 0), 1); ;} - break; - - case 199: -#line 690 "parser.y" - { (yyval.type) = make_builtin((yyvsp[(1) - (1)].str)); ;} - break; - - case 200: -#line 691 "parser.y" - { (yyval.type) = make_builtin((yyvsp[(1) - (1)].str)); ;} - break; - - case 201: -#line 692 "parser.y" - { (yyval.type) = make_builtin((yyvsp[(1) - (1)].str)); ;} - break; - - case 202: -#line 693 "parser.y" - { (yyval.type) = make_builtin((yyvsp[(1) - (1)].str)); ;} - break; - - case 205: -#line 700 "parser.y" - { (yyval.type) = make_builtin((yyvsp[(1) - (1)].str)); ;} - break; - - case 206: -#line 701 "parser.y" - { (yyval.type) = make_builtin((yyvsp[(1) - (2)].str)); ;} - break; - - case 207: -#line 702 "parser.y" - { (yyval.type) = make_builtin((yyvsp[(1) - (1)].str)); ;} - break; - - case 208: -#line 703 "parser.y" - { (yyval.type) = make_builtin((yyvsp[(1) - (2)].str)); ;} - break; - - case 209: -#line 704 "parser.y" - { (yyval.type) = make_builtin((yyvsp[(1) - (2)].str)); ;} - break; - - case 210: -#line 705 "parser.y" - { (yyval.type) = make_builtin((yyvsp[(1) - (1)].str)); ;} - break; - - case 211: -#line 706 "parser.y" - { (yyval.type) = make_builtin((yyvsp[(1) - (1)].str)); ;} - break; - - case 212: -#line 709 "parser.y" - { (yyval.type) = make_class((yyvsp[(2) - (2)].str)); ;} - break; - - case 213: -#line 710 "parser.y" - { (yyval.type) = find_type((yyvsp[(2) - (2)].str), 0); - if ((yyval.type)->defined) yyerror("multiple definition error"); - if ((yyval.type)->kind != TKIND_COCLASS) yyerror("%s was not declared a coclass", (yyvsp[(2) - (2)].str)); - ;} - break; - - case 214: -#line 716 "parser.y" - { (yyval.type) = (yyvsp[(2) - (2)].type); - (yyval.type)->attrs = (yyvsp[(1) - (2)].attr_list); - if (!parse_only && do_header) - write_coclass((yyval.type)); - if (!parse_only && do_idfile) - write_clsid((yyval.type)); - ;} - break; - - case 215: -#line 725 "parser.y" - { (yyval.type) = (yyvsp[(1) - (4)].type); - (yyval.type)->ifaces = (yyvsp[(3) - (4)].ifref_list); - (yyval.type)->defined = TRUE; - ;} - break; - - case 216: -#line 731 "parser.y" - { (yyval.ifref_list) = NULL; ;} - break; - - case 217: -#line 732 "parser.y" - { (yyval.ifref_list) = append_ifref( (yyvsp[(1) - (2)].ifref_list), (yyvsp[(2) - (2)].ifref) ); ;} - break; - - case 218: -#line 736 "parser.y" - { (yyval.ifref) = make_ifref((yyvsp[(2) - (2)].type)); (yyval.ifref)->attrs = (yyvsp[(1) - (2)].attr_list); ;} - break; - - case 219: -#line 739 "parser.y" - { (yyval.type) = get_type(0, (yyvsp[(2) - (2)].str), 0); (yyval.type)->kind = TKIND_DISPATCH; ;} - break; - - case 220: -#line 740 "parser.y" - { (yyval.type) = get_type(0, (yyvsp[(2) - (2)].str), 0); (yyval.type)->kind = TKIND_DISPATCH; ;} - break; - - case 221: -#line 743 "parser.y" - { attr_t *attrs; - (yyval.type) = (yyvsp[(2) - (2)].type); - if ((yyval.type)->defined) yyerror("multiple definition error"); - attrs = make_attr(ATTR_DISPINTERFACE); - (yyval.type)->attrs = append_attr( (yyvsp[(1) - (2)].attr_list), attrs ); - (yyval.type)->ref = find_type("IDispatch", 0); - if (!(yyval.type)->ref) yyerror("IDispatch is undefined"); - (yyval.type)->defined = TRUE; - if (!parse_only && do_header) write_forward((yyval.type)); - ;} - break; - - case 222: -#line 755 "parser.y" - { (yyval.var_list) = NULL; ;} - break; - - case 223: -#line 756 "parser.y" - { (yyval.var_list) = append_var( (yyvsp[(1) - (3)].var_list), (yyvsp[(2) - (3)].var) ); ;} - break; - - case 224: -#line 759 "parser.y" - { (yyval.func_list) = NULL; ;} - break; - - case 225: -#line 760 "parser.y" - { (yyval.func_list) = append_func( (yyvsp[(1) - (3)].func_list), (yyvsp[(2) - (3)].func) ); ;} - break; - - case 226: -#line 766 "parser.y" - { (yyval.type) = (yyvsp[(1) - (5)].type); - (yyval.type)->fields = (yyvsp[(3) - (5)].var_list); - (yyval.type)->funcs = (yyvsp[(4) - (5)].func_list); - if (!parse_only && do_header) write_dispinterface((yyval.type)); - if (!parse_only && do_idfile) write_diid((yyval.type)); - ;} - break; - - case 227: -#line 773 "parser.y" - { (yyval.type) = (yyvsp[(1) - (5)].type); - (yyval.type)->fields = (yyvsp[(3) - (5)].type)->fields; - (yyval.type)->funcs = (yyvsp[(3) - (5)].type)->funcs; - if (!parse_only && do_header) write_dispinterface((yyval.type)); - if (!parse_only && do_idfile) write_diid((yyval.type)); - ;} - break; - - case 228: -#line 781 "parser.y" - { (yyval.type) = NULL; ;} - break; - - case 229: -#line 782 "parser.y" - { (yyval.type) = find_type2((yyvsp[(2) - (2)].str), 0); ;} - break; - - case 230: -#line 785 "parser.y" - { (yyval.type) = get_type(RPC_FC_IP, (yyvsp[(2) - (2)].str), 0); (yyval.type)->kind = TKIND_INTERFACE; ;} - break; - - case 231: -#line 786 "parser.y" - { (yyval.type) = get_type(RPC_FC_IP, (yyvsp[(2) - (2)].str), 0); (yyval.type)->kind = TKIND_INTERFACE; ;} - break; - - case 232: -#line 789 "parser.y" - { (yyval.type) = (yyvsp[(2) - (2)].type); - if ((yyval.type)->defined) yyerror("multiple definition error"); - (yyval.type)->attrs = (yyvsp[(1) - (2)].attr_list); - (yyval.type)->defined = TRUE; - if (!parse_only && do_header) write_forward((yyval.type)); - ;} - break; - - case 233: -#line 798 "parser.y" - { (yyval.type) = (yyvsp[(1) - (5)].type); - (yyval.type)->ref = (yyvsp[(2) - (5)].type); - (yyval.type)->funcs = (yyvsp[(4) - (5)].func_list); - compute_method_indexes((yyval.type)); - if (!parse_only && do_header) write_interface((yyval.type)); - if (!parse_only && do_idfile) write_iid((yyval.type)); - ;} - break; - - case 234: -#line 808 "parser.y" - { (yyval.type) = (yyvsp[(1) - (7)].type); - (yyval.type)->ref = find_type2((yyvsp[(3) - (7)].str), 0); - if (!(yyval.type)->ref) yyerror("base class '%s' not found in import", (yyvsp[(3) - (7)].str)); - (yyval.type)->funcs = (yyvsp[(6) - (7)].func_list); - compute_method_indexes((yyval.type)); - if (!parse_only && do_header) write_interface((yyval.type)); - if (!parse_only && do_idfile) write_iid((yyval.type)); - ;} - break; - - case 235: -#line 816 "parser.y" - { (yyval.type) = (yyvsp[(1) - (1)].type); ;} - break; - - case 236: -#line 820 "parser.y" - { (yyval.type) = (yyvsp[(1) - (2)].type); if (!parse_only && do_header) write_forward((yyval.type)); ;} - break; - - case 237: -#line 821 "parser.y" - { (yyval.type) = (yyvsp[(1) - (2)].type); if (!parse_only && do_header) write_forward((yyval.type)); ;} - break; - - case 238: -#line 824 "parser.y" - { (yyval.type) = make_type(0, NULL); (yyval.type)->name = (yyvsp[(2) - (2)].str); (yyval.type)->kind = TKIND_MODULE; ;} - break; - - case 239: -#line 825 "parser.y" - { (yyval.type) = make_type(0, NULL); (yyval.type)->name = (yyvsp[(2) - (2)].str); (yyval.type)->kind = TKIND_MODULE; ;} - break; - - case 240: -#line 828 "parser.y" - { (yyval.type) = (yyvsp[(2) - (2)].type); - (yyval.type)->attrs = (yyvsp[(1) - (2)].attr_list); - ;} - break; - - case 241: -#line 833 "parser.y" - { (yyval.type) = (yyvsp[(1) - (4)].type); - (yyval.type)->funcs = (yyvsp[(3) - (4)].func_list); - /* FIXME: if (!parse_only && do_header) write_module($$); */ - ;} - break; - - case 242: -#line 839 "parser.y" - { (yyval.pident) = (yyvsp[(2) - (2)].pident); (yyval.pident)->ptr_level++; ;} - break; - - case 243: -#line 840 "parser.y" - { (yyval.pident) = (yyvsp[(2) - (2)].pident); /* FIXME */ ;} - break; - - case 244: -#line 843 "parser.y" - { (yyval.pident) = make_pident((yyvsp[(1) - (1)].var)); ;} - break; - - case 246: -#line 845 "parser.y" - { (yyval.pident) = (yyvsp[(2) - (3)].pident); ;} - break; - - case 247: -#line 849 "parser.y" - { (yyval.pident_list) = append_pident( NULL, (yyvsp[(1) - (1)].pident) ); ;} - break; - - case 248: -#line 850 "parser.y" - { (yyval.pident_list) = append_pident( (yyvsp[(1) - (3)].pident_list), (yyvsp[(3) - (3)].pident) ); ;} - break; - - case 249: -#line 854 "parser.y" - { (yyval.num) = RPC_FC_RP; ;} - break; - - case 250: -#line 855 "parser.y" - { (yyval.num) = RPC_FC_UP; ;} - break; - - case 251: -#line 856 "parser.y" - { (yyval.num) = RPC_FC_FP; ;} - break; - - case 252: -#line 859 "parser.y" - { (yyval.type) = get_typev(RPC_FC_STRUCT, (yyvsp[(2) - (5)].var), tsSTRUCT); - /* overwrite RPC_FC_STRUCT with a more exact type */ - (yyval.type)->type = get_struct_type( (yyvsp[(4) - (5)].var_list) ); - (yyval.type)->kind = TKIND_RECORD; - (yyval.type)->fields = (yyvsp[(4) - (5)].var_list); - (yyval.type)->defined = TRUE; - if(in_typelib) - add_typelib_entry((yyval.type)); - ;} - break; - - case 253: -#line 870 "parser.y" - { (yyval.type) = duptype(find_type("void", 0), 1); ;} - break; - - case 254: -#line 871 "parser.y" - { (yyval.type) = find_type((yyvsp[(1) - (1)].str), 0); ;} - break; - - case 255: -#line 872 "parser.y" - { (yyval.type) = (yyvsp[(1) - (1)].type); ;} - break; - - case 256: -#line 873 "parser.y" - { (yyval.type) = duptype((yyvsp[(2) - (2)].type), 1); (yyval.type)->is_const = TRUE; ;} - break; - - case 257: -#line 874 "parser.y" - { (yyval.type) = (yyvsp[(1) - (1)].type); ;} - break; - - case 258: -#line 875 "parser.y" - { (yyval.type) = find_type2((yyvsp[(2) - (2)].str), tsENUM); ;} - break; - - case 259: -#line 876 "parser.y" - { (yyval.type) = (yyvsp[(1) - (1)].type); ;} - break; - - case 260: -#line 877 "parser.y" - { (yyval.type) = get_type(RPC_FC_STRUCT, (yyvsp[(2) - (2)].str), tsSTRUCT); ;} - break; - - case 261: -#line 878 "parser.y" - { (yyval.type) = (yyvsp[(1) - (1)].type); ;} - break; - - case 262: -#line 879 "parser.y" - { (yyval.type) = find_type2((yyvsp[(2) - (2)].str), tsUNION); ;} - break; - - case 263: -#line 880 "parser.y" - { (yyval.type) = make_safearray((yyvsp[(3) - (4)].type)); ;} - break; - - case 264: -#line 883 "parser.y" - { reg_typedefs((yyvsp[(3) - (4)].type), (yyvsp[(4) - (4)].pident_list), (yyvsp[(2) - (4)].attr_list)); - process_typedefs((yyvsp[(4) - (4)].pident_list)); - ;} - break; - - case 265: -#line 888 "parser.y" - { (yyval.type) = get_typev(RPC_FC_NON_ENCAPSULATED_UNION, (yyvsp[(2) - (5)].var), tsUNION); - (yyval.type)->kind = TKIND_UNION; - (yyval.type)->fields = (yyvsp[(4) - (5)].var_list); - (yyval.type)->defined = TRUE; - ;} - break; - - case 266: -#line 895 "parser.y" - { var_t *u = (yyvsp[(7) - (10)].var); - (yyval.type) = get_typev(RPC_FC_ENCAPSULATED_UNION, (yyvsp[(2) - (10)].var), tsUNION); - (yyval.type)->kind = TKIND_UNION; - if (!u) u = make_var( xstrdup("tagged_union") ); - u->type = make_type(RPC_FC_NON_ENCAPSULATED_UNION, NULL); - u->type->kind = TKIND_UNION; - u->type->fields = (yyvsp[(9) - (10)].var_list); - u->type->defined = TRUE; - (yyval.type)->fields = append_var( (yyval.type)->fields, (yyvsp[(5) - (10)].var) ); - (yyval.type)->fields = append_var( (yyval.type)->fields, u ); - (yyval.type)->defined = TRUE; - ;} - break; - - case 267: -#line 910 "parser.y" - { (yyval.num) = MAKELONG((yyvsp[(1) - (1)].num), 0); ;} - break; - - case 268: -#line 911 "parser.y" - { (yyval.num) = MAKELONG((yyvsp[(1) - (3)].num), (yyvsp[(3) - (3)].num)); ;} - break; - - -/* Line 1267 of yacc.c. */ -#line 3822 "parser.tab.c" - default: break; - } - YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); - - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - - *++yyvsp = yyval; - - - /* Now `shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTOKENS]; - - goto yynewstate; - - -/*------------------------------------. -| yyerrlab -- here on detecting error | -`------------------------------------*/ -yyerrlab: - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) - { - ++yynerrs; -#if ! YYERROR_VERBOSE - yyerror (YY_("syntax error")); -#else - { - YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); - if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) - { - YYSIZE_T yyalloc = 2 * yysize; - if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) - yyalloc = YYSTACK_ALLOC_MAXIMUM; - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - yymsg = (char *) YYSTACK_ALLOC (yyalloc); - if (yymsg) - yymsg_alloc = yyalloc; - else - { - yymsg = yymsgbuf; - yymsg_alloc = sizeof yymsgbuf; - } - } - - if (0 < yysize && yysize <= yymsg_alloc) - { - (void) yysyntax_error (yymsg, yystate, yychar); - yyerror (yymsg); - } - else - { - yyerror (YY_("syntax error")); - if (yysize != 0) - goto yyexhaustedlab; - } - } -#endif - } - - - - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse look-ahead token after an - error, discard it. */ - - if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } - else - { - yydestruct ("Error: discarding", - yytoken, &yylval); - yychar = YYEMPTY; - } - } - - /* Else will try to reuse look-ahead token after shifting the error - token. */ - goto yyerrlab1; - - -/*---------------------------------------------------. -| yyerrorlab -- error raised explicitly by YYERROR. | -`---------------------------------------------------*/ -yyerrorlab: - - /* Pacify compilers like GCC when the user code never invokes - YYERROR and the label yyerrorlab therefore never appears in user - code. */ - if (/*CONSTCOND*/ 0) - goto yyerrorlab; - - /* Do not reclaim the symbols of the rule which action triggered - this YYERROR. */ - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - yystate = *yyssp; - goto yyerrlab1; - - -/*-------------------------------------------------------------. -| yyerrlab1 -- common code for both syntax error and YYERROR. | -`-------------------------------------------------------------*/ -yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ - - for (;;) - { - yyn = yypact[yystate]; - if (yyn != YYPACT_NINF) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) - YYABORT; - - - yydestruct ("Error: popping", - yystos[yystate], yyvsp); - YYPOPSTACK (1); - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); - } - - if (yyn == YYFINAL) - YYACCEPT; - - *++yyvsp = yylval; - - - /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); - - yystate = yyn; - goto yynewstate; - - -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturn; - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturn; - -#ifndef yyoverflow -/*-------------------------------------------------. -| yyexhaustedlab -- memory exhaustion comes here. | -`-------------------------------------------------*/ -yyexhaustedlab: - yyerror (YY_("memory exhausted")); - yyresult = 2; - /* Fall through. */ -#endif - -yyreturn: - if (yychar != YYEOF && yychar != YYEMPTY) - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval); - /* Do not reclaim the symbols of the rule which action triggered - this YYABORT or YYACCEPT. */ - YYPOPSTACK (yylen); - YY_STACK_PRINT (yyss, yyssp); - while (yyssp != yyss) - { - yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp); - YYPOPSTACK (1); - } -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif -#if YYERROR_VERBOSE - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); -#endif - /* Make sure YYID is used. */ - return YYID (yyresult); -} - - -#line 914 "parser.y" - - -static void decl_builtin(const char *name, unsigned char type) -{ - type_t *t = make_type(type, NULL); - t->name = xstrdup(name); - reg_type(t, name, 0); -} - -static type_t *make_builtin(char *name) -{ - /* NAME is strdup'd in the lexer */ - type_t *t = duptype(find_type(name, 0), 0); - t->name = name; - return t; -} - -static type_t *make_int(int sign) -{ - type_t *t = duptype(find_type("int", 0), 1); - - t->sign = sign; - if (sign < 0) - t->type = t->type == RPC_FC_LONG ? RPC_FC_ULONG : RPC_FC_USHORT; - - return t; -} - -void init_types(void) -{ - decl_builtin("void", 0); - decl_builtin("byte", RPC_FC_BYTE); - decl_builtin("wchar_t", RPC_FC_WCHAR); - decl_builtin("int", RPC_FC_LONG); /* win32 */ - decl_builtin("short", RPC_FC_SHORT); - decl_builtin("small", RPC_FC_SMALL); - decl_builtin("long", RPC_FC_LONG); - decl_builtin("hyper", RPC_FC_HYPER); - decl_builtin("__int64", RPC_FC_HYPER); - decl_builtin("char", RPC_FC_CHAR); - decl_builtin("float", RPC_FC_FLOAT); - decl_builtin("double", RPC_FC_DOUBLE); - decl_builtin("boolean", RPC_FC_BYTE); - decl_builtin("error_status_t", RPC_FC_ERROR_STATUS_T); - decl_builtin("handle_t", RPC_FC_BIND_PRIMITIVE); -} - -static str_list_t *append_str(str_list_t *list, char *str) -{ - struct str_list_entry_t *entry; - - if (!str) return list; - if (!list) - { - list = xmalloc( sizeof(*list) ); - list_init( list ); - } - entry = xmalloc( sizeof(*entry) ); - entry->str = str; - list_add_tail( list, &entry->entry ); - return list; -} - -static attr_list_t *append_attr(attr_list_t *list, attr_t *attr) -{ - if (!attr) return list; - if (!list) - { - list = xmalloc( sizeof(*list) ); - list_init( list ); - } - list_add_tail( list, &attr->entry ); - return list; -} - -static attr_t *make_attr(enum attr_type type) -{ - attr_t *a = xmalloc(sizeof(attr_t)); - a->type = type; - a->u.ival = 0; - return a; -} - -static attr_t *make_attrv(enum attr_type type, unsigned long val) -{ - attr_t *a = xmalloc(sizeof(attr_t)); - a->type = type; - a->u.ival = val; - return a; -} - -static attr_t *make_attrp(enum attr_type type, void *val) -{ - attr_t *a = xmalloc(sizeof(attr_t)); - a->type = type; - a->u.pval = val; - return a; -} - -static expr_t *make_expr(enum expr_type type) -{ - expr_t *e = xmalloc(sizeof(expr_t)); - e->type = type; - e->ref = NULL; - e->u.lval = 0; - e->is_const = FALSE; - return e; -} - -static expr_t *make_exprl(enum expr_type type, long val) -{ - expr_t *e = xmalloc(sizeof(expr_t)); - e->type = type; - e->ref = NULL; - e->u.lval = val; - e->is_const = FALSE; - /* check for numeric constant */ - if (type == EXPR_NUM || type == EXPR_HEXNUM || type == EXPR_TRUEFALSE) { - /* make sure true/false value is valid */ - assert(type != EXPR_TRUEFALSE || val == 0 || val == 1); - e->is_const = TRUE; - e->cval = val; - } - return e; -} - -static expr_t *make_exprd(enum expr_type type, double val) -{ - expr_t *e = xmalloc(sizeof(expr_t)); - e->type = type; - e->ref = NULL; - e->u.dval = val; - e->is_const = TRUE; - e->cval = val; - return e; -} - -static expr_t *make_exprs(enum expr_type type, char *val) -{ - expr_t *e; - e = xmalloc(sizeof(expr_t)); - e->type = type; - e->ref = NULL; - e->u.sval = val; - e->is_const = FALSE; - /* check for predefined constants */ - if (type == EXPR_IDENTIFIER) { - var_t *c = find_const(val, 0); - if (c) { - e->u.sval = c->name; - free(val); - e->is_const = TRUE; - e->cval = c->eval->cval; - } - } - return e; -} - -static expr_t *make_exprt(enum expr_type type, type_t *tref, expr_t *expr) -{ - expr_t *e; - e = xmalloc(sizeof(expr_t)); - e->type = type; - e->ref = expr; - e->u.tref = tref; - e->is_const = FALSE; - /* check for cast of constant expression */ - if (type == EXPR_SIZEOF) { - switch (tref->type) { - case RPC_FC_BYTE: - case RPC_FC_CHAR: - case RPC_FC_SMALL: - case RPC_FC_USMALL: - e->is_const = TRUE; - e->cval = 1; - break; - case RPC_FC_WCHAR: - case RPC_FC_USHORT: - case RPC_FC_SHORT: - e->is_const = TRUE; - e->cval = 2; - break; - case RPC_FC_LONG: - case RPC_FC_ULONG: - case RPC_FC_FLOAT: - case RPC_FC_ERROR_STATUS_T: - e->is_const = TRUE; - e->cval = 4; - break; - case RPC_FC_HYPER: - case RPC_FC_DOUBLE: - e->is_const = TRUE; - e->cval = 8; - break; - } - } - if (type == EXPR_CAST && expr->is_const) { - e->is_const = TRUE; - e->cval = expr->cval; - } - return e; -} - -static expr_t *make_expr1(enum expr_type type, expr_t *expr) -{ - expr_t *e; - e = xmalloc(sizeof(expr_t)); - e->type = type; - e->ref = expr; - e->u.lval = 0; - e->is_const = FALSE; - /* check for compile-time optimization */ - if (expr->is_const) { - e->is_const = TRUE; - switch (type) { - case EXPR_NEG: - e->cval = -expr->cval; - break; - case EXPR_NOT: - e->cval = ~expr->cval; - break; - default: - e->is_const = FALSE; - break; - } - } - return e; -} - -static expr_t *make_expr2(enum expr_type type, expr_t *expr1, expr_t *expr2) -{ - expr_t *e; - e = xmalloc(sizeof(expr_t)); - e->type = type; - e->ref = expr1; - e->u.ext = expr2; - e->is_const = FALSE; - /* check for compile-time optimization */ - if (expr1->is_const && expr2->is_const) { - e->is_const = TRUE; - switch (type) { - case EXPR_ADD: - e->cval = expr1->cval + expr2->cval; - break; - case EXPR_SUB: - e->cval = expr1->cval - expr2->cval; - break; - case EXPR_MUL: - e->cval = expr1->cval * expr2->cval; - break; - case EXPR_DIV: - e->cval = expr1->cval / expr2->cval; - break; - case EXPR_OR: - e->cval = expr1->cval | expr2->cval; - break; - case EXPR_AND: - e->cval = expr1->cval & expr2->cval; - break; - case EXPR_SHL: - e->cval = expr1->cval << expr2->cval; - break; - case EXPR_SHR: - e->cval = expr1->cval >> expr2->cval; - break; - default: - e->is_const = FALSE; - break; - } - } - return e; -} - -static expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, expr_t *expr3) -{ - expr_t *e; - e = xmalloc(sizeof(expr_t)); - e->type = type; - e->ref = expr1; - e->u.ext = expr2; - e->ext2 = expr3; - e->is_const = FALSE; - /* check for compile-time optimization */ - if (expr1->is_const && expr2->is_const && expr3->is_const) { - e->is_const = TRUE; - switch (type) { - case EXPR_COND: - e->cval = expr1->cval ? expr2->cval : expr3->cval; - break; - default: - e->is_const = FALSE; - break; - } - } - return e; -} - -static expr_list_t *append_expr(expr_list_t *list, expr_t *expr) -{ - if (!expr) return list; - if (!list) - { - list = xmalloc( sizeof(*list) ); - list_init( list ); - } - list_add_tail( list, &expr->entry ); - return list; -} - -static array_dims_t *append_array(array_dims_t *list, expr_t *expr) -{ - if (!expr) return list; - if (!list) - { - list = xmalloc( sizeof(*list) ); - list_init( list ); - } - list_add_tail( list, &expr->entry ); - return list; -} - -static type_t *make_type(unsigned char type, type_t *ref) -{ - type_t *t = xmalloc(sizeof(type_t)); - t->name = NULL; - t->kind = TKIND_PRIMITIVE; - t->type = type; - t->ref = ref; - t->attrs = NULL; - t->orig = NULL; - t->funcs = NULL; - t->fields = NULL; - t->ifaces = NULL; - t->dim = 0; - t->size_is = NULL; - t->length_is = NULL; - t->typestring_offset = 0; - t->declarray = FALSE; - t->ignore = (parse_only != 0); - t->is_const = FALSE; - t->sign = 0; - t->defined = FALSE; - t->written = FALSE; - t->user_types_registered = FALSE; - t->tfswrite = FALSE; - t->typelib_idx = -1; - return t; -} - -static void set_type(var_t *v, type_t *type, int ptr_level, array_dims_t *arr) -{ - expr_list_t *sizes = get_attrp(v->attrs, ATTR_SIZEIS); - expr_list_t *lengs = get_attrp(v->attrs, ATTR_LENGTHIS); - int sizeless, has_varconf; - expr_t *dim; - type_t *atype, **ptype; - - v->type = type; - - for ( ; 0 < ptr_level; --ptr_level) - v->type = make_type(RPC_FC_RP, v->type); - - sizeless = FALSE; - if (arr) LIST_FOR_EACH_ENTRY_REV(dim, arr, expr_t, entry) - { - if (sizeless) - error("%s: only the first array dimension can be unspecified\n", v->name); - - if (dim->is_const) - { - unsigned int align = 0; - size_t size = type_memsize(v->type, &align); - - if (dim->cval <= 0) - error("%s: array dimension must be positive\n", v->name); - - if (0xffffffffuL / size < (unsigned long) dim->cval) - error("%s: total array size is too large", v->name); - else if (0xffffuL < size * dim->cval) - v->type = make_type(RPC_FC_LGFARRAY, v->type); - else - v->type = make_type(RPC_FC_SMFARRAY, v->type); - } - else - { - sizeless = TRUE; - v->type = make_type(RPC_FC_CARRAY, v->type); - } - - v->type->declarray = TRUE; - v->type->dim = dim->cval; - } - - ptype = &v->type; - has_varconf = FALSE; - if (sizes) LIST_FOR_EACH_ENTRY(dim, sizes, expr_t, entry) - { - if (dim->type != EXPR_VOID) - { - has_varconf = TRUE; - atype = *ptype = duptype(*ptype, 0); - - if (atype->type == RPC_FC_SMFARRAY || atype->type == RPC_FC_LGFARRAY) - error("%s: cannot specify size_is for a fixed sized array\n", v->name); - - if (atype->type != RPC_FC_CARRAY && !is_ptr(atype)) - error("%s: size_is attribute applied to illegal type\n", v->name); - - atype->type = RPC_FC_CARRAY; - atype->size_is = dim; - } - - ptype = &(*ptype)->ref; - if (*ptype == NULL) - error("%s: too many expressions in size_is attribute\n", v->name); - } - - ptype = &v->type; - if (lengs) LIST_FOR_EACH_ENTRY(dim, lengs, expr_t, entry) - { - if (dim->type != EXPR_VOID) - { - has_varconf = TRUE; - atype = *ptype = duptype(*ptype, 0); - - if (atype->type == RPC_FC_SMFARRAY) - atype->type = RPC_FC_SMVARRAY; - else if (atype->type == RPC_FC_LGFARRAY) - atype->type = RPC_FC_LGVARRAY; - else if (atype->type == RPC_FC_CARRAY) - atype->type = RPC_FC_CVARRAY; - else - error("%s: length_is attribute applied to illegal type\n", v->name); - - atype->length_is = dim; - } - - ptype = &(*ptype)->ref; - if (*ptype == NULL) - error("%s: too many expressions in length_is attribute\n", v->name); - } - - if (has_varconf && !last_array(v->type)) - { - ptype = &v->type; - for (ptype = &v->type; is_array(*ptype); ptype = &(*ptype)->ref) - { - *ptype = duptype(*ptype, 0); - (*ptype)->type = RPC_FC_BOGUS_ARRAY; - } - } -} - -static ifref_list_t *append_ifref(ifref_list_t *list, ifref_t *iface) -{ - if (!iface) return list; - if (!list) - { - list = xmalloc( sizeof(*list) ); - list_init( list ); - } - list_add_tail( list, &iface->entry ); - return list; -} - -static ifref_t *make_ifref(type_t *iface) -{ - ifref_t *l = xmalloc(sizeof(ifref_t)); - l->iface = iface; - l->attrs = NULL; - return l; -} - -static var_list_t *append_var(var_list_t *list, var_t *var) -{ - if (!var) return list; - if (!list) - { - list = xmalloc( sizeof(*list) ); - list_init( list ); - } - list_add_tail( list, &var->entry ); - return list; -} - -static var_t *make_var(char *name) -{ - var_t *v = xmalloc(sizeof(var_t)); - v->name = name; - v->type = NULL; - v->args = NULL; - v->attrs = NULL; - v->eval = NULL; - return v; -} - -static pident_list_t *append_pident(pident_list_t *list, pident_t *p) -{ - if (!p) return list; - if (!list) { - list = xmalloc(sizeof(*list)); - list_init(list); - } - list_add_tail(list, &p->entry); - return list; -} - -static pident_t *make_pident(var_t *var) -{ - pident_t *p = xmalloc(sizeof(*p)); - p->var = var; - p->ptr_level = 0; - return p; -} - -static func_list_t *append_func(func_list_t *list, func_t *func) -{ - if (!func) return list; - if (!list) - { - list = xmalloc( sizeof(*list) ); - list_init( list ); - } - list_add_tail( list, &func->entry ); - return list; -} - -static func_t *make_func(var_t *def, var_list_t *args) -{ - func_t *f = xmalloc(sizeof(func_t)); - f->def = def; - f->args = args; - f->ignore = parse_only; - f->idx = -1; - return f; -} - -static type_t *make_class(char *name) -{ - type_t *c = make_type(0, NULL); - c->name = name; - c->kind = TKIND_COCLASS; - return c; -} - -static type_t *make_safearray(type_t *type) -{ - type_t *sa = duptype(find_type("SAFEARRAY", 0), 1); - sa->ref = type; - return make_type(RPC_FC_FP, sa); -} - -#define HASHMAX 64 - -static int hash_ident(const char *name) -{ - const char *p = name; - int sum = 0; - /* a simple sum hash is probably good enough */ - while (*p) { - sum += *p; - p++; - } - return sum & (HASHMAX-1); -} - -/***** type repository *****/ - -struct rtype { - const char *name; - type_t *type; - int t; - struct rtype *next; -}; - -struct rtype *type_hash[HASHMAX]; - -static type_t *reg_type(type_t *type, const char *name, int t) -{ - struct rtype *nt; - int hash; - if (!name) { - yyerror("registering named type without name"); - return type; - } - hash = hash_ident(name); - nt = xmalloc(sizeof(struct rtype)); - nt->name = name; - nt->type = type; - nt->t = t; - nt->next = type_hash[hash]; - type_hash[hash] = nt; - return type; -} - -static int is_incomplete(const type_t *t) -{ - return !t->defined && (is_struct(t->type) || is_union(t->type)); -} - -static void add_incomplete(type_t *t) -{ - struct typenode *tn = xmalloc(sizeof *tn); - tn->type = t; - list_add_tail(&incomplete_types, &tn->entry); -} - -static void fix_type(type_t *t) -{ - if (t->kind == TKIND_ALIAS && is_incomplete(t)) { - type_t *ot = t->orig; - fix_type(ot); - t->fields = ot->fields; - t->defined = ot->defined; - } -} - -static void fix_incomplete(void) -{ - struct typenode *tn, *next; - - LIST_FOR_EACH_ENTRY_SAFE(tn, next, &incomplete_types, struct typenode, entry) { - fix_type(tn->type); - free(tn); - } -} - -static type_t *reg_typedefs(type_t *type, pident_list_t *pidents, attr_list_t *attrs) -{ - type_t *ptr = type; - const pident_t *pident; - int ptrc = 0; - int is_str = is_attr(attrs, ATTR_STRING); - unsigned char ptr_type = get_attrv(attrs, ATTR_POINTERTYPE); - - if (is_str) - { - type_t *t = type; - unsigned char c; - - while (is_ptr(t)) - t = t->ref; - - c = t->type; - if (c != RPC_FC_CHAR && c != RPC_FC_BYTE && c != RPC_FC_WCHAR) - { - pident = LIST_ENTRY( list_head( pidents ), const pident_t, entry ); - yyerror("'%s': [string] attribute is only valid on 'char', 'byte', or 'wchar_t' pointers and arrays", - pident->var->name); - } - } - - /* We must generate names for tagless enum, struct or union. - Typedef-ing a tagless enum, struct or union means we want the typedef - to be included in a library whether it has other attributes or not, - hence the public attribute. */ - if ((type->kind == TKIND_ENUM || type->kind == TKIND_RECORD - || type->kind == TKIND_UNION) && ! type->name && ! parse_only) - { - if (! is_attr(attrs, ATTR_PUBLIC)) - attrs = append_attr( attrs, make_attr(ATTR_PUBLIC) ); - type->name = gen_name(); - } - - LIST_FOR_EACH_ENTRY( pident, pidents, const pident_t, entry ) - { - var_t *name = pident->var; - - if (name->name) { - type_t *cur = ptr; - int cptr = pident->ptr_level; - if (cptr > ptrc) { - while (cptr > ptrc) { - cur = ptr = make_type(RPC_FC_RP, cur); - ptrc++; - } - } else { - while (cptr < ptrc) { - cur = cur->ref; - cptr++; - } - } - cur = alias(cur, name->name); - cur->attrs = attrs; - if (ptr_type) - { - if (is_ptr(cur)) - cur->type = ptr_type; - else - yyerror("'%s': pointer attribute applied to non-pointer type", - cur->name); - } - else if (is_str && ! is_ptr(cur)) - yyerror("'%s': [string] attribute applied to non-pointer type", - cur->name); - - if (is_incomplete(cur)) - add_incomplete(cur); - reg_type(cur, cur->name, 0); - } - } - return type; -} - -static type_t *find_type(const char *name, int t) -{ - struct rtype *cur = type_hash[hash_ident(name)]; - while (cur && (cur->t != t || strcmp(cur->name, name))) - cur = cur->next; - if (!cur) { - yyerror("type '%s' not found", name); - return NULL; - } - return cur->type; -} - -static type_t *find_type2(char *name, int t) -{ - type_t *tp = find_type(name, t); - free(name); - return tp; -} - -int is_type(const char *name) -{ - struct rtype *cur = type_hash[hash_ident(name)]; - while (cur && (cur->t || strcmp(cur->name, name))) - cur = cur->next; - if (cur) return TRUE; - return FALSE; -} - -static type_t *get_type(unsigned char type, char *name, int t) -{ - struct rtype *cur = NULL; - type_t *tp; - if (name) { - cur = type_hash[hash_ident(name)]; - while (cur && (cur->t != t || strcmp(cur->name, name))) - cur = cur->next; - } - if (cur) { - free(name); - return cur->type; - } - tp = make_type(type, NULL); - tp->name = name; - if (!name) return tp; - return reg_type(tp, name, t); -} - -static type_t *get_typev(unsigned char type, var_t *name, int t) -{ - char *sname = NULL; - if (name) { - sname = name->name; - free(name); - } - return get_type(type, sname, t); -} - -static int get_struct_type(var_list_t *fields) -{ - int has_pointer = 0; - int has_conformance = 0; - int has_variance = 0; - var_t *field; - - if (fields) LIST_FOR_EACH_ENTRY( field, fields, var_t, entry ) - { - type_t *t = field->type; - - if (is_ptr(t)) - { - do - t = t->ref; - while (is_ptr(t)); - - switch (t->type) - { - case RPC_FC_IP: - case RPC_FC_ENCAPSULATED_UNION: - case RPC_FC_NON_ENCAPSULATED_UNION: - case RPC_FC_BOGUS_STRUCT: - return RPC_FC_BOGUS_STRUCT; - } - - has_pointer = 1; - continue; - } - - if (field->type->declarray) - { - if (is_string_type(field->attrs, field->type)) - { - if (is_conformant_array(field->type)) - has_conformance = 1; - has_variance = 1; - continue; - } - - if (is_array(field->type->ref)) - return RPC_FC_BOGUS_STRUCT; - - if (is_conformant_array(field->type)) - { - has_conformance = 1; - if (field->type->declarray && list_next(fields, &field->entry)) - yyerror("field '%s' deriving from a conformant array must be the last field in the structure", - field->name); - } - if (field->type->length_is) - has_variance = 1; - - t = field->type->ref; - } - - switch (t->type) - { - /* - * RPC_FC_BYTE, RPC_FC_STRUCT, etc - * Simple types don't effect the type of struct. - * A struct containing a simple struct is still a simple struct. - * So long as we can block copy the data, we return RPC_FC_STRUCT. - */ - case 0: /* void pointer */ - case RPC_FC_BYTE: - case RPC_FC_CHAR: - case RPC_FC_SMALL: - case RPC_FC_USMALL: - case RPC_FC_WCHAR: - case RPC_FC_SHORT: - case RPC_FC_USHORT: - case RPC_FC_LONG: - case RPC_FC_ULONG: - case RPC_FC_INT3264: - case RPC_FC_UINT3264: - case RPC_FC_HYPER: - case RPC_FC_FLOAT: - case RPC_FC_DOUBLE: - case RPC_FC_STRUCT: - case RPC_FC_ENUM16: - case RPC_FC_ENUM32: - break; - - case RPC_FC_RP: - case RPC_FC_UP: - case RPC_FC_FP: - case RPC_FC_OP: - case RPC_FC_CARRAY: - case RPC_FC_CVARRAY: - has_pointer = 1; - break; - - /* - * Propagate member attributes - * a struct should be at least as complex as its member - */ - case RPC_FC_CVSTRUCT: - has_conformance = 1; - has_variance = 1; - has_pointer = 1; - break; - - case RPC_FC_CPSTRUCT: - has_conformance = 1; - if (list_next( fields, &field->entry )) - yyerror("field '%s' deriving from a conformant array must be the last field in the structure", - field->name); - has_pointer = 1; - break; - - case RPC_FC_CSTRUCT: - has_conformance = 1; - if (list_next( fields, &field->entry )) - yyerror("field '%s' deriving from a conformant array must be the last field in the structure", - field->name); - break; - - case RPC_FC_PSTRUCT: - has_pointer = 1; - break; - - default: - fprintf(stderr,"Unknown struct member %s with type (0x%02x)\n", - field->name, t->type); - /* fallthru - treat it as complex */ - - /* as soon as we see one of these these members, it's bogus... */ - case RPC_FC_IP: - case RPC_FC_ENCAPSULATED_UNION: - case RPC_FC_NON_ENCAPSULATED_UNION: - case RPC_FC_TRANSMIT_AS: - case RPC_FC_REPRESENT_AS: - case RPC_FC_PAD: - case RPC_FC_EMBEDDED_COMPLEX: - case RPC_FC_BOGUS_STRUCT: - return RPC_FC_BOGUS_STRUCT; - } - } - - if( has_variance ) - { - if ( has_conformance ) - return RPC_FC_CVSTRUCT; - else - return RPC_FC_BOGUS_STRUCT; - } - if( has_conformance && has_pointer ) - return RPC_FC_CPSTRUCT; - if( has_conformance ) - return RPC_FC_CSTRUCT; - if( has_pointer ) - return RPC_FC_PSTRUCT; - return RPC_FC_STRUCT; -} - -/***** constant repository *****/ - -struct rconst { - char *name; - var_t *var; - struct rconst *next; -}; - -struct rconst *const_hash[HASHMAX]; - -static var_t *reg_const(var_t *var) -{ - struct rconst *nc; - int hash; - if (!var->name) { - yyerror("registering constant without name"); - return var; - } - hash = hash_ident(var->name); - nc = xmalloc(sizeof(struct rconst)); - nc->name = var->name; - nc->var = var; - nc->next = const_hash[hash]; - const_hash[hash] = nc; - return var; -} - -static var_t *find_const(char *name, int f) -{ - struct rconst *cur = const_hash[hash_ident(name)]; - while (cur && strcmp(cur->name, name)) - cur = cur->next; - if (!cur) { - if (f) yyerror("constant '%s' not found", name); - return NULL; - } - return cur->var; -} - -static void write_libid(const char *name, const attr_list_t *attr) -{ - const UUID *uuid = get_attrp(attr, ATTR_UUID); - write_guid(idfile, "LIBID", name, uuid); -} - -static void write_clsid(type_t *cls) -{ - const UUID *uuid = get_attrp(cls->attrs, ATTR_UUID); - write_guid(idfile, "CLSID", cls->name, uuid); -} - -static void write_diid(type_t *iface) -{ - const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID); - write_guid(idfile, "DIID", iface->name, uuid); -} - -static void write_iid(type_t *iface) -{ - const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID); - write_guid(idfile, "IID", iface->name, uuid); -} - -static int compute_method_indexes(type_t *iface) -{ - int idx; - func_t *f; - - if (iface->ref) - idx = compute_method_indexes(iface->ref); - else - idx = 0; - - if (!iface->funcs) - return idx; - - LIST_FOR_EACH_ENTRY( f, iface->funcs, func_t, entry ) - if (! is_callas(f->def->attrs)) - f->idx = idx++; - - return idx; -} - -static char *gen_name(void) -{ - static const char format[] = "__WIDL_%s_generated_name_%08lX"; - static unsigned long n = 0; - static const char *file_id; - static size_t size; - char *name; - - if (! file_id) - { - char *dst = dup_basename(input_name, ".idl"); - file_id = dst; - - for (; *dst; ++dst) - if (! isalnum((unsigned char) *dst)) - *dst = '_'; - - size = sizeof format - 7 + strlen(file_id) + 8; - } - - name = xmalloc(size); - sprintf(name, format, file_id, n++); - return name; -} - -static void process_typedefs(pident_list_t *pidents) -{ - pident_t *pident, *next; - - if (!pidents) return; - LIST_FOR_EACH_ENTRY_SAFE( pident, next, pidents, pident_t, entry ) - { - var_t *var = pident->var; - type_t *type = find_type(var->name, 0); - - if (! parse_only && do_header) - write_typedef(type); - if (in_typelib && type->attrs) - add_typelib_entry(type); - - free(pident); - free(var); - } -} - -static void check_arg(var_t *arg) -{ - type_t *t = arg->type; - - if (t->type == 0 && ! is_var_ptr(arg)) - yyerror("argument '%s' has void type", arg->name); -} - -static void check_all_user_types(ifref_list_t *ifrefs) -{ - const ifref_t *ifref; - const func_t *f; - - if (ifrefs) LIST_FOR_EACH_ENTRY(ifref, ifrefs, const ifref_t, entry) - { - const func_list_t *fs = ifref->iface->funcs; - if (fs) LIST_FOR_EACH_ENTRY(f, fs, const func_t, entry) - check_for_user_types(f->args); - } -} - diff --git a/reactos/tools/widl_new/parser.tab.h b/reactos/tools/widl_new/parser.tab.h deleted file mode 100644 index af5713a610c..00000000000 --- a/reactos/tools/widl_new/parser.tab.h +++ /dev/null @@ -1,346 +0,0 @@ -/* A Bison parser, made by GNU Bison 2.3. */ - -/* Skeleton interface for Bison's Yacc-like parsers in C - - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 - Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - aIDENTIFIER = 258, - aKNOWNTYPE = 259, - aNUM = 260, - aHEXNUM = 261, - aDOUBLE = 262, - aSTRING = 263, - aUUID = 264, - aEOF = 265, - SHL = 266, - SHR = 267, - tAGGREGATABLE = 268, - tALLOCATE = 269, - tAPPOBJECT = 270, - tASYNC = 271, - tASYNCUUID = 272, - tAUTOHANDLE = 273, - tBINDABLE = 274, - tBOOLEAN = 275, - tBROADCAST = 276, - tBYTE = 277, - tBYTECOUNT = 278, - tCALLAS = 279, - tCALLBACK = 280, - tCASE = 281, - tCDECL = 282, - tCHAR = 283, - tCOCLASS = 284, - tCODE = 285, - tCOMMSTATUS = 286, - tCONST = 287, - tCONTEXTHANDLE = 288, - tCONTEXTHANDLENOSERIALIZE = 289, - tCONTEXTHANDLESERIALIZE = 290, - tCONTROL = 291, - tCPPQUOTE = 292, - tDEFAULT = 293, - tDEFAULTCOLLELEM = 294, - tDEFAULTVALUE = 295, - tDEFAULTVTABLE = 296, - tDISPLAYBIND = 297, - tDISPINTERFACE = 298, - tDLLNAME = 299, - tDOUBLE = 300, - tDUAL = 301, - tENDPOINT = 302, - tENTRY = 303, - tENUM = 304, - tERRORSTATUST = 305, - tEXPLICITHANDLE = 306, - tEXTERN = 307, - tFALSE = 308, - tFLOAT = 309, - tHANDLE = 310, - tHANDLET = 311, - tHELPCONTEXT = 312, - tHELPFILE = 313, - tHELPSTRING = 314, - tHELPSTRINGCONTEXT = 315, - tHELPSTRINGDLL = 316, - tHIDDEN = 317, - tHYPER = 318, - tID = 319, - tIDEMPOTENT = 320, - tIIDIS = 321, - tIMMEDIATEBIND = 322, - tIMPLICITHANDLE = 323, - tIMPORT = 324, - tIMPORTLIB = 325, - tIN = 326, - tINLINE = 327, - tINPUTSYNC = 328, - tINT = 329, - tINT64 = 330, - tINTERFACE = 331, - tLCID = 332, - tLENGTHIS = 333, - tLIBRARY = 334, - tLOCAL = 335, - tLONG = 336, - tMETHODS = 337, - tMODULE = 338, - tNONBROWSABLE = 339, - tNONCREATABLE = 340, - tNONEXTENSIBLE = 341, - tOBJECT = 342, - tODL = 343, - tOLEAUTOMATION = 344, - tOPTIONAL = 345, - tOUT = 346, - tPOINTERDEFAULT = 347, - tPROPERTIES = 348, - tPROPGET = 349, - tPROPPUT = 350, - tPROPPUTREF = 351, - tPTR = 352, - tPUBLIC = 353, - tRANGE = 354, - tREADONLY = 355, - tREF = 356, - tREQUESTEDIT = 357, - tRESTRICTED = 358, - tRETVAL = 359, - tSAFEARRAY = 360, - tSHORT = 361, - tSIGNED = 362, - tSINGLE = 363, - tSIZEIS = 364, - tSIZEOF = 365, - tSMALL = 366, - tSOURCE = 367, - tSTDCALL = 368, - tSTRING = 369, - tSTRUCT = 370, - tSWITCH = 371, - tSWITCHIS = 372, - tSWITCHTYPE = 373, - tTRANSMITAS = 374, - tTRUE = 375, - tTYPEDEF = 376, - tUNION = 377, - tUNIQUE = 378, - tUNSIGNED = 379, - tUUID = 380, - tV1ENUM = 381, - tVARARG = 382, - tVERSION = 383, - tVOID = 384, - tWCHAR = 385, - tWIREMARSHAL = 386, - CAST = 387, - PPTR = 388, - NEG = 389 - }; -#endif -/* Tokens. */ -#define aIDENTIFIER 258 -#define aKNOWNTYPE 259 -#define aNUM 260 -#define aHEXNUM 261 -#define aDOUBLE 262 -#define aSTRING 263 -#define aUUID 264 -#define aEOF 265 -#define SHL 266 -#define SHR 267 -#define tAGGREGATABLE 268 -#define tALLOCATE 269 -#define tAPPOBJECT 270 -#define tASYNC 271 -#define tASYNCUUID 272 -#define tAUTOHANDLE 273 -#define tBINDABLE 274 -#define tBOOLEAN 275 -#define tBROADCAST 276 -#define tBYTE 277 -#define tBYTECOUNT 278 -#define tCALLAS 279 -#define tCALLBACK 280 -#define tCASE 281 -#define tCDECL 282 -#define tCHAR 283 -#define tCOCLASS 284 -#define tCODE 285 -#define tCOMMSTATUS 286 -#define tCONST 287 -#define tCONTEXTHANDLE 288 -#define tCONTEXTHANDLENOSERIALIZE 289 -#define tCONTEXTHANDLESERIALIZE 290 -#define tCONTROL 291 -#define tCPPQUOTE 292 -#define tDEFAULT 293 -#define tDEFAULTCOLLELEM 294 -#define tDEFAULTVALUE 295 -#define tDEFAULTVTABLE 296 -#define tDISPLAYBIND 297 -#define tDISPINTERFACE 298 -#define tDLLNAME 299 -#define tDOUBLE 300 -#define tDUAL 301 -#define tENDPOINT 302 -#define tENTRY 303 -#define tENUM 304 -#define tERRORSTATUST 305 -#define tEXPLICITHANDLE 306 -#define tEXTERN 307 -#define tFALSE 308 -#define tFLOAT 309 -#define tHANDLE 310 -#define tHANDLET 311 -#define tHELPCONTEXT 312 -#define tHELPFILE 313 -#define tHELPSTRING 314 -#define tHELPSTRINGCONTEXT 315 -#define tHELPSTRINGDLL 316 -#define tHIDDEN 317 -#define tHYPER 318 -#define tID 319 -#define tIDEMPOTENT 320 -#define tIIDIS 321 -#define tIMMEDIATEBIND 322 -#define tIMPLICITHANDLE 323 -#define tIMPORT 324 -#define tIMPORTLIB 325 -#define tIN 326 -#define tINLINE 327 -#define tINPUTSYNC 328 -#define tINT 329 -#define tINT64 330 -#define tINTERFACE 331 -#define tLCID 332 -#define tLENGTHIS 333 -#define tLIBRARY 334 -#define tLOCAL 335 -#define tLONG 336 -#define tMETHODS 337 -#define tMODULE 338 -#define tNONBROWSABLE 339 -#define tNONCREATABLE 340 -#define tNONEXTENSIBLE 341 -#define tOBJECT 342 -#define tODL 343 -#define tOLEAUTOMATION 344 -#define tOPTIONAL 345 -#define tOUT 346 -#define tPOINTERDEFAULT 347 -#define tPROPERTIES 348 -#define tPROPGET 349 -#define tPROPPUT 350 -#define tPROPPUTREF 351 -#define tPTR 352 -#define tPUBLIC 353 -#define tRANGE 354 -#define tREADONLY 355 -#define tREF 356 -#define tREQUESTEDIT 357 -#define tRESTRICTED 358 -#define tRETVAL 359 -#define tSAFEARRAY 360 -#define tSHORT 361 -#define tSIGNED 362 -#define tSINGLE 363 -#define tSIZEIS 364 -#define tSIZEOF 365 -#define tSMALL 366 -#define tSOURCE 367 -#define tSTDCALL 368 -#define tSTRING 369 -#define tSTRUCT 370 -#define tSWITCH 371 -#define tSWITCHIS 372 -#define tSWITCHTYPE 373 -#define tTRANSMITAS 374 -#define tTRUE 375 -#define tTYPEDEF 376 -#define tUNION 377 -#define tUNIQUE 378 -#define tUNSIGNED 379 -#define tUUID 380 -#define tV1ENUM 381 -#define tVARARG 382 -#define tVERSION 383 -#define tVOID 384 -#define tWCHAR 385 -#define tWIREMARSHAL 386 -#define CAST 387 -#define PPTR 388 -#define NEG 389 - - - - -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE -#line 136 "parser.y" -{ - attr_t *attr; - attr_list_t *attr_list; - str_list_t *str_list; - expr_t *expr; - expr_list_t *expr_list; - array_dims_t *array_dims; - type_t *type; - var_t *var; - var_list_t *var_list; - pident_t *pident; - pident_list_t *pident_list; - func_t *func; - func_list_t *func_list; - ifref_t *ifref; - ifref_list_t *ifref_list; - char *str; - UUID *uuid; - unsigned int num; - double dbl; -} -/* Line 1489 of yacc.c. */ -#line 339 "parser.tab.h" - YYSTYPE; -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 -#endif - -extern YYSTYPE parser_lval; - diff --git a/reactos/tools/widl_new/parser.y b/reactos/tools/widl_new/parser.y deleted file mode 100644 index 5b4c5ff860c..00000000000 --- a/reactos/tools/widl_new/parser.y +++ /dev/null @@ -1,1978 +0,0 @@ -%{ -/* - * IDL Compiler - * - * Copyright 2002 Ove Kaaven - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" - -#include -#include -#include -#include -#include -#include -#ifdef HAVE_ALLOCA_H -#include -#endif - -#include "windef.h" - -#include "widl.h" -#include "utils.h" -#include "parser.h" -#include "header.h" -#include "typelib.h" -#include "typegen.h" - -#if defined(YYBYACC) - /* Berkeley yacc (byacc) doesn't seem to know about these */ - /* Some *BSD supplied versions do define these though */ -# ifndef YYEMPTY -# define YYEMPTY (-1) /* Empty lookahead value of yychar */ -# endif -# ifndef YYLEX -# define YYLEX yylex() -# endif - -#elif defined(YYBISON) - /* Bison was used for original development */ - /* #define YYEMPTY -2 */ - /* #define YYLEX yylex() */ - -#else - /* No yacc we know yet */ -# if !defined(YYEMPTY) || !defined(YYLEX) -# error Yacc version/type unknown. This version needs to be verified for settings of YYEMPTY and YYLEX. -# elif defined(__GNUC__) /* gcc defines the #warning directive */ -# warning Yacc version/type unknown. It defines YYEMPTY and YYLEX, but is not tested - /* #else we just take a chance that it works... */ -# endif -#endif - -typedef struct list typelist_t; -struct typenode { - type_t *type; - struct list entry; -}; - -typelist_t incomplete_types = LIST_INIT(incomplete_types); - -static void add_incomplete(type_t *t); -static void fix_incomplete(void); - -static str_list_t *append_str(str_list_t *list, char *str); -static attr_list_t *append_attr(attr_list_t *list, attr_t *attr); -static attr_t *make_attr(enum attr_type type); -static attr_t *make_attrv(enum attr_type type, unsigned long val); -static attr_t *make_attrp(enum attr_type type, void *val); -static expr_t *make_expr(enum expr_type type); -static expr_t *make_exprl(enum expr_type type, long val); -static expr_t *make_exprd(enum expr_type type, double val); -static expr_t *make_exprs(enum expr_type type, char *val); -static expr_t *make_exprt(enum expr_type type, type_t *tref, expr_t *expr); -static expr_t *make_expr1(enum expr_type type, expr_t *expr); -static expr_t *make_expr2(enum expr_type type, expr_t *exp1, expr_t *exp2); -static expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, expr_t *expr3); -static type_t *make_type(unsigned char type, type_t *ref); -static expr_list_t *append_expr(expr_list_t *list, expr_t *expr); -static array_dims_t *append_array(array_dims_t *list, expr_t *expr); -static void set_type(var_t *v, type_t *type, int ptr_level, array_dims_t *arr); -static ifref_list_t *append_ifref(ifref_list_t *list, ifref_t *iface); -static ifref_t *make_ifref(type_t *iface); -static var_list_t *append_var(var_list_t *list, var_t *var); -static var_t *make_var(char *name); -static pident_list_t *append_pident(pident_list_t *list, pident_t *p); -static pident_t *make_pident(var_t *var); -static func_list_t *append_func(func_list_t *list, func_t *func); -static func_t *make_func(var_t *def, var_list_t *args); -static type_t *make_class(char *name); -static type_t *make_safearray(type_t *type); -static type_t *make_builtin(char *name); -static type_t *make_int(int sign); - -static type_t *reg_type(type_t *type, const char *name, int t); -static type_t *reg_typedefs(type_t *type, var_list_t *names, attr_list_t *attrs); -static type_t *find_type(const char *name, int t); -static type_t *find_type2(char *name, int t); -static type_t *get_type(unsigned char type, char *name, int t); -static type_t *get_typev(unsigned char type, var_t *name, int t); -static int get_struct_type(var_list_t *fields); - -static var_t *reg_const(var_t *var); -static var_t *find_const(char *name, int f); - -static void write_libid(const char *name, const attr_list_t *attr); -static void write_clsid(type_t *cls); -static void write_diid(type_t *iface); -static void write_iid(type_t *iface); - -static int compute_method_indexes(type_t *iface); -static char *gen_name(void); -static void process_typedefs(var_list_t *names); -static void check_arg(var_t *arg); -static void check_all_user_types(ifref_list_t *ifaces); - -#define tsENUM 1 -#define tsSTRUCT 2 -#define tsUNION 3 - -%} -%union { - attr_t *attr; - attr_list_t *attr_list; - str_list_t *str_list; - expr_t *expr; - expr_list_t *expr_list; - array_dims_t *array_dims; - type_t *type; - var_t *var; - var_list_t *var_list; - pident_t *pident; - pident_list_t *pident_list; - func_t *func; - func_list_t *func_list; - ifref_t *ifref; - ifref_list_t *ifref_list; - char *str; - UUID *uuid; - unsigned int num; - double dbl; -} - -%token aIDENTIFIER -%token aKNOWNTYPE -%token aNUM aHEXNUM -%token aDOUBLE -%token aSTRING -%token aUUID -%token aEOF -%token SHL SHR -%token tAGGREGATABLE tALLOCATE tAPPOBJECT tASYNC tASYNCUUID -%token tAUTOHANDLE tBINDABLE tBOOLEAN tBROADCAST tBYTE tBYTECOUNT -%token tCALLAS tCALLBACK tCASE tCDECL tCHAR tCOCLASS tCODE tCOMMSTATUS -%token tCONST tCONTEXTHANDLE tCONTEXTHANDLENOSERIALIZE -%token tCONTEXTHANDLESERIALIZE tCONTROL tCPPQUOTE -%token tDEFAULT -%token tDEFAULTCOLLELEM -%token tDEFAULTVALUE -%token tDEFAULTVTABLE -%token tDISPLAYBIND -%token tDISPINTERFACE -%token tDLLNAME tDOUBLE tDUAL -%token tENDPOINT -%token tENTRY tENUM tERRORSTATUST -%token tEXPLICITHANDLE tEXTERN -%token tFALSE -%token tFLOAT -%token tHANDLE -%token tHANDLET -%token tHELPCONTEXT tHELPFILE -%token tHELPSTRING tHELPSTRINGCONTEXT tHELPSTRINGDLL -%token tHIDDEN -%token tHYPER tID tIDEMPOTENT -%token tIIDIS -%token tIMMEDIATEBIND -%token tIMPLICITHANDLE -%token tIMPORT tIMPORTLIB -%token tIN tINLINE -%token tINPUTSYNC -%token tINT tINT64 -%token tINTERFACE -%token tLCID -%token tLENGTHIS tLIBRARY -%token tLOCAL -%token tLONG -%token tMETHODS -%token tMODULE -%token tNONBROWSABLE -%token tNONCREATABLE -%token tNONEXTENSIBLE -%token tOBJECT tODL tOLEAUTOMATION -%token tOPTIONAL -%token tOUT -%token tPOINTERDEFAULT -%token tPROPERTIES -%token tPROPGET tPROPPUT tPROPPUTREF -%token tPTR -%token tPUBLIC -%token tRANGE -%token tREADONLY tREF -%token tREQUESTEDIT -%token tRESTRICTED -%token tRETVAL -%token tSAFEARRAY -%token tSHORT -%token tSIGNED -%token tSINGLE -%token tSIZEIS tSIZEOF -%token tSMALL -%token tSOURCE -%token tSTDCALL -%token tSTRING tSTRUCT -%token tSWITCH tSWITCHIS tSWITCHTYPE -%token tTRANSMITAS -%token tTRUE -%token tTYPEDEF -%token tUNION -%token tUNIQUE -%token tUNSIGNED -%token tUUID -%token tV1ENUM -%token tVARARG -%token tVERSION -%token tVOID -%token tWCHAR tWIREMARSHAL - -%type attribute -%type m_attributes attributes attrib_list -%type str_list -%type m_expr expr expr_const -%type m_exprs /* exprs expr_list */ expr_list_const -%type array array_list -%type inherit interface interfacehdr interfacedef interfacedec -%type dispinterface dispinterfacehdr dispinterfacedef -%type module modulehdr moduledef -%type base_type int_std -%type enumdef structdef uniondef -%type type -%type coclass_int -%type gbl_statements coclass_ints -%type arg field s_field case enum constdef externdef -%type m_args no_args args fields cases enums enum_list dispint_props -%type m_ident t_ident ident -%type p_ident pident -%type pident_list -%type funcdef -%type int_statements dispint_meths -%type coclass coclasshdr coclassdef -%type pointer_type version -%type libraryhdr - -%left ',' -%right '?' ':' -%left '|' -%left '&' -%left '-' '+' -%left '*' '/' -%left SHL SHR -%right '~' -%right CAST -%right PPTR -%right NEG - -%% - -input: gbl_statements { fix_incomplete(); - check_all_user_types($1); - write_proxies($1); - write_client($1); - write_server($1); - } - ; - -gbl_statements: { $$ = NULL; } - | gbl_statements interfacedec { $$ = $1; } - | gbl_statements interfacedef { $$ = append_ifref( $1, make_ifref($2) ); } - | gbl_statements coclass ';' { $$ = $1; - reg_type($2, $2->name, 0); - if (!parse_only && do_header) write_coclass_forward($2); - } - | gbl_statements coclassdef { $$ = $1; - add_typelib_entry($2); - reg_type($2, $2->name, 0); - if (!parse_only && do_header) write_coclass_forward($2); - } - | gbl_statements moduledef { $$ = $1; add_typelib_entry($2); } - | gbl_statements librarydef { $$ = $1; } - | gbl_statements statement { $$ = $1; } - ; - -imp_statements: {} - | imp_statements interfacedec { if (!parse_only) add_typelib_entry($2); } - | imp_statements interfacedef { if (!parse_only) add_typelib_entry($2); } - | imp_statements coclass ';' { reg_type($2, $2->name, 0); if (!parse_only && do_header) write_coclass_forward($2); } - | imp_statements coclassdef { if (!parse_only) add_typelib_entry($2); - reg_type($2, $2->name, 0); - if (!parse_only && do_header) write_coclass_forward($2); - } - | imp_statements moduledef { if (!parse_only) add_typelib_entry($2); } - | imp_statements statement {} - | imp_statements importlib {} - ; - -int_statements: { $$ = NULL; } - | int_statements funcdef ';' { $$ = append_func( $1, $2 ); } - | int_statements statement { $$ = $1; } - ; - -statement: ';' {} - | constdef ';' { if (!parse_only && do_header) { write_constdef($1); } } - | cppquote {} - | enumdef ';' { if (!parse_only && do_header) { - write_type(header, $1, FALSE, NULL); - fprintf(header, ";\n\n"); - } - } - | externdef ';' { if (!parse_only && do_header) { write_externdef($1); } } - | import {} - | structdef ';' { if (!parse_only && do_header) { - write_type(header, $1, FALSE, NULL); - fprintf(header, ";\n\n"); - } - } - | typedef ';' {} - | uniondef ';' { if (!parse_only && do_header) { - write_type(header, $1, FALSE, NULL); - fprintf(header, ";\n\n"); - } - } - ; - -cppquote: tCPPQUOTE '(' aSTRING ')' { if (!parse_only && do_header) fprintf(header, "%s\n", $3); } - ; -import_start: tIMPORT aSTRING ';' { assert(yychar == YYEMPTY); - if (!do_import($2)) yychar = aEOF; } - ; -import: import_start imp_statements aEOF {} - ; - -importlib: tIMPORTLIB '(' aSTRING ')' { if(!parse_only) add_importlib($3); } - ; - -libraryhdr: tLIBRARY aIDENTIFIER { $$ = $2; } - ; -library_start: attributes libraryhdr '{' { start_typelib($2, $1); - if (!parse_only && do_header) write_library($2, $1); - if (!parse_only && do_idfile) write_libid($2, $1); - } - ; -librarydef: library_start imp_statements '}' { end_typelib(); } - ; - -m_args: { $$ = NULL; } - | args - ; - -no_args: tVOID { $$ = NULL; } - ; - -args: arg { check_arg($1); $$ = append_var( NULL, $1 ); } - | args ',' arg { check_arg($3); $$ = append_var( $1, $3); } - | no_args - ; - -/* split into two rules to get bison to resolve a tVOID conflict */ -arg: attributes type pident array { $$ = $3->var; - $$->attrs = $1; - set_type($$, $2, $3->ptr_level, $4); - free($3); - } - | type pident array { $$ = $2->var; - set_type($$, $1, $2->ptr_level, $3); - free($2); - } - | attributes type pident '(' m_args ')' { $$ = $3->var; - $$->attrs = $1; - set_type($$, $2, $3->ptr_level - 1, NULL); - free($3); - $$->args = $5; - } - | type pident '(' m_args ')' { $$ = $2->var; - set_type($$, $1, $2->ptr_level - 1, NULL); - free($2); - $$->args = $4; - } - ; - -array: { $$ = NULL; } - | '[' array_list ']' { $$ = $2; } - | '[' '*' ']' { $$ = append_array( NULL, make_expr(EXPR_VOID) ); } - ; - -array_list: m_expr /* size of first dimension is optional */ { $$ = append_array( NULL, $1 ); } - | array_list ',' expr { $$ = append_array( $1, $3 ); } - | array_list ']' '[' expr { $$ = append_array( $1, $4 ); } - ; - -m_attributes: { $$ = NULL; } - | attributes - ; - -attributes: - '[' attrib_list ']' { $$ = $2; - if (!$$) - yyerror("empty attribute lists unsupported"); - } - ; - -attrib_list: attribute { $$ = append_attr( NULL, $1 ); } - | attrib_list ',' attribute { $$ = append_attr( $1, $3 ); } - | attrib_list ']' '[' attribute { $$ = append_attr( $1, $4 ); } - ; - -str_list: aSTRING { $$ = append_str( NULL, $1 ); } - | str_list ',' aSTRING { $$ = append_str( $1, $3 ); } - ; - -attribute: { $$ = NULL; } - | tAGGREGATABLE { $$ = make_attr(ATTR_AGGREGATABLE); } - | tAPPOBJECT { $$ = make_attr(ATTR_APPOBJECT); } - | tASYNC { $$ = make_attr(ATTR_ASYNC); } - | tAUTOHANDLE { $$ = make_attr(ATTR_AUTO_HANDLE); } - | tBINDABLE { $$ = make_attr(ATTR_BINDABLE); } - | tCALLAS '(' ident ')' { $$ = make_attrp(ATTR_CALLAS, $3); } - | tCASE '(' expr_list_const ')' { $$ = make_attrp(ATTR_CASE, $3); } - | tCONTEXTHANDLE { $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); } - | tCONTEXTHANDLENOSERIALIZE { $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_DONT_SERIALIZE */ } - | tCONTEXTHANDLESERIALIZE { $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_SERIALIZE */ } - | tCONTROL { $$ = make_attr(ATTR_CONTROL); } - | tDEFAULT { $$ = make_attr(ATTR_DEFAULT); } - | tDEFAULTCOLLELEM { $$ = make_attr(ATTR_DEFAULTCOLLELEM); } - | tDEFAULTVALUE '(' expr_const ')' { $$ = make_attrp(ATTR_DEFAULTVALUE_EXPR, $3); } - | tDEFAULTVALUE '(' aSTRING ')' { $$ = make_attrp(ATTR_DEFAULTVALUE_STRING, $3); } - | tDEFAULTVTABLE { $$ = make_attr(ATTR_DEFAULTVTABLE); } - | tDISPLAYBIND { $$ = make_attr(ATTR_DISPLAYBIND); } - | tDLLNAME '(' aSTRING ')' { $$ = make_attrp(ATTR_DLLNAME, $3); } - | tDUAL { $$ = make_attr(ATTR_DUAL); } - | tENDPOINT '(' str_list ')' { $$ = make_attrp(ATTR_ENDPOINT, $3); } - | tENTRY '(' aSTRING ')' { $$ = make_attrp(ATTR_ENTRY_STRING, $3); } - | tENTRY '(' expr_const ')' { $$ = make_attrp(ATTR_ENTRY_ORDINAL, $3); } - | tEXPLICITHANDLE { $$ = make_attr(ATTR_EXPLICIT_HANDLE); } - | tHANDLE { $$ = make_attr(ATTR_HANDLE); } - | tHELPCONTEXT '(' expr_const ')' { $$ = make_attrp(ATTR_HELPCONTEXT, $3); } - | tHELPFILE '(' aSTRING ')' { $$ = make_attrp(ATTR_HELPFILE, $3); } - | tHELPSTRING '(' aSTRING ')' { $$ = make_attrp(ATTR_HELPSTRING, $3); } - | tHELPSTRINGCONTEXT '(' expr_const ')' { $$ = make_attrp(ATTR_HELPSTRINGCONTEXT, $3); } - | tHELPSTRINGDLL '(' aSTRING ')' { $$ = make_attrp(ATTR_HELPSTRINGDLL, $3); } - | tHIDDEN { $$ = make_attr(ATTR_HIDDEN); } - | tID '(' expr_const ')' { $$ = make_attrp(ATTR_ID, $3); } - | tIDEMPOTENT { $$ = make_attr(ATTR_IDEMPOTENT); } - | tIIDIS '(' ident ')' { $$ = make_attrp(ATTR_IIDIS, $3); } - | tIMMEDIATEBIND { $$ = make_attr(ATTR_IMMEDIATEBIND); } - | tIMPLICITHANDLE '(' tHANDLET aIDENTIFIER ')' { $$ = make_attrp(ATTR_IMPLICIT_HANDLE, $4); } - | tIN { $$ = make_attr(ATTR_IN); } - | tINPUTSYNC { $$ = make_attr(ATTR_INPUTSYNC); } - | tLENGTHIS '(' m_exprs ')' { $$ = make_attrp(ATTR_LENGTHIS, $3); } - | tLOCAL { $$ = make_attr(ATTR_LOCAL); } - | tNONBROWSABLE { $$ = make_attr(ATTR_NONBROWSABLE); } - | tNONCREATABLE { $$ = make_attr(ATTR_NONCREATABLE); } - | tNONEXTENSIBLE { $$ = make_attr(ATTR_NONEXTENSIBLE); } - | tOBJECT { $$ = make_attr(ATTR_OBJECT); } - | tODL { $$ = make_attr(ATTR_ODL); } - | tOLEAUTOMATION { $$ = make_attr(ATTR_OLEAUTOMATION); } - | tOPTIONAL { $$ = make_attr(ATTR_OPTIONAL); } - | tOUT { $$ = make_attr(ATTR_OUT); } - | tPOINTERDEFAULT '(' pointer_type ')' { $$ = make_attrv(ATTR_POINTERDEFAULT, $3); } - | tPROPGET { $$ = make_attr(ATTR_PROPGET); } - | tPROPPUT { $$ = make_attr(ATTR_PROPPUT); } - | tPROPPUTREF { $$ = make_attr(ATTR_PROPPUTREF); } - | tPUBLIC { $$ = make_attr(ATTR_PUBLIC); } - | tRANGE '(' expr_const ',' expr_const ')' { expr_list_t *list = append_expr( NULL, $3 ); - list = append_expr( list, $5 ); - $$ = make_attrp(ATTR_RANGE, list); } - | tREADONLY { $$ = make_attr(ATTR_READONLY); } - | tREQUESTEDIT { $$ = make_attr(ATTR_REQUESTEDIT); } - | tRESTRICTED { $$ = make_attr(ATTR_RESTRICTED); } - | tRETVAL { $$ = make_attr(ATTR_RETVAL); } - | tSIZEIS '(' m_exprs ')' { $$ = make_attrp(ATTR_SIZEIS, $3); } - | tSOURCE { $$ = make_attr(ATTR_SOURCE); } - | tSTRING { $$ = make_attr(ATTR_STRING); } - | tSWITCHIS '(' expr ')' { $$ = make_attrp(ATTR_SWITCHIS, $3); } - | tSWITCHTYPE '(' type ')' { $$ = make_attrp(ATTR_SWITCHTYPE, $3); } - | tTRANSMITAS '(' type ')' { $$ = make_attrp(ATTR_TRANSMITAS, $3); } - | tUUID '(' aUUID ')' { $$ = make_attrp(ATTR_UUID, $3); } - | tV1ENUM { $$ = make_attr(ATTR_V1ENUM); } - | tVARARG { $$ = make_attr(ATTR_VARARG); } - | tVERSION '(' version ')' { $$ = make_attrv(ATTR_VERSION, $3); } - | tWIREMARSHAL '(' type ')' { $$ = make_attrp(ATTR_WIREMARSHAL, $3); } - | pointer_type { $$ = make_attrv(ATTR_POINTERTYPE, $1); } - ; - -callconv: - | tSTDCALL - ; - -cases: { $$ = NULL; } - | cases case { $$ = append_var( $1, $2 ); } - ; - -case: tCASE expr ':' field { attr_t *a = make_attrp(ATTR_CASE, append_expr( NULL, $2 )); - $$ = $4; if (!$$) $$ = make_var(NULL); - $$->attrs = append_attr( $$->attrs, a ); - } - | tDEFAULT ':' field { attr_t *a = make_attr(ATTR_DEFAULT); - $$ = $3; if (!$$) $$ = make_var(NULL); - $$->attrs = append_attr( $$->attrs, a ); - } - ; - -constdef: tCONST type ident '=' expr_const { $$ = reg_const($3); - set_type($$, $2, 0, NULL); - $$->eval = $5; - } - ; - -enums: { $$ = NULL; } - | enum_list ',' { $$ = $1; } - | enum_list - ; - -enum_list: enum { if (!$1->eval) - $1->eval = make_exprl(EXPR_NUM, 0 /* default for first enum entry */); - $$ = append_var( NULL, $1 ); - } - | enum_list ',' enum { if (!$3->eval) - { - var_t *last = LIST_ENTRY( list_tail($$), var_t, entry ); - $3->eval = make_exprl(EXPR_NUM, last->eval->cval + 1); - } - $$ = append_var( $1, $3 ); - } - ; - -enum: ident '=' expr_const { $$ = reg_const($1); - $$->eval = $3; - $$->type = make_int(0); - } - | ident { $$ = reg_const($1); - $$->type = make_int(0); - } - ; - -enumdef: tENUM t_ident '{' enums '}' { $$ = get_typev(RPC_FC_ENUM16, $2, tsENUM); - $$->kind = TKIND_ENUM; - $$->fields = $4; - $$->defined = TRUE; - if(in_typelib) - add_typelib_entry($$); - } - ; - -m_exprs: m_expr { $$ = append_expr( NULL, $1 ); } - | m_exprs ',' m_expr { $$ = append_expr( $1, $3 ); } - ; - -/* -exprs: { $$ = make_expr(EXPR_VOID); } - | expr_list - ; - -expr_list: expr - | expr_list ',' expr { LINK($3, $1); $$ = $3; } - ; -*/ - -m_expr: { $$ = make_expr(EXPR_VOID); } - | expr - ; - -expr: aNUM { $$ = make_exprl(EXPR_NUM, $1); } - | aHEXNUM { $$ = make_exprl(EXPR_HEXNUM, $1); } - | aDOUBLE { $$ = make_exprd(EXPR_DOUBLE, $1); } - | tFALSE { $$ = make_exprl(EXPR_TRUEFALSE, 0); } - | tTRUE { $$ = make_exprl(EXPR_TRUEFALSE, 1); } - | aIDENTIFIER { $$ = make_exprs(EXPR_IDENTIFIER, $1); } - | expr '?' expr ':' expr { $$ = make_expr3(EXPR_COND, $1, $3, $5); } - | expr '|' expr { $$ = make_expr2(EXPR_OR , $1, $3); } - | expr '&' expr { $$ = make_expr2(EXPR_AND, $1, $3); } - | expr '+' expr { $$ = make_expr2(EXPR_ADD, $1, $3); } - | expr '-' expr { $$ = make_expr2(EXPR_SUB, $1, $3); } - | expr '*' expr { $$ = make_expr2(EXPR_MUL, $1, $3); } - | expr '/' expr { $$ = make_expr2(EXPR_DIV, $1, $3); } - | expr SHL expr { $$ = make_expr2(EXPR_SHL, $1, $3); } - | expr SHR expr { $$ = make_expr2(EXPR_SHR, $1, $3); } - | '~' expr { $$ = make_expr1(EXPR_NOT, $2); } - | '-' expr %prec NEG { $$ = make_expr1(EXPR_NEG, $2); } - | '*' expr %prec PPTR { $$ = make_expr1(EXPR_PPTR, $2); } - | '(' type ')' expr %prec CAST { $$ = make_exprt(EXPR_CAST, $2, $4); } - | tSIZEOF '(' type ')' { $$ = make_exprt(EXPR_SIZEOF, $3, NULL); } - | '(' expr ')' { $$ = $2; } - ; - -expr_list_const: expr_const { $$ = append_expr( NULL, $1 ); } - | expr_list_const ',' expr_const { $$ = append_expr( $1, $3 ); } - ; - -expr_const: expr { $$ = $1; - if (!$$->is_const) - yyerror("expression is not constant"); - } - ; - -externdef: tEXTERN tCONST type ident { $$ = $4; - set_type($$, $3, 0, NULL); - } - ; - -fields: { $$ = NULL; } - | fields field { $$ = append_var( $1, $2 ); } - ; - -field: s_field ';' { $$ = $1; } - | m_attributes uniondef ';' { $$ = make_var(NULL); $$->type = $2; $$->attrs = $1; } - | attributes ';' { $$ = make_var(NULL); $$->attrs = $1; } - | ';' { $$ = NULL; } - ; - -s_field: m_attributes type pident array { $$ = $3->var; - $$->attrs = $1; - set_type($$, $2, $3->ptr_level, $4); - free($3); - } - ; - -funcdef: - m_attributes type callconv pident - '(' m_args ')' { var_t *v = $4->var; - v->attrs = $1; - set_type(v, $2, $4->ptr_level, NULL); - free($4); - $$ = make_func(v, $6); - if (is_attr(v->attrs, ATTR_IN)) { - yyerror("inapplicable attribute [in] for function '%s'",$$->def->name); - } - } - ; - -m_ident: { $$ = NULL; } - | ident - ; - -t_ident: { $$ = NULL; } - | aIDENTIFIER { $$ = make_var($1); } - | aKNOWNTYPE { $$ = make_var($1); } - ; - -ident: aIDENTIFIER { $$ = make_var($1); } -/* some "reserved words" used in attributes are also used as field names in some MS IDL files */ - | aKNOWNTYPE { $$ = make_var($1); } - ; - -base_type: tBYTE { $$ = make_builtin($1); } - | tWCHAR { $$ = make_builtin($1); } - | int_std - | tSIGNED int_std { $$ = $2; $$->sign = 1; } - | tUNSIGNED int_std { $$ = $2; $$->sign = -1; - switch ($$->type) { - case RPC_FC_CHAR: break; - case RPC_FC_SMALL: $$->type = RPC_FC_USMALL; break; - case RPC_FC_SHORT: $$->type = RPC_FC_USHORT; break; - case RPC_FC_LONG: $$->type = RPC_FC_ULONG; break; - case RPC_FC_HYPER: - if ($$->name[0] == 'h') /* hyper, as opposed to __int64 */ - { - $$ = alias($$, "MIDL_uhyper"); - $$->sign = 0; - } - break; - default: break; - } - } - | tUNSIGNED { $$ = make_int(-1); } - | tFLOAT { $$ = make_builtin($1); } - | tSINGLE { $$ = duptype(find_type("float", 0), 1); } - | tDOUBLE { $$ = make_builtin($1); } - | tBOOLEAN { $$ = make_builtin($1); } - | tERRORSTATUST { $$ = make_builtin($1); } - | tHANDLET { $$ = make_builtin($1); } - ; - -m_int: - | tINT - ; - -int_std: tINT { $$ = make_builtin($1); } - | tSHORT m_int { $$ = make_builtin($1); } - | tSMALL { $$ = make_builtin($1); } - | tLONG m_int { $$ = make_builtin($1); } - | tHYPER m_int { $$ = make_builtin($1); } - | tINT64 { $$ = make_builtin($1); } - | tCHAR { $$ = make_builtin($1); } - ; - -coclass: tCOCLASS aIDENTIFIER { $$ = make_class($2); } - | tCOCLASS aKNOWNTYPE { $$ = find_type($2, 0); - if ($$->defined) yyerror("multiple definition error"); - if ($$->kind != TKIND_COCLASS) yyerror("%s was not declared a coclass", $2); - } - ; - -coclasshdr: attributes coclass { $$ = $2; - $$->attrs = $1; - if (!parse_only && do_header) - write_coclass($$); - if (!parse_only && do_idfile) - write_clsid($$); - } - ; - -coclassdef: coclasshdr '{' coclass_ints '}' { $$ = $1; - $$->ifaces = $3; - $$->defined = TRUE; - } - ; - -coclass_ints: { $$ = NULL; } - | coclass_ints coclass_int { $$ = append_ifref( $1, $2 ); } - ; - -coclass_int: - m_attributes interfacedec { $$ = make_ifref($2); $$->attrs = $1; } - ; - -dispinterface: tDISPINTERFACE aIDENTIFIER { $$ = get_type(0, $2, 0); $$->kind = TKIND_DISPATCH; } - | tDISPINTERFACE aKNOWNTYPE { $$ = get_type(0, $2, 0); $$->kind = TKIND_DISPATCH; } - ; - -dispinterfacehdr: attributes dispinterface { attr_t *attrs; - $$ = $2; - if ($$->defined) yyerror("multiple definition error"); - attrs = make_attr(ATTR_DISPINTERFACE); - $$->attrs = append_attr( $1, attrs ); - $$->ref = find_type("IDispatch", 0); - if (!$$->ref) yyerror("IDispatch is undefined"); - $$->defined = TRUE; - if (!parse_only && do_header) write_forward($$); - } - ; - -dispint_props: tPROPERTIES ':' { $$ = NULL; } - | dispint_props s_field ';' { $$ = append_var( $1, $2 ); } - ; - -dispint_meths: tMETHODS ':' { $$ = NULL; } - | dispint_meths funcdef ';' { $$ = append_func( $1, $2 ); } - ; - -dispinterfacedef: dispinterfacehdr '{' - dispint_props - dispint_meths - '}' { $$ = $1; - $$->fields = $3; - $$->funcs = $4; - if (!parse_only && do_header) write_dispinterface($$); - if (!parse_only && do_idfile) write_diid($$); - } - | dispinterfacehdr - '{' interface ';' '}' { $$ = $1; - $$->fields = $3->fields; - $$->funcs = $3->funcs; - if (!parse_only && do_header) write_dispinterface($$); - if (!parse_only && do_idfile) write_diid($$); - } - ; - -inherit: { $$ = NULL; } - | ':' aKNOWNTYPE { $$ = find_type2($2, 0); } - ; - -interface: tINTERFACE aIDENTIFIER { $$ = get_type(RPC_FC_IP, $2, 0); $$->kind = TKIND_INTERFACE; } - | tINTERFACE aKNOWNTYPE { $$ = get_type(RPC_FC_IP, $2, 0); $$->kind = TKIND_INTERFACE; } - ; - -interfacehdr: attributes interface { $$ = $2; - if ($$->defined) yyerror("multiple definition error"); - $$->attrs = $1; - $$->defined = TRUE; - if (!parse_only && do_header) write_forward($$); - } - ; - -interfacedef: interfacehdr inherit - '{' int_statements '}' { $$ = $1; - $$->ref = $2; - $$->funcs = $4; - compute_method_indexes($$); - if (!parse_only && do_header) write_interface($$); - if (!parse_only && do_idfile) write_iid($$); - } -/* MIDL is able to import the definition of a base class from inside the - * definition of a derived class, I'll try to support it with this rule */ - | interfacehdr ':' aIDENTIFIER - '{' import int_statements '}' { $$ = $1; - $$->ref = find_type2($3, 0); - if (!$$->ref) yyerror("base class '%s' not found in import", $3); - $$->funcs = $6; - compute_method_indexes($$); - if (!parse_only && do_header) write_interface($$); - if (!parse_only && do_idfile) write_iid($$); - } - | dispinterfacedef { $$ = $1; } - ; - -interfacedec: - interface ';' { $$ = $1; if (!parse_only && do_header) write_forward($$); } - | dispinterface ';' { $$ = $1; if (!parse_only && do_header) write_forward($$); } - ; - -module: tMODULE aIDENTIFIER { $$ = make_type(0, NULL); $$->name = $2; $$->kind = TKIND_MODULE; } - | tMODULE aKNOWNTYPE { $$ = make_type(0, NULL); $$->name = $2; $$->kind = TKIND_MODULE; } - ; - -modulehdr: attributes module { $$ = $2; - $$->attrs = $1; - } - ; - -moduledef: modulehdr '{' int_statements '}' { $$ = $1; - $$->funcs = $3; - /* FIXME: if (!parse_only && do_header) write_module($$); */ - } - ; - -p_ident: '*' pident %prec PPTR { $$ = $2; $$->ptr_level++; } - | tCONST p_ident { $$ = $2; /* FIXME */ } - ; - -pident: ident { $$ = make_pident($1); } - | p_ident - | '(' pident ')' { $$ = $2; } - ; - -pident_list: - pident { $$ = append_pident( NULL, $1 ); } - | pident_list ',' pident { $$ = append_pident( $1, $3 ); } - ; - -pointer_type: - tREF { $$ = RPC_FC_RP; } - | tUNIQUE { $$ = RPC_FC_UP; } - | tPTR { $$ = RPC_FC_FP; } - ; - -structdef: tSTRUCT t_ident '{' fields '}' { $$ = get_typev(RPC_FC_STRUCT, $2, tsSTRUCT); - /* overwrite RPC_FC_STRUCT with a more exact type */ - $$->type = get_struct_type( $4 ); - $$->kind = TKIND_RECORD; - $$->fields = $4; - $$->defined = TRUE; - if(in_typelib) - add_typelib_entry($$); - } - ; - -type: tVOID { $$ = duptype(find_type("void", 0), 1); } - | aKNOWNTYPE { $$ = find_type($1, 0); } - | base_type { $$ = $1; } - | tCONST type { $$ = duptype($2, 1); $$->is_const = TRUE; } - | enumdef { $$ = $1; } - | tENUM aIDENTIFIER { $$ = find_type2($2, tsENUM); } - | structdef { $$ = $1; } - | tSTRUCT aIDENTIFIER { $$ = get_type(RPC_FC_STRUCT, $2, tsSTRUCT); } - | uniondef { $$ = $1; } - | tUNION aIDENTIFIER { $$ = find_type2($2, tsUNION); } - | tSAFEARRAY '(' type ')' { $$ = make_safearray($3); } - ; - -typedef: tTYPEDEF m_attributes type pident_list { reg_typedefs($3, $4, $2); - process_typedefs($4); - } - ; - -uniondef: tUNION t_ident '{' fields '}' { $$ = get_typev(RPC_FC_NON_ENCAPSULATED_UNION, $2, tsUNION); - $$->kind = TKIND_UNION; - $$->fields = $4; - $$->defined = TRUE; - } - | tUNION t_ident - tSWITCH '(' s_field ')' - m_ident '{' cases '}' { var_t *u = $7; - $$ = get_typev(RPC_FC_ENCAPSULATED_UNION, $2, tsUNION); - $$->kind = TKIND_UNION; - if (!u) u = make_var( xstrdup("tagged_union") ); - u->type = make_type(RPC_FC_NON_ENCAPSULATED_UNION, NULL); - u->type->kind = TKIND_UNION; - u->type->fields = $9; - u->type->defined = TRUE; - $$->fields = append_var( $$->fields, $5 ); - $$->fields = append_var( $$->fields, u ); - $$->defined = TRUE; - } - ; - -version: - aNUM { $$ = MAKELONG($1, 0); } - | aNUM '.' aNUM { $$ = MAKELONG($1, $3); } - ; - -%% - -static void decl_builtin(const char *name, unsigned char type) -{ - type_t *t = make_type(type, NULL); - t->name = xstrdup(name); - reg_type(t, name, 0); -} - -static type_t *make_builtin(char *name) -{ - /* NAME is strdup'd in the lexer */ - type_t *t = duptype(find_type(name, 0), 0); - t->name = name; - return t; -} - -static type_t *make_int(int sign) -{ - type_t *t = duptype(find_type("int", 0), 1); - - t->sign = sign; - if (sign < 0) - t->type = t->type == RPC_FC_LONG ? RPC_FC_ULONG : RPC_FC_USHORT; - - return t; -} - -void init_types(void) -{ - decl_builtin("void", 0); - decl_builtin("byte", RPC_FC_BYTE); - decl_builtin("wchar_t", RPC_FC_WCHAR); - decl_builtin("int", RPC_FC_LONG); /* win32 */ - decl_builtin("short", RPC_FC_SHORT); - decl_builtin("small", RPC_FC_SMALL); - decl_builtin("long", RPC_FC_LONG); - decl_builtin("hyper", RPC_FC_HYPER); - decl_builtin("__int64", RPC_FC_HYPER); - decl_builtin("char", RPC_FC_CHAR); - decl_builtin("float", RPC_FC_FLOAT); - decl_builtin("double", RPC_FC_DOUBLE); - decl_builtin("boolean", RPC_FC_BYTE); - decl_builtin("error_status_t", RPC_FC_ERROR_STATUS_T); - decl_builtin("handle_t", RPC_FC_BIND_PRIMITIVE); -} - -static str_list_t *append_str(str_list_t *list, char *str) -{ - struct str_list_entry_t *entry; - - if (!str) return list; - if (!list) - { - list = xmalloc( sizeof(*list) ); - list_init( list ); - } - entry = xmalloc( sizeof(*entry) ); - entry->str = str; - list_add_tail( list, &entry->entry ); - return list; -} - -static attr_list_t *append_attr(attr_list_t *list, attr_t *attr) -{ - if (!attr) return list; - if (!list) - { - list = xmalloc( sizeof(*list) ); - list_init( list ); - } - list_add_tail( list, &attr->entry ); - return list; -} - -static attr_t *make_attr(enum attr_type type) -{ - attr_t *a = xmalloc(sizeof(attr_t)); - a->type = type; - a->u.ival = 0; - return a; -} - -static attr_t *make_attrv(enum attr_type type, unsigned long val) -{ - attr_t *a = xmalloc(sizeof(attr_t)); - a->type = type; - a->u.ival = val; - return a; -} - -static attr_t *make_attrp(enum attr_type type, void *val) -{ - attr_t *a = xmalloc(sizeof(attr_t)); - a->type = type; - a->u.pval = val; - return a; -} - -static expr_t *make_expr(enum expr_type type) -{ - expr_t *e = xmalloc(sizeof(expr_t)); - e->type = type; - e->ref = NULL; - e->u.lval = 0; - e->is_const = FALSE; - return e; -} - -static expr_t *make_exprl(enum expr_type type, long val) -{ - expr_t *e = xmalloc(sizeof(expr_t)); - e->type = type; - e->ref = NULL; - e->u.lval = val; - e->is_const = FALSE; - /* check for numeric constant */ - if (type == EXPR_NUM || type == EXPR_HEXNUM || type == EXPR_TRUEFALSE) { - /* make sure true/false value is valid */ - assert(type != EXPR_TRUEFALSE || val == 0 || val == 1); - e->is_const = TRUE; - e->cval = val; - } - return e; -} - -static expr_t *make_exprd(enum expr_type type, double val) -{ - expr_t *e = xmalloc(sizeof(expr_t)); - e->type = type; - e->ref = NULL; - e->u.dval = val; - e->is_const = TRUE; - e->cval = val; - return e; -} - -static expr_t *make_exprs(enum expr_type type, char *val) -{ - expr_t *e; - e = xmalloc(sizeof(expr_t)); - e->type = type; - e->ref = NULL; - e->u.sval = val; - e->is_const = FALSE; - /* check for predefined constants */ - if (type == EXPR_IDENTIFIER) { - var_t *c = find_const(val, 0); - if (c) { - e->u.sval = c->name; - free(val); - e->is_const = TRUE; - e->cval = c->eval->cval; - } - } - return e; -} - -static expr_t *make_exprt(enum expr_type type, type_t *tref, expr_t *expr) -{ - expr_t *e; - e = xmalloc(sizeof(expr_t)); - e->type = type; - e->ref = expr; - e->u.tref = tref; - e->is_const = FALSE; - /* check for cast of constant expression */ - if (type == EXPR_SIZEOF) { - switch (tref->type) { - case RPC_FC_BYTE: - case RPC_FC_CHAR: - case RPC_FC_SMALL: - case RPC_FC_USMALL: - e->is_const = TRUE; - e->cval = 1; - break; - case RPC_FC_WCHAR: - case RPC_FC_USHORT: - case RPC_FC_SHORT: - e->is_const = TRUE; - e->cval = 2; - break; - case RPC_FC_LONG: - case RPC_FC_ULONG: - case RPC_FC_FLOAT: - case RPC_FC_ERROR_STATUS_T: - e->is_const = TRUE; - e->cval = 4; - break; - case RPC_FC_HYPER: - case RPC_FC_DOUBLE: - e->is_const = TRUE; - e->cval = 8; - break; - } - } - if (type == EXPR_CAST && expr->is_const) { - e->is_const = TRUE; - e->cval = expr->cval; - } - return e; -} - -static expr_t *make_expr1(enum expr_type type, expr_t *expr) -{ - expr_t *e; - e = xmalloc(sizeof(expr_t)); - e->type = type; - e->ref = expr; - e->u.lval = 0; - e->is_const = FALSE; - /* check for compile-time optimization */ - if (expr->is_const) { - e->is_const = TRUE; - switch (type) { - case EXPR_NEG: - e->cval = -expr->cval; - break; - case EXPR_NOT: - e->cval = ~expr->cval; - break; - default: - e->is_const = FALSE; - break; - } - } - return e; -} - -static expr_t *make_expr2(enum expr_type type, expr_t *expr1, expr_t *expr2) -{ - expr_t *e; - e = xmalloc(sizeof(expr_t)); - e->type = type; - e->ref = expr1; - e->u.ext = expr2; - e->is_const = FALSE; - /* check for compile-time optimization */ - if (expr1->is_const && expr2->is_const) { - e->is_const = TRUE; - switch (type) { - case EXPR_ADD: - e->cval = expr1->cval + expr2->cval; - break; - case EXPR_SUB: - e->cval = expr1->cval - expr2->cval; - break; - case EXPR_MUL: - e->cval = expr1->cval * expr2->cval; - break; - case EXPR_DIV: - e->cval = expr1->cval / expr2->cval; - break; - case EXPR_OR: - e->cval = expr1->cval | expr2->cval; - break; - case EXPR_AND: - e->cval = expr1->cval & expr2->cval; - break; - case EXPR_SHL: - e->cval = expr1->cval << expr2->cval; - break; - case EXPR_SHR: - e->cval = expr1->cval >> expr2->cval; - break; - default: - e->is_const = FALSE; - break; - } - } - return e; -} - -static expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, expr_t *expr3) -{ - expr_t *e; - e = xmalloc(sizeof(expr_t)); - e->type = type; - e->ref = expr1; - e->u.ext = expr2; - e->ext2 = expr3; - e->is_const = FALSE; - /* check for compile-time optimization */ - if (expr1->is_const && expr2->is_const && expr3->is_const) { - e->is_const = TRUE; - switch (type) { - case EXPR_COND: - e->cval = expr1->cval ? expr2->cval : expr3->cval; - break; - default: - e->is_const = FALSE; - break; - } - } - return e; -} - -static expr_list_t *append_expr(expr_list_t *list, expr_t *expr) -{ - if (!expr) return list; - if (!list) - { - list = xmalloc( sizeof(*list) ); - list_init( list ); - } - list_add_tail( list, &expr->entry ); - return list; -} - -static array_dims_t *append_array(array_dims_t *list, expr_t *expr) -{ - if (!expr) return list; - if (!list) - { - list = xmalloc( sizeof(*list) ); - list_init( list ); - } - list_add_tail( list, &expr->entry ); - return list; -} - -static type_t *make_type(unsigned char type, type_t *ref) -{ - type_t *t = xmalloc(sizeof(type_t)); - t->name = NULL; - t->kind = TKIND_PRIMITIVE; - t->type = type; - t->ref = ref; - t->attrs = NULL; - t->orig = NULL; - t->funcs = NULL; - t->fields = NULL; - t->ifaces = NULL; - t->dim = 0; - t->size_is = NULL; - t->length_is = NULL; - t->typestring_offset = 0; - t->declarray = FALSE; - t->ignore = (parse_only != 0); - t->is_const = FALSE; - t->sign = 0; - t->defined = FALSE; - t->written = FALSE; - t->user_types_registered = FALSE; - t->tfswrite = FALSE; - t->typelib_idx = -1; - return t; -} - -static void set_type(var_t *v, type_t *type, int ptr_level, array_dims_t *arr) -{ - expr_list_t *sizes = get_attrp(v->attrs, ATTR_SIZEIS); - expr_list_t *lengs = get_attrp(v->attrs, ATTR_LENGTHIS); - int sizeless, has_varconf; - expr_t *dim; - type_t *atype, **ptype; - - v->type = type; - - for ( ; 0 < ptr_level; --ptr_level) - v->type = make_type(RPC_FC_RP, v->type); - - sizeless = FALSE; - if (arr) LIST_FOR_EACH_ENTRY_REV(dim, arr, expr_t, entry) - { - if (sizeless) - error("%s: only the first array dimension can be unspecified\n", v->name); - - if (dim->is_const) - { - unsigned int align = 0; - size_t size = type_memsize(v->type, &align); - - if (dim->cval <= 0) - error("%s: array dimension must be positive\n", v->name); - - if (0xffffffffuL / size < (unsigned long) dim->cval) - error("%s: total array size is too large", v->name); - else if (0xffffuL < size * dim->cval) - v->type = make_type(RPC_FC_LGFARRAY, v->type); - else - v->type = make_type(RPC_FC_SMFARRAY, v->type); - } - else - { - sizeless = TRUE; - v->type = make_type(RPC_FC_CARRAY, v->type); - } - - v->type->declarray = TRUE; - v->type->dim = dim->cval; - } - - ptype = &v->type; - has_varconf = FALSE; - if (sizes) LIST_FOR_EACH_ENTRY(dim, sizes, expr_t, entry) - { - if (dim->type != EXPR_VOID) - { - has_varconf = TRUE; - atype = *ptype = duptype(*ptype, 0); - - if (atype->type == RPC_FC_SMFARRAY || atype->type == RPC_FC_LGFARRAY) - error("%s: cannot specify size_is for a fixed sized array\n", v->name); - - if (atype->type != RPC_FC_CARRAY && !is_ptr(atype)) - error("%s: size_is attribute applied to illegal type\n", v->name); - - atype->type = RPC_FC_CARRAY; - atype->size_is = dim; - } - - ptype = &(*ptype)->ref; - if (*ptype == NULL) - error("%s: too many expressions in size_is attribute\n", v->name); - } - - ptype = &v->type; - if (lengs) LIST_FOR_EACH_ENTRY(dim, lengs, expr_t, entry) - { - if (dim->type != EXPR_VOID) - { - has_varconf = TRUE; - atype = *ptype = duptype(*ptype, 0); - - if (atype->type == RPC_FC_SMFARRAY) - atype->type = RPC_FC_SMVARRAY; - else if (atype->type == RPC_FC_LGFARRAY) - atype->type = RPC_FC_LGVARRAY; - else if (atype->type == RPC_FC_CARRAY) - atype->type = RPC_FC_CVARRAY; - else - error("%s: length_is attribute applied to illegal type\n", v->name); - - atype->length_is = dim; - } - - ptype = &(*ptype)->ref; - if (*ptype == NULL) - error("%s: too many expressions in length_is attribute\n", v->name); - } - - if (has_varconf && !last_array(v->type)) - { - ptype = &v->type; - for (ptype = &v->type; is_array(*ptype); ptype = &(*ptype)->ref) - { - *ptype = duptype(*ptype, 0); - (*ptype)->type = RPC_FC_BOGUS_ARRAY; - } - } -} - -static ifref_list_t *append_ifref(ifref_list_t *list, ifref_t *iface) -{ - if (!iface) return list; - if (!list) - { - list = xmalloc( sizeof(*list) ); - list_init( list ); - } - list_add_tail( list, &iface->entry ); - return list; -} - -static ifref_t *make_ifref(type_t *iface) -{ - ifref_t *l = xmalloc(sizeof(ifref_t)); - l->iface = iface; - l->attrs = NULL; - return l; -} - -static var_list_t *append_var(var_list_t *list, var_t *var) -{ - if (!var) return list; - if (!list) - { - list = xmalloc( sizeof(*list) ); - list_init( list ); - } - list_add_tail( list, &var->entry ); - return list; -} - -static var_t *make_var(char *name) -{ - var_t *v = xmalloc(sizeof(var_t)); - v->name = name; - v->type = NULL; - v->args = NULL; - v->attrs = NULL; - v->eval = NULL; - return v; -} - -static pident_list_t *append_pident(pident_list_t *list, pident_t *p) -{ - if (!p) return list; - if (!list) { - list = xmalloc(sizeof(*list)); - list_init(list); - } - list_add_tail(list, &p->entry); - return list; -} - -static pident_t *make_pident(var_t *var) -{ - pident_t *p = xmalloc(sizeof(*p)); - p->var = var; - p->ptr_level = 0; - return p; -} - -static func_list_t *append_func(func_list_t *list, func_t *func) -{ - if (!func) return list; - if (!list) - { - list = xmalloc( sizeof(*list) ); - list_init( list ); - } - list_add_tail( list, &func->entry ); - return list; -} - -static func_t *make_func(var_t *def, var_list_t *args) -{ - func_t *f = xmalloc(sizeof(func_t)); - f->def = def; - f->args = args; - f->ignore = parse_only; - f->idx = -1; - return f; -} - -static type_t *make_class(char *name) -{ - type_t *c = make_type(0, NULL); - c->name = name; - c->kind = TKIND_COCLASS; - return c; -} - -static type_t *make_safearray(type_t *type) -{ - type_t *sa = duptype(find_type("SAFEARRAY", 0), 1); - sa->ref = type; - return make_type(RPC_FC_FP, sa); -} - -#define HASHMAX 64 - -static int hash_ident(const char *name) -{ - const char *p = name; - int sum = 0; - /* a simple sum hash is probably good enough */ - while (*p) { - sum += *p; - p++; - } - return sum & (HASHMAX-1); -} - -/***** type repository *****/ - -struct rtype { - const char *name; - type_t *type; - int t; - struct rtype *next; -}; - -struct rtype *type_hash[HASHMAX]; - -static type_t *reg_type(type_t *type, const char *name, int t) -{ - struct rtype *nt; - int hash; - if (!name) { - yyerror("registering named type without name"); - return type; - } - hash = hash_ident(name); - nt = xmalloc(sizeof(struct rtype)); - nt->name = name; - nt->type = type; - nt->t = t; - nt->next = type_hash[hash]; - type_hash[hash] = nt; - return type; -} - -static int is_incomplete(const type_t *t) -{ - return !t->defined && (is_struct(t->type) || is_union(t->type)); -} - -static void add_incomplete(type_t *t) -{ - struct typenode *tn = xmalloc(sizeof *tn); - tn->type = t; - list_add_tail(&incomplete_types, &tn->entry); -} - -static void fix_type(type_t *t) -{ - if (t->kind == TKIND_ALIAS && is_incomplete(t)) { - type_t *ot = t->orig; - fix_type(ot); - t->fields = ot->fields; - t->defined = ot->defined; - } -} - -static void fix_incomplete(void) -{ - struct typenode *tn, *next; - - LIST_FOR_EACH_ENTRY_SAFE(tn, next, &incomplete_types, struct typenode, entry) { - fix_type(tn->type); - free(tn); - } -} - -static type_t *reg_typedefs(type_t *type, pident_list_t *pidents, attr_list_t *attrs) -{ - type_t *ptr = type; - const pident_t *pident; - int ptrc = 0; - int is_str = is_attr(attrs, ATTR_STRING); - unsigned char ptr_type = get_attrv(attrs, ATTR_POINTERTYPE); - - if (is_str) - { - type_t *t = type; - unsigned char c; - - while (is_ptr(t)) - t = t->ref; - - c = t->type; - if (c != RPC_FC_CHAR && c != RPC_FC_BYTE && c != RPC_FC_WCHAR) - { - pident = LIST_ENTRY( list_head( pidents ), const pident_t, entry ); - yyerror("'%s': [string] attribute is only valid on 'char', 'byte', or 'wchar_t' pointers and arrays", - pident->var->name); - } - } - - /* We must generate names for tagless enum, struct or union. - Typedef-ing a tagless enum, struct or union means we want the typedef - to be included in a library whether it has other attributes or not, - hence the public attribute. */ - if ((type->kind == TKIND_ENUM || type->kind == TKIND_RECORD - || type->kind == TKIND_UNION) && ! type->name && ! parse_only) - { - if (! is_attr(attrs, ATTR_PUBLIC)) - attrs = append_attr( attrs, make_attr(ATTR_PUBLIC) ); - type->name = gen_name(); - } - - LIST_FOR_EACH_ENTRY( pident, pidents, const pident_t, entry ) - { - var_t *name = pident->var; - - if (name->name) { - type_t *cur = ptr; - int cptr = pident->ptr_level; - if (cptr > ptrc) { - while (cptr > ptrc) { - cur = ptr = make_type(RPC_FC_RP, cur); - ptrc++; - } - } else { - while (cptr < ptrc) { - cur = cur->ref; - cptr++; - } - } - cur = alias(cur, name->name); - cur->attrs = attrs; - if (ptr_type) - { - if (is_ptr(cur)) - cur->type = ptr_type; - else - yyerror("'%s': pointer attribute applied to non-pointer type", - cur->name); - } - else if (is_str && ! is_ptr(cur)) - yyerror("'%s': [string] attribute applied to non-pointer type", - cur->name); - - if (is_incomplete(cur)) - add_incomplete(cur); - reg_type(cur, cur->name, 0); - } - } - return type; -} - -static type_t *find_type(const char *name, int t) -{ - struct rtype *cur = type_hash[hash_ident(name)]; - while (cur && (cur->t != t || strcmp(cur->name, name))) - cur = cur->next; - if (!cur) { - yyerror("type '%s' not found", name); - return NULL; - } - return cur->type; -} - -static type_t *find_type2(char *name, int t) -{ - type_t *tp = find_type(name, t); - free(name); - return tp; -} - -int is_type(const char *name) -{ - struct rtype *cur = type_hash[hash_ident(name)]; - while (cur && (cur->t || strcmp(cur->name, name))) - cur = cur->next; - if (cur) return TRUE; - return FALSE; -} - -static type_t *get_type(unsigned char type, char *name, int t) -{ - struct rtype *cur = NULL; - type_t *tp; - if (name) { - cur = type_hash[hash_ident(name)]; - while (cur && (cur->t != t || strcmp(cur->name, name))) - cur = cur->next; - } - if (cur) { - free(name); - return cur->type; - } - tp = make_type(type, NULL); - tp->name = name; - if (!name) return tp; - return reg_type(tp, name, t); -} - -static type_t *get_typev(unsigned char type, var_t *name, int t) -{ - char *sname = NULL; - if (name) { - sname = name->name; - free(name); - } - return get_type(type, sname, t); -} - -static int get_struct_type(var_list_t *fields) -{ - int has_pointer = 0; - int has_conformance = 0; - int has_variance = 0; - var_t *field; - - if (fields) LIST_FOR_EACH_ENTRY( field, fields, var_t, entry ) - { - type_t *t = field->type; - - if (is_ptr(t)) - { - do - t = t->ref; - while (is_ptr(t)); - - switch (t->type) - { - case RPC_FC_IP: - case RPC_FC_ENCAPSULATED_UNION: - case RPC_FC_NON_ENCAPSULATED_UNION: - case RPC_FC_BOGUS_STRUCT: - return RPC_FC_BOGUS_STRUCT; - } - - has_pointer = 1; - continue; - } - - if (field->type->declarray) - { - if (is_string_type(field->attrs, field->type)) - { - if (is_conformant_array(field->type)) - has_conformance = 1; - has_variance = 1; - continue; - } - - if (is_array(field->type->ref)) - return RPC_FC_BOGUS_STRUCT; - - if (is_conformant_array(field->type)) - { - has_conformance = 1; - if (field->type->declarray && list_next(fields, &field->entry)) - yyerror("field '%s' deriving from a conformant array must be the last field in the structure", - field->name); - } - if (field->type->length_is) - has_variance = 1; - - t = field->type->ref; - } - - switch (t->type) - { - /* - * RPC_FC_BYTE, RPC_FC_STRUCT, etc - * Simple types don't effect the type of struct. - * A struct containing a simple struct is still a simple struct. - * So long as we can block copy the data, we return RPC_FC_STRUCT. - */ - case 0: /* void pointer */ - case RPC_FC_BYTE: - case RPC_FC_CHAR: - case RPC_FC_SMALL: - case RPC_FC_USMALL: - case RPC_FC_WCHAR: - case RPC_FC_SHORT: - case RPC_FC_USHORT: - case RPC_FC_LONG: - case RPC_FC_ULONG: - case RPC_FC_INT3264: - case RPC_FC_UINT3264: - case RPC_FC_HYPER: - case RPC_FC_FLOAT: - case RPC_FC_DOUBLE: - case RPC_FC_STRUCT: - case RPC_FC_ENUM16: - case RPC_FC_ENUM32: - break; - - case RPC_FC_RP: - case RPC_FC_UP: - case RPC_FC_FP: - case RPC_FC_OP: - case RPC_FC_CARRAY: - case RPC_FC_CVARRAY: - has_pointer = 1; - break; - - /* - * Propagate member attributes - * a struct should be at least as complex as its member - */ - case RPC_FC_CVSTRUCT: - has_conformance = 1; - has_variance = 1; - has_pointer = 1; - break; - - case RPC_FC_CPSTRUCT: - has_conformance = 1; - if (list_next( fields, &field->entry )) - yyerror("field '%s' deriving from a conformant array must be the last field in the structure", - field->name); - has_pointer = 1; - break; - - case RPC_FC_CSTRUCT: - has_conformance = 1; - if (list_next( fields, &field->entry )) - yyerror("field '%s' deriving from a conformant array must be the last field in the structure", - field->name); - break; - - case RPC_FC_PSTRUCT: - has_pointer = 1; - break; - - default: - fprintf(stderr,"Unknown struct member %s with type (0x%02x)\n", - field->name, t->type); - /* fallthru - treat it as complex */ - - /* as soon as we see one of these these members, it's bogus... */ - case RPC_FC_IP: - case RPC_FC_ENCAPSULATED_UNION: - case RPC_FC_NON_ENCAPSULATED_UNION: - case RPC_FC_TRANSMIT_AS: - case RPC_FC_REPRESENT_AS: - case RPC_FC_PAD: - case RPC_FC_EMBEDDED_COMPLEX: - case RPC_FC_BOGUS_STRUCT: - return RPC_FC_BOGUS_STRUCT; - } - } - - if( has_variance ) - { - if ( has_conformance ) - return RPC_FC_CVSTRUCT; - else - return RPC_FC_BOGUS_STRUCT; - } - if( has_conformance && has_pointer ) - return RPC_FC_CPSTRUCT; - if( has_conformance ) - return RPC_FC_CSTRUCT; - if( has_pointer ) - return RPC_FC_PSTRUCT; - return RPC_FC_STRUCT; -} - -/***** constant repository *****/ - -struct rconst { - char *name; - var_t *var; - struct rconst *next; -}; - -struct rconst *const_hash[HASHMAX]; - -static var_t *reg_const(var_t *var) -{ - struct rconst *nc; - int hash; - if (!var->name) { - yyerror("registering constant without name"); - return var; - } - hash = hash_ident(var->name); - nc = xmalloc(sizeof(struct rconst)); - nc->name = var->name; - nc->var = var; - nc->next = const_hash[hash]; - const_hash[hash] = nc; - return var; -} - -static var_t *find_const(char *name, int f) -{ - struct rconst *cur = const_hash[hash_ident(name)]; - while (cur && strcmp(cur->name, name)) - cur = cur->next; - if (!cur) { - if (f) yyerror("constant '%s' not found", name); - return NULL; - } - return cur->var; -} - -static void write_libid(const char *name, const attr_list_t *attr) -{ - const UUID *uuid = get_attrp(attr, ATTR_UUID); - write_guid(idfile, "LIBID", name, uuid); -} - -static void write_clsid(type_t *cls) -{ - const UUID *uuid = get_attrp(cls->attrs, ATTR_UUID); - write_guid(idfile, "CLSID", cls->name, uuid); -} - -static void write_diid(type_t *iface) -{ - const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID); - write_guid(idfile, "DIID", iface->name, uuid); -} - -static void write_iid(type_t *iface) -{ - const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID); - write_guid(idfile, "IID", iface->name, uuid); -} - -static int compute_method_indexes(type_t *iface) -{ - int idx; - func_t *f; - - if (iface->ref) - idx = compute_method_indexes(iface->ref); - else - idx = 0; - - if (!iface->funcs) - return idx; - - LIST_FOR_EACH_ENTRY( f, iface->funcs, func_t, entry ) - if (! is_callas(f->def->attrs)) - f->idx = idx++; - - return idx; -} - -static char *gen_name(void) -{ - static const char format[] = "__WIDL_%s_generated_name_%08lX"; - static unsigned long n = 0; - static const char *file_id; - static size_t size; - char *name; - - if (! file_id) - { - char *dst = dup_basename(input_name, ".idl"); - file_id = dst; - - for (; *dst; ++dst) - if (! isalnum((unsigned char) *dst)) - *dst = '_'; - - size = sizeof format - 7 + strlen(file_id) + 8; - } - - name = xmalloc(size); - sprintf(name, format, file_id, n++); - return name; -} - -static void process_typedefs(pident_list_t *pidents) -{ - pident_t *pident, *next; - - if (!pidents) return; - LIST_FOR_EACH_ENTRY_SAFE( pident, next, pidents, pident_t, entry ) - { - var_t *var = pident->var; - type_t *type = find_type(var->name, 0); - - if (! parse_only && do_header) - write_typedef(type); - if (in_typelib && type->attrs) - add_typelib_entry(type); - - free(pident); - free(var); - } -} - -static void check_arg(var_t *arg) -{ - type_t *t = arg->type; - - if (t->type == 0 && ! is_var_ptr(arg)) - yyerror("argument '%s' has void type", arg->name); -} - -static void check_all_user_types(ifref_list_t *ifrefs) -{ - const ifref_t *ifref; - const func_t *f; - - if (ifrefs) LIST_FOR_EACH_ENTRY(ifref, ifrefs, const ifref_t, entry) - { - const func_list_t *fs = ifref->iface->funcs; - if (fs) LIST_FOR_EACH_ENTRY(f, fs, const func_t, entry) - check_for_user_types(f->args); - } -} diff --git a/reactos/tools/widl_new/parser.yy.c b/reactos/tools/widl_new/parser.yy.c deleted file mode 100644 index 565a0559924..00000000000 --- a/reactos/tools/widl_new/parser.yy.c +++ /dev/null @@ -1,2160 +0,0 @@ -#define yy_create_buffer parser__create_buffer -#define yy_delete_buffer parser__delete_buffer -#define yy_scan_buffer parser__scan_buffer -#define yy_scan_string parser__scan_string -#define yy_scan_bytes parser__scan_bytes -#define yy_flex_debug parser__flex_debug -#define yy_init_buffer parser__init_buffer -#define yy_flush_buffer parser__flush_buffer -#define yy_load_buffer_state parser__load_buffer_state -#define yy_switch_to_buffer parser__switch_to_buffer -#define yyin parser_in -#define yyleng parser_leng -#define yylex parser_lex -#define yyout parser_out -#define yyrestart parser_restart -#define yytext parser_text -#define yywrap parser_wrap - -/* A lexical scanner generated by flex */ - -/* Scanner skeleton version: - * $Header: /home/daffy/u0/vern/flex/RCS/flex.skl,v 2.91 96/09/10 16:58:48 vern Exp $ - */ - -#define FLEX_SCANNER -#define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 5 - -#include -#include - -/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ -#ifdef c_plusplus -#ifndef __cplusplus -#define __cplusplus -#endif -#endif - - -#ifdef __cplusplus - -#include -#ifndef _WIN32 -#include -#endif - -/* Use prototypes in function declarations. */ -#define YY_USE_PROTOS - -/* The "const" storage-class-modifier is valid. */ -#define YY_USE_CONST - -#else /* ! __cplusplus */ - -#if __STDC__ - -#define YY_USE_PROTOS -#define YY_USE_CONST - -#endif /* __STDC__ */ -#endif /* ! __cplusplus */ - -#ifdef __TURBOC__ - #pragma warn -rch - #pragma warn -use -#include -#include -#define YY_USE_CONST -#define YY_USE_PROTOS -#endif - -#ifdef YY_USE_CONST -#define yyconst const -#else -#define yyconst -#endif - - -#ifdef YY_USE_PROTOS -#define YY_PROTO(proto) proto -#else -#define YY_PROTO(proto) () -#endif - - -/* Returned upon end-of-file. */ -#define YY_NULL 0 - -/* Promotes a possibly negative, possibly signed char to an unsigned - * integer for use as an array index. If the signed char is negative, - * we want to instead treat it as an 8-bit unsigned char, hence the - * double cast. - */ -#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) - -/* Enter a start condition. This macro really ought to take a parameter, - * but we do it the disgusting crufty way forced on us by the ()-less - * definition of BEGIN. - */ -#define BEGIN yy_start = 1 + 2 * - -/* Translate the current start state into a value that can be later handed - * to BEGIN to return to the state. The YYSTATE alias is for lex - * compatibility. - */ -#define YY_START ((yy_start - 1) / 2) -#define YYSTATE YY_START - -/* Action number for EOF rule of a given start state. */ -#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) - -/* Special action meaning "start processing a new file". */ -#define YY_NEW_FILE yyrestart( yyin ) - -#define YY_END_OF_BUFFER_CHAR 0 - -/* Size of default input buffer. */ -#define YY_BUF_SIZE 16384 - -typedef struct yy_buffer_state *YY_BUFFER_STATE; - -extern int yyleng; -extern FILE *yyin, *yyout; - -#define EOB_ACT_CONTINUE_SCAN 0 -#define EOB_ACT_END_OF_FILE 1 -#define EOB_ACT_LAST_MATCH 2 - -/* The funky do-while in the following #define is used to turn the definition - * int a single C statement (which needs a semi-colon terminator). This - * avoids problems with code like: - * - * if ( condition_holds ) - * yyless( 5 ); - * else - * do_something_else(); - * - * Prior to using the do-while the compiler would get upset at the - * "else" because it interpreted the "if" statement as being all - * done when it reached the ';' after the yyless() call. - */ - -/* Return all but the first 'n' matched characters back to the input stream. */ - -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - *yy_cp = yy_hold_char; \ - YY_RESTORE_YY_MORE_OFFSET \ - yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \ - YY_DO_BEFORE_ACTION; /* set up yytext again */ \ - } \ - while ( 0 ) - -#define unput(c) yyunput( c, yytext_ptr ) - -/* The following is because we cannot portably get our hands on size_t - * (without autoconf's help, which isn't available because we want - * flex-generated scanners to compile on their own). - */ -typedef unsigned int yy_size_t; - - -struct yy_buffer_state - { - FILE *yy_input_file; - - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ - - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ - yy_size_t yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ - int yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to - * delete it. - */ - int yy_is_our_buffer; - - /* Whether this is an "interactive" input source; if so, and - * if we're using stdio for input, then we want to use getc() - * instead of fread(), to make sure we stop fetching input after - * each newline. - */ - int yy_is_interactive; - - /* Whether we're considered to be at the beginning of a line. - * If so, '^' rules will be active on the next match, otherwise - * not. - */ - int yy_at_bol; - - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ - int yy_fill_buffer; - - int yy_buffer_status; -#define YY_BUFFER_NEW 0 -#define YY_BUFFER_NORMAL 1 - /* When an EOF's been seen but there's still some text to process - * then we mark the buffer as YY_EOF_PENDING, to indicate that we - * shouldn't try reading from the input source any more. We might - * still have a bunch of tokens to match, though, because of - * possible backing-up. - * - * When we actually see the EOF, we change the status to "new" - * (via yyrestart()), so that the user can continue scanning by - * just pointing yyin at a new input file. - */ -#define YY_BUFFER_EOF_PENDING 2 - }; - -static YY_BUFFER_STATE yy_current_buffer = 0; - -/* We provide macros for accessing buffer states in case in the - * future we want to put the buffer states in a more general - * "scanner state". - */ -#define YY_CURRENT_BUFFER yy_current_buffer - - -/* yy_hold_char holds the character lost when yytext is formed. */ -static char yy_hold_char; - -static int yy_n_chars; /* number of characters read into yy_ch_buf */ - - -int yyleng; - -/* Points to current character in buffer. */ -static char *yy_c_buf_p = (char *) 0; -static int yy_init = 1; /* whether we need to initialize */ -static int yy_start = 0; /* start state number */ - -/* Flag which is used to allow yywrap()'s to do buffer switches - * instead of setting up a fresh yyin. A bit of a hack ... - */ -static int yy_did_buffer_switch_on_eof; - -void yyrestart YY_PROTO(( FILE *input_file )); - -void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer )); -void yy_load_buffer_state YY_PROTO(( void )); -YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size )); -void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b )); -void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file )); -void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b )); -#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer ) - -YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size )); -YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str )); -YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len )); - -static void *yy_flex_alloc YY_PROTO(( yy_size_t )); -static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t )); -static void yy_flex_free YY_PROTO(( void * )); - -#define yy_new_buffer yy_create_buffer - -#define yy_set_interactive(is_interactive) \ - { \ - if ( ! yy_current_buffer ) \ - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ - yy_current_buffer->yy_is_interactive = is_interactive; \ - } - -#define yy_set_bol(at_bol) \ - { \ - if ( ! yy_current_buffer ) \ - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ - yy_current_buffer->yy_at_bol = at_bol; \ - } - -#define YY_AT_BOL() (yy_current_buffer->yy_at_bol) - -typedef unsigned char YY_CHAR; -FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; -typedef int yy_state_type; -extern char *yytext; -#define yytext_ptr yytext - -static yy_state_type yy_get_previous_state YY_PROTO(( void )); -static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state )); -static int yy_get_next_buffer YY_PROTO(( void )); -static void yy_fatal_error YY_PROTO(( yyconst char msg[] )); - -/* Done after the current pattern has been matched and before the - * corresponding action - sets up yytext. - */ -#define YY_DO_BEFORE_ACTION \ - yytext_ptr = yy_bp; \ - yyleng = (int) (yy_cp - yy_bp); \ - yy_hold_char = *yy_cp; \ - *yy_cp = '\0'; \ - yy_c_buf_p = yy_cp; - -#define YY_NUM_RULES 23 -#define YY_END_OF_BUFFER 24 -static yyconst short int yy_accept[113] = - { 0, - 0, 0, 0, 0, 0, 0, 2, 2, 24, 22, - 19, 18, 3, 14, 14, 22, 22, 17, 17, 9, - 19, 1, 8, 23, 4, 8, 14, 14, 11, 11, - 10, 2, 0, 14, 0, 20, 21, 17, 17, 0, - 1, 1, 7, 6, 5, 14, 0, 11, 11, 2, - 15, 13, 17, 14, 0, 11, 0, 17, 14, 0, - 11, 0, 15, 17, 14, 0, 11, 17, 14, 0, - 11, 17, 14, 0, 11, 17, 14, 0, 11, 17, - 0, 14, 0, 16, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 12, 0 - } ; - -static yyconst int yy_ec[256] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, - 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 1, 4, 5, 1, 1, 1, 1, 6, - 1, 1, 7, 1, 8, 9, 1, 10, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 1, 1, 12, - 1, 13, 1, 1, 14, 15, 15, 15, 16, 17, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 19, 20, 18, 18, 18, 18, 18, 21, 18, - 22, 23, 24, 1, 18, 1, 15, 15, 15, 15, - - 25, 15, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 26, - 18, 18, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1 - } ; - -static yyconst int yy_meta[27] = - { 0, - 1, 1, 2, 1, 1, 1, 1, 1, 1, 3, - 3, 1, 1, 3, 3, 3, 3, 4, 4, 4, - 4, 1, 1, 1, 3, 5 - } ; - -static yyconst short int yy_base[151] = - { 0, - 0, 25, 25, 28, 42, 31, 265, 264, 266, 269, - 269, 269, 269, 60, 28, 253, 251, 0, 249, 269, - 38, 260, 269, 269, 269, 31, 39, 62, 79, 0, - 269, 0, 31, 35, 0, 269, 269, 0, 244, 72, - 258, 257, 269, 269, 269, 65, 0, 96, 0, 0, - 113, 0, 242, 68, 0, 129, 149, 240, 70, 0, - 151, 72, 74, 229, 81, 0, 168, 224, 91, 0, - 185, 212, 98, 0, 202, 204, 117, 216, 207, 124, - 0, 108, 129, 269, 0, 0, 0, 206, 0, 0, - 0, 0, 201, 0, 0, 0, 0, 200, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 269, 269, 228, 233, 236, 241, 244, 247, 252, 204, - 195, 194, 189, 188, 187, 178, 177, 172, 171, 170, - 161, 160, 155, 150, 149, 148, 139, 138, 134, 133, - 131, 130, 129, 117, 100, 84, 61, 52, 44, 31 - } ; - -static yyconst short int yy_def[151] = - { 0, - 112, 1, 113, 113, 1, 5, 114, 114, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 115, 115, 112, - 112, 112, 112, 112, 112, 116, 117, 117, 112, 118, - 112, 119, 112, 112, 120, 112, 112, 115, 115, 112, - 112, 112, 112, 112, 112, 121, 121, 112, 118, 119, - 112, 120, 115, 122, 122, 112, 112, 115, 123, 123, - 112, 112, 51, 115, 124, 124, 112, 115, 125, 125, - 112, 115, 126, 126, 112, 115, 112, 112, 118, 115, - 127, 112, 112, 112, 128, 129, 130, 112, 131, 132, - 133, 134, 112, 135, 136, 137, 138, 112, 139, 140, - - 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, - 112, 0, 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, 112, 112 - } ; - -static yyconst short int yy_nxt[296] = - { 0, - 10, 11, 12, 13, 10, 10, 10, 10, 10, 14, - 15, 16, 17, 18, 18, 18, 18, 18, 18, 19, - 18, 20, 10, 10, 18, 18, 21, 24, 25, 22, - 24, 25, 21, 111, 44, 22, 33, 34, 34, 40, - 51, 51, 41, 33, 34, 34, 110, 26, 46, 46, - 26, 27, 28, 45, 109, 29, 29, 29, 29, 30, - 30, 30, 30, 108, 35, 31, 29, 30, 33, 34, - 34, 46, 46, 40, 54, 54, 41, 59, 59, 65, - 65, 63, 63, 63, 63, 35, 107, 112, 48, 48, - 69, 69, 48, 48, 48, 48, 49, 49, 49, 49, - - 73, 73, 106, 48, 49, 56, 56, 77, 77, 56, - 56, 56, 56, 49, 49, 49, 49, 82, 82, 105, - 56, 49, 51, 51, 81, 83, 82, 82, 57, 84, - 83, 104, 103, 102, 84, 101, 100, 57, 61, 61, - 98, 97, 61, 61, 61, 61, 49, 49, 49, 49, - 96, 95, 93, 61, 49, 62, 62, 92, 63, 63, - 67, 67, 91, 90, 67, 67, 67, 67, 49, 49, - 49, 49, 88, 87, 86, 67, 49, 71, 71, 85, - 78, 71, 71, 71, 71, 49, 49, 49, 49, 74, - 70, 66, 71, 49, 75, 75, 60, 55, 75, 75, - - 75, 75, 49, 49, 49, 49, 52, 99, 94, 75, - 49, 79, 79, 89, 81, 79, 79, 79, 79, 49, - 49, 49, 49, 81, 80, 76, 79, 49, 23, 23, - 23, 23, 23, 32, 32, 32, 32, 32, 38, 38, - 38, 43, 72, 43, 43, 43, 47, 68, 47, 49, - 49, 49, 50, 64, 50, 50, 50, 58, 42, 42, - 53, 42, 39, 37, 36, 112, 24, 24, 9, 112, - 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112 - - } ; - -static yyconst short int yy_chk[296] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 2, 3, 3, 2, - 4, 4, 6, 150, 26, 6, 15, 15, 15, 21, - 33, 33, 21, 34, 34, 34, 149, 3, 27, 27, - 4, 5, 5, 26, 148, 5, 5, 5, 5, 5, - 5, 5, 5, 147, 27, 5, 5, 5, 14, 14, - 14, 28, 28, 40, 46, 46, 40, 54, 54, 59, - 59, 62, 62, 63, 63, 14, 146, 28, 29, 29, - 65, 65, 29, 29, 29, 29, 29, 29, 29, 29, - - 69, 69, 145, 29, 29, 48, 48, 73, 73, 48, - 48, 48, 48, 48, 48, 48, 48, 82, 82, 144, - 48, 48, 51, 51, 77, 80, 77, 77, 51, 80, - 83, 143, 142, 141, 83, 140, 139, 51, 56, 56, - 138, 137, 56, 56, 56, 56, 56, 56, 56, 56, - 136, 135, 134, 56, 56, 57, 57, 133, 57, 57, - 61, 61, 132, 131, 61, 61, 61, 61, 61, 61, - 61, 61, 130, 129, 128, 61, 61, 67, 67, 127, - 126, 67, 67, 67, 67, 67, 67, 67, 67, 125, - 124, 123, 67, 67, 71, 71, 122, 121, 71, 71, - - 71, 71, 71, 71, 71, 71, 120, 98, 93, 71, - 71, 75, 75, 88, 79, 75, 75, 75, 75, 75, - 75, 75, 75, 78, 76, 72, 75, 75, 113, 113, - 113, 113, 113, 114, 114, 114, 114, 114, 115, 115, - 115, 116, 68, 116, 116, 116, 117, 64, 117, 118, - 118, 118, 119, 58, 119, 119, 119, 53, 42, 41, - 39, 22, 19, 17, 16, 9, 8, 7, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112 - - } ; - -static yy_state_type yy_last_accepting_state; -static char *yy_last_accepting_cpos; - -/* The intent behind this definition is that it'll catch - * any uses of REJECT which flex missed. - */ -#define REJECT reject_used_but_not_detected -#define yymore() yymore_used_but_not_detected -#define YY_MORE_ADJ 0 -#define YY_RESTORE_YY_MORE_OFFSET -char *yytext; -#line 1 "parser.l" -#define INITIAL 0 -/* -*-C-*- - * IDL Compiler - * - * Copyright 2002 Ove Kaaven - * - * 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 - */ -#define YY_STACK_USED 1 -#define YY_NO_UNPUT 1 -#define YY_NO_TOP_STATE 1 -#define YY_NEVER_INTERACTIVE 1 -#define QUOTE 1 - -#define ATTR 2 - -#define PP_LINE 3 - -#line 39 "parser.l" - -#include "config.h" - -#include -#include -#include -#include -#include -#ifdef HAVE_UNISTD_H -# include -#endif - -#include "widl.h" -#include "utils.h" -#include "parser.h" -#include "wine/wpp.h" - -#include "parser.tab.h" - -extern char *temp_name; - -static void addcchar(char c); -static char *get_buffered_cstring(void); - -static char *cbuffer; -static int cbufidx; -static int cbufalloc = 0; - -static int kw_token(const char *kw); -static int attr_token(const char *kw); - -#define MAX_IMPORT_DEPTH 10 -struct { - YY_BUFFER_STATE state; - char *input_name; - int line_number; - char *temp_name; -} import_stack[MAX_IMPORT_DEPTH]; -int import_stack_ptr = 0; - -static void pop_import(void); - -static UUID* parse_uuid(const char*u) -{ - UUID* uuid = xmalloc(sizeof(UUID)); - char b[3]; - /* it would be nice to use UuidFromStringA */ - uuid->Data1 = strtoul(u, NULL, 16); - uuid->Data2 = strtoul(u+9, NULL, 16); - uuid->Data3 = strtoul(u+14, NULL, 16); - b[2] = 0; - memcpy(b, u+19, 2); uuid->Data4[0] = strtoul(b, NULL, 16); - memcpy(b, u+21, 2); uuid->Data4[1] = strtoul(b, NULL, 16); - memcpy(b, u+24, 2); uuid->Data4[2] = strtoul(b, NULL, 16); - memcpy(b, u+26, 2); uuid->Data4[3] = strtoul(b, NULL, 16); - memcpy(b, u+28, 2); uuid->Data4[4] = strtoul(b, NULL, 16); - memcpy(b, u+30, 2); uuid->Data4[5] = strtoul(b, NULL, 16); - memcpy(b, u+32, 2); uuid->Data4[6] = strtoul(b, NULL, 16); - memcpy(b, u+34, 2); uuid->Data4[7] = strtoul(b, NULL, 16); - return uuid; -} - -/* - ************************************************************************** - * The flexer starts here - ************************************************************************** - */ - -/* Macros after this point can all be overridden by user definitions in - * section 1. - */ - -#ifndef YY_SKIP_YYWRAP -#ifdef __cplusplus -extern "C" int yywrap YY_PROTO(( void )); -#else -extern int yywrap YY_PROTO(( void )); -#endif -#endif - -#ifndef YY_NO_UNPUT -static void yyunput YY_PROTO(( int c, char *buf_ptr )); -#endif - -#ifndef yytext_ptr -static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int )); -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen YY_PROTO(( yyconst char * )); -#endif - -#ifndef YY_NO_INPUT -#ifdef __cplusplus -static int yyinput YY_PROTO(( void )); -#else -static int input YY_PROTO(( void )); -#endif -#endif - -#if YY_STACK_USED -static int yy_start_stack_ptr = 0; -static int yy_start_stack_depth = 0; -static int *yy_start_stack = 0; -#ifndef YY_NO_PUSH_STATE -static void yy_push_state YY_PROTO(( int new_state )); -#endif -#ifndef YY_NO_POP_STATE -static void yy_pop_state YY_PROTO(( void )); -#endif -#ifndef YY_NO_TOP_STATE -static int yy_top_state YY_PROTO(( void )); -#endif - -#else -#define YY_NO_PUSH_STATE 1 -#define YY_NO_POP_STATE 1 -#define YY_NO_TOP_STATE 1 -#endif - -#ifdef YY_MALLOC_DECL -YY_MALLOC_DECL -#else -#if __STDC__ -#ifndef __cplusplus -#include -#endif -#else -/* Just try to get by without declaring the routines. This will fail - * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int) - * or sizeof(void*) != sizeof(int). - */ -#endif -#endif - -/* Amount of stuff to slurp up with each read. */ -#ifndef YY_READ_BUF_SIZE -#define YY_READ_BUF_SIZE 8192 -#endif - -/* Copy whatever the last rule matched to the standard output. */ - -#ifndef ECHO -/* This used to be an fputs(), but since the string might contain NUL's, - * we now use fwrite(). - */ -#define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) -#endif - -/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, - * is returned in "result". - */ -#ifndef YY_INPUT -#define YY_INPUT(buf,result,max_size) \ - if ( yy_current_buffer->yy_is_interactive ) \ - { \ - int c = '*', n; \ - for ( n = 0; n < max_size && \ - (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ - buf[n] = (char) c; \ - if ( c == '\n' ) \ - buf[n++] = (char) c; \ - if ( c == EOF && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - result = n; \ - } \ - else \ - { \ - errno=0; \ - while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ - { \ - if( errno != EINTR) \ - { \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - break; \ - } \ - errno=0; \ - clearerr(yyin); \ - } \ - } -#endif - -/* No semi-colon after return; correct usage is to write "yyterminate();" - - * we don't want an extra ';' after the "return" because that will cause - * some compilers to complain about unreachable statements. - */ -#ifndef yyterminate -#define yyterminate() return YY_NULL -#endif - -/* Number of entries by which start-condition stack grows. */ -#ifndef YY_START_STACK_INCR -#define YY_START_STACK_INCR 25 -#endif - -/* Report a fatal error. */ -#ifndef YY_FATAL_ERROR -#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) -#endif - -/* Default declaration of generated scanner - a define so the user can - * easily add parameters. - */ -#ifndef YY_DECL -#define YY_DECL int yylex YY_PROTO(( void )) -#endif - -/* Code executed at the beginning of each rule, after yytext and yyleng - * have been set up. - */ -#ifndef YY_USER_ACTION -#define YY_USER_ACTION -#endif - -/* Code executed at the end of each rule. */ -#ifndef YY_BREAK -#define YY_BREAK break; -#endif - -#define YY_RULE_SETUP \ - if ( yyleng > 0 ) \ - yy_current_buffer->yy_at_bol = \ - (yytext[yyleng - 1] == '\n'); \ - YY_USER_ACTION - -YY_DECL - { - register yy_state_type yy_current_state; - register char *yy_cp, *yy_bp; - register int yy_act; - -#line 108 "parser.l" - - - if ( yy_init ) - { - yy_init = 0; - -#ifdef YY_USER_INIT - YY_USER_INIT; -#endif - - if ( ! yy_start ) - yy_start = 1; /* first start state */ - - if ( ! yyin ) - yyin = stdin; - - if ( ! yyout ) - yyout = stdout; - - if ( ! yy_current_buffer ) - yy_current_buffer = - yy_create_buffer( yyin, YY_BUF_SIZE ); - - yy_load_buffer_state(); - } - - while ( 1 ) /* loops until end-of-file is reached */ - { - yy_cp = yy_c_buf_p; - - /* Support of yytext. */ - *yy_cp = yy_hold_char; - - /* yy_bp points to the position in yy_ch_buf of the start of - * the current run. - */ - yy_bp = yy_cp; - - yy_current_state = yy_start; - yy_current_state += YY_AT_BOL(); -yy_match: - do - { - register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; - if ( yy_accept[yy_current_state] ) - { - yy_last_accepting_state = yy_current_state; - yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 113 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - ++yy_cp; - } - while ( yy_base[yy_current_state] != 269 ); - -yy_find_action: - yy_act = yy_accept[yy_current_state]; - if ( yy_act == 0 ) - { /* have to back up */ - yy_cp = yy_last_accepting_cpos; - yy_current_state = yy_last_accepting_state; - yy_act = yy_accept[yy_current_state]; - } - - YY_DO_BEFORE_ACTION; - - -do_action: /* This label is used only to access EOF actions. */ - - - switch ( yy_act ) - { /* beginning of action switch */ - case 0: /* must back up */ - /* undo the effects of YY_DO_BEFORE_ACTION */ - *yy_cp = yy_hold_char; - yy_cp = yy_last_accepting_cpos; - yy_current_state = yy_last_accepting_state; - goto yy_find_action; - -case 1: -YY_RULE_SETUP -#line 109 "parser.l" -yy_push_state(PP_LINE); - YY_BREAK -case 2: -YY_RULE_SETUP -#line 110 "parser.l" -{ - int lineno; - char *cptr, *fname; - yy_pop_state(); - lineno = (int)strtol(yytext, &cptr, 10); - if(!lineno) - parser_error("Malformed '#...' line-directive; invalid linenumber"); - fname = strchr(cptr, '"'); - if(!fname) - parser_error("Malformed '#...' line-directive; missing filename"); - fname++; - cptr = strchr(fname, '"'); - if(!cptr) - parser_error("Malformed '#...' line-directive; missing terminating \""); - *cptr = '\0'; - line_number = lineno - 1; /* We didn't read the newline */ - free( input_name ); - input_name = xstrdup(fname); - } - YY_BREAK -case 3: -YY_RULE_SETUP -#line 129 "parser.l" -yy_push_state(QUOTE); cbufidx = 0; - YY_BREAK -case 4: -YY_RULE_SETUP -#line 130 "parser.l" -{ - yy_pop_state(); - parser_lval.str = get_buffered_cstring(); - return aSTRING; - } - YY_BREAK -case 5: -#line 136 "parser.l" -case 6: -YY_RULE_SETUP -#line 136 "parser.l" -addcchar(yytext[1]); - YY_BREAK -case 7: -YY_RULE_SETUP -#line 137 "parser.l" -addcchar('\\'); addcchar(yytext[1]); - YY_BREAK -case 8: -YY_RULE_SETUP -#line 138 "parser.l" -addcchar(yytext[0]); - YY_BREAK -case 9: -YY_RULE_SETUP -#line 139 "parser.l" -yy_push_state(ATTR); return '['; - YY_BREAK -case 10: -YY_RULE_SETUP -#line 140 "parser.l" -yy_pop_state(); return ']'; - YY_BREAK -case 11: -YY_RULE_SETUP -#line 141 "parser.l" -return attr_token(yytext); - YY_BREAK -case 12: -YY_RULE_SETUP -#line 142 "parser.l" -{ - parser_lval.uuid = parse_uuid(yytext); - return aUUID; - } - YY_BREAK -case 13: -YY_RULE_SETUP -#line 146 "parser.l" -{ - parser_lval.num = strtoul(yytext, NULL, 0); - return aHEXNUM; - } - YY_BREAK -case 14: -YY_RULE_SETUP -#line 150 "parser.l" -{ - parser_lval.num = strtoul(yytext, NULL, 0); - return aNUM; - } - YY_BREAK -case 15: -YY_RULE_SETUP -#line 154 "parser.l" -{ - parser_lval.dbl = strtod(yytext, NULL); - return aDOUBLE; - } - YY_BREAK -case 16: -*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ -yy_c_buf_p = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -YY_RULE_SETUP -#line 158 "parser.l" -return tSAFEARRAY; - YY_BREAK -case 17: -YY_RULE_SETUP -#line 159 "parser.l" -return kw_token(yytext); - YY_BREAK -case 18: -YY_RULE_SETUP -#line 160 "parser.l" -line_number++; - YY_BREAK -case 19: -YY_RULE_SETUP -#line 161 "parser.l" - - YY_BREAK -case 20: -YY_RULE_SETUP -#line 162 "parser.l" -return SHL; - YY_BREAK -case 21: -YY_RULE_SETUP -#line 163 "parser.l" -return SHR; - YY_BREAK -case 22: -YY_RULE_SETUP -#line 164 "parser.l" -return yytext[0]; - YY_BREAK -case YY_STATE_EOF(INITIAL): -case YY_STATE_EOF(QUOTE): -case YY_STATE_EOF(ATTR): -case YY_STATE_EOF(PP_LINE): -#line 165 "parser.l" -{ - if (import_stack_ptr) { - pop_import(); - return aEOF; - } - else yyterminate(); - } - YY_BREAK -case 23: -YY_RULE_SETUP -#line 172 "parser.l" -ECHO; - YY_BREAK - - case YY_END_OF_BUFFER: - { - /* Amount of text matched not including the EOB char. */ - int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1; - - /* Undo the effects of YY_DO_BEFORE_ACTION. */ - *yy_cp = yy_hold_char; - YY_RESTORE_YY_MORE_OFFSET - - if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW ) - { - /* We're scanning a new file or input source. It's - * possible that this happened because the user - * just pointed yyin at a new source and called - * yylex(). If so, then we have to assure - * consistency between yy_current_buffer and our - * globals. Here is the right place to do so, because - * this is the first action (other than possibly a - * back-up) that will match for the new input source. - */ - yy_n_chars = yy_current_buffer->yy_n_chars; - yy_current_buffer->yy_input_file = yyin; - yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL; - } - - /* Note that here we test for yy_c_buf_p "<=" to the position - * of the first EOB in the buffer, since yy_c_buf_p will - * already have been incremented past the NUL character - * (since all states make transitions on EOB to the - * end-of-buffer state). Contrast this with the test - * in input(). - */ - if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) - { /* This was really a NUL. */ - yy_state_type yy_next_state; - - yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state(); - - /* Okay, we're now positioned to make the NUL - * transition. We couldn't have - * yy_get_previous_state() go ahead and do it - * for us because it doesn't know how to deal - * with the possibility of jamming (and we don't - * want to build jamming into it because then it - * will run more slowly). - */ - - yy_next_state = yy_try_NUL_trans( yy_current_state ); - - yy_bp = yytext_ptr + YY_MORE_ADJ; - - if ( yy_next_state ) - { - /* Consume the NUL. */ - yy_cp = ++yy_c_buf_p; - yy_current_state = yy_next_state; - goto yy_match; - } - - else - { - yy_cp = yy_c_buf_p; - goto yy_find_action; - } - } - - else switch ( yy_get_next_buffer() ) - { - case EOB_ACT_END_OF_FILE: - { - yy_did_buffer_switch_on_eof = 0; - - if ( yywrap() ) - { - /* Note: because we've taken care in - * yy_get_next_buffer() to have set up - * yytext, we can now set up - * yy_c_buf_p so that if some total - * hoser (like flex itself) wants to - * call the scanner after we return the - * YY_NULL, it'll still work - another - * YY_NULL will get returned. - */ - yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; - - yy_act = YY_STATE_EOF(YY_START); - goto do_action; - } - - else - { - if ( ! yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; - } - break; - } - - case EOB_ACT_CONTINUE_SCAN: - yy_c_buf_p = - yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state(); - - yy_cp = yy_c_buf_p; - yy_bp = yytext_ptr + YY_MORE_ADJ; - goto yy_match; - - case EOB_ACT_LAST_MATCH: - yy_c_buf_p = - &yy_current_buffer->yy_ch_buf[yy_n_chars]; - - yy_current_state = yy_get_previous_state(); - - yy_cp = yy_c_buf_p; - yy_bp = yytext_ptr + YY_MORE_ADJ; - goto yy_find_action; - } - break; - } - - default: - YY_FATAL_ERROR( - "fatal flex scanner internal error--no action found" ); - } /* end of action switch */ - } /* end of scanning one token */ - } /* end of yylex */ - - -/* yy_get_next_buffer - try to read in a new buffer - * - * Returns a code representing an action: - * EOB_ACT_LAST_MATCH - - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position - * EOB_ACT_END_OF_FILE - end of file - */ - -static int yy_get_next_buffer() - { - register char *dest = yy_current_buffer->yy_ch_buf; - register char *source = yytext_ptr; - register int number_to_move, i; - int ret_val; - - if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) - YY_FATAL_ERROR( - "fatal flex scanner internal error--end of buffer missed" ); - - if ( yy_current_buffer->yy_fill_buffer == 0 ) - { /* Don't try to fill the buffer, so this is an EOF. */ - if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 ) - { - /* We matched a single character, the EOB, so - * treat this as a final EOF. - */ - return EOB_ACT_END_OF_FILE; - } - - else - { - /* We matched some text prior to the EOB, first - * process it. - */ - return EOB_ACT_LAST_MATCH; - } - } - - /* Try to read more data. */ - - /* First move last chars to start of buffer. */ - number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1; - - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); - - if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING ) - /* don't do the read, it's not guaranteed to return an EOF, - * just force an EOF - */ - yy_current_buffer->yy_n_chars = yy_n_chars = 0; - - else - { - int num_to_read = - yy_current_buffer->yy_buf_size - number_to_move - 1; - - while ( num_to_read <= 0 ) - { /* Not enough room in the buffer - grow it. */ -#ifdef YY_USES_REJECT - YY_FATAL_ERROR( -"input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); -#else - - /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = yy_current_buffer; - - int yy_c_buf_p_offset = - (int) (yy_c_buf_p - b->yy_ch_buf); - - if ( b->yy_is_our_buffer ) - { - int new_size = b->yy_buf_size * 2; - - if ( new_size <= 0 ) - b->yy_buf_size += b->yy_buf_size / 8; - else - b->yy_buf_size *= 2; - - b->yy_ch_buf = (char *) - /* Include room in for 2 EOB chars. */ - yy_flex_realloc( (void *) b->yy_ch_buf, - b->yy_buf_size + 2 ); - } - else - /* Can't grow it, we don't own it. */ - b->yy_ch_buf = 0; - - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( - "fatal error - scanner input buffer overflow" ); - - yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; - - num_to_read = yy_current_buffer->yy_buf_size - - number_to_move - 1; -#endif - } - - if ( num_to_read > YY_READ_BUF_SIZE ) - num_to_read = YY_READ_BUF_SIZE; - - /* Read in more data. */ - YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), - yy_n_chars, num_to_read ); - - yy_current_buffer->yy_n_chars = yy_n_chars; - } - - if ( yy_n_chars == 0 ) - { - if ( number_to_move == YY_MORE_ADJ ) - { - ret_val = EOB_ACT_END_OF_FILE; - yyrestart( yyin ); - } - - else - { - ret_val = EOB_ACT_LAST_MATCH; - yy_current_buffer->yy_buffer_status = - YY_BUFFER_EOF_PENDING; - } - } - - else - ret_val = EOB_ACT_CONTINUE_SCAN; - - yy_n_chars += number_to_move; - yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; - yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; - - yytext_ptr = &yy_current_buffer->yy_ch_buf[0]; - - return ret_val; - } - - -/* yy_get_previous_state - get the state just before the EOB char was reached */ - -static yy_state_type yy_get_previous_state() - { - register yy_state_type yy_current_state; - register char *yy_cp; - - yy_current_state = yy_start; - yy_current_state += YY_AT_BOL(); - - for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) - { - register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); - if ( yy_accept[yy_current_state] ) - { - yy_last_accepting_state = yy_current_state; - yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 113 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - } - - return yy_current_state; - } - - -/* yy_try_NUL_trans - try to make a transition on the NUL character - * - * synopsis - * next_state = yy_try_NUL_trans( current_state ); - */ - -#ifdef YY_USE_PROTOS -static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state ) -#else -static yy_state_type yy_try_NUL_trans( yy_current_state ) -yy_state_type yy_current_state; -#endif - { - register int yy_is_jam; - register char *yy_cp = yy_c_buf_p; - - register YY_CHAR yy_c = 1; - if ( yy_accept[yy_current_state] ) - { - yy_last_accepting_state = yy_current_state; - yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 113 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 112); - - return yy_is_jam ? 0 : yy_current_state; - } - - -#ifndef YY_NO_UNPUT -#ifdef YY_USE_PROTOS -static void yyunput( int c, register char *yy_bp ) -#else -static void yyunput( c, yy_bp ) -int c; -register char *yy_bp; -#endif - { - register char *yy_cp = yy_c_buf_p; - - /* undo effects of setting up yytext */ - *yy_cp = yy_hold_char; - - if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) - { /* need to shift things up to make room */ - /* +2 for EOB chars. */ - register int number_to_move = yy_n_chars + 2; - register char *dest = &yy_current_buffer->yy_ch_buf[ - yy_current_buffer->yy_buf_size + 2]; - register char *source = - &yy_current_buffer->yy_ch_buf[number_to_move]; - - while ( source > yy_current_buffer->yy_ch_buf ) - *--dest = *--source; - - yy_cp += (int) (dest - source); - yy_bp += (int) (dest - source); - yy_current_buffer->yy_n_chars = - yy_n_chars = yy_current_buffer->yy_buf_size; - - if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) - YY_FATAL_ERROR( "flex scanner push-back overflow" ); - } - - *--yy_cp = (char) c; - - - yytext_ptr = yy_bp; - yy_hold_char = *yy_cp; - yy_c_buf_p = yy_cp; - } -#endif /* ifndef YY_NO_UNPUT */ - - -#ifdef __cplusplus -static int yyinput() -#else -static int input() -#endif - { - int c; - - *yy_c_buf_p = yy_hold_char; - - if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) - { - /* yy_c_buf_p now points to the character we want to return. - * If this occurs *before* the EOB characters, then it's a - * valid NUL; if not, then we've hit the end of the buffer. - */ - if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) - /* This was really a NUL. */ - *yy_c_buf_p = '\0'; - - else - { /* need more input */ - int offset = yy_c_buf_p - yytext_ptr; - ++yy_c_buf_p; - - switch ( yy_get_next_buffer() ) - { - case EOB_ACT_LAST_MATCH: - /* This happens because yy_g_n_b() - * sees that we've accumulated a - * token and flags that we need to - * try matching the token before - * proceeding. But for input(), - * there's no matching to consider. - * So convert the EOB_ACT_LAST_MATCH - * to EOB_ACT_END_OF_FILE. - */ - - /* Reset buffer status. */ - yyrestart( yyin ); - - /* fall through */ - - case EOB_ACT_END_OF_FILE: - { - if ( yywrap() ) - return EOF; - - if ( ! yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; -#ifdef __cplusplus - return yyinput(); -#else - return input(); -#endif - } - - case EOB_ACT_CONTINUE_SCAN: - yy_c_buf_p = yytext_ptr + offset; - break; - } - } - } - - c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */ - *yy_c_buf_p = '\0'; /* preserve yytext */ - yy_hold_char = *++yy_c_buf_p; - - yy_current_buffer->yy_at_bol = (c == '\n'); - - return c; - } - - -#ifdef YY_USE_PROTOS -void yyrestart( FILE *input_file ) -#else -void yyrestart( input_file ) -FILE *input_file; -#endif - { - if ( ! yy_current_buffer ) - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); - - yy_init_buffer( yy_current_buffer, input_file ); - yy_load_buffer_state(); - } - - -#ifdef YY_USE_PROTOS -void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) -#else -void yy_switch_to_buffer( new_buffer ) -YY_BUFFER_STATE new_buffer; -#endif - { - if ( yy_current_buffer == new_buffer ) - return; - - if ( yy_current_buffer ) - { - /* Flush out information for old buffer. */ - *yy_c_buf_p = yy_hold_char; - yy_current_buffer->yy_buf_pos = yy_c_buf_p; - yy_current_buffer->yy_n_chars = yy_n_chars; - } - - yy_current_buffer = new_buffer; - yy_load_buffer_state(); - - /* We don't actually know whether we did this switch during - * EOF (yywrap()) processing, but the only time this flag - * is looked at is after yywrap() is called, so it's safe - * to go ahead and always set it. - */ - yy_did_buffer_switch_on_eof = 1; - } - - -#ifdef YY_USE_PROTOS -void yy_load_buffer_state( void ) -#else -void yy_load_buffer_state() -#endif - { - yy_n_chars = yy_current_buffer->yy_n_chars; - yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos; - yyin = yy_current_buffer->yy_input_file; - yy_hold_char = *yy_c_buf_p; - } - - -#ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_create_buffer( FILE *file, int size ) -#else -YY_BUFFER_STATE yy_create_buffer( file, size ) -FILE *file; -int size; -#endif - { - YY_BUFFER_STATE b; - - b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_buf_size = size; - - /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. - */ - b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 ); - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_is_our_buffer = 1; - - yy_init_buffer( b, file ); - - return b; - } - - -#ifdef YY_USE_PROTOS -void yy_delete_buffer( YY_BUFFER_STATE b ) -#else -void yy_delete_buffer( b ) -YY_BUFFER_STATE b; -#endif - { - if ( ! b ) - return; - - if ( b == yy_current_buffer ) - yy_current_buffer = (YY_BUFFER_STATE) 0; - - if ( b->yy_is_our_buffer ) - yy_flex_free( (void *) b->yy_ch_buf ); - - yy_flex_free( (void *) b ); - } - - -#ifndef _WIN32 -#include -#else -#ifndef YY_ALWAYS_INTERACTIVE -#ifndef YY_NEVER_INTERACTIVE -extern int isatty YY_PROTO(( int )); -#endif -#endif -#endif - -#ifdef YY_USE_PROTOS -void yy_init_buffer( YY_BUFFER_STATE b, FILE *file ) -#else -void yy_init_buffer( b, file ) -YY_BUFFER_STATE b; -FILE *file; -#endif - - - { - yy_flush_buffer( b ); - - b->yy_input_file = file; - b->yy_fill_buffer = 1; - -#if YY_ALWAYS_INTERACTIVE - b->yy_is_interactive = 1; -#else -#if YY_NEVER_INTERACTIVE - b->yy_is_interactive = 0; -#else - b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; -#endif -#endif - } - - -#ifdef YY_USE_PROTOS -void yy_flush_buffer( YY_BUFFER_STATE b ) -#else -void yy_flush_buffer( b ) -YY_BUFFER_STATE b; -#endif - - { - if ( ! b ) - return; - - b->yy_n_chars = 0; - - /* We always need two end-of-buffer characters. The first causes - * a transition to the end-of-buffer state. The second causes - * a jam in that state. - */ - b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; - b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; - - b->yy_buf_pos = &b->yy_ch_buf[0]; - - b->yy_at_bol = 1; - b->yy_buffer_status = YY_BUFFER_NEW; - - if ( b == yy_current_buffer ) - yy_load_buffer_state(); - } - - -#ifndef YY_NO_SCAN_BUFFER -#ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size ) -#else -YY_BUFFER_STATE yy_scan_buffer( base, size ) -char *base; -yy_size_t size; -#endif - { - YY_BUFFER_STATE b; - - if ( size < 2 || - base[size-2] != YY_END_OF_BUFFER_CHAR || - base[size-1] != YY_END_OF_BUFFER_CHAR ) - /* They forgot to leave room for the EOB's. */ - return 0; - - b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); - - b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ - b->yy_buf_pos = b->yy_ch_buf = base; - b->yy_is_our_buffer = 0; - b->yy_input_file = 0; - b->yy_n_chars = b->yy_buf_size; - b->yy_is_interactive = 0; - b->yy_at_bol = 1; - b->yy_fill_buffer = 0; - b->yy_buffer_status = YY_BUFFER_NEW; - - yy_switch_to_buffer( b ); - - return b; - } -#endif - - -#ifndef YY_NO_SCAN_STRING -#ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str ) -#else -YY_BUFFER_STATE yy_scan_string( yy_str ) -yyconst char *yy_str; -#endif - { - int len; - for ( len = 0; yy_str[len]; ++len ) - ; - - return yy_scan_bytes( yy_str, len ); - } -#endif - - -#ifndef YY_NO_SCAN_BYTES -#ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len ) -#else -YY_BUFFER_STATE yy_scan_bytes( bytes, len ) -yyconst char *bytes; -int len; -#endif - { - YY_BUFFER_STATE b; - char *buf; - yy_size_t n; - int i; - - /* Get memory for full buffer, including space for trailing EOB's. */ - n = len + 2; - buf = (char *) yy_flex_alloc( n ); - if ( ! buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); - - for ( i = 0; i < len; ++i ) - buf[i] = bytes[i]; - - buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; - - b = yy_scan_buffer( buf, n ); - if ( ! b ) - YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); - - /* It's okay to grow etc. this buffer, and we should throw it - * away when we're done. - */ - b->yy_is_our_buffer = 1; - - return b; - } -#endif - - -#ifndef YY_NO_PUSH_STATE -#ifdef YY_USE_PROTOS -static void yy_push_state( int new_state ) -#else -static void yy_push_state( new_state ) -int new_state; -#endif - { - if ( yy_start_stack_ptr >= yy_start_stack_depth ) - { - yy_size_t new_size; - - yy_start_stack_depth += YY_START_STACK_INCR; - new_size = yy_start_stack_depth * sizeof( int ); - - if ( ! yy_start_stack ) - yy_start_stack = (int *) yy_flex_alloc( new_size ); - - else - yy_start_stack = (int *) yy_flex_realloc( - (void *) yy_start_stack, new_size ); - - if ( ! yy_start_stack ) - YY_FATAL_ERROR( - "out of memory expanding start-condition stack" ); - } - - yy_start_stack[yy_start_stack_ptr++] = YY_START; - - BEGIN(new_state); - } -#endif - - -#ifndef YY_NO_POP_STATE -static void yy_pop_state() - { - if ( --yy_start_stack_ptr < 0 ) - YY_FATAL_ERROR( "start-condition stack underflow" ); - - BEGIN(yy_start_stack[yy_start_stack_ptr]); - } -#endif - - -#ifndef YY_NO_TOP_STATE -static int yy_top_state() - { - return yy_start_stack[yy_start_stack_ptr - 1]; - } -#endif - -#ifndef YY_EXIT_FAILURE -#define YY_EXIT_FAILURE 2 -#endif - -#ifdef YY_USE_PROTOS -static void yy_fatal_error( yyconst char msg[] ) -#else -static void yy_fatal_error( msg ) -char msg[]; -#endif - { - (void) fprintf( stderr, "%s\n", msg ); - exit( YY_EXIT_FAILURE ); - } - - - -/* Redefine yyless() so it works in section 3 code. */ - -#undef yyless -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - yytext[yyleng] = yy_hold_char; \ - yy_c_buf_p = yytext + n; \ - yy_hold_char = *yy_c_buf_p; \ - *yy_c_buf_p = '\0'; \ - yyleng = n; \ - } \ - while ( 0 ) - - -/* Internal utility routines. */ - -#ifndef yytext_ptr -#ifdef YY_USE_PROTOS -static void yy_flex_strncpy( char *s1, yyconst char *s2, int n ) -#else -static void yy_flex_strncpy( s1, s2, n ) -char *s1; -yyconst char *s2; -int n; -#endif - { - register int i; - for ( i = 0; i < n; ++i ) - s1[i] = s2[i]; - } -#endif - -#ifdef YY_NEED_STRLEN -#ifdef YY_USE_PROTOS -static int yy_flex_strlen( yyconst char *s ) -#else -static int yy_flex_strlen( s ) -yyconst char *s; -#endif - { - register int n; - for ( n = 0; s[n]; ++n ) - ; - - return n; - } -#endif - - -#ifdef YY_USE_PROTOS -static void *yy_flex_alloc( yy_size_t size ) -#else -static void *yy_flex_alloc( size ) -yy_size_t size; -#endif - { - return (void *) malloc( size ); - } - -#ifdef YY_USE_PROTOS -static void *yy_flex_realloc( void *ptr, yy_size_t size ) -#else -static void *yy_flex_realloc( ptr, size ) -void *ptr; -yy_size_t size; -#endif - { - /* The cast to (char *) in the following accommodates both - * implementations that use char* generic pointers, and those - * that use void* generic pointers. It works with the latter - * because both ANSI C and C++ allow castless assignment from - * any pointer type to void*, and deal with argument conversions - * as though doing an assignment. - */ - return (void *) realloc( (char *) ptr, size ); - } - -#ifdef YY_USE_PROTOS -static void yy_flex_free( void *ptr ) -#else -static void yy_flex_free( ptr ) -void *ptr; -#endif - { - free( ptr ); - } - -#if YY_MAIN -int main() - { - yylex(); - return 0; - } -#endif -#line 172 "parser.l" - - -#ifndef parser_wrap -int parser_wrap(void) -{ - return 1; -} -#endif - -struct keyword { - const char *kw; - int token; -}; - -static const struct keyword keywords[] = { - {"FALSE", tFALSE}, - {"TRUE", tTRUE}, - {"__cdecl", tCDECL}, - {"__int64", tINT64}, - {"__stdcall", tSTDCALL}, - {"_stdcall", tSTDCALL}, - {"boolean", tBOOLEAN}, - {"byte", tBYTE}, - {"callback", tCALLBACK}, - {"case", tCASE}, - {"char", tCHAR}, - {"coclass", tCOCLASS}, - {"code", tCODE}, - {"comm_status", tCOMMSTATUS}, - {"const", tCONST}, - {"cpp_quote", tCPPQUOTE}, - {"default", tDEFAULT}, - {"dispinterface", tDISPINTERFACE}, - {"double", tDOUBLE}, - {"enum", tENUM}, - {"error_status_t", tERRORSTATUST}, - {"extern", tEXTERN}, - {"float", tFLOAT}, - {"handle_t", tHANDLET}, - {"hyper", tHYPER}, - {"import", tIMPORT}, - {"importlib", tIMPORTLIB}, - {"in_line", tINLINE}, - {"int", tINT}, - {"interface", tINTERFACE}, - {"library", tLIBRARY}, - {"long", tLONG}, - {"methods", tMETHODS}, - {"module", tMODULE}, - {"properties", tPROPERTIES}, - {"short", tSHORT}, - {"signed", tSIGNED}, - {"sizeof", tSIZEOF}, - {"small", tSMALL}, - {"struct", tSTRUCT}, - {"switch", tSWITCH}, - {"typedef", tTYPEDEF}, - {"union", tUNION}, - {"unsigned", tUNSIGNED}, - {"void", tVOID}, - {"wchar_t", tWCHAR}, -}; -#define NKEYWORDS (sizeof(keywords)/sizeof(keywords[0])) - -/* keywords only recognized in attribute lists */ -static const struct keyword attr_keywords[] = -{ - {"aggregatable", tAGGREGATABLE}, - {"allocate", tALLOCATE}, - {"appobject", tAPPOBJECT}, - {"async", tASYNC}, - {"async_uuid", tASYNCUUID}, - {"auto_handle", tAUTOHANDLE}, - {"bindable", tBINDABLE}, - {"broadcast", tBROADCAST}, - {"byte_count", tBYTECOUNT}, - {"call_as", tCALLAS}, - {"context_handle", tCONTEXTHANDLE}, - {"context_handle_noserialize", tCONTEXTHANDLENOSERIALIZE}, - {"context_handle_serialize", tCONTEXTHANDLENOSERIALIZE}, - {"control", tCONTROL}, - {"defaultcollelem", tDEFAULTCOLLELEM}, - {"defaultvalue", tDEFAULTVALUE}, - {"defaultvtable", tDEFAULTVTABLE}, - {"displaybind", tDISPLAYBIND}, - {"dllname", tDLLNAME}, - {"dual", tDUAL}, - {"endpoint", tENDPOINT}, - {"entry", tENTRY}, - {"explicit_handle", tEXPLICITHANDLE}, - {"handle", tHANDLE}, - {"helpcontext", tHELPCONTEXT}, - {"helpfile", tHELPFILE}, - {"helpstring", tHELPSTRING}, - {"helpstringcontext", tHELPSTRINGCONTEXT}, - {"helpstringdll", tHELPSTRINGDLL}, - {"hidden", tHIDDEN}, - {"id", tID}, - {"idempotent", tIDEMPOTENT}, - {"iid_is", tIIDIS}, - {"immediatebind", tIMMEDIATEBIND}, - {"implicit_handle", tIMPLICITHANDLE}, - {"in", tIN}, - {"input_sync", tINPUTSYNC}, - {"lcid", tLCID}, - {"length_is", tLENGTHIS}, - {"local", tLOCAL}, - {"nonbrowsable", tNONBROWSABLE}, - {"noncreatable", tNONCREATABLE}, - {"nonextensible", tNONEXTENSIBLE}, - {"object", tOBJECT}, - {"odl", tODL}, - {"oleautomation", tOLEAUTOMATION}, - {"optional", tOPTIONAL}, - {"out", tOUT}, - {"pointer_default", tPOINTERDEFAULT}, - {"propget", tPROPGET}, - {"propput", tPROPPUT}, - {"propputref", tPROPPUTREF}, - {"ptr", tPTR}, - {"public", tPUBLIC}, - {"range", tRANGE}, - {"readonly", tREADONLY}, - {"ref", tREF}, - {"requestedit", tREQUESTEDIT}, - {"restricted", tRESTRICTED}, - {"retval", tRETVAL}, - {"single", tSINGLE}, - {"size_is", tSIZEIS}, - {"source", tSOURCE}, - {"string", tSTRING}, - {"switch_is", tSWITCHIS}, - {"switch_type", tSWITCHTYPE}, - {"transmit_as", tTRANSMITAS}, - {"unique", tUNIQUE}, - {"uuid", tUUID}, - {"v1_enum", tV1ENUM}, - {"vararg", tVARARG}, - {"version", tVERSION}, - {"wire_marshal", tWIREMARSHAL}, -}; - - -#define KWP(p) ((const struct keyword *)(p)) - -static int kw_cmp_func(const void *s1, const void *s2) -{ - return strcmp(KWP(s1)->kw, KWP(s2)->kw); -} - -static int kw_token(const char *kw) -{ - struct keyword key, *kwp; - key.kw = kw; - kwp = bsearch(&key, keywords, NKEYWORDS, sizeof(keywords[0]), kw_cmp_func); - if (kwp) { - parser_lval.str = xstrdup(kwp->kw); - return kwp->token; - } - parser_lval.str = xstrdup(kw); - return is_type(kw) ? aKNOWNTYPE : aIDENTIFIER; -} - -static int attr_token(const char *kw) -{ - struct keyword key, *kwp; - key.kw = kw; - kwp = bsearch(&key, attr_keywords, sizeof(attr_keywords)/sizeof(attr_keywords[0]), - sizeof(attr_keywords[0]), kw_cmp_func); - if (kwp) { - parser_lval.str = xstrdup(kwp->kw); - return kwp->token; - } - return kw_token(kw); -} - -static void addcchar(char c) -{ - if(cbufidx >= cbufalloc) - { - cbufalloc += 1024; - cbuffer = xrealloc(cbuffer, cbufalloc * sizeof(cbuffer[0])); - if(cbufalloc > 65536) - parser_warning("Reallocating string buffer larger than 64kB"); - } - cbuffer[cbufidx++] = c; -} - -static char *get_buffered_cstring(void) -{ - addcchar(0); - return xstrdup(cbuffer); -} - -static void pop_import(void) -{ - int ptr = import_stack_ptr-1; - - fclose(yyin); - yy_delete_buffer( YY_CURRENT_BUFFER ); - yy_switch_to_buffer( import_stack[ptr].state ); - if (temp_name) { - unlink(temp_name); - free(temp_name); - } - temp_name = import_stack[ptr].temp_name; - free( input_name ); - input_name = import_stack[ptr].input_name; - line_number = import_stack[ptr].line_number; - import_stack_ptr--; -} - -struct imports { - char *name; - struct imports *next; -} *first_import; - -int do_import(char *fname) -{ - FILE *f; - char *hname, *path, *p; - struct imports *import; - int ptr = import_stack_ptr; - int ret; - - if (!parse_only && do_header) { - hname = dup_basename(fname, ".idl"); - p = hname + strlen(hname) - 2; - if (p <= hname || strcmp( p, ".h" )) strcat(hname, ".h"); - - fprintf(header, "#include <%s>\n", hname); - free(hname); - } - - import = first_import; - while (import && strcmp(import->name, fname)) - import = import->next; - if (import) return 0; /* already imported */ - - import = xmalloc(sizeof(struct imports)); - import->name = xstrdup(fname); - import->next = first_import; - first_import = import; - - if (!(path = wpp_find_include( fname, input_name ))) - parser_error("Unable to open include file %s", fname); - - import_stack[ptr].temp_name = temp_name; - import_stack[ptr].input_name = input_name; - import_stack[ptr].line_number = line_number; - import_stack_ptr++; - input_name = path; - line_number = 1; - - ret = wpp_parse_temp( path, NULL, &temp_name ); - if (ret) exit(1); - - if((f = fopen(temp_name, "r")) == NULL) - parser_error("Unable to open %s", temp_name); - - import_stack[ptr].state = YY_CURRENT_BUFFER; - yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE)); - return 1; -} - -void abort_import(void) -{ - int ptr; - - for (ptr=0; ptr -#include -#include -#include -#include -#include -#ifdef HAVE_UNISTD_H -#include -#endif -#ifdef HAVE_SYS_TIME_H -#include -#endif -#ifdef HAVE_PROCESS_H -#include -#endif - -/* We need to provide a type for gcc_uint64_t. */ -#ifdef __GNUC__ -__extension__ typedef unsigned long long gcc_uint64_t; -#else -typedef unsigned long gcc_uint64_t; -#endif - -#ifndef TMP_MAX -#define TMP_MAX 16384 -#endif - -/* - -@deftypefn Replacement int mkstemps (char *@var{template}, int @var{suffix_len}) - -Generate a unique temporary file name from @var{template}. -@var{template} has the form: - -@example - @var{path}/ccXXXXXX@var{suffix} -@end example - -@var{suffix_len} tells us how long @var{suffix} is (it can be zero -length). The last six characters of @var{template} before @var{suffix} -must be @samp{XXXXXX}; they are replaced with a string that makes the -filename unique. Returns a file descriptor open on the file for -reading and writing. - -@end deftypefn - -*/ - -int -mkstemps ( - char *template, - int suffix_len) -{ - static const char letters[] - = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; - static gcc_uint64_t value; -#ifdef HAVE_GETTIMEOFDAY - struct timeval tv; -#endif - char *XXXXXX; - size_t len; - int count; - - len = strlen (template); - - if ((int) len < 6 + suffix_len - || strncmp (&template[len - 6 - suffix_len], "XXXXXX", 6)) - { - return -1; - } - - XXXXXX = &template[len - 6 - suffix_len]; - -#ifdef HAVE_GETTIMEOFDAY - /* Get some more or less random data. */ - gettimeofday (&tv, NULL); - value += ((gcc_uint64_t) tv.tv_usec << 16) ^ tv.tv_sec ^ getpid (); -#else - value += getpid (); -#endif - - for (count = 0; count < TMP_MAX; ++count) - { - gcc_uint64_t v = value; - int fd; - - /* Fill in the random bits. */ - XXXXXX[0] = letters[v % 62]; - v /= 62; - XXXXXX[1] = letters[v % 62]; - v /= 62; - XXXXXX[2] = letters[v % 62]; - v /= 62; - XXXXXX[3] = letters[v % 62]; - v /= 62; - XXXXXX[4] = letters[v % 62]; - v /= 62; - XXXXXX[5] = letters[v % 62]; - -#ifdef VMS - fd = open (template, O_RDWR|O_CREAT|O_EXCL, 0600, "fop=tmd"); -#else - fd = open (template, O_RDWR|O_CREAT|O_EXCL, 0600); -#endif - if (fd >= 0) - /* The file does not exist. */ - return fd; - - /* This is a random value. It is only necessary that the next - TMP_MAX values generated by adding 7777 to VALUE are different - with (module 2^32). */ - value += 7777; - } - - /* We return the null string if we can't find a unique file name. */ - template[0] = '\0'; - return -1; -} diff --git a/reactos/tools/widl_new/proxy.c b/reactos/tools/widl_new/proxy.c deleted file mode 100644 index 4911caf2b66..00000000000 --- a/reactos/tools/widl_new/proxy.c +++ /dev/null @@ -1,664 +0,0 @@ -/* - * IDL Compiler - * - * Copyright 2002 Ove Kaaven - * Copyright 2004 Mike McCormack - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" -#include "wine/port.h" - -#include -#include -#ifdef HAVE_UNISTD_H -# include -#endif -#include -#include -#include -#include - -#include "widl.h" -#include "utils.h" -#include "parser.h" -#include "header.h" -#include "typegen.h" - -#define END_OF_LIST(list) \ - do { \ - if (list) { \ - while (NEXT_LINK(list)) \ - list = NEXT_LINK(list); \ - } \ - } while(0) - -static FILE* proxy; -static int indent = 0; - -/* FIXME: support generation of stubless proxies */ - -static void print_proxy( const char *format, ... ) -{ - va_list va; - va_start( va, format ); - print( proxy, indent, format, va ); - va_end( va ); -} - -static void write_stubdescproto(void) -{ - print_proxy( "static const MIDL_STUB_DESC Object_StubDesc;\n"); - print_proxy( "\n"); -} - -static void write_stubdesc(void) -{ - print_proxy( "static const MIDL_STUB_DESC Object_StubDesc =\n{\n"); - indent++; - print_proxy( "0,\n"); - print_proxy( "NdrOleAllocate,\n"); - print_proxy( "NdrOleFree,\n"); - print_proxy( "{0}, 0, 0, 0, 0,\n"); - print_proxy( "__MIDL_TypeFormatString.Format,\n"); - print_proxy( "1, /* -error bounds_check flag */\n"); - print_proxy( "0x10001, /* Ndr library version */\n"); - print_proxy( "0,\n"); - print_proxy( "0x50100a4, /* MIDL Version 5.1.164 */\n"); - print_proxy( "0,\n"); - print_proxy("%s,\n", list_empty(&user_type_list) ? "0" : "UserMarshalRoutines"); - print_proxy( "0, /* notify & notify_flag routine table */\n"); - print_proxy( "1, /* Flags */\n"); - print_proxy( "0, /* Reserved3 */\n"); - print_proxy( "0, /* Reserved4 */\n"); - print_proxy( "0 /* Reserved5 */\n"); - indent--; - print_proxy( "};\n"); - print_proxy( "\n"); -} - -static void init_proxy(ifref_list_t *ifaces) -{ - if (proxy) return; - if(!(proxy = fopen(proxy_name, "w"))) - error("Could not open %s for output\n", proxy_name); - print_proxy( "/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n", PACKAGE_VERSION, input_name); - print_proxy( "\n"); - print_proxy( "#ifndef __REDQ_RPCPROXY_H_VERSION__\n"); - print_proxy( "#define __REQUIRED_RPCPROXY_H_VERSION__ 440\n"); - print_proxy( "#endif /* __REDQ_RPCPROXY_H_VERSION__ */\n"); - print_proxy( "\n"); - print_proxy( "#define __midl_proxy\n"); - print_proxy( "#include \"objbase.h\"\n"); - print_proxy( "#include \"rpcproxy.h\"\n"); - print_proxy( "#ifndef __RPCPROXY_H_VERSION__\n"); - print_proxy( "#error This code needs a newer version of rpcproxy.h\n"); - print_proxy( "#endif /* __RPCPROXY_H_VERSION__ */\n"); - print_proxy( "\n"); - print_proxy( "#include \"%s\"\n", header_name); - print_proxy( "\n"); - write_formatstringsdecl(proxy, indent, ifaces, 1); - write_stubdescproto(); -} - -static void clear_output_vars( const var_list_t *args ) -{ - const var_t *arg; - - if (!args) return; - LIST_FOR_EACH_ENTRY( arg, args, const var_t, entry ) - { - if (is_attr(arg->attrs, ATTR_OUT) && !is_attr(arg->attrs, ATTR_IN)) { - print_proxy( "if(%s)\n", arg->name ); - indent++; - print_proxy( "MIDL_memset( %s, 0, sizeof( *%s ));\n", arg->name, arg->name ); - indent--; - } - } -} - -int is_var_ptr(const var_t *v) -{ - return is_ptr(v->type); -} - -int cant_be_null(const var_t *v) -{ - /* Search backwards for the most recent pointer attribute. */ - const attr_list_t *attrs = v->attrs; - const type_t *type = v->type; - - if (! attrs && type) - { - attrs = type->attrs; - type = type->ref; - } - - while (attrs) - { - int t = get_attrv(attrs, ATTR_POINTERTYPE); - - if (t == RPC_FC_FP || t == RPC_FC_OP || t == RPC_FC_UP) - return 0; - - if (t == RPC_FC_RP) - return 1; - - if (type) - { - attrs = type->attrs; - type = type->ref; - } - else - attrs = NULL; - } - - return 1; /* Default is RPC_FC_RP. */ -} - -static void proxy_check_pointers( const var_list_t *args ) -{ - const var_t *arg; - - if (!args) return; - LIST_FOR_EACH_ENTRY( arg, args, const var_t, entry ) - { - if (is_var_ptr(arg) && cant_be_null(arg)) { - print_proxy( "if(!%s)\n", arg->name ); - indent++; - print_proxy( "RpcRaiseException(RPC_X_NULL_REF_POINTER);\n"); - indent--; - } - } -} - -static void free_variable( const var_t *arg ) -{ - unsigned int type_offset = arg->type->typestring_offset; - var_t *constraint; - type_t *type; - expr_list_t *expr; - - expr = get_attrp( arg->attrs, ATTR_SIZEIS ); - if (expr) - { - const expr_t *size = LIST_ENTRY( list_head(expr), const expr_t, entry ); - print_proxy( "_StubMsg.MaxCount = " ); - write_expr(proxy, size, 0); - fprintf(proxy, ";\n\n"); - print_proxy( "NdrClearOutParameters( &_StubMsg, "); - fprintf(proxy, "&__MIDL_TypeFormatString.Format[%u], ", type_offset ); - fprintf(proxy, "(void*)%s );\n", arg->name ); - return; - } - - type = arg->type; - switch( type->type ) - { - case RPC_FC_BYTE: - case RPC_FC_CHAR: - case RPC_FC_WCHAR: - case RPC_FC_SHORT: - case RPC_FC_USHORT: - case RPC_FC_ENUM16: - case RPC_FC_LONG: - case RPC_FC_ULONG: - case RPC_FC_ENUM32: - case RPC_FC_STRUCT: - break; - - case RPC_FC_FP: - case RPC_FC_IP: - constraint = get_attrp( arg->attrs, ATTR_IIDIS ); - if( constraint ) - print_proxy( "_StubMsg.MaxCount = (unsigned long) ( %s );\n",constraint->name); - print_proxy( "NdrClearOutParameters( &_StubMsg, "); - fprintf(proxy, "&__MIDL_TypeFormatString.Format[%u], ", type_offset ); - fprintf(proxy, "(void*)%s );\n", arg->name ); - break; - - default: - print_proxy("/* FIXME: %s code for %s type %d missing */\n", __FUNCTION__, arg->name, type->type ); - } -} - -static void proxy_free_variables( var_list_t *args ) -{ - const var_t *arg; - - if (!args) return; - LIST_FOR_EACH_ENTRY( arg, args, const var_t, entry ) - if (is_attr(arg->attrs, ATTR_OUT)) - { - free_variable( arg ); - fprintf(proxy, "\n"); - } -} - -static void gen_proxy(type_t *iface, const func_t *cur, int idx, - unsigned int proc_offset) -{ - var_t *def = cur->def; - int has_ret = !is_void(def->type); - - indent = 0; - write_type_left(proxy, def->type); - print_proxy( " STDMETHODCALLTYPE %s_", iface->name); - write_name(proxy, def); - print_proxy( "_Proxy(\n"); - write_args(proxy, cur->args, iface->name, 1, TRUE); - print_proxy( ")\n"); - print_proxy( "{\n"); - indent ++; - /* local variables */ - if (has_ret) { - print_proxy( "" ); - write_type_left(proxy, def->type); - print_proxy( " _RetVal;\n"); - } - print_proxy( "RPC_MESSAGE _RpcMessage;\n" ); - print_proxy( "MIDL_STUB_MESSAGE _StubMsg;\n" ); - print_proxy( "\n"); - - /* FIXME: trace */ - clear_output_vars( cur->args ); - - print_proxy( "RpcTryExcept\n" ); - print_proxy( "{\n" ); - indent++; - print_proxy( "NdrProxyInitialize(This, &_RpcMessage, &_StubMsg, &Object_StubDesc, %d);\n", idx); - proxy_check_pointers( cur->args ); - - print_proxy( "RpcTryFinally\n" ); - print_proxy( "{\n" ); - indent++; - - write_remoting_arguments(proxy, indent, cur, PASS_IN, PHASE_BUFFERSIZE); - - print_proxy( "NdrProxyGetBuffer(This, &_StubMsg);\n" ); - - write_remoting_arguments(proxy, indent, cur, PASS_IN, PHASE_MARSHAL); - - print_proxy( "NdrProxySendReceive(This, &_StubMsg);\n" ); - fprintf(proxy, "\n"); - print_proxy( "_StubMsg.BufferStart = _RpcMessage.Buffer;\n" ); - print_proxy( "_StubMsg.BufferEnd = _StubMsg.BufferStart + _RpcMessage.BufferLength;\n\n" ); - - print_proxy("if ((_RpcMessage.DataRepresentation & 0xffff) != NDR_LOCAL_DATA_REPRESENTATION)\n"); - indent++; - print_proxy("NdrConvert( &_StubMsg, &__MIDL_ProcFormatString.Format[%u]);\n", proc_offset ); - indent--; - fprintf(proxy, "\n"); - - write_remoting_arguments(proxy, indent, cur, PASS_OUT, PHASE_UNMARSHAL); - - if (has_ret) - print_phase_basetype(proxy, indent, PHASE_UNMARSHAL, PASS_RETURN, def, "_RetVal"); - - indent--; - print_proxy( "}\n"); - print_proxy( "RpcFinally\n" ); - print_proxy( "{\n" ); - indent++; - print_proxy( "NdrProxyFreeBuffer(This, &_StubMsg);\n" ); - indent--; - print_proxy( "}\n"); - print_proxy( "RpcEndFinally\n" ); - indent--; - print_proxy( "}\n" ); - print_proxy( "RpcExcept(_StubMsg.dwStubPhase != PROXY_SENDRECEIVE)\n" ); - print_proxy( "{\n" ); - if (has_ret) { - indent++; - proxy_free_variables( cur->args ); - print_proxy( "_RetVal = NdrProxyErrorHandler(RpcExceptionCode());\n" ); - indent--; - } - print_proxy( "}\n" ); - print_proxy( "RpcEndExcept\n" ); - - if (has_ret) { - print_proxy( "return _RetVal;\n" ); - } - indent--; - print_proxy( "}\n"); - print_proxy( "\n"); -} - -static void gen_stub(type_t *iface, const func_t *cur, const char *cas, - unsigned int proc_offset) -{ - var_t *def = cur->def; - const var_t *arg; - int has_ret = !is_void(def->type); - - indent = 0; - print_proxy( "void __RPC_STUB %s_", iface->name); - write_name(proxy, def); - print_proxy( "_Stub(\n"); - indent++; - print_proxy( "IRpcStubBuffer* This,\n"); - print_proxy( "IRpcChannelBuffer *_pRpcChannelBuffer,\n"); - print_proxy( "PRPC_MESSAGE _pRpcMessage,\n"); - print_proxy( "DWORD* _pdwStubPhase)\n"); - indent--; - print_proxy( "{\n"); - indent++; - print_proxy("%s * _This = (%s*)((CStdStubBuffer*)This)->pvServerObject;\n", iface->name, iface->name); - print_proxy("MIDL_STUB_MESSAGE _StubMsg;\n"); - declare_stub_args( proxy, indent, cur ); - fprintf(proxy, "\n"); - - /* FIXME: trace */ - - print_proxy("NdrStubInitialize(_pRpcMessage, &_StubMsg, &Object_StubDesc, _pRpcChannelBuffer);\n"); - fprintf(proxy, "\n"); - - write_parameters_init(proxy, indent, cur); - - print_proxy("RpcTryFinally\n"); - print_proxy("{\n"); - indent++; - print_proxy("if ((_pRpcMessage->DataRepresentation & 0xffff) != NDR_LOCAL_DATA_REPRESENTATION)\n"); - indent++; - print_proxy("NdrConvert( &_StubMsg, &__MIDL_ProcFormatString.Format[%u]);\n", proc_offset ); - indent--; - fprintf(proxy, "\n"); - - write_remoting_arguments(proxy, indent, cur, PASS_IN, PHASE_UNMARSHAL); - fprintf(proxy, "\n"); - - assign_stub_out_args( proxy, indent, cur ); - - print_proxy("*_pdwStubPhase = STUB_CALL_SERVER;\n"); - fprintf(proxy, "\n"); - print_proxy(""); - if (has_ret) fprintf(proxy, "_RetVal = "); - if (cas) fprintf(proxy, "%s_%s_Stub", iface->name, cas); - else - { - fprintf(proxy, "_This->lpVtbl->"); - write_name(proxy, def); - } - fprintf(proxy, "(_This"); - - if (cur->args) - { - LIST_FOR_EACH_ENTRY( arg, cur->args, const var_t, entry ) - { - fprintf(proxy, ", "); - if (arg->type->declarray) - fprintf(proxy, "*"); - write_name(proxy, arg); - } - } - fprintf(proxy, ");\n"); - fprintf(proxy, "\n"); - print_proxy("*_pdwStubPhase = STUB_MARSHAL;\n"); - fprintf(proxy, "\n"); - - write_remoting_arguments(proxy, indent, cur, PASS_OUT, PHASE_BUFFERSIZE); - - print_proxy("NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg);\n"); - - write_remoting_arguments(proxy, indent, cur, PASS_OUT, PHASE_MARSHAL); - fprintf(proxy, "\n"); - - if (has_ret) - print_phase_basetype(proxy, indent, PHASE_MARSHAL, PASS_RETURN, def, "_RetVal"); - - indent--; - print_proxy("}\n"); - print_proxy("RpcFinally\n"); - print_proxy("{\n"); - - write_remoting_arguments(proxy, indent+1, cur, PASS_OUT, PHASE_FREE); - - print_proxy("}\n"); - print_proxy("RpcEndFinally\n"); - - print_proxy("_pRpcMessage->BufferLength = _StubMsg.Buffer - (unsigned char *)_pRpcMessage->Buffer;\n"); - indent--; - - print_proxy("}\n"); - print_proxy("\n"); -} - -static int write_proxy_methods(type_t *iface) -{ - const func_t *cur; - int i = 0; - - if (iface->ref) i = write_proxy_methods(iface->ref); - if (iface->funcs) LIST_FOR_EACH_ENTRY( cur, iface->funcs, const func_t, entry ) { - var_t *def = cur->def; - if (!is_callas(def->attrs)) { - if (i) fprintf(proxy, ",\n"); - print_proxy( "%s_", iface->name); - write_name(proxy, def); - fprintf(proxy, "_Proxy"); - i++; - } - } - return i; -} - -static int write_stub_methods(type_t *iface) -{ - const func_t *cur; - int i = 0; - - if (iface->ref) i = write_stub_methods(iface->ref); - else return i; /* skip IUnknown */ - - if (iface->funcs) LIST_FOR_EACH_ENTRY( cur, iface->funcs, const func_t, entry ) { - var_t *def = cur->def; - if (!is_local(def->attrs)) { - if (i) fprintf(proxy,",\n"); - print_proxy( "%s_", iface->name); - write_name(proxy, def); - fprintf(proxy, "_Stub"); - i++; - } - } - return i; -} - -static void write_proxy(type_t *iface, unsigned int *proc_offset) -{ - int midx = -1, stubs; - const func_t *cur; - - if (!iface->funcs) return; - - /* FIXME: check for [oleautomation], shouldn't generate proxies/stubs if specified */ - - fprintf(proxy, "/*****************************************************************************\n"); - fprintf(proxy, " * %s interface\n", iface->name); - fprintf(proxy, " */\n"); - LIST_FOR_EACH_ENTRY( cur, iface->funcs, const func_t, entry ) - { - const var_t *def = cur->def; - if (!is_local(def->attrs)) { - const var_t *cas = is_callas(def->attrs); - const char *cname = cas ? cas->name : NULL; - int idx = cur->idx; - if (cname) { - const func_t *m; - LIST_FOR_EACH_ENTRY( m, iface->funcs, const func_t, entry ) - if (!strcmp(m->def->name, cname)) - { - idx = m->idx; - break; - } - } - gen_proxy(iface, cur, idx, *proc_offset); - gen_stub(iface, cur, cname, *proc_offset); - *proc_offset += get_size_procformatstring_func( cur ); - if (midx == -1) midx = idx; - else if (midx != idx) parser_error("method index mismatch in write_proxy"); - midx++; - } - } - - /* proxy vtable */ - print_proxy( "static const CINTERFACE_PROXY_VTABLE(%d) _%sProxyVtbl =\n", midx, iface->name); - print_proxy( "{\n"); - indent++; - print_proxy( "{\n", iface->name); - indent++; - print_proxy( "&IID_%s,\n", iface->name); - indent--; - print_proxy( "},\n"); - print_proxy( "{\n"); - indent++; - write_proxy_methods(iface); - fprintf(proxy, "\n"); - indent--; - print_proxy( "}\n"); - indent--; - print_proxy( "};\n"); - fprintf(proxy, "\n\n"); - - /* stub vtable */ - print_proxy( "static const PRPC_STUB_FUNCTION %s_table[] =\n", iface->name); - print_proxy( "{\n"); - indent++; - stubs = write_stub_methods(iface); - fprintf(proxy, "\n"); - indent--; - fprintf(proxy, "};\n"); - print_proxy( "\n"); - print_proxy( "static const CInterfaceStubVtbl _%sStubVtbl =\n", iface->name); - print_proxy( "{\n"); - indent++; - print_proxy( "{\n"); - indent++; - print_proxy( "&IID_%s,\n", iface->name); - print_proxy( "0,\n"); - print_proxy( "%d,\n", stubs+3); - print_proxy( "&%s_table[-3],\n", iface->name); - indent--; - print_proxy( "},\n", iface->name); - print_proxy( "{\n"); - indent++; - print_proxy( "CStdStubBuffer_METHODS\n"); - indent--; - print_proxy( "}\n"); - indent--; - print_proxy( "};\n"); - print_proxy( "\n"); -} - -void write_proxies(ifref_list_t *ifaces) -{ - ifref_t *cur; - char *file_id = proxy_token; - int c; - unsigned int proc_offset = 0; - - if (!do_proxies) return; - if (do_everything && !ifaces) return; - - init_proxy(ifaces); - if(!proxy) return; - - if (ifaces) - LIST_FOR_EACH_ENTRY( cur, ifaces, ifref_t, entry ) - if (is_object(cur->iface->attrs) && !is_local(cur->iface->attrs)) - write_proxy(cur->iface, &proc_offset); - - write_user_quad_list(proxy); - write_stubdesc(); - - print_proxy( "#if !defined(__RPC_WIN32__)\n"); - print_proxy( "#error Currently only Wine and WIN32 are supported.\n"); - print_proxy( "#endif\n"); - print_proxy( "\n"); - write_procformatstring(proxy, ifaces, 1); - write_typeformatstring(proxy, ifaces, 1); - - fprintf(proxy, "static const CInterfaceProxyVtbl* const _%s_ProxyVtblList[] =\n", file_id); - fprintf(proxy, "{\n"); - if (ifaces) - LIST_FOR_EACH_ENTRY( cur, ifaces, ifref_t, entry ) - if(cur->iface->ref && cur->iface->funcs && - is_object(cur->iface->attrs) && !is_local(cur->iface->attrs)) - fprintf(proxy, " (const CInterfaceProxyVtbl*)&_%sProxyVtbl,\n", cur->iface->name); - - fprintf(proxy, " 0\n"); - fprintf(proxy, "};\n"); - fprintf(proxy, "\n"); - - fprintf(proxy, "static const CInterfaceStubVtbl* const _%s_StubVtblList[] =\n", file_id); - fprintf(proxy, "{\n"); - if (ifaces) - LIST_FOR_EACH_ENTRY( cur, ifaces, ifref_t, entry ) - if(cur->iface->ref && cur->iface->funcs && - is_object(cur->iface->attrs) && !is_local(cur->iface->attrs)) - fprintf(proxy, " (const CInterfaceStubVtbl*)&_%sStubVtbl,\n", cur->iface->name); - fprintf(proxy, " 0\n"); - fprintf(proxy, "};\n"); - fprintf(proxy, "\n"); - - fprintf(proxy, "static PCInterfaceName const _%s_InterfaceNamesList[] =\n", file_id); - fprintf(proxy, "{\n"); - if (ifaces) - LIST_FOR_EACH_ENTRY( cur, ifaces, ifref_t, entry ) - if(cur->iface->ref && cur->iface->funcs && - is_object(cur->iface->attrs) && !is_local(cur->iface->attrs)) - fprintf(proxy, " \"%s\",\n", cur->iface->name); - fprintf(proxy, " 0\n"); - fprintf(proxy, "};\n"); - fprintf(proxy, "\n"); - - fprintf(proxy, "#define _%s_CHECK_IID(n) IID_GENERIC_CHECK_IID(_%s, pIID, n)\n", file_id, file_id); - fprintf(proxy, "\n"); - fprintf(proxy, "int __stdcall _%s_IID_Lookup(const IID* pIID, int* pIndex)\n", file_id); - fprintf(proxy, "{\n"); - c = 0; - if (ifaces) - LIST_FOR_EACH_ENTRY( cur, ifaces, ifref_t, entry ) - if(cur->iface->ref) - { - fprintf(proxy, " if (!_%s_CHECK_IID(%d))\n", file_id, c); - fprintf(proxy, " {\n"); - fprintf(proxy, " *pIndex = %d;\n", c); - fprintf(proxy, " return 1;\n"); - fprintf(proxy, " }\n"); - c++; - } - fprintf(proxy, " return 0;\n"); - fprintf(proxy, "}\n"); - fprintf(proxy, "\n"); - - fprintf(proxy, "const ExtendedProxyFileInfo %s_ProxyFileInfo =\n", file_id); - fprintf(proxy, "{\n"); - fprintf(proxy, " (const PCInterfaceProxyVtblList*)&_%s_ProxyVtblList,\n", file_id); - fprintf(proxy, " (const PCInterfaceStubVtblList*)&_%s_StubVtblList,\n", file_id); - fprintf(proxy, " _%s_InterfaceNamesList,\n", file_id); - fprintf(proxy, " 0,\n"); - fprintf(proxy, " &_%s_IID_Lookup,\n", file_id); - fprintf(proxy, " %d,\n", c); - fprintf(proxy, " 1,\n"); - fprintf(proxy, " 0,\n"); - fprintf(proxy, " 0,\n"); - fprintf(proxy, " 0,\n"); - fprintf(proxy, " 0\n"); - fprintf(proxy, "};\n"); - - fclose(proxy); -} diff --git a/reactos/tools/widl_new/server.c b/reactos/tools/widl_new/server.c deleted file mode 100644 index 673c93bf516..00000000000 --- a/reactos/tools/widl_new/server.c +++ /dev/null @@ -1,448 +0,0 @@ -/* - * IDL Compiler - * - * Copyright 2005-2006 Eric Kohl - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" -#include "wine/port.h" - -#include -#include -#ifdef HAVE_UNISTD_H -# include -#endif -#include -#include -#include -#include - -#include "widl.h" -#include "utils.h" -#include "parser.h" -#include "header.h" -#include "windef.h" - -#include "widl.h" -#include "typelib.h" -#include "typelib_struct.h" -#include "typegen.h" - -static FILE* server; -static int indent = 0; - - -static void print_server(const char *format, ...) -{ - va_list va; - va_start(va, format); - print(server, indent, format, va); - va_end(va); -} - -static void write_function_stubs(type_t *iface, unsigned int *proc_offset) -{ - char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE); - int explicit_handle = is_attr(iface->attrs, ATTR_EXPLICIT_HANDLE); - const func_t *func; - const var_t *var; - const var_t* explicit_handle_var; - - if (!iface->funcs) return; - LIST_FOR_EACH_ENTRY( func, iface->funcs, const func_t, entry ) - { - const var_t *def = func->def; - - /* check for a defined binding handle */ - explicit_handle_var = get_explicit_handle_var(func); - if (explicit_handle) - { - if (!explicit_handle_var) - { - error("%s() does not define an explicit binding handle!\n", def->name); - return; - } - } - else if (implicit_handle) - { - if (explicit_handle_var) - { - error("%s() must not define a binding handle!\n", def->name); - return; - } - } - - fprintf(server, "void __RPC_STUB\n"); - fprintf(server, "%s_", iface->name); - write_name(server, def); - fprintf(server, "(\n"); - indent++; - print_server("PRPC_MESSAGE _pRpcMessage)\n"); - indent--; - - /* write the functions body */ - fprintf(server, "{\n"); - indent++; - - /* Declare arguments */ - declare_stub_args(server, indent, func); - - print_server("MIDL_STUB_MESSAGE _StubMsg;\n"); - print_server("RPC_STATUS _Status;\n"); - fprintf(server, "\n"); - - - print_server("((void)(_Status));\n"); - print_server("NdrServerInitializeNew(\n"); - indent++; - print_server("_pRpcMessage,\n"); - print_server("&_StubMsg,\n"); - print_server("&%s_StubDesc);\n", iface->name); - indent--; - fprintf(server, "\n"); - - write_parameters_init(server, indent, func); - - if (explicit_handle_var) - { - print_server("%s = _pRpcMessage->Handle;\n", explicit_handle_var->name); - fprintf(server, "\n"); - } - - print_server("RpcTryFinally\n"); - print_server("{\n"); - indent++; - print_server("RpcTryExcept\n"); - print_server("{\n"); - indent++; - - if (func->args) - { - print_server("if ((_pRpcMessage->DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION)\n"); - indent++; - print_server("NdrConvert(\n"); - indent++; - print_server("(PMIDL_STUB_MESSAGE)&_StubMsg,\n"); - print_server("(PFORMAT_STRING)&__MIDL_ProcFormatString.Format[%u]);\n", *proc_offset); - indent -= 2; - fprintf(server, "\n"); - - /* unmarshall arguments */ - write_remoting_arguments(server, indent, func, PASS_IN, PHASE_UNMARSHAL); - } - - print_server("if (_StubMsg.Buffer > _StubMsg.BufferEnd)\n"); - print_server("{\n"); - indent++; - print_server("RpcRaiseException(RPC_X_BAD_STUB_DATA);\n"); - indent--; - print_server("}\n"); - indent--; - print_server("}\n"); - print_server("RpcExcept(RPC_BAD_STUB_DATA_EXCEPTION_FILTER)\n"); - print_server("{\n"); - indent++; - print_server("RpcRaiseException(RPC_X_BAD_STUB_DATA);\n"); - indent--; - print_server("}\n"); - print_server("RpcEndExcept\n"); - fprintf(server, "\n"); - - /* Assign 'out' arguments */ - assign_stub_out_args(server, indent, func); - - /* Call the real server function */ - if (!is_void(def->type)) - print_server("_RetVal = "); - else - print_server(""); - write_prefix_name(server, prefix_server, def); - - if (func->args) - { - int first_arg = 1; - - fprintf(server, "(\n"); - indent++; - LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) - { - if (first_arg) - first_arg = 0; - else - fprintf(server, ",\n"); - print_server(""); - if (var->type->declarray) - fprintf(server, "*"); - write_name(server, var); - } - fprintf(server, ");\n"); - indent--; - } - else - { - fprintf(server, "();\n"); - } - - if (has_out_arg_or_return(func)) - { - write_remoting_arguments(server, indent, func, PASS_OUT, PHASE_BUFFERSIZE); - - print_server("_pRpcMessage->BufferLength = _StubMsg.BufferLength;\n"); - fprintf(server, "\n"); - print_server("_Status = I_RpcGetBuffer(_pRpcMessage);\n"); - print_server("if (_Status)\n"); - indent++; - print_server("RpcRaiseException(_Status);\n"); - indent--; - fprintf(server, "\n"); - print_server("_StubMsg.Buffer = (unsigned char *)_pRpcMessage->Buffer;\n"); - fprintf(server, "\n"); - } - - /* marshall arguments */ - write_remoting_arguments(server, indent, func, PASS_OUT, PHASE_MARSHAL); - - /* marshall the return value */ - if (!is_void(def->type)) - print_phase_basetype(server, indent, PHASE_MARSHAL, PASS_RETURN, def, "_RetVal"); - - indent--; - print_server("}\n"); - print_server("RpcFinally\n"); - print_server("{\n"); - indent++; - - write_remoting_arguments(server, indent, func, PASS_OUT, PHASE_FREE); - - indent--; - print_server("}\n"); - print_server("RpcEndFinally\n"); - - /* calculate buffer length */ - fprintf(server, "\n"); - print_server("_pRpcMessage->BufferLength =\n"); - indent++; - print_server("(unsigned int)(_StubMsg.Buffer - (unsigned char *)_pRpcMessage->Buffer);\n"); - indent--; - indent--; - fprintf(server, "}\n"); - fprintf(server, "\n"); - - /* update proc_offset */ - *proc_offset += get_size_procformatstring_func( func ); - } -} - - -static void write_dispatchtable(type_t *iface) -{ - unsigned long ver = get_attrv(iface->attrs, ATTR_VERSION); - unsigned long method_count = 0; - const func_t *func; - - print_server("static RPC_DISPATCH_FUNCTION %s_table[] =\n", iface->name); - print_server("{\n"); - indent++; - - if (iface->funcs) LIST_FOR_EACH_ENTRY( func, iface->funcs, const func_t, entry ) - { - var_t *def = func->def; - - print_server("%s_", iface->name); - write_name(server, def); - fprintf(server, ",\n"); - - method_count++; - } - print_server("0\n"); - indent--; - print_server("};\n"); - print_server("RPC_DISPATCH_TABLE %s_v%d_%d_DispatchTable =\n", iface->name, LOWORD(ver), HIWORD(ver)); - print_server("{\n"); - indent++; - print_server("%u,\n", method_count); - print_server("%s_table\n", iface->name); - indent--; - print_server("};\n"); - fprintf(server, "\n"); -} - - -static void write_stubdescdecl(type_t *iface) -{ - print_server("static const MIDL_STUB_DESC %s_StubDesc;\n", iface->name); - fprintf(server, "\n"); -} - - -static void write_stubdescriptor(type_t *iface, int expr_eval_routines) -{ - print_server("static const MIDL_STUB_DESC %s_StubDesc =\n", iface->name); - print_server("{\n"); - indent++; - print_server("(void *)& %s___RpcServerInterface,\n", iface->name); - print_server("MIDL_user_allocate,\n"); - print_server("MIDL_user_free,\n"); - print_server("{\n"); - indent++; - print_server("0,\n"); - indent--; - print_server("},\n"); - print_server("0,\n"); - print_server("0,\n"); - if (expr_eval_routines) - print_server("ExprEvalRoutines,\n"); - else - print_server("0,\n"); - print_server("0,\n"); - print_server("__MIDL_TypeFormatString.Format,\n"); - print_server("1, /* -error bounds_check flag */\n"); - print_server("0x10001, /* Ndr library version */\n"); - print_server("0,\n"); - print_server("0x50100a4, /* MIDL Version 5.1.164 */\n"); - print_server("0,\n"); - print_server("%s,\n", list_empty(&user_type_list) ? "0" : "UserMarshalRoutines"); - print_server("0, /* notify & notify_flag routine table */\n"); - print_server("1, /* Flags */\n"); - print_server("0, /* Reserved3 */\n"); - print_server("0, /* Reserved4 */\n"); - print_server("0 /* Reserved5 */\n"); - indent--; - print_server("};\n"); - fprintf(server, "\n"); -} - - -static void write_serverinterfacedecl(type_t *iface) -{ - unsigned long ver = get_attrv(iface->attrs, ATTR_VERSION); - UUID *uuid = get_attrp(iface->attrs, ATTR_UUID); - const str_list_t *endpoints = get_attrp(iface->attrs, ATTR_ENDPOINT); - - if (endpoints) write_endpoints( server, iface->name, endpoints ); - - print_server("extern RPC_DISPATCH_TABLE %s_v%d_%d_DispatchTable;\n", iface->name, LOWORD(ver), HIWORD(ver)); - fprintf(server, "\n"); - print_server("static const RPC_SERVER_INTERFACE %s___RpcServerInterface =\n", iface->name ); - print_server("{\n"); - indent++; - print_server("sizeof(RPC_SERVER_INTERFACE),\n"); - print_server("{{0x%08lx,0x%04x,0x%04x,{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x}},{%d,%d}},\n", - uuid->Data1, uuid->Data2, uuid->Data3, uuid->Data4[0], uuid->Data4[1], - uuid->Data4[2], uuid->Data4[3], uuid->Data4[4], uuid->Data4[5], uuid->Data4[6], - uuid->Data4[7], LOWORD(ver), HIWORD(ver)); - print_server("{{0x8a885d04,0x1ceb,0x11c9,{0x9f,0xe8,0x08,0x00,0x2b,0x10,0x48,0x60}},{2,0}},\n"); /* FIXME */ - print_server("&%s_v%d_%d_DispatchTable,\n", iface->name, LOWORD(ver), HIWORD(ver)); - if (endpoints) - { - print_server("%u,\n", list_count(endpoints)); - print_server("(PRPC_PROTSEQ_ENDPOINT)%s__RpcProtseqEndpoint,\n", iface->name); - } - else - { - print_server("0,\n"); - print_server("0,\n"); - } - print_server("0,\n"); - print_server("0,\n"); - print_server("0,\n"); - indent--; - print_server("};\n"); - if (old_names) - print_server("RPC_IF_HANDLE %s_ServerIfHandle = (RPC_IF_HANDLE)& %s___RpcServerInterface;\n", - iface->name, iface->name); - else - print_server("RPC_IF_HANDLE %s%s_v%d_%d_s_ifspec = (RPC_IF_HANDLE)& %s___RpcServerInterface;\n", - prefix_server, iface->name, LOWORD(ver), HIWORD(ver), iface->name); - fprintf(server, "\n"); -} - - -static void init_server(void) -{ - if (server) - return; - if (!(server = fopen(server_name, "w"))) - error("Could not open %s for output\n", server_name); - - print_server("/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n", PACKAGE_VERSION, input_name); - print_server("#include \n"); - fprintf(server, "\n"); - print_server("#define _SEH_NO_NATIVE_NLG\n"); - print_server("#include \"%s\"\n", header_name); - fprintf(server, "\n"); -} - - -void write_server(ifref_list_t *ifaces) -{ - unsigned int proc_offset = 0; - ifref_t *iface; - - if (!do_server) - return; - if (do_everything && !ifaces) - return; - - init_server(); - if (!server) - return; - - write_formatstringsdecl(server, indent, ifaces, 0); - - if (ifaces) LIST_FOR_EACH_ENTRY( iface, ifaces, ifref_t, entry ) - { - if (is_object(iface->iface->attrs) || is_local(iface->iface->attrs)) - continue; - - fprintf(server, "/*****************************************************************************\n"); - fprintf(server, " * %s interface\n", iface->iface->name); - fprintf(server, " */\n"); - fprintf(server, "\n"); - - if (iface->iface->funcs) - { - int expr_eval_routines; - - write_serverinterfacedecl(iface->iface); - write_stubdescdecl(iface->iface); - - write_function_stubs(iface->iface, &proc_offset); - - print_server("#if !defined(__RPC_WIN32__)\n"); - print_server("#error Invalid build platform for this stub.\n"); - print_server("#endif\n"); - - fprintf(server, "\n"); - - expr_eval_routines = write_expr_eval_routines(server, iface->iface->name); - if (expr_eval_routines) - write_expr_eval_routine_list(server, iface->iface->name); - - write_user_quad_list(server); - write_stubdescriptor(iface->iface, expr_eval_routines); - write_dispatchtable(iface->iface); - } - } - - fprintf(server, "\n"); - - write_procformatstring(server, ifaces, 0); - write_typeformatstring(server, ifaces, 0); - - fclose(server); -} diff --git a/reactos/tools/widl_new/typegen.c b/reactos/tools/widl_new/typegen.c deleted file mode 100644 index 3b1030a384b..00000000000 --- a/reactos/tools/widl_new/typegen.c +++ /dev/null @@ -1,2973 +0,0 @@ -/* - * Format String Generator for IDL Compiler - * - * Copyright 2005-2006 Eric Kohl - * Copyright 2005-2006 Robert Shearman - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" -#include "wine/port.h" - -#include -#include -#ifdef HAVE_UNISTD_H -# include -#endif -#include -#include -#include -#include -#include - -#include "widl.h" -#include "utils.h" -#include "parser.h" -#include "header.h" -#include "windef.h" -#include "wine/list.h" - -#include "widl.h" -#include "typegen.h" - -static const func_t *current_func; -static const type_t *current_structure; - -static struct list expr_eval_routines = LIST_INIT(expr_eval_routines); -struct expr_eval_routine -{ - struct list entry; - const type_t *structure; - const expr_t *expr; -}; - -static size_t fields_memsize(const var_list_t *fields, unsigned int *align); -static size_t write_struct_tfs(FILE *file, type_t *type, const char *name, unsigned int *tfsoff); -static int write_embedded_types(FILE *file, const attr_list_t *attrs, type_t *type, - const char *name, int write_ptr, unsigned int *tfsoff); - -const char *string_of_type(unsigned char type) -{ - switch (type) - { - case RPC_FC_BYTE: return "FC_BYTE"; - case RPC_FC_CHAR: return "FC_CHAR"; - case RPC_FC_SMALL: return "FC_SMALL"; - case RPC_FC_USMALL: return "FC_USMALL"; - case RPC_FC_WCHAR: return "FC_WCHAR"; - case RPC_FC_SHORT: return "FC_SHORT"; - case RPC_FC_USHORT: return "FC_USHORT"; - case RPC_FC_LONG: return "FC_LONG"; - case RPC_FC_ULONG: return "FC_ULONG"; - case RPC_FC_FLOAT: return "FC_FLOAT"; - case RPC_FC_HYPER: return "FC_HYPER"; - case RPC_FC_DOUBLE: return "FC_DOUBLE"; - case RPC_FC_ENUM16: return "FC_ENUM16"; - case RPC_FC_ENUM32: return "FC_ENUM32"; - case RPC_FC_IGNORE: return "FC_IGNORE"; - case RPC_FC_ERROR_STATUS_T: return "FC_ERROR_STATUS_T"; - case RPC_FC_RP: return "FC_RP"; - case RPC_FC_UP: return "FC_UP"; - case RPC_FC_OP: return "FC_OP"; - case RPC_FC_FP: return "FC_FP"; - case RPC_FC_ENCAPSULATED_UNION: return "FC_ENCAPSULATED_UNION"; - case RPC_FC_NON_ENCAPSULATED_UNION: return "FC_NON_ENCAPSULATED_UNION"; - case RPC_FC_STRUCT: return "FC_STRUCT"; - case RPC_FC_PSTRUCT: return "FC_PSTRUCT"; - case RPC_FC_CSTRUCT: return "FC_CSTRUCT"; - case RPC_FC_CPSTRUCT: return "FC_CPSTRUCT"; - case RPC_FC_CVSTRUCT: return "FC_CVSTRUCT"; - case RPC_FC_BOGUS_STRUCT: return "FC_BOGUS_STRUCT"; - case RPC_FC_SMFARRAY: return "FC_SMFARRAY"; - case RPC_FC_LGFARRAY: return "FC_LGFARRAY"; - case RPC_FC_SMVARRAY: return "FC_SMVARRAY"; - case RPC_FC_LGVARRAY: return "FC_LGVARRAY"; - case RPC_FC_CARRAY: return "FC_CARRAY"; - case RPC_FC_CVARRAY: return "FC_CVARRAY"; - case RPC_FC_BOGUS_ARRAY: return "FC_BOGUS_ARRAY"; - case RPC_FC_ALIGNM4: return "RPC_FC_ALIGNM4"; - case RPC_FC_ALIGNM8: return "RPC_FC_ALIGNM8"; - default: - error("string_of_type: unknown type 0x%02x\n", type); - return NULL; - } -} - -int is_struct(unsigned char type) -{ - switch (type) - { - case RPC_FC_STRUCT: - case RPC_FC_PSTRUCT: - case RPC_FC_CSTRUCT: - case RPC_FC_CPSTRUCT: - case RPC_FC_CVSTRUCT: - case RPC_FC_BOGUS_STRUCT: - return 1; - default: - return 0; - } -} - -static int is_non_complex_struct(const type_t *type) -{ - switch (type->type) - { - case RPC_FC_STRUCT: - case RPC_FC_PSTRUCT: - case RPC_FC_CSTRUCT: - case RPC_FC_CPSTRUCT: - case RPC_FC_CVSTRUCT: - return 1; - default: - return 0; - } -} - -int is_union(unsigned char type) -{ - switch (type) - { - case RPC_FC_ENCAPSULATED_UNION: - case RPC_FC_NON_ENCAPSULATED_UNION: - return 1; - default: - return 0; - } -} - -static unsigned short user_type_offset(const char *name) -{ - user_type_t *ut; - unsigned short off = 0; - LIST_FOR_EACH_ENTRY(ut, &user_type_list, user_type_t, entry) - { - if (strcmp(name, ut->name) == 0) - return off; - ++off; - } - error("user_type_offset: couldn't find type (%s)\n", name); - return 0; -} - -static void update_tfsoff(type_t *type, unsigned int offset, FILE *file) -{ - type->typestring_offset = offset; - if (file) type->tfswrite = FALSE; -} - -static void guard_rec(type_t *type) -{ - /* types that contain references to themselves (like a linked list), - need to be shielded from infinite recursion when writing embedded - types */ - if (type->typestring_offset) - type->tfswrite = FALSE; - else - type->typestring_offset = 1; -} - -static type_t *get_user_type(const type_t *t, const char **pname) -{ - for (;;) - { - type_t *ut = get_attrp(t->attrs, ATTR_WIREMARSHAL); - if (ut) - { - if (pname) - *pname = t->name; - return ut; - } - - if (t->kind == TKIND_ALIAS) - t = t->orig; - else - return 0; - } -} - -static int is_user_type(const type_t *t) -{ - return get_user_type(t, NULL) != NULL; -} - -static int is_embedded_complex(const type_t *type) -{ - unsigned char tc = type->type; - return is_struct(tc) || is_union(tc) || is_array(type) || is_user_type(type) - || (is_ptr(type) && type->ref->type == RPC_FC_IP); -} - -static int compare_expr(const expr_t *a, const expr_t *b) -{ - int ret; - - if (a->type != b->type) - return a->type - b->type; - - switch (a->type) - { - case EXPR_NUM: - case EXPR_HEXNUM: - case EXPR_TRUEFALSE: - return a->u.lval - b->u.lval; - case EXPR_DOUBLE: - return a->u.dval - b->u.dval; - case EXPR_IDENTIFIER: - return strcmp(a->u.sval, b->u.sval); - case EXPR_COND: - ret = compare_expr(a->ref, b->ref); - if (ret != 0) - return ret; - ret = compare_expr(a->u.ext, b->u.ext); - if (ret != 0) - return ret; - return compare_expr(a->ext2, b->ext2); - case EXPR_OR: - case EXPR_AND: - case EXPR_ADD: - case EXPR_SUB: - case EXPR_MUL: - case EXPR_DIV: - case EXPR_SHL: - case EXPR_SHR: - ret = compare_expr(a->ref, b->ref); - if (ret != 0) - return ret; - return compare_expr(a->u.ext, b->u.ext); - case EXPR_NOT: - case EXPR_NEG: - case EXPR_PPTR: - case EXPR_CAST: - case EXPR_SIZEOF: - return compare_expr(a->ref, b->ref); - case EXPR_VOID: - return 0; - } - return -1; -} - -#define WRITE_FCTYPE(file, fctype, typestring_offset) \ - do { \ - if (file) \ - fprintf(file, "/* %2u */\n", typestring_offset); \ - print_file((file), 2, "0x%02x, /* " #fctype " */\n", RPC_##fctype); \ - } \ - while (0) - -static void print_file(FILE *file, int indent, const char *format, ...) -{ - va_list va; - va_start(va, format); - print(file, indent, format, va); - va_end(va); -} - -void print(FILE *file, int indent, const char *format, va_list va) -{ - if (file) - { - if (format[0] != '\n') - while (0 < indent--) - fprintf(file, " "); - vfprintf(file, format, va); - } -} - -void write_parameters_init(FILE *file, int indent, const func_t *func) -{ - const var_t *var; - - if (!func->args) - return; - - LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) - { - const type_t *t = var->type; - const char *n = var->name; - if (decl_indirect(t)) - print_file(file, indent, "MIDL_memset(&%s, 0, sizeof %s);\n", n, n); - else if (is_ptr(t) || is_array(t)) - print_file(file, indent, "%s = 0;\n", n); - } - - fprintf(file, "\n"); -} - -static void write_formatdesc(FILE *f, int indent, const char *str) -{ - print_file(f, indent, "typedef struct _MIDL_%s_FORMAT_STRING\n", str); - print_file(f, indent, "{\n"); - print_file(f, indent + 1, "short Pad;\n"); - print_file(f, indent + 1, "unsigned char Format[%s_FORMAT_STRING_SIZE];\n", str); - print_file(f, indent, "} MIDL_%s_FORMAT_STRING;\n", str); - print_file(f, indent, "\n"); -} - -void write_formatstringsdecl(FILE *f, int indent, ifref_list_t *ifaces, int for_objects) -{ - print_file(f, indent, "#define TYPE_FORMAT_STRING_SIZE %d\n", - get_size_typeformatstring(ifaces, for_objects)); - - print_file(f, indent, "#define PROC_FORMAT_STRING_SIZE %d\n", - get_size_procformatstring(ifaces, for_objects)); - - fprintf(f, "\n"); - write_formatdesc(f, indent, "TYPE"); - write_formatdesc(f, indent, "PROC"); - fprintf(f, "\n"); - print_file(f, indent, "static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString;\n"); - print_file(f, indent, "static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString;\n"); - print_file(f, indent, "\n"); -} - -static inline int is_base_type(unsigned char type) -{ - switch (type) - { - case RPC_FC_BYTE: - case RPC_FC_CHAR: - case RPC_FC_USMALL: - case RPC_FC_SMALL: - case RPC_FC_WCHAR: - case RPC_FC_USHORT: - case RPC_FC_SHORT: - case RPC_FC_ULONG: - case RPC_FC_LONG: - case RPC_FC_HYPER: - case RPC_FC_IGNORE: - case RPC_FC_FLOAT: - case RPC_FC_DOUBLE: - case RPC_FC_ENUM16: - case RPC_FC_ENUM32: - case RPC_FC_ERROR_STATUS_T: - case RPC_FC_BIND_PRIMITIVE: - return TRUE; - - default: - return FALSE; - } -} - -int decl_indirect(const type_t *t) -{ - return is_user_type(t) - || (!is_base_type(t->type) - && !is_ptr(t) - && !is_array(t)); -} - -static size_t write_procformatstring_var(FILE *file, int indent, - const var_t *var, int is_return) -{ - size_t size; - const type_t *type = var->type; - - int is_in = is_attr(var->attrs, ATTR_IN); - int is_out = is_attr(var->attrs, ATTR_OUT); - - if (!is_in && !is_out) is_in = TRUE; - - if (!type->declarray && is_base_type(type->type)) - { - if (is_return) - print_file(file, indent, "0x53, /* FC_RETURN_PARAM_BASETYPE */\n"); - else - print_file(file, indent, "0x4e, /* FC_IN_PARAM_BASETYPE */\n"); - - if (type->type == RPC_FC_BIND_PRIMITIVE) - { - print_file(file, indent, "0x%02x, /* FC_IGNORE */\n", RPC_FC_IGNORE); - size = 2; /* includes param type prefix */ - } - else if (is_base_type(type->type)) - { - print_file(file, indent, "0x%02x, /* %s */\n", type->type, string_of_type(type->type)); - size = 2; /* includes param type prefix */ - } - else - { - error("Unknown/unsupported type: %s (0x%02x)\n", var->name, type->type); - size = 0; - } - } - else - { - if (is_return) - print_file(file, indent, "0x52, /* FC_RETURN_PARAM */\n"); - else if (is_in && is_out) - print_file(file, indent, "0x50, /* FC_IN_OUT_PARAM */\n"); - else if (is_out) - print_file(file, indent, "0x51, /* FC_OUT_PARAM */\n"); - else - print_file(file, indent, "0x4d, /* FC_IN_PARAM */\n"); - - print_file(file, indent, "0x01,\n"); - print_file(file, indent, "NdrFcShort(0x%x),\n", type->typestring_offset); - size = 4; /* includes param type prefix */ - } - return size; -} - -void write_procformatstring(FILE *file, const ifref_list_t *ifaces, int for_objects) -{ - const ifref_t *iface; - int indent = 0; - const var_t *var; - - print_file(file, indent, "static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString =\n"); - print_file(file, indent, "{\n"); - indent++; - print_file(file, indent, "0,\n"); - print_file(file, indent, "{\n"); - indent++; - - if (ifaces) LIST_FOR_EACH_ENTRY( iface, ifaces, const ifref_t, entry ) - { - if (for_objects != is_object(iface->iface->attrs) || is_local(iface->iface->attrs)) - continue; - - if (iface->iface->funcs) - { - const func_t *func; - LIST_FOR_EACH_ENTRY( func, iface->iface->funcs, const func_t, entry ) - { - if (is_local(func->def->attrs)) continue; - /* emit argument data */ - if (func->args) - { - LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) - write_procformatstring_var(file, indent, var, FALSE); - } - - /* emit return value data */ - var = func->def; - if (is_void(var->type)) - { - print_file(file, indent, "0x5b, /* FC_END */\n"); - print_file(file, indent, "0x5c, /* FC_PAD */\n"); - } - else - write_procformatstring_var(file, indent, var, TRUE); - } - } - } - - print_file(file, indent, "0x0\n"); - indent--; - print_file(file, indent, "}\n"); - indent--; - print_file(file, indent, "};\n"); - print_file(file, indent, "\n"); -} - -static int write_base_type(FILE *file, const type_t *type, unsigned int *typestring_offset) -{ - if (is_base_type(type->type)) - { - print_file(file, 2, "0x%02x,\t/* %s */\n", type->type, string_of_type(type->type)); - *typestring_offset += 1; - return 1; - } - - return 0; -} - -/* write conformance / variance descriptor */ -static size_t write_conf_or_var_desc(FILE *file, const func_t *func, const type_t *structure, - unsigned int baseoff, const expr_t *expr) -{ - unsigned char operator_type = 0; - const char *operator_string = "no operators"; - const expr_t *subexpr; - - if (!structure) - { - /* Top-level conformance calculations are done inline. */ - print_file (file, 2, "0x%x,\t/* Corr desc: parameter */\n", - RPC_FC_TOP_LEVEL_CONFORMANCE); - print_file (file, 2, "0x0,\n"); - print_file (file, 2, "NdrFcShort(0x0),\n"); - return 4; - } - - if (expr->is_const) - { - if (expr->cval > UCHAR_MAX * (USHRT_MAX + 1) + USHRT_MAX) - error("write_conf_or_var_desc: constant value %ld is greater than " - "the maximum constant size of %d\n", expr->cval, - UCHAR_MAX * (USHRT_MAX + 1) + USHRT_MAX); - - print_file(file, 2, "0x%x, /* Corr desc: constant, val = %ld */\n", - RPC_FC_CONSTANT_CONFORMANCE, expr->cval); - print_file(file, 2, "0x%x,\n", expr->cval & ~USHRT_MAX); - print_file(file, 2, "NdrFcShort(0x%x),\n", expr->cval & USHRT_MAX); - - return 4; - } - - subexpr = expr; - switch (subexpr->type) - { - case EXPR_PPTR: - subexpr = subexpr->ref; - operator_type = RPC_FC_DEREFERENCE; - operator_string = "FC_DEREFERENCE"; - break; - case EXPR_DIV: - if (subexpr->u.ext->is_const && (subexpr->u.ext->cval == 2)) - { - subexpr = subexpr->ref; - operator_type = RPC_FC_DIV_2; - operator_string = "FC_DIV_2"; - } - break; - case EXPR_MUL: - if (subexpr->u.ext->is_const && (subexpr->u.ext->cval == 2)) - { - subexpr = subexpr->ref; - operator_type = RPC_FC_MULT_2; - operator_string = "FC_MULT_2"; - } - break; - case EXPR_SUB: - if (subexpr->u.ext->is_const && (subexpr->u.ext->cval == 1)) - { - subexpr = subexpr->ref; - operator_type = RPC_FC_SUB_1; - operator_string = "FC_SUB_1"; - } - break; - case EXPR_ADD: - if (subexpr->u.ext->is_const && (subexpr->u.ext->cval == 1)) - { - subexpr = subexpr->ref; - operator_type = RPC_FC_ADD_1; - operator_string = "FC_ADD_1"; - } - break; - default: - break; - } - - if (subexpr->type == EXPR_IDENTIFIER) - { - const type_t *correlation_variable = NULL; - unsigned char correlation_variable_type; - unsigned char param_type = 0; - const char *param_type_string = NULL; - size_t offset = 0; - const var_t *var; - - if (structure->fields) LIST_FOR_EACH_ENTRY( var, structure->fields, const var_t, entry ) - { - unsigned int align = 0; - /* FIXME: take alignment into account */ - if (var->name && !strcmp(var->name, subexpr->u.sval)) - { - correlation_variable = var->type; - break; - } - offset += type_memsize(var->type, &align); - } - if (!correlation_variable) - error("write_conf_or_var_desc: couldn't find variable %s in structure\n", - subexpr->u.sval); - - offset -= baseoff; - correlation_variable_type = correlation_variable->type; - - switch (correlation_variable_type) - { - case RPC_FC_CHAR: - case RPC_FC_SMALL: - param_type = RPC_FC_SMALL; - param_type_string = "FC_SMALL"; - break; - case RPC_FC_BYTE: - case RPC_FC_USMALL: - param_type = RPC_FC_USMALL; - param_type_string = "FC_USMALL"; - break; - case RPC_FC_WCHAR: - case RPC_FC_SHORT: - case RPC_FC_ENUM16: - param_type = RPC_FC_SHORT; - param_type_string = "FC_SHORT"; - break; - case RPC_FC_USHORT: - param_type = RPC_FC_USHORT; - param_type_string = "FC_USHORT"; - break; - case RPC_FC_LONG: - case RPC_FC_ENUM32: - param_type = RPC_FC_LONG; - param_type_string = "FC_LONG"; - break; - case RPC_FC_ULONG: - param_type = RPC_FC_ULONG; - param_type_string = "FC_ULONG"; - break; - case RPC_FC_RP: - case RPC_FC_UP: - case RPC_FC_OP: - case RPC_FC_FP: - if (sizeof(void *) == 4) /* FIXME */ - { - param_type = RPC_FC_LONG; - param_type_string = "FC_LONG"; - } - else - { - param_type = RPC_FC_HYPER; - param_type_string = "FC_HYPER"; - } - break; - default: - error("write_conf_or_var_desc: conformance variable type not supported 0x%x\n", - correlation_variable_type); - } - - print_file(file, 2, "0x%x, /* Corr desc: %s */\n", - RPC_FC_NORMAL_CONFORMANCE | param_type, param_type_string); - print_file(file, 2, "0x%x, /* %s */\n", operator_type, operator_string); - print_file(file, 2, "NdrFcShort(0x%x), /* offset = %d */\n", - offset, offset); - } - else - { - unsigned int callback_offset = 0; - struct expr_eval_routine *eval; - int found = 0; - - LIST_FOR_EACH_ENTRY(eval, &expr_eval_routines, struct expr_eval_routine, entry) - { - if (!strcmp (eval->structure->name, structure->name) - && !compare_expr (eval->expr, expr)) - { - found = 1; - break; - } - callback_offset++; - } - - if (!found) - { - eval = xmalloc (sizeof(*eval)); - eval->structure = structure; - eval->expr = expr; - list_add_tail (&expr_eval_routines, &eval->entry); - } - - if (callback_offset > USHRT_MAX) - error("Maximum number of callback routines reached\n"); - - print_file(file, 2, "0x%x, /* Corr desc: */\n", RPC_FC_NORMAL_CONFORMANCE); - print_file(file, 2, "0x%x, /* %s */\n", RPC_FC_CALLBACK, "FC_CALLBACK"); - print_file(file, 2, "NdrFcShort(0x%x), /* %u */\n", callback_offset, callback_offset); - } - return 4; -} - -static size_t fields_memsize(const var_list_t *fields, unsigned int *align) -{ - int have_align = FALSE; - size_t size = 0; - const var_t *v; - - if (!fields) return 0; - LIST_FOR_EACH_ENTRY( v, fields, const var_t, entry ) - { - unsigned int falign = 0; - size_t fsize = type_memsize(v->type, &falign); - if (!have_align) - { - *align = falign; - have_align = TRUE; - } - size = (size + (falign - 1)) & ~(falign - 1); - size += fsize; - } - - size = (size + (*align - 1)) & ~(*align - 1); - return size; -} - -static size_t union_memsize(const var_list_t *fields, unsigned int *pmaxa) -{ - size_t size, maxs = 0; - unsigned int align = *pmaxa; - const var_t *v; - - if (fields) LIST_FOR_EACH_ENTRY( v, fields, const var_t, entry ) - { - /* we could have an empty default field with NULL type */ - if (v->type) - { - size = type_memsize(v->type, &align); - if (maxs < size) maxs = size; - if (*pmaxa < align) *pmaxa = align; - } - } - - return maxs; -} - -size_t type_memsize(const type_t *t, unsigned int *align) -{ - size_t size = 0; - - if (t->declarray && is_conformant_array(t)) - { - type_memsize(t->ref, align); - size = 0; - } - else if (is_ptr(t) || is_conformant_array(t)) - { - size = sizeof(void *); - if (size > *align) *align = size; - } - else switch (t->type) - { - case RPC_FC_BYTE: - case RPC_FC_CHAR: - case RPC_FC_USMALL: - case RPC_FC_SMALL: - size = 1; - if (size > *align) *align = size; - break; - case RPC_FC_WCHAR: - case RPC_FC_USHORT: - case RPC_FC_SHORT: - case RPC_FC_ENUM16: - size = 2; - if (size > *align) *align = size; - break; - case RPC_FC_ULONG: - case RPC_FC_LONG: - case RPC_FC_ERROR_STATUS_T: - case RPC_FC_ENUM32: - case RPC_FC_FLOAT: - size = 4; - if (size > *align) *align = size; - break; - case RPC_FC_HYPER: - case RPC_FC_DOUBLE: - size = 8; - if (size > *align) *align = size; - break; - case RPC_FC_STRUCT: - case RPC_FC_CVSTRUCT: - case RPC_FC_CPSTRUCT: - case RPC_FC_CSTRUCT: - case RPC_FC_PSTRUCT: - case RPC_FC_BOGUS_STRUCT: - size = fields_memsize(t->fields, align); - break; - case RPC_FC_ENCAPSULATED_UNION: - case RPC_FC_NON_ENCAPSULATED_UNION: - size = union_memsize(t->fields, align); - break; - case RPC_FC_SMFARRAY: - case RPC_FC_LGFARRAY: - case RPC_FC_SMVARRAY: - case RPC_FC_LGVARRAY: - case RPC_FC_BOGUS_ARRAY: - size = t->dim * type_memsize(t->ref, align); - break; - default: - error("type_memsize: Unknown type %d\n", t->type); - size = 0; - } - - return size; -} - -static unsigned int write_nonsimple_pointer(FILE *file, const type_t *type, size_t offset) -{ - short absoff = type->ref->typestring_offset; - short reloff = absoff - (offset + 2); - int ptr_attr = is_ptr(type->ref) ? 0x10 : 0x0; - - print_file(file, 2, "0x%02x, 0x%x,\t/* %s */\n", - type->type, ptr_attr, string_of_type(type->type)); - print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%hd) */\n", - reloff, reloff, absoff); - return 4; -} - -static unsigned int write_simple_pointer(FILE *file, const type_t *type) -{ - print_file(file, 2, "0x%02x, 0x8,\t/* %s [simple_pointer] */\n", - type->type, string_of_type(type->type)); - print_file(file, 2, "0x%02x,\t/* %s */\n", type->ref->type, - string_of_type(type->ref->type)); - print_file(file, 2, "0x5c,\t/* FC_PAD */\n"); - return 4; -} - -static size_t write_pointer_tfs(FILE *file, type_t *type, unsigned int *typestring_offset) -{ - unsigned int offset = *typestring_offset; - - print_file(file, 0, "/* %d */\n", offset); - update_tfsoff(type, offset, file); - - if (type->ref->typestring_offset) - *typestring_offset += write_nonsimple_pointer(file, type, offset); - else if (is_base_type(type->ref->type)) - *typestring_offset += write_simple_pointer(file, type); - - return offset; -} - -static int processed(const type_t *type) -{ - return type->typestring_offset && !type->tfswrite; -} - -static void write_user_tfs(FILE *file, type_t *type, unsigned int *tfsoff) -{ - unsigned int start, absoff, flags; - unsigned int align = 0, ualign = 0; - const char *name; - type_t *utype = get_user_type(type, &name); - size_t usize = type_memsize(utype, &ualign); - size_t size = type_memsize(type, &align); - unsigned short funoff = user_type_offset(name); - short reloff; - - guard_rec(type); - - if (is_base_type(utype->type)) - { - absoff = *tfsoff; - print_file(file, 0, "/* %d */\n", absoff); - print_file(file, 2, "0x%x,\t/* %s */\n", utype->type, string_of_type(utype->type)); - print_file(file, 2, "0x5c,\t/* FC_PAD */\n"); - *tfsoff += 2; - } - else - { - if (!processed(utype)) - write_embedded_types(file, NULL, utype, utype->name, TRUE, tfsoff); - absoff = utype->typestring_offset; - } - - if (utype->type == RPC_FC_RP) - flags = 0x40; - else if (utype->type == RPC_FC_UP) - flags = 0x80; - else - flags = 0; - - start = *tfsoff; - update_tfsoff(type, start, file); - print_file(file, 0, "/* %d */\n", start); - print_file(file, 2, "0x%x,\t/* FC_USER_MARSHAL */\n", RPC_FC_USER_MARSHAL); - print_file(file, 2, "0x%x,\t/* Alignment= %d, Flags= %02x */\n", - flags | (align - 1), align - 1, flags); - print_file(file, 2, "NdrFcShort(0x%hx),\t/* Function offset= %hu */\n", funoff, funoff); - print_file(file, 2, "NdrFcShort(0x%lx),\t/* %lu */\n", usize, usize); - print_file(file, 2, "NdrFcShort(0x%lx),\t/* %lu */\n", size, size); - *tfsoff += 8; - reloff = absoff - *tfsoff; - print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%lu) */\n", reloff, reloff, absoff); - *tfsoff += 2; -} - -static void write_member_type(FILE *file, type_t *type, const var_t *field, - unsigned int *corroff, unsigned int *tfsoff) -{ - if (is_embedded_complex(type)) - { - size_t absoff; - short reloff; - - if (is_union(type->type) && is_attr(field->attrs, ATTR_SWITCHIS)) - { - absoff = *corroff; - *corroff += 8; - } - else - { - absoff = type->typestring_offset; - } - reloff = absoff - (*tfsoff + 2); - - print_file(file, 2, "0x4c,\t/* FC_EMBEDDED_COMPLEX */\n"); - /* FIXME: actually compute necessary padding */ - print_file(file, 2, "0x0,\t/* FIXME: padding */\n"); - print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%lu) */\n", - reloff, reloff, absoff); - *tfsoff += 4; - } - else if (is_ptr(type)) - { - print_file(file, 2, "0x8,\t/* FC_LONG */\n"); - *tfsoff += 1; - } - else if (!write_base_type(file, type, tfsoff)) - error("Unsupported member type 0x%x\n", type->type); -} - -static void write_end(FILE *file, unsigned int *tfsoff) -{ - if (*tfsoff % 2 == 0) - { - print_file(file, 2, "0x%x,\t\t/* FC_PAD */\n", RPC_FC_PAD); - *tfsoff += 1; - } - print_file(file, 2, "0x%x,\t\t/* FC_END */\n", RPC_FC_END); - *tfsoff += 1; -} - -static void write_descriptors(FILE *file, type_t *type, unsigned int *tfsoff) -{ - unsigned int offset = 0; - var_list_t *fs = type->fields; - var_t *f; - - if (fs) LIST_FOR_EACH_ENTRY(f, fs, var_t, entry) - { - unsigned int align = 0; - type_t *ft = f->type; - if (is_union(ft->type) && is_attr(f->attrs, ATTR_SWITCHIS)) - { - unsigned int absoff = ft->typestring_offset; - short reloff = absoff - (*tfsoff + 6); - print_file(file, 0, "/* %d */\n", *tfsoff); - print_file(file, 2, "0x%x,\t/* %s */\n", ft->type, string_of_type(ft->type)); - print_file(file, 2, "0x%x,\t/* FIXME: always FC_LONG */\n", RPC_FC_LONG); - write_conf_or_var_desc(file, current_func, current_structure, offset, - get_attrp(f->attrs, ATTR_SWITCHIS)); - print_file(file, 2, "NdrFcShort(%hd),\t/* Offset= %hd (%u) */\n", - reloff, reloff, absoff); - *tfsoff += 8; - } - - /* FIXME: take alignment into account */ - offset += type_memsize(ft, &align); - } -} - -static int write_no_repeat_pointer_descriptions( - FILE *file, type_t *type, - size_t *offset_in_memory, size_t *offset_in_buffer, - unsigned int *typestring_offset) -{ - int written = 0; - unsigned int align; - - if (is_ptr(type)) - { - print_file(file, 2, "0x%02x, /* FC_NO_REPEAT */\n", RPC_FC_NO_REPEAT); - print_file(file, 2, "0x%02x, /* FC_PAD */\n", RPC_FC_PAD); - - /* pointer instance */ - print_file(file, 2, "NdrFcShort(0x%x), /* Memory offset = %d */\n", *offset_in_memory, *offset_in_memory); - print_file(file, 2, "NdrFcShort(0x%x), /* Buffer offset = %d */\n", *offset_in_buffer, *offset_in_buffer); - *typestring_offset += 6; - - if (processed(type->ref) || is_base_type(type->ref->type)) - write_pointer_tfs(file, type, typestring_offset); - else - error("write_pointer_description: type format string unknown\n"); - - align = 0; - *offset_in_memory += type_memsize(type, &align); - /* FIXME: is there a case where these two are different? */ - align = 0; - *offset_in_buffer += type_memsize(type, &align); - - return 1; - } - - if (is_non_complex_struct(type)) - { - const var_t *v; - LIST_FOR_EACH_ENTRY( v, type->fields, const var_t, entry ) - written += write_no_repeat_pointer_descriptions( - file, v->type, - offset_in_memory, offset_in_buffer, typestring_offset); - } - else - { - align = 0; - *offset_in_memory += type_memsize(type, &align); - /* FIXME: is there a case where these two are different? */ - align = 0; - *offset_in_buffer += type_memsize(type, &align); - } - - return written; -} - -static int write_pointer_description_offsets( - FILE *file, const attr_list_t *attrs, type_t *type, - size_t *offset_in_memory, size_t *offset_in_buffer, - unsigned int *typestring_offset) -{ - int written = 0; - unsigned int align; - - if (is_ptr(type) && type->ref->type != RPC_FC_IP) - { - if (offset_in_memory && offset_in_buffer) - { - /* pointer instance */ - /* FIXME: sometimes from end of structure, sometimes from beginning */ - print_file(file, 2, "NdrFcShort(0x%x), /* Memory offset = %d */\n", *offset_in_memory, *offset_in_memory); - print_file(file, 2, "NdrFcShort(0x%x), /* Buffer offset = %d */\n", *offset_in_buffer, *offset_in_buffer); - - align = 0; - *offset_in_memory += type_memsize(type, &align); - /* FIXME: is there a case where these two are different? */ - align = 0; - *offset_in_buffer += type_memsize(type, &align); - } - *typestring_offset += 4; - - if (processed(type->ref) || is_base_type(type->ref->type)) - write_pointer_tfs(file, type, typestring_offset); - else - error("write_pointer_description_offsets: type format string unknown\n"); - - return 1; - } - - if (is_array(type)) - { - return write_pointer_description_offsets( - file, attrs, type->ref, offset_in_memory, offset_in_buffer, - typestring_offset); - } - else if (is_non_complex_struct(type)) - { - /* otherwise search for interesting fields to parse */ - const var_t *v; - LIST_FOR_EACH_ENTRY( v, type->fields, const var_t, entry ) - { - written += write_pointer_description_offsets( - file, v->attrs, v->type, offset_in_memory, offset_in_buffer, - typestring_offset); - } - } - else - { - align = 0; - if (offset_in_memory) - *offset_in_memory += type_memsize(type, &align); - /* FIXME: is there a case where these two are different? */ - align = 0; - if (offset_in_buffer) - *offset_in_buffer += type_memsize(type, &align); - } - - return written; -} - -/* Note: if file is NULL return value is number of pointers to write, else - * it is the number of type format characters written */ -static int write_fixed_array_pointer_descriptions( - FILE *file, const attr_list_t *attrs, type_t *type, - size_t *offset_in_memory, size_t *offset_in_buffer, - unsigned int *typestring_offset) -{ - unsigned int align; - int pointer_count = 0; - - if (type->type == RPC_FC_SMFARRAY || type->type == RPC_FC_LGFARRAY) - { - unsigned int temp = 0; - /* unfortunately, this needs to be done in two passes to avoid - * writing out redundant FC_FIXED_REPEAT descriptions */ - pointer_count = write_pointer_description_offsets( - NULL, attrs, type->ref, NULL, NULL, &temp); - if (pointer_count > 0) - { - unsigned int increment_size; - size_t offset_of_array_pointer_mem = 0; - size_t offset_of_array_pointer_buf = 0; - - align = 0; - increment_size = type_memsize(type->ref, &align); - - print_file(file, 2, "0x%02x, /* FC_FIXED_REPEAT */\n", RPC_FC_FIXED_REPEAT); - print_file(file, 2, "0x%02x, /* FC_PAD */\n", RPC_FC_PAD); - print_file(file, 2, "NdrFcShort(0x%x), /* Iterations = %d */\n", type->dim, type->dim); - print_file(file, 2, "NdrFcShort(0x%x), /* Increment = %d */\n", increment_size, increment_size); - print_file(file, 2, "NdrFcShort(0x%x), /* Offset to array = %d */\n", *offset_in_memory, *offset_in_memory); - print_file(file, 2, "NdrFcShort(0x%x), /* Number of pointers = %d */\n", pointer_count, pointer_count); - *typestring_offset += 10; - - pointer_count = write_pointer_description_offsets( - file, attrs, type, &offset_of_array_pointer_mem, - &offset_of_array_pointer_buf, typestring_offset); - } - } - else if (is_struct(type->type)) - { - const var_t *v; - LIST_FOR_EACH_ENTRY( v, type->fields, const var_t, entry ) - { - pointer_count += write_fixed_array_pointer_descriptions( - file, v->attrs, v->type, offset_in_memory, offset_in_buffer, - typestring_offset); - } - } - else - { - align = 0; - if (offset_in_memory) - *offset_in_memory += type_memsize(type, &align); - /* FIXME: is there a case where these two are different? */ - align = 0; - if (offset_in_buffer) - *offset_in_buffer += type_memsize(type, &align); - } - - return pointer_count; -} - -/* Note: if file is NULL return value is number of pointers to write, else - * it is the number of type format characters written */ -static int write_conformant_array_pointer_descriptions( - FILE *file, const attr_list_t *attrs, type_t *type, - size_t *offset_in_memory, size_t *offset_in_buffer, - unsigned int *typestring_offset) -{ - unsigned int align; - int pointer_count = 0; - - if (is_conformant_array(type) && !type->length_is) - { - unsigned int temp = 0; - /* unfortunately, this needs to be done in two passes to avoid - * writing out redundant FC_VARIABLE_REPEAT descriptions */ - pointer_count = write_pointer_description_offsets( - NULL, attrs, type->ref, NULL, NULL, &temp); - if (pointer_count > 0) - { - unsigned int increment_size; - size_t offset_of_array_pointer_mem = 0; - size_t offset_of_array_pointer_buf = 0; - - align = 0; - increment_size = type_memsize(type->ref, &align); - - if (increment_size > USHRT_MAX) - error("array size of %u bytes is too large\n", increment_size); - - print_file(file, 2, "0x%02x, /* FC_VARIABLE_REPEAT */\n", RPC_FC_VARIABLE_REPEAT); - print_file(file, 2, "0x%02x, /* FC_FIXED_OFFSET */\n", RPC_FC_FIXED_OFFSET); - print_file(file, 2, "NdrFcShort(0x%x), /* Increment = %d */\n", increment_size, increment_size); - print_file(file, 2, "NdrFcShort(0x%x), /* Offset to array = %d */\n", *offset_in_memory, *offset_in_memory); - print_file(file, 2, "NdrFcShort(0x%x), /* Number of pointers = %d */\n", pointer_count, pointer_count); - *typestring_offset += 8; - - pointer_count = write_pointer_description_offsets( - file, attrs, type->ref, &offset_of_array_pointer_mem, - &offset_of_array_pointer_buf, typestring_offset); - } - } - else if (is_struct(type->type)) - { - const var_t *v; - LIST_FOR_EACH_ENTRY( v, type->fields, const var_t, entry ) - { - pointer_count += write_conformant_array_pointer_descriptions( - file, v->attrs, v->type, offset_in_memory, offset_in_buffer, - typestring_offset); - } - } - else - { - align = 0; - if (offset_in_memory) - *offset_in_memory += type_memsize(type, &align); - /* FIXME: is there a case where these two are different? */ - align = 0; - if (offset_in_buffer) - *offset_in_buffer += type_memsize(type, &align); - } - - return pointer_count; -} - -/* Note: if file is NULL return value is number of pointers to write, else - * it is the number of type format characters written */ -static int write_varying_array_pointer_descriptions( - FILE *file, const attr_list_t *attrs, type_t *type, - size_t *offset_in_memory, size_t *offset_in_buffer, - unsigned int *typestring_offset) -{ - unsigned int align; - int pointer_count = 0; - - /* FIXME: do varying array searching here, but pointer searching in write_pointer_description_offsets */ - - if (is_array(type) && type->length_is) - { - unsigned int temp = 0; - /* unfortunately, this needs to be done in two passes to avoid - * writing out redundant FC_VARIABLE_REPEAT descriptions */ - pointer_count = write_pointer_description_offsets( - NULL, attrs, type->ref, NULL, NULL, &temp); - if (pointer_count > 0) - { - unsigned int increment_size; - size_t offset_of_array_pointer_mem = 0; - size_t offset_of_array_pointer_buf = 0; - - align = 0; - increment_size = type_memsize(type->ref, &align); - - if (increment_size > USHRT_MAX) - error("array size of %u bytes is too large\n", increment_size); - - print_file(file, 2, "0x%02x, /* FC_VARIABLE_REPEAT */\n", RPC_FC_VARIABLE_REPEAT); - print_file(file, 2, "0x%02x, /* FC_VARIABLE_OFFSET */\n", RPC_FC_VARIABLE_OFFSET); - print_file(file, 2, "NdrFcShort(0x%x), /* Increment = %d */\n", increment_size, increment_size); - print_file(file, 2, "NdrFcShort(0x%x), /* Offset to array = %d */\n", *offset_in_memory, *offset_in_memory); - print_file(file, 2, "NdrFcShort(0x%x), /* Number of pointers = %d */\n", pointer_count, pointer_count); - *typestring_offset += 8; - - pointer_count = write_pointer_description_offsets( - file, attrs, type, &offset_of_array_pointer_mem, - &offset_of_array_pointer_buf, typestring_offset); - } - } - else if (is_struct(type->type)) - { - const var_t *v; - LIST_FOR_EACH_ENTRY( v, type->fields, const var_t, entry ) - { - pointer_count += write_varying_array_pointer_descriptions( - file, v->attrs, v->type, offset_in_memory, offset_in_buffer, - typestring_offset); - } - } - else - { - align = 0; - if (offset_in_memory) - *offset_in_memory += type_memsize(type, &align); - /* FIXME: is there a case where these two are different? */ - align = 0; - if (offset_in_buffer) - *offset_in_buffer += type_memsize(type, &align); - } - - return pointer_count; -} - -static void write_pointer_description(FILE *file, type_t *type, - unsigned int *typestring_offset) -{ - size_t offset_in_buffer; - size_t offset_in_memory; - - /* pass 1: search for single instance of a pointer (i.e. don't descend - * into arrays) */ - offset_in_memory = 0; - offset_in_buffer = 0; - write_no_repeat_pointer_descriptions( - file, type, - &offset_in_memory, &offset_in_buffer, typestring_offset); - - /* pass 2: search for pointers in fixed arrays */ - offset_in_memory = 0; - offset_in_buffer = 0; - write_fixed_array_pointer_descriptions( - file, NULL, type, - &offset_in_memory, &offset_in_buffer, typestring_offset); - - /* pass 3: search for pointers in conformant only arrays (but don't descend - * into conformant varying or varying arrays) */ - offset_in_memory = 0; - offset_in_buffer = 0; - write_conformant_array_pointer_descriptions( - file, NULL, type, - &offset_in_memory, &offset_in_buffer, typestring_offset); - - /* pass 4: search for pointers in varying arrays */ - offset_in_memory = 0; - offset_in_buffer = 0; - write_varying_array_pointer_descriptions( - file, NULL, type, - &offset_in_memory, &offset_in_buffer, typestring_offset); -} - -static int is_declptr(const type_t *t) -{ - return is_ptr(t) || (is_conformant_array(t) && !t->declarray); -} - -static size_t write_string_tfs(FILE *file, const attr_list_t *attrs, - const type_t *type, - const char *name, unsigned int *typestring_offset) -{ - size_t start_offset = *typestring_offset; - unsigned char rtype; - - if (is_declptr(type)) - { - unsigned char flag = is_conformant_array(type) ? 0 : RPC_FC_P_SIMPLEPOINTER; - int pointer_type = is_ptr(type) ? type->type : get_attrv(attrs, ATTR_POINTERTYPE); - if (!pointer_type) - pointer_type = RPC_FC_RP; - print_file(file, 2,"0x%x, 0x%x,\t/* %s%s */\n", - pointer_type, flag, string_of_type(pointer_type), - flag ? " [simple_pointer]" : ""); - *typestring_offset += 2; - if (!flag) - { - print_file(file, 2, "NdrFcShort(0x2),\n"); - *typestring_offset += 2; - } - rtype = type->ref->type; - } - else - rtype = type->type; - - if ((rtype != RPC_FC_BYTE) && (rtype != RPC_FC_CHAR) && (rtype != RPC_FC_WCHAR)) - { - error("write_string_tfs: Unimplemented for type 0x%x of name: %s\n", rtype, name); - return start_offset; - } - - if (type->declarray && !is_conformant_array(type)) - { - /* FIXME: multi-dimensional array */ - if (0xffffuL < type->dim) - error("array size for parameter %s exceeds %u bytes by %lu bytes\n", - name, 0xffffu, type->dim - 0xffffu); - - if (rtype == RPC_FC_CHAR) - WRITE_FCTYPE(file, FC_CSTRING, *typestring_offset); - else - WRITE_FCTYPE(file, FC_WSTRING, *typestring_offset); - print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD); - *typestring_offset += 2; - - print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", type->dim, type->dim); - *typestring_offset += 2; - - return start_offset; - } - else if (type->size_is) - { - unsigned int align = 0; - - if (rtype == RPC_FC_CHAR) - WRITE_FCTYPE(file, FC_C_CSTRING, *typestring_offset); - else - WRITE_FCTYPE(file, FC_C_WSTRING, *typestring_offset); - print_file(file, 2, "0x%x, /* FC_STRING_SIZED */\n", RPC_FC_STRING_SIZED); - *typestring_offset += 2; - - *typestring_offset += write_conf_or_var_desc( - file, current_func, current_structure, - (type->declarray && current_structure - ? type_memsize(current_structure, &align) - : 0), - type->size_is); - - return start_offset; - } - else - { - if (rtype == RPC_FC_WCHAR) - WRITE_FCTYPE(file, FC_C_WSTRING, *typestring_offset); - else - WRITE_FCTYPE(file, FC_C_CSTRING, *typestring_offset); - print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD); - *typestring_offset += 2; - - return start_offset; - } -} - -static size_t write_array_tfs(FILE *file, const attr_list_t *attrs, type_t *type, - const char *name, unsigned int *typestring_offset) -{ - const expr_t *length_is = type->length_is; - const expr_t *size_is = type->size_is; - unsigned int align = 0; - size_t size; - size_t start_offset; - int has_pointer; - int pointer_type = get_attrv(attrs, ATTR_POINTERTYPE); - 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; - - size = type_memsize(type, &align); - if (size == 0) /* conformant array */ - size = type_memsize(type->ref, &align); - - start_offset = *typestring_offset; - update_tfsoff(type, start_offset, file); - print_file(file, 0, "/* %lu */\n", start_offset); - print_file(file, 2, "0x%02x,\t/* %s */\n", type->type, string_of_type(type->type)); - print_file(file, 2, "0x%x,\t/* %d */\n", align - 1, align - 1); - *typestring_offset += 2; - - align = 0; - if (type->type != RPC_FC_BOGUS_ARRAY) - { - unsigned char tc = type->type; - unsigned int baseoff - = type->declarray && current_structure - ? type_memsize(current_structure, &align) - : 0; - - if (tc == RPC_FC_LGFARRAY || tc == RPC_FC_LGVARRAY) - { - print_file(file, 2, "NdrFcLong(0x%x),\t/* %lu */\n", size, size); - *typestring_offset += 4; - } - else - { - print_file(file, 2, "NdrFcShort(0x%x),\t/* %lu */\n", size, size); - *typestring_offset += 2; - } - - if (is_conformant_array(type)) - *typestring_offset - += write_conf_or_var_desc(file, current_func, current_structure, - baseoff, size_is); - - if (type->type == RPC_FC_SMVARRAY || type->type == RPC_FC_LGVARRAY) - { - unsigned int elalign = 0; - size_t elsize = type_memsize(type->ref, &elalign); - - if (type->type == RPC_FC_LGVARRAY) - { - print_file(file, 2, "NdrFcLong(0x%x),\t/* %lu */\n", type->dim, type->dim); - *typestring_offset += 4; - } - else - { - print_file(file, 2, "NdrFcShort(0x%x),\t/* %lu */\n", type->dim, type->dim); - *typestring_offset += 2; - } - - print_file(file, 2, "NdrFcShort(0x%x),\t/* %lu */\n", elsize, elsize); - *typestring_offset += 2; - } - - if (length_is) - *typestring_offset - += write_conf_or_var_desc(file, current_func, current_structure, - baseoff, length_is); - - if (has_pointer) - { - print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP); - print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD); - *typestring_offset += 2; - write_pointer_description(file, type, typestring_offset); - print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END); - *typestring_offset += 1; - } - - write_member_type(file, type->ref, NULL, NULL, typestring_offset); - write_end(file, typestring_offset); - } - else - error("%s: complex arrays unimplemented\n", name); - - return start_offset; -} - -static const var_t *find_array_or_string_in_struct(const type_t *type) -{ - const var_t *last_field = LIST_ENTRY( list_tail(type->fields), const var_t, entry ); - const type_t *ft = last_field->type; - - if (ft->declarray && is_conformant_array(ft)) - return last_field; - - if (ft->type == RPC_FC_CSTRUCT || ft->type == RPC_FC_CPSTRUCT || ft->type == RPC_FC_CVSTRUCT) - return find_array_or_string_in_struct(last_field->type); - else - return NULL; -} - -static void write_struct_members(FILE *file, const type_t *type, - unsigned int *corroff, unsigned int *typestring_offset) -{ - const var_t *field; - unsigned short offset = 0; - - if (type->fields) LIST_FOR_EACH_ENTRY( field, type->fields, const var_t, entry ) - { - type_t *ft = field->type; - if (!ft->declarray || !is_conformant_array(ft)) - { - unsigned int align = 0; - size_t size = type_memsize(ft, &align); - if ((align - 1) & offset) - { - unsigned char fc = 0; - switch (align) - { - case 4: - fc = RPC_FC_ALIGNM4; - break; - case 8: - fc = RPC_FC_ALIGNM8; - break; - default: - error("write_struct_members: cannot align type %d", ft->type); - } - print_file(file, 2, "0x%x,\t/* %s */\n", fc, string_of_type(fc)); - offset = (offset + (align - 1)) & ~(align - 1); - *typestring_offset += 1; - } - write_member_type(file, ft, field, corroff, typestring_offset); - offset += size; - } - } - - write_end(file, typestring_offset); -} - -static size_t write_struct_tfs(FILE *file, type_t *type, - const char *name, unsigned int *tfsoff) -{ - const type_t *save_current_structure = current_structure; - unsigned int total_size; - const var_t *array; - size_t start_offset; - size_t array_offset; - int has_pointers = 0; - unsigned int align = 0; - unsigned int corroff; - var_t *f; - - guard_rec(type); - current_structure = type; - - total_size = type_memsize(type, &align); - if (total_size > USHRT_MAX) - error("structure size for %s exceeds %d bytes by %d bytes\n", - name, USHRT_MAX, total_size - USHRT_MAX); - - 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); - - array = find_array_or_string_in_struct(type); - if (array && !processed(array->type)) - array_offset - = is_attr(array->attrs, ATTR_STRING) - ? write_string_tfs(file, array->attrs, array->type, array->name, tfsoff) - : write_array_tfs(file, array->attrs, array->type, array->name, tfsoff); - - corroff = *tfsoff; - write_descriptors(file, type, tfsoff); - - start_offset = *tfsoff; - update_tfsoff(type, start_offset, file); - print_file(file, 0, "/* %d */\n", start_offset); - print_file(file, 2, "0x%x,\t/* %s */\n", type->type, string_of_type(type->type)); - print_file(file, 2, "0x%x,\t/* %d */\n", align - 1, align - 1); - print_file(file, 2, "NdrFcShort(0x%x),\t/* %d */\n", total_size, total_size); - *tfsoff += 4; - - if (array) - { - unsigned int absoff = array->type->typestring_offset; - short reloff = absoff - *tfsoff; - print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%lu) */\n", - reloff, reloff, absoff); - *tfsoff += 2; - } - else if (type->type == RPC_FC_BOGUS_STRUCT) - { - print_file(file, 2, "NdrFcShort(0x0),\n"); - *tfsoff += 2; - } - - if (type->type == RPC_FC_BOGUS_STRUCT) - { - - print_file(file, 2, "NdrFcShort(0x0),\t/* FIXME: pointer stuff */\n"); - *tfsoff += 2; - } - else if ((type->type == RPC_FC_PSTRUCT) || - (type->type == RPC_FC_CPSTRUCT) || - (type->type == RPC_FC_CVSTRUCT && has_pointers)) - { - print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP); - print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD); - *tfsoff += 2; - write_pointer_description(file, type, tfsoff); - print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END); - *tfsoff += 1; - } - - write_struct_members(file, type, &corroff, tfsoff); - - current_structure = save_current_structure; - return start_offset; -} - -static size_t write_pointer_only_tfs(FILE *file, const attr_list_t *attrs, int pointer_type, - unsigned char flags, size_t offset, - unsigned int *typeformat_offset) -{ - size_t start_offset = *typeformat_offset; - short reloff = offset - (*typeformat_offset + 2); - int in_attr, out_attr; - in_attr = is_attr(attrs, ATTR_IN); - out_attr = is_attr(attrs, ATTR_OUT); - if (!in_attr && !out_attr) in_attr = 1; - - if (out_attr && !in_attr && pointer_type == RPC_FC_RP) - flags |= 0x04; - - print_file(file, 2, "0x%x, 0x%x,\t\t/* %s", - pointer_type, - flags, - string_of_type(pointer_type)); - if (file) - { - if (flags & 0x04) - fprintf(file, " [allocated_on_stack]"); - if (flags & 0x10) - fprintf(file, " [pointer_deref]"); - fprintf(file, " */\n"); - } - - print_file(file, 2, "NdrFcShort(0x%x),\t/* %d */\n", reloff, offset); - *typeformat_offset += 4; - - return start_offset; -} - -static void write_branch_type(FILE *file, const type_t *t, unsigned int *tfsoff) -{ - if (t == NULL) - { - print_file(file, 2, "NdrFcShort(0x0),\t/* No type */\n"); - } - else if (is_base_type(t->type)) - { - print_file(file, 2, "NdrFcShort(0x80%02x),\t/* Simple arm type: %s */\n", - t->type, string_of_type(t->type)); - } - else if (t->typestring_offset) - { - short reloff = t->typestring_offset - *tfsoff; - print_file(file, 2, "NdrFcShort(0x%x),\t/* Offset= %d (%d) */\n", - reloff, reloff, t->typestring_offset); - } - else - error("write_branch_type: type unimplemented (0x%x)\n", t->type); - - *tfsoff += 2; -} - -static size_t write_union_tfs(FILE *file, type_t *type, unsigned int *tfsoff) -{ - unsigned int align = 0; - unsigned int start_offset; - size_t size = type_memsize(type, &align); - var_list_t *fields; - size_t nbranch = 0; - type_t *deftype = NULL; - short nodeftype = 0xffff; - var_t *f; - - guard_rec(type); - - 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(f, fields, var_t, entry) - { - expr_list_t *cases = get_attrp(f->attrs, ATTR_CASE); - if (cases) - nbranch += list_count(cases); - if (f->type) - write_embedded_types(file, f->attrs, f->type, f->name, TRUE, tfsoff); - } - - start_offset = *tfsoff; - update_tfsoff(type, start_offset, file); - print_file(file, 0, "/* %d */\n", start_offset); - if (type->type == RPC_FC_ENCAPSULATED_UNION) - { - const var_t *sv = LIST_ENTRY(list_head(type->fields), const var_t, entry); - const type_t *st = sv->type; - - switch (st->type) - { - case RPC_FC_CHAR: - case RPC_FC_SMALL: - case RPC_FC_USMALL: - case RPC_FC_SHORT: - case RPC_FC_USHORT: - case RPC_FC_LONG: - case RPC_FC_ULONG: - case RPC_FC_ENUM16: - case RPC_FC_ENUM32: - print_file(file, 2, "0x%x,\t/* %s */\n", type->type, string_of_type(type->type)); - print_file(file, 2, "0x%x,\t/* Switch type= %s */\n", - 0x40 | st->type, string_of_type(st->type)); - *tfsoff += 2; - break; - default: - error("union switch type must be an integer, char, or enum\n"); - } - } - print_file(file, 2, "NdrFcShort(0x%x),\t/* %d */\n", size, size); - print_file(file, 2, "NdrFcShort(0x%x),\t/* %d */\n", nbranch, nbranch); - *tfsoff += 4; - - if (fields) LIST_FOR_EACH_ENTRY(f, fields, var_t, entry) - { - type_t *ft = f->type; - expr_list_t *cases = get_attrp(f->attrs, ATTR_CASE); - int deflt = is_attr(f->attrs, ATTR_DEFAULT); - expr_t *c; - - if (cases == NULL && !deflt) - error("union field %s with neither case nor default attribute\n", f->name); - - if (cases) LIST_FOR_EACH_ENTRY(c, cases, expr_t, entry) - { - /* MIDL doesn't check for duplicate cases, even though that seems - like a reasonable thing to do, it just dumps them to the TFS - like we're going to do here. */ - print_file(file, 2, "NdrFcLong(0x%x),\t/* %d */\n", c->cval, c->cval); - *tfsoff += 4; - write_branch_type(file, ft, tfsoff); - } - - /* MIDL allows multiple default branches, even though that seems - illogical, it just chooses the last one, which is what we will - do. */ - if (deflt) - { - deftype = ft; - nodeftype = 0; - } - } - - if (deftype) - { - write_branch_type(file, deftype, tfsoff); - } - else - { - print_file(file, 2, "NdrFcShort(0x%x),\n", nodeftype); - *tfsoff += 2; - } - - return start_offset; -} - -static size_t write_ip_tfs(FILE *file, const func_t *func, const attr_list_t *attrs, - type_t *type, unsigned int *typeformat_offset) -{ - size_t i; - size_t start_offset = *typeformat_offset; - const var_t *iid = get_attrp(attrs, ATTR_IIDIS); - - if (iid) - { - expr_t expr; - - expr.type = EXPR_IDENTIFIER; - expr.ref = NULL; - expr.u.sval = iid->name; - expr.is_const = FALSE; - print_file(file, 2, "0x2f, /* FC_IP */\n"); - print_file(file, 2, "0x5c, /* FC_PAD */\n"); - *typeformat_offset += write_conf_or_var_desc(file, func, NULL, 0, &expr) + 2; - } - else - { - const type_t *base = is_ptr(type) ? type->ref : type; - const UUID *uuid = get_attrp(base->attrs, ATTR_UUID); - - if (! uuid) - error("%s: interface %s missing UUID\n", __FUNCTION__, base->name); - - update_tfsoff(type, start_offset, file); - print_file(file, 0, "/* %d */\n", start_offset); - print_file(file, 2, "0x2f,\t/* FC_IP */\n"); - print_file(file, 2, "0x5a,\t/* FC_CONSTANT_IID */\n"); - print_file(file, 2, "NdrFcLong(0x%08lx),\n", uuid->Data1); - print_file(file, 2, "NdrFcShort(0x%04x),\n", uuid->Data2); - print_file(file, 2, "NdrFcShort(0x%04x),\n", uuid->Data3); - for (i = 0; i < 8; ++i) - print_file(file, 2, "0x%02x,\n", uuid->Data4[i]); - - if (file) - fprintf(file, "\n"); - - *typeformat_offset += 18; - } - return start_offset; -} - -static int get_ptr_attr(const type_t *t, int def_type) -{ - while (TRUE) - { - int ptr_attr = get_attrv(t->attrs, ATTR_POINTERTYPE); - if (ptr_attr) - return ptr_attr; - if (t->kind != TKIND_ALIAS) - return def_type; - t = t->orig; - } -} - -static size_t write_typeformatstring_var(FILE *file, int indent, const func_t *func, - type_t *type, const var_t *var, - unsigned int *typeformat_offset) -{ - int pointer_type; - size_t offset; - - if (is_user_type(type)) - { - write_user_tfs(file, type, typeformat_offset); - return type->typestring_offset; - } - - if (type == var->type) /* top-level pointers */ - { - int pointer_attr = get_attrv(var->attrs, ATTR_POINTERTYPE); - if (pointer_attr != 0 && !is_ptr(type) && !is_array(type)) - error("'%s': pointer attribute applied to non-pointer type\n", var->name); - - if (pointer_attr == 0) - pointer_attr = get_ptr_attr(type, RPC_FC_RP); - - pointer_type = pointer_attr; - } - else - pointer_type = get_ptr_attr(type, RPC_FC_UP); - - if ((last_ptr(type) || last_array(type)) && is_ptrchain_attr(var, ATTR_STRING)) - return write_string_tfs(file, var->attrs, type, var->name, typeformat_offset); - - if (is_array(type)) - return write_array_tfs(file, var->attrs, type, var->name, typeformat_offset); - - if (!is_ptr(type)) - { - /* basic types don't need a type format string */ - if (is_base_type(type->type)) - return 0; - - switch (type->type) - { - case RPC_FC_STRUCT: - case RPC_FC_PSTRUCT: - case RPC_FC_CSTRUCT: - case RPC_FC_CPSTRUCT: - case RPC_FC_CVSTRUCT: - case RPC_FC_BOGUS_STRUCT: - return write_struct_tfs(file, type, var->name, typeformat_offset); - case RPC_FC_ENCAPSULATED_UNION: - case RPC_FC_NON_ENCAPSULATED_UNION: - return write_union_tfs(file, type, typeformat_offset); - case RPC_FC_IGNORE: - case RPC_FC_BIND_PRIMITIVE: - /* nothing to do */ - return 0; - default: - error("write_typeformatstring_var: Unsupported type 0x%x for variable %s\n", type->type, var->name); - } - } - else if (last_ptr(type)) - { - size_t start_offset = *typeformat_offset; - int in_attr = is_attr(var->attrs, ATTR_IN); - int out_attr = is_attr(var->attrs, ATTR_OUT); - const type_t *base = type->ref; - - if (base->type == RPC_FC_IP) - { - return write_ip_tfs(file, func, var->attrs, type, typeformat_offset); - } - - /* special case for pointers to base types */ - if (is_base_type(base->type)) - { - print_file(file, indent, "0x%x, 0x%x, /* %s %s[simple_pointer] */\n", - pointer_type, (!in_attr && out_attr) ? 0x0C : 0x08, - string_of_type(pointer_type), - (!in_attr && out_attr) ? "[allocated_on_stack] " : ""); - print_file(file, indent, "0x%02x, /* %s */\n", base->type, string_of_type(base->type)); - print_file(file, indent, "0x5c, /* FC_PAD */\n"); - *typeformat_offset += 4; - return start_offset; - } - } - - assert(is_ptr(type)); - - offset = write_typeformatstring_var(file, indent, func, type->ref, var, typeformat_offset); - if (file) - fprintf(file, "/* %2u */\n", *typeformat_offset); - return write_pointer_only_tfs(file, var->attrs, pointer_type, - !last_ptr(type) ? 0x10 : 0, - offset, typeformat_offset); -} - -static void set_tfswrite(type_t *type, int val) -{ - while (type->tfswrite != val) - { - type_t *utype = get_user_type(type, NULL); - - type->tfswrite = val; - - if (utype) - set_tfswrite(utype, val); - - if (type->kind == TKIND_ALIAS) - type = type->orig; - else if (is_ptr(type) || is_array(type)) - type = type->ref; - else - { - if (type->fields) - { - var_t *v; - LIST_FOR_EACH_ENTRY( v, type->fields, var_t, entry ) - if (v->type) - set_tfswrite(v->type, val); - } - - return; - } - } -} - -static int write_embedded_types(FILE *file, const attr_list_t *attrs, type_t *type, - const char *name, int write_ptr, unsigned int *tfsoff) -{ - int retmask = 0; - - if (is_user_type(type)) - { - write_user_tfs(file, type, tfsoff); - } - else if (is_ptr(type)) - { - type_t *ref = type->ref; - - if (ref->type == RPC_FC_IP) - { - write_ip_tfs(file, NULL, attrs, type, tfsoff); - } - else - { - if (!processed(ref) && !is_base_type(ref->type)) - retmask |= write_embedded_types(file, NULL, ref, name, TRUE, tfsoff); - - if (write_ptr) - write_pointer_tfs(file, type, tfsoff); - - retmask |= 1; - } - } - else if (type->declarray && is_conformant_array(type)) - ; /* conformant arrays and strings are handled specially */ - else if (is_array(type)) - { - write_array_tfs(file, attrs, type, name, tfsoff); - } - else if (is_struct(type->type)) - { - if (!processed(type)) - write_struct_tfs(file, type, name, tfsoff); - } - else if (is_union(type->type)) - { - if (!processed(type)) - write_union_tfs(file, type, tfsoff); - } - else if (!is_base_type(type->type)) - error("write_embedded_types: unknown embedded type for %s (0x%x)\n", - name, type->type); - - return retmask; -} - -static void set_all_tfswrite(const ifref_list_t *ifaces, int val) -{ - const ifref_t * iface; - const func_t *func; - const var_t *var; - - if (ifaces) - LIST_FOR_EACH_ENTRY( iface, ifaces, const ifref_t, entry ) - if (iface->iface->funcs) - LIST_FOR_EACH_ENTRY( func, iface->iface->funcs, const func_t, entry ) - if (func->args) - LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) - set_tfswrite(var->type, val); -} - -static size_t process_tfs(FILE *file, const ifref_list_t *ifaces, int for_objects) -{ - const var_t *var; - const ifref_t *iface; - unsigned int typeformat_offset = 2; - - if (ifaces) LIST_FOR_EACH_ENTRY( iface, ifaces, const ifref_t, entry ) - { - if (for_objects != is_object(iface->iface->attrs) || is_local(iface->iface->attrs)) - continue; - - if (iface->iface->funcs) - { - const func_t *func; - LIST_FOR_EACH_ENTRY( func, iface->iface->funcs, const func_t, entry ) - { - if (is_local(func->def->attrs)) continue; - - current_func = func; - if (func->args) - LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) - update_tfsoff( - var->type, - write_typeformatstring_var( - file, 2, func, var->type, var, - &typeformat_offset), - file); - } - } - } - - return typeformat_offset + 1; -} - - -void write_typeformatstring(FILE *file, const ifref_list_t *ifaces, int for_objects) -{ - int indent = 0; - - print_file(file, indent, "static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString =\n"); - print_file(file, indent, "{\n"); - indent++; - print_file(file, indent, "0,\n"); - print_file(file, indent, "{\n"); - indent++; - print_file(file, indent, "NdrFcShort(0x0),\n"); - - set_all_tfswrite(ifaces, TRUE); - process_tfs(file, ifaces, for_objects); - - print_file(file, indent, "0x0\n"); - indent--; - print_file(file, indent, "}\n"); - indent--; - print_file(file, indent, "};\n"); - print_file(file, indent, "\n"); -} - -static unsigned int get_required_buffer_size_type( - const type_t *type, const char *name, unsigned int *alignment) -{ - size_t size = 0; - - *alignment = 0; - if (is_user_type(type)) - { - const char *uname; - const type_t *utype = get_user_type(type, &uname); - size = get_required_buffer_size_type(utype, uname, alignment); - } - else if (!is_ptr(type)) - { - switch (type->type) - { - case RPC_FC_BYTE: - case RPC_FC_CHAR: - case RPC_FC_USMALL: - case RPC_FC_SMALL: - *alignment = 4; - size = 1; - break; - - case RPC_FC_WCHAR: - case RPC_FC_USHORT: - case RPC_FC_SHORT: - case RPC_FC_ENUM16: - *alignment = 4; - size = 2; - break; - - case RPC_FC_ULONG: - case RPC_FC_LONG: - case RPC_FC_ENUM32: - case RPC_FC_FLOAT: - case RPC_FC_ERROR_STATUS_T: - *alignment = 4; - size = 4; - break; - - case RPC_FC_HYPER: - case RPC_FC_DOUBLE: - *alignment = 8; - size = 8; - break; - - case RPC_FC_IGNORE: - case RPC_FC_BIND_PRIMITIVE: - return 0; - - case RPC_FC_STRUCT: - case RPC_FC_PSTRUCT: - { - const var_t *field; - if (!type->fields) return 0; - LIST_FOR_EACH_ENTRY( field, type->fields, const var_t, entry ) - { - unsigned int alignment; - size += get_required_buffer_size_type(field->type, field->name, - &alignment); - } - break; - } - - case RPC_FC_RP: - if (is_base_type( type->ref->type ) || type->ref->type == RPC_FC_STRUCT) - size = get_required_buffer_size_type( type->ref, name, alignment ); - break; - - case RPC_FC_SMFARRAY: - case RPC_FC_LGFARRAY: - size = type->dim * get_required_buffer_size_type(type->ref, name, alignment); - break; - - case RPC_FC_SMVARRAY: - case RPC_FC_LGVARRAY: - get_required_buffer_size_type(type->ref, name, alignment); - size = 0; - break; - - case RPC_FC_CARRAY: - case RPC_FC_CVARRAY: - get_required_buffer_size_type(type->ref, name, alignment); - size = sizeof(void *); - break; - - default: - error("get_required_buffer_size: Unknown/unsupported type: %s (0x%02x)\n", name, type->type); - return 0; - } - } - return size; -} - -static unsigned int get_required_buffer_size(const var_t *var, unsigned int *alignment, enum pass pass) -{ - int in_attr = is_attr(var->attrs, ATTR_IN); - int out_attr = is_attr(var->attrs, ATTR_OUT); - - if (!in_attr && !out_attr) - in_attr = 1; - - *alignment = 0; - - if (pass == PASS_OUT) - { - if (out_attr && is_ptr(var->type)) - { - type_t *type = var->type; - - if (type->type == RPC_FC_STRUCT) - { - const var_t *field; - unsigned int size = 36; - - if (!type->fields) return size; - LIST_FOR_EACH_ENTRY( field, type->fields, const var_t, entry ) - { - unsigned int align; - size += get_required_buffer_size_type( - field->type, field->name, &align); - } - return size; - } - } - return 0; - } - else - { - if ((!out_attr || in_attr) && !var->type->size_is - && !is_attr(var->attrs, ATTR_STRING) && !var->type->declarray) - { - if (is_ptr(var->type)) - { - type_t *type = var->type; - - if (is_base_type(type->type)) - { - return 25; - } - else if (type->type == RPC_FC_STRUCT) - { - unsigned int size = 36; - const var_t *field; - - if (!type->fields) return size; - LIST_FOR_EACH_ENTRY( field, type->fields, const var_t, entry ) - { - unsigned int align; - size += get_required_buffer_size_type( - field->type, field->name, &align); - } - return size; - } - } - } - - return get_required_buffer_size_type(var->type, var->name, alignment); - } -} - -static unsigned int get_function_buffer_size( const func_t *func, enum pass pass ) -{ - const var_t *var; - unsigned int total_size = 0, alignment; - - if (func->args) - { - LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) - { - total_size += get_required_buffer_size(var, &alignment, pass); - total_size += alignment; - } - } - - if (pass == PASS_OUT && !is_void(func->def->type)) - { - total_size += get_required_buffer_size(func->def, &alignment, PASS_RETURN); - total_size += alignment; - } - return total_size; -} - -static void print_phase_function(FILE *file, int indent, const char *type, - enum remoting_phase phase, - const var_t *var, unsigned int type_offset) -{ - const char *function; - switch (phase) - { - case PHASE_BUFFERSIZE: - function = "BufferSize"; - break; - case PHASE_MARSHAL: - function = "Marshall"; - break; - case PHASE_UNMARSHAL: - function = "Unmarshall"; - break; - case PHASE_FREE: - function = "Free"; - break; - default: - assert(0); - return; - } - - print_file(file, indent, "Ndr%s%s(\n", type, function); - indent++; - print_file(file, indent, "&_StubMsg,\n"); - print_file(file, indent, "%s%s%s%s,\n", - (phase == PHASE_UNMARSHAL) ? "(unsigned char **)" : "(unsigned char *)", - (phase == PHASE_UNMARSHAL || decl_indirect(var->type)) ? "&" : "", - (phase == PHASE_UNMARSHAL && decl_indirect(var->type)) ? "_p_" : "", - var->name); - print_file(file, indent, "(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%d]%s\n", - type_offset, (phase == PHASE_UNMARSHAL) ? "," : ");"); - if (phase == PHASE_UNMARSHAL) - print_file(file, indent, "0);\n"); - indent--; -} - -void print_phase_basetype(FILE *file, int indent, enum remoting_phase phase, - enum pass pass, const var_t *var, - const char *varname) -{ - type_t *type = var->type; - unsigned int size; - unsigned int alignment = 0; - unsigned char rtype; - - /* no work to do for other phases, buffer sizing is done elsewhere */ - if (phase != PHASE_MARSHAL && phase != PHASE_UNMARSHAL) - return; - - rtype = is_ptr(type) ? type->ref->type : type->type; - - switch (rtype) - { - case RPC_FC_BYTE: - case RPC_FC_CHAR: - case RPC_FC_SMALL: - case RPC_FC_USMALL: - size = 1; - alignment = 1; - break; - - case RPC_FC_WCHAR: - case RPC_FC_USHORT: - case RPC_FC_SHORT: - case RPC_FC_ENUM16: - size = 2; - alignment = 2; - break; - - case RPC_FC_ULONG: - case RPC_FC_LONG: - case RPC_FC_ENUM32: - case RPC_FC_FLOAT: - case RPC_FC_ERROR_STATUS_T: - size = 4; - alignment = 4; - break; - - case RPC_FC_HYPER: - case RPC_FC_DOUBLE: - size = 8; - alignment = 8; - break; - - case RPC_FC_IGNORE: - case RPC_FC_BIND_PRIMITIVE: - /* no marshalling needed */ - return; - - default: - error("print_phase_basetype: Unsupported type: %s (0x%02x, ptr_level: 0)\n", var->name, rtype); - size = 0; - } - - print_file(file, indent, "_StubMsg.Buffer = (unsigned char *)(((long)_StubMsg.Buffer + %u) & ~0x%x);\n", - alignment - 1, alignment - 1); - - if (phase == PHASE_MARSHAL) - { - print_file(file, indent, "*("); - write_type(file, is_ptr(type) ? type->ref : type, FALSE, NULL); - if (is_ptr(type)) - fprintf(file, " *)_StubMsg.Buffer = *"); - else - fprintf(file, " *)_StubMsg.Buffer = "); - fprintf(file, varname); - fprintf(file, ";\n"); - } - else if (phase == PHASE_UNMARSHAL) - { - if (pass == PASS_IN || pass == PASS_RETURN) - print_file(file, indent, ""); - else - print_file(file, indent, "*"); - fprintf(file, varname); - if (pass == PASS_IN && is_ptr(type)) - fprintf(file, " = ("); - else - fprintf(file, " = *("); - write_type(file, is_ptr(type) ? type->ref : type, FALSE, NULL); - fprintf(file, " *)_StubMsg.Buffer;\n"); - } - - print_file(file, indent, "_StubMsg.Buffer += sizeof("); - write_type(file, var->type, FALSE, NULL); - fprintf(file, ");\n"); -} - -/* returns whether the MaxCount, Offset or ActualCount members need to be - * filled in for the specified phase */ -static inline int is_size_needed_for_phase(enum remoting_phase phase) -{ - return (phase != PHASE_UNMARSHAL); -} - -void write_remoting_arguments(FILE *file, int indent, const func_t *func, - enum pass pass, enum remoting_phase phase) -{ - int in_attr, out_attr, pointer_type; - const var_t *var; - - if (!func->args) - return; - - if (phase == PHASE_BUFFERSIZE) - { - unsigned int size = get_function_buffer_size( func, pass ); - print_file(file, indent, "_StubMsg.BufferLength = %u;\n", size); - } - - LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) - { - const type_t *type = var->type; - unsigned char rtype; - size_t start_offset = type->typestring_offset; - - pointer_type = get_attrv(var->attrs, ATTR_POINTERTYPE); - if (!pointer_type) - pointer_type = RPC_FC_RP; - - in_attr = is_attr(var->attrs, ATTR_IN); - out_attr = is_attr(var->attrs, ATTR_OUT); - if (!in_attr && !out_attr) - in_attr = 1; - - switch (pass) - { - case PASS_IN: - if (!in_attr) continue; - break; - case PASS_OUT: - if (!out_attr) continue; - break; - case PASS_RETURN: - break; - } - - rtype = type->type; - - if (is_user_type(var->type)) - { - print_phase_function(file, indent, "UserMarshal", phase, var, start_offset); - } - else if (is_string_type(var->attrs, var->type)) - { - if (is_array(type) && !is_conformant_array(type)) - print_phase_function(file, indent, "NonConformantString", phase, var, start_offset); - else - { - if (type->size_is && is_size_needed_for_phase(phase)) - { - print_file(file, indent, "_StubMsg.MaxCount = (unsigned long)"); - write_expr(file, type->size_is, 1); - fprintf(file, ";\n"); - } - - if ((phase == PHASE_FREE) || (pointer_type == RPC_FC_UP)) - print_phase_function(file, indent, "Pointer", phase, var, start_offset); - else - print_phase_function(file, indent, "ConformantString", phase, var, - start_offset + (type->size_is ? 4 : 2)); - } - } - else if (is_array(type)) - { - unsigned char tc = type->type; - const char *array_type; - - if (tc == RPC_FC_SMFARRAY || tc == RPC_FC_LGFARRAY) - array_type = "FixedArray"; - else if (tc == RPC_FC_SMVARRAY || tc == RPC_FC_LGVARRAY) - { - if (is_size_needed_for_phase(phase)) - { - print_file(file, indent, "_StubMsg.Offset = (unsigned long)0;\n"); /* FIXME */ - print_file(file, indent, "_StubMsg.ActualCount = (unsigned long)"); - write_expr(file, type->length_is, 1); - fprintf(file, ";\n\n"); - } - array_type = "VaryingArray"; - } - else if (tc == RPC_FC_CARRAY) - { - if (is_size_needed_for_phase(phase) && phase != PHASE_FREE) - { - print_file(file, indent, "_StubMsg.MaxCount = (unsigned long)"); - write_expr(file, type->size_is, 1); - fprintf(file, ";\n\n"); - } - array_type = "ConformantArray"; - } - else if (tc == RPC_FC_CVARRAY) - { - if (is_size_needed_for_phase(phase)) - { - print_file(file, indent, "_StubMsg.MaxCount = (unsigned long)"); - write_expr(file, type->size_is, 1); - fprintf(file, ";\n"); - print_file(file, indent, "_StubMsg.Offset = (unsigned long)0;\n"); /* FIXME */ - print_file(file, indent, "_StubMsg.ActualCount = (unsigned long)"); - write_expr(file, type->length_is, 1); - fprintf(file, ";\n\n"); - } - array_type = "ConformantVaryingArray"; - } - else - array_type = "ComplexArray"; - - if (!in_attr && phase == PHASE_FREE) - { - print_file(file, indent, "if (%s)\n", var->name); - indent++; - print_file(file, indent, "_StubMsg.pfnFree(%s);\n", var->name); - } - else if (phase != PHASE_FREE) - { - if (pointer_type == RPC_FC_UP) - print_phase_function(file, indent, "Pointer", phase, var, start_offset); - else - print_phase_function(file, indent, array_type, phase, var, start_offset); - } - } - else if (!is_ptr(var->type) && is_base_type(rtype)) - { - print_phase_basetype(file, indent, phase, pass, var, var->name); - } - else if (!is_ptr(var->type)) - { - switch (rtype) - { - case RPC_FC_STRUCT: - case RPC_FC_PSTRUCT: - print_phase_function(file, indent, "SimpleStruct", phase, var, start_offset); - break; - case RPC_FC_CSTRUCT: - case RPC_FC_CPSTRUCT: - print_phase_function(file, indent, "ConformantStruct", phase, var, start_offset); - break; - case RPC_FC_CVSTRUCT: - print_phase_function(file, indent, "ConformantVaryingStruct", phase, var, start_offset); - break; - case RPC_FC_BOGUS_STRUCT: - print_phase_function(file, indent, "ComplexStruct", phase, var, start_offset); - break; - case RPC_FC_RP: - if (is_base_type( var->type->ref->type )) - { - print_phase_basetype(file, indent, phase, pass, var, var->name); - } - else if (var->type->ref->type == RPC_FC_STRUCT) - { - if (phase != PHASE_BUFFERSIZE && phase != PHASE_FREE) - print_phase_function(file, indent, "SimpleStruct", phase, var, start_offset + 4); - } - else - { - const var_t *iid; - if ((iid = get_attrp( var->attrs, ATTR_IIDIS ))) - print_file( file, indent, "_StubMsg.MaxCount = (unsigned long)%s;\n", iid->name ); - print_phase_function(file, indent, "Pointer", phase, var, start_offset); - } - break; - default: - error("write_remoting_arguments: Unsupported type: %s (0x%02x)\n", var->name, rtype); - } - } - else - { - if (last_ptr(var->type) && (pointer_type == RPC_FC_RP) && is_base_type(rtype)) - { - print_phase_basetype(file, indent, phase, pass, var, var->name); - } - else if (last_ptr(var->type) && (pointer_type == RPC_FC_RP) && (rtype == RPC_FC_STRUCT)) - { - if (phase != PHASE_BUFFERSIZE && phase != PHASE_FREE) - print_phase_function(file, indent, "SimpleStruct", phase, var, start_offset + 4); - } - else - { - const var_t *iid; - if ((iid = get_attrp( var->attrs, ATTR_IIDIS ))) - print_file( file, indent, "_StubMsg.MaxCount = (unsigned long)%s;\n", iid->name ); - print_phase_function(file, indent, "Pointer", phase, var, start_offset); - } - } - fprintf(file, "\n"); - } -} - - -size_t get_size_procformatstring_var(const var_t *var) -{ - return write_procformatstring_var(NULL, 0, var, FALSE); -} - - -size_t get_size_procformatstring_func(const func_t *func) -{ - const var_t *var; - size_t size = 0; - - /* argument list size */ - if (func->args) - LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) - size += get_size_procformatstring_var(var); - - /* return value size */ - if (is_void(func->def->type)) - size += 2; /* FC_END and FC_PAD */ - else - size += get_size_procformatstring_var(func->def); - - return size; -} - -size_t get_size_procformatstring(const ifref_list_t *ifaces, int for_objects) -{ - const ifref_t *iface; - size_t size = 1; - const func_t *func; - - if (ifaces) LIST_FOR_EACH_ENTRY( iface, ifaces, const ifref_t, entry ) - { - if (for_objects != is_object(iface->iface->attrs) || is_local(iface->iface->attrs)) - continue; - - if (iface->iface->funcs) - LIST_FOR_EACH_ENTRY( func, iface->iface->funcs, const func_t, entry ) - if (!is_local(func->def->attrs)) - size += get_size_procformatstring_func( func ); - } - return size; -} - -size_t get_size_typeformatstring(const ifref_list_t *ifaces, int for_objects) -{ - set_all_tfswrite(ifaces, FALSE); - return process_tfs(NULL, ifaces, for_objects); -} - -static void write_struct_expr(FILE *h, const expr_t *e, int brackets, - const var_list_t *fields, const char *structvar) -{ - switch (e->type) { - case EXPR_VOID: - break; - case EXPR_NUM: - fprintf(h, "%lu", e->u.lval); - break; - case EXPR_HEXNUM: - fprintf(h, "0x%lx", e->u.lval); - break; - case EXPR_DOUBLE: - fprintf(h, "%#.15g", e->u.dval); - break; - case EXPR_TRUEFALSE: - if (e->u.lval == 0) - fprintf(h, "FALSE"); - else - fprintf(h, "TRUE"); - break; - case EXPR_IDENTIFIER: - { - const var_t *field; - LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry ) - if (!strcmp(e->u.sval, field->name)) - { - fprintf(h, "%s->%s", structvar, e->u.sval); - break; - } - - if (&field->entry == fields) error("no field found for identifier %s\n", e->u.sval); - break; - } - case EXPR_NEG: - fprintf(h, "-"); - write_struct_expr(h, e->ref, 1, fields, structvar); - break; - case EXPR_NOT: - fprintf(h, "~"); - write_struct_expr(h, e->ref, 1, fields, structvar); - break; - case EXPR_PPTR: - fprintf(h, "*"); - write_struct_expr(h, e->ref, 1, fields, structvar); - break; - case EXPR_CAST: - fprintf(h, "("); - write_type(h, e->u.tref, FALSE, NULL); - fprintf(h, ")"); - write_struct_expr(h, e->ref, 1, fields, structvar); - break; - case EXPR_SIZEOF: - fprintf(h, "sizeof("); - write_type(h, e->u.tref, FALSE, NULL); - fprintf(h, ")"); - break; - case EXPR_SHL: - case EXPR_SHR: - case EXPR_MUL: - case EXPR_DIV: - case EXPR_ADD: - case EXPR_SUB: - case EXPR_AND: - case EXPR_OR: - if (brackets) fprintf(h, "("); - write_struct_expr(h, e->ref, 1, fields, structvar); - switch (e->type) { - case EXPR_SHL: fprintf(h, " << "); break; - case EXPR_SHR: fprintf(h, " >> "); break; - case EXPR_MUL: fprintf(h, " * "); break; - case EXPR_DIV: fprintf(h, " / "); break; - case EXPR_ADD: fprintf(h, " + "); break; - case EXPR_SUB: fprintf(h, " - "); break; - case EXPR_AND: fprintf(h, " & "); break; - case EXPR_OR: fprintf(h, " | "); break; - default: break; - } - write_struct_expr(h, e->u.ext, 1, fields, structvar); - if (brackets) fprintf(h, ")"); - break; - case EXPR_COND: - if (brackets) fprintf(h, "("); - write_struct_expr(h, e->ref, 1, fields, structvar); - fprintf(h, " ? "); - write_struct_expr(h, e->u.ext, 1, fields, structvar); - fprintf(h, " : "); - write_struct_expr(h, e->ext2, 1, fields, structvar); - if (brackets) fprintf(h, ")"); - break; - } -} - - -void declare_stub_args( FILE *file, int indent, const func_t *func ) -{ - int in_attr, out_attr; - int i = 0; - const var_t *def = func->def; - const var_t *var; - - /* declare return value '_RetVal' */ - if (!is_void(def->type)) - { - print_file(file, indent, ""); - write_type_left(file, def->type); - fprintf(file, " _RetVal;\n"); - } - - if (!func->args) - return; - - LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) - { - int is_string = is_attr(var->attrs, ATTR_STRING); - - in_attr = is_attr(var->attrs, ATTR_IN); - out_attr = is_attr(var->attrs, ATTR_OUT); - if (!out_attr && !in_attr) - in_attr = 1; - - if (!in_attr && !var->type->size_is && !is_string) - { - print_file(file, indent, ""); - write_type(file, var->type->ref, FALSE, "_W%u", i++); - fprintf(file, ";\n"); - } - - print_file(file, indent, ""); - write_type_left(file, var->type); - fprintf(file, " "); - if (var->type->declarray) { - fprintf(file, "( *"); - write_name(file, var); - fprintf(file, " )"); - } else - write_name(file, var); - write_type_right(file, var->type, FALSE); - fprintf(file, ";\n"); - - if (decl_indirect(var->type)) - print_file(file, indent, "void *_p_%s = &%s;\n", - var->name, var->name); - } -} - - -void assign_stub_out_args( FILE *file, int indent, const func_t *func ) -{ - int in_attr, out_attr; - int i = 0, sep = 0; - const var_t *var; - - if (!func->args) - return; - - LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) - { - int is_string = is_attr(var->attrs, ATTR_STRING); - in_attr = is_attr(var->attrs, ATTR_IN); - out_attr = is_attr(var->attrs, ATTR_OUT); - if (!out_attr && !in_attr) - in_attr = 1; - - if (!in_attr) - { - print_file(file, indent, ""); - write_name(file, var); - - if (var->type->size_is) - { - unsigned int size, align = 0; - type_t *type = var->type; - - fprintf(file, " = NdrAllocate(&_StubMsg, "); - for ( ; type->size_is ; type = type->ref) - { - write_expr(file, type->size_is, TRUE); - fprintf(file, " * "); - } - size = type_memsize(type, &align); - fprintf(file, "%u);\n", size); - } - else if (!is_string) - { - fprintf(file, " = &_W%u;\n", i); - if (is_ptr(var->type) && !last_ptr(var->type)) - print_file(file, indent, "_W%u = 0;\n", i); - i++; - } - - sep = 1; - } - } - if (sep) - fprintf(file, "\n"); -} - - -int write_expr_eval_routines(FILE *file, const char *iface) -{ - static const char *var_name = "pS"; - int result = 0; - struct expr_eval_routine *eval; - unsigned short callback_offset = 0; - - LIST_FOR_EACH_ENTRY(eval, &expr_eval_routines, struct expr_eval_routine, entry) - { - const char *name = eval->structure->name; - const var_list_t *fields = eval->structure->fields; - unsigned align = 0; - result = 1; - print_file(file, 0, "static void __RPC_USER %s_%sExprEval_%04u(PMIDL_STUB_MESSAGE pStubMsg)\n", - iface, name, callback_offset); - print_file(file, 0, "{\n"); - print_file (file, 1, "%s *%s = (%s *)(pStubMsg->StackTop - %u);\n", - name, var_name, name, type_memsize (eval->structure, &align)); - print_file(file, 1, "pStubMsg->Offset = 0;\n"); /* FIXME */ - print_file(file, 1, "pStubMsg->MaxCount = (unsigned long)"); - write_struct_expr(file, eval->expr, 1, fields, var_name); - fprintf(file, ";\n"); - print_file(file, 0, "}\n\n"); - callback_offset++; - } - return result; -} - -void write_expr_eval_routine_list(FILE *file, const char *iface) -{ - struct expr_eval_routine *eval; - struct expr_eval_routine *cursor; - unsigned short callback_offset = 0; - - fprintf(file, "static const EXPR_EVAL ExprEvalRoutines[] =\n"); - fprintf(file, "{\n"); - - LIST_FOR_EACH_ENTRY_SAFE(eval, cursor, &expr_eval_routines, struct expr_eval_routine, entry) - { - const char *name = eval->structure->name; - print_file(file, 1, "%s_%sExprEval_%04u,\n", iface, name, callback_offset); - callback_offset++; - list_remove(&eval->entry); - free(eval); - } - - fprintf(file, "};\n\n"); -} - -void write_user_quad_list(FILE *file) -{ - user_type_t *ut; - - if (list_empty(&user_type_list)) - return; - - fprintf(file, "static const USER_MARSHAL_ROUTINE_QUADRUPLE UserMarshalRoutines[] =\n"); - fprintf(file, "{\n"); - LIST_FOR_EACH_ENTRY(ut, &user_type_list, user_type_t, entry) - { - const char *sep = &ut->entry == list_tail(&user_type_list) ? "" : ","; - print_file(file, 1, "{\n"); - print_file(file, 2, "(USER_MARSHAL_SIZING_ROUTINE)%s_UserSize,\n", ut->name); - print_file(file, 2, "(USER_MARSHAL_MARSHALLING_ROUTINE)%s_UserMarshal,\n", ut->name); - print_file(file, 2, "(USER_MARSHAL_UNMARSHALLING_ROUTINE)%s_UserUnmarshal,\n", ut->name); - print_file(file, 2, "(USER_MARSHAL_FREEING_ROUTINE)%s_UserFree\n", ut->name); - print_file(file, 1, "}%s\n", sep); - } - fprintf(file, "};\n\n"); -} - -void write_endpoints( FILE *f, const char *prefix, const str_list_t *list ) -{ - const struct str_list_entry_t *endpoint; - const char *p; - - /* this should be an array of RPC_PROTSEQ_ENDPOINT but we want const strings */ - print_file( f, 0, "static const unsigned char * %s__RpcProtseqEndpoint[][2] =\n{\n", prefix ); - LIST_FOR_EACH_ENTRY( endpoint, list, const struct str_list_entry_t, entry ) - { - print_file( f, 1, "{ (const unsigned char *)\"" ); - for (p = endpoint->str; *p && *p != ':'; p++) - { - if (*p == '"' || *p == '\\') fputc( '\\', f ); - fputc( *p, f ); - } - if (!*p) goto error; - if (p[1] != '[') goto error; - - fprintf( f, "\", (const unsigned char *)\"" ); - for (p += 2; *p && *p != ']'; p++) - { - if (*p == '"' || *p == '\\') fputc( '\\', f ); - fputc( *p, f ); - } - if (*p != ']') goto error; - fprintf( f, "\" },\n" ); - } - print_file( f, 0, "};\n\n" ); - return; - -error: - error("Invalid endpoint syntax '%s'\n", endpoint->str); -} diff --git a/reactos/tools/widl_new/typegen.h b/reactos/tools/widl_new/typegen.h deleted file mode 100644 index eefecd79e8f..00000000000 --- a/reactos/tools/widl_new/typegen.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Format String Generator for IDL Compiler - * - * Copyright 2005-2006 Eric Kohl - * Copyright 2005 Robert Shearman - * - * 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 - -enum pass -{ - PASS_IN, - PASS_OUT, - PASS_RETURN -}; - -enum remoting_phase -{ - PHASE_BUFFERSIZE, - PHASE_MARSHAL, - PHASE_UNMARSHAL, - PHASE_FREE -}; - -void write_formatstringsdecl(FILE *f, int indent, ifref_list_t *ifaces, int for_objects); -void write_procformatstring(FILE *file, const ifref_list_t *ifaces, int for_objects); -void write_typeformatstring(FILE *file, const ifref_list_t *ifaces, int for_objects); -void print_phase_basetype(FILE *file, int indent, enum remoting_phase phase, enum pass pass, const var_t *var, const char *varname); -void write_remoting_arguments(FILE *file, int indent, const func_t *func, enum pass pass, enum remoting_phase phase); -size_t get_size_procformatstring_var(const var_t *var); -size_t get_size_procformatstring_func(const func_t *func); -size_t get_size_procformatstring(const ifref_list_t *ifaces, int for_objects); -size_t get_size_typeformatstring(const ifref_list_t *ifaces, int for_objects); -void assign_stub_out_args( FILE *file, int indent, const func_t *func ); -void declare_stub_args( FILE *file, int indent, const func_t *func ); -int write_expr_eval_routines(FILE *file, const char *iface); -void write_expr_eval_routine_list(FILE *file, const char *iface); -void write_user_quad_list(FILE *file); -void write_endpoints( FILE *f, const char *prefix, const str_list_t *list ); -size_t type_memsize(const type_t *t, unsigned int *align); -int decl_indirect(const type_t *t); -void write_parameters_init(FILE *file, int indent, const func_t *func); -void print(FILE *file, int indent, const char *format, va_list ap); diff --git a/reactos/tools/widl_new/typelib.c b/reactos/tools/widl_new/typelib.c deleted file mode 100644 index 7afeef6ffd8..00000000000 --- a/reactos/tools/widl_new/typelib.c +++ /dev/null @@ -1,399 +0,0 @@ -/* - * IDL Compiler - * - * Copyright 2004 Ove Kaaven - * Copyright 2006 Jacek Caban 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 "config.h" -#include "wine/port.h" -#include "wine/wpp.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#define NONAMELESSUNION -#define NONAMELESSSTRUCT - -#include "windef.h" -#include "winbase.h" - -#include "widl.h" -#include "utils.h" -#include "parser.h" -#include "header.h" -#include "typelib.h" -#include "widltypes.h" -#include "typelib_struct.h" - -int in_typelib = 0; - -static typelib_t *typelib; - -type_t *duptype(type_t *t, int dupname) -{ - type_t *d = xmalloc(sizeof *d); - - *d = *t; - if (dupname && t->name) - d->name = xstrdup(t->name); - - d->orig = t; - return d; -} - -type_t *alias(type_t *t, const char *name) -{ - type_t *a = duptype(t, 0); - - a->name = xstrdup(name); - a->kind = TKIND_ALIAS; - a->attrs = NULL; - a->declarray = FALSE; - - return a; -} - -int is_ptr(const type_t *t) -{ - unsigned char c = t->type; - return c == RPC_FC_RP - || c == RPC_FC_UP - || c == RPC_FC_FP - || c == RPC_FC_OP; -} - -int is_array(const type_t *t) -{ - switch (t->type) - { - case RPC_FC_SMFARRAY: - case RPC_FC_LGFARRAY: - case RPC_FC_SMVARRAY: - case RPC_FC_LGVARRAY: - case RPC_FC_CARRAY: - case RPC_FC_CVARRAY: - case RPC_FC_BOGUS_ARRAY: - return TRUE; - default: - return FALSE; - } -} - -/* List of oleauto types that should be recognized by name. - * (most of) these seem to be intrinsic types in mktyplib. */ - -static const struct oatype { - const char *kw; - unsigned short vt; -} oatypes[] = { - {"BSTR", VT_BSTR}, - {"CURRENCY", VT_CY}, - {"DATE", VT_DATE}, - {"DECIMAL", VT_DECIMAL}, - {"HRESULT", VT_HRESULT}, - {"LPSTR", VT_LPSTR}, - {"LPWSTR", VT_LPWSTR}, - {"SCODE", VT_ERROR}, - {"VARIANT", VT_VARIANT}, - {"VARIANT_BOOL", VT_BOOL} -}; -#define NTYPES (sizeof(oatypes)/sizeof(oatypes[0])) -#define KWP(p) ((const struct oatype *)(p)) - -static int kw_cmp_func(const void *s1, const void *s2) -{ - return strcmp(KWP(s1)->kw, KWP(s2)->kw); -} - -static unsigned short builtin_vt(const type_t *t) -{ - const char *kw = t->name; - struct oatype key; - const struct oatype *kwp; - key.kw = kw; -#ifdef KW_BSEARCH - kwp = bsearch(&key, oatypes, NTYPES, sizeof(oatypes[0]), kw_cmp_func); -#else - { - unsigned int i; - for (kwp=NULL, i=0; i < NTYPES; i++) - if (!kw_cmp_func(&key, &oatypes[i])) { - kwp = &oatypes[i]; - break; - } - } -#endif - if (kwp) { - return kwp->vt; - } - if (is_string_type (t->attrs, t)) - switch (t->ref->type) - { - case RPC_FC_CHAR: return VT_LPSTR; - case RPC_FC_WCHAR: return VT_LPWSTR; - default: break; - } - return 0; -} - -static int match(const char*n, const char*m) -{ - if (!n) return 0; - return !strcmp(n, m); -} - -unsigned short get_type_vt(type_t *t) -{ - unsigned short vt; - - chat("get_type_vt: %p type->name %s\n", t, t->name); - if (t->name) { - vt = builtin_vt(t); - if (vt) return vt; - } - - if (t->kind == TKIND_ALIAS && t->attrs) - return VT_USERDEFINED; - - switch (t->type) { - case RPC_FC_BYTE: - case RPC_FC_USMALL: - return VT_UI1; - case RPC_FC_CHAR: - case RPC_FC_SMALL: - return VT_I1; - case RPC_FC_WCHAR: - return VT_I2; /* mktyplib seems to parse wchar_t as short */ - case RPC_FC_SHORT: - return VT_I2; - case RPC_FC_USHORT: - return VT_UI2; - case RPC_FC_LONG: - if (match(t->name, "int")) return VT_INT; - return VT_I4; - case RPC_FC_ULONG: - if (match(t->name, "int")) return VT_UINT; - return VT_UI4; - case RPC_FC_HYPER: - if (t->sign < 0) return VT_UI8; - if (match(t->name, "MIDL_uhyper")) return VT_UI8; - return VT_I8; - case RPC_FC_FLOAT: - return VT_R4; - case RPC_FC_DOUBLE: - return VT_R8; - case RPC_FC_RP: - case RPC_FC_UP: - case RPC_FC_OP: - case RPC_FC_FP: - case RPC_FC_CARRAY: - case RPC_FC_CVARRAY: - if(t->ref) - { - if (match(t->ref->name, "SAFEARRAY")) - return VT_SAFEARRAY; - return VT_PTR; - } - - error("get_type_vt: unknown-deref-type: %d\n", t->ref->type); - break; - case RPC_FC_IP: - if(match(t->name, "IUnknown")) - return VT_UNKNOWN; - if(match(t->name, "IDispatch")) - return VT_DISPATCH; - return VT_USERDEFINED; - - case RPC_FC_ENUM16: - case RPC_FC_STRUCT: - case RPC_FC_PSTRUCT: - case RPC_FC_CSTRUCT: - case RPC_FC_CPSTRUCT: - case RPC_FC_CVSTRUCT: - case RPC_FC_BOGUS_STRUCT: - return VT_USERDEFINED; - case 0: - return t->kind == TKIND_PRIMITIVE ? VT_VOID : VT_USERDEFINED; - default: - error("get_type_vt: unknown type: 0x%02x\n", t->type); - } - return 0; -} - -void start_typelib(char *name, attr_list_t *attrs) -{ - in_typelib++; - if (!do_typelib) return; - - typelib = xmalloc(sizeof(*typelib)); - typelib->name = xstrdup(name); - typelib->filename = xstrdup(typelib_name); - typelib->attrs = attrs; - list_init( &typelib->entries ); - list_init( &typelib->importlibs ); -} - -void end_typelib(void) -{ - in_typelib--; - if (!typelib) return; - - create_msft_typelib(typelib); - return; -} - -void add_typelib_entry(type_t *t) -{ - typelib_entry_t *entry; - if (!typelib) return; - - chat("add kind %i: %s\n", t->kind, t->name); - entry = xmalloc(sizeof(*entry)); - entry->type = t; - list_add_tail( &typelib->entries, &entry->entry ); -} - -static void tlb_read(int fd, void *buf, int count) -{ - if(read(fd, buf, count) < count) - error("error while reading importlib.\n"); -} - -static void tlb_lseek(int fd, off_t offset) -{ - if(lseek(fd, offset, SEEK_SET) == -1) - error("lseek failed\n"); -} - -static void msft_read_guid(int fd, MSFT_SegDir *segdir, int offset, GUID *guid) -{ - tlb_lseek(fd, segdir->pGuidTab.offset+offset); - tlb_read(fd, guid, sizeof(GUID)); -} - -static void read_msft_importlib(importlib_t *importlib, int fd) -{ - MSFT_Header header; - MSFT_SegDir segdir; - int *typeinfo_offs; - int i; - - importlib->allocated = 0; - - tlb_lseek(fd, 0); - tlb_read(fd, &header, sizeof(header)); - - importlib->version = header.version; - - typeinfo_offs = xmalloc(header.nrtypeinfos*sizeof(INT)); - tlb_read(fd, typeinfo_offs, header.nrtypeinfos*sizeof(INT)); - tlb_read(fd, &segdir, sizeof(segdir)); - - msft_read_guid(fd, &segdir, header.posguid, &importlib->guid); - - importlib->ntypeinfos = header.nrtypeinfos; - importlib->importinfos = xmalloc(importlib->ntypeinfos*sizeof(importinfo_t)); - - for(i=0; i < importlib->ntypeinfos; i++) { - MSFT_TypeInfoBase base; - MSFT_NameIntro nameintro; - int len; - - tlb_lseek(fd, sizeof(MSFT_Header) + header.nrtypeinfos*sizeof(INT) + sizeof(MSFT_SegDir) - + typeinfo_offs[i]); - tlb_read(fd, &base, sizeof(base)); - - importlib->importinfos[i].importlib = importlib; - importlib->importinfos[i].flags = (base.typekind&0xf)<<24; - importlib->importinfos[i].offset = -1; - importlib->importinfos[i].id = i; - - if(base.posguid != -1) { - importlib->importinfos[i].flags |= MSFT_IMPINFO_OFFSET_IS_GUID; - msft_read_guid(fd, &segdir, base.posguid, &importlib->importinfos[i].guid); - } - else memset( &importlib->importinfos[i].guid, 0, sizeof(importlib->importinfos[i].guid)); - - tlb_lseek(fd, segdir.pNametab.offset + base.NameOffset); - tlb_read(fd, &nameintro, sizeof(nameintro)); - - len = nameintro.namelen & 0xff; - - importlib->importinfos[i].name = xmalloc(len+1); - tlb_read(fd, importlib->importinfos[i].name, len); - importlib->importinfos[i].name[len] = 0; - } - - free(typeinfo_offs); -} - -static void read_importlib(importlib_t *importlib) -{ - int fd; - INT magic; - char *file_name; - - file_name = wpp_find_include(importlib->name, NULL); - if(file_name) { - fd = open(file_name, O_RDONLY); - free(file_name); - }else { - fd = open(importlib->name, O_RDONLY); - } - - if(fd < 0) - error("Could not open importlib %s.\n", importlib->name); - - tlb_read(fd, &magic, sizeof(magic)); - - switch(magic) { - case MSFT_MAGIC: - read_msft_importlib(importlib, fd); - break; - default: - error("Wrong or unsupported typelib magic %x\n", magic); - }; - - close(fd); -} - -void add_importlib(const char *name) -{ - importlib_t *importlib; - - if(!typelib) return; - - LIST_FOR_EACH_ENTRY( importlib, &typelib->importlibs, importlib_t, entry ) - if(!strcmp(name, importlib->name)) - return; - - chat("add_importlib: %s\n", name); - - importlib = xmalloc(sizeof(*importlib)); - memset( importlib, 0, sizeof(*importlib) ); - importlib->name = xstrdup(name); - - read_importlib(importlib); - list_add_head( &typelib->importlibs, &importlib->entry ); -} diff --git a/reactos/tools/widl_new/typelib.h b/reactos/tools/widl_new/typelib.h deleted file mode 100644 index b17387dfc39..00000000000 --- a/reactos/tools/widl_new/typelib.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * IDL Compiler - * - * Copyright 2004 Ove Kaaven - * - * 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 - */ - -#ifndef __WIDL_TYPELIB_H -#define __WIDL_TYPELIB_H - -extern int in_typelib; -extern void start_typelib(char *name, attr_list_t *attrs); -extern void end_typelib(void); -extern void add_typelib_entry(type_t *t); -extern void add_importlib(const char *name); - -/* Copied from wtypes.h. Not included directly because that would create a - * circular dependency (after all, wtypes.h is generated by widl...) */ - -enum VARENUM { - VT_EMPTY = 0, - VT_NULL = 1, - VT_I2 = 2, - VT_I4 = 3, - VT_R4 = 4, - VT_R8 = 5, - VT_CY = 6, - VT_DATE = 7, - VT_BSTR = 8, - VT_DISPATCH = 9, - VT_ERROR = 10, - VT_BOOL = 11, - VT_VARIANT = 12, - VT_UNKNOWN = 13, - VT_DECIMAL = 14, - VT_I1 = 16, - VT_UI1 = 17, - VT_UI2 = 18, - VT_UI4 = 19, - VT_I8 = 20, - VT_UI8 = 21, - VT_INT = 22, - VT_UINT = 23, - VT_VOID = 24, - VT_HRESULT = 25, - VT_PTR = 26, - VT_SAFEARRAY = 27, - VT_CARRAY = 28, - VT_USERDEFINED = 29, - VT_LPSTR = 30, - VT_LPWSTR = 31, - VT_RECORD = 36, - VT_FILETIME = 64, - VT_BLOB = 65, - VT_STREAM = 66, - VT_STORAGE = 67, - VT_STREAMED_OBJECT = 68, - VT_STORED_OBJECT = 69, - VT_BLOB_OBJECT = 70, - VT_CF = 71, - VT_CLSID = 72, - VT_BSTR_BLOB = 0xfff, - VT_VECTOR = 0x1000, - VT_ARRAY = 0x2000, - VT_BYREF = 0x4000, - VT_RESERVED = 0x8000, - VT_ILLEGAL = 0xffff, - VT_ILLEGALMASKED = 0xfff, - VT_TYPEMASK = 0xfff -}; -extern unsigned short get_type_vt(type_t *t); - -extern int create_msft_typelib(typelib_t *typelib); -#endif diff --git a/reactos/tools/widl_new/typelib_struct.h b/reactos/tools/widl_new/typelib_struct.h deleted file mode 100644 index e16387c8dcd..00000000000 --- a/reactos/tools/widl_new/typelib_struct.h +++ /dev/null @@ -1,605 +0,0 @@ -/* - * typelib_struct.h internal wine data structures - * used to decode typelib's - * - * Copyright 1999 Rein KLazes - * - * 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 - */ -#ifndef _WIDL_TYPELIB_STRUCT_H -#define _WIDL_TYPELIB_STRUCT_H - -#define HELPDLLFLAG (0x0100) -#define DO_NOT_SEEK (-1) - -#define MSFT_HREFTYPE_INTHISFILE(href) (!((href) & 3)) -#define MSFT_HREFTYPE_INDEX(href) ((href) /sizeof(MSFT_TypeInfoBase)) - -/*-------------------------FILE STRUCTURES-----------------------------------*/ - -/* There are two known file formats, those created with ICreateTypeLib - * have the signature "SLTG" as their first four bytes, while those created - * with ICreateTypeLib2 have "MSFT". - */ - -#define MSFT_MAGIC 0x5446534d - -/***************************************************** - * MSFT typelibs - * - * These are TypeLibs created with ICreateTypeLib2 - * - */ - -/* - * structure of the typelib type2 header - * it is at the beginning of a type lib file - * - */ -typedef struct tagMSFT_Header { -/*0x00*/INT magic1; /* 0x5446534D "MSFT" */ - INT magic2; /* 0x00010002 version nr? */ - INT posguid; /* position of libid in guid table */ - /* (should be, else -1) */ - INT lcid; /* locale id */ -/*0x10*/INT lcid2; - INT varflags; /* (largely) unknown flags */ - /* the lower nibble is syskind */ - /* 0x40 always seems to be set */ - /* 0x10 set with a helpfile defined */ - /* 0x100 set with a helpstringdll defined - in this - case the offset to the name in the stringtable - appears right after this struct, before the - typeinfo offsets */ - INT version; /* set with SetVersion() */ - INT flags; /* set with SetFlags() */ -/*0x20*/INT nrtypeinfos; /* number of typeinfo's (till so far) */ - INT helpstring; /* position of help string in stringtable */ - INT helpstringcontext; - INT helpcontext; -/*0x30*/INT nametablecount; /* number of names in name table */ - INT nametablechars; /* nr of characters in name table */ - INT NameOffset; /* offset of name in name table */ - INT helpfile; /* position of helpfile in stringtable */ -/*0x40*/INT CustomDataOffset; /* if -1 no custom data, else it is offset */ - /* in customer data/guid offset table */ - INT res44; /* unknown always: 0x20 (guid hash size?) */ - INT res48; /* unknown always: 0x80 (name hash size?) */ - INT dispatchpos; /* HREFTYPE to IDispatch, or -1 if no IDispatch */ -/*0x50*/INT nimpinfos; /* number of impinfos */ -} MSFT_Header; - -/* segments in the type lib file have a structure like this: */ -typedef struct tagMSFT_pSeg { - INT offset; /* absolute offset in file */ - INT length; /* length of segment */ - INT res08; /* unknown always -1 */ - INT res0c; /* unknown always 0x0f in the header */ - /* 0x03 in the typeinfo_data */ -} MSFT_pSeg; - -/* layout of the main segment directory */ -typedef struct tagMSFT_SegDir { -/*1*/MSFT_pSeg pTypeInfoTab; /* each type info get an entry of 0x64 bytes */ - /* (25 ints) */ -/*2*/MSFT_pSeg pImpInfo; /* table with info for imported types */ -/*3*/MSFT_pSeg pImpFiles; /* import libaries */ -/*4*/MSFT_pSeg pRefTab; /* References table */ -/*5*/MSFT_pSeg pLibtab; /* always exists, alway same size (0x80) */ - /* hash table w offsets to guid????? */ -/*6*/MSFT_pSeg pGuidTab; /* all guids are stored here together with */ - /* offset in some table???? */ -/*7*/MSFT_pSeg res07; /* always created, alway same size (0x200) */ - /* purpose largely unknown */ -/*8*/MSFT_pSeg pNametab; /* name tables */ -/*9*/MSFT_pSeg pStringtab; /* string table */ -/*A*/MSFT_pSeg pTypdescTab; /* table with type descriptors */ -/*B*/MSFT_pSeg pArrayDescriptions; -/*C*/MSFT_pSeg pCustData; /* data table, used for custom data and default */ - /* parameter values */ -/*D*/MSFT_pSeg pCDGuids; /* table with offsets for the guids and into */ - /* the customer data table */ -/*E*/MSFT_pSeg res0e; /* unknown */ -/*F*/MSFT_pSeg res0f; /* unknown */ -} MSFT_SegDir; - - -/* base type info data */ -typedef struct tagMSFT_TypeInfoBase { -/*000*/ INT typekind; /* it is the TKIND_xxx */ - /* some byte alignment stuf */ - INT memoffset; /* points past the file, if no elements */ - INT res2; /* zero if no element, N*0x40 */ - INT res3; /* -1 if no lement, (N-1)*0x38 */ -/*010*/ INT res4; /* always? 3 */ - INT res5; /* always? zero */ - INT cElement; /* counts elements, HI=cVars, LO=cFuncs */ - INT res7; /* always? zero */ -/*020*/ INT res8; /* always? zero */ - INT res9; /* always? zero */ - INT resA; /* always? zero */ - INT posguid; /* position in guid table */ -/*030*/ INT flags; /* Typeflags */ - INT NameOffset; /* offset in name table */ - INT version; /* element version */ - INT docstringoffs; /* offset of docstring in string tab */ -/*040*/ INT helpstringcontext; /* */ - INT helpcontext; /* */ - INT oCustData; /* offset in customer data table */ -#ifdef WORDS_BIGENDIAN - INT16 cbSizeVft; /* virtual table size, including inherits */ - INT16 cImplTypes; /* nr of implemented interfaces */ -#else - INT16 cImplTypes; /* nr of implemented interfaces */ - INT16 cbSizeVft; /* virtual table size, including inherits */ -#endif -/*050*/ INT size; /* size in bytes, at least for structures */ - /* FIXME: name of this field */ - INT datatype1; /* position in type description table */ - /* or in base interfaces */ - /* if coclass: offset in reftable */ - /* if interface: reference to inherited if */ - INT datatype2; /* for interfaces: hiword is num of inherited funcs */ - /* loword is num of inherited interfaces */ - INT res18; /* always? 0 */ -/*060*/ INT res19; /* always? -1 */ -} MSFT_TypeInfoBase; - -/* layout of an entry with information on imported types */ -typedef struct tagMSFT_ImpInfo { - INT flags; /* bits 0 - 15: count */ - /* bit 16: if set oGuid is an offset to Guid */ - /* if clear oGuid is a typeinfo index in the specified typelib */ - /* bits 24 - 31: TKIND of reference */ - INT oImpFile; /* offset in the Import File table */ - INT oGuid; /* offset in Guid table or typeinfo index (see bit 16 of flags) */ -} MSFT_ImpInfo; - -#define MSFT_IMPINFO_OFFSET_IS_GUID 0x00010000 - -/* function description data */ -typedef struct { -/* INT recsize; record size including some xtra stuff */ - INT DataType; /* data type of the member, eg return of function */ - INT Flags; /* something to do with attribute flags (LOWORD) */ -#ifdef WORDS_BIGENDIAN - INT16 funcdescsize; /* size of reconstituted FUNCDESC and related structs */ - INT16 VtableOffset; /* offset in vtable */ -#else - INT16 VtableOffset; /* offset in vtable */ - INT16 funcdescsize; /* size of reconstituted FUNCDESC and related structs */ -#endif - INT FKCCIC; /* bit string with the following */ - /* meaning (bit 0 is the lsb): */ - /* bits 0 - 2: FUNCKIND */ - /* bits 3 - 6: INVOKEKIND */ - /* bit 7: custom data present */ - /* bits 8 - 11: CALLCONV */ - /* bit 12: parameters have default values */ - /* bit 13: oEntry is numeric */ - /* bit 14: has retval param */ - /* bits 16 - 31: index of next function with same id */ -#ifdef WORDS_BIGENDIAN - INT16 nroargs; /* nr of optional arguments */ - INT16 nrargs; /* number of arguments (including optional ????) */ -#else - INT16 nrargs; /* number of arguments (including optional ????) */ - INT16 nroargs; /* nr of optional arguments */ -#endif - /* optional attribute fields, the number of them is variable */ - INT OptAttr[1]; -/* -0* INT helpcontext; -1* INT oHelpString; -2* INT oEntry; // either offset in string table or numeric as it is (see bit 13 of FKCCIC) // -3* INT res9; // unknown (-1) // -4* INT resA; // unknown (-1) // -5* INT HelpStringContext; - // these are controlled by a bit set in the FKCCIC field // -6* INT oCustData; // custom data for function // -7* INT oArgCustData[1]; // custom data per argument // -*/ -} MSFT_FuncRecord; - -/* after this may follow an array with default value pointers if the - * appropriate bit in the FKCCIC field has been set: - * INT oDefautlValue[nrargs]; - */ - - /* Parameter info one per argument*/ -typedef struct { - INT DataType; - INT oName; - INT Flags; - } MSFT_ParameterInfo; - -/* Variable description data */ -typedef struct { -/* INT recsize; // record size including some xtra stuff */ - INT DataType; /* data type of the variable */ - INT Flags; /* VarFlags (LOWORD) */ -#ifdef WORDS_BIGENDIAN - INT16 vardescsize; /* size of reconstituted VARDESC and related structs */ - INT16 VarKind; /* VarKind */ -#else - INT16 VarKind; /* VarKind */ - INT16 vardescsize; /* size of reconstituted VARDESC and related structs */ -#endif - INT OffsValue; /* value of the variable or the offset */ - /* in the data structure */ - /* optional attribute fields, the number of them is variable */ - /* controlled by record length */ - INT HelpContext; - INT oHelpString; - INT res9; /* unknown (-1) */ - INT oCustData; /* custom data for variable */ - INT HelpStringContext; - -} MSFT_VarRecord; - -/* Structure of the reference data */ -typedef struct { - INT reftype; /* either offset in type info table, then it's */ - /* a multiple of 64 */ - /* or offset in the external reference table */ - /* with an offset of 1 */ - INT flags; - INT oCustData; /* custom data */ - INT onext; /* next offset, -1 if last */ -} MSFT_RefRecord; - -/* this is how a guid is stored */ -typedef struct { - GUID guid; - INT hreftype; /* -2 for the typelib guid, typeinfo offset - for typeinfo guid, low two bits are 01 if - this is an imported typeinfo, low two bits - are 10 if this is an imported typelib (used - by imported typeinfos) */ - INT next_hash; /* offset to next guid in the hash bucket */ -} MSFT_GuidEntry; -/* some data preceding entries in the name table */ -typedef struct { - INT hreftype; /* is -1 if name is for neither a typeinfo, - a variable, or a function (that is, name - is for a typelib or a function parameter). - otherwise is the offset of the first - typeinfo that this name refers to (either - to the typeinfo itself or to a member of - the typeinfo */ - INT next_hash; /* offset to next name in the hash bucket */ - INT namelen; /* only lower 8 bits are valid */ - /* 0x1000 if name is only used once as a variable name */ - /* 0x2000 if name is a variable in an enumeration */ - /* 0x3800 if name is typeinfo name */ - /* upper 16 bits are hash code */ -} MSFT_NameIntro; -/* the custom data table directory has entries like this */ -typedef struct { - INT GuidOffset; - INT DataOffset; - INT next; /* next offset in the table, -1 if it's the last */ -} MSFT_CDGuid; - - -/*********************************************************** - * - * SLTG typelibs. - * - * These are created with ICreateTypeLib - * - */ - -#include "pshpack1.h" - -typedef struct { -/*00*/ DWORD SLTG_magic; /* 0x47544c53 == "SLTG" */ -/*04*/ WORD nrOfFileBlks; /* no of SLTG_BlkEntry's + 1 */ -/*06*/ WORD res06; /* ?? always 9 */ -/*08*/ WORD res08; /* some kind of len/offset ?? */ -/*0a*/ WORD first_blk; /* 1 based index into blk entries that - corresponds to first block in file */ -/*0c*/ DWORD res0c; /* always 0x000204ff */ -/*10*/ DWORD res10; /* always 0x00000000 */ -/*14*/ DWORD res14; /* always 0x000000c0 */ -/*18*/ DWORD res18; /* always 0x46000000 */ -/*1c*/ DWORD res1c; /* always 0x00000044 */ -/*20*/ DWORD res20; /* always 0xffff0000 */ -} SLTG_Header; - -/* This gets followed by a list of block entries */ -typedef struct { -/*00*/ DWORD len; -/*04*/ WORD index_string; /* offs from start of SLTG_Magic to index string */ -/*06*/ WORD next; -} SLTG_BlkEntry; - -/* The order of the blocks in the file is given by starting at Block - entry firt_blk and stepping through using the next pointer */ - -/* These then get followed by this magic */ -typedef struct { -/*00*/ BYTE res00; /* always 0x01 */ -/*01*/ CHAR CompObj_magic[8]; /* always "CompObj" */ -/*09*/ CHAR dir_magic[4]; /* always "dir" */ -} SLTG_Magic; - -#define SLTG_COMPOBJ_MAGIC "CompObj" -#define SLTG_DIR_MAGIC "dir" - -/* Next we have SLTG_Header.nrOfFileBlks - 2 of Index strings. These -are presumably unique to within the file and look something like -"AAAAAAAAAA" with the first character incremented from 'A' to ensure -uniqueness. I guess successive chars increment when we need to wrap -the first one. */ - -typedef struct { -/*00*/ CHAR string[11]; -} SLTG_Index; - - -/* This is followed by SLTG_pad9 */ -typedef struct { -/*00*/ CHAR pad[9]; /* 9 '\0's */ -} SLTG_Pad9; - - -/* Now we have the noOfFileBlks - 1 worth of blocks. The length of -each block is given by its entry in SLTG_BlkEntry. */ - -/* type SLTG_NAME in rather like a BSTR except that the length in -bytes is given by the first WORD and the string contains 8bit chars */ - -typedef WORD SLTG_Name; - -/* The main library block looks like this. This one seems to come last */ - -typedef struct { -/*00*/ WORD magic; /* 0x51cc */ -/*02*/ WORD res02; /* 0x0003, 0x0004 */ -/*04*/ WORD name; /* offset to name in name table */ -/*06*/ SLTG_Name res06; /* maybe this is just WORD == 0xffff */ - SLTG_Name helpstring; - SLTG_Name helpfile; - DWORD helpcontext; - WORD syskind; /* == 1 for win32, 0 for win16 */ - WORD lcid; /* == 0x409, 0x809 etc */ - DWORD res12; /* == 0 */ - WORD libflags; /* LIBFLAG_* */ - WORD maj_vers; - WORD min_vers; - GUID uuid; -} SLTG_LibBlk; - -#define SLTG_LIBBLK_MAGIC 0x51cc - -/* we then get 0x40 bytes worth of 0xffff or small numbers followed by - nrOfFileBlks - 2 of these */ -typedef struct { - WORD small_no; - SLTG_Name index_name; /* This refers to a name in the directory */ - SLTG_Name other_name; /* Another one of these weird names */ - WORD res1a; /* 0xffff */ - WORD name_offs; /* offset to name in name table */ - WORD more_bytes; /* if this is non-zero we get this many - bytes before the next element, which seem - to reference the docstring of the type ? */ - WORD res20; /* 0xffff */ - DWORD helpcontext; - WORD res26; /* 0xffff */ - GUID uuid; -} SLTG_OtherTypeInfo; - -/* Next we get WORD 0x0003 followed by a DWORD which if we add to -0x216 gives the offset to the name table from the start of the LibBlk -struct */ - -typedef struct { -/*00*/ WORD magic; /* 0x0501 */ -/*02*/ DWORD href_table; /* if not 0xffffffff, then byte offset from - beginning of struct to href table */ -/*06*/ DWORD res06; /* 0xffffffff */ -/*0a*/ DWORD elem_table; /* offset to members */ -/*0e*/ DWORD res0e; /* 0xffffffff */ -/*12*/ WORD major_version; /* major version number */ -/*14*/ WORD minor_version; /* minor version number */ -/*16*/ DWORD res16; /* 0xfffe0000 */ -/*1a*/ BYTE typeflags1;/* 0x02 | top 5 bits hold l5sbs of TYPEFLAGS */ -/*1b*/ BYTE typeflags2;/* TYPEFLAGS >> 5 */ -/*1c*/ BYTE typeflags3;/* 0x02*/ -/*1d*/ BYTE typekind; /* 0x03 == TKIND_INTERFACE etc. */ -/*1e*/ DWORD res1e; /* 0x00000000 or 0xffffffff */ -} SLTG_TypeInfoHeader; - -#define SLTG_TIHEADER_MAGIC 0x0501 - -typedef struct { -/*00*/ WORD cFuncs; -/*02*/ WORD cVars; -/*04*/ WORD cImplTypes; -/*06*/ WORD res06; -/*08*/ WORD res08; -/*0a*/ WORD res0a; -/*0c*/ WORD res0c; -/*0e*/ WORD res0e; -/*10*/ WORD res10; -/*12*/ WORD res12; -/*14*/ WORD tdescalias_vt; /* for TKIND_ALIAS */ -/*16*/ WORD res16; -/*18*/ WORD res18; -/*1a*/ WORD res1a; -/*1c*/ WORD res1c; -/*1e*/ WORD res1e; -/*20*/ WORD cbSizeInstance; -/*22*/ WORD cbAlignment; -/*24*/ WORD res24; -/*26*/ WORD res26; -/*28*/ WORD cbSizeVft; -/*2a*/ WORD res2a; -/*2c*/ WORD res2c; -/*2e*/ WORD res2e; -/*30*/ WORD res30; -/*32*/ WORD res32; -/*34*/ WORD res34; -} SLTG_TypeInfoTail; - -typedef struct { -/*00*/ WORD res00; /* 0x0001 sometimes 0x0003 ?? */ -/*02*/ WORD res02; /* 0xffff */ -/*04*/ BYTE res04; /* 0x01 */ -/*05*/ DWORD cbExtra; /* No of bytes that follow */ -} SLTG_MemberHeader; - -typedef struct { -/*00*/ WORD magic; /* 0x120a */ -/*02*/ WORD next; /* offset in bytes to next block from start of block - group, 0xffff if last item */ -/*04*/ WORD name; /* offset to name within name table */ -/*06*/ WORD value; /* offset to value from start of block group */ -/*08*/ WORD res08; /* 0x56 */ -/*0a*/ DWORD memid; /* memid */ -/*0e*/ WORD helpcontext;/* 0xfffe == no context, 0x0001 == stored in EnumInfo struct, else offset - to value from start of block group */ -/*10*/ WORD helpstring;/* offset from start of block group to string offset */ -} SLTG_EnumItem; - -#define SLTG_ENUMITEM_MAGIC 0x120a - -typedef struct { -/*00*/ WORD vt; /* vartype, 0xffff marks end. */ -/*02*/ WORD res02; /* ?, 0xffff marks end */ -} SLTG_AliasItem; - -#define SLTG_ALIASITEM_MAGIC 0x001d - - -typedef struct { - BYTE magic; /* 0x4c or 0x6c */ - BYTE inv; /* high nibble is INVOKE_KIND, low nibble = 2 */ - WORD next; /* byte offset from beginning of group to next fn */ - WORD name; /* Offset within name table to name */ - DWORD dispid; /* dispid */ - WORD helpcontext; /* helpcontext (again 1 is special) */ - WORD helpstring;/* helpstring offset to offset */ - WORD arg_off; /* offset to args from start of block */ - BYTE nacc; /* lowest 3bits are CALLCONV, rest are no of args */ - BYTE retnextopt;/* if 0x80 bit set ret type follows else next WORD - is offset to ret type. No of optional args is - middle 6 bits */ - WORD rettype; /* return type VT_?? or offset to ret type */ - WORD vtblpos; /* position in vtbl? */ - WORD funcflags; /* present if magic == 0x6c */ -/* Param list starts, repeat next two as required */ -#if 0 - WORD name; /* offset to 2nd letter of name */ - WORD+ type; /* VT_ of param */ -#endif -} SLTG_Function; - -#define SLTG_FUNCTION_MAGIC 0x4c -#define SLTG_FUNCTION_WITH_FLAGS_MAGIC 0x6c - -typedef struct { -/*00*/ BYTE magic; /* 0xdf */ -/*01*/ BYTE res01; /* 0x00 */ -/*02*/ DWORD res02; /* 0xffffffff */ -/*06*/ DWORD res06; /* 0xffffffff */ -/*0a*/ DWORD res0a; /* 0xffffffff */ -/*0e*/ DWORD res0e; /* 0xffffffff */ -/*12*/ DWORD res12; /* 0xffffffff */ -/*16*/ DWORD res16; /* 0xffffffff */ -/*1a*/ DWORD res1a; /* 0xffffffff */ -/*1e*/ DWORD res1e; /* 0xffffffff */ -/*22*/ DWORD res22; /* 0xffffffff */ -/*26*/ DWORD res26; /* 0xffffffff */ -/*2a*/ DWORD res2a; /* 0xffffffff */ -/*2e*/ DWORD res2e; /* 0xffffffff */ -/*32*/ DWORD res32; /* 0xffffffff */ -/*36*/ DWORD res36; /* 0xffffffff */ -/*3a*/ DWORD res3a; /* 0xffffffff */ -/*3e*/ DWORD res3e; /* 0xffffffff */ -/*42*/ WORD res42; /* 0xffff */ -/*44*/ DWORD number; /* this is 8 times the number of refs */ -/*48*/ /* Now we have number bytes (8 for each ref) of SLTG_UnknownRefInfo */ - -/*50*/ WORD res50; /* 0xffff */ -/*52*/ BYTE res52; /* 0x01 */ -/*53*/ DWORD res53; /* 0x00000000 */ -/*57*/ SLTG_Name names[1]; - /* Now we have number/8 SLTG_Names (first WORD is no of bytes in the ascii - * string). Strings look like "*\Rxxxx*#n". If xxxx == ffff then the - * ref refers to the nth type listed in this library (0 based). Else - * the xxxx (which maybe fewer than 4 digits) is the offset into the name - * table to a string "*\G{}#1.0#0#C:\WINNT\System32\stdole32.tlb#" - * The guid is the typelib guid; the ref again refers to the nth type of - * the imported typelib. - */ - -/*xx*/ BYTE resxx; /* 0xdf */ - -} SLTG_RefInfo; - -#define SLTG_REF_MAGIC 0xdf - -typedef struct { - WORD res00; /* 0x0001 */ - BYTE res02; /* 0x02 */ - BYTE res03; /* 0x40 if internal ref, 0x00 if external ? */ - WORD res04; /* 0xffff */ - WORD res06; /* 0x0000, 0x0013 or 0xffff ?? */ -} SLTG_UnknownRefInfo; - -typedef struct { - WORD res00; /* 0x004a */ - WORD next; /* byte offs to next interface */ - WORD res04; /* 0xffff */ - BYTE impltypeflags; /* IMPLTYPEFLAG_* */ - BYTE res07; /* 0x80 */ - WORD res08; /* 0x0012, 0x0028 ?? */ - WORD ref; /* number in ref table ? */ - WORD res0c; /* 0x4000 */ - WORD res0e; /* 0xfffe */ - WORD res10; /* 0xffff */ - WORD res12; /* 0x001d */ - WORD pos_in_table; /* 0x0, 0x4, ? */ -} SLTG_ImplInfo; - -#define SLTG_IMPL_MAGIC 0x004a - -typedef struct { - BYTE magic; /* 0x0a */ - BYTE typepos; - WORD next; - WORD name; - WORD byte_offs; /* pos in struct */ - WORD type; /* if typepos == 0x02 this is the type, else offset to type */ - DWORD memid; - WORD helpcontext; /* ?? */ - WORD helpstring; /* ?? */ -} SLTG_RecordItem; - -#define SLTG_RECORD_MAGIC 0x0a - - -/* CARRAYs look like this -WORD type == VT_CARRAY -WORD offset from start of block to SAFEARRAY -WORD typeofarray -*/ - -#include "poppack.h" - -/*---------------------------END--------------------------------------------*/ -#endif diff --git a/reactos/tools/widl_new/utils.c b/reactos/tools/widl_new/utils.c deleted file mode 100644 index 007d1cb0311..00000000000 --- a/reactos/tools/widl_new/utils.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Utility routines - * - * Copyright 1998 Bertho A. Stultiens - * Copyright 2002 Ove Kaaven - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" -#include "wine/port.h" - -#include -#include -#include -#include -#include -#include -#include - -#include "widl.h" -#include "utils.h" -#include "parser.h" - -static const int want_near_indication = 0; - -static void make_print(char *str) -{ - while(*str) - { - if(!isprint(*str)) - *str = ' '; - str++; - } -} - -static void generic_msg(const char *s, const char *t, const char *n, va_list ap) -{ - fprintf(stderr, "%s:%d: %s: ", input_name ? input_name : "stdin", line_number, t); - vfprintf(stderr, s, ap); - - if (want_near_indication) - { - char *cpy; - if(n) - { - cpy = xstrdup(n); - make_print(cpy); - fprintf(stderr, " near '%s'", cpy); - free(cpy); - } - } - - fprintf(stderr, "\n"); -} - - -int parser_error(const char *s, ...) -{ - va_list ap; - va_start(ap, s); - generic_msg(s, "Error", parser_text, ap); - va_end(ap); - exit(1); - return 1; -} - -int parser_warning(const char *s, ...) -{ - va_list ap; - va_start(ap, s); - generic_msg(s, "Warning", parser_text, ap); - va_end(ap); - return 0; -} - -void internal_error(const char *file, int line, const char *s, ...) -{ - va_list ap; - va_start(ap, s); - fprintf(stderr, "Internal error (please report) %s %d: ", file, line); - vfprintf(stderr, s, ap); - va_end(ap); - exit(3); -} - -void error(const char *s, ...) -{ - va_list ap; - va_start(ap, s); - fprintf(stderr, "error: "); - vfprintf(stderr, s, ap); - va_end(ap); - exit(2); -} - -void warning(const char *s, ...) -{ - va_list ap; - va_start(ap, s); - fprintf(stderr, "warning: "); - vfprintf(stderr, s, ap); - va_end(ap); -} - -void chat(const char *s, ...) -{ - if(debuglevel & DEBUGLEVEL_CHAT) - { - va_list ap; - va_start(ap, s); - fprintf(stderr, "chat: "); - vfprintf(stderr, s, ap); - va_end(ap); - } -} - -char *dup_basename(const char *name, const char *ext) -{ - int namelen; - int extlen = strlen(ext); - char *base; - char *slash; - - if(!name) - name = "widl.tab"; - - slash = strrchr(name, '/'); - if (slash) - name = slash + 1; - - namelen = strlen(name); - - /* +4 for later extension and +1 for '\0' */ - base = xmalloc(namelen +4 +1); - strcpy(base, name); - if(!strcasecmp(name + namelen-extlen, ext)) - { - base[namelen - extlen] = '\0'; - } - return base; -} - -void *xmalloc(size_t size) -{ - void *res; - - assert(size > 0); - res = malloc(size); - if(res == NULL) - { - error("Virtual memory exhausted.\n"); - } - memset(res, 0x55, size); - return res; -} - - -void *xrealloc(void *p, size_t size) -{ - void *res; - - assert(size > 0); - res = realloc(p, size); - if(res == NULL) - { - error("Virtual memory exhausted.\n"); - } - return res; -} - -char *xstrdup(const char *str) -{ - char *s; - - assert(str != NULL); - s = xmalloc(strlen(str)+1); - return strcpy(s, str); -} diff --git a/reactos/tools/widl_new/utils.h b/reactos/tools/widl_new/utils.h deleted file mode 100644 index 3641aaecae1..00000000000 --- a/reactos/tools/widl_new/utils.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Utility routines' prototypes etc. - * - * Copyright 1998 Bertho A. Stultiens (BS) - * - * 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 - */ - -#ifndef __WIDL_UTILS_H -#define __WIDL_UTILS_H - -#include "widltypes.h" - -#include /* size_t */ - -void *xmalloc(size_t); -void *xrealloc(void *, size_t); -char *xstrdup(const char *str); - -#ifndef __GNUC__ -#define __attribute__(X) -#endif - -int parser_error(const char *s, ...) __attribute__((format (printf, 1, 2))); -int parser_warning(const char *s, ...) __attribute__((format (printf, 1, 2))); -void internal_error(const char *file, int line, const char *s, ...) __attribute__((format (printf, 3, 4))); -void error(const char *s, ...) __attribute__((format (printf, 1, 2))); -void warning(const char *s, ...) __attribute__((format (printf, 1, 2))); -void chat(const char *s, ...) __attribute__((format (printf, 1, 2))); - -char *dup_basename(const char *name, const char *ext); - -#endif diff --git a/reactos/tools/widl_new/widl.c b/reactos/tools/widl_new/widl.c deleted file mode 100644 index 6dacc485aec..00000000000 --- a/reactos/tools/widl_new/widl.c +++ /dev/null @@ -1,460 +0,0 @@ -/* - * IDL Compiler - * - * Copyright 2002 Ove Kaaven - * based on WRC code by Bertho Stultiens - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" -#include "wine/port.h" - -#include -#include -#include -#ifdef HAVE_UNISTD_H -# include -#endif -#include -#include -#include -#include -#ifdef HAVE_GETOPT_H -# include -#endif - -#include "widl.h" -#include "utils.h" -#include "parser.h" -#include "wine/wpp.h" -#include "header.h" - -/* future options to reserve characters for: */ -/* a = alignment of structures */ -/* A = ACF input filename */ -/* J = do not search standard include path */ -/* O = generate interpreted stubs */ -/* w = select win16/win32 output (?) */ - -static const char usage[] = -"Usage: widl [options...] infile.idl\n" -" -c Generate client stub\n" -" -C file Name of client stub file (default is infile_c.c)\n" -" -d n Set debug level to 'n'\n" -" -D id[=val] Define preprocessor identifier id=val\n" -" -E Preprocess only\n" -" -h Generate headers\n" -" -H file Name of header file (default is infile.h)\n" -" -I path Set include search dir to path (multiple -I allowed)\n" -" -N Do not preprocess input\n" -" --oldnames Use old naming conventions\n" -" -p Generate proxy\n" -" -P file Name of proxy file (default is infile_p.c)\n" -" --prefix-all=p Prefix names of client stubs / server functions with 'p'\n" -" --prefix-client=p Prefix names of client stubs with 'p'\n" -" --prefix-server=p Prefix names of server functions with 'p'\n" -" -s Generate server stub\n" -" -S file Name of server stub file (default is infile_s.c)\n" -" -t Generate typelib\n" -" -T file Name of typelib file (default is infile.tlb)\n" -" -u Generate interface identifiers file\n" -" -U file Name of interface identifiers file (default is infile_i.c)\n" -" -V Print version and exit\n" -" -W Enable pedantic warnings\n" -"Debug level 'n' is a bitmask with following meaning:\n" -" * 0x01 Tell which resource is parsed (verbose mode)\n" -" * 0x02 Dump internal structures\n" -" * 0x04 Create a parser trace (yydebug=1)\n" -" * 0x08 Preprocessor messages\n" -" * 0x10 Preprocessor lex messages\n" -" * 0x20 Preprocessor yacc trace\n" -; - -static const char version_string[] = "Wine IDL Compiler version " PACKAGE_VERSION "\n" - "Copyright 2002 Ove Kaaven\n"; - -int win32 = 1; -int debuglevel = DEBUGLEVEL_NONE; -int parser_debug, yy_flex_debug; - -int pedantic = 0; -int do_everything = 1; -int preprocess_only = 0; -int do_header = 0; -int do_typelib = 0; -int do_proxies = 0; -int do_client = 0; -int do_server = 0; -int do_idfile = 0; -int no_preprocess = 0; -int old_names = 0; - -char *input_name; -char *header_name; -char *header_token; -char *typelib_name; -char *proxy_name; -char *proxy_token; -char *client_name; -char *client_token; -char *server_name; -char *server_token; -char *idfile_name; -char *idfile_token; -char *temp_name; -const char *prefix_client = ""; -const char *prefix_server = ""; - -int line_number = 1; - -FILE *header; -FILE *proxy; -FILE *idfile; - -time_t now; - -enum { - OLDNAMES_OPTION = CHAR_MAX + 1, - PREFIX_ALL_OPTION, - PREFIX_CLIENT_OPTION, - PREFIX_SERVER_OPTION -}; - -static const char short_options[] = - "cC:d:D:EhH:I:NpP:sS:tT:uU:VW"; -static const struct option long_options[] = { - { "oldnames", no_argument, 0, OLDNAMES_OPTION }, - { "prefix-all", required_argument, 0, PREFIX_ALL_OPTION }, - { "prefix-client", required_argument, 0, PREFIX_CLIENT_OPTION }, - { "prefix-server", required_argument, 0, PREFIX_SERVER_OPTION }, - { 0, 0, 0, 0 } -}; - -static void rm_tempfile(void); - -static char *make_token(const char *name) -{ - char *token; - char *slash; - int i; - - slash = strrchr(name, '/'); - if (slash) name = slash + 1; - - token = xstrdup(name); - for (i=0; token[i]; i++) { - if (!isalnum(token[i])) token[i] = '_'; - else token[i] = toupper(token[i]); - } - return token; -} - -/* duplicate a basename into a valid C token */ -static char *dup_basename_token(const char *name, const char *ext) -{ - char *p, *ret = dup_basename( name, ext ); - /* map invalid characters to '_' */ - for (p = ret; *p; p++) if (!isalnum(*p)) *p = '_'; - return ret; -} - -/* clean things up when aborting on a signal */ -static void exit_on_signal( int sig ) -{ - exit(1); /* this will call the atexit functions */ -} - -int main(int argc,char *argv[]) -{ - extern char* optarg; - extern int optind; - int optc; - int ret = 0; - int opti = 0; - - signal( SIGTERM, exit_on_signal ); - signal( SIGINT, exit_on_signal ); -#ifdef SIGHUP - signal( SIGHUP, exit_on_signal ); -#endif - - now = time(NULL); - - while((optc = getopt_long(argc, argv, short_options, long_options, &opti)) != EOF) { - switch(optc) { - case OLDNAMES_OPTION: - old_names = 1; - break; - case PREFIX_ALL_OPTION: - prefix_client = xstrdup(optarg); - prefix_server = xstrdup(optarg); - break; - case PREFIX_CLIENT_OPTION: - prefix_client = xstrdup(optarg); - break; - case PREFIX_SERVER_OPTION: - prefix_server = xstrdup(optarg); - break; - case 'c': - do_everything = 0; - do_client = 1; - break; - case 'C': - client_name = xstrdup(optarg); - break; - case 'd': - debuglevel = strtol(optarg, NULL, 0); - break; - case 'D': - wpp_add_cmdline_define(optarg); - break; - case 'E': - do_everything = 0; - preprocess_only = 1; - break; - case 'h': - do_everything = 0; - do_header = 1; - break; - case 'H': - header_name = xstrdup(optarg); - break; - case 'I': - wpp_add_include_path(optarg); - break; - case 'N': - no_preprocess = 1; - break; - case 'p': - do_everything = 0; - do_proxies = 1; - break; - case 'P': - proxy_name = xstrdup(optarg); - break; - case 's': - do_everything = 0; - do_server = 1; - break; - case 'S': - server_name = xstrdup(optarg); - break; - case 't': - do_everything = 0; - do_typelib = 1; - break; - case 'T': - typelib_name = xstrdup(optarg); - break; - case 'u': - do_everything = 0; - do_idfile = 1; - break; - case 'U': - idfile_name = xstrdup(optarg); - break; - case 'V': - printf(version_string); - return 0; - case 'W': - pedantic = 1; - break; - default: - fprintf(stderr, usage); - return 1; - } - } - - if(do_everything) { - do_header = do_typelib = do_proxies = do_client = do_server = do_idfile = 1; - } - if(optind < argc) { - input_name = xstrdup(argv[optind]); - } - else { - fprintf(stderr, usage); - return 1; - } - - if(debuglevel) - { - setbuf(stdout,0); - setbuf(stderr,0); - } - - parser_debug = debuglevel & DEBUGLEVEL_TRACE ? 1 : 0; - yy_flex_debug = debuglevel & DEBUGLEVEL_TRACE ? 1 : 0; - - wpp_set_debug( (debuglevel & DEBUGLEVEL_PPLEX) != 0, - (debuglevel & DEBUGLEVEL_PPTRACE) != 0, - (debuglevel & DEBUGLEVEL_PPMSG) != 0 ); - - if (!header_name) { - header_name = dup_basename(input_name, ".idl"); - strcat(header_name, ".h"); - } - - if (!typelib_name && do_typelib) { - typelib_name = dup_basename(input_name, ".idl"); - strcat(typelib_name, ".tlb"); - } - - if (!proxy_name && do_proxies) { - proxy_name = dup_basename(input_name, ".idl"); - strcat(proxy_name, "_p.c"); - } - - if (!client_name && do_client) { - client_name = dup_basename(input_name, ".idl"); - strcat(client_name, "_c.c"); - } - - if (!server_name && do_server) { - server_name = dup_basename(input_name, ".idl"); - strcat(server_name, "_s.c"); - } - - if (!idfile_name && do_idfile) { - idfile_name = dup_basename(input_name, ".idl"); - strcat(idfile_name, "_i.c"); - } - - if (do_proxies) proxy_token = dup_basename_token(proxy_name,"_p.c"); - if (do_client) client_token = dup_basename_token(client_name,"_c.c"); - if (do_server) server_token = dup_basename_token(server_name,"_s.c"); - - wpp_add_cmdline_define("__WIDL__"); - - atexit(rm_tempfile); - if (!no_preprocess) - { - chat("Starting preprocess\n"); - - if (!preprocess_only) - { - ret = wpp_parse_temp( input_name, header_name, &temp_name ); - } - else - { - ret = wpp_parse( input_name, stdout ); - } - - if(ret) exit(1); - if(preprocess_only) exit(0); - if(!(parser_in = fopen(temp_name, "r"))) { - fprintf(stderr, "Could not open %s for input\n", temp_name); - return 1; - } - } - else { - if(!(parser_in = fopen(input_name, "r"))) { - fprintf(stderr, "Could not open %s for input\n", input_name); - return 1; - } - } - - if(do_header) { - if (strrchr(header_name, '\\')) - header_token = make_token(strrchr(header_name, '\\') + 1); - else if (strrchr(header_name, '/')) - header_token = make_token(strrchr(header_name, '/') + 1); - else - header_token = make_token(header_name); - - if(!(header = fopen(header_name, "w"))) { - fprintf(stderr, "Could not open %s for output\n", header_name); - return 1; - } - fprintf(header, "/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n", PACKAGE_VERSION, input_name); - fprintf(header, "#include \n" ); - fprintf(header, "#include \n\n" ); - fprintf(header, "#ifndef __WIDL_%s\n", header_token); - fprintf(header, "#define __WIDL_%s\n", header_token); - fprintf(header, "#ifdef __cplusplus\n"); - fprintf(header, "extern \"C\" {\n"); - fprintf(header, "#endif\n"); - } - - if (do_idfile) { - idfile_token = make_token(idfile_name); - - idfile = fopen(idfile_name, "w"); - if (! idfile) { - fprintf(stderr, "Could not open %s for output\n", idfile_name); - return 1; - } - - fprintf(idfile, "/*** Autogenerated by WIDL %s ", PACKAGE_VERSION); - fprintf(idfile, "from %s - Do not edit ***/\n\n", input_name); - fprintf(idfile, "#include \n"); - fprintf(idfile, "#include \n\n"); - fprintf(idfile, "#define INITGUID\n"); - fprintf(idfile, "#include \n\n"); - fprintf(idfile, "#ifdef __cplusplus\n"); - fprintf(idfile, "extern \"C\" {\n"); - fprintf(idfile, "#endif\n\n"); - } - - init_types(); - ret = parser_parse(); - - if(do_header) { - fprintf(header, "/* Begin additional prototypes for all interfaces */\n"); - fprintf(header, "\n"); - write_user_types(); - fprintf(header, "\n"); - fprintf(header, "/* End additional prototypes */\n"); - fprintf(header, "\n"); - fprintf(header, "#ifdef __cplusplus\n"); - fprintf(header, "}\n"); - fprintf(header, "#endif\n"); - fprintf(header, "#endif /* __WIDL_%s */\n", header_token); - fclose(header); - } - - if (do_idfile) { - fprintf(idfile, "\n"); - fprintf(idfile, "#ifdef __cplusplus\n"); - fprintf(idfile, "}\n"); - fprintf(idfile, "#endif\n"); - - fclose(idfile); - } - - fclose(parser_in); - - if(ret) { - exit(1); - } - header_name = NULL; - client_name = NULL; - server_name = NULL; - idfile_name = NULL; - return 0; -} - -static void rm_tempfile(void) -{ - abort_import(); - if(temp_name) - unlink(temp_name); - if (header_name) - unlink(header_name); - if (client_name) - unlink(client_name); - if (server_name) - unlink(server_name); -} diff --git a/reactos/tools/widl_new/widl.h b/reactos/tools/widl_new/widl.h deleted file mode 100644 index a2b905c2225..00000000000 --- a/reactos/tools/widl_new/widl.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * IDL Compiler - * - * Copyright 2002 Ove Kaaven - * - * 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 - */ - -#ifndef __WIDL_WIDL_H -#define __WIDL_WIDL_H - -#include "widltypes.h" - -#include - -extern int debuglevel; -#define DEBUGLEVEL_NONE 0x0000 -#define DEBUGLEVEL_CHAT 0x0001 -#define DEBUGLEVEL_DUMP 0x0002 -#define DEBUGLEVEL_TRACE 0x0004 -#define DEBUGLEVEL_PPMSG 0x0008 -#define DEBUGLEVEL_PPLEX 0x0010 -#define DEBUGLEVEL_PPTRACE 0x0020 - -extern int win32; -extern int pedantic; -extern int do_everything; -extern int do_header; -extern int do_typelib; -extern int do_proxies; -extern int do_client; -extern int do_server; -extern int do_idfile; -extern int old_names; - -extern char *input_name; -extern char *header_name; -extern char *typelib_name; -extern char *proxy_name; -extern char *proxy_token; -extern char *client_name; -extern char *client_token; -extern char *server_name; -extern char *server_token; -extern const char *prefix_client; -extern const char *prefix_server; -extern time_t now; - -extern int line_number; -extern int char_number; - -extern FILE* header; -extern FILE* idfile; - -extern void write_proxies(ifref_list_t *ifaces); -extern void write_client(ifref_list_t *ifaces); -extern void write_server(ifref_list_t *ifaces); - -#endif diff --git a/reactos/tools/widl_new/widl.mak b/reactos/tools/widl_new/widl.mak deleted file mode 100644 index de6813ac536..00000000000 --- a/reactos/tools/widl_new/widl.mak +++ /dev/null @@ -1,131 +0,0 @@ -WIDL_BASE = $(TOOLS_BASE)$(SEP)widl -WIDL_BASE_ = $(WIDL_BASE)$(SEP) -WIDL_INT = $(INTERMEDIATE_)$(WIDL_BASE) -WIDL_INT_ = $(WIDL_INT)$(SEP) -WIDL_OUT = $(OUTPUT_)$(WIDL_BASE) -WIDL_OUT_ = $(WIDL_OUT)$(SEP) - -$(WIDL_INT): | $(TOOLS_INT) - $(ECHO_MKDIR) - ${mkdir} $@ - -ifneq ($(INTERMEDIATE),$(OUTPUT)) -$(WIDL_OUT): | $(TOOLS_OUT) - $(ECHO_MKDIR) - ${mkdir} $@ -endif - -WIDL_PORT_BASE = $(WIDL_BASE)$(SEP)port -WIDL_PORT_BASE_ = $(WIDL_PORT_BASE)$(SEP) -WIDL_PORT_INT = $(INTERMEDIATE_)$(WIDL_PORT_BASE) -WIDL_PORT_INT_ = $(WIDL_PORT_INT)$(SEP) -WIDL_PORT_OUT = $(OUTPUT_)$(WIDL_PORT_BASE) -WIDL_PORT_OUT_ = $(WIDL_PORT_OUT)$(SEP) - -$(WIDL_PORT_INT): | $(WIDL_INT) - $(ECHO_MKDIR) - ${mkdir} $@ - -ifneq ($(INTERMEDIATE),$(OUTPUT)) -$(WIDL_PORT_OUT): | $(WIDL_OUT) - $(ECHO_MKDIR) - ${mkdir} $@ -endif - -WIDL_TARGET = \ - $(WIDL_OUT_)widl$(EXEPOSTFIX) - -WIDL_DEPENDS = $(BUILDNO_H) - -WIDL_SOURCES = $(addprefix $(WIDL_BASE_), \ - client.c \ - hash.c \ - header.c \ - proxy.c \ - server.c \ - typegen.c \ - typelib.c \ - utils.c \ - widl.c \ - write_msft.c \ - parser.yy.c \ - parser.tab.c \ - port$(SEP)mkstemps.c \ - ) - -WIDL_OBJECTS = \ - $(addprefix $(INTERMEDIATE_), $(WIDL_SOURCES:.c=.o)) - -WIDL_HOST_CFLAGS = $(TOOLS_CFLAGS) \ - -DINT16=SHORT -D__USE_W32API -DYYDEBUG=1 -D__REACTOS__=1 \ - -I$(WIDL_BASE) -I$(WPP_BASE) \ - -Iinclude/reactos/wine -Iinclude/reactos -Iinclude -Iinclude/psdk \ - -I$(INTERMEDIATE_)include - -WIDL_HOST_LFLAGS = $(TOOLS_LFLAGS) - -WIDL_LIBS = $(WPP_TARGET) - -.PHONY: widl -widl: $(WIDL_TARGET) - -$(WIDL_TARGET): $(WIDL_OBJECTS) $(WIDL_LIBS) | $(WIDL_OUT) - $(ECHO_LD) - ${host_gcc} $(WIDL_OBJECTS) $(WIDL_LIBS) $(WIDL_HOST_LFLAGS) -o $@ - -$(WIDL_INT_)client.o: $(WIDL_BASE_)client.c $(WIDL_DEPENDS) | $(WIDL_INT) - $(ECHO_CC) - ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ - -$(WIDL_INT_)hash.o: $(WIDL_BASE_)hash.c $(WIDL_DEPENDS) | $(WIDL_INT) - $(ECHO_CC) - ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ - -$(WIDL_INT_)header.o: $(WIDL_BASE_)header.c $(WIDL_DEPENDS) | $(WIDL_INT) - $(ECHO_CC) - ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ - -$(WIDL_INT_)proxy.o: $(WIDL_BASE_)proxy.c $(WIDL_DEPENDS) | $(WIDL_INT) - $(ECHO_CC) - ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ - -$(WIDL_INT_)server.o: $(WIDL_BASE_)server.c $(WIDL_DEPENDS) | $(WIDL_INT) - $(ECHO_CC) - ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ - -$(WIDL_INT_)typegen.o: $(WIDL_BASE_)typegen.c $(WIDL_DEPENDS) | $(WIDL_INT) - $(ECHO_CC) - ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ - -$(WIDL_INT_)typelib.o: $(WIDL_BASE_)typelib.c $(WIDL_DEPENDS) | $(WIDL_INT) - $(ECHO_CC) - ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ - -$(WIDL_INT_)utils.o: $(WIDL_BASE_)utils.c $(WIDL_DEPENDS) | $(WIDL_INT) - $(ECHO_CC) - ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ - -$(WIDL_INT_)widl.o: $(WIDL_BASE_)widl.c $(WIDL_DEPENDS) | $(WIDL_INT) - $(ECHO_CC) - ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ - -$(WIDL_INT_)write_msft.o: $(WIDL_BASE_)write_msft.c $(WIDL_DEPENDS) | $(WIDL_INT) - $(ECHO_CC) - ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ - -$(WIDL_INT_)parser.yy.o: $(WIDL_BASE_)parser.yy.c $(WIDL_DEPENDS) | $(WIDL_INT) - $(ECHO_CC) - ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ - -$(WIDL_INT_)parser.tab.o: $(WIDL_BASE_)parser.tab.c $(WIDL_DEPENDS) | $(WIDL_INT) - $(ECHO_CC) - ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ - -$(WIDL_PORT_INT_)mkstemps.o: $(WIDL_PORT_BASE_)mkstemps.c $(WIDL_DEPENDS) | $(WIDL_PORT_INT) - $(ECHO_CC) - ${host_gcc} $(WIDL_HOST_CFLAGS) -c $< -o $@ - -.PHONY: widl_clean -widl_clean: - -@$(rm) $(WIDL_TARGET) $(WIDL_OBJECTS) 2>$(NUL) -clean: widl_clean diff --git a/reactos/tools/widl_new/widl.man.in b/reactos/tools/widl_new/widl.man.in deleted file mode 100644 index be534451427..00000000000 --- a/reactos/tools/widl_new/widl.man.in +++ /dev/null @@ -1,95 +0,0 @@ -.\" -*- nroff -*- -.TH WIDL 1 "October 2005" "@PACKAGE_STRING@" "Wine Developers Manual" -.SH NAME -widl \- Wine Interface Definition Language Compiler -.SH SYNOPSIS -.BR "widl "\fI[options]\fR " \fIinfile.idl\fR" -.SH DESCRIPTION -.B widl -is a Wine tool which purpose is to compile Interface Definition Language (IDL) files. -.PP -.SH OPTIONS -.B Help mode: -.nf -No options are used. -The program prints the help info and then exits. -.PP -.B General options: -.IP "\fB-V\fR" -Print version number and exits from the program. -.PP -.B Header options: -.IP "\fB-h\fR" -Generate header files. -.IP "\fB-H \fIfile\fR" -Name of header file to generate. The default header -filename is infile.h. -.IP "\fB--oldnames\fR" -Use old naming conventions. -.PP -.B Type library options: -.IP \fB-t\fR -Generate a type library. -.IP "\fB-T \fIfile\fR" -Define the name of the type library to be generated. -The default filename is infile.tlb. -.PP -.B UUID file options: -.IP "\fB-u\fR" -Generate a UUID file. -.IP "\fB-U \fIfile\fR" -Define the name of the UUID file to be generated. -The default filename is infile_i.c. -.PP -.B Proxy/stub generation options: -.IP "\fB-c\fR" -Generate client stub. -.IP "\fB-C \fIfile\fR" -Name of client stub file (default is infile_c.c) -.IP "\fB-p\fR" -Generate proxy. -.IP "\fB-P \fIfile\fR" -Name of proxy file (default is infile_p.c) -.IP "\fB-s\fR" -Generate server stub. -.IP "\fB-S \fIfile\fR" -Name of server stub file (default is infile_s.c) -.PP -.B Preprocessor options: -.IP "\fB-I \fIpath\fR" -Add a header search dir to path. Multiple search -dirs are allowed. -.IP "\fB-D \fIid[=val]\fR" -Define preprocessor identifier id value. -.IP "\fB-E\fR" -Preprocess only. -.IP "\fB-N\fR" -Do not preprocess input. -.PP -.B Debug options: -.IP "\fB-W\fR" -Enable pedantic warnings. -.IP "\fB-d \fIn\fR" -.nf -Set debug level to n. -n may be '0x01', '0x02', '0x04', '0x08', '0x10' or '0x20'. -(See section \fBDebug\fR) -.PP -.SH Debug -Debug level 'n' is a bitmask with the following meaning: - * 0x01 Tell which resource is parsed (verbose mode) - * 0x02 Dump internal structures - * 0x04 Create a parser trace (yydebug=1) - * 0x08 Preprocessor messages - * 0x10 Preprocessor lex messages - * 0x20 Preprocessor yacc trace -.SH BUGS -Typelib generation doesn't work at the moment. It is still under development. -.SH AUTHORS -.B widl -was written by Ove Kaaven. This man page was written by Hannu -Valtonen. -.SH "SEE ALSO" -The Winelib User Guide -.nf -The Wine Developers Guide diff --git a/reactos/tools/widl_new/widltypes.h b/reactos/tools/widl_new/widltypes.h deleted file mode 100644 index d514d546b73..00000000000 --- a/reactos/tools/widl_new/widltypes.h +++ /dev/null @@ -1,322 +0,0 @@ -/* - * IDL Compiler - * - * Copyright 2002 Ove Kaaven - * - * 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 - */ - -#ifndef __WIDL_WIDLTYPES_H -#define __WIDL_WIDLTYPES_H - -#include -#include "guiddef.h" -#include "wine/rpcfc.h" -#include "wine/list.h" - -#ifndef UUID_DEFINED -#define UUID_DEFINED -typedef GUID UUID; -#endif - -#define TRUE 1 -#define FALSE 0 - -typedef struct _attr_t attr_t; -typedef struct _expr_t expr_t; -typedef struct _type_t type_t; -typedef struct _typeref_t typeref_t; -typedef struct _var_t var_t; -typedef struct _pident_t pident_t; -typedef struct _func_t func_t; -typedef struct _ifref_t ifref_t; -typedef struct _typelib_entry_t typelib_entry_t; -typedef struct _importlib_t importlib_t; -typedef struct _importinfo_t importinfo_t; -typedef struct _typelib_t typelib_t; -typedef struct _user_type_t user_type_t; - -typedef struct list attr_list_t; -typedef struct list str_list_t; -typedef struct list func_list_t; -typedef struct list expr_list_t; -typedef struct list var_list_t; -typedef struct list pident_list_t; -typedef struct list ifref_list_t; -typedef struct list array_dims_t; -typedef struct list user_type_list_t; - -enum attr_type -{ - ATTR_AGGREGATABLE, - ATTR_APPOBJECT, - ATTR_ASYNC, - ATTR_AUTO_HANDLE, - ATTR_BINDABLE, - ATTR_CALLAS, - ATTR_CASE, - ATTR_CONTEXTHANDLE, - ATTR_CONTROL, - ATTR_DEFAULT, - ATTR_DEFAULTCOLLELEM, - ATTR_DEFAULTVALUE_EXPR, - ATTR_DEFAULTVALUE_STRING, - ATTR_DEFAULTVTABLE, - ATTR_DISPINTERFACE, - ATTR_DISPLAYBIND, - ATTR_DLLNAME, - ATTR_DUAL, - ATTR_ENDPOINT, - ATTR_ENTRY_ORDINAL, - ATTR_ENTRY_STRING, - ATTR_EXPLICIT_HANDLE, - ATTR_HANDLE, - ATTR_HELPCONTEXT, - ATTR_HELPFILE, - ATTR_HELPSTRING, - ATTR_HELPSTRINGCONTEXT, - ATTR_HELPSTRINGDLL, - ATTR_HIDDEN, - ATTR_ID, - ATTR_IDEMPOTENT, - ATTR_IIDIS, - ATTR_IMMEDIATEBIND, - ATTR_IMPLICIT_HANDLE, - ATTR_IN, - ATTR_INPUTSYNC, - ATTR_LENGTHIS, - ATTR_LOCAL, - ATTR_NONBROWSABLE, - ATTR_NONCREATABLE, - ATTR_NONEXTENSIBLE, - ATTR_OBJECT, - ATTR_ODL, - ATTR_OLEAUTOMATION, - ATTR_OPTIONAL, - ATTR_OUT, - ATTR_POINTERDEFAULT, - ATTR_POINTERTYPE, - ATTR_PROPGET, - ATTR_PROPPUT, - ATTR_PROPPUTREF, - ATTR_PUBLIC, - ATTR_RANGE, - ATTR_READONLY, - ATTR_REQUESTEDIT, - ATTR_RESTRICTED, - ATTR_RETVAL, - ATTR_SIZEIS, - ATTR_SOURCE, - ATTR_STRING, - ATTR_SWITCHIS, - ATTR_SWITCHTYPE, - ATTR_TRANSMITAS, - ATTR_UUID, - ATTR_V1ENUM, - ATTR_VARARG, - ATTR_VERSION, - ATTR_WIREMARSHAL -}; - -enum expr_type -{ - EXPR_VOID, - EXPR_NUM, - EXPR_HEXNUM, - EXPR_DOUBLE, - EXPR_IDENTIFIER, - EXPR_NEG, - EXPR_NOT, - EXPR_PPTR, - EXPR_CAST, - EXPR_SIZEOF, - EXPR_SHL, - EXPR_SHR, - EXPR_MUL, - EXPR_DIV, - EXPR_ADD, - EXPR_SUB, - EXPR_AND, - EXPR_OR, - EXPR_COND, - EXPR_TRUEFALSE, -}; - -enum type_kind -{ - TKIND_PRIMITIVE = -1, - TKIND_ENUM, - TKIND_RECORD, - TKIND_MODULE, - TKIND_INTERFACE, - TKIND_DISPATCH, - TKIND_COCLASS, - TKIND_ALIAS, - TKIND_UNION, - TKIND_MAX -}; - -struct str_list_entry_t -{ - char *str; - struct list entry; -}; - -struct _attr_t { - enum attr_type type; - union { - unsigned long ival; - void *pval; - } u; - /* parser-internal */ - struct list entry; -}; - -struct _expr_t { - enum expr_type type; - const expr_t *ref; - union { - long lval; - double dval; - const char *sval; - const expr_t *ext; - type_t *tref; - } u; - const expr_t *ext2; - int is_const; - long cval; - /* parser-internal */ - struct list entry; -}; - -struct _type_t { - const char *name; - enum type_kind kind; - unsigned char type; - struct _type_t *ref; - const attr_list_t *attrs; - func_list_t *funcs; /* interfaces and modules */ - var_list_t *fields; /* interfaces, structures and enumerations */ - ifref_list_t *ifaces; /* coclasses */ - unsigned long dim; /* array dimension */ - expr_t *size_is, *length_is; - type_t *orig; /* dup'd types */ - unsigned int typestring_offset; - int typelib_idx; - unsigned int declarray : 1; /* if declared as an array */ - unsigned int ignore : 1; - unsigned int is_const : 1; - unsigned int defined : 1; - unsigned int written : 1; - unsigned int user_types_registered : 1; - unsigned int tfswrite : 1; /* if the type needs to be written to the TFS */ - int sign : 2; -}; - -struct _var_t { - char *name; - type_t *type; - var_list_t *args; /* for function pointers */ - attr_list_t *attrs; - expr_t *eval; - - /* parser-internal */ - struct list entry; -}; - -struct _pident_t { - var_t *var; - int ptr_level; - - /* parser-internal */ - struct list entry; -}; - -struct _func_t { - var_t *def; - var_list_t *args; - int ignore, idx; - - /* parser-internal */ - struct list entry; -}; - -struct _ifref_t { - type_t *iface; - attr_list_t *attrs; - - /* parser-internal */ - struct list entry; -}; - -struct _typelib_entry_t { - type_t *type; - struct list entry; -}; - -struct _importinfo_t { - int offset; - GUID guid; - int flags; - int id; - - char *name; - - importlib_t *importlib; -}; - -struct _importlib_t { - char *name; - - int version; - GUID guid; - - importinfo_t *importinfos; - int ntypeinfos; - - int allocated; - - struct list entry; -}; - -struct _typelib_t { - char *name; - char *filename; - attr_list_t *attrs; - struct list entries; - struct list importlibs; -}; - -struct _user_type_t { - struct list entry; - const char *name; -}; - -extern user_type_list_t user_type_list; -void check_for_user_types(const var_list_t *list); - -void init_types(void); - -type_t *duptype(type_t *t, int dupname); -type_t *alias(type_t *t, const char *name); - -int is_ptr(const type_t *t); -int is_array(const type_t *t); -int is_var_ptr(const var_t *v); -int cant_be_null(const var_t *v); -int is_struct(unsigned char tc); -int is_union(unsigned char tc); - -#endif diff --git a/reactos/tools/widl_new/write_msft.c b/reactos/tools/widl_new/write_msft.c deleted file mode 100644 index 2492464865f..00000000000 --- a/reactos/tools/widl_new/write_msft.c +++ /dev/null @@ -1,2531 +0,0 @@ -/* - * Typelib v2 (MSFT) generation - * - * Copyright 2004 Alastair Bridgewater - * 2004, 2005 Huw Davies - * - * 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 - * - * -------------------------------------------------------------------------------------- - * Known problems: - * - * Badly incomplete. - * - * Only works on little-endian systems. - * - */ - -#include "config.h" -#include "wine/port.h" - -#include -#include -#include -#include -#include -#include - -#define NONAMELESSUNION -#define NONAMELESSSTRUCT - -#include "winerror.h" -#include "windef.h" -#include "winbase.h" -#include "winnls.h" - -#include "widltypes.h" -#include "typelib.h" -#include "typelib_struct.h" -#include "utils.h" -#include "header.h" -#include "hash.h" - -enum MSFT_segment_index { - MSFT_SEG_TYPEINFO = 0, /* type information */ - MSFT_SEG_IMPORTINFO, /* import information */ - MSFT_SEG_IMPORTFILES, /* import filenames */ - MSFT_SEG_REFERENCES, /* references (?) */ - MSFT_SEG_GUIDHASH, /* hash table for guids? */ - MSFT_SEG_GUID, /* guid storage */ - MSFT_SEG_NAMEHASH, /* hash table for names */ - MSFT_SEG_NAME, /* name storage */ - MSFT_SEG_STRING, /* string storage */ - MSFT_SEG_TYPEDESC, /* type descriptions */ - MSFT_SEG_ARRAYDESC, /* array descriptions */ - MSFT_SEG_CUSTDATA, /* custom data */ - MSFT_SEG_CUSTDATAGUID, /* custom data guids */ - MSFT_SEG_UNKNOWN, /* ??? */ - MSFT_SEG_UNKNOWN2, /* ??? */ - MSFT_SEG_MAX /* total number of segments */ -}; - -typedef struct tagMSFT_ImpFile { - int guid; - LCID lcid; - int version; - char filename[0]; /* preceded by two bytes of encoded (length << 2) + flags in the low two bits. */ -} MSFT_ImpFile; - -typedef struct _msft_typelib_t -{ - typelib_t *typelib; - MSFT_Header typelib_header; - MSFT_pSeg typelib_segdir[MSFT_SEG_MAX]; - char *typelib_segment_data[MSFT_SEG_MAX]; - int typelib_segment_block_length[MSFT_SEG_MAX]; - - INT typelib_typeinfo_offsets[0x200]; /* Hope that's enough. */ - - INT *typelib_namehash_segment; - INT *typelib_guidhash_segment; - - INT help_string_dll_offset; - - struct _msft_typeinfo_t *typeinfos; - struct _msft_typeinfo_t *last_typeinfo; -} msft_typelib_t; - -typedef struct _msft_typeinfo_t -{ - msft_typelib_t *typelib; - MSFT_TypeInfoBase *typeinfo; - - int typekind; - - unsigned int var_data_allocated; - int *var_data; - - unsigned int func_data_allocated; - int *func_data; - - int vars_allocated; - int *var_indices; - int *var_names; - int *var_offsets; - - int funcs_allocated; - int *func_indices; - int *func_names; - int *func_offsets; - - int datawidth; - - struct _msft_typeinfo_t *next_typeinfo; -} msft_typeinfo_t; - - - -/*================== Internal functions ===================================*/ - -/**************************************************************************** - * ctl2_init_header - * - * Initializes the type library header of a new typelib. - */ -static void ctl2_init_header( - msft_typelib_t *typelib) /* [I] The typelib to initialize. */ -{ - typelib->typelib_header.magic1 = 0x5446534d; - typelib->typelib_header.magic2 = 0x00010002; - typelib->typelib_header.posguid = -1; - typelib->typelib_header.lcid = 0x0409; /* or do we use the current one? */ - typelib->typelib_header.lcid2 = 0x0; - typelib->typelib_header.varflags = 0x40; - typelib->typelib_header.version = 0; - typelib->typelib_header.flags = 0; - typelib->typelib_header.nrtypeinfos = 0; - typelib->typelib_header.helpstring = -1; - typelib->typelib_header.helpstringcontext = 0; - typelib->typelib_header.helpcontext = 0; - typelib->typelib_header.nametablecount = 0; - typelib->typelib_header.nametablechars = 0; - typelib->typelib_header.NameOffset = -1; - typelib->typelib_header.helpfile = -1; - typelib->typelib_header.CustomDataOffset = -1; - typelib->typelib_header.res44 = 0x20; - typelib->typelib_header.res48 = 0x80; - typelib->typelib_header.dispatchpos = -1; - typelib->typelib_header.nimpinfos = 0; -} - -/**************************************************************************** - * ctl2_init_segdir - * - * Initializes the segment directory of a new typelib. - */ -static void ctl2_init_segdir( - msft_typelib_t *typelib) /* [I] The typelib to initialize. */ -{ - int i; - MSFT_pSeg *segdir; - - segdir = &typelib->typelib_segdir[MSFT_SEG_TYPEINFO]; - - for (i = 0; i < 15; i++) { - segdir[i].offset = -1; - segdir[i].length = 0; - segdir[i].res08 = -1; - segdir[i].res0c = 0x0f; - } -} - -/**************************************************************************** - * ctl2_hash_guid - * - * Generates a hash key from a GUID. - * - * RETURNS - * - * The hash key for the GUID. - */ -static int ctl2_hash_guid( - REFGUID guid) /* [I] The guid to hash. */ -{ - int hash; - int i; - - hash = 0; - for (i = 0; i < 8; i ++) { - hash ^= ((const short *)guid)[i]; - } - - return hash & 0x1f; -} - -/**************************************************************************** - * ctl2_find_guid - * - * Locates a guid in a type library. - * - * RETURNS - * - * The offset into the GUID segment of the guid, or -1 if not found. - */ -static int ctl2_find_guid( - msft_typelib_t *typelib, /* [I] The typelib to operate against. */ - int hash_key, /* [I] The hash key for the guid. */ - REFGUID guid) /* [I] The guid to find. */ -{ - int offset; - MSFT_GuidEntry *guidentry; - - offset = typelib->typelib_guidhash_segment[hash_key]; - while (offset != -1) { - guidentry = (MSFT_GuidEntry *)&typelib->typelib_segment_data[MSFT_SEG_GUID][offset]; - - if (!memcmp(guidentry, guid, sizeof(GUID))) return offset; - - offset = guidentry->next_hash; - } - - return offset; -} - -/**************************************************************************** - * ctl2_find_name - * - * Locates a name in a type library. - * - * RETURNS - * - * The offset into the NAME segment of the name, or -1 if not found. - * - * NOTES - * - * The name must be encoded as with ctl2_encode_name(). - */ -static int ctl2_find_name( - msft_typelib_t *typelib, /* [I] The typelib to operate against. */ - char *name) /* [I] The encoded name to find. */ -{ - int offset; - int *namestruct; - - offset = typelib->typelib_namehash_segment[name[2] & 0x7f]; - while (offset != -1) { - namestruct = (int *)&typelib->typelib_segment_data[MSFT_SEG_NAME][offset]; - - if (!((namestruct[2] ^ *((int *)name)) & 0xffff00ff)) { - /* hash codes and lengths match, final test */ - if (!strncasecmp(name+4, (void *)(namestruct+3), name[0])) break; - } - - /* move to next item in hash bucket */ - offset = namestruct[1]; - } - - return offset; -} - -/**************************************************************************** - * ctl2_encode_name - * - * Encodes a name string to a form suitable for storing into a type library - * or comparing to a name stored in a type library. - * - * RETURNS - * - * The length of the encoded name, including padding and length+hash fields. - * - * NOTES - * - * Will throw an exception if name or result are NULL. Is not multithread - * safe in the slightest. - */ -static int ctl2_encode_name( - msft_typelib_t *typelib, /* [I] The typelib to operate against (used for LCID only). */ - const char *name, /* [I] The name string to encode. */ - char **result) /* [O] A pointer to a pointer to receive the encoded name. */ -{ - int length; - static char converted_name[0x104]; - int offset; - int value; - - length = strlen(name); - memcpy(converted_name + 4, name, length); - converted_name[0] = length & 0xff; - - converted_name[length + 4] = 0; - - converted_name[1] = 0x00; - - value = lhash_val_of_name_sys(typelib->typelib_header.varflags & 0x0f, typelib->typelib_header.lcid, converted_name + 4); - - converted_name[2] = value; - converted_name[3] = value >> 8; - - for (offset = (4 - length) & 3; offset; offset--) converted_name[length + offset + 3] = 0x57; - - *result = converted_name; - - return (length + 7) & ~3; -} - -/**************************************************************************** - * ctl2_encode_string - * - * Encodes a string to a form suitable for storing into a type library or - * comparing to a string stored in a type library. - * - * RETURNS - * - * The length of the encoded string, including padding and length fields. - * - * NOTES - * - * Will throw an exception if string or result are NULL. Is not multithread - * safe in the slightest. - */ -static int ctl2_encode_string( - const char *string, /* [I] The string to encode. */ - char **result) /* [O] A pointer to a pointer to receive the encoded string. */ -{ - int length; - static char converted_string[0x104]; - int offset; - - length = strlen(string); - memcpy(converted_string + 2, string, length); - converted_string[0] = length & 0xff; - converted_string[1] = (length >> 8) & 0xff; - - if(length < 3) { /* strings of this length are padded with up to 8 bytes incl the 2 byte length */ - for(offset = 0; offset < 4; offset++) - converted_string[length + offset + 2] = 0x57; - length += 4; - } - for (offset = (4 - (length + 2)) & 3; offset; offset--) converted_string[length + offset + 1] = 0x57; - - *result = converted_string; - - return (length + 5) & ~3; -} - -/**************************************************************************** - * ctl2_alloc_segment - * - * Allocates memory from a segment in a type library. - * - * RETURNS - * - * Success: The offset within the segment of the new data area. - * - * BUGS - * - * Does not (yet) handle the case where the allocated segment memory needs to grow. - */ -static int ctl2_alloc_segment( - msft_typelib_t *typelib, /* [I] The type library in which to allocate. */ - enum MSFT_segment_index segment, /* [I] The segment in which to allocate. */ - int size, /* [I] The amount to allocate. */ - int block_size) /* [I] Initial allocation block size, or 0 for default. */ -{ - int offset; - - if(!typelib->typelib_segment_data[segment]) { - if (!block_size) block_size = 0x2000; - - typelib->typelib_segment_block_length[segment] = block_size; - typelib->typelib_segment_data[segment] = xmalloc(block_size); - if (!typelib->typelib_segment_data[segment]) return -1; - memset(typelib->typelib_segment_data[segment], 0x57, block_size); - } - - while ((typelib->typelib_segdir[segment].length + size) > typelib->typelib_segment_block_length[segment]) { - char *block; - - block_size = typelib->typelib_segment_block_length[segment]; - block = xrealloc(typelib->typelib_segment_data[segment], block_size << 1); - - if (segment == MSFT_SEG_TYPEINFO) { - /* TypeInfos have a direct pointer to their memory space, so we have to fix them up. */ - msft_typeinfo_t *typeinfo; - - for (typeinfo = typelib->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) { - typeinfo->typeinfo = (void *)&block[((char *)typeinfo->typeinfo) - typelib->typelib_segment_data[segment]]; - } - } - - memset(block + block_size, 0x57, block_size); - typelib->typelib_segment_block_length[segment] = block_size << 1; - typelib->typelib_segment_data[segment] = block; - } - - offset = typelib->typelib_segdir[segment].length; - typelib->typelib_segdir[segment].length += size; - - return offset; -} - -/**************************************************************************** - * ctl2_alloc_typeinfo - * - * Allocates and initializes a typeinfo structure in a type library. - * - * RETURNS - * - * Success: The offset of the new typeinfo. - * Failure: -1 (this is invariably an out of memory condition). - */ -static int ctl2_alloc_typeinfo( - msft_typelib_t *typelib, /* [I] The type library to allocate in. */ - int nameoffset) /* [I] The offset of the name for this typeinfo. */ -{ - int offset; - MSFT_TypeInfoBase *typeinfo; - - offset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEINFO, sizeof(MSFT_TypeInfoBase), 0); - - typelib->typelib_typeinfo_offsets[typelib->typelib_header.nrtypeinfos++] = offset; - - typeinfo = (void *)(typelib->typelib_segment_data[MSFT_SEG_TYPEINFO] + offset); - - typeinfo->typekind = (typelib->typelib_header.nrtypeinfos - 1) << 16; - typeinfo->memoffset = -1; /* should be EOF if no elements */ - typeinfo->res2 = 0; - typeinfo->res3 = -1; - typeinfo->res4 = 3; - typeinfo->res5 = 0; - typeinfo->cElement = 0; - typeinfo->res7 = 0; - typeinfo->res8 = 0; - typeinfo->res9 = 0; - typeinfo->resA = 0; - typeinfo->posguid = -1; - typeinfo->flags = 0; - typeinfo->NameOffset = nameoffset; - typeinfo->version = 0; - typeinfo->docstringoffs = -1; - typeinfo->helpstringcontext = 0; - typeinfo->helpcontext = 0; - typeinfo->oCustData = -1; - typeinfo->cbSizeVft = 0; - typeinfo->cImplTypes = 0; - typeinfo->size = 0; - typeinfo->datatype1 = -1; - typeinfo->datatype2 = 0; - typeinfo->res18 = 0; - typeinfo->res19 = -1; - - return offset; -} - -/**************************************************************************** - * ctl2_alloc_guid - * - * Allocates and initializes a GUID structure in a type library. Also updates - * the GUID hash table as needed. - * - * RETURNS - * - * Success: The offset of the new GUID. - */ -static int ctl2_alloc_guid( - msft_typelib_t *typelib, /* [I] The type library to allocate in. */ - MSFT_GuidEntry *guid) /* [I] The GUID to store. */ -{ - int offset; - MSFT_GuidEntry *guid_space; - int hash_key; - - hash_key = ctl2_hash_guid(&guid->guid); - - offset = ctl2_find_guid(typelib, hash_key, &guid->guid); - if (offset != -1) return offset; - - offset = ctl2_alloc_segment(typelib, MSFT_SEG_GUID, sizeof(MSFT_GuidEntry), 0); - - guid_space = (void *)(typelib->typelib_segment_data[MSFT_SEG_GUID] + offset); - *guid_space = *guid; - - guid_space->next_hash = typelib->typelib_guidhash_segment[hash_key]; - typelib->typelib_guidhash_segment[hash_key] = offset; - - return offset; -} - -/**************************************************************************** - * ctl2_alloc_name - * - * Allocates and initializes a name within a type library. Also updates the - * name hash table as needed. - * - * RETURNS - * - * Success: The offset within the segment of the new name. - * Failure: -1 (this is invariably an out of memory condition). - */ -static int ctl2_alloc_name( - msft_typelib_t *typelib, /* [I] The type library to allocate in. */ - const char *name) /* [I] The name to store. */ -{ - int length; - int offset; - MSFT_NameIntro *name_space; - char *encoded_name; - - length = ctl2_encode_name(typelib, name, &encoded_name); - - offset = ctl2_find_name(typelib, encoded_name); - if (offset != -1) return offset; - - offset = ctl2_alloc_segment(typelib, MSFT_SEG_NAME, length + 8, 0); - - name_space = (void *)(typelib->typelib_segment_data[MSFT_SEG_NAME] + offset); - name_space->hreftype = -1; - name_space->next_hash = -1; - memcpy(&name_space->namelen, encoded_name, length); - - if (typelib->typelib_namehash_segment[encoded_name[2] & 0x7f] != -1) - name_space->next_hash = typelib->typelib_namehash_segment[encoded_name[2] & 0x7f]; - - typelib->typelib_namehash_segment[encoded_name[2] & 0x7f] = offset; - - typelib->typelib_header.nametablecount += 1; - typelib->typelib_header.nametablechars += *encoded_name; - - return offset; -} - -/**************************************************************************** - * ctl2_alloc_string - * - * Allocates and initializes a string in a type library. - * - * RETURNS - * - * Success: The offset within the segment of the new string. - * Failure: -1 (this is invariably an out of memory condition). - */ -static int ctl2_alloc_string( - msft_typelib_t *typelib, /* [I] The type library to allocate in. */ - const char *string) /* [I] The string to store. */ -{ - int length; - int offset; - char *string_space; - char *encoded_string; - - length = ctl2_encode_string(string, &encoded_string); - - for (offset = 0; offset < typelib->typelib_segdir[MSFT_SEG_STRING].length; - offset += ((((typelib->typelib_segment_data[MSFT_SEG_STRING][offset + 1] << 8) & 0xff) - | (typelib->typelib_segment_data[MSFT_SEG_STRING][offset + 0] & 0xff)) + 5) & ~3) { - if (!memcmp(encoded_string, typelib->typelib_segment_data[MSFT_SEG_STRING] + offset, length)) return offset; - } - - offset = ctl2_alloc_segment(typelib, MSFT_SEG_STRING, length, 0); - - string_space = typelib->typelib_segment_data[MSFT_SEG_STRING] + offset; - memcpy(string_space, encoded_string, length); - - return offset; -} - -/**************************************************************************** - * alloc_msft_importinfo - * - * Allocates and initializes an import information structure in a type library. - * - * RETURNS - * - * Success: The offset of the new importinfo. - * Failure: -1 (this is invariably an out of memory condition). - */ -static int alloc_msft_importinfo( - msft_typelib_t *typelib, /* [I] The type library to allocate in. */ - MSFT_ImpInfo *impinfo) /* [I] The import information to store. */ -{ - int offset; - MSFT_ImpInfo *impinfo_space; - - for (offset = 0; - offset < typelib->typelib_segdir[MSFT_SEG_IMPORTINFO].length; - offset += sizeof(MSFT_ImpInfo)) { - if (!memcmp(&(typelib->typelib_segment_data[MSFT_SEG_IMPORTINFO][offset]), - impinfo, sizeof(MSFT_ImpInfo))) { - return offset; - } - } - - impinfo->flags |= typelib->typelib_header.nimpinfos++; - - offset = ctl2_alloc_segment(typelib, MSFT_SEG_IMPORTINFO, sizeof(MSFT_ImpInfo), 0); - - impinfo_space = (void *)(typelib->typelib_segment_data[MSFT_SEG_IMPORTINFO] + offset); - *impinfo_space = *impinfo; - - return offset; -} - -/**************************************************************************** - * alloc_importfile - * - * Allocates and initializes an import file definition in a type library. - * - * RETURNS - * - * Success: The offset of the new importinfo. - * Failure: -1 (this is invariably an out of memory condition). - */ -static int alloc_importfile( - msft_typelib_t *typelib, /* [I] The type library to allocate in. */ - int guidoffset, /* [I] The offset to the GUID for the imported library. */ - int major_version, /* [I] The major version number of the imported library. */ - int minor_version, /* [I] The minor version number of the imported library. */ - const char *filename) /* [I] The filename of the imported library. */ -{ - int length; - int offset; - MSFT_ImpFile *importfile; - char *encoded_string; - - length = ctl2_encode_string(filename, &encoded_string); - - encoded_string[0] <<= 2; - encoded_string[0] |= 1; - - for (offset = 0; offset < typelib->typelib_segdir[MSFT_SEG_IMPORTFILES].length; - offset += ((((typelib->typelib_segment_data[MSFT_SEG_IMPORTFILES][offset + 0xd] << 8) & 0xff) - | (typelib->typelib_segment_data[MSFT_SEG_IMPORTFILES][offset + 0xc] & 0xff)) >> 2) + 0xc) { - if (!memcmp(encoded_string, typelib->typelib_segment_data[MSFT_SEG_IMPORTFILES] + offset + 0xc, length)) return offset; - } - - offset = ctl2_alloc_segment(typelib, MSFT_SEG_IMPORTFILES, length + 0xc, 0); - - importfile = (MSFT_ImpFile *)&typelib->typelib_segment_data[MSFT_SEG_IMPORTFILES][offset]; - importfile->guid = guidoffset; - importfile->lcid = typelib->typelib_header.lcid2; - importfile->version = major_version | (minor_version << 16); - memcpy(&importfile->filename, encoded_string, length); - - return offset; -} - -static void alloc_importinfo(msft_typelib_t *typelib, importinfo_t *importinfo) -{ - importlib_t *importlib = importinfo->importlib; - - chat("alloc_importinfo: %s\n", importinfo->name); - - if(!importlib->allocated) { - MSFT_GuidEntry guid; - int guid_idx; - - chat("allocating importlib %s\n", importlib->name); - - importlib->allocated = -1; - - memcpy(&guid.guid, &importlib->guid, sizeof(GUID)); - guid.hreftype = 2; - - guid_idx = ctl2_alloc_guid(typelib, &guid); - - alloc_importfile(typelib, guid_idx, importlib->version&0xffff, - importlib->version>>16, importlib->name); - } - - if(importinfo->offset == -1 || !(importinfo->flags & MSFT_IMPINFO_OFFSET_IS_GUID)) { - MSFT_ImpInfo impinfo; - - impinfo.flags = importinfo->flags; - impinfo.oImpFile = 0; - - if(importinfo->flags & MSFT_IMPINFO_OFFSET_IS_GUID) { - MSFT_GuidEntry guid; - - guid.hreftype = 0; - memcpy(&guid.guid, &importinfo->guid, sizeof(GUID)); - - impinfo.oGuid = ctl2_alloc_guid(typelib, &guid); - - importinfo->offset = alloc_msft_importinfo(typelib, &impinfo); - - typelib->typelib_segment_data[MSFT_SEG_GUID][impinfo.oGuid+sizeof(GUID)] - = importinfo->offset+1; - - if(!strcmp(importinfo->name, "IDispatch")) - typelib->typelib_header.dispatchpos = importinfo->offset+1; - }else { - impinfo.oGuid = importinfo->id; - importinfo->offset = alloc_msft_importinfo(typelib, &impinfo); - } - } -} - -static importinfo_t *find_importinfo(msft_typelib_t *typelib, const char *name) -{ - importlib_t *importlib; - int i; - - chat("search importlib %s\n", name); - - if(!name) - return NULL; - - LIST_FOR_EACH_ENTRY( importlib, &typelib->typelib->importlibs, importlib_t, entry ) - { - for(i=0; i < importlib->ntypeinfos; i++) { - if(!strcmp(name, importlib->importinfos[i].name)) { - chat("Found %s in importlib.\n", name); - return importlib->importinfos+i; - } - } - } - - return NULL; -} - -static void add_structure_typeinfo(msft_typelib_t *typelib, type_t *structure); -static void add_interface_typeinfo(msft_typelib_t *typelib, type_t *interface); -static void add_enum_typeinfo(msft_typelib_t *typelib, type_t *enumeration); -static void add_coclass_typeinfo(msft_typelib_t *typelib, type_t *cls); -static void add_dispinterface_typeinfo(msft_typelib_t *typelib, type_t *dispinterface); - - -/**************************************************************************** - * encode_type - * - * Encodes a type, storing information in the TYPEDESC and ARRAYDESC - * segments as needed. - * - * RETURNS - * - * Success: 0. - * Failure: -1. - */ -static int encode_type( - msft_typelib_t *typelib, /* [I] The type library in which to encode the TYPEDESC. */ - int vt, /* [I] vt to encode */ - type_t *type, /* [I] type */ - int *encoded_type, /* [O] The encoded type description. */ - int *width, /* [O] The width of the type, or NULL. */ - int *alignment, /* [O] The alignment of the type, or NULL. */ - int *decoded_size) /* [O] The total size of the unencoded TYPEDESCs, including nested descs. */ -{ - int default_type; - int scratch; - int typeoffset; - int *typedata; - int target_type; - int child_size = 0; - - chat("encode_type vt %d type %p\n", vt, type); - - default_type = 0x80000000 | (vt << 16) | vt; - if (!width) width = &scratch; - if (!alignment) alignment = &scratch; - if (!decoded_size) decoded_size = &scratch; - - - switch (vt) { - case VT_I1: - case VT_UI1: - *encoded_type = default_type; - *width = 1; - *alignment = 1; - break; - - case VT_INT: - *encoded_type = 0x80000000 | (VT_I4 << 16) | VT_INT; - if ((typelib->typelib_header.varflags & 0x0f) == SYS_WIN16) { - *width = 2; - *alignment = 2; - } else { - *width = 4; - *alignment = 4; - } - break; - - case VT_UINT: - *encoded_type = 0x80000000 | (VT_UI4 << 16) | VT_UINT; - if ((typelib->typelib_header.varflags & 0x0f) == SYS_WIN16) { - *width = 2; - *alignment = 2; - } else { - *width = 4; - *alignment = 4; - } - break; - - case VT_UI2: - case VT_I2: - case VT_BOOL: - *encoded_type = default_type; - *width = 2; - *alignment = 2; - break; - - case VT_I4: - case VT_UI4: - case VT_R4: - case VT_ERROR: - case VT_BSTR: - case VT_HRESULT: - *encoded_type = default_type; - *width = 4; - *alignment = 4; - break; - - case VT_R8: - case VT_I8: - case VT_UI8: - *encoded_type = default_type; - *width = 8; - *alignment = 8; - break; - - case VT_CY: - case VT_DATE: - *encoded_type = default_type; - *width = 8; - *alignment = 8; - break; - - case VT_VOID: - *encoded_type = 0x80000000 | (VT_EMPTY << 16) | vt; - *width = 0; - *alignment = 1; - break; - - case VT_UNKNOWN: - case VT_DISPATCH: - *encoded_type = default_type; - *width = 4; - *alignment = 4; - break; - - case VT_VARIANT: - *encoded_type = default_type; - break; - - case VT_LPSTR: - case VT_LPWSTR: - *encoded_type = 0xfffe0000 | vt; - *width = 4; - *alignment = 4; - break; - - case VT_PTR: - { - int next_vt; - for(next_vt = 0; type->ref; type = type->ref) { - next_vt = get_type_vt(type->ref); - if (next_vt != 0) - break; - } - /* if no type found then it must be void */ - if (next_vt == 0) - next_vt = VT_VOID; - - encode_type(typelib, next_vt, type->ref, &target_type, NULL, NULL, &child_size); - if(type->ref && (type->ref->type == RPC_FC_IP)) { - chat("encode_type: skipping ptr\n"); - *encoded_type = target_type; - *width = 4; - *alignment = 4; - *decoded_size = child_size; - break; - } - - for (typeoffset = 0; typeoffset < typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) { - typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; - if (((typedata[0] & 0xffff) == VT_PTR) && (typedata[1] == target_type)) break; - } - - if (typeoffset == typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length) { - int mix_field; - - if (target_type & 0x80000000) { - mix_field = ((target_type >> 16) & 0x3fff) | VT_BYREF; - } else { - typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][target_type]; - mix_field = ((typedata[0] >> 16) == 0x7fff)? 0x7fff: 0x7ffe; - } - - typeoffset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEDESC, 8, 0); - typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; - - typedata[0] = (mix_field << 16) | VT_PTR; - typedata[1] = target_type; - } - - *encoded_type = typeoffset; - - *width = 4; - *alignment = 4; - *decoded_size = 8 /*sizeof(TYPEDESC)*/ + child_size; - break; - } - - - case VT_SAFEARRAY: - { - int next_vt; - - /* skip over SAFEARRAY type straight to element type */ - type = type->ref; - - for(next_vt = 0; type->ref; type = type->ref) { - next_vt = get_type_vt(type->ref); - if (next_vt != 0) - break; - } - - encode_type(typelib, next_vt, type->ref, &target_type, NULL, NULL, &child_size); - - for (typeoffset = 0; typeoffset < typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) { - typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; - if (((typedata[0] & 0xffff) == VT_SAFEARRAY) && (typedata[1] == target_type)) break; - } - - if (typeoffset == typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length) { - int mix_field; - - if (target_type & 0x80000000) { - mix_field = ((target_type >> 16) & VT_TYPEMASK) | VT_ARRAY; - } else { - typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][target_type]; - mix_field = ((typedata[0] >> 16) == 0x7fff)? 0x7fff: 0x7ffe; - } - - typeoffset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEDESC, 8, 0); - typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; - - typedata[0] = (mix_field << 16) | VT_SAFEARRAY; - typedata[1] = target_type; - } - - *encoded_type = typeoffset; - - *width = 4; - *alignment = 4; - *decoded_size = 8 /*sizeof(TYPEDESC)*/ + child_size; - break; - } - - - case VT_USERDEFINED: - { - int typeinfo_offset; - - /* typedef'd types without attributes aren't included in the typelib */ - while (type->typelib_idx < 0 && type->kind == TKIND_ALIAS && ! type->attrs) - type = type->orig; - - chat("encode_type: VT_USERDEFINED - type %p name = %s type->type %d idx %d\n", type, - type->name, type->type, type->typelib_idx); - - if(type->typelib_idx == -1) { - chat("encode_type: trying to ref not added type\n"); - switch(type->type) { - case RPC_FC_STRUCT: - case RPC_FC_PSTRUCT: - case RPC_FC_CSTRUCT: - case RPC_FC_CPSTRUCT: - case RPC_FC_CVSTRUCT: - case RPC_FC_BOGUS_STRUCT: - add_structure_typeinfo(typelib, type); - break; - case RPC_FC_IP: - add_interface_typeinfo(typelib, type); - break; - case RPC_FC_ENUM16: - add_enum_typeinfo(typelib, type); - break; - case 0: - if (type->kind == TKIND_COCLASS) - add_coclass_typeinfo(typelib, type); - else if (type->kind == TKIND_DISPATCH) - add_dispinterface_typeinfo(typelib, type); - else - error("encode_type: VT_USERDEFINED - can't yet add typedef's on the fly\n"); - break; - default: - error("encode_type: VT_USERDEFINED - unhandled type %d\n", type->type); - } - } - - typeinfo_offset = typelib->typelib_typeinfo_offsets[type->typelib_idx]; - for (typeoffset = 0; typeoffset < typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) { - typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; - if ((typedata[0] == ((0x7fff << 16) | VT_USERDEFINED)) && (typedata[1] == typeinfo_offset)) break; - } - - if (typeoffset == typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length) { - typeoffset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEDESC, 8, 0); - typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; - - typedata[0] = (0x7fff << 16) | VT_USERDEFINED; - typedata[1] = typeinfo_offset; - } - - *encoded_type = typeoffset; - *width = 0; - *alignment = 1; - - if(type->type == RPC_FC_IP) { - for (typeoffset = 0; typeoffset < typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) { - typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; - if ((typedata[0] == ((0x7fff << 16) | VT_PTR)) && (typedata[1] == *encoded_type)) break; - } - if (typeoffset == typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length) { - typeoffset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEDESC, 8, 0); - typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; - - typedata[0] = (0x7fff << 16) | VT_PTR; - typedata[1] = *encoded_type; - } - *encoded_type = typeoffset; - *width = 4; - *alignment = 4; - *decoded_size += 8; - } - break; - } - - default: - error("encode_type: unrecognized type %d.\n", vt); - *encoded_type = default_type; - *width = 0; - *alignment = 1; - break; - } - - return 0; -} - -static void dump_type(type_t *t) -{ - chat("dump_type: %p name %s type %d ref %p attrs %p\n", t, t->name, t->type, t->ref, t->attrs); - if(t->ref) dump_type(t->ref); -} - -static int encode_var( - msft_typelib_t *typelib, /* [I] The type library in which to encode the TYPEDESC. */ - type_t *type, /* [I] The type description to encode. */ - var_t *var, /* [I] The var to encode. */ - int *encoded_type, /* [O] The encoded type description. */ - int *width, /* [O] The width of the type, or NULL. */ - int *alignment, /* [O] The alignment of the type, or NULL. */ - int *decoded_size) /* [O] The total size of the unencoded TYPEDESCs, including nested descs. */ -{ - int typeoffset; - int *typedata; - int target_type; - int child_size; - int vt; - int scratch; - - if (!width) width = &scratch; - if (!alignment) alignment = &scratch; - if (!decoded_size) decoded_size = &scratch; - *decoded_size = 0; - - chat("encode_var: var %p type %p type->name %s type->ref %p\n", - var, type, type->name ? type->name : "NULL", type->ref); - - if (type->declarray) { - int num_dims, elements = 1, arrayoffset; - type_t *atype; - int *arraydata; - - num_dims = 0; - for (atype = type; atype->declarray; atype = atype->ref) - ++num_dims; - - chat("array with %d dimensions\n", num_dims); - encode_var(typelib, atype, var, &target_type, width, alignment, NULL); - arrayoffset = ctl2_alloc_segment(typelib, MSFT_SEG_ARRAYDESC, (2 + 2 * num_dims) * sizeof(long), 0); - arraydata = (void *)&typelib->typelib_segment_data[MSFT_SEG_ARRAYDESC][arrayoffset]; - - arraydata[0] = target_type; - arraydata[1] = num_dims; - arraydata[1] |= ((num_dims * 2 * sizeof(long)) << 16); - - arraydata += 2; - for (atype = type; atype->declarray; atype = atype->ref) - { - arraydata[0] = atype->dim; - arraydata[1] = 0; - arraydata += 2; - elements *= atype->dim; - } - - typeoffset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEDESC, 8, 0); - typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; - - typedata[0] = (0x7ffe << 16) | VT_CARRAY; - typedata[1] = arrayoffset; - - *encoded_type = typeoffset; - *width = *width * elements; - *decoded_size = 20 /*sizeof(ARRAYDESC)*/ + (num_dims - 1) * 8 /*sizeof(SAFEARRAYBOUND)*/; - return 0; - } - - vt = get_type_vt(type); - if (vt == VT_PTR) { - int skip_ptr = encode_var(typelib, type->ref, var, &target_type, NULL, NULL, &child_size); - - if(skip_ptr == 2) { - chat("encode_var: skipping ptr\n"); - *encoded_type = target_type; - *decoded_size = child_size; - *width = 4; - *alignment = 4; - return 0; - } - - for (typeoffset = 0; typeoffset < typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) { - typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; - if (((typedata[0] & 0xffff) == VT_PTR) && (typedata[1] == target_type)) break; - } - - if (typeoffset == typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length) { - int mix_field; - - if (target_type & 0x80000000) { - mix_field = ((target_type >> 16) & 0x3fff) | VT_BYREF; - } else { - typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][target_type]; - mix_field = ((typedata[0] >> 16) == 0x7fff)? 0x7fff: 0x7ffe; - } - - typeoffset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEDESC, 8, 0); - typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; - - typedata[0] = (mix_field << 16) | VT_PTR; - typedata[1] = target_type; - } - - *encoded_type = typeoffset; - - *width = 4; - *alignment = 4; - *decoded_size = 8 /*sizeof(TYPEDESC)*/ + child_size; - return 0; - } - - dump_type(type); - - encode_type(typelib, vt, type, encoded_type, width, alignment, decoded_size); - if(type->type == RPC_FC_IP) return 2; - return 0; -} - -static unsigned long get_ulong_val(unsigned long val, int vt) -{ - switch(vt) { - case VT_I2: - case VT_BOOL: - case VT_UI2: - return val & 0xffff; - case VT_I1: - case VT_UI1: - return val & 0xff; - } - - return val; -} - -static void write_value(msft_typelib_t* typelib, int *out, int vt, void *value) -{ - switch(vt) { - case VT_I2: - case VT_I4: - case VT_R4: - case VT_BOOL: - case VT_I1: - case VT_UI1: - case VT_UI2: - case VT_UI4: - case VT_INT: - case VT_UINT: - case VT_HRESULT: - case VT_PTR: - { - const unsigned long lv = get_ulong_val(*(unsigned long*)value, vt); - if((lv & 0x3ffffff) == lv) { - *out = 0x80000000; - *out |= vt << 26; - *out |= lv; - } else { - int offset = ctl2_alloc_segment(typelib, MSFT_SEG_CUSTDATA, 8, 0); - *((unsigned short *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset]) = vt; - memcpy(&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset+2], value, 4); - *((unsigned short *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset+6]) = 0x5757; - *out = offset; - } - return; - } - case VT_BSTR: - { - char *s = (char *) value; - int len = strlen(s), seg_len = (len + 6 + 3) & ~0x3; - int offset = ctl2_alloc_segment(typelib, MSFT_SEG_CUSTDATA, seg_len, 0); - *((unsigned short *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset]) = vt; - *((unsigned int *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset+2]) = len; - memcpy(&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset+6], value, len); - len += 6; - while(len < seg_len) { - *((char *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset+len]) = 0x57; - len++; - } - *out = offset; - return; - } - - default: - warning("can't write value of type %d yet\n", vt); - } - return; -} - -static HRESULT set_custdata(msft_typelib_t *typelib, REFGUID guid, - int vt, void *value, int *offset) -{ - MSFT_GuidEntry guidentry; - int guidoffset; - int custoffset; - int *custdata; - int data_out; - - guidentry.guid = *guid; - - guidentry.hreftype = -1; - guidentry.next_hash = -1; - - guidoffset = ctl2_alloc_guid(typelib, &guidentry); - write_value(typelib, &data_out, vt, value); - - custoffset = ctl2_alloc_segment(typelib, MSFT_SEG_CUSTDATAGUID, 12, 0); - - custdata = (int *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATAGUID][custoffset]; - custdata[0] = guidoffset; - custdata[1] = data_out; - custdata[2] = *offset; - *offset = custoffset; - - return S_OK; -} - -static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, const func_t *func, int index) -{ - int offset, name_offset; - int *typedata, typedata_size; - int i, id, next_idx; - int decoded_size, extra_attr = 0; - int num_params = 0, num_optional = 0, num_defaults = 0; - var_t *arg; - char *namedata; - const attr_t *attr; - unsigned int funcflags = 0, callconv = 4 /* CC_STDCALL */; - unsigned int funckind, invokekind = 1 /* INVOKE_FUNC */; - int help_context = 0, help_string_context = 0, help_string_offset = -1; - int entry = -1, entry_is_ord = 0; - - chat("add_func_desc(%p,%d)\n", typeinfo, index); - - id = ((0x6000 | (typeinfo->typeinfo->datatype2 & 0xffff)) << 16) | index; - - switch(typeinfo->typekind) { - case TKIND_DISPATCH: - funckind = 0x4; /* FUNC_DISPATCH */ - break; - case TKIND_MODULE: - funckind = 0x3; /* FUNC_STATIC */ - break; - default: - funckind = 0x1; /* FUNC_PUREVIRTUAL */ - break; - } - - if (is_local( func->def->attrs )) { - chat("add_func_desc: skipping local function\n"); - return S_FALSE; - } - - if (func->args) - LIST_FOR_EACH_ENTRY( arg, func->args, var_t, entry ) - { - num_params++; - if (arg->attrs) LIST_FOR_EACH_ENTRY( attr, arg->attrs, const attr_t, entry ) { - if(attr->type == ATTR_DEFAULTVALUE_EXPR || attr->type == ATTR_DEFAULTVALUE_STRING) - num_defaults++; - else if(attr->type == ATTR_OPTIONAL) - num_optional++; - } - } - - chat("add_func_desc: num of params %d\n", num_params); - - name_offset = ctl2_alloc_name(typeinfo->typelib, func->def->name); - - if (func->def->attrs) LIST_FOR_EACH_ENTRY( attr, func->def->attrs, const attr_t, entry ) { - expr_t *expr = attr->u.pval; - switch(attr->type) { - case ATTR_BINDABLE: - funcflags |= 0x4; /* FUNCFLAG_BINDABLE */ - break; - case ATTR_DISPLAYBIND: - funcflags |= 0x10; /* FUNCFLAG_DISPLAYBIND */ - break; - case ATTR_ENTRY_ORDINAL: - extra_attr = max(extra_attr, 3); - entry = expr->cval; - entry_is_ord = 1; - break; - case ATTR_ENTRY_STRING: - extra_attr = max(extra_attr, 3); - entry = ctl2_alloc_string(typeinfo->typelib, attr->u.pval); - break; - case ATTR_HELPCONTEXT: - extra_attr = max(extra_attr, 1); - help_context = expr->u.lval; - break; - case ATTR_HELPSTRING: - extra_attr = max(extra_attr, 2); - help_string_offset = ctl2_alloc_string(typeinfo->typelib, attr->u.pval); - break; - case ATTR_HELPSTRINGCONTEXT: - extra_attr = max(extra_attr, 6); - help_string_context = expr->u.lval; - break; - case ATTR_HIDDEN: - funcflags |= 0x40; /* FUNCFLAG_FHIDDEN */ - break; - case ATTR_ID: - id = expr->cval; - break; - case ATTR_NONBROWSABLE: - funcflags |= 0x400; /* FUNCFLAG_NONBROWSABLE */ - break; - case ATTR_OUT: - break; - case ATTR_PROPGET: - invokekind = 0x2; /* INVOKE_PROPERTYGET */ - break; - case ATTR_PROPPUT: - invokekind = 0x4; /* INVOKE_PROPERTYPUT */ - break; - case ATTR_PROPPUTREF: - invokekind = 0x8; /* INVOKE_PROPERTYPUTREF */ - break; - case ATTR_RESTRICTED: - funcflags |= 0x1; /* FUNCFLAG_FRESTRICTED */ - break; - case ATTR_VARARG: - if (num_optional || num_defaults) - warning("add_func_desc: ignoring vararg in function with optional or defaultvalue params\n"); - else - num_optional = -1; - break; - default: - warning("add_func_desc: ignoring attr %d\n", attr->type); - break; - } - } - - /* allocate type data space for us */ - typedata_size = 0x18 + extra_attr * sizeof(int) + (num_params * (num_defaults ? 16 : 12)); - - if (!typeinfo->func_data) { - typeinfo->func_data = xmalloc(0x100); - typeinfo->func_data_allocated = 0x100; - typeinfo->func_data[0] = 0; - } - - if(typeinfo->func_data[0] + typedata_size + sizeof(int) > typeinfo->func_data_allocated) { - typeinfo->func_data_allocated = max(typeinfo->func_data_allocated * 2, - typeinfo->func_data[0] + typedata_size + sizeof(int)); - typeinfo->func_data = xrealloc(typeinfo->func_data, typeinfo->func_data_allocated); - } - - offset = typeinfo->func_data[0]; - typeinfo->func_data[0] += typedata_size; - typedata = typeinfo->func_data + (offset >> 2) + 1; - - - /* find func with the same name - if it exists use its id */ - for(i = 0; i < (typeinfo->typeinfo->cElement & 0xffff); i++) { - if(name_offset == typeinfo->func_names[i]) { - id = typeinfo->func_indices[i]; - break; - } - } - - /* find the first func with the same id and link via the hiword of typedata[4] */ - next_idx = index; - for(i = 0; i < (typeinfo->typeinfo->cElement & 0xffff); i++) { - if(id == typeinfo->func_indices[i]) { - next_idx = typeinfo->func_data[(typeinfo->func_offsets[i] >> 2) + 1 + 4] >> 16; - typeinfo->func_data[(typeinfo->func_offsets[i] >> 2) + 1 + 4] &= 0xffff; - typeinfo->func_data[(typeinfo->func_offsets[i] >> 2) + 1 + 4] |= (index << 16); - break; - } - } - - /* fill out the basic type information */ - typedata[0] = typedata_size | (index << 16); - encode_var(typeinfo->typelib, func->def->type, func->def, &typedata[1], NULL, NULL, &decoded_size); - typedata[2] = funcflags; - typedata[3] = ((52 /*sizeof(FUNCDESC)*/ + decoded_size) << 16) | typeinfo->typeinfo->cbSizeVft; - typedata[4] = (next_idx << 16) | (callconv << 8) | (invokekind << 3) | funckind; - if(num_defaults) typedata[4] |= 0x1000; - if(entry_is_ord) typedata[4] |= 0x2000; - typedata[5] = (num_optional << 16) | num_params; - - /* NOTE: High word of typedata[3] is total size of FUNCDESC + size of all ELEMDESCs for params + TYPEDESCs for pointer params and return types. */ - /* That is, total memory allocation required to reconstitute the FUNCDESC in its entirety. */ - typedata[3] += (16 /*sizeof(ELEMDESC)*/ * num_params) << 16; - typedata[3] += (24 /*sizeof(PARAMDESCEX)*/ * num_defaults) << 16; - - switch(extra_attr) { - case 6: typedata[11] = help_string_context; - case 5: typedata[10] = -1; - case 4: typedata[9] = -1; - case 3: typedata[8] = entry; - case 2: typedata[7] = help_string_offset; - case 1: typedata[6] = help_context; - case 0: - break; - default: - warning("unknown number of optional attrs\n"); - } - - if (func->args) - { - i = 0; - LIST_FOR_EACH_ENTRY( arg, func->args, var_t, entry ) - { - const attr_t *attr; - int paramflags = 0; - int *paramdata = typedata + 6 + extra_attr + (num_defaults ? num_params : 0) + i * 3; - int *defaultdata = num_defaults ? typedata + 6 + extra_attr + i : NULL; - - if(defaultdata) *defaultdata = -1; - - encode_var(typeinfo->typelib, arg->type, arg, paramdata, NULL, NULL, &decoded_size); - if (arg->attrs) LIST_FOR_EACH_ENTRY( attr, arg->attrs, const attr_t, entry ) { - switch(attr->type) { - case ATTR_DEFAULTVALUE_EXPR: - { - int vt; - expr_t *expr = (expr_t *)attr->u.pval; - if (arg->type->type == RPC_FC_ENUM16) - vt = VT_INT; - else - vt = get_type_vt(arg->type); - paramflags |= 0x30; /* PARAMFLAG_FHASDEFAULT | PARAMFLAG_FOPT */ - chat("default value %ld\n", expr->cval); - write_value(typeinfo->typelib, defaultdata, vt, &expr->cval); - break; - } - case ATTR_DEFAULTVALUE_STRING: - { - char *s = (char *)attr->u.pval; - int vt; - if (arg->type->type == RPC_FC_ENUM16) - vt = VT_INT; - else - vt = get_type_vt(arg->type); - paramflags |= 0x30; /* PARAMFLAG_FHASDEFAULT | PARAMFLAG_FOPT */ - chat("default value '%s'\n", s); - write_value(typeinfo->typelib, defaultdata, vt, s); - break; - } - case ATTR_IN: - paramflags |= 0x01; /* PARAMFLAG_FIN */ - break; - case ATTR_OPTIONAL: - paramflags |= 0x10; /* PARAMFLAG_FOPT */ - break; - case ATTR_OUT: - paramflags |= 0x02; /* PARAMFLAG_FOUT */ - break; - case ATTR_RETVAL: - paramflags |= 0x08; /* PARAMFLAG_FRETVAL */ - typedata[4] |= 0x4000; - break; - default: - chat("unhandled param attr %d\n", attr->type); - break; - } - } - paramdata[1] = -1; - paramdata[2] = paramflags; - typedata[3] += decoded_size << 16; - i++; - } - } - - if(typeinfo->funcs_allocated == 0) { - typeinfo->funcs_allocated = 10; - typeinfo->func_indices = xmalloc(typeinfo->funcs_allocated * sizeof(int)); - typeinfo->func_names = xmalloc(typeinfo->funcs_allocated * sizeof(int)); - typeinfo->func_offsets = xmalloc(typeinfo->funcs_allocated * sizeof(int)); - } - if(typeinfo->funcs_allocated == (typeinfo->typeinfo->cElement & 0xffff)) { - typeinfo->funcs_allocated *= 2; - typeinfo->func_indices = xrealloc(typeinfo->func_indices, typeinfo->funcs_allocated * sizeof(int)); - typeinfo->func_names = xrealloc(typeinfo->func_names, typeinfo->funcs_allocated * sizeof(int)); - typeinfo->func_offsets = xrealloc(typeinfo->func_offsets, typeinfo->funcs_allocated * sizeof(int)); - } - - /* update the index data */ - typeinfo->func_indices[typeinfo->typeinfo->cElement & 0xffff] = id; - typeinfo->func_offsets[typeinfo->typeinfo->cElement & 0xffff] = offset; - typeinfo->func_names[typeinfo->typeinfo->cElement & 0xffff] = name_offset; - - /* ??? */ - if (!typeinfo->typeinfo->res2) typeinfo->typeinfo->res2 = 0x20; - typeinfo->typeinfo->res2 <<= 1; - /* ??? */ - if (index < 2) typeinfo->typeinfo->res2 += num_params << 4; - - if (typeinfo->typeinfo->res3 == -1) typeinfo->typeinfo->res3 = 0; - typeinfo->typeinfo->res3 += 0x38 + num_params * 0x10; - if(num_defaults) typeinfo->typeinfo->res3 += num_params * 0x4; - - /* adjust size of VTBL */ - if(funckind != 0x3 /* FUNC_STATIC */) - typeinfo->typeinfo->cbSizeVft += 4; - - /* Increment the number of function elements */ - typeinfo->typeinfo->cElement += 1; - - namedata = typeinfo->typelib->typelib_segment_data[MSFT_SEG_NAME] + name_offset; - if (*((INT *)namedata) == -1) { - *((INT *)namedata) = typeinfo->typelib->typelib_typeinfo_offsets[typeinfo->typeinfo->typekind >> 16]; - if(typeinfo->typekind == TKIND_MODULE) - namedata[9] |= 0x10; - } else - namedata[9] &= ~0x10; - - if(typeinfo->typekind == TKIND_MODULE) - namedata[9] |= 0x20; - - if (func->args) - { - i = 0; - LIST_FOR_EACH_ENTRY( arg, func->args, var_t, entry ) - { - /* don't give the last arg of a [propput*] func a name */ - if(i != num_params - 1 || (invokekind != 0x4 /* INVOKE_PROPERTYPUT */ && invokekind != 0x8 /* INVOKE_PROPERTYPUTREF */)) - { - int *paramdata = typedata + 6 + extra_attr + (num_defaults ? num_params : 0) + i * 3; - offset = ctl2_alloc_name(typeinfo->typelib, arg->name); - paramdata[1] = offset; - } - i++; - } - } - return S_OK; -} - -static HRESULT add_var_desc(msft_typeinfo_t *typeinfo, UINT index, var_t* var) -{ - int offset, id; - unsigned int typedata_size; - INT *typedata; - int var_datawidth; - int var_alignment; - int var_type_size, var_kind = 0 /* VAR_PERINSTANCE */; - int alignment; - int varflags = 0; - const attr_t *attr; - char *namedata; - int var_num = (typeinfo->typeinfo->cElement >> 16) & 0xffff; - - chat("add_var_desc(%d, %s)\n", index, var->name); - - id = 0x40000000 + index; - - if (var->attrs) LIST_FOR_EACH_ENTRY( attr, var->attrs, const attr_t, entry ) { - expr_t *expr = attr->u.pval; - switch(attr->type) { - case ATTR_HIDDEN: - varflags |= 0x40; /* VARFLAG_FHIDDEN */ - break; - case ATTR_ID: - id = expr->cval; - break; - case ATTR_READONLY: - varflags |= 0x01; /* VARFLAG_FREADONLY */ - break; - case ATTR_RESTRICTED: - varflags |= 0x80; /* VARFLAG_FRESTRICTED */ - break; - case ATTR_SOURCE: - varflags |= 0x02; /* VARFLAG_FSOURCE */ - break; - default: - warning("AddVarDesc: unhandled attr type %d\n", attr->type); - break; - } - } - - /* allocate type data space for us */ - typedata_size = 0x14; - - if (!typeinfo->var_data) { - typeinfo->var_data = xmalloc(0x100); - typeinfo->var_data_allocated = 0x100; - typeinfo->var_data[0] = 0; - } - - if(typeinfo->var_data[0] + typedata_size + sizeof(int) > typeinfo->var_data_allocated) { - typeinfo->var_data_allocated = max(typeinfo->var_data_allocated * 2, - typeinfo->var_data[0] + typedata_size + sizeof(int)); - typeinfo->var_data = xrealloc(typeinfo->var_data, typeinfo->var_data_allocated); - } - - offset = typeinfo->var_data[0]; - typeinfo->var_data[0] += typedata_size; - typedata = typeinfo->var_data + (offset >> 2) + 1; - - /* fill out the basic type information */ - typedata[0] = typedata_size | (index << 16); - typedata[2] = varflags; - typedata[3] = (36 /*sizeof(VARDESC)*/ << 16) | 0; - - if(typeinfo->vars_allocated == 0) { - typeinfo->vars_allocated = 10; - typeinfo->var_indices = xmalloc(typeinfo->vars_allocated * sizeof(int)); - typeinfo->var_names = xmalloc(typeinfo->vars_allocated * sizeof(int)); - typeinfo->var_offsets = xmalloc(typeinfo->vars_allocated * sizeof(int)); - } - if(typeinfo->vars_allocated == var_num) { - typeinfo->vars_allocated *= 2; - typeinfo->var_indices = xrealloc(typeinfo->var_indices, typeinfo->vars_allocated * sizeof(int)); - typeinfo->var_names = xrealloc(typeinfo->var_names, typeinfo->vars_allocated * sizeof(int)); - typeinfo->var_offsets = xrealloc(typeinfo->var_offsets, typeinfo->vars_allocated * sizeof(int)); - } - /* update the index data */ - typeinfo->var_indices[var_num] = id; - typeinfo->var_names[var_num] = -1; - typeinfo->var_offsets[var_num] = offset; - - /* figure out type widths and whatnot */ - encode_var(typeinfo->typelib, var->type, var, &typedata[1], &var_datawidth, - &var_alignment, &var_type_size); - - /* pad out starting position to data width */ - typeinfo->datawidth += var_alignment - 1; - typeinfo->datawidth &= ~(var_alignment - 1); - - switch(typeinfo->typekind) { - case TKIND_ENUM: - write_value(typeinfo->typelib, &typedata[4], VT_I4, &var->eval->cval); - var_kind = 2; /* VAR_CONST */ - var_type_size += 16; /* sizeof(VARIANT) */ - typeinfo->datawidth = var_datawidth; - break; - case TKIND_RECORD: - typedata[4] = typeinfo->datawidth; - typeinfo->datawidth += var_datawidth; - break; - case TKIND_DISPATCH: - var_kind = 3; /* VAR_DISPATCH */ - typeinfo->datawidth = 4; - var_alignment = 4; - break; - default: - error("add_var_desc: unhandled type kind %d\n", typeinfo->typekind); - break; - } - - /* add type description size to total required allocation */ - typedata[3] += var_type_size << 16 | var_kind; - - /* fix type alignment */ - alignment = (typeinfo->typeinfo->typekind >> 11) & 0x1f; - if (alignment < var_alignment) { - alignment = var_alignment; - typeinfo->typeinfo->typekind &= ~0xffc0; - typeinfo->typeinfo->typekind |= alignment << 11 | alignment << 6; - } - - /* ??? */ - if (!typeinfo->typeinfo->res2) typeinfo->typeinfo->res2 = 0x1a; - if ((index == 0) || (index == 1) || (index == 2) || (index == 4) || (index == 9)) { - typeinfo->typeinfo->res2 <<= 1; - } - - /* ??? */ - if (typeinfo->typeinfo->res3 == -1) typeinfo->typeinfo->res3 = 0; - typeinfo->typeinfo->res3 += 0x2c; - - /* increment the number of variable elements */ - typeinfo->typeinfo->cElement += 0x10000; - - /* pad data width to alignment */ - typeinfo->typeinfo->size = (typeinfo->datawidth + (alignment - 1)) & ~(alignment - 1); - - offset = ctl2_alloc_name(typeinfo->typelib, var->name); - if (offset == -1) return E_OUTOFMEMORY; - - namedata = typeinfo->typelib->typelib_segment_data[MSFT_SEG_NAME] + offset; - if (*((INT *)namedata) == -1) { - *((INT *)namedata) = typeinfo->typelib->typelib_typeinfo_offsets[typeinfo->typeinfo->typekind >> 16]; - if(typeinfo->typekind != TKIND_DISPATCH) - namedata[9] |= 0x10; - } else - namedata[9] &= ~0x10; - - if (typeinfo->typekind == TKIND_ENUM) { - namedata[9] |= 0x20; - } - typeinfo->var_names[var_num] = offset; - - return S_OK; -} - -static HRESULT add_impl_type(msft_typeinfo_t *typeinfo, type_t *ref, importinfo_t *importinfo) -{ - if(importinfo) { - alloc_importinfo(typeinfo->typelib, importinfo); - typeinfo->typeinfo->datatype1 = importinfo->offset+1; - }else { - if(ref->typelib_idx == -1) - add_interface_typeinfo(typeinfo->typelib, ref); - if(ref->typelib_idx == -1) - error("add_impl_type: unable to add inherited interface\n"); - - typeinfo->typeinfo->datatype1 = typeinfo->typelib->typelib_typeinfo_offsets[ref->typelib_idx]; - } - - typeinfo->typeinfo->cImplTypes++; - return S_OK; -} - -static msft_typeinfo_t *create_msft_typeinfo(msft_typelib_t *typelib, enum type_kind kind, - const char *name, const attr_list_t *attrs) -{ - const attr_t *attr; - msft_typeinfo_t *msft_typeinfo; - int nameoffset; - int typeinfo_offset; - MSFT_TypeInfoBase *typeinfo; - MSFT_GuidEntry guidentry; - - chat("create_msft_typeinfo: name %s kind %d\n", name, kind); - - msft_typeinfo = xmalloc(sizeof(*msft_typeinfo)); - memset( msft_typeinfo, 0, sizeof(*msft_typeinfo) ); - - msft_typeinfo->typelib = typelib; - - nameoffset = ctl2_alloc_name(typelib, name); - typeinfo_offset = ctl2_alloc_typeinfo(typelib, nameoffset); - typeinfo = (MSFT_TypeInfoBase *)&typelib->typelib_segment_data[MSFT_SEG_TYPEINFO][typeinfo_offset]; - - typelib->typelib_segment_data[MSFT_SEG_NAME][nameoffset + 9] = 0x38; - *((int *)&typelib->typelib_segment_data[MSFT_SEG_NAME][nameoffset]) = typeinfo_offset; - - msft_typeinfo->typekind = kind; - msft_typeinfo->typeinfo = typeinfo; - - typeinfo->typekind |= kind | 0x20; - - if(kind == TKIND_COCLASS) - typeinfo->flags |= 0x2; /* TYPEFLAG_FCANCREATE */ - - if (attrs) LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry ) { - switch(attr->type) { - case ATTR_AGGREGATABLE: - if (kind == TKIND_COCLASS) - typeinfo->flags |= 0x400; /* TYPEFLAG_FAGGREGATABLE */ - break; - - case ATTR_APPOBJECT: - if (kind == TKIND_COCLASS) - typeinfo->flags |= 0x1; /* TYPEFLAG_FAPPOBJECT */ - break; - - case ATTR_CONTROL: - if (kind == TKIND_COCLASS) - typeinfo->flags |= 0x20; /* TYPEFLAG_FCONTROL */ - break; - - case ATTR_DISPINTERFACE: - break; - - case ATTR_DLLNAME: - { - int offset = ctl2_alloc_string(typelib, attr->u.pval); - typeinfo->datatype1 = offset; - break; - } - - case ATTR_DUAL: - /* FIXME: check interface is compatible */ - typeinfo->typekind = (typeinfo->typekind & ~0xff) | 0x34; - typeinfo->flags |= 0x140; /* TYPEFLAG_FDUAL | TYPEFLAG_FOLEAUTOMATION */ - break; - - case ATTR_HELPCONTEXT: - { - expr_t *expr = (expr_t*)attr->u.pval; - typeinfo->helpcontext = expr->cval; - break; - } - case ATTR_HELPSTRING: - { - int offset = ctl2_alloc_string(typelib, attr->u.pval); - if (offset == -1) break; - typeinfo->docstringoffs = offset; - break; - } - case ATTR_HELPSTRINGCONTEXT: - { - expr_t *expr = (expr_t*)attr->u.pval; - typeinfo->helpstringcontext = expr->cval; - break; - } - case ATTR_HIDDEN: - typeinfo->flags |= 0x10; /* TYPEFLAG_FHIDDEN */ - break; - - case ATTR_NONCREATABLE: - typeinfo->flags &= ~0x2; /* TYPEFLAG_FCANCREATE */ - break; - - case ATTR_NONEXTENSIBLE: - typeinfo->flags |= 0x80; /* TYPEFLAG_FNONEXTENSIBLE */ - break; - - case ATTR_OBJECT: - break; - - case ATTR_ODL: - break; - - case ATTR_OLEAUTOMATION: - typeinfo->flags |= 0x100; /* TYPEFLAG_FOLEAUTOMATION */ - break; - - case ATTR_PUBLIC: - break; - - case ATTR_RESTRICTED: - typeinfo->flags |= 0x200; /* TYPEFLAG_FRESTRICTED */ - break; - - case ATTR_UUID: - guidentry.guid = *(GUID*)attr->u.pval; - guidentry.hreftype = typelib->typelib_typeinfo_offsets[typeinfo->typekind >> 16]; - guidentry.next_hash = -1; - typeinfo->posguid = ctl2_alloc_guid(typelib, &guidentry); -#if 0 - if (IsEqualIID(guid, &IID_IDispatch)) { - typelib->typelib_header.dispatchpos = typelib->typelib_typeinfo_offsets[typeinfo->typekind >> 16]; - } -#endif - break; - - case ATTR_VERSION: - typeinfo->version = attr->u.ival; - break; - - default: - warning("create_msft_typeinfo: ignoring attr %d\n", attr->type); - break; - } - } - - if (typelib->last_typeinfo) typelib->last_typeinfo->next_typeinfo = msft_typeinfo; - typelib->last_typeinfo = msft_typeinfo; - if (!typelib->typeinfos) typelib->typeinfos = msft_typeinfo; - - - return msft_typeinfo; -} - -static void add_dispatch(msft_typelib_t *typelib) -{ - int guid_offset, impfile_offset; - MSFT_GuidEntry guidentry; - MSFT_ImpInfo impinfo; - GUID stdole = {0x00020430,0x0000,0x0000,{0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}}; - GUID iid_idispatch = {0x00020400,0x0000,0x0000,{0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}}; - - if(typelib->typelib_header.dispatchpos != -1) return; - - guidentry.guid = stdole; - guidentry.hreftype = 2; - guidentry.next_hash = -1; - guid_offset = ctl2_alloc_guid(typelib, &guidentry); - impfile_offset = alloc_importfile(typelib, guid_offset, 2, 0, "stdole2.tlb"); - - guidentry.guid = iid_idispatch; - guidentry.hreftype = 1; - guidentry.next_hash = -1; - impinfo.flags = TKIND_INTERFACE << 24 | MSFT_IMPINFO_OFFSET_IS_GUID; - impinfo.oImpFile = impfile_offset; - impinfo.oGuid = ctl2_alloc_guid(typelib, &guidentry); - typelib->typelib_header.dispatchpos = alloc_msft_importinfo(typelib, &impinfo) | 0x01; -} - -static void add_dispinterface_typeinfo(msft_typelib_t *typelib, type_t *dispinterface) -{ - int idx = 0; - const func_t *func; - var_t *var; - msft_typeinfo_t *msft_typeinfo; - - if (-1 < dispinterface->typelib_idx) - return; - - dispinterface->typelib_idx = typelib->typelib_header.nrtypeinfos; - msft_typeinfo = create_msft_typeinfo(typelib, TKIND_DISPATCH, dispinterface->name, - dispinterface->attrs); - - msft_typeinfo->typeinfo->size = 4; - msft_typeinfo->typeinfo->typekind |= 0x2100; - - msft_typeinfo->typeinfo->flags |= 0x1000; /* TYPEFLAG_FDISPATCHABLE */ - add_dispatch(typelib); - msft_typeinfo->typeinfo->cImplTypes = 1; - - /* count the no of funcs, as the variable indices come after the funcs */ - if (dispinterface->funcs) - LIST_FOR_EACH_ENTRY( func, dispinterface->funcs, const func_t, entry ) idx++; - - if (dispinterface->fields) - LIST_FOR_EACH_ENTRY( var, dispinterface->fields, var_t, entry ) - add_var_desc(msft_typeinfo, idx++, var); - - if (dispinterface->funcs) - { - idx = 0; - LIST_FOR_EACH_ENTRY( func, dispinterface->funcs, const func_t, entry ) - if(add_func_desc(msft_typeinfo, func, idx) == S_OK) - idx++; - } -} - -static void add_interface_typeinfo(msft_typelib_t *typelib, type_t *interface) -{ - int idx = 0; - const func_t *func; - type_t *ref; - msft_typeinfo_t *msft_typeinfo; - importinfo_t *ref_importinfo = NULL; - int num_parents = 0, num_funcs = 0; - const type_t *derived; - - if (-1 < interface->typelib_idx) - return; - - if (is_attr(interface->attrs, ATTR_DISPINTERFACE)) - return add_dispinterface_typeinfo(typelib, interface); - - /* midl adds the parent interface first, unless the parent itself - has no parent (i.e. it stops before IUnknown). */ - - if(interface->ref) { - ref_importinfo = find_importinfo(typelib, interface->ref->name); - - if(!ref_importinfo && interface->ref->ref && interface->ref->typelib_idx == -1) - add_interface_typeinfo(typelib, interface->ref); - } - - interface->typelib_idx = typelib->typelib_header.nrtypeinfos; - msft_typeinfo = create_msft_typeinfo(typelib, TKIND_INTERFACE, interface->name, interface->attrs); - msft_typeinfo->typeinfo->size = 4; - msft_typeinfo->typeinfo->typekind |= 0x2200; - - for (derived = interface->ref; derived; derived = derived->ref) - if (derived->name && !strcmp(derived->name, "IDispatch")) - msft_typeinfo->typeinfo->flags |= 0x1000; /* TYPEFLAG_FDISPATCHABLE */ - - /* can't be dual if it doesn't derive from IDispatch */ - if (!(msft_typeinfo->typeinfo->flags & 0x1000)) /* TYPEFLAG_FDISPATCHABLE */ - msft_typeinfo->typeinfo->flags &= ~0x40; /* TYPEFLAG_FDUAL */ - - if(interface->ref) - add_impl_type(msft_typeinfo, interface->ref, ref_importinfo); - - /* count the number of inherited interfaces and non-local functions */ - for(ref = interface->ref; ref; ref = ref->ref) { - num_parents++; - if (ref->funcs) - LIST_FOR_EACH_ENTRY( func, ref->funcs, const func_t, entry ) - if (!is_local(func->def->attrs)) num_funcs++; - } - msft_typeinfo->typeinfo->datatype2 = num_funcs << 16 | num_parents; - msft_typeinfo->typeinfo->cbSizeVft = num_funcs * 4; - - if (interface->funcs) - LIST_FOR_EACH_ENTRY( func, interface->funcs, const func_t, entry ) - if(add_func_desc(msft_typeinfo, func, idx) == S_OK) - idx++; -} - -static void add_structure_typeinfo(msft_typelib_t *typelib, type_t *structure) -{ - int idx = 0; - var_t *cur; - msft_typeinfo_t *msft_typeinfo; - - if (-1 < structure->typelib_idx) - return; - - structure->typelib_idx = typelib->typelib_header.nrtypeinfos; - msft_typeinfo = create_msft_typeinfo(typelib, TKIND_RECORD, structure->name, structure->attrs); - msft_typeinfo->typeinfo->size = 0; - - if (structure->fields) - LIST_FOR_EACH_ENTRY( cur, structure->fields, var_t, entry ) - add_var_desc(msft_typeinfo, idx++, cur); -} - -static void add_enum_typeinfo(msft_typelib_t *typelib, type_t *enumeration) -{ - int idx = 0; - var_t *cur; - msft_typeinfo_t *msft_typeinfo; - - enumeration->typelib_idx = typelib->typelib_header.nrtypeinfos; - msft_typeinfo = create_msft_typeinfo(typelib, TKIND_ENUM, enumeration->name, enumeration->attrs); - msft_typeinfo->typeinfo->size = 0; - - if (enumeration->fields) - LIST_FOR_EACH_ENTRY( cur, enumeration->fields, var_t, entry ) - add_var_desc(msft_typeinfo, idx++, cur); -} - -static void add_typedef_typeinfo(msft_typelib_t *typelib, type_t *tdef) -{ - msft_typeinfo_t *msft_typeinfo; - int alignment; - - if (-1 < tdef->typelib_idx) - return; - - tdef->typelib_idx = typelib->typelib_header.nrtypeinfos; - msft_typeinfo = create_msft_typeinfo(typelib, TKIND_ALIAS, tdef->name, tdef->attrs); - encode_type(typelib, get_type_vt(tdef->orig), tdef->orig, &msft_typeinfo->typeinfo->datatype1, &msft_typeinfo->typeinfo->size, - &alignment, &msft_typeinfo->typeinfo->datatype2); - msft_typeinfo->typeinfo->typekind |= (alignment << 11 | alignment << 6); -} - -static void add_coclass_typeinfo(msft_typelib_t *typelib, type_t *cls) -{ - msft_typeinfo_t *msft_typeinfo; - ifref_t *iref; - int num_ifaces = 0, offset, i; - MSFT_RefRecord *ref, *first = NULL, *first_source = NULL; - int have_default = 0, have_default_source = 0; - const attr_t *attr; - - if (-1 < cls->typelib_idx) - return; - - cls->typelib_idx = typelib->typelib_header.nrtypeinfos; - msft_typeinfo = create_msft_typeinfo(typelib, TKIND_COCLASS, cls->name, cls->attrs); - - if (cls->ifaces) LIST_FOR_EACH_ENTRY( iref, cls->ifaces, ifref_t, entry ) num_ifaces++; - - offset = msft_typeinfo->typeinfo->datatype1 = ctl2_alloc_segment(typelib, MSFT_SEG_REFERENCES, - num_ifaces * sizeof(*ref), 0); - - i = 0; - if (cls->ifaces) LIST_FOR_EACH_ENTRY( iref, cls->ifaces, ifref_t, entry ) { - if(iref->iface->typelib_idx == -1) - add_interface_typeinfo(typelib, iref->iface); - ref = (MSFT_RefRecord*) (typelib->typelib_segment_data[MSFT_SEG_REFERENCES] + offset + i * sizeof(*ref)); - ref->reftype = typelib->typelib_typeinfo_offsets[iref->iface->typelib_idx]; - ref->flags = 0; - ref->oCustData = -1; - ref->onext = -1; - if(i < num_ifaces - 1) - ref->onext = offset + (i + 1) * sizeof(*ref); - - if (iref->attrs) LIST_FOR_EACH_ENTRY( attr, iref->attrs, const attr_t, entry ) { - switch(attr->type) { - case ATTR_DEFAULT: - ref->flags |= 0x1; /* IMPLTYPEFLAG_FDEFAULT */ - break; - case ATTR_RESTRICTED: - ref->flags |= 0x4; /* IMPLTYPEFLAG_FRESTRICTED */ - break; - case ATTR_SOURCE: - ref->flags |= 0x2; /* IMPLTYPEFLAG_FSOURCE */ - break; - default: - warning("add_coclass_typeinfo: unhandled attr %d\n", attr->type); - } - } - if(ref->flags & 0x1) { /* IMPLTYPEFLAG_FDEFAULT */ - if(ref->flags & 0x2) /* IMPLTYPEFLAG_SOURCE */ - have_default_source = 1; - else - have_default = 1; - } - - /* If the interface is non-restricted and we haven't already had one then - remember it so that we can use it as a default later */ - if((ref->flags & 0x4) == 0) { /* IMPLTYPEFLAG_FRESTRICTED */ - if(ref->flags & 0x2) { /* IMPLTYPEFLAG_FSOURCE */ - if(!first_source) - first_source = ref; - } - else if(!first) - first = ref; - } - i++; - } - - /* If we haven't had a default interface, then set the default flags on the - first ones */ - if(!have_default && first) - first->flags |= 0x1; - if(!have_default_source && first_source) - first_source->flags |= 0x1; - - msft_typeinfo->typeinfo->cImplTypes = num_ifaces; - msft_typeinfo->typeinfo->size = 4; - msft_typeinfo->typeinfo->typekind |= 0x2200; -} - -static void add_module_typeinfo(msft_typelib_t *typelib, type_t *module) -{ - int idx = 0; - const func_t *func; - msft_typeinfo_t *msft_typeinfo; - - if (-1 < module->typelib_idx) - return; - - module->typelib_idx = typelib->typelib_header.nrtypeinfos; - msft_typeinfo = create_msft_typeinfo(typelib, TKIND_MODULE, module->name, module->attrs); - msft_typeinfo->typeinfo->typekind |= 0x0a00; - - if (module->funcs) - LIST_FOR_EACH_ENTRY( func, module->funcs, const func_t, entry ) - if(add_func_desc(msft_typeinfo, func, idx) == S_OK) - idx++; - - msft_typeinfo->typeinfo->size = idx; -} - -static void add_entry(msft_typelib_t *typelib, typelib_entry_t *entry) -{ - switch(entry->type->kind) { - case TKIND_INTERFACE: - case TKIND_DISPATCH: - add_interface_typeinfo(typelib, entry->type); - break; - - case TKIND_RECORD: - add_structure_typeinfo(typelib, entry->type); - break; - - case TKIND_ENUM: - add_enum_typeinfo(typelib, entry->type); - break; - - case TKIND_ALIAS: - add_typedef_typeinfo(typelib, entry->type); - break; - - case TKIND_COCLASS: - add_coclass_typeinfo(typelib, entry->type); - break; - - case TKIND_MODULE: - add_module_typeinfo(typelib, entry->type); - break; - - default: - error("add_entry: unhandled type %d\n", entry->type->kind); - break; - } -} - -static void set_name(msft_typelib_t *typelib) -{ - int offset; - - offset = ctl2_alloc_name(typelib, typelib->typelib->name); - if (offset == -1) return; - typelib->typelib_header.NameOffset = offset; - return; -} - -static void set_version(msft_typelib_t *typelib) -{ - typelib->typelib_header.version = get_attrv( typelib->typelib->attrs, ATTR_VERSION ); -} - -static void set_guid(msft_typelib_t *typelib) -{ - MSFT_GuidEntry guidentry; - int offset; - void *ptr; - GUID guid = {0,0,0,{0,0,0,0,0,0}}; - - guidentry.guid = guid; - guidentry.hreftype = -2; - guidentry.next_hash = -1; - - ptr = get_attrp( typelib->typelib->attrs, ATTR_UUID ); - if (ptr) guidentry.guid = *(GUID *)ptr; - - offset = ctl2_alloc_guid(typelib, &guidentry); - typelib->typelib_header.posguid = offset; - - return; -} - -static void set_doc_string(msft_typelib_t *typelib) -{ - char *str = get_attrp( typelib->typelib->attrs, ATTR_HELPSTRING ); - - if (str) - { - int offset = ctl2_alloc_string(typelib, str); - if (offset != -1) typelib->typelib_header.helpstring = offset; - } -} - -static void set_help_file_name(msft_typelib_t *typelib) -{ - char *str = get_attrp( typelib->typelib->attrs, ATTR_HELPFILE ); - - if (str) - { - int offset = ctl2_alloc_string(typelib, str); - if (offset != -1) - { - typelib->typelib_header.helpfile = offset; - typelib->typelib_header.varflags |= 0x10; - } - } -} - -static void set_help_context(msft_typelib_t *typelib) -{ - const expr_t *expr = get_attrp( typelib->typelib->attrs, ATTR_HELPCONTEXT ); - if (expr) typelib->typelib_header.helpcontext = expr->cval; -} - -static void set_help_string_dll(msft_typelib_t *typelib) -{ - char *str = get_attrp( typelib->typelib->attrs, ATTR_HELPSTRINGDLL ); - - if (str) - { - int offset = ctl2_alloc_string(typelib, str); - if (offset != -1) - { - typelib->help_string_dll_offset = offset; - typelib->typelib_header.varflags |= 0x100; - } - } -} - -static void set_help_string_context(msft_typelib_t *typelib) -{ - const expr_t *expr = get_attrp( typelib->typelib->attrs, ATTR_HELPSTRINGCONTEXT ); - if (expr) typelib->typelib_header.helpstringcontext = expr->cval; -} - -static void set_lcid(msft_typelib_t *typelib) -{ - typelib->typelib_header.lcid2 = 0x0; - return; -} - -static void set_lib_flags(msft_typelib_t *typelib) -{ - const attr_t *attr; - - typelib->typelib_header.flags = 0; - if (!typelib->typelib->attrs) return; - LIST_FOR_EACH_ENTRY( attr, typelib->typelib->attrs, const attr_t, entry ) - { - switch(attr->type) { - case ATTR_CONTROL: - typelib->typelib_header.flags |= 0x02; /* LIBFLAG_FCONTROL */ - break; - case ATTR_HIDDEN: - typelib->typelib_header.flags |= 0x04; /* LIBFLAG_FHIDDEN */ - break; - case ATTR_RESTRICTED: - typelib->typelib_header.flags |= 0x01; /* LIBFLAG_FRESTRICTED */ - break; - default: - break; - } - } - return; -} - -static int ctl2_write_chunk(int fd, void *segment, int length) -{ - if (write(fd, segment, length) != length) { - close(fd); - return 0; - } - return -1; -} - -static int ctl2_write_segment(msft_typelib_t *typelib, int fd, int segment) -{ - if (write(fd, typelib->typelib_segment_data[segment], typelib->typelib_segdir[segment].length) - != typelib->typelib_segdir[segment].length) { - close(fd); - return 0; - } - - return -1; -} - -static void ctl2_finalize_typeinfos(msft_typelib_t *typelib, int filesize) -{ - msft_typeinfo_t *typeinfo; - - for (typeinfo = typelib->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) { - typeinfo->typeinfo->memoffset = filesize; - if (typeinfo->func_data) - filesize += typeinfo->func_data[0] + ((typeinfo->typeinfo->cElement & 0xffff) * 12); - if (typeinfo->var_data) - filesize += typeinfo->var_data[0] + (((typeinfo->typeinfo->cElement >> 16) & 0xffff) * 12); - if (typeinfo->func_data || typeinfo->var_data) - filesize += 4; - } -} - -static int ctl2_finalize_segment(msft_typelib_t *typelib, int filepos, int segment) -{ - if (typelib->typelib_segdir[segment].length) { - typelib->typelib_segdir[segment].offset = filepos; - } else { - typelib->typelib_segdir[segment].offset = -1; - } - - return typelib->typelib_segdir[segment].length; -} - - -static void ctl2_write_typeinfos(msft_typelib_t *typelib, int fd) -{ - msft_typeinfo_t *typeinfo; - int typedata_size; - - for (typeinfo = typelib->typeinfos; typeinfo; typeinfo = typeinfo->next_typeinfo) { - if (!typeinfo->func_data && !typeinfo->var_data) continue; - typedata_size = 0; - if (typeinfo->func_data) - typedata_size = typeinfo->func_data[0]; - if (typeinfo->var_data) - typedata_size += typeinfo->var_data[0]; - ctl2_write_chunk(fd, &typedata_size, sizeof(int)); - if (typeinfo->func_data) - ctl2_write_chunk(fd, typeinfo->func_data + 1, typeinfo->func_data[0]); - if (typeinfo->var_data) - ctl2_write_chunk(fd, typeinfo->var_data + 1, typeinfo->var_data[0]); - if (typeinfo->func_indices) - ctl2_write_chunk(fd, typeinfo->func_indices, (typeinfo->typeinfo->cElement & 0xffff) * 4); - if (typeinfo->var_indices) - ctl2_write_chunk(fd, typeinfo->var_indices, (typeinfo->typeinfo->cElement >> 16) * 4); - if (typeinfo->func_names) - ctl2_write_chunk(fd, typeinfo->func_names, (typeinfo->typeinfo->cElement & 0xffff) * 4); - if (typeinfo->var_names) - ctl2_write_chunk(fd, typeinfo->var_names, (typeinfo->typeinfo->cElement >> 16) * 4); - if (typeinfo->func_offsets) - ctl2_write_chunk(fd, typeinfo->func_offsets, (typeinfo->typeinfo->cElement & 0xffff) * 4); - if (typeinfo->var_offsets) { - int add = 0, i, offset; - if(typeinfo->func_data) - add = typeinfo->func_data[0]; - for(i = 0; i < (typeinfo->typeinfo->cElement >> 16); i++) { - offset = typeinfo->var_offsets[i]; - offset += add; - ctl2_write_chunk(fd, &offset, 4); - } - } - } -} - -static int save_all_changes(msft_typelib_t *typelib) -{ - int retval; - int filepos; - int fd; - - chat("save_all_changes(%p)\n", typelib); - - retval = TYPE_E_IOERROR; - - fd = creat(typelib->typelib->filename, 0666); - if (fd == -1) return retval; - - filepos = sizeof(MSFT_Header) + sizeof(MSFT_SegDir); - if(typelib->typelib_header.varflags & 0x100) filepos += 4; /* helpstringdll */ - filepos += typelib->typelib_header.nrtypeinfos * 4; - - filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_TYPEINFO); - filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_GUIDHASH); - filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_GUID); - filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_REFERENCES); - filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_IMPORTINFO); - filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_IMPORTFILES); - filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_NAMEHASH); - filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_NAME); - filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_STRING); - filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_TYPEDESC); - filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_ARRAYDESC); - filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_CUSTDATA); - filepos += ctl2_finalize_segment(typelib, filepos, MSFT_SEG_CUSTDATAGUID); - - ctl2_finalize_typeinfos(typelib, filepos); - - if (!ctl2_write_chunk(fd, &typelib->typelib_header, sizeof(typelib->typelib_header))) return retval; - if(typelib->typelib_header.varflags & 0x100) - if (!ctl2_write_chunk(fd, &typelib->help_string_dll_offset, sizeof(typelib->help_string_dll_offset))) - return retval; - - if (!ctl2_write_chunk(fd, typelib->typelib_typeinfo_offsets, typelib->typelib_header.nrtypeinfos * 4)) return retval; - if (!ctl2_write_chunk(fd, &typelib->typelib_segdir, sizeof(typelib->typelib_segdir))) return retval; - if (!ctl2_write_segment(typelib, fd, MSFT_SEG_TYPEINFO )) return retval; - if (!ctl2_write_segment(typelib, fd, MSFT_SEG_GUIDHASH )) return retval; - if (!ctl2_write_segment(typelib, fd, MSFT_SEG_GUID )) return retval; - if (!ctl2_write_segment(typelib, fd, MSFT_SEG_REFERENCES )) return retval; - if (!ctl2_write_segment(typelib, fd, MSFT_SEG_IMPORTINFO )) return retval; - if (!ctl2_write_segment(typelib, fd, MSFT_SEG_IMPORTFILES )) return retval; - if (!ctl2_write_segment(typelib, fd, MSFT_SEG_NAMEHASH )) return retval; - if (!ctl2_write_segment(typelib, fd, MSFT_SEG_NAME )) return retval; - if (!ctl2_write_segment(typelib, fd, MSFT_SEG_STRING )) return retval; - if (!ctl2_write_segment(typelib, fd, MSFT_SEG_TYPEDESC )) return retval; - if (!ctl2_write_segment(typelib, fd, MSFT_SEG_ARRAYDESC )) return retval; - if (!ctl2_write_segment(typelib, fd, MSFT_SEG_CUSTDATA )) return retval; - if (!ctl2_write_segment(typelib, fd, MSFT_SEG_CUSTDATAGUID)) return retval; - - ctl2_write_typeinfos(typelib, fd); - - if (close(fd) == -1) return retval; - - retval = S_OK; - return retval; -} - -int create_msft_typelib(typelib_t *typelib) -{ - msft_typelib_t *msft; - int failed = 0; - typelib_entry_t *entry; - time_t cur_time; - unsigned int version = 5 << 24 | 1 << 16 | 164; /* 5.01.0164 */ - GUID midl_time_guid = {0xde77ba63,0x517c,0x11d1,{0xa2,0xda,0x00,0x00,0xf8,0x77,0x3c,0xe9}}; - GUID midl_version_guid = {0xde77ba64,0x517c,0x11d1,{0xa2,0xda,0x00,0x00,0xf8,0x77,0x3c,0xe9}}; - - msft = xmalloc(sizeof(*msft)); - memset(msft, 0, sizeof(*msft)); - msft->typelib = typelib; - - ctl2_init_header(msft); - ctl2_init_segdir(msft); - - msft->typelib_header.varflags |= SYS_WIN32; - - /* - * The following two calls return an offset or -1 if out of memory. We - * specifically need an offset of 0, however, so... - */ - if (ctl2_alloc_segment(msft, MSFT_SEG_GUIDHASH, 0x80, 0x80)) { failed = 1; } - if (ctl2_alloc_segment(msft, MSFT_SEG_NAMEHASH, 0x200, 0x200)) { failed = 1; } - - if(failed) - { - free(msft); - return 0; - } - - msft->typelib_guidhash_segment = (int *)msft->typelib_segment_data[MSFT_SEG_GUIDHASH]; - msft->typelib_namehash_segment = (int *)msft->typelib_segment_data[MSFT_SEG_NAMEHASH]; - - memset(msft->typelib_guidhash_segment, 0xff, 0x80); - memset(msft->typelib_namehash_segment, 0xff, 0x200); - - set_lib_flags(msft); - set_lcid(msft); - set_help_file_name(msft); - set_doc_string(msft); - set_guid(msft); - set_version(msft); - set_name(msft); - set_help_context(msft); - set_help_string_dll(msft); - set_help_string_context(msft); - - /* midl adds two sets of custom data to the library: the current unix time - and midl's version number */ - cur_time = time(NULL); - set_custdata(msft, &midl_time_guid, VT_UI4, &cur_time, &msft->typelib_header.CustomDataOffset); - set_custdata(msft, &midl_version_guid, VT_UI4, &version, &msft->typelib_header.CustomDataOffset); - - LIST_FOR_EACH_ENTRY( entry, &typelib->entries, typelib_entry_t, entry ) - add_entry(msft, entry); - - save_all_changes(msft); - free(msft); - return 1; -}