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"
43 #include "wine/debug.h"
44 #include "wine/rpcfc.h"
49 WINE_DEFAULT_DEBUG_CHANNEL(rpc
);
51 #define NDR_TABLE_MASK 127
53 static inline void call_buffer_sizer(PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
, PFORMAT_STRING pFormat
)
55 NDR_BUFFERSIZE m
= NdrBufferSizer
[pFormat
[0] & NDR_TABLE_MASK
];
56 if (m
) m(pStubMsg
, pMemory
, pFormat
);
59 FIXME("format type 0x%x not implemented\n", pFormat
[0]);
60 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
64 static inline unsigned char *call_marshaller(PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
, PFORMAT_STRING pFormat
)
66 NDR_MARSHALL m
= NdrMarshaller
[pFormat
[0] & NDR_TABLE_MASK
];
67 if (m
) return m(pStubMsg
, pMemory
, pFormat
);
70 FIXME("format type 0x%x not implemented\n", pFormat
[0]);
71 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
76 static inline unsigned char *call_unmarshaller(PMIDL_STUB_MESSAGE pStubMsg
, unsigned char **ppMemory
, PFORMAT_STRING pFormat
, unsigned char fMustAlloc
)
78 NDR_UNMARSHALL m
= NdrUnmarshaller
[pFormat
[0] & NDR_TABLE_MASK
];
79 if (m
) return m(pStubMsg
, ppMemory
, pFormat
, fMustAlloc
);
82 FIXME("format type 0x%x not implemented\n", pFormat
[0]);
83 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
88 static inline void call_freer(PMIDL_STUB_MESSAGE pStubMsg
, unsigned char *pMemory
, PFORMAT_STRING pFormat
)
90 NDR_FREE m
= NdrFreer
[pFormat
[0] & NDR_TABLE_MASK
];
91 if (m
) m(pStubMsg
, pMemory
, pFormat
);
94 FIXME("format type 0x%x not implemented\n", pFormat
[0]);
95 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
99 static inline unsigned long call_memory_sizer(PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
101 NDR_MEMORYSIZE m
= NdrMemorySizer
[pFormat
[0] & NDR_TABLE_MASK
];
102 if (m
) return m(pStubMsg
, pFormat
);
105 FIXME("format type 0x%x not implemented\n", pFormat
[0]);
106 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
111 /* there can't be any alignment with the structures in this file */
112 #include "pshpack1.h"
114 #define STUBLESS_UNMARSHAL 1
115 #define STUBLESS_CALLSERVER 2
116 #define STUBLESS_CALCSIZE 3
117 #define STUBLESS_GETBUFFER 4
118 #define STUBLESS_MARSHAL 5
120 /* From http://msdn.microsoft.com/library/default.asp?url=/library/en-us/rpc/rpc/parameter_descriptors.asp */
121 typedef struct _NDR_PROC_HEADER
123 /* type of handle to use:
124 * RPC_FC_BIND_EXPLICIT = 0 - Explicit handle.
125 * Handle is passed as a parameter to the function.
126 * Indicates that explicit handle information follows the header,
127 * which actually describes the handle.
128 * RPC_FC_BIND_GENERIC = 31 - Implicit handle with custom binding routines
129 * (MIDL_STUB_DESC::IMPLICIT_HANDLE_INFO::pGenericBindingInfo)
130 * RPC_FC_BIND_PRIMITIVE = 32 - Implicit handle using handle_t created by
131 * calling application
132 * RPC_FC_AUTO_HANDLE = 33 - Automatic handle
133 * RPC_FC_CALLBACK_HANDLE = 34 - undocmented
135 unsigned char handle_type
;
138 * Oi_FULL_PTR_USED = 0x01 - A full pointer can have the value NULL and can
139 * change during the call from NULL to non-NULL and supports aliasing
140 * and cycles. Indicates that the NdrFullPointerXlatInit function
142 * Oi_RPCSS_ALLOC_USED = 0x02 - Use RpcSS allocate/free routines instead of
143 * normal allocate/free routines
144 * Oi_OBJECT_PROC = 0x04 - Indicates a procedure that is part of an OLE
145 * interface, rather than a DCE RPC interface.
146 * Oi_HAS_RPCFLAGS = 0x08 - Indicates that the rpc_flags element is
147 * present in the header.
148 * Oi_HAS_COMM_OR_FAULT = 0x20 - If Oi_OBJECT_PROC not present only then
149 * indicates that the procedure has the comm_status or fault_status
151 * Oi_OBJ_USE_V2_INTERPRETER = 0x20 - If Oi_OBJECT_PROC present only
152 * then indicates that the format string is in -Oif or -Oicf format
153 * Oi_USE_NEW_INIT_ROUTINES = 0x40 - Use NdrXInitializeNew instead of
156 unsigned char Oi_flags
;
158 /* the zero-based index of the procedure */
159 unsigned short proc_num
;
161 /* total size of all parameters on the stack, including any "this"
162 * pointer and/or return value */
163 unsigned short stack_size
;
166 /* same as above struct except additional element rpc_flags */
167 typedef struct _NDR_PROC_HEADER_RPC
169 unsigned char handle_type
;
170 unsigned char Oi_flags
;
173 * RPCF_Idempotent = 0x0001 - [idempotent] MIDL attribute
174 * RPCF_Broadcast = 0x0002 - [broadcast] MIDL attribute
175 * RPCF_Maybe = 0x0004 - [maybe] MIDL attribute
176 * Reserved = 0x0008 - 0x0080
177 * RPCF_Message = 0x0100 - [message] MIDL attribute
178 * Reserved = 0x0200 - 0x1000
179 * RPCF_InputSynchronous = 0x2000 - unknown
180 * RPCF_Asynchronous = 0x4000 - [async] MIDL attribute
183 unsigned long rpc_flags
;
184 unsigned short proc_num
;
185 unsigned short stack_size
;
187 } NDR_PROC_HEADER_RPC
;
189 typedef struct _NDR_PROC_PARTIAL_OIF_HEADER
191 /* the pre-computed client buffer size so that interpreter can skip all
192 * or some (if the flag RPC_FC_PROC_OI2F_CLTMUSTSIZE is specified) of the
194 unsigned short constant_client_buffer_size
;
196 /* the pre-computed server buffer size so that interpreter can skip all
197 * or some (if the flag RPC_FC_PROC_OI2F_SRVMUSTSIZE is specified) of the
199 unsigned short constant_server_buffer_size
;
202 * RPC_FC_PROC_OI2F_SRVMUSTSIZE = 0x01 - the server must perform a
204 * RPC_FC_PROC_OI2F_CLTMUSTSIZE = 0x02 - the client must perform a
206 * RPC_FC_PROC_OI2F_HASRETURN = 0x04 - procedure has a return value.
207 * RPC_FC_PROC_OI2F_HASPIPES = 0x08 - the pipe package should be used.
208 * RPC_FC_PROC_OI2F_HASASYNCUUID = 0x20 - indicates an asynchronous DCOM
210 * RPC_FC_PROC_OI2F_HASEXTS = 0x40 - indicates that Windows 2000
211 * extensions are in use.
212 * RPC_FC_PROC_OI2F_HASASYNCHND = 0x80 - indicates an asynchronous RPC
215 unsigned char Oif_flags
;
217 /* number of params */
218 unsigned char number_of_params
;
219 } NDR_PROC_PARTIAL_OIF_HEADER
;
221 /* Windows 2000 extensions */
222 typedef struct _NDR_PROC_EXTENSION
224 /* size in bytes of all following extensions */
225 unsigned char extension_version
;
228 * HasNewCorrDesc = 0x01 - indicates new correlation descriptors in use
229 * ClientCorrCheck = 0x02 - client needs correlation check
230 * ServerCorrCheck = 0x04 - server needs correlation check
231 * HasNotify = 0x08 - should call MIDL [notify] routine @ NotifyIndex
232 * HasNotify2 = 0x10 - should call MIDL [notify_flag] routine @
235 unsigned char ext_flags
;
237 /* client cache size hint */
238 unsigned short ClientCorrHint
;
240 /* server cache size hint */
241 unsigned short ServerCorrHint
;
243 /* index of routine in MIDL_STUB_DESC::NotifyRoutineTable to call if
244 * HasNotify or HasNotify2 flag set */
245 unsigned short NotifyIndex
;
246 } NDR_PROC_EXTENSION
;
248 /* usually generated only on IA64 */
249 typedef struct _NDR_PROC_EXTENSION_64
251 NDR_PROC_EXTENSION ext
;
253 /* needed only on IA64 to cope with float/register loading */
254 unsigned short FloatDoubleMask
;
255 } NDR_PROC_EXTENSION_64
;
258 typedef struct _NDR_PARAM_OI_BASETYPE
260 /* parameter direction. One of:
261 * FC_IN_PARAM_BASETYPE = 0x4e - an in param
262 * FC_RETURN_PARAM_BASETYPE = 0x53 - a return param
264 unsigned char param_direction
;
266 /* One of: FC_BYTE,FC_CHAR,FC_SMALL,FC_USMALL,FC_WCHAR,FC_SHORT,FC_USHORT,
267 * FC_LONG,FC_ULONG,FC_FLOAT,FC_HYPER,FC_DOUBLE,FC_ENUM16,FC_ENUM32,
268 * FC_ERROR_STATUS_T,FC_INT3264,FC_UINT3264 */
269 unsigned char type_format_char
;
270 } NDR_PARAM_OI_BASETYPE
;
272 typedef struct _NDR_PARAM_OI_OTHER
275 * FC_IN_PARAM = 0x4d - An in param
276 * FC_IN_OUT_PARAM = 0x50 - An in/out param
277 * FC_OUT_PARAM = 0x51 - An out param
278 * FC_RETURN_PARAM = 0x52 - A return value
279 * FC_IN_PARAM_NO_FREE_INST = 0x4f - A param for which no freeing is done
281 unsigned char param_direction
;
283 /* Size of param on stack in NUMBERS OF INTS */
284 unsigned char stack_size
;
286 /* offset in the type format string table */
287 unsigned short type_offset
;
288 } NDR_PARAM_OI_OTHER
;
290 typedef struct _NDR_PARAM_OIF_BASETYPE
292 PARAM_ATTRIBUTES param_attributes
;
294 /* the offset on the calling stack where the parameter is located */
295 unsigned short stack_offset
;
297 /* see NDR_PARAM_OI_BASETYPE::type_format_char */
298 unsigned char type_format_char
;
301 unsigned char unused
;
302 } NDR_PARAM_OIF_BASETYPE
;
304 typedef struct _NDR_PARAM_OIF_OTHER
306 PARAM_ATTRIBUTES param_attributes
;
308 /* see NDR_PARAM_OIF_BASETYPE::stack_offset */
309 unsigned short stack_offset
;
311 /* offset into the provided type format string where the type for this
312 * parameter starts */
313 unsigned short type_offset
;
314 } NDR_PARAM_OIF_OTHER
;
316 /* explicit handle description for FC_BIND_PRIMITIVE type */
317 typedef struct _NDR_EHD_PRIMITIVE
319 /* FC_BIND_PRIMITIVE */
320 unsigned char handle_type
;
322 /* is the handle passed in via a pointer? */
325 /* offset from the beginning of the stack to the handle in bytes */
326 unsigned short offset
;
329 /* explicit handle description for FC_BIND_GENERIC type */
330 typedef struct _NDR_EHD_GENERIC
332 /* FC_BIND_GENERIC */
333 unsigned char handle_type
;
335 /* upper 4bits is a flag indicating whether the handle is passed in
336 * via a pointer. lower 4bits is the size of the user defined generic
337 * handle type. the size must be less than or equal to the machine
339 unsigned char flag_and_size
;
341 /* offset from the beginning of the stack to the handle in bytes */
342 unsigned short offset
;
344 /* the index into the aGenericBindingRoutinesPairs field of MIDL_STUB_DESC
345 * giving the bind and unbind routines for the handle */
346 unsigned char binding_routine_pair_index
;
349 unsigned char unused
;
352 /* explicit handle description for FC_BIND_CONTEXT type */
353 typedef struct _NDR_EHD_CONTEXT
355 /* FC_BIND_CONTEXT */
356 unsigned char handle_type
;
358 /* Any of the following flags:
359 * NDR_CONTEXT_HANDLE_CANNOT_BE_NULL = 0x01
360 * NDR_CONTEXT_HANDLE_SERIALIZE = 0x02
361 * NDR_CONTEXT_HANDLE_NO_SERIALIZE = 0x04
362 * NDR_STRICT_CONTEXT_HANDLE = 0x08
363 * HANDLE_PARAM_IS_OUT = 0x20
364 * HANDLE_PARAM_IS_RETURN = 0x21
365 * HANDLE_PARAM_IS_IN = 0x40
366 * HANDLE_PARAM_IS_VIA_PTR = 0x80
370 /* offset from the beginning of the stack to the handle in bytes */
371 unsigned short offset
;
373 /* zero-based index on rundown routine in apfnNdrRundownRoutines field
374 * of MIDL_STUB_DESC */
375 unsigned char context_rundown_routine_index
;
377 /* varies depending on NDR version used.
378 * V1: zero-based index into parameters
379 * V2: zero-based index into handles that are parameters */
380 unsigned char param_num
;
385 void WINAPI
NdrRpcSmSetClientToOsf(PMIDL_STUB_MESSAGE pMessage
)
387 #if 0 /* these functions are not defined yet */
388 pMessage
->pfnAllocate
= NdrRpcSmClientAllocate
;
389 pMessage
->pfnFree
= NdrRpcSmClientFree
;
393 static void WINAPI
dump_RPC_FC_PROC_PF(PARAM_ATTRIBUTES param_attributes
)
395 if (param_attributes
.MustSize
) TRACE(" MustSize");
396 if (param_attributes
.MustFree
) TRACE(" MustFree");
397 if (param_attributes
.IsPipe
) TRACE(" IsPipe");
398 if (param_attributes
.IsIn
) TRACE(" IsIn");
399 if (param_attributes
.IsOut
) TRACE(" IsOut");
400 if (param_attributes
.IsReturn
) TRACE(" IsReturn");
401 if (param_attributes
.IsBasetype
) TRACE(" IsBasetype");
402 if (param_attributes
.IsByValue
) TRACE(" IsByValue");
403 if (param_attributes
.IsSimpleRef
) TRACE(" IsSimpleRef");
404 if (param_attributes
.IsDontCallFreeInst
) TRACE(" IsDontCallFreeInst");
405 if (param_attributes
.SaveForAsyncFinish
) TRACE(" SaveForAsyncFinish");
406 if (param_attributes
.ServerAllocSize
) TRACE(" ServerAllocSize = %d", param_attributes
.ServerAllocSize
* 8);
409 /* FIXME: this will be different on other plaftorms than i386 */
410 #define ARG_FROM_OFFSET(args, offset) (*(unsigned char **)args + offset)
412 /* the return type should be CLIENT_CALL_RETURN, but this is incompatible
413 * with the way gcc returns structures. "void *" should be the largest type
414 * that MIDL should allow you to return anyway */
415 LONG_PTR WINAPIV
NdrClientCall2(PMIDL_STUB_DESC pStubDesc
, PFORMAT_STRING pFormat
, ...)
417 /* pointer to start of stack where arguments start */
418 /* FIXME: not portable */
419 unsigned char *args
= (unsigned char *)(&pFormat
+1);
421 MIDL_STUB_MESSAGE stubMsg
;
422 handle_t hBinding
= NULL
;
423 /* procedure number */
424 unsigned short procedure_number
;
426 unsigned short stack_size
;
427 /* current stack offset */
428 unsigned short current_stack_offset
;
429 /* number of parameters. optional for client to give it to us */
430 unsigned char number_of_params
= ~0;
433 /* cache of Oif_flags from v2 procedure header */
434 unsigned char Oif_flags
= 0;
435 /* cache of extension flags from NDR_PROC_EXTENSION */
436 unsigned char ext_flags
= 0;
437 /* the type of pass we are currently doing */
439 /* header for procedure string */
440 const NDR_PROC_HEADER
* pProcHeader
= (const NDR_PROC_HEADER
*)&pFormat
[0];
441 /* offset in format string for start of params */
442 int parameter_start_offset
;
443 /* current format string offset */
445 /* -Oif or -Oicf generated format */
446 BOOL bV2Format
= FALSE
;
447 /* the value to return to the client from the remote procedure */
449 /* the pointer to the object when in OLE mode */
452 TRACE("pStubDesc %p, pFormat %p, ...\n", pStubDesc
, pFormat
);
453 TRACE("&first_argument = %p -> %p\n", args
, ARG_FROM_OFFSET(args
, 0));
455 /* Later NDR language versions probably won't be backwards compatible */
456 if (pStubDesc
->Version
> 0x50002)
458 FIXME("Incompatible stub description version: 0x%lx\n", pStubDesc
->Version
);
459 RpcRaiseException(RPC_X_WRONG_STUB_VERSION
);
462 if (pProcHeader
->Oi_flags
& RPC_FC_PROC_OIF_RPCFLAGS
)
464 NDR_PROC_HEADER_RPC
* pProcHeader
= (NDR_PROC_HEADER_RPC
*)&pFormat
[0];
465 stack_size
= pProcHeader
->stack_size
;
466 procedure_number
= pProcHeader
->proc_num
;
467 current_offset
= sizeof(NDR_PROC_HEADER_RPC
);
471 stack_size
= pProcHeader
->stack_size
;
472 procedure_number
= pProcHeader
->proc_num
;
473 TRACE("proc num: %d\n", procedure_number
);
474 current_offset
= sizeof(NDR_PROC_HEADER
);
477 TRACE("Oi_flags = 0x%02x\n", pProcHeader
->Oi_flags
);
478 TRACE("MIDL stub version = 0x%lx\n", pStubDesc
->MIDLVersion
);
480 /* we only need a handle if this isn't an object method */
481 if (!(pProcHeader
->Oi_flags
& RPC_FC_PROC_OIF_OBJECT
))
484 switch (pProcHeader
->handle_type
)
486 /* explicit binding: parse additional section */
487 case RPC_FC_BIND_EXPLICIT
:
488 switch (pFormat
[current_offset
]) /* handle_type */
490 case RPC_FC_BIND_PRIMITIVE
: /* explicit primitive */
492 NDR_EHD_PRIMITIVE
* pDesc
= (NDR_EHD_PRIMITIVE
*)&pFormat
[current_offset
];
494 TRACE("Explicit primitive handle @ %d\n", pDesc
->offset
);
496 if (pDesc
->flag
) /* pointer to binding */
497 hBinding
= **(handle_t
**)ARG_FROM_OFFSET(args
, pDesc
->offset
);
499 hBinding
= *(handle_t
*)ARG_FROM_OFFSET(args
, pDesc
->offset
);
500 current_offset
+= sizeof(NDR_EHD_PRIMITIVE
);
503 case RPC_FC_BIND_GENERIC
: /* explicit generic */
504 FIXME("RPC_FC_BIND_GENERIC\n");
505 RpcRaiseException(RPC_X_WRONG_STUB_VERSION
); /* FIXME: remove when implemented */
506 current_offset
+= sizeof(NDR_EHD_GENERIC
);
508 case RPC_FC_BIND_CONTEXT
: /* explicit context */
510 NDR_EHD_CONTEXT
* pDesc
= (NDR_EHD_CONTEXT
*)&pFormat
[current_offset
];
511 TRACE("Explicit bind context\n");
512 hBinding
= NDRCContextBinding(*(NDR_CCONTEXT
*)ARG_FROM_OFFSET(args
, pDesc
->offset
));
513 /* FIXME: should we store this structure in stubMsg.pContext? */
514 current_offset
+= sizeof(NDR_EHD_CONTEXT
);
518 ERR("bad explicit binding handle type (0x%02x)\n", pProcHeader
->handle_type
);
519 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
522 case RPC_FC_BIND_GENERIC
: /* implicit generic */
523 FIXME("RPC_FC_BIND_GENERIC\n");
524 RpcRaiseException(RPC_X_BAD_STUB_DATA
); /* FIXME: remove when implemented */
526 case RPC_FC_BIND_PRIMITIVE
: /* implicit primitive */
527 TRACE("Implicit primitive handle\n");
528 hBinding
= *pStubDesc
->IMPLICIT_HANDLE_INFO
.pPrimitiveHandle
;
530 case RPC_FC_CALLBACK_HANDLE
: /* implicit callback */
531 FIXME("RPC_FC_CALLBACK_HANDLE\n");
533 case RPC_FC_AUTO_HANDLE
: /* implicit auto handle */
534 /* strictly speaking, it isn't necessary to set hBinding here
535 * since it isn't actually used (hence the automatic in its name),
536 * but then why does MIDL generate a valid entry in the
537 * MIDL_STUB_DESC for it? */
538 TRACE("Implicit auto handle\n");
539 hBinding
= *pStubDesc
->IMPLICIT_HANDLE_INFO
.pAutoHandle
;
542 ERR("bad implicit binding handle type (0x%02x)\n", pProcHeader
->handle_type
);
543 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
547 bV2Format
= (pStubDesc
->Version
>= 0x20000);
551 NDR_PROC_PARTIAL_OIF_HEADER
* pOIFHeader
=
552 (NDR_PROC_PARTIAL_OIF_HEADER
*)&pFormat
[current_offset
];
554 Oif_flags
= pOIFHeader
->Oif_flags
;
555 number_of_params
= pOIFHeader
->number_of_params
;
557 current_offset
+= sizeof(NDR_PROC_PARTIAL_OIF_HEADER
);
560 TRACE("Oif_flags = 0x%02x\n", Oif_flags
);
562 if (Oif_flags
& RPC_FC_PROC_OI2F_HASEXTS
)
564 NDR_PROC_EXTENSION
* pExtensions
=
565 (NDR_PROC_EXTENSION
*)&pFormat
[current_offset
];
566 ext_flags
= pExtensions
->ext_flags
;
567 current_offset
+= pExtensions
->extension_version
;
570 if (pProcHeader
->Oi_flags
& RPC_FC_PROC_OIF_OBJECT
)
572 /* object is always the first argument */
573 This
= *(void **)ARG_FROM_OFFSET(args
, 0);
574 NdrProxyInitialize(This
, &rpcMsg
, &stubMsg
, pStubDesc
, procedure_number
);
577 NdrClientInitializeNew(&rpcMsg
, &stubMsg
, pStubDesc
, procedure_number
);
579 /* create the full pointer translation tables, if requested */
580 if (pProcHeader
->Oi_flags
& RPC_FC_PROC_OIF_FULLPTR
)
582 stubMsg
.FullPtrXlatTables
= NdrFullPointerXlatInit(0,XLAT_CLIENT
);
584 FIXME("initialize full pointer translation tables\n");
587 stubMsg
.BufferLength
= 0;
588 /* needed for conformance of top-level objects */
589 stubMsg
.StackTop
= *(unsigned char **)args
;
591 /* store the RPC flags away */
592 if (pProcHeader
->Oi_flags
& RPC_FC_PROC_OIF_RPCFLAGS
)
593 rpcMsg
.RpcFlags
= ((NDR_PROC_HEADER_RPC
*)pProcHeader
)->rpc_flags
;
595 /* use alternate memory allocation routines */
596 if (pProcHeader
->Oi_flags
& RPC_FC_PROC_OIF_RPCSSALLOC
)
597 NdrRpcSmSetClientToOsf(&stubMsg
);
599 if (Oif_flags
& RPC_FC_PROC_OI2F_HASPIPES
)
601 FIXME("pipes not supported yet\n");
602 RpcRaiseException(RPC_X_WRONG_STUB_VERSION
); /* FIXME: remove when implemented */
603 /* init pipes package */
604 /* NdrPipesInitialize(...) */
606 if (ext_flags
& RPC_FC_PROC_EXT_NEWCORRDESC
)
608 /* initialize extra correlation package */
609 FIXME("new correlation description not implemented\n");
610 stubMsg
.fHasNewCorrDesc
= TRUE
;
613 parameter_start_offset
= current_offset
;
616 * 1. PROXY_CALCSIZE - calculate the buffer size
617 * 2. PROXY_GETBUFFER - allocate the buffer
618 * 3. PROXY_MARHSAL - marshal [in] params into the buffer
619 * 4. PROXY_SENDRECEIVE - send/receive buffer
620 * 5. PROXY_UNMARHSAL - unmarshal [out] params from buffer
622 for (phase
= PROXY_CALCSIZE
; phase
<= PROXY_UNMARSHAL
; phase
++)
624 TRACE("phase = %d\n", phase
);
627 case PROXY_GETBUFFER
:
628 /* allocate the buffer */
629 if (pProcHeader
->Oi_flags
& RPC_FC_PROC_OIF_OBJECT
)
630 NdrProxyGetBuffer(This
, &stubMsg
);
631 else if (Oif_flags
& RPC_FC_PROC_OI2F_HASPIPES
)
632 /* NdrGetPipeBuffer(...) */
633 FIXME("pipes not supported yet\n");
636 if (pProcHeader
->handle_type
== RPC_FC_AUTO_HANDLE
)
638 NdrNsGetBuffer(&stubMsg
, stubMsg
.BufferLength
, hBinding
);
640 FIXME("using auto handle - call NdrNsGetBuffer when it gets implemented\n");
643 NdrGetBuffer(&stubMsg
, stubMsg
.BufferLength
, hBinding
);
646 case PROXY_SENDRECEIVE
:
647 /* send the [in] params and receive the [out] and [retval]
649 if (pProcHeader
->Oi_flags
& RPC_FC_PROC_OIF_OBJECT
)
650 NdrProxySendReceive(This
, &stubMsg
);
651 else if (Oif_flags
& RPC_FC_PROC_OI2F_HASPIPES
)
652 /* NdrPipesSendReceive(...) */
653 FIXME("pipes not supported yet\n");
656 if (pProcHeader
->handle_type
== RPC_FC_AUTO_HANDLE
)
658 NdrNsSendReceive(&stubMsg
, stubMsg
.Buffer
, pStubDesc
->IMPLICIT_HANDLE_INFO
.pAutoHandle
);
660 FIXME("using auto handle - call NdrNsSendReceive when it gets implemented\n");
663 NdrSendReceive(&stubMsg
, stubMsg
.Buffer
);
666 /* convert strings, floating point values and endianess into our
667 * preferred format */
668 if ((rpcMsg
.DataRepresentation
& 0x0000FFFFUL
) != NDR_LOCAL_DATA_REPRESENTATION
)
669 NdrConvert(&stubMsg
, pFormat
);
674 case PROXY_UNMARSHAL
:
675 current_offset
= parameter_start_offset
;
676 current_stack_offset
= 0;
678 /* NOTE: V1 style format does't terminate on the number_of_params
679 * condition as it doesn't have this attribute. Instead it
680 * terminates when the stack size given in the header is exceeded.
682 for (i
= 0; i
< number_of_params
; i
++)
684 if (bV2Format
) /* new parameter format */
686 NDR_PARAM_OIF_BASETYPE
* pParam
=
687 (NDR_PARAM_OIF_BASETYPE
*)&pFormat
[current_offset
];
688 unsigned char * pArg
;
690 current_stack_offset
= pParam
->stack_offset
;
691 pArg
= ARG_FROM_OFFSET(args
, current_stack_offset
);
693 TRACE("param[%d]: new format\n", i
);
694 TRACE("\tparam_attributes:"); dump_RPC_FC_PROC_PF(pParam
->param_attributes
); TRACE("\n");
695 TRACE("\tstack_offset: 0x%x\n", current_stack_offset
);
696 TRACE("\tmemory addr (before): %p\n", pArg
);
698 if (pParam
->param_attributes
.IsBasetype
)
700 const unsigned char * pTypeFormat
=
701 &pParam
->type_format_char
;
703 if (pParam
->param_attributes
.IsSimpleRef
)
704 pArg
= *(unsigned char **)pArg
;
706 TRACE("\tbase type: 0x%02x\n", *pTypeFormat
);
711 if (pParam
->param_attributes
.IsIn
)
712 call_buffer_sizer(&stubMsg
, pArg
, pTypeFormat
);
715 if (pParam
->param_attributes
.IsIn
)
716 call_marshaller(&stubMsg
, pArg
, pTypeFormat
);
718 case PROXY_UNMARSHAL
:
719 if (pParam
->param_attributes
.IsOut
)
721 unsigned char *pRetVal
= (unsigned char *)&RetVal
;
722 if (pParam
->param_attributes
.IsReturn
)
723 call_unmarshaller(&stubMsg
, &pRetVal
, pTypeFormat
, 0);
725 call_unmarshaller(&stubMsg
, &pArg
, pTypeFormat
, 0);
726 TRACE("pRetVal = %p\n", pRetVal
);
730 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
733 current_offset
+= sizeof(NDR_PARAM_OIF_BASETYPE
);
737 NDR_PARAM_OIF_OTHER
* pParamOther
=
738 (NDR_PARAM_OIF_OTHER
*)&pFormat
[current_offset
];
740 const unsigned char * pTypeFormat
=
741 &(pStubDesc
->pFormatTypes
[pParamOther
->type_offset
]);
743 /* if a simple ref pointer then we have to do the
744 * check for the pointer being non-NULL. */
745 if (pParam
->param_attributes
.IsSimpleRef
)
747 if (!*(unsigned char **)pArg
)
748 RpcRaiseException(RPC_X_NULL_REF_POINTER
);
751 TRACE("\tcomplex type: 0x%02x\n", *pTypeFormat
);
756 if (pParam
->param_attributes
.IsIn
)
758 if (pParam
->param_attributes
.IsByValue
)
759 call_buffer_sizer(&stubMsg
, pArg
, pTypeFormat
);
761 call_buffer_sizer(&stubMsg
, *(unsigned char **)pArg
, pTypeFormat
);
765 if (pParam
->param_attributes
.IsIn
)
767 if (pParam
->param_attributes
.IsByValue
)
768 call_marshaller(&stubMsg
, pArg
, pTypeFormat
);
770 call_marshaller(&stubMsg
, *(unsigned char **)pArg
, pTypeFormat
);
773 case PROXY_UNMARSHAL
:
774 if (pParam
->param_attributes
.IsOut
)
776 unsigned char *pRetVal
= (unsigned char *)&RetVal
;
777 if (pParam
->param_attributes
.IsReturn
)
778 call_unmarshaller(&stubMsg
, &pRetVal
, pTypeFormat
, 0);
779 else if (pParam
->param_attributes
.IsByValue
)
780 call_unmarshaller(&stubMsg
, &pArg
, pTypeFormat
, 0);
782 call_unmarshaller(&stubMsg
, (unsigned char **)pArg
, pTypeFormat
, 0);
786 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
789 current_offset
+= sizeof(NDR_PARAM_OIF_OTHER
);
791 TRACE("\tmemory addr (after): %p\n", pArg
);
793 else /* old parameter format */
795 NDR_PARAM_OI_BASETYPE
* pParam
=
796 (NDR_PARAM_OI_BASETYPE
*)&pFormat
[current_offset
];
797 unsigned char * pArg
= ARG_FROM_OFFSET(args
, current_stack_offset
);
799 /* no more parameters; exit loop */
800 if (current_stack_offset
> stack_size
)
803 TRACE("param[%d]: old format\n", i
);
804 TRACE("\tparam_direction: %x\n", pParam
->param_direction
);
805 TRACE("\tstack_offset: 0x%x\n", current_stack_offset
);
806 TRACE("\tmemory addr (before): %p\n", pArg
);
808 if (pParam
->param_direction
== RPC_FC_IN_PARAM_BASETYPE
||
809 pParam
->param_direction
== RPC_FC_RETURN_PARAM_BASETYPE
)
811 const unsigned char * pTypeFormat
=
812 &pParam
->type_format_char
;
814 TRACE("\tbase type 0x%02x\n", *pTypeFormat
);
819 if (pParam
->param_direction
== RPC_FC_IN_PARAM_BASETYPE
)
820 call_buffer_sizer(&stubMsg
, pArg
, pTypeFormat
);
823 if (pParam
->param_direction
== RPC_FC_IN_PARAM_BASETYPE
)
824 call_marshaller(&stubMsg
, pArg
, pTypeFormat
);
826 case PROXY_UNMARSHAL
:
827 if (pParam
->param_direction
== RPC_FC_RETURN_PARAM_BASETYPE
)
829 if (pParam
->param_direction
& RPC_FC_RETURN_PARAM
)
830 call_unmarshaller(&stubMsg
, (unsigned char **)&RetVal
, pTypeFormat
, 0);
832 call_unmarshaller(&stubMsg
, &pArg
, pTypeFormat
, 0);
836 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
839 current_stack_offset
+= call_memory_sizer(&stubMsg
, pTypeFormat
);
840 current_offset
+= sizeof(NDR_PARAM_OI_BASETYPE
);
844 NDR_PARAM_OI_OTHER
* pParamOther
=
845 (NDR_PARAM_OI_OTHER
*)&pFormat
[current_offset
];
847 const unsigned char *pTypeFormat
=
848 &pStubDesc
->pFormatTypes
[pParamOther
->type_offset
];
850 TRACE("\tcomplex type 0x%02x\n", *pTypeFormat
);
855 if (pParam
->param_direction
== RPC_FC_IN_PARAM
||
856 pParam
->param_direction
& RPC_FC_IN_OUT_PARAM
)
857 call_buffer_sizer(&stubMsg
, pArg
, pTypeFormat
);
860 if (pParam
->param_direction
== RPC_FC_IN_PARAM
||
861 pParam
->param_direction
& RPC_FC_IN_OUT_PARAM
)
862 call_marshaller(&stubMsg
, pArg
, pTypeFormat
);
864 case PROXY_UNMARSHAL
:
865 if (pParam
->param_direction
== RPC_FC_IN_OUT_PARAM
||
866 pParam
->param_direction
== RPC_FC_OUT_PARAM
)
867 call_unmarshaller(&stubMsg
, &pArg
, pTypeFormat
, 0);
868 else if (pParam
->param_direction
== RPC_FC_RETURN_PARAM
)
869 call_unmarshaller(&stubMsg
, (unsigned char **)&RetVal
, pTypeFormat
, 0);
872 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
875 current_stack_offset
+= pParamOther
->stack_size
* sizeof(INT
);
876 current_offset
+= sizeof(NDR_PARAM_OI_OTHER
);
878 TRACE("\tmemory addr (after): %p\n", pArg
);
884 ERR("shouldn't reach here. phase %d\n", phase
);
889 /* FIXME: unbind the binding handle */
891 if (ext_flags
& RPC_FC_PROC_EXT_NEWCORRDESC
)
893 /* free extra correlation package */
894 /* NdrCorrelationFree(&stubMsg); */
897 if (Oif_flags
& RPC_FC_PROC_OI2F_HASPIPES
)
899 /* NdrPipesDone(...) */
903 /* free the full pointer translation tables */
904 if (pProcHeader
->Oi_flags
& RPC_FC_PROC_OIF_FULLPTR
)
905 NdrFullPointerXlatFree(stubMsg
.FullPtrXlatTables
);
908 /* free marshalling buffer */
909 if (pProcHeader
->Oi_flags
& RPC_FC_PROC_OIF_OBJECT
)
910 NdrProxyFreeBuffer(This
, &stubMsg
);
912 NdrFreeBuffer(&stubMsg
);
914 TRACE("RetVal = 0x%lx\n", RetVal
);
919 /* calls a function with the specificed arguments, restoring the stack
920 * properly afterwards as we don't know the calling convention of the
922 #if defined __i386__ && defined _MSC_VER
923 __declspec(naked
) LONG_PTR __cdecl
call_server_func(SERVER_ROUTINE func
, unsigned char * args
, unsigned int stack_size
)
928 push edi
; Save registers
931 mov eax
, [ebp
+16] ; Get stack size
932 sub esp
, eax
; Make room in stack
for arguments
938 rep movsd
; Copy dword blocks
939 call
[ebp
+8] ; Call function
940 lea esp
, [ebp
-8] ; Restore stack
941 pop esi
; Restore registers
947 #elif defined __i386__ && defined __GNUC__
948 LONG_PTR __cdecl
call_server_func(SERVER_ROUTINE func
, unsigned char * args
, unsigned int stack_size
);
949 __ASM_GLOBAL_FUNC(call_server_func
,
951 "movl %esp, %ebp\n\t"
952 "pushl %edi\n\t" /* Save registers */
954 "movl 16(%ebp), %eax\n\t" /* Get stack size */
955 "subl %eax, %esp\n\t" /* Make room in stack for arguments */
956 "andl $~15, %esp\n\t" /* Make sure stack has 16-byte alignment for MacOS X */
957 "movl %esp, %edi\n\t"
958 "movl %eax, %ecx\n\t"
959 "movl 12(%ebp), %esi\n\t"
960 "shrl $2, %ecx\n\t" /* divide by 4 */
962 "rep; movsl\n\t" /* Copy dword blocks */
963 "call *8(%ebp)\n\t" /* Call function */
964 "leal -8(%ebp), %esp\n\t" /* Restore stack */
965 "popl %esi\n\t" /* Restore registers */
970 #warning call_server_func not implemented for your architecture
971 LONG_PTR __cdecl
call_server_func(SERVER_ROUTINE func
, unsigned char * args
, unsigned short stack_size
)
973 FIXME("Not implemented for your architecture\n");
978 /* FIXME: need to free some stuff in here too */
979 long WINAPI
NdrStubCall2(
980 struct IRpcStubBuffer
* pThis
,
981 struct IRpcChannelBuffer
* pChannel
,
982 PRPC_MESSAGE pRpcMsg
,
983 unsigned long * pdwStubPhase
)
985 const MIDL_SERVER_INFO
*pServerInfo
;
986 const MIDL_STUB_DESC
*pStubDesc
;
987 PFORMAT_STRING pFormat
;
988 MIDL_STUB_MESSAGE stubMsg
;
989 /* pointer to start of stack to pass into stub implementation */
990 unsigned char * args
;
992 unsigned short stack_size
;
993 /* current stack offset */
994 unsigned short current_stack_offset
;
995 /* number of parameters. optional for client to give it to us */
996 unsigned char number_of_params
= ~0;
999 /* cache of Oif_flags from v2 procedure header */
1000 unsigned char Oif_flags
= 0;
1001 /* cache of extension flags from NDR_PROC_EXTENSION */
1002 unsigned char ext_flags
= 0;
1003 /* the type of pass we are currently doing */
1005 /* header for procedure string */
1006 const NDR_PROC_HEADER
*pProcHeader
;
1007 /* offset in format string for start of params */
1008 int parameter_start_offset
;
1009 /* current format string offset */
1011 /* -Oif or -Oicf generated format */
1012 BOOL bV2Format
= FALSE
;
1013 /* location to put retval into */
1014 LONG_PTR
*retval_ptr
= NULL
;
1016 TRACE("pThis %p, pChannel %p, pRpcMsg %p, pdwStubPhase %p\n", pThis
, pChannel
, pRpcMsg
, pdwStubPhase
);
1019 pServerInfo
= CStdStubBuffer_GetServerInfo(pThis
);
1021 pServerInfo
= ((RPC_SERVER_INTERFACE
*)pRpcMsg
->RpcInterfaceInformation
)->InterpreterInfo
;
1023 pStubDesc
= pServerInfo
->pStubDesc
;
1024 pFormat
= pServerInfo
->ProcString
+ pServerInfo
->FmtStringOffset
[pRpcMsg
->ProcNum
];
1025 pProcHeader
= (const NDR_PROC_HEADER
*)&pFormat
[0];
1027 /* Later NDR language versions probably won't be backwards compatible */
1028 if (pStubDesc
->Version
> 0x50002)
1030 FIXME("Incompatible stub description version: 0x%lx\n", pStubDesc
->Version
);
1031 RpcRaiseException(RPC_X_WRONG_STUB_VERSION
);
1034 if (pProcHeader
->Oi_flags
& RPC_FC_PROC_OIF_RPCFLAGS
)
1036 NDR_PROC_HEADER_RPC
* pProcHeader
= (NDR_PROC_HEADER_RPC
*)&pFormat
[0];
1037 stack_size
= pProcHeader
->stack_size
;
1038 current_offset
= sizeof(NDR_PROC_HEADER_RPC
);
1043 stack_size
= pProcHeader
->stack_size
;
1044 current_offset
= sizeof(NDR_PROC_HEADER
);
1047 TRACE("Oi_flags = 0x%02x\n", pProcHeader
->Oi_flags
);
1050 switch (pProcHeader
->handle_type
)
1052 /* explicit binding: parse additional section */
1053 case RPC_FC_BIND_EXPLICIT
:
1054 switch (pFormat
[current_offset
]) /* handle_type */
1056 case RPC_FC_BIND_PRIMITIVE
: /* explicit primitive */
1057 current_offset
+= sizeof(NDR_EHD_PRIMITIVE
);
1059 case RPC_FC_BIND_GENERIC
: /* explicit generic */
1060 current_offset
+= sizeof(NDR_EHD_GENERIC
);
1062 case RPC_FC_BIND_CONTEXT
: /* explicit context */
1063 current_offset
+= sizeof(NDR_EHD_CONTEXT
);
1066 ERR("bad explicit binding handle type (0x%02x)\n", pProcHeader
->handle_type
);
1067 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1070 case RPC_FC_BIND_GENERIC
: /* implicit generic */
1071 case RPC_FC_BIND_PRIMITIVE
: /* implicit primitive */
1072 case RPC_FC_CALLBACK_HANDLE
: /* implicit callback */
1073 case RPC_FC_AUTO_HANDLE
: /* implicit auto handle */
1076 ERR("bad implicit binding handle type (0x%02x)\n", pProcHeader
->handle_type
);
1077 RpcRaiseException(RPC_X_BAD_STUB_DATA
);
1080 bV2Format
= (pStubDesc
->Version
>= 0x20000);
1084 NDR_PROC_PARTIAL_OIF_HEADER
* pOIFHeader
=
1085 (NDR_PROC_PARTIAL_OIF_HEADER
*)&pFormat
[current_offset
];
1087 Oif_flags
= pOIFHeader
->Oif_flags
;
1088 number_of_params
= pOIFHeader
->number_of_params
;
1090 current_offset
+= sizeof(NDR_PROC_PARTIAL_OIF_HEADER
);
1093 TRACE("Oif_flags = 0x%02x\n", Oif_flags
);
1095 if (Oif_flags
& RPC_FC_PROC_OI2F_HASEXTS
)
1097 NDR_PROC_EXTENSION
* pExtensions
=
1098 (NDR_PROC_EXTENSION
*)&pFormat
[current_offset
];
1099 ext_flags
= pExtensions
->ext_flags
;
1100 current_offset
+= pExtensions
->extension_version
;
1103 if (pProcHeader
->Oi_flags
& RPC_FC_PROC_OIF_OBJECT
)
1104 NdrStubInitialize(pRpcMsg
, &stubMsg
, pStubDesc
, pChannel
);
1106 NdrServerInitializeNew(pRpcMsg
, &stubMsg
, pStubDesc
);
1108 /* create the full pointer translation tables, if requested */
1109 if (pProcHeader
->Oi_flags
& RPC_FC_PROC_OIF_FULLPTR
)
1111 stubMsg
.FullPtrXlatTables
= NdrFullPointerXlatInit(0,XLAT_SERVER
);
1113 FIXME("initialize full pointer translation tables\n");
1116 /* store the RPC flags away */
1117 if (pProcHeader
->Oi_flags
& RPC_FC_PROC_OIF_RPCFLAGS
)
1118 pRpcMsg
->RpcFlags
= ((NDR_PROC_HEADER_RPC
*)pProcHeader
)->rpc_flags
;
1120 /* use alternate memory allocation routines */
1121 if (pProcHeader
->Oi_flags
& RPC_FC_PROC_OIF_RPCSSALLOC
)
1123 NdrRpcSsEnableAllocate(&stubMsg
);
1125 FIXME("Set RPCSS memory allocation routines\n");
1128 if (Oif_flags
& RPC_FC_PROC_OI2F_HASPIPES
)
1130 FIXME("pipes not supported yet\n");
1131 RpcRaiseException(RPC_X_WRONG_STUB_VERSION
); /* FIXME: remove when implemented */
1132 /* init pipes package */
1133 /* NdrPipesInitialize(...) */
1135 if (ext_flags
& RPC_FC_PROC_EXT_NEWCORRDESC
)
1137 /* initialize extra correlation package */
1138 FIXME("new correlation description not implemented\n");
1139 stubMsg
.fHasNewCorrDesc
= TRUE
;
1142 /* convert strings, floating point values and endianess into our
1143 * preferred format */
1144 if ((pRpcMsg
->DataRepresentation
& 0x0000FFFFUL
) != NDR_LOCAL_DATA_REPRESENTATION
)
1145 NdrConvert(&stubMsg
, pFormat
);
1147 parameter_start_offset
= current_offset
;
1149 TRACE("allocating memory for stack of size %x\n", stack_size
);
1151 args
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, stack_size
);
1152 stubMsg
.StackTop
= args
; /* used by conformance of top-level objects */
1154 /* add the implicit This pointer as the first arg to the function if we
1155 * are calling an object method */
1157 *(void **)args
= ((CStdStubBuffer
*)pThis
)->pvServerObject
;
1160 * 1. STUBLESS_UNMARHSAL - unmarshal [in] params from buffer
1161 * 2. STUBLESS_CALLSERVER - send/receive buffer
1162 * 3. STUBLESS_CALCSIZE - get [out] buffer size
1163 * 4. STUBLESS_GETBUFFER - allocate [out] buffer
1164 * 5. STUBLESS_MARHSAL - marshal [out] params to buffer
1166 for (phase
= STUBLESS_UNMARSHAL
; phase
<= STUBLESS_MARSHAL
; phase
++)
1168 TRACE("phase = %d\n", phase
);
1171 case STUBLESS_CALLSERVER
:
1172 /* call the server function */
1173 if (pServerInfo
->ThunkTable
&& pServerInfo
->ThunkTable
[pRpcMsg
->ProcNum
])
1174 pServerInfo
->ThunkTable
[pRpcMsg
->ProcNum
](&stubMsg
);
1177 SERVER_ROUTINE func
;
1180 if (pProcHeader
->Oi_flags
& RPC_FC_PROC_OIF_OBJECT
)
1182 SERVER_ROUTINE
*vtbl
= *(SERVER_ROUTINE
**)((CStdStubBuffer
*)pThis
)->pvServerObject
;
1183 func
= vtbl
[pRpcMsg
->ProcNum
];
1186 func
= pServerInfo
->DispatchTable
[pRpcMsg
->ProcNum
];
1188 /* FIXME: what happens with return values that don't fit into a single register on x86? */
1189 retval
= call_server_func(func
, args
, stack_size
);
1193 TRACE("stub implementation returned 0x%lx\n", retval
);
1194 *retval_ptr
= retval
;
1197 TRACE("void stub implementation\n");
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
.ServerAllocSize
)
1248 FIXME("ServerAllocSize of %d ignored for parameter %d\n",
1249 pParam
->param_attributes
.ServerAllocSize
* 8, i
);
1251 if (pParam
->param_attributes
.IsBasetype
)
1253 const unsigned char *pTypeFormat
=
1254 &pParam
->type_format_char
;
1256 TRACE("\tbase type: 0x%02x\n", *pTypeFormat
);
1260 case STUBLESS_MARSHAL
:
1261 if (pParam
->param_attributes
.IsOut
|| pParam
->param_attributes
.IsReturn
)
1263 if (pParam
->param_attributes
.IsSimpleRef
)
1264 call_marshaller(&stubMsg
, *(unsigned char **)pArg
, pTypeFormat
);
1266 call_marshaller(&stubMsg
, pArg
, pTypeFormat
);
1268 /* FIXME: call call_freer here */
1270 case STUBLESS_UNMARSHAL
:
1271 if (pParam
->param_attributes
.IsIn
)
1273 if (pParam
->param_attributes
.IsSimpleRef
)
1274 call_unmarshaller(&stubMsg
, (unsigned char **)pArg
, pTypeFormat
, 0);
1276 call_unmarshaller(&stubMsg
, &pArg
, pTypeFormat
, 0);
1279 /* make a note of the address of the return value parameter for later */
1280 if (pParam
->param_attributes
.IsReturn
)
1281 retval_ptr
= (LONG_PTR
*)pArg
;
1284 case STUBLESS_CALCSIZE
:
1285 if (pParam
->param_attributes
.IsOut
|| pParam
->param_attributes
.IsReturn
)
1287 if (pParam
->param_attributes
.IsSimpleRef
)
1288 call_buffer_sizer(&stubMsg
, *(unsigned char **)pArg
, pTypeFormat
);
1290 call_buffer_sizer(&stubMsg
, pArg
, pTypeFormat
);
1294 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
1297 current_offset
+= sizeof(NDR_PARAM_OIF_BASETYPE
);
1301 NDR_PARAM_OIF_OTHER
* pParamOther
=
1302 (NDR_PARAM_OIF_OTHER
*)&pFormat
[current_offset
];
1304 const unsigned char * pTypeFormat
=
1305 &(pStubDesc
->pFormatTypes
[pParamOther
->type_offset
]);
1307 TRACE("\tcomplex type 0x%02x\n", *pTypeFormat
);
1311 case STUBLESS_MARSHAL
:
1312 if (pParam
->param_attributes
.IsOut
|| pParam
->param_attributes
.IsReturn
)
1314 if (pParam
->param_attributes
.IsByValue
)
1315 call_marshaller(&stubMsg
, pArg
, pTypeFormat
);
1318 call_marshaller(&stubMsg
, *(unsigned char **)pArg
, pTypeFormat
);
1319 stubMsg
.pfnFree(*(void **)pArg
);
1322 /* FIXME: call call_freer here for IN types */
1324 case STUBLESS_UNMARSHAL
:
1325 if (pParam
->param_attributes
.IsIn
)
1327 if (pParam
->param_attributes
.IsByValue
)
1328 call_unmarshaller(&stubMsg
, &pArg
, pTypeFormat
, 0);
1330 call_unmarshaller(&stubMsg
, (unsigned char **)pArg
, pTypeFormat
, 0);
1332 else if (pParam
->param_attributes
.IsOut
&&
1333 !pParam
->param_attributes
.IsByValue
)
1335 *(void **)pArg
= NdrAllocate(&stubMsg
, sizeof(void *));
1336 **(void ***)pArg
= 0;
1339 case STUBLESS_CALCSIZE
:
1340 if (pParam
->param_attributes
.IsOut
|| pParam
->param_attributes
.IsReturn
)
1342 if (pParam
->param_attributes
.IsByValue
)
1343 call_buffer_sizer(&stubMsg
, pArg
, pTypeFormat
);
1345 call_buffer_sizer(&stubMsg
, *(unsigned char **)pArg
, pTypeFormat
);
1349 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
1352 current_offset
+= sizeof(NDR_PARAM_OIF_OTHER
);
1354 TRACE("\tmemory addr (after): %p -> %p\n", pArg
, *(unsigned char **)pArg
);
1356 else /* old parameter format */
1358 NDR_PARAM_OI_BASETYPE
*pParam
=
1359 (NDR_PARAM_OI_BASETYPE
*)&pFormat
[current_offset
];
1360 unsigned char *pArg
= (unsigned char *)(args
+current_stack_offset
);
1362 /* no more parameters; exit loop */
1363 if (current_stack_offset
> stack_size
)
1366 TRACE("param[%d]: old format\n\tparam_direction: 0x%x\n", i
, pParam
->param_direction
);
1368 if (pParam
->param_direction
== RPC_FC_IN_PARAM_BASETYPE
||
1369 pParam
->param_direction
== RPC_FC_RETURN_PARAM_BASETYPE
)
1371 const unsigned char *pTypeFormat
=
1372 &pParam
->type_format_char
;
1374 TRACE("\tbase type 0x%02x\n", *pTypeFormat
);
1378 case STUBLESS_MARSHAL
:
1379 if (pParam
->param_direction
== RPC_FC_RETURN_PARAM_BASETYPE
)
1380 call_marshaller(&stubMsg
, pArg
, pTypeFormat
);
1382 case STUBLESS_UNMARSHAL
:
1383 if (pParam
->param_direction
== RPC_FC_IN_PARAM_BASETYPE
)
1384 call_unmarshaller(&stubMsg
, &pArg
, pTypeFormat
, 0);
1386 case STUBLESS_CALCSIZE
:
1387 if (pParam
->param_direction
== RPC_FC_RETURN_PARAM_BASETYPE
)
1388 call_buffer_sizer(&stubMsg
, pArg
, pTypeFormat
);
1391 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
1394 current_stack_offset
+= call_memory_sizer(&stubMsg
, pTypeFormat
);
1395 current_offset
+= sizeof(NDR_PARAM_OI_BASETYPE
);
1399 NDR_PARAM_OI_OTHER
* pParamOther
=
1400 (NDR_PARAM_OI_OTHER
*)&pFormat
[current_offset
];
1402 const unsigned char * pTypeFormat
=
1403 &pStubDesc
->pFormatTypes
[pParamOther
->type_offset
];
1405 TRACE("\tcomplex type 0x%02x\n", *pTypeFormat
);
1409 case STUBLESS_MARSHAL
:
1410 if (pParam
->param_direction
== RPC_FC_OUT_PARAM
||
1411 pParam
->param_direction
== RPC_FC_IN_OUT_PARAM
||
1412 pParam
->param_direction
== RPC_FC_RETURN_PARAM
)
1413 call_marshaller(&stubMsg
, pArg
, pTypeFormat
);
1415 case STUBLESS_UNMARSHAL
:
1416 if (pParam
->param_direction
== RPC_FC_IN_OUT_PARAM
||
1417 pParam
->param_direction
== RPC_FC_IN_PARAM
)
1418 call_unmarshaller(&stubMsg
, &pArg
, pTypeFormat
, 0);
1420 case STUBLESS_CALCSIZE
:
1421 if (pParam
->param_direction
== RPC_FC_OUT_PARAM
||
1422 pParam
->param_direction
== RPC_FC_IN_OUT_PARAM
||
1423 pParam
->param_direction
== RPC_FC_RETURN_PARAM
)
1424 call_buffer_sizer(&stubMsg
, pArg
, pTypeFormat
);
1427 RpcRaiseException(RPC_S_INTERNAL_ERROR
);
1430 current_stack_offset
+= pParamOther
->stack_size
* sizeof(INT
);
1431 current_offset
+= sizeof(NDR_PARAM_OI_OTHER
);
1438 ERR("shouldn't reach here. phase %d\n", phase
);
1443 pRpcMsg
->BufferLength
= (unsigned int)(stubMsg
.Buffer
- (unsigned char *)pRpcMsg
->Buffer
);
1445 if (ext_flags
& RPC_FC_PROC_EXT_NEWCORRDESC
)
1447 /* free extra correlation package */
1448 /* NdrCorrelationFree(&stubMsg); */
1451 if (Oif_flags
& RPC_FC_PROC_OI2F_HASPIPES
)
1453 /* NdrPipesDone(...) */
1457 /* free the full pointer translation tables */
1458 if (pProcHeader
->Oi_flags
& RPC_FC_PROC_OIF_FULLPTR
)
1459 NdrFullPointerXlatFree(stubMsg
.FullPtrXlatTables
);
1462 /* free server function stack */
1463 HeapFree(GetProcessHeap(), 0, args
);
1468 void WINAPI
NdrServerCall2(PRPC_MESSAGE pRpcMsg
)
1471 NdrStubCall2(NULL
, NULL
, pRpcMsg
, &dwPhase
);