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; -}