2 * NDR -Oi,-Oif,-Oicf Interpreter
4 * Copyright 2001 Ove Kåven, TransGaming Technologies
5 * Copyright 2003-5 Robert Shearman (for CodeWeavers)
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 * - Some types of binding handles
27 #include "wine/port.h"
42 #include "wine/debug.h"
43 #include "wine/rpcfc.h"
48 WINE_DEFAULT_DEBUG_CHANNEL(rpc);
50 static inline void call_buffer_sizer(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
52 NDR_BUFFERSIZE m = NdrBufferSizer[pFormat[0]];
53 if (m) m(pStubMsg, pMemory, pFormat);
56 FIXME("format type 0x%x not implemented\n", pFormat[0]);
57 RpcRaiseException(RPC_X_BAD_STUB_DATA);
61 static inline unsigned char *call_marshaller(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
63 NDR_MARSHALL m = NdrMarshaller[pFormat[0]];
64 if (m) return m(pStubMsg, pMemory, pFormat);
67 FIXME("format type 0x%x not implemented\n", pFormat[0]);
68 RpcRaiseException(RPC_X_BAD_STUB_DATA);
73 static inline unsigned char *call_unmarshaller(PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory, PFORMAT_STRING pFormat, unsigned char fMustAlloc)
75 NDR_UNMARSHALL m = NdrUnmarshaller[pFormat[0]];
76 if (m) return m(pStubMsg, ppMemory, pFormat, fMustAlloc);
79 FIXME("format type 0x%x not implemented\n", pFormat[0]);
80 RpcRaiseException(RPC_X_BAD_STUB_DATA);
85 static inline void call_freer(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat)
87 NDR_FREE m = NdrFreer[pFormat[0]];
88 if (m) m(pStubMsg, pMemory, pFormat);
91 FIXME("format type 0x%x not implemented\n", pFormat[0]);
92 RpcRaiseException(RPC_X_BAD_STUB_DATA);
96 static inline unsigned long call_memory_sizer(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
98 NDR_MEMORYSIZE m = NdrMemorySizer[pFormat[0]];
99 if (m) return m(pStubMsg, pFormat);
102 FIXME("format type 0x%x not implemented\n", pFormat[0]);
103 RpcRaiseException(RPC_X_BAD_STUB_DATA);
108 /* there can't be any alignment with the structures in this file */
109 #include "pshpack1.h"
111 #define STUBLESS_UNMARSHAL 1
112 #define STUBLESS_CALLSERVER 2
113 #define STUBLESS_CALCSIZE 3
114 #define STUBLESS_GETBUFFER 4
115 #define STUBLESS_MARSHAL 5
117 /* From http://msdn.microsoft.com/library/default.asp?url=/library/en-us/rpc/rpc/parameter_descriptors.asp */
118 typedef struct _NDR_PROC_HEADER
120 /* type of handle to use:
121 * RPC_FC_BIND_EXPLICIT = 0 - Explicit handle.
122 * Handle is passed as a parameter to the function.
123 * Indicates that explicit handle information follows the header,
124 * which actually describes the handle.
125 * RPC_FC_BIND_GENERIC = 31 - Implicit handle with custom binding routines
126 * (MIDL_STUB_DESC::IMPLICIT_HANDLE_INFO::pGenericBindingInfo)
127 * RPC_FC_BIND_PRIMITIVE = 32 - Implicit handle using handle_t created by
128 * calling application
129 * RPC_FC_AUTO_HANDLE = 33 - Automatic handle
130 * RPC_FC_CALLBACK_HANDLE = 34 - undocmented
132 unsigned char handle_type;
135 * Oi_FULL_PTR_USED = 0x01 - A full pointer can have the value NULL and can
136 * change during the call from NULL to non-NULL and supports aliasing
137 * and cycles. Indicates that the NdrFullPointerXlatInit function
139 * Oi_RPCSS_ALLOC_USED = 0x02 - Use RpcSS allocate/free routines instead of
140 * normal allocate/free routines
141 * Oi_OBJECT_PROC = 0x04 - Indicates a procedure that is part of an OLE
142 * interface, rather than a DCE RPC interface.
143 * Oi_HAS_RPCFLAGS = 0x08 - Indicates that the rpc_flags element is
144 * present in the header.
145 * Oi_HAS_COMM_OR_FAULT = 0x20 - If Oi_OBJECT_PROC not present only then
146 * indicates that the procedure has the comm_status or fault_status
148 * Oi_OBJ_USE_V2_INTERPRETER = 0x20 - If Oi_OBJECT_PROC present only
149 * then indicates that the format string is in -Oif or -Oicf format
150 * Oi_USE_NEW_INIT_ROUTINES = 0x40 - Use NdrXInitializeNew instead of
153 unsigned char Oi_flags;
155 /* the zero-based index of the procedure */
156 unsigned short proc_num;
158 /* total size of all parameters on the stack, including any "this"
159 * pointer and/or return value */
160 unsigned short stack_size;
163 /* same as above struct except additional element rpc_flags */
164 typedef struct _NDR_PROC_HEADER_RPC
166 unsigned char handle_type;
167 unsigned char Oi_flags;
170 * RPCF_Idempotent = 0x0001 - [idempotent] MIDL attribute
171 * RPCF_Broadcast = 0x0002 - [broadcast] MIDL attribute
172 * RPCF_Maybe = 0x0004 - [maybe] MIDL attribute
173 * Reserved = 0x0008 - 0x0080
174 * RPCF_Message = 0x0100 - [message] MIDL attribute
175 * Reserved = 0x0200 - 0x1000
176 * RPCF_InputSynchronous = 0x2000 - unknown
177 * RPCF_Asynchronous = 0x4000 - [async] MIDL attribute
180 unsigned long rpc_flags;
181 unsigned short proc_num;
182 unsigned short stack_size;
184 } NDR_PROC_HEADER_RPC;
186 typedef struct _NDR_PROC_PARTIAL_OIF_HEADER
188 /* the pre-computed client buffer size so that interpreter can skip all
189 * or some (if the flag RPC_FC_PROC_OI2F_CLTMUSTSIZE is specified) of the
191 unsigned short constant_client_buffer_size;
193 /* the pre-computed server buffer size so that interpreter can skip all
194 * or some (if the flag RPC_FC_PROC_OI2F_SRVMUSTSIZE is specified) of the
196 unsigned short constant_server_buffer_size;
199 * RPC_FC_PROC_OI2F_SRVMUSTSIZE = 0x01 - the server must perform a
201 * RPC_FC_PROC_OI2F_CLTMUSTSIZE = 0x02 - the client must perform a
203 * RPC_FC_PROC_OI2F_HASRETURN = 0x04 - procedure has a return value.
204 * RPC_FC_PROC_OI2F_HASPIPES = 0x08 - the pipe package should be used.
205 * RPC_FC_PROC_OI2F_HASASYNCUUID = 0x20 - indicates an asynchronous DCOM
207 * RPC_FC_PROC_OI2F_HASEXTS = 0x40 - indicates that Windows 2000
208 * extensions are in use.
209 * RPC_FC_PROC_OI2F_HASASYNCHND = 0x80 - indicates an asynchronous RPC
212 unsigned char Oif_flags;
214 /* number of params */
215 unsigned char number_of_params;
216 } NDR_PROC_PARTIAL_OIF_HEADER;
218 /* Windows 2000 extensions */
219 typedef struct _NDR_PROC_EXTENSION
221 /* size in bytes of all following extensions */
222 unsigned char extension_version;
225 * HasNewCorrDesc = 0x01 - indicates new correlation descriptors in use
226 * ClientCorrCheck = 0x02 - client needs correlation check
227 * ServerCorrCheck = 0x04 - server needs correlation check
228 * HasNotify = 0x08 - should call MIDL [notify] routine @ NotifyIndex
229 * HasNotify2 = 0x10 - should call MIDL [notify_flag] routine @
232 unsigned char ext_flags;
234 /* client cache size hint */
235 unsigned short ClientCorrHint;
237 /* server cache size hint */
238 unsigned short ServerCorrHint;
240 /* index of routine in MIDL_STUB_DESC::NotifyRoutineTable to call if
241 * HasNotify or HasNotify2 flag set */
242 unsigned short NotifyIndex;
243 } NDR_PROC_EXTENSION;
245 /* usually generated only on IA64 */
246 typedef struct _NDR_PROC_EXTENSION_64
248 NDR_PROC_EXTENSION ext;
250 /* needed only on IA64 to cope with float/register loading */
251 unsigned short FloatDoubleMask;
252 } NDR_PROC_EXTENSION_64;
255 typedef struct _NDR_PARAM_OI_BASETYPE
257 /* parameter direction. One of:
258 * FC_IN_PARAM_BASETYPE = 0x4e - an in param
259 * FC_RETURN_PARAM_BASETYPE = 0x53 - a return param
261 unsigned char param_direction;
263 /* One of: FC_BYTE,FC_CHAR,FC_SMALL,FC_USMALL,FC_WCHAR,FC_SHORT,FC_USHORT,
264 * FC_LONG,FC_ULONG,FC_FLOAT,FC_HYPER,FC_DOUBLE,FC_ENUM16,FC_ENUM32,
265 * FC_ERROR_STATUS_T,FC_INT3264,FC_UINT3264 */
266 unsigned char type_format_char;
267 } NDR_PARAM_OI_BASETYPE;
269 typedef struct _NDR_PARAM_OI_OTHER
272 * FC_IN_PARAM = 0x4d - An in param
273 * FC_IN_OUT_PARAM = 0x50 - An in/out param
274 * FC_OUT_PARAM = 0x51 - An out param
275 * FC_RETURN_PARAM = 0x52 - A return value
276 * FC_IN_PARAM_NO_FREE_INST = 0x4f - A param for which no freeing is done
278 unsigned char param_direction;
280 /* Size of param on stack in NUMBERS OF INTS */
281 unsigned char stack_size;
283 /* offset in the type format string table */
284 unsigned short type_offset;
285 } NDR_PARAM_OI_OTHER;
287 typedef struct _NDR_PARAM_OIF_BASETYPE
289 /* attributes of the parameter:
290 * RPC_FC_PROC_PF_MUSTSIZE = 0x0001 - client interpreter MUST size this
291 * parameter, other parameters may be skipped, using the value in
292 * NDR_PROC_PARTIAL_OIF_HEADER::constant_client_buffer_size instead.
293 * RPC_FC_PROC_PF_MUSTFREE = 0x0002 - server interpreter MUST size this
294 * parameter, other parameters may be skipped, using the value in
295 * NDR_PROC_PARTIAL_OIF_HEADER::constant_server_buffer_size instead.
296 * RPC_FC_PROC_PF_PIPE = 0x0004 - The parameter is a pipe handle. See
297 * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/rpc/rpc/pipes.asp
298 * for more information on pipes.
299 * RPC_FC_PROC_PF_IN = 0x0008 - The parameter is an input
300 * RPC_FC_PROC_PF_OUT = 0x0010 - The parameter is an output
301 * RPC_FC_PROC_PF_RETURN = 0x0020 - The parameter is to be returned
302 * RPC_FC_PROC_PF_BASETYPE = 0x0040 - The parameter is simple and has the
303 * format defined by NDR_PARAM_OIF_BASETYPE rather than by
304 * NDR_PARAM_OIF_OTHER.
305 * RPC_FC_PROC_PF_BYVAL = 0x0080 - Set for compound types being sent by
306 * value. Can be of type: structure, union, transmit_as, represent_as,
307 * wire_marshal and SAFEARRAY.
308 * RPC_FC_PROC_PF_SIMPLEREF = 0x0100 - parameter that is a reference
309 * pointer to anything other than another pointer, and which has no
310 * allocate attributes.
311 * RPC_FC_PROC_PF_DONTFREEINST = 0x0200 - Used for some represent_as types
312 * for when the free instance routine should not be called.
313 * RPC_FC_PROC_PF_SAVEASYNC = 0x0400 - unknown
314 * RPC_FC_PROC_PF_SRVALLOCSIZE = 0xe000 - bitmask, which if non-zero
315 * specifies the size of the object in numbers of 8byte blocks needed.
316 * It will be stored on the server's stack rather than using an allocate
319 unsigned short param_attributes;
321 /* the offset on the calling stack where the parameter is located */
322 unsigned short stack_offset;
324 /* see NDR_PARAM_OI_BASETYPE::type_format_char */
325 unsigned char type_format_char;
328 unsigned char unused;
329 } NDR_PARAM_OIF_BASETYPE;
331 typedef struct _NDR_PARAM_OIF_OTHER
333 /* see NDR_PARAM_OIF_BASETYPE::param_attributes */
334 unsigned short param_attributes;
336 /* see NDR_PARAM_OIF_BASETYPE::stack_offset */
337 unsigned short stack_offset;
339 /* offset into the provided type format string where the type for this
340 * parameter starts */
341 unsigned short type_offset;
342 } NDR_PARAM_OIF_OTHER;
344 /* explicit handle description for FC_BIND_PRIMITIVE type */
345 typedef struct _NDR_EHD_PRIMITIVE
347 /* FC_BIND_PRIMITIVE */
348 unsigned char handle_type;
350 /* is the handle passed in via a pointer? */
353 /* offset from the beginning of the stack to the handle in bytes */
354 unsigned short offset;
357 /* explicit handle description for FC_BIND_GENERIC type */
358 typedef struct _NDR_EHD_GENERIC
360 /* FC_BIND_GENERIC */
361 unsigned char handle_type;
363 /* upper 4bits is a flag indicating whether the handle is passed in
364 * via a pointer. lower 4bits is the size of the user defined generic
365 * handle type. the size must be less than or equal to the machine
367 unsigned char flag_and_size;
369 /* offset from the beginning of the stack to the handle in bytes */
370 unsigned short offset;
372 /* the index into the aGenericBindingRoutinesPairs field of MIDL_STUB_DESC
373 * giving the bind and unbind routines for the handle */
374 unsigned char binding_routine_pair_index;
377 unsigned char unused;
380 /* explicit handle description for FC_BIND_CONTEXT type */
381 typedef struct _NDR_EHD_CONTEXT
383 /* FC_BIND_CONTEXT */
384 unsigned char handle_type;
386 /* Any of the following flags:
387 * NDR_CONTEXT_HANDLE_CANNOT_BE_NULL = 0x01
388 * NDR_CONTEXT_HANDLE_SERIALIZE = 0x02
389 * NDR_CONTEXT_HANDLE_NO_SERIALIZE = 0x04
390 * NDR_STRICT_CONTEXT_HANDLE = 0x08
391 * HANDLE_PARAM_IS_OUT = 0x20
392 * HANDLE_PARAM_IS_RETURN = 0x21
393 * HANDLE_PARAM_IS_IN = 0x40
394 * HANDLE_PARAM_IS_VIA_PTR = 0x80
398 /* offset from the beginning of the stack to the handle in bytes */
399 unsigned short offset;
401 /* zero-based index on rundown routine in apfnNdrRundownRoutines field
402 * of MIDL_STUB_DESC */
403 unsigned char context_rundown_routine_index;
405 /* varies depending on NDR version used.
406 * V1: zero-based index into parameters
407 * V2: zero-based index into handles that are parameters */
408 unsigned char param_num;
413 void WINAPI NdrRpcSmSetClientToOsf(PMIDL_STUB_MESSAGE pMessage)
415 #if 0 /* these functions are not defined yet */
416 pMessage->pfnAllocate = NdrRpcSmClientAllocate;
417 pMessage->pfnFree = NdrRpcSmClientFree;
421 static void WINAPI dump_RPC_FC_PROC_PF(unsigned short param_attributes)
423 if (param_attributes & RPC_FC_PROC_PF_MUSTSIZE) TRACE(" RPC_FC_PROC_PF_MUSTSIZE");
424 if (param_attributes & RPC_FC_PROC_PF_MUSTFREE) TRACE(" RPC_FC_PROC_PF_MUSTFREE");
425 if (param_attributes & RPC_FC_PROC_PF_PIPE) TRACE(" RPC_FC_PROC_PF_PIPE");
426 if (param_attributes & RPC_FC_PROC_PF_IN) TRACE(" RPC_FC_PROC_PF_IN");
427 if (param_attributes & RPC_FC_PROC_PF_OUT) TRACE(" RPC_FC_PROC_PF_OUT");
428 if (param_attributes & RPC_FC_PROC_PF_RETURN) TRACE(" RPC_FC_PROC_PF_RETURN");
429 if (param_attributes & RPC_FC_PROC_PF_BASETYPE) TRACE(" RPC_FC_PROC_PF_BASETYPE");
430 if (param_attributes & RPC_FC_PROC_PF_BYVAL) TRACE(" RPC_FC_PROC_PF_BYVAL");
431 if (param_attributes & RPC_FC_PROC_PF_SIMPLEREF) TRACE(" RPC_FC_PROC_PF_SIMPLEREF");
432 if (param_attributes & RPC_FC_PROC_PF_DONTFREEINST) TRACE(" RPC_FC_PROC_PF_DONTFREEINST");
433 if (param_attributes & RPC_FC_PROC_PF_SAVEASYNC) TRACE(" RPC_FC_PROC_PF_SAVEASYNC");
434 if (param_attributes & RPC_FC_PROC_PF_SRVALLOCSIZE) TRACE(" RPC_FC_PROC_PF_SRVALLOCSIZE");
437 /* FIXME: this will be different on other plaftorms than i386 */
438 #define ARG_FROM_OFFSET(args, offset) (*(unsigned char **)args + offset)
440 /* the return type should be CLIENT_CALL_RETURN, but this is incompatible
441 * with the way gcc returns structures. "void *" should be the largest type
442 * that MIDL should allow you to return anyway */
443 LONG_PTR WINAPIV NdrClientCall2(PMIDL_STUB_DESC pStubDesc, PFORMAT_STRING pFormat, ...)
445 /* pointer to start of stack where arguments start */
446 /* FIXME: not portable */
447 unsigned char *args = (unsigned char *)(&pFormat+1);
449 MIDL_STUB_MESSAGE stubMsg;
450 handle_t hBinding = NULL;
451 /* procedure number */
452 unsigned short procedure_number;
454 unsigned short stack_size;
455 /* current stack offset */
456 unsigned short current_stack_offset;
457 /* number of parameters. optional for client to give it to us */
458 unsigned char number_of_params = ~0;
461 /* cache of Oif_flags from v2 procedure header */
462 unsigned char Oif_flags = 0;
463 /* cache of extension flags from NDR_PROC_EXTENSION */
464 unsigned char ext_flags = 0;
465 /* the type of pass we are currently doing */
467 /* header for procedure string */
468 const NDR_PROC_HEADER * pProcHeader = (const NDR_PROC_HEADER *)&pFormat[0];
469 /* offset in format string for start of params */
470 int parameter_start_offset;
471 /* current format string offset */
473 /* -Oif or -Oicf generated format */
474 BOOL bV2Format = FALSE;
475 /* the value to return to the client from the remote procedure */
477 /* the pointer to the object when in OLE mode */
480 TRACE("pStubDesc %p, pFormat %p, ...\n", pStubDesc, pFormat);
481 TRACE("&first_argument = %p -> %p\n", args, ARG_FROM_OFFSET(args, 0));
483 /* Later NDR language versions probably won't be backwards compatible */
484 if (pStubDesc->Version > 0x50002)
486 FIXME("Incompatible stub description version: 0x%lx\n", pStubDesc->Version);
487 RpcRaiseException(RPC_X_WRONG_STUB_VERSION);
490 if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCFLAGS)
492 NDR_PROC_HEADER_RPC * pProcHeader = (NDR_PROC_HEADER_RPC *)&pFormat[0];
493 stack_size = pProcHeader->stack_size;
494 procedure_number = pProcHeader->proc_num;
495 current_offset = sizeof(NDR_PROC_HEADER_RPC);
499 stack_size = pProcHeader->stack_size;
500 procedure_number = pProcHeader->proc_num;
501 TRACE("proc num: %d\n", procedure_number);
502 current_offset = sizeof(NDR_PROC_HEADER);
505 TRACE("Oi_flags = 0x%02x\n", pProcHeader->Oi_flags);
506 TRACE("MIDL stub version = 0x%lx\n", pStubDesc->MIDLVersion);
508 /* we only need a handle if this isn't an object method */
509 if (!(pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT))
512 switch (pProcHeader->handle_type)
514 /* explicit binding: parse additional section */
515 case RPC_FC_BIND_EXPLICIT:
516 switch (pFormat[current_offset]) /* handle_type */
518 case RPC_FC_BIND_PRIMITIVE: /* explicit primitive */
520 NDR_EHD_PRIMITIVE * pDesc = (NDR_EHD_PRIMITIVE *)&pFormat[current_offset];
522 TRACE("Explicit primitive handle @ %d\n", pDesc->offset);
524 if (pDesc->flag) /* pointer to binding */
525 hBinding = **(handle_t **)ARG_FROM_OFFSET(args, pDesc->offset);
527 hBinding = *(handle_t *)ARG_FROM_OFFSET(args, pDesc->offset);
528 current_offset += sizeof(NDR_EHD_PRIMITIVE);
531 case RPC_FC_BIND_GENERIC: /* explicit generic */
532 FIXME("RPC_FC_BIND_GENERIC\n");
533 RpcRaiseException(RPC_X_WRONG_STUB_VERSION); /* FIXME: remove when implemented */
534 current_offset += sizeof(NDR_EHD_GENERIC);
536 case RPC_FC_BIND_CONTEXT: /* explicit context */
538 NDR_EHD_CONTEXT * pDesc = (NDR_EHD_CONTEXT *)&pFormat[current_offset];
539 TRACE("Explicit bind context\n");
540 hBinding = NDRCContextBinding(*(NDR_CCONTEXT *)ARG_FROM_OFFSET(args, pDesc->offset));
541 /* FIXME: should we store this structure in stubMsg.pContext? */
542 current_offset += sizeof(NDR_EHD_CONTEXT);
546 ERR("bad explicit binding handle type (0x%02x)\n", pProcHeader->handle_type);
547 RpcRaiseException(RPC_X_BAD_STUB_DATA);
550 case RPC_FC_BIND_GENERIC: /* implicit generic */
551 FIXME("RPC_FC_BIND_GENERIC\n");
552 RpcRaiseException(RPC_X_BAD_STUB_DATA); /* FIXME: remove when implemented */
554 case RPC_FC_BIND_PRIMITIVE: /* implicit primitive */
555 TRACE("Implicit primitive handle\n");
556 hBinding = *pStubDesc->IMPLICIT_HANDLE_INFO.pPrimitiveHandle;
558 case RPC_FC_CALLBACK_HANDLE: /* implicit callback */
559 FIXME("RPC_FC_CALLBACK_HANDLE\n");
561 case RPC_FC_AUTO_HANDLE: /* implicit auto handle */
562 /* strictly speaking, it isn't necessary to set hBinding here
563 * since it isn't actually used (hence the automatic in its name),
564 * but then why does MIDL generate a valid entry in the
565 * MIDL_STUB_DESC for it? */
566 TRACE("Implicit auto handle\n");
567 hBinding = *pStubDesc->IMPLICIT_HANDLE_INFO.pAutoHandle;
570 ERR("bad implicit binding handle type (0x%02x)\n", pProcHeader->handle_type);
571 RpcRaiseException(RPC_X_BAD_STUB_DATA);
575 bV2Format = (pStubDesc->Version >= 0x20000);
579 NDR_PROC_PARTIAL_OIF_HEADER * pOIFHeader =
580 (NDR_PROC_PARTIAL_OIF_HEADER*)&pFormat[current_offset];
582 Oif_flags = pOIFHeader->Oif_flags;
583 number_of_params = pOIFHeader->number_of_params;
585 current_offset += sizeof(NDR_PROC_PARTIAL_OIF_HEADER);
588 TRACE("Oif_flags = 0x%02x\n", Oif_flags);
590 if (Oif_flags & RPC_FC_PROC_OI2F_HASEXTS)
592 NDR_PROC_EXTENSION * pExtensions =
593 (NDR_PROC_EXTENSION *)&pFormat[current_offset];
594 ext_flags = pExtensions->ext_flags;
595 current_offset += pExtensions->extension_version;
598 if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT)
600 /* object is always the first argument */
601 This = *(void **)ARG_FROM_OFFSET(args, 0);
602 NdrProxyInitialize(This, &rpcMsg, &stubMsg, pStubDesc, procedure_number);
605 NdrClientInitializeNew(&rpcMsg, &stubMsg, pStubDesc, procedure_number);
607 /* create the full pointer translation tables, if requested */
608 if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_FULLPTR)
610 stubMsg.FullPtrXlatTables = NdrFullPointerXlatInit(0,XLAT_CLIENT);
612 FIXME("initialize full pointer translation tables\n");
615 stubMsg.BufferLength = 0;
617 /* store the RPC flags away */
618 if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCFLAGS)
619 rpcMsg.RpcFlags = ((NDR_PROC_HEADER_RPC *)pProcHeader)->rpc_flags;
621 /* use alternate memory allocation routines */
622 if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCSSALLOC)
623 NdrRpcSmSetClientToOsf(&stubMsg);
625 if (Oif_flags & RPC_FC_PROC_OI2F_HASPIPES)
627 FIXME("pipes not supported yet\n");
628 RpcRaiseException(RPC_X_WRONG_STUB_VERSION); /* FIXME: remove when implemented */
629 /* init pipes package */
630 /* NdrPipesInitialize(...) */
632 if (ext_flags & RPC_FC_PROC_EXT_NEWCORRDESC)
634 /* initialize extra correlation package */
635 FIXME("new correlation description not implemented\n");
636 stubMsg.fHasNewCorrDesc = TRUE;
639 parameter_start_offset = current_offset;
642 * 1. PROXY_CALCSIZE - calculate the buffer size
643 * 2. PROXY_GETBUFFER - allocate the buffer
644 * 3. PROXY_MARHSAL - marshal [in] params into the buffer
645 * 4. PROXY_SENDRECEIVE - send/receive buffer
646 * 5. PROXY_UNMARHSAL - unmarshal [out] params from buffer
648 for (phase = PROXY_CALCSIZE; phase <= PROXY_UNMARSHAL; phase++)
650 TRACE("phase = %d\n", phase);
653 case PROXY_GETBUFFER:
654 /* allocate the buffer */
655 if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT)
656 NdrProxyGetBuffer(This, &stubMsg);
657 else if (Oif_flags & RPC_FC_PROC_OI2F_HASPIPES)
658 /* NdrGetPipeBuffer(...) */
659 FIXME("pipes not supported yet\n");
662 if (pProcHeader->handle_type == RPC_FC_AUTO_HANDLE)
664 NdrNsGetBuffer(&stubMsg, stubMsg.BufferLength, hBinding);
666 FIXME("using auto handle - call NdrNsGetBuffer when it gets implemented\n");
669 NdrGetBuffer(&stubMsg, stubMsg.BufferLength, hBinding);
672 case PROXY_SENDRECEIVE:
673 /* send the [in] params and receive the [out] and [retval]
675 if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT)
676 NdrProxySendReceive(This, &stubMsg);
677 else if (Oif_flags & RPC_FC_PROC_OI2F_HASPIPES)
678 /* NdrPipesSendReceive(...) */
679 FIXME("pipes not supported yet\n");
682 if (pProcHeader->handle_type == RPC_FC_AUTO_HANDLE)
684 NdrNsSendReceive(&stubMsg, stubMsg.Buffer, pStubDesc->IMPLICIT_HANDLE_INFO.pAutoHandle);
686 FIXME("using auto handle - call NdrNsSendReceive when it gets implemented\n");
689 NdrSendReceive(&stubMsg, stubMsg.Buffer);
692 /* convert strings, floating point values and endianess into our
693 * preferred format */
694 if ((rpcMsg.DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION)
695 NdrConvert(&stubMsg, pFormat);
700 case PROXY_UNMARSHAL:
701 current_offset = parameter_start_offset;
702 current_stack_offset = 0;
704 /* NOTE: V1 style format does't terminate on the number_of_params
705 * condition as it doesn't have this attribute. Instead it
706 * terminates when the stack size given in the header is exceeded.
708 for (i = 0; i < number_of_params; i++)
710 if (bV2Format) /* new parameter format */
712 NDR_PARAM_OIF_BASETYPE * pParam =
713 (NDR_PARAM_OIF_BASETYPE *)&pFormat[current_offset];
714 unsigned char * pArg;
716 current_stack_offset = pParam->stack_offset;
717 pArg = ARG_FROM_OFFSET(args, current_stack_offset);
719 TRACE("param[%d]: new format\n", i);
720 TRACE("\tparam_attributes:"); dump_RPC_FC_PROC_PF(pParam->param_attributes); TRACE("\n");
721 TRACE("\tstack_offset: 0x%x\n", current_stack_offset);
722 TRACE("\tmemory addr (before): %p\n", pArg);
724 if (pParam->param_attributes & RPC_FC_PROC_PF_BASETYPE)
726 const unsigned char * pTypeFormat =
727 &pParam->type_format_char;
729 if (pParam->param_attributes & RPC_FC_PROC_PF_SIMPLEREF)
730 pArg = *(unsigned char **)pArg;
732 TRACE("\tbase type: 0x%02x\n", *pTypeFormat);
737 if (pParam->param_attributes & RPC_FC_PROC_PF_IN)
738 call_buffer_sizer(&stubMsg, pArg, pTypeFormat);
741 if (pParam->param_attributes & RPC_FC_PROC_PF_IN)
742 call_marshaller(&stubMsg, pArg, pTypeFormat);
744 case PROXY_UNMARSHAL:
745 if (pParam->param_attributes & RPC_FC_PROC_PF_OUT)
747 unsigned char *pRetVal = (unsigned char *)&RetVal;
748 if (pParam->param_attributes & RPC_FC_PROC_PF_RETURN)
749 call_unmarshaller(&stubMsg, &pRetVal, pTypeFormat, 0);
751 call_unmarshaller(&stubMsg, &pArg, pTypeFormat, 0);
752 TRACE("pRetVal = %p\n", pRetVal);
756 RpcRaiseException(RPC_S_INTERNAL_ERROR);
759 current_offset += sizeof(NDR_PARAM_OIF_BASETYPE);
763 NDR_PARAM_OIF_OTHER * pParamOther =
764 (NDR_PARAM_OIF_OTHER *)&pFormat[current_offset];
766 const unsigned char * pTypeFormat =
767 &(pStubDesc->pFormatTypes[pParamOther->type_offset]);
769 /* if a simple ref pointer then we have to do the
770 * check for the pointer being non-NULL. */
771 if (pParam->param_attributes & RPC_FC_PROC_PF_SIMPLEREF)
773 if (!*(unsigned char **)pArg)
774 RpcRaiseException(RPC_X_NULL_REF_POINTER);
777 TRACE("\tcomplex type: 0x%02x\n", *pTypeFormat);
782 if (pParam->param_attributes & RPC_FC_PROC_PF_IN)
783 call_buffer_sizer(&stubMsg, *(unsigned char **)pArg, pTypeFormat);
786 if (pParam->param_attributes & RPC_FC_PROC_PF_IN)
787 call_marshaller(&stubMsg, *(unsigned char **)pArg, pTypeFormat);
789 case PROXY_UNMARSHAL:
790 if (pParam->param_attributes & RPC_FC_PROC_PF_OUT)
792 unsigned char *pRetVal = (unsigned char *)&RetVal;
793 if (pParam->param_attributes & RPC_FC_PROC_PF_RETURN)
794 call_unmarshaller(&stubMsg, &pRetVal, pTypeFormat, 0);
796 call_unmarshaller(&stubMsg, (unsigned char **)pArg, pTypeFormat, 0);
800 RpcRaiseException(RPC_S_INTERNAL_ERROR);
803 current_offset += sizeof(NDR_PARAM_OIF_OTHER);
805 TRACE("\tmemory addr (after): %p\n", pArg);
807 else /* old parameter format */
809 NDR_PARAM_OI_BASETYPE * pParam =
810 (NDR_PARAM_OI_BASETYPE *)&pFormat[current_offset];
811 unsigned char * pArg = ARG_FROM_OFFSET(args, current_stack_offset);
813 /* no more parameters; exit loop */
814 if (current_stack_offset > stack_size)
817 TRACE("param[%d]: old format\n", i);
818 TRACE("\tparam_direction: %x\n", pParam->param_direction);
819 TRACE("\tstack_offset: 0x%x\n", current_stack_offset);
820 TRACE("\tmemory addr (before): %p\n", pArg);
822 if (pParam->param_direction == RPC_FC_IN_PARAM_BASETYPE ||
823 pParam->param_direction == RPC_FC_RETURN_PARAM_BASETYPE)
825 const unsigned char * pTypeFormat =
826 &pParam->type_format_char;
828 TRACE("\tbase type 0x%02x\n", *pTypeFormat);
833 if (pParam->param_direction == RPC_FC_IN_PARAM_BASETYPE)
834 call_buffer_sizer(&stubMsg, pArg, pTypeFormat);
837 if (pParam->param_direction == RPC_FC_IN_PARAM_BASETYPE)
838 call_marshaller(&stubMsg, pArg, pTypeFormat);
840 case PROXY_UNMARSHAL:
841 if (pParam->param_direction == RPC_FC_RETURN_PARAM_BASETYPE)
843 if (pParam->param_direction & RPC_FC_RETURN_PARAM)
844 call_unmarshaller(&stubMsg, (unsigned char **)&RetVal, pTypeFormat, 0);
846 call_unmarshaller(&stubMsg, &pArg, pTypeFormat, 0);
850 RpcRaiseException(RPC_S_INTERNAL_ERROR);
853 current_stack_offset += call_memory_sizer(&stubMsg, pTypeFormat);
854 current_offset += sizeof(NDR_PARAM_OI_BASETYPE);
858 NDR_PARAM_OI_OTHER * pParamOther =
859 (NDR_PARAM_OI_OTHER *)&pFormat[current_offset];
861 const unsigned char *pTypeFormat =
862 &pStubDesc->pFormatTypes[pParamOther->type_offset];
864 TRACE("\tcomplex type 0x%02x\n", *pTypeFormat);
869 if (pParam->param_direction == RPC_FC_IN_PARAM ||
870 pParam->param_direction & RPC_FC_IN_OUT_PARAM)
871 call_buffer_sizer(&stubMsg, pArg, pTypeFormat);
874 if (pParam->param_direction == RPC_FC_IN_PARAM ||
875 pParam->param_direction & RPC_FC_IN_OUT_PARAM)
876 call_marshaller(&stubMsg, pArg, pTypeFormat);
878 case PROXY_UNMARSHAL:
879 if (pParam->param_direction == RPC_FC_IN_OUT_PARAM ||
880 pParam->param_direction == RPC_FC_OUT_PARAM)
881 call_unmarshaller(&stubMsg, &pArg, pTypeFormat, 0);
882 else if (pParam->param_direction == RPC_FC_RETURN_PARAM)
883 call_unmarshaller(&stubMsg, (unsigned char **)&RetVal, pTypeFormat, 0);
886 RpcRaiseException(RPC_S_INTERNAL_ERROR);
889 current_stack_offset += pParamOther->stack_size * sizeof(INT);
890 current_offset += sizeof(NDR_PARAM_OI_OTHER);
892 TRACE("\tmemory addr (after): %p\n", pArg);
898 ERR("shouldn't reach here. phase %d\n", phase);
903 /* FIXME: unbind the binding handle */
905 if (ext_flags & RPC_FC_PROC_EXT_NEWCORRDESC)
907 /* free extra correlation package */
908 /* NdrCorrelationFree(&stubMsg); */
911 if (Oif_flags & RPC_FC_PROC_OI2F_HASPIPES)
913 /* NdrPipesDone(...) */
917 /* free the full pointer translation tables */
918 if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_FULLPTR)
919 NdrFullPointerXlatFree(stubMsg.FullPtrXlatTables);
922 /* free marshalling buffer */
923 if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT)
924 NdrProxyFreeBuffer(This, &stubMsg);
926 NdrFreeBuffer(&stubMsg);
928 TRACE("RetVal = 0x%lx\n", RetVal);
933 /* calls a function with the specificed arguments, restoring the stack
934 * properly afterwards as we don't know the calling convention of the
936 #if defined __i386__ && defined _MSC_VER
937 __declspec(naked) LONG_PTR __cdecl call_server_func(SERVER_ROUTINE func, unsigned char * args, unsigned int stack_size)
942 push edi ; Save registers
945 mov eax, [ebp+16] ; Get stack size
946 sub esp, eax ; Make room in stack for arguments
952 rep movsd ; Copy dword blocks
953 call [ebp+8] ; Call function
954 lea esp, [ebp-8] ; Restore stack
955 pop ebp ; Restore registers
961 #elif defined __i386__ && defined __GNUC__
962 LONG_PTR __cdecl call_server_func(SERVER_ROUTINE func, unsigned char * args, unsigned int stack_size);
963 __ASM_GLOBAL_FUNC(call_server_func,
965 "movl %esp, %ebp\n\t"
966 "pushl %edi\n\t" /* Save registers */
968 "movl 16(%ebp), %eax\n\t" /* Get stack size */
969 "subl %eax, %esp\n\t" /* Make room in stack for arguments */
970 "andl $~15, %esp\n\t" /* Make sure stack has 16-byte alignment for MacOS X */
971 "movl %esp, %edi\n\t"
972 "movl %eax, %ecx\n\t"
973 "movl 12(%ebp), %esi\n\t"
974 "shrl $2, %ecx\n\t" /* divide by 4 */
976 "rep; movsl\n\t" /* Copy dword blocks */
977 "call *8(%ebp)\n\t" /* Call function */
978 "leal -8(%ebp), %esp\n\t" /* Restore stack */
979 "popl %esi\n\t" /* Restore registers */
984 #warning call_server_func not implemented for your architecture
985 LONG_PTR __cdecl call_server_func(SERVER_ROUTINE func, unsigned char * args, unsigned short stack_size)
987 FIXME("Not implemented for your architecture\n");
992 /* FIXME: need to free some stuff in here too */
993 long WINAPI NdrStubCall2(
994 struct IRpcStubBuffer * pThis,
995 struct IRpcChannelBuffer * pChannel,
996 PRPC_MESSAGE pRpcMsg,
997 unsigned long * pdwStubPhase)
999 const MIDL_SERVER_INFO *pServerInfo;
1000 const MIDL_STUB_DESC *pStubDesc;
1001 PFORMAT_STRING pFormat;
1002 MIDL_STUB_MESSAGE stubMsg;
1003 /* pointer to start of stack to pass into stub implementation */
1004 unsigned char * args;
1006 unsigned short stack_size;
1007 /* current stack offset */
1008 unsigned short current_stack_offset;
1009 /* number of parameters. optional for client to give it to us */
1010 unsigned char number_of_params = ~0;
1013 /* cache of Oif_flags from v2 procedure header */
1014 unsigned char Oif_flags = 0;
1015 /* cache of extension flags from NDR_PROC_EXTENSION */
1016 unsigned char ext_flags = 0;
1017 /* the type of pass we are currently doing */
1019 /* header for procedure string */
1020 const NDR_PROC_HEADER *pProcHeader;
1021 /* offset in format string for start of params */
1022 int parameter_start_offset;
1023 /* current format string offset */
1025 /* -Oif or -Oicf generated format */
1026 BOOL bV2Format = FALSE;
1027 /* the return value (not from this function, but to be put back onto
1029 LONG_PTR RetVal = 0;
1031 TRACE("pThis %p, pChannel %p, pRpcMsg %p, pdwStubPhase %p\n", pThis, pChannel, pRpcMsg, pdwStubPhase);
1034 pServerInfo = CStdStubBuffer_GetServerInfo(pThis);
1036 pServerInfo = ((RPC_SERVER_INTERFACE *)pRpcMsg->RpcInterfaceInformation)->InterpreterInfo;
1038 pStubDesc = pServerInfo->pStubDesc;
1039 pFormat = pServerInfo->ProcString + pServerInfo->FmtStringOffset[pRpcMsg->ProcNum];
1040 pProcHeader = (const NDR_PROC_HEADER *)&pFormat[0];
1042 /* Later NDR language versions probably won't be backwards compatible */
1043 if (pStubDesc->Version > 0x50002)
1045 FIXME("Incompatible stub description version: 0x%lx\n", pStubDesc->Version);
1046 RpcRaiseException(RPC_X_WRONG_STUB_VERSION);
1049 if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCFLAGS)
1051 NDR_PROC_HEADER_RPC * pProcHeader = (NDR_PROC_HEADER_RPC *)&pFormat[0];
1052 stack_size = pProcHeader->stack_size;
1053 current_offset = sizeof(NDR_PROC_HEADER_RPC);
1058 stack_size = pProcHeader->stack_size;
1059 current_offset = sizeof(NDR_PROC_HEADER);
1062 TRACE("Oi_flags = 0x%02x\n", pProcHeader->Oi_flags);
1065 switch (pProcHeader->handle_type)
1067 /* explicit binding: parse additional section */
1068 case RPC_FC_BIND_EXPLICIT:
1069 switch (pFormat[current_offset]) /* handle_type */
1071 case RPC_FC_BIND_PRIMITIVE: /* explicit primitive */
1072 current_offset += sizeof(NDR_EHD_PRIMITIVE);
1074 case RPC_FC_BIND_GENERIC: /* explicit generic */
1075 current_offset += sizeof(NDR_EHD_GENERIC);
1077 case RPC_FC_BIND_CONTEXT: /* explicit context */
1078 current_offset += sizeof(NDR_EHD_CONTEXT);
1081 ERR("bad explicit binding handle type (0x%02x)\n", pProcHeader->handle_type);
1082 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1085 case RPC_FC_BIND_GENERIC: /* implicit generic */
1086 case RPC_FC_BIND_PRIMITIVE: /* implicit primitive */
1087 case RPC_FC_CALLBACK_HANDLE: /* implicit callback */
1088 case RPC_FC_AUTO_HANDLE: /* implicit auto handle */
1091 ERR("bad implicit binding handle type (0x%02x)\n", pProcHeader->handle_type);
1092 RpcRaiseException(RPC_X_BAD_STUB_DATA);
1095 bV2Format = (pStubDesc->Version >= 0x20000);
1099 NDR_PROC_PARTIAL_OIF_HEADER * pOIFHeader =
1100 (NDR_PROC_PARTIAL_OIF_HEADER*)&pFormat[current_offset];
1102 Oif_flags = pOIFHeader->Oif_flags;
1103 number_of_params = pOIFHeader->number_of_params;
1105 current_offset += sizeof(NDR_PROC_PARTIAL_OIF_HEADER);
1108 TRACE("Oif_flags = 0x%02x\n", Oif_flags);
1110 if (Oif_flags & RPC_FC_PROC_OI2F_HASEXTS)
1112 NDR_PROC_EXTENSION * pExtensions =
1113 (NDR_PROC_EXTENSION *)&pFormat[current_offset];
1114 ext_flags = pExtensions->ext_flags;
1115 current_offset += pExtensions->extension_version;
1118 if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT)
1119 NdrStubInitialize(pRpcMsg, &stubMsg, pStubDesc, pChannel);
1121 NdrServerInitializeNew(pRpcMsg, &stubMsg, pStubDesc);
1123 /* create the full pointer translation tables, if requested */
1124 if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_FULLPTR)
1126 stubMsg.FullPtrXlatTables = NdrFullPointerXlatInit(0,XLAT_SERVER);
1128 FIXME("initialize full pointer translation tables\n");
1131 /* store the RPC flags away */
1132 if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCFLAGS)
1133 pRpcMsg->RpcFlags = ((NDR_PROC_HEADER_RPC *)pProcHeader)->rpc_flags;
1135 /* use alternate memory allocation routines */
1136 if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCSSALLOC)
1138 NdrRpcSsEnableAllocate(&stubMsg);
1140 FIXME("Set RPCSS memory allocation routines\n");
1143 if (Oif_flags & RPC_FC_PROC_OI2F_HASPIPES)
1145 FIXME("pipes not supported yet\n");
1146 RpcRaiseException(RPC_X_WRONG_STUB_VERSION); /* FIXME: remove when implemented */
1147 /* init pipes package */
1148 /* NdrPipesInitialize(...) */
1150 if (ext_flags & RPC_FC_PROC_EXT_NEWCORRDESC)
1152 /* initialize extra correlation package */
1153 FIXME("new correlation description not implemented\n");
1154 stubMsg.fHasNewCorrDesc = TRUE;
1158 /* convert strings, floating point values and endianess into our
1159 * preferred format */
1160 if ((pRpcMsg->DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION)
1161 NdrConvert(&stubMsg, pFormat);
1163 parameter_start_offset = current_offset;
1165 TRACE("allocating memory for stack of size %x\n", stack_size);
1167 args = HeapAlloc(GetProcessHeap(), 0, stack_size);
1168 ZeroMemory(args, stack_size);
1170 /* add the implicit This pointer as the first arg to the function if we
1171 * are calling an object method */
1173 *(void **)args = ((CStdStubBuffer *)pThis)->pvServerObject;
1176 * 1. STUBLESS_UNMARHSAL - unmarshal [in] params from buffer
1177 * 2. STUBLESS_CALLSERVER - send/receive buffer
1178 * 3. STUBLESS_CALCSIZE - get [out] buffer size
1179 * 4. STUBLESS_GETBUFFER - allocate [out] buffer
1180 * 5. STUBLESS_MARHSAL - marshal [out] params to buffer
1182 for (phase = STUBLESS_UNMARSHAL; phase <= STUBLESS_MARSHAL; phase++)
1184 TRACE("phase = %d\n", phase);
1187 case STUBLESS_CALLSERVER:
1188 /* call the server function */
1189 if (pServerInfo->ThunkTable)
1191 stubMsg.StackTop = args;
1192 pServerInfo->ThunkTable[pRpcMsg->ProcNum](&stubMsg);
1193 /* FIXME: RetVal is stored as the last argument - retrieve it */
1196 RetVal = call_server_func(pServerInfo->DispatchTable[pRpcMsg->ProcNum], args, stack_size);
1198 TRACE("stub implementation returned %p\n", (void *)RetVal);
1200 stubMsg.Buffer = NULL;
1201 stubMsg.BufferLength = 0;
1204 case STUBLESS_GETBUFFER:
1205 if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT)
1206 NdrStubGetBuffer(pThis, pChannel, &stubMsg);
1211 pRpcMsg->BufferLength = stubMsg.BufferLength;
1212 /* allocate buffer for [out] and [ret] params */
1213 Status = I_RpcGetBuffer(pRpcMsg);
1215 RpcRaiseException(Status);
1216 stubMsg.BufferStart = pRpcMsg->Buffer;
1217 stubMsg.BufferEnd = stubMsg.BufferStart + stubMsg.BufferLength;
1218 stubMsg.Buffer = stubMsg.BufferStart;
1221 case STUBLESS_MARSHAL:
1222 case STUBLESS_UNMARSHAL:
1223 case STUBLESS_CALCSIZE:
1224 current_offset = parameter_start_offset;
1225 current_stack_offset = 0;
1227 /* NOTE: V1 style format does't terminate on the number_of_params
1228 * condition as it doesn't have this attribute. Instead it
1229 * terminates when the stack size given in the header is exceeded.
1231 for (i = 0; i < number_of_params; i++)
1233 if (bV2Format) /* new parameter format */
1235 const NDR_PARAM_OIF_BASETYPE *pParam =
1236 (NDR_PARAM_OIF_BASETYPE *)&pFormat[current_offset];
1237 unsigned char *pArg;
1239 current_stack_offset = pParam->stack_offset;
1240 pArg = (unsigned char *)(args+current_stack_offset);
1242 TRACE("param[%d]: new format\n", i);
1243 TRACE("\tparam_attributes:"); dump_RPC_FC_PROC_PF(pParam->param_attributes); TRACE("\n");
1244 TRACE("\tstack_offset: %x\n", current_stack_offset);
1245 TRACE("\tmemory addr (before): %p -> %p\n", pArg, *(unsigned char **)pArg);
1247 if (pParam->param_attributes & RPC_FC_PROC_PF_SRVALLOCSIZE)
1248 FIXME("RPC_FC_PROC_PF_SRVALLOCSIZE ignored for parameter %d\n", i);
1250 if (pParam->param_attributes & RPC_FC_PROC_PF_BASETYPE)
1252 const unsigned char *pTypeFormat =
1253 &pParam->type_format_char;
1255 TRACE("\tbase type: 0x%02x\n", *pTypeFormat);
1259 case STUBLESS_MARSHAL:
1260 if (pParam->param_attributes & RPC_FC_PROC_PF_RETURN)
1261 call_marshaller(&stubMsg, (unsigned char *)&RetVal, pTypeFormat);
1262 else if (pParam->param_attributes & RPC_FC_PROC_PF_OUT)
1264 if (pParam->param_attributes & RPC_FC_PROC_PF_SIMPLEREF)
1265 call_marshaller(&stubMsg, *(unsigned char **)pArg, pTypeFormat);
1267 call_marshaller(&stubMsg, pArg, pTypeFormat);
1269 /* FIXME: call call_freer here */
1271 case STUBLESS_UNMARSHAL:
1272 if (pParam->param_attributes & RPC_FC_PROC_PF_IN)
1274 if (pParam->param_attributes & RPC_FC_PROC_PF_SIMPLEREF)
1275 call_unmarshaller(&stubMsg, (unsigned char **)pArg, pTypeFormat, 0);
1277 call_unmarshaller(&stubMsg, &pArg, pTypeFormat, 0);
1280 case STUBLESS_CALCSIZE:
1281 if (pParam->param_attributes & RPC_FC_PROC_PF_RETURN)
1282 call_buffer_sizer(&stubMsg, (unsigned char *)&RetVal, pTypeFormat);
1283 else if (pParam->param_attributes & RPC_FC_PROC_PF_OUT)
1285 if (pParam->param_attributes & RPC_FC_PROC_PF_SIMPLEREF)
1286 call_buffer_sizer(&stubMsg, *(unsigned char **)pArg, pTypeFormat);
1288 call_buffer_sizer(&stubMsg, pArg, pTypeFormat);
1292 RpcRaiseException(RPC_S_INTERNAL_ERROR);
1295 current_offset += sizeof(NDR_PARAM_OIF_BASETYPE);
1299 NDR_PARAM_OIF_OTHER * pParamOther =
1300 (NDR_PARAM_OIF_OTHER *)&pFormat[current_offset];
1302 const unsigned char * pTypeFormat =
1303 &(pStubDesc->pFormatTypes[pParamOther->type_offset]);
1305 TRACE("\tcomplex type 0x%02x\n", *pTypeFormat);
1309 case STUBLESS_MARSHAL:
1310 if (pParam->param_attributes & RPC_FC_PROC_PF_RETURN)
1311 call_marshaller(&stubMsg, (unsigned char *)&RetVal, pTypeFormat);
1312 else if (pParam->param_attributes & RPC_FC_PROC_PF_OUT)
1314 /* we have to dereference the pointer again for complex types */
1315 call_marshaller(&stubMsg, *(unsigned char **)pArg, pTypeFormat);
1316 stubMsg.pfnFree(*(void **)pArg);
1318 /* FIXME: call call_freer here */
1320 case STUBLESS_UNMARSHAL:
1321 if (pParam->param_attributes & RPC_FC_PROC_PF_IN)
1322 call_unmarshaller(&stubMsg, (unsigned char **)pArg, pTypeFormat, 0);
1323 else if (pParam->param_attributes & RPC_FC_PROC_PF_OUT)
1325 *(void **)pArg = NdrAllocate(&stubMsg, sizeof(void *));
1326 **(void ***)pArg = 0;
1329 case STUBLESS_CALCSIZE:
1330 if (pParam->param_attributes & RPC_FC_PROC_PF_RETURN)
1331 call_buffer_sizer(&stubMsg, (unsigned char *)&RetVal, pTypeFormat);
1332 else if (pParam->param_attributes & RPC_FC_PROC_PF_OUT)
1333 /* we have to dereference the pointer again for complex types */
1334 call_buffer_sizer(&stubMsg, *(unsigned char **)pArg, pTypeFormat);
1337 RpcRaiseException(RPC_S_INTERNAL_ERROR);
1340 current_offset += sizeof(NDR_PARAM_OIF_OTHER);
1342 TRACE("\tmemory addr (after): %p -> %p\n", pArg, *(unsigned char **)pArg);
1344 else /* old parameter format */
1346 NDR_PARAM_OI_BASETYPE *pParam =
1347 (NDR_PARAM_OI_BASETYPE *)&pFormat[current_offset];
1348 unsigned char *pArg = (unsigned char *)(args+current_stack_offset);
1350 /* no more parameters; exit loop */
1351 if (current_stack_offset > stack_size)
1354 TRACE("param[%d]: old format\n\tparam_direction: 0x%x\n", i, pParam->param_direction);
1356 if (pParam->param_direction == RPC_FC_IN_PARAM_BASETYPE ||
1357 pParam->param_direction == RPC_FC_RETURN_PARAM_BASETYPE)
1359 const unsigned char *pTypeFormat =
1360 &pParam->type_format_char;
1362 TRACE("\tbase type 0x%02x\n", *pTypeFormat);
1366 case STUBLESS_MARSHAL:
1367 if (pParam->param_direction == RPC_FC_RETURN_PARAM_BASETYPE)
1369 unsigned char *pRetVal = (unsigned char *)&RetVal;
1370 call_marshaller(&stubMsg, (unsigned char *)&pRetVal, pTypeFormat);
1373 case STUBLESS_UNMARSHAL:
1374 if (pParam->param_direction == RPC_FC_IN_PARAM_BASETYPE)
1375 call_unmarshaller(&stubMsg, &pArg, pTypeFormat, 0);
1377 case STUBLESS_CALCSIZE:
1378 if (pParam->param_direction == RPC_FC_RETURN_PARAM_BASETYPE)
1380 unsigned char * pRetVal = (unsigned char *)&RetVal;
1381 call_buffer_sizer(&stubMsg, (unsigned char *)&pRetVal, pTypeFormat);
1385 RpcRaiseException(RPC_S_INTERNAL_ERROR);
1388 current_stack_offset += call_memory_sizer(&stubMsg, pTypeFormat);
1389 current_offset += sizeof(NDR_PARAM_OI_BASETYPE);
1393 NDR_PARAM_OI_OTHER * pParamOther =
1394 (NDR_PARAM_OI_OTHER *)&pFormat[current_offset];
1396 const unsigned char * pTypeFormat =
1397 &pStubDesc->pFormatTypes[pParamOther->type_offset];
1399 TRACE("\tcomplex type 0x%02x\n", *pTypeFormat);
1403 case STUBLESS_MARSHAL:
1404 if (pParam->param_direction == RPC_FC_RETURN_PARAM)
1406 unsigned char *pRetVal = (unsigned char *)&RetVal;
1407 call_marshaller(&stubMsg, (unsigned char *)&pRetVal, pTypeFormat);
1409 else if (pParam->param_direction == RPC_FC_OUT_PARAM ||
1410 pParam->param_direction == RPC_FC_IN_OUT_PARAM)
1411 call_marshaller(&stubMsg, pArg, pTypeFormat);
1413 case STUBLESS_UNMARSHAL:
1414 if (pParam->param_direction == RPC_FC_IN_OUT_PARAM ||
1415 pParam->param_direction == RPC_FC_IN_PARAM)
1416 call_unmarshaller(&stubMsg, &pArg, pTypeFormat, 0);
1418 case STUBLESS_CALCSIZE:
1419 if (pParam->param_direction == RPC_FC_RETURN_PARAM)
1421 unsigned char * pRetVal = (unsigned char *)&RetVal;
1422 call_buffer_sizer(&stubMsg, (unsigned char *)&pRetVal, pTypeFormat);
1424 else if (pParam->param_direction == RPC_FC_OUT_PARAM ||
1425 pParam->param_direction == RPC_FC_IN_OUT_PARAM)
1426 call_buffer_sizer(&stubMsg, pArg, pTypeFormat);
1429 RpcRaiseException(RPC_S_INTERNAL_ERROR);
1432 current_stack_offset += pParamOther->stack_size * sizeof(INT);
1433 current_offset += sizeof(NDR_PARAM_OI_OTHER);
1440 ERR("shouldn't reach here. phase %d\n", phase);
1445 pRpcMsg->BufferLength = (unsigned int)(stubMsg.Buffer - (unsigned char *)pRpcMsg->Buffer);
1447 if (ext_flags & RPC_FC_PROC_EXT_NEWCORRDESC)
1449 /* free extra correlation package */
1450 /* NdrCorrelationFree(&stubMsg); */
1453 if (Oif_flags & RPC_FC_PROC_OI2F_HASPIPES)
1455 /* NdrPipesDone(...) */
1459 /* free the full pointer translation tables */
1460 if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_FULLPTR)
1461 NdrFullPointerXlatFree(stubMsg.FullPtrXlatTables);
1464 /* free server function stack */
1465 HeapFree(GetProcessHeap(), 0, args);
1470 void WINAPI NdrServerCall2(PRPC_MESSAGE pRpcMsg)
1473 NdrStubCall2(NULL, NULL, pRpcMsg, &dwPhase);