LICENSE: X11 CHANGELOG: * dlls/rpcrt4: ndr_marshall.c, ndr_midl.c, ndr_misc.h, rpcrt4_main.c, ndr_stubless.c; include: rpcndr.h, wine/rpcfc.h: Greg Turner <gmturner007@ameritech.net> - make explicit some missing include dependencies - Implement NdrGetBuffer, NdrFreeBuffer, NdrConformantStringBufferSize and NdrConformantStringMarshall - define the RPC_FC_C_CSTRING constant - perhaps I don't want those MIDL_*_FORMAT_STRING structs, after all. removed. - add RPC todo list - MIDL_STUB_MESSAGE.uFlags aren't. - comment out the NdrClientCall2 mock-up since that stuff is in the process of being implemented and might cause problems. -- gmt "Oh, and of course, the fastest way to dig a tunnel is to dig at both sides." -- The Linux Advanced Routing HOWTO
diff -ur -x CVS -x 'bigdif*' ../wine.test/dlls/rpcrt4/ndr_marshall.c ./dlls/rpcrt4/ndr_marshall.c --- ../wine.test/dlls/rpcrt4/ndr_marshall.c 2002-10-22 02:43:40.000000000 -0500 +++ ./dlls/rpcrt4/ndr_marshall.c 2002-10-24 00:11:20.000000000 -0500 @@ -24,26 +24,56 @@ #include <stdio.h> #include <string.h> +#include <assert.h> #include "windef.h" #include "winbase.h" #include "winerror.h" #include "winreg.h" +#include "ndr_misc.h" + +#include "wine/rpcfc.h" #include "wine/obj_base.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(ole); +#define BUFFER_PARANOIA 40 + /*********************************************************************** * NdrConformantStringMarshall [RPCRT4.@] */ unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg, unsigned char *pszMessage, PFORMAT_STRING pFormat) { - FIXME("stub\n"); - return NULL; + UINT32 len, i; + unsigned char *c; + + TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg, pszMessage, pFormat); + + if (*pFormat == RPC_FC_C_CSTRING) { + len = strlen(pszMessage); + assert( (pStubMsg->BufferLength > (len + 13)) && (pStubMsg->Buffer != NULL) ); + /* in DCE terminology this is a Conformant Varying String */ + c = pStubMsg->Buffer; + ZeroMemory(c, 12); + *((UINT32 *)c) = len + 1; /* max length: strlen + 1 (for '\0') */ + c += 8; /* offset: 0 */ + *((UINT32 *)c) = len + 1; /* actual length: (same) */ + c += 4; + for (i = 0; i <= len; i++) + *(c++) = *(pszMessage++); /* copy the string itself into the remaining space */ + } else { + ERR("Unhandled string type: %#x\n", *pFormat); + /* FIXME what to do here? */ + return NULL; + } + + /* success */ + pStubMsg->fBufferValid = 1; + return NULL; /* is this always right? */ } /*********************************************************************** @@ -51,7 +81,14 @@ */ void WINAPI NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat) { - FIXME("stub\n"); + TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg, pMemory, pFormat); + + if (*pFormat == RPC_FC_C_CSTRING) { + pStubMsg->BufferLength = strlen(pMemory) + BUFFER_PARANOIA; + } else { + ERR("Unhandled string type: %#x\n", *pFormat); + /* FIXME what to do here? */ + } } /************************************************************************ @@ -59,7 +96,7 @@ */ unsigned long WINAPI NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat ) { - FIXME("stub\n"); + FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg, pFormat); return 0; } @@ -70,5 +107,7 @@ PFORMAT_STRING pFormat, unsigned char fMustAlloc ) { FIXME("stub\n"); - return 0; + return NULL; } + +#undef BUFFER_PARANOIA diff -ur -x CVS -x 'bigdif*' ../wine.test/dlls/rpcrt4/ndr_midl.c ./dlls/rpcrt4/ndr_midl.c --- ../wine.test/dlls/rpcrt4/ndr_midl.c 2002-10-23 23:17:52.000000000 -0500 +++ ./dlls/rpcrt4/ndr_midl.c 2002-10-23 23:59:14.000000000 -0500 @@ -196,15 +196,27 @@ */ unsigned char *WINAPI NdrGetBuffer(MIDL_STUB_MESSAGE *stubmsg, unsigned long buflen, RPC_BINDING_HANDLE handle) { - FIXME("stub\n"); - return NULL; + TRACE("(stubmsg == ^%p, buflen == %lu, handle == %p): wild guess.\n", stubmsg, buflen, handle); + + /* FIXME: What are we supposed to do with the handle? */ + + stubmsg->RpcMsg->BufferLength = buflen; + if (I_RpcGetBuffer(stubmsg->RpcMsg) != S_OK) + return NULL; + + stubmsg->BufferLength = stubmsg->RpcMsg->BufferLength; + stubmsg->BufferEnd = stubmsg->BufferStart = 0; + return (stubmsg->Buffer = (unsigned char *)stubmsg->RpcMsg->Buffer); } /*********************************************************************** * NdrFreeBuffer [RPCRT4.@] */ void WINAPI NdrFreeBuffer(MIDL_STUB_MESSAGE *pStubMsg) { - FIXME("stub\n"); + TRACE("(pStubMsg == ^%p): wild guess.\n", pStubMsg); + I_RpcFreeBuffer(pStubMsg->RpcMsg); + pStubMsg->BufferLength = 0; + pStubMsg->Buffer = (unsigned char *)(pStubMsg->RpcMsg->Buffer = NULL); } /************************************************************************ diff -ur -x CVS -x 'bigdif*' ../wine.test/dlls/rpcrt4/ndr_misc.h ./dlls/rpcrt4/ndr_misc.h --- ../wine.test/dlls/rpcrt4/ndr_misc.h 2002-10-22 02:43:40.000000000 -0500 +++ ./dlls/rpcrt4/ndr_misc.h 2002-10-23 23:59:14.000000000 -0500 @@ -23,21 +23,7 @@ #include <stdarg.h> -#define FORMAT_STRING_PARANOIA 20 -#define TYPE_FORMAT_STRING_SIZE (5 + FORMAT_STRING_PARANOIA) -#define PROC_FORMAT_STRING_SIZE (9 + FORMAT_STRING_PARANOIA) - -typedef struct _MIDL_TYPE_FORMAT_STRING -{ - short Pad; - unsigned char Format[TYPE_FORMAT_STRING_SIZE]; -} MIDL_TYPE_FORMAT_STRING; - -typedef struct _MIDL_PROC_FORMAT_STRING -{ - short Pad; - unsigned char Format[PROC_FORMAT_STRING_SIZE]; -} MIDL_PROC_FORMAT_STRING; +#include "rpcndr.h" struct IPSFactoryBuffer; diff -ur -x CVS -x 'bigdif*' ../wine.test/dlls/rpcrt4/ndr_stubless.c ./dlls/rpcrt4/ndr_stubless.c --- ../wine.test/dlls/rpcrt4/ndr_stubless.c 2002-10-21 21:48:54.000000000 -0500 +++ ./dlls/rpcrt4/ndr_stubless.c 2002-10-24 00:40:07.000000000 -0500 @@ -63,16 +63,18 @@ TRACE(" Flags == ^%d\n", rpc_cli_if->Flags); } + /* for now, while these functons are under development, this is too sketchy. commented out. */ + /* NdrClientInitializeNew( &rpcmsg, &stubmsg, pStubDesc, 0 ); - handle = (RPC_BINDING_HANDLE)0xdeadbeef; /* FIXME: dce uses interop_binding_handle; */ - - stubmsg.BufferLength = 0; /* FIXME */ + handle = (RPC_BINDING_HANDLE)0xdeadbeef; */ /* FIXME */ + /* stubmsg.BufferLength = 0;*/ /* FIXME */ + /* NdrGetBuffer( &stubmsg, stubmsg.BufferLength, handle ); NdrSendReceive( &stubmsg, stubmsg.Buffer ); NdrFreeBuffer( &stubmsg ); - + */ return ret; } diff -ur -x CVS -x 'bigdif*' ../wine.test/dlls/rpcrt4/rpcrt4_main.c ./dlls/rpcrt4/rpcrt4_main.c --- ../wine.test/dlls/rpcrt4/rpcrt4_main.c 2002-10-11 12:52:37.000000000 -0500 +++ ./dlls/rpcrt4/rpcrt4_main.c 2002-10-23 23:59:14.000000000 -0500 @@ -16,6 +16,81 @@ * 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 + * + * WINE RPC TODO's (and a few TODONT's) + * + * - widl is like MIDL for wine. For wine to be a useful RPC platform, quite + * a bit of work needs to be done here. widl currently doesn't generate stubs + * for RPC invocation -- it will need to; this is tricky because the MIDL compiler + * does some really wierd stuff. Then again, we don't neccesarily have to + * make widl work like MIDL, so it could be worse. + * + * - RPC has a quite featureful error handling mechanism; none of it is implemented + * right now. + * + * - The server portions of the patch don't seem to be getting accepted by + * Alexandre. My guess is that once I have a working test he'll conceed to + * let this in. To implement this properly is tricky and possibly beyond my + * abilities; Ove seems to think the right way to do this is to use LPC + * (Local Procedure Call, another undocumented monster). LPC has no implementation + * in wine and is not going to be trivial to create. + * + * - 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 a small extent we already do). + * + * - Some transports are not yet implemented. The existing transport implementations + * are incomplete; the various transports probably ought to be supported in a more + * object-oriented manner, like in DCE's RPC implementation, instead of cluttering + * up the code with conditionals like we do now. + * + * - Data marshalling: So far, only the very beginnings of an implementation + * exist in wine. NDR protocol is mostly documented, but the MS API's to + * convert data-types in memory into NDR are not. + * + * - 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 a 100% disconnect between the marshalling in the OLE DLL's + * and the marshalling going on here. This is a good thing, since marshalling + * doesn't work yet. But once it does, obviously there will be the opportunity + * to implement out-of-process OLE using wine's rpcrt4 or some derivative. + * + * - In-source API Documentation, at least for those functions which we have + * implemented, but preferably for everything we can document, would be nice. + * I started out being quite good about this, and ended up getting lazy. + * Some stuff is undocumented by Microsoft and we are guessing how to implement + * (in these cases we should document the behavior we implemented, or, if there + * is no implementation, at least hazard some kind of guess, and put a few + * question marks after it ;) ). + * + * - Stubs. Lots of stuff is defined in Microsoft's headers, including undocumented + * stuff. So let's make a stub-farm and populate it with as many rpcrt4 api's as + * we can stand, so people don't get unimplemented function exceptions. + * + * - Name services: this part hasn't even been started. + * + * - Concurrency: right now I don't think (?) we handle more than one request at a time; + * we are supposed to be able to do this, and to queue requests which exceed the + * concurrency limit. + * + * - Protocol Towers: Totally unimplemented. I don't even know what these are. + * + * - Context Handle Rundown: whatever that is. + * + * - Nested RPC's: Totally unimplemented. + * + * - Statistics: we are supposed to be keeping various counters. we aren't. + * + * - Connectionless RPC: unimplemented. + * + * - ...? More stuff I haven't thought of. If you think of more RPC todo's drop me + * an e-mail <gmturner007@ameritech.net> or send a patch to wine-patches. */ #include "config.h" diff -ur -x CVS -x 'bigdif*' ../wine.test/include/rpcndr.h ./include/rpcndr.h --- ../wine.test/include/rpcndr.h 2002-10-23 23:17:53.000000000 -0500 +++ ./include/rpcndr.h 2002-10-23 23:59:14.000000000 -0500 @@ -24,6 +24,8 @@ #ifndef __WINE_RPCNDR_H #define __WINE_RPCNDR_H +#include "rpc.h" + #define TARGET_IS_NT40_OR_LATER 1 #define TARGET_IS_NT351_OR_WIN95_OR_LATER 1 @@ -93,7 +95,7 @@ int IgnoreEmbeddedPointers; unsigned char *PointerBufferMark; unsigned char fBufferValid; - unsigned char uFlags; + unsigned char Unused; ULONG_PTR MaxCount; unsigned long Offset; unsigned long ActualCount; diff -ur -x CVS -x 'bigdif*' ../wine.test/include/wine/rpcfc.h ./include/wine/rpcfc.h --- ../wine.test/include/wine/rpcfc.h 2002-10-22 02:43:40.000000000 -0500 +++ ./include/wine/rpcfc.h 2002-10-23 23:59:14.000000000 -0500 @@ -46,6 +46,7 @@ #define RPC_FC_BOGUS_ARRAY 0x21 +#define RPC_FC_C_CSTRING 0x22 #define RPC_FC_C_WSTRING 0x25 #define RPC_FC_ENCAPSULATED_UNION 0x2a