4 * Copyright 2002 Greg Turner
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 * - figure out whether we *really* got this right
22 * - check for errors and throw exceptions
36 #include "wine/rpcfc.h"
37 #include "wine/obj_base.h"
39 #include "wine/debug.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
43 #define BUFFER_PARANOIA 20
46 #define LITTLE_ENDIAN_32_WRITE(pchar, word32) \
47 (*((UINT32 *)(pchar)) = (word32))
49 #define LITTLE_ENDIAN_32_READ(pchar) \
50 (*((UINT32 *)(pchar)))
52 /* these would work for i386 too, but less efficient */
53 #define LITTLE_ENDIAN_32_WRITE(pchar, word32) \
54 (*(pchar) = LOBYTE(LOWORD(word32)), \
55 *((pchar)+1) = HIBYTE(LOWORD(word32)), \
56 *((pchar)+2) = LOBYTE(HIWORD(word32)), \
57 *((pchar)+3) = HIBYTE(HIWORD(word32)), \
58 (word32)) /* allow as r-value */
60 #define LITTLE_ENDIAN_32_READ(pchar) \
62 MAKEWORD(*(pchar), *((pchar)+1)) \
63 MAKEWORD(*((pchar)+2), *((pchar)+3)))
67 * NdrConformantString:
69 * What MS calls a ConformantString is, in DCE terminology,
70 * a Varying Conformant String.
72 * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0')
73 * offset: DWORD (actual elements begin at (offset) CHARTYPE's into (data))
74 * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
76 * data: CHARTYPE[maxlen]
78 * ], where CHARTYPE is the appropriate character type (specified externally)
82 /***********************************************************************
83 * NdrConformantStringMarshall [RPCRT4.@]
85 unsigned char *WINAPI
NdrConformantStringMarshall(MIDL_STUB_MESSAGE
*pStubMsg
, unsigned char *pszMessage
,
86 PFORMAT_STRING pFormat
)
91 TRACE("(pStubMsg == ^%p, pszMessage == ^%p, pFormat == ^%p)\n", pStubMsg
, pszMessage
, pFormat
);
94 if (*pFormat
== RPC_FC_C_CSTRING
) {
95 len
= strlen(pszMessage
);
96 assert( (pStubMsg
->BufferLength
> (len
+ 13)) && (pStubMsg
->Buffer
!= NULL
) );
99 LITTLE_ENDIAN_32_WRITE(c
, len
+ 1); /* max length: strlen + 1 (for '\0') */
100 c
+= 8; /* offset: 0 */
101 LITTLE_ENDIAN_32_WRITE(c
, len
+ 1); /* actual length: (same) */
103 for (i
= 0; i
<= len
; i
++)
104 *(c
++) = *(pszMessage
++); /* the string itself */
106 ERR("Unhandled string type: %#x\n", *pFormat
);
107 /* FIXME: raise an exception. */
112 pStubMsg
->fBufferValid
= 1;
113 return NULL
; /* is this always right? */
116 /***********************************************************************
117 * NdrConformantStringBufferSize [RPCRT4.@]
119 void WINAPI
NdrConformantStringBufferSize(PMIDL_STUB_MESSAGE pStubMsg
, unsigned char* pMemory
, PFORMAT_STRING pFormat
)
121 TRACE("(pStubMsg == ^%p, pMemory == ^%p, pFormat == ^%p)\n", pStubMsg
, pMemory
, pFormat
);
124 if (*pFormat
== RPC_FC_C_CSTRING
) {
125 /* we need 12 octets for the [maxlen, offset, len] DWORDS, + 1 octet for '\0' */
126 pStubMsg
->BufferLength
= strlen(pMemory
) + 13 + BUFFER_PARANOIA
;
128 ERR("Unhandled string type: %#x\n", *pFormat
);
129 /* FIXME: raise an exception */
133 /************************************************************************
134 * NdrConformantStringMemorySize [RPCRT4.@]
136 unsigned long WINAPI
NdrConformantStringMemorySize( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
138 unsigned long rslt
= 0;
140 TRACE("(pStubMsg == ^%p, pFormat == ^%p)\n", pStubMsg
, pFormat
);
142 assert(pStubMsg
&& pFormat
);
144 if (*pFormat
== RPC_FC_C_CSTRING
) {
145 rslt
= LITTLE_ENDIAN_32_READ(pStubMsg
->Buffer
); /* maxlen */
147 ERR("Unhandled string type: %#x\n", *pFormat
);
148 /* FIXME: raise an exception */
151 TRACE(" --> %lu\n", rslt
);
155 /************************************************************************
156 * NdrConformantStringUnmarshall [RPCRT4.@]
158 unsigned char *WINAPI
NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
, unsigned char** ppMemory
,
159 PFORMAT_STRING pFormat
, unsigned char fMustAlloc
)
161 unsigned long len
, ofs
;
163 TRACE("(pStubMsg == ^%p, *pMemory == ^%p, pFormat == ^%p, fMustAlloc == %u)\n",
164 pStubMsg
, *ppMemory
, pFormat
, fMustAlloc
);
166 assert(pFormat
&& ppMemory
&& pStubMsg
);
168 len
= NdrConformantStringMemorySize(pStubMsg
, pFormat
);
170 /* now the actual length (in bytes) that we need to store
171 the unmarshalled string is in len, including terminating '\0' */
173 if ( fMustAlloc
|| (!(*ppMemory
)) || (pStubMsg
->Memory
!= *ppMemory
) ||
174 (pStubMsg
->MemorySize
< (len
+BUFFER_PARANOIA
)) ) {
175 /* crap, looks like we need to do something about the Memory. I don't
176 understand, it doesn't look like Microsoft is doing this the same
177 way... but then how do they do it? AFAICS the Memory is never deallocated by
178 the stub code so where does it go?... anyhow, I guess we'll just do it
179 our own way for now... */
180 pStubMsg
->MemorySize
= len
+ BUFFER_PARANOIA
;
181 pStubMsg
->Memory
= *ppMemory
;
182 /* FIXME: pfnAllocate? or does that not apply to these "Memory" parts? */
183 *ppMemory
= pStubMsg
->Memory
= HeapReAlloc(GetProcessHeap(), 0, pStubMsg
->Memory
, pStubMsg
->MemorySize
);
186 if (!(pStubMsg
->Memory
)) {
187 ERR("Memory Allocation Failure\n");
188 /* FIXME: raise an exception */
192 /* OK, we've got our ram. now do the real unmarshalling */
193 if (*pFormat
== RPC_FC_C_CSTRING
) {
196 pStubMsg
->Buffer
+= 4;
197 ofs
= LITTLE_ENDIAN_32_READ(pStubMsg
->Buffer
);
198 pStubMsg
->Buffer
+= 4;
199 len
= LITTLE_ENDIAN_32_READ(pStubMsg
->Buffer
);
200 pStubMsg
->Buffer
+= 4;
202 pStubMsg
->Buffer
+= ofs
;
204 while ((*c
++ = *(pStubMsg
->Buffer
++)) != '\0')
207 ERR("Unhandled string type: %#x\n", *pFormat
);
208 /* FIXME: raise an exception */
211 return NULL
; /* FIXME: is this always right? */
214 /***********************************************************************
215 * NdrConvert [RPCRT4.@]
217 void WINAPI
NdrConvert( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
)
219 FIXME("(pStubMsg == ^%p, pFormat == ^%p): stub.\n", pStubMsg
, pFormat
);
220 /* FIXME: since this stub doesn't do any converting, the proper behavior
221 is to raise an exception */
224 /***********************************************************************
225 * NdrConvert2 [RPCRT4.@]
227 void WINAPI
NdrConvert2( PMIDL_STUB_MESSAGE pStubMsg
, PFORMAT_STRING pFormat
, long NumberParams
)
229 FIXME("(pStubMsg == ^%p, pFormat == ^%p, NumberParams == %ld): stub.\n", pStubMsg
, pFormat
, NumberParams
);
230 /* FIXME: since this stub doesn't do any converting, the proper behavior
231 is to raise an exception */