User-supplied routines

The routines required by user_marshall have the following prototypes.

<type_name> means a user specific type name. This may be non-RPC-able type or even, when used with user_marshal, a type unknown to MIDL at all. The wire type name (the name of transmissible type) is not used here.


unsigned long __RPC_USER  <type_name>_UserSize(
   unsigned long __RPC_FAR *   pFlags,
   unsigned long           StartingSize,
   <type_name>  __RPC_FAR *    pFoo);

unsigned char __RPC_FAR * __RPC_USER  <type_name>_UserMarshal(
   unsigned long    __RPC_FAR *   pFlags,
   unsigned char __RPC_FAR *     Buffer,
   <type_name>  __RPC_FAR *    pFoo);

unsigned char __RPC_FAR * __RPC_USER  <type_name>_UserUnmarshal(
   unsigned long    __RPC_FAR *   pFlags,
   unsigned char __RPC_FAR *       Buffer,
   <type_name>  __RPC_FAR *   pFoo);

void __RPC_USER  <type_name>_UserFree(
   unsigned long    __RPC_FAR *   pFlags,
   <type_name>  __RPC_FAR *   pFoo );

The meaning of the arguments is as follows:

The return value when sizing, marshaling or unmarshaling is the new offset or buffer position. See the function description below for details.

The flags pointed to by the first argument have the following layout.

31

24

16

8

4

0

Floating point

Int

Char

MSHCTX flags

Ndr data representation

Marshal context flags



typedef 
enum tagMSHCTX
    {   MSHCTX_LOCAL      = 0,
      MSHCTX_NOSHAREDMEM   = 1,
      MSHCTX_DIFFERENTMACHINE = 2,
      MSHCTX_INPROC      = 3
    } MSHCTX;

The flags make it possible to differ the behavior of the routines depending on the context for the RPC call. For example when a handle is remoted in-process it could be sent as a handle (a long), while sending it remotely would mean sending the data related to the handle.