4 * Copyright 2001 Ove Kåven, TransGaming Technologies
5 * Copyright 2003 Mike Hearn
6 * Copyright 2004 Filip Navara
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
37 #include "wine/unicode.h"
42 #include "wine/debug.h"
44 #include "rpc_binding.h"
45 #include "rpc_message.h"
47 WINE_DEFAULT_DEBUG_CHANNEL(rpc
);
49 LPSTR
RPCRT4_strndupA(LPCSTR src
, INT slen
)
53 if (!src
) return NULL
;
54 if (slen
== -1) slen
= strlen(src
);
56 s
= HeapAlloc(GetProcessHeap(), 0, len
+1);
62 LPSTR
RPCRT4_strdupWtoA(LPWSTR src
)
66 if (!src
) return NULL
;
67 len
= WideCharToMultiByte(CP_ACP
, 0, src
, -1, NULL
, 0, NULL
, NULL
);
68 s
= HeapAlloc(GetProcessHeap(), 0, len
);
69 WideCharToMultiByte(CP_ACP
, 0, src
, -1, s
, len
, NULL
, NULL
);
73 LPWSTR
RPCRT4_strdupAtoW(LPSTR src
)
77 if (!src
) return NULL
;
78 len
= MultiByteToWideChar(CP_ACP
, 0, src
, -1, NULL
, 0);
79 s
= HeapAlloc(GetProcessHeap(), 0, len
*sizeof(WCHAR
));
80 MultiByteToWideChar(CP_ACP
, 0, src
, -1, s
, len
);
84 LPWSTR
RPCRT4_strndupW(LPWSTR src
, INT slen
)
88 if (!src
) return NULL
;
89 if (slen
== -1) slen
= strlenW(src
);
91 s
= HeapAlloc(GetProcessHeap(), 0, (len
+1)*sizeof(WCHAR
));
92 memcpy(s
, src
, len
*sizeof(WCHAR
));
97 void RPCRT4_strfree(LPSTR src
)
99 HeapFree(GetProcessHeap(), 0, src
);
102 static RPC_STATUS
RPCRT4_AllocBinding(RpcBinding
** Binding
, BOOL server
)
104 RpcBinding
* NewBinding
;
106 NewBinding
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(RpcBinding
));
107 NewBinding
->refs
= 1;
108 NewBinding
->server
= server
;
110 *Binding
= NewBinding
;
115 RPC_STATUS
RPCRT4_CreateBindingA(RpcBinding
** Binding
, BOOL server
, LPSTR Protseq
)
117 RpcBinding
* NewBinding
;
119 RPCRT4_AllocBinding(&NewBinding
, server
);
120 NewBinding
->Protseq
= RPCRT4_strdupA(Protseq
);
122 TRACE("binding: %p\n", NewBinding
);
123 *Binding
= NewBinding
;
128 RPC_STATUS
RPCRT4_CreateBindingW(RpcBinding
** Binding
, BOOL server
, LPWSTR Protseq
)
130 RpcBinding
* NewBinding
;
132 RPCRT4_AllocBinding(&NewBinding
, server
);
133 NewBinding
->Protseq
= RPCRT4_strdupWtoA(Protseq
);
135 TRACE("binding: %p\n", NewBinding
);
136 *Binding
= NewBinding
;
141 RPC_STATUS
RPCRT4_CompleteBindingA(RpcBinding
* Binding
, LPSTR NetworkAddr
, LPSTR Endpoint
, LPSTR NetworkOptions
)
143 TRACE("(RpcBinding == ^%p, NetworkAddr == \"%s\", EndPoint == \"%s\", NetworkOptions == \"%s\")\n", Binding
,
144 debugstr_a(NetworkAddr
), debugstr_a(Endpoint
), debugstr_a(NetworkOptions
));
146 RPCRT4_strfree(Binding
->NetworkAddr
);
147 Binding
->NetworkAddr
= RPCRT4_strdupA(NetworkAddr
);
148 RPCRT4_strfree(Binding
->Endpoint
);
150 Binding
->Endpoint
= RPCRT4_strdupA(Endpoint
);
152 Binding
->Endpoint
= RPCRT4_strdupA("");
154 if (!Binding
->Endpoint
) ERR("out of memory?\n");
159 RPC_STATUS
RPCRT4_CompleteBindingW(RpcBinding
* Binding
, LPWSTR NetworkAddr
, LPWSTR Endpoint
, LPWSTR NetworkOptions
)
161 TRACE("(RpcBinding == ^%p, NetworkAddr == \"%s\", EndPoint == \"%s\", NetworkOptions == \"%s\")\n", Binding
,
162 debugstr_w(NetworkAddr
), debugstr_w(Endpoint
), debugstr_w(NetworkOptions
));
164 RPCRT4_strfree(Binding
->NetworkAddr
);
165 Binding
->NetworkAddr
= RPCRT4_strdupWtoA(NetworkAddr
);
166 RPCRT4_strfree(Binding
->Endpoint
);
168 Binding
->Endpoint
= RPCRT4_strdupWtoA(Endpoint
);
170 Binding
->Endpoint
= RPCRT4_strdupA("");
172 if (!Binding
->Endpoint
) ERR("out of memory?\n");
177 RPC_STATUS
RPCRT4_ResolveBinding(RpcBinding
* Binding
, LPSTR Endpoint
)
179 TRACE("(RpcBinding == ^%p, EndPoint == \"%s\"\n", Binding
, Endpoint
);
181 RPCRT4_strfree(Binding
->Endpoint
);
182 Binding
->Endpoint
= RPCRT4_strdupA(Endpoint
);
187 RPC_STATUS
RPCRT4_SetBindingObject(RpcBinding
* Binding
, UUID
* ObjectUuid
)
189 TRACE("(*RpcBinding == ^%p, UUID == %s)\n", Binding
, debugstr_guid(ObjectUuid
));
190 if (ObjectUuid
) memcpy(&Binding
->ObjectUuid
, ObjectUuid
, sizeof(UUID
));
191 else UuidCreateNil(&Binding
->ObjectUuid
);
195 RPC_STATUS
RPCRT4_MakeBinding(RpcBinding
** Binding
, RpcConnection
* Connection
)
197 RpcBinding
* NewBinding
;
198 TRACE("(RpcBinding == ^%p, Connection == ^%p)\n", Binding
, Connection
);
200 RPCRT4_AllocBinding(&NewBinding
, Connection
->server
);
201 NewBinding
->Protseq
= RPCRT4_strdupA(rpcrt4_conn_get_name(Connection
));
202 NewBinding
->NetworkAddr
= RPCRT4_strdupA(Connection
->NetworkAddr
);
203 NewBinding
->Endpoint
= RPCRT4_strdupA(Connection
->Endpoint
);
204 NewBinding
->FromConn
= Connection
;
206 TRACE("binding: %p\n", NewBinding
);
207 *Binding
= NewBinding
;
212 RPC_STATUS
RPCRT4_ExportBinding(RpcBinding
** Binding
, RpcBinding
* OldBinding
)
214 InterlockedIncrement(&OldBinding
->refs
);
215 *Binding
= OldBinding
;
219 RPC_STATUS
RPCRT4_DestroyBinding(RpcBinding
* Binding
)
221 if (InterlockedDecrement(&Binding
->refs
))
224 TRACE("binding: %p\n", Binding
);
225 /* FIXME: release connections */
226 RPCRT4_strfree(Binding
->Endpoint
);
227 RPCRT4_strfree(Binding
->NetworkAddr
);
228 RPCRT4_strfree(Binding
->Protseq
);
229 HeapFree(GetProcessHeap(), 0, Binding
);
233 RPC_STATUS
RPCRT4_OpenBinding(RpcBinding
* Binding
, RpcConnection
** Connection
,
234 PRPC_SYNTAX_IDENTIFIER TransferSyntax
,
235 PRPC_SYNTAX_IDENTIFIER InterfaceId
)
237 RpcConnection
* NewConnection
;
240 TRACE("(Binding == ^%p)\n", Binding
);
242 /* if we try to bind a new interface and the connection is already opened,
243 * close the current connection and create a new with the new binding. */
244 if (!Binding
->server
&& Binding
->FromConn
&&
245 memcmp(&Binding
->FromConn
->ActiveInterface
, InterfaceId
,
246 sizeof(RPC_SYNTAX_IDENTIFIER
))) {
248 TRACE("releasing pre-existing connection\n");
249 RPCRT4_DestroyConnection(Binding
->FromConn
);
250 Binding
->FromConn
= NULL
;
252 /* we already have a connection with acceptable binding, so use it */
253 if (Binding
->FromConn
) {
254 *Connection
= Binding
->FromConn
;
259 /* create a new connection */
260 RPCRT4_CreateConnection(&NewConnection
, Binding
->server
, Binding
->Protseq
, Binding
->NetworkAddr
, Binding
->Endpoint
, NULL
, Binding
);
261 *Connection
= NewConnection
;
262 status
= RPCRT4_OpenConnection(NewConnection
);
263 if (status
!= RPC_S_OK
) {
267 /* we need to send a binding packet if we are client. */
268 if (!(*Connection
)->server
) {
272 RpcPktHdr
*response_hdr
;
274 TRACE("sending bind request to server\n");
276 hdr
= RPCRT4_BuildBindHeader(NDR_LOCAL_DATA_REPRESENTATION
,
277 RPC_MAX_PACKET_SIZE
, RPC_MAX_PACKET_SIZE
,
278 InterfaceId
, TransferSyntax
);
280 status
= RPCRT4_Send(*Connection
, hdr
, NULL
, 0);
281 RPCRT4_FreeHeader(hdr
);
282 if (status
!= RPC_S_OK
) {
283 RPCRT4_DestroyConnection(*Connection
);
287 response
= HeapAlloc(GetProcessHeap(), 0, RPC_MAX_PACKET_SIZE
);
288 if (response
== NULL
) {
289 WARN("Can't allocate memory for binding response\n");
290 RPCRT4_DestroyConnection(*Connection
);
291 return E_OUTOFMEMORY
;
294 count
= rpcrt4_conn_read(NewConnection
, response
, RPC_MAX_PACKET_SIZE
);
295 if (count
< sizeof(response_hdr
->common
)) {
296 WARN("received invalid header\n");
297 HeapFree(GetProcessHeap(), 0, response
);
298 RPCRT4_DestroyConnection(*Connection
);
299 return RPC_S_PROTOCOL_ERROR
;
302 response_hdr
= (RpcPktHdr
*)response
;
304 if (response_hdr
->common
.rpc_ver
!= RPC_VER_MAJOR
||
305 response_hdr
->common
.rpc_ver_minor
!= RPC_VER_MINOR
||
306 response_hdr
->common
.ptype
!= PKT_BIND_ACK
) {
307 WARN("invalid protocol version or rejection packet\n");
308 HeapFree(GetProcessHeap(), 0, response
);
309 RPCRT4_DestroyConnection(*Connection
);
310 return RPC_S_PROTOCOL_ERROR
;
313 if (response_hdr
->bind_ack
.max_tsize
< RPC_MIN_PACKET_SIZE
) {
314 WARN("server doesn't allow large enough packets\n");
315 HeapFree(GetProcessHeap(), 0, response
);
316 RPCRT4_DestroyConnection(*Connection
);
317 return RPC_S_PROTOCOL_ERROR
;
320 /* FIXME: do more checks? */
322 (*Connection
)->MaxTransmissionSize
= response_hdr
->bind_ack
.max_tsize
;
323 (*Connection
)->ActiveInterface
= *InterfaceId
;
324 HeapFree(GetProcessHeap(), 0, response
);
330 RPC_STATUS
RPCRT4_CloseBinding(RpcBinding
* Binding
, RpcConnection
* Connection
)
332 TRACE("(Binding == ^%p)\n", Binding
);
333 if (!Connection
) return RPC_S_OK
;
334 if (Binding
->FromConn
== Connection
) return RPC_S_OK
;
335 return RPCRT4_DestroyConnection(Connection
);
338 /* utility functions for string composing and parsing */
339 static unsigned RPCRT4_strcopyA(LPSTR data
, LPCSTR src
)
341 unsigned len
= strlen(src
);
342 memcpy(data
, src
, len
*sizeof(CHAR
));
346 static unsigned RPCRT4_strcopyW(LPWSTR data
, LPCWSTR src
)
348 unsigned len
= strlenW(src
);
349 memcpy(data
, src
, len
*sizeof(WCHAR
));
353 static LPSTR
RPCRT4_strconcatA(LPSTR dst
, LPCSTR src
)
355 DWORD len
= strlen(dst
), slen
= strlen(src
);
356 LPSTR ndst
= HeapReAlloc(GetProcessHeap(), 0, dst
, (len
+slen
+2)*sizeof(CHAR
));
359 HeapFree(GetProcessHeap(), 0, dst
);
363 memcpy(ndst
+len
+1, src
, slen
+1);
367 static LPWSTR
RPCRT4_strconcatW(LPWSTR dst
, LPCWSTR src
)
369 DWORD len
= strlenW(dst
), slen
= strlenW(src
);
370 LPWSTR ndst
= HeapReAlloc(GetProcessHeap(), 0, dst
, (len
+slen
+2)*sizeof(WCHAR
));
373 HeapFree(GetProcessHeap(), 0, dst
);
377 memcpy(ndst
+len
+1, src
, (slen
+1)*sizeof(WCHAR
));
382 /***********************************************************************
383 * RpcStringBindingComposeA (RPCRT4.@)
385 RPC_STATUS WINAPI
RpcStringBindingComposeA(unsigned char *ObjUuid
, unsigned char *Protseq
,
386 unsigned char *NetworkAddr
, unsigned char *Endpoint
,
387 unsigned char *Options
, unsigned char** StringBinding
)
392 TRACE( "(%s,%s,%s,%s,%s,%p)\n",
393 debugstr_a( (char*)ObjUuid
), debugstr_a( (char*)Protseq
),
394 debugstr_a( (char*)NetworkAddr
), debugstr_a( (char*)Endpoint
),
395 debugstr_a( (char*)Options
), StringBinding
);
397 if (ObjUuid
&& *ObjUuid
) len
+= strlen((char*)ObjUuid
) + 1;
398 if (Protseq
&& *Protseq
) len
+= strlen((char*)Protseq
) + 1;
399 if (NetworkAddr
&& *NetworkAddr
) len
+= strlen((char*)NetworkAddr
);
400 if (Endpoint
&& *Endpoint
) len
+= strlen((char*)Endpoint
) + 2;
401 if (Options
&& *Options
) len
+= strlen((char*)Options
) + 2;
403 data
= HeapAlloc(GetProcessHeap(), 0, len
);
404 *StringBinding
= (unsigned char*)data
;
406 if (ObjUuid
&& *ObjUuid
) {
407 data
+= RPCRT4_strcopyA(data
, (char*)ObjUuid
);
410 if (Protseq
&& *Protseq
) {
411 data
+= RPCRT4_strcopyA(data
, (char*)Protseq
);
414 if (NetworkAddr
&& *NetworkAddr
)
415 data
+= RPCRT4_strcopyA(data
, (char*)NetworkAddr
);
417 if ((Endpoint
&& *Endpoint
) ||
418 (Options
&& *Options
)) {
420 if (Endpoint
&& *Endpoint
) {
421 data
+= RPCRT4_strcopyA(data
, (char*)Endpoint
);
422 if (Options
&& *Options
) *data
++ = ',';
424 if (Options
&& *Options
) {
425 data
+= RPCRT4_strcopyA(data
, (char*)Options
);
434 /***********************************************************************
435 * RpcStringBindingComposeW (RPCRT4.@)
437 RPC_STATUS WINAPI
RpcStringBindingComposeW( LPWSTR ObjUuid
, LPWSTR Protseq
,
438 LPWSTR NetworkAddr
, LPWSTR Endpoint
,
439 LPWSTR Options
, LPWSTR
* StringBinding
)
444 TRACE("(%s,%s,%s,%s,%s,%p)\n",
445 debugstr_w( ObjUuid
), debugstr_w( Protseq
),
446 debugstr_w( NetworkAddr
), debugstr_w( Endpoint
),
447 debugstr_w( Options
), StringBinding
);
449 if (ObjUuid
&& *ObjUuid
) len
+= strlenW(ObjUuid
) + 1;
450 if (Protseq
&& *Protseq
) len
+= strlenW(Protseq
) + 1;
451 if (NetworkAddr
&& *NetworkAddr
) len
+= strlenW(NetworkAddr
);
452 if (Endpoint
&& *Endpoint
) len
+= strlenW(Endpoint
) + 2;
453 if (Options
&& *Options
) len
+= strlenW(Options
) + 2;
455 data
= HeapAlloc(GetProcessHeap(), 0, len
*sizeof(WCHAR
));
456 *StringBinding
= data
;
458 if (ObjUuid
&& *ObjUuid
) {
459 data
+= RPCRT4_strcopyW(data
, ObjUuid
);
462 if (Protseq
&& *Protseq
) {
463 data
+= RPCRT4_strcopyW(data
, Protseq
);
466 if (NetworkAddr
&& *NetworkAddr
) {
467 data
+= RPCRT4_strcopyW(data
, NetworkAddr
);
469 if ((Endpoint
&& *Endpoint
) ||
470 (Options
&& *Options
)) {
472 if (Endpoint
&& *Endpoint
) {
473 data
+= RPCRT4_strcopyW(data
, Endpoint
);
474 if (Options
&& *Options
) *data
++ = ',';
476 if (Options
&& *Options
) {
477 data
+= RPCRT4_strcopyW(data
, Options
);
487 /***********************************************************************
488 * RpcStringBindingParseA (RPCRT4.@)
490 RPC_STATUS WINAPI
RpcStringBindingParseA( unsigned char *StringBinding
, unsigned char **ObjUuid
,
491 unsigned char **Protseq
, unsigned char **NetworkAddr
,
492 unsigned char **Endpoint
, unsigned char **Options
)
495 static const char ep_opt
[] = "endpoint=";
497 TRACE("(%s,%p,%p,%p,%p,%p)\n", debugstr_a((char*)StringBinding
),
498 ObjUuid
, Protseq
, NetworkAddr
, Endpoint
, Options
);
500 if (ObjUuid
) *ObjUuid
= NULL
;
501 if (Protseq
) *Protseq
= NULL
;
502 if (NetworkAddr
) *NetworkAddr
= NULL
;
503 if (Endpoint
) *Endpoint
= NULL
;
504 if (Options
) *Options
= NULL
;
506 data
= (char*) StringBinding
;
508 next
= strchr(data
, '@');
510 if (ObjUuid
) *ObjUuid
= (unsigned char*)RPCRT4_strndupA(data
, next
- data
);
514 next
= strchr(data
, ':');
516 if (Protseq
) *Protseq
= (unsigned char*)RPCRT4_strndupA(data
, next
- data
);
520 next
= strchr(data
, '[');
524 if (NetworkAddr
) *NetworkAddr
= (unsigned char*)RPCRT4_strndupA(data
, next
- data
);
526 close
= strchr(data
, ']');
527 if (!close
) goto fail
;
529 /* tokenize options */
530 while (data
< close
) {
531 next
= strchr(data
, ',');
532 if (!next
|| next
> close
) next
= close
;
533 /* FIXME: this is kind of inefficient */
534 opt
= RPCRT4_strndupA(data
, next
- data
);
538 next
= strchr(opt
, '=');
540 /* not an option, must be an endpoint */
541 if (*Endpoint
) goto fail
;
542 *Endpoint
= (unsigned char*) opt
;
544 if (strncmp(opt
, ep_opt
, strlen(ep_opt
)) == 0) {
545 /* endpoint option */
546 if (*Endpoint
) goto fail
;
547 *Endpoint
= (unsigned char*) RPCRT4_strdupA(next
+1);
548 HeapFree(GetProcessHeap(), 0, opt
);
552 /* FIXME: this is kind of inefficient */
553 *Options
= (unsigned char*) RPCRT4_strconcatA( (char*)*Options
, opt
);
554 HeapFree(GetProcessHeap(), 0, opt
);
556 *Options
= (unsigned char*) opt
;
562 if (*data
) goto fail
;
564 else if (NetworkAddr
)
565 *NetworkAddr
= (unsigned char*)RPCRT4_strdupA(data
);
570 if (ObjUuid
) RpcStringFreeA((unsigned char**)ObjUuid
);
571 if (Protseq
) RpcStringFreeA((unsigned char**)Protseq
);
572 if (NetworkAddr
) RpcStringFreeA((unsigned char**)NetworkAddr
);
573 if (Endpoint
) RpcStringFreeA((unsigned char**)Endpoint
);
574 if (Options
) RpcStringFreeA((unsigned char**)Options
);
575 return RPC_S_INVALID_STRING_BINDING
;
578 /***********************************************************************
579 * RpcStringBindingParseW (RPCRT4.@)
581 RPC_STATUS WINAPI
RpcStringBindingParseW( LPWSTR StringBinding
, LPWSTR
*ObjUuid
,
582 LPWSTR
*Protseq
, LPWSTR
*NetworkAddr
,
583 LPWSTR
*Endpoint
, LPWSTR
*Options
)
586 static const WCHAR ep_opt
[] = {'e','n','d','p','o','i','n','t','=',0};
588 TRACE("(%s,%p,%p,%p,%p,%p)\n", debugstr_w(StringBinding
),
589 ObjUuid
, Protseq
, NetworkAddr
, Endpoint
, Options
);
591 if (ObjUuid
) *ObjUuid
= NULL
;
592 if (Protseq
) *Protseq
= NULL
;
593 if (NetworkAddr
) *NetworkAddr
= NULL
;
594 if (Endpoint
) *Endpoint
= NULL
;
595 if (Options
) *Options
= NULL
;
597 data
= StringBinding
;
599 next
= strchrW(data
, '@');
601 if (ObjUuid
) *ObjUuid
= RPCRT4_strndupW(data
, next
- data
);
605 next
= strchrW(data
, ':');
607 if (Protseq
) *Protseq
= RPCRT4_strndupW(data
, next
- data
);
611 next
= strchrW(data
, '[');
615 if (NetworkAddr
) *NetworkAddr
= RPCRT4_strndupW(data
, next
- data
);
617 close
= strchrW(data
, ']');
618 if (!close
) goto fail
;
620 /* tokenize options */
621 while (data
< close
) {
622 next
= strchrW(data
, ',');
623 if (!next
|| next
> close
) next
= close
;
624 /* FIXME: this is kind of inefficient */
625 opt
= RPCRT4_strndupW(data
, next
- data
);
629 next
= strchrW(opt
, '=');
631 /* not an option, must be an endpoint */
632 if (*Endpoint
) goto fail
;
635 if (strncmpW(opt
, ep_opt
, strlenW(ep_opt
)) == 0) {
636 /* endpoint option */
637 if (*Endpoint
) goto fail
;
638 *Endpoint
= RPCRT4_strdupW(next
+1);
639 HeapFree(GetProcessHeap(), 0, opt
);
643 /* FIXME: this is kind of inefficient */
644 *Options
= RPCRT4_strconcatW(*Options
, opt
);
645 HeapFree(GetProcessHeap(), 0, opt
);
653 if (*data
) goto fail
;
654 } else if (NetworkAddr
)
655 *NetworkAddr
= RPCRT4_strdupW(data
);
660 if (ObjUuid
) RpcStringFreeW(ObjUuid
);
661 if (Protseq
) RpcStringFreeW(Protseq
);
662 if (NetworkAddr
) RpcStringFreeW(NetworkAddr
);
663 if (Endpoint
) RpcStringFreeW(Endpoint
);
664 if (Options
) RpcStringFreeW(Options
);
665 return RPC_S_INVALID_STRING_BINDING
;
668 /***********************************************************************
669 * RpcBindingFree (RPCRT4.@)
671 RPC_STATUS WINAPI
RpcBindingFree( RPC_BINDING_HANDLE
* Binding
)
674 TRACE("(%p) = %p\n", Binding
, *Binding
);
675 status
= RPCRT4_DestroyBinding(*Binding
);
676 if (status
== RPC_S_OK
) *Binding
= 0;
680 /***********************************************************************
681 * RpcBindingVectorFree (RPCRT4.@)
683 RPC_STATUS WINAPI
RpcBindingVectorFree( RPC_BINDING_VECTOR
** BindingVector
)
688 TRACE("(%p)\n", BindingVector
);
689 for (c
=0; c
<(*BindingVector
)->Count
; c
++) {
690 status
= RpcBindingFree(&(*BindingVector
)->BindingH
[c
]);
692 HeapFree(GetProcessHeap(), 0, *BindingVector
);
693 *BindingVector
= NULL
;
697 /***********************************************************************
698 * RpcBindingInqObject (RPCRT4.@)
700 RPC_STATUS WINAPI
RpcBindingInqObject( RPC_BINDING_HANDLE Binding
, UUID
* ObjectUuid
)
702 RpcBinding
* bind
= (RpcBinding
*)Binding
;
704 TRACE("(%p,%p) = %s\n", Binding
, ObjectUuid
, debugstr_guid(&bind
->ObjectUuid
));
705 memcpy(ObjectUuid
, &bind
->ObjectUuid
, sizeof(UUID
));
709 /***********************************************************************
710 * RpcBindingSetObject (RPCRT4.@)
712 RPC_STATUS WINAPI
RpcBindingSetObject( RPC_BINDING_HANDLE Binding
, UUID
* ObjectUuid
)
714 RpcBinding
* bind
= (RpcBinding
*)Binding
;
716 TRACE("(%p,%s)\n", Binding
, debugstr_guid(ObjectUuid
));
717 if (bind
->server
) return RPC_S_WRONG_KIND_OF_BINDING
;
718 return RPCRT4_SetBindingObject(Binding
, ObjectUuid
);
721 /***********************************************************************
722 * RpcBindingFromStringBindingA (RPCRT4.@)
724 RPC_STATUS WINAPI
RpcBindingFromStringBindingA( unsigned char *StringBinding
, RPC_BINDING_HANDLE
* Binding
)
727 RpcBinding
* bind
= NULL
;
728 unsigned char *ObjectUuid
, *Protseq
, *NetworkAddr
, *Endpoint
, *Options
;
731 TRACE("(%s,%p)\n", debugstr_a((char*)StringBinding
), Binding
);
733 ret
= RpcStringBindingParseA(StringBinding
, &ObjectUuid
, &Protseq
,
734 &NetworkAddr
, &Endpoint
, &Options
);
735 if (ret
!= RPC_S_OK
) return ret
;
737 ret
= UuidFromStringA(ObjectUuid
, &Uuid
);
740 ret
= RPCRT4_CreateBindingA(&bind
, FALSE
, (char*)Protseq
);
742 ret
= RPCRT4_SetBindingObject(bind
, &Uuid
);
744 ret
= RPCRT4_CompleteBindingA(bind
, (char*)NetworkAddr
, (char*)Endpoint
, (char*)Options
);
746 RpcStringFreeA((unsigned char**)&Options
);
747 RpcStringFreeA((unsigned char**)&Endpoint
);
748 RpcStringFreeA((unsigned char**)&NetworkAddr
);
749 RpcStringFreeA((unsigned char**)&Protseq
);
750 RpcStringFreeA((unsigned char**)&ObjectUuid
);
753 *Binding
= (RPC_BINDING_HANDLE
)bind
;
755 RPCRT4_DestroyBinding(bind
);
760 /***********************************************************************
761 * RpcBindingFromStringBindingW (RPCRT4.@)
763 RPC_STATUS WINAPI
RpcBindingFromStringBindingW( LPWSTR StringBinding
, RPC_BINDING_HANDLE
* Binding
)
766 RpcBinding
* bind
= NULL
;
767 LPWSTR ObjectUuid
, Protseq
, NetworkAddr
, Endpoint
, Options
;
770 TRACE("(%s,%p)\n", debugstr_w(StringBinding
), Binding
);
772 ret
= RpcStringBindingParseW(StringBinding
, &ObjectUuid
, &Protseq
,
773 &NetworkAddr
, &Endpoint
, &Options
);
774 if (ret
!= RPC_S_OK
) return ret
;
776 ret
= UuidFromStringW(ObjectUuid
, &Uuid
);
779 ret
= RPCRT4_CreateBindingW(&bind
, FALSE
, Protseq
);
781 ret
= RPCRT4_SetBindingObject(bind
, &Uuid
);
783 ret
= RPCRT4_CompleteBindingW(bind
, NetworkAddr
, Endpoint
, Options
);
785 RpcStringFreeW(&Options
);
786 RpcStringFreeW(&Endpoint
);
787 RpcStringFreeW(&NetworkAddr
);
788 RpcStringFreeW(&Protseq
);
789 RpcStringFreeW(&ObjectUuid
);
792 *Binding
= (RPC_BINDING_HANDLE
)bind
;
794 RPCRT4_DestroyBinding(bind
);
799 /***********************************************************************
800 * RpcBindingToStringBindingA (RPCRT4.@)
802 RPC_STATUS WINAPI
RpcBindingToStringBindingA( RPC_BINDING_HANDLE Binding
, unsigned char** StringBinding
)
805 RpcBinding
* bind
= (RpcBinding
*)Binding
;
808 TRACE("(%p,%p)\n", Binding
, StringBinding
);
810 ret
= UuidToStringA(&bind
->ObjectUuid
, (unsigned char**)&ObjectUuid
);
811 if (ret
!= RPC_S_OK
) return ret
;
813 ret
= RpcStringBindingComposeA((unsigned char*) ObjectUuid
, (unsigned char*)bind
->Protseq
, (unsigned char*) bind
->NetworkAddr
,
814 (unsigned char*) bind
->Endpoint
, NULL
, StringBinding
);
816 RpcStringFreeA((unsigned char**)&ObjectUuid
);
821 /***********************************************************************
822 * RpcBindingToStringBindingW (RPCRT4.@)
824 RPC_STATUS WINAPI
RpcBindingToStringBindingW( RPC_BINDING_HANDLE Binding
, unsigned short** StringBinding
)
827 unsigned char *str
= NULL
;
828 TRACE("(%p,%p)\n", Binding
, StringBinding
);
829 ret
= RpcBindingToStringBindingA(Binding
, &str
);
830 *StringBinding
= RPCRT4_strdupAtoW((char*)str
);
831 RpcStringFreeA((unsigned char**)&str
);
835 /***********************************************************************
836 * I_RpcBindingSetAsync (RPCRT4.@)
838 * Exists in win9x and winNT, but with different number of arguments
839 * (9x version has 3 arguments, NT has 2).
841 RPC_STATUS WINAPI
I_RpcBindingSetAsync( RPC_BINDING_HANDLE Binding
, RPC_BLOCKING_FN BlockingFn
)
843 RpcBinding
* bind
= (RpcBinding
*)Binding
;
845 TRACE( "(%p,%p): stub\n", Binding
, BlockingFn
);
847 bind
->BlockingFn
= BlockingFn
;
852 /***********************************************************************
853 * RpcNetworkIsProtseqValidA (RPCRT4.@)
855 RPC_STATUS WINAPI
RpcNetworkIsProtseqValidA(unsigned char *protseq
) {
856 UNICODE_STRING protseqW
;
858 if (!protseq
) return RPC_S_INVALID_RPC_PROTSEQ
; /* ? */
860 if (RtlCreateUnicodeStringFromAsciiz(&protseqW
, (char*)protseq
)) {
861 RPC_STATUS ret
= RpcNetworkIsProtseqValidW(protseqW
.Buffer
);
862 RtlFreeUnicodeString(&protseqW
);
864 } else return RPC_S_OUT_OF_MEMORY
;
867 /***********************************************************************
868 * RpcNetworkIsProtseqValidW (RPCRT4.@)
870 * Checks if the given protocol sequence is known by the RPC system.
871 * If it is, returns RPC_S_OK, otherwise RPC_S_PROTSEQ_NOT_SUPPORTED.
873 * We currently support:
874 * ncalrpc local-only rpc over LPC (LPC is not really used)
875 * ncacn_np rpc over named pipes
877 RPC_STATUS WINAPI
RpcNetworkIsProtseqValidW(LPWSTR protseq
) {
878 static const WCHAR protseqsW
[][15] = {
879 {'n','c','a','l','r','p','c',0},
880 {'n','c','a','c','n','_','n','p',0}
882 static const int count
= sizeof(protseqsW
) / sizeof(protseqsW
[0]);
885 if (!protseq
) return RPC_S_INVALID_RPC_PROTSEQ
; /* ? */
887 for (i
= 0; i
< count
; i
++) {
888 if (!strcmpW(protseq
, protseqsW
[i
])) return RPC_S_OK
;
891 FIXME("Unknown protseq %s - we probably need to implement it one day\n", debugstr_w(protseq
));
892 return RPC_S_PROTSEQ_NOT_SUPPORTED
;
895 /***********************************************************************
896 * RpcImpersonateClient (RPCRT4.@)
898 * Impersonates the client connected via a binding handle so that security
899 * checks are done in the context of the client.
902 * BindingHandle [I] Handle to the binding to the client.
906 * Failure: RPC_STATUS value.
910 * If BindingHandle is NULL then the function impersonates the client
911 * connected to the binding handle of the current thread.
913 RPC_STATUS WINAPI
RpcImpersonateClient(RPC_BINDING_HANDLE BindingHandle
)
915 FIXME("(%p): stub\n", BindingHandle
);
919 /***********************************************************************
920 * RpcRevertToSelfEx (RPCRT4.@)
922 * Stops impersonating the client connected to the binding handle so that security
923 * checks are no longer done in the context of the client.
926 * BindingHandle [I] Handle to the binding to the client.
930 * Failure: RPC_STATUS value.
934 * If BindingHandle is NULL then the function stops impersonating the client
935 * connected to the binding handle of the current thread.
937 RPC_STATUS WINAPI
RpcRevertToSelfEx(RPC_BINDING_HANDLE BindingHandle
)
939 FIXME("(%p): stub\n", BindingHandle
);
943 /***********************************************************************
944 * RpcBindingInqAuthInfoExA (RPCRT4.@)
946 RPCRTAPI RPC_STATUS RPC_ENTRY
947 RpcBindingInqAuthInfoExA( RPC_BINDING_HANDLE Binding
, unsigned char ** ServerPrincName
, unsigned long *AuthnLevel
,
948 unsigned long *AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE
*AuthIdentity
, unsigned long *AuthzSvc
,
949 unsigned long RpcQosVersion
, RPC_SECURITY_QOS
*SecurityQOS
)
951 FIXME("%p %p %p %p %p %p %lu %p\n", Binding
, ServerPrincName
, AuthnLevel
,
952 AuthnSvc
, AuthIdentity
, AuthzSvc
, RpcQosVersion
, SecurityQOS
);
953 return RPC_S_INVALID_BINDING
;
956 /***********************************************************************
957 * RpcBindingInqAuthInfoExW (RPCRT4.@)
959 RPCRTAPI RPC_STATUS RPC_ENTRY
960 RpcBindingInqAuthInfoExW( RPC_BINDING_HANDLE Binding
, unsigned short ** ServerPrincName
, unsigned long *AuthnLevel
,
961 unsigned long *AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE
*AuthIdentity
, unsigned long *AuthzSvc
,
962 unsigned long RpcQosVersion
, RPC_SECURITY_QOS
*SecurityQOS
)
964 FIXME("%p %p %p %p %p %p %lu %p\n", Binding
, ServerPrincName
, AuthnLevel
,
965 AuthnSvc
, AuthIdentity
, AuthzSvc
, RpcQosVersion
, SecurityQOS
);
966 return RPC_S_INVALID_BINDING
;
969 /***********************************************************************
970 * RpcBindingInqAuthInfoA (RPCRT4.@)
972 RPCRTAPI RPC_STATUS RPC_ENTRY
973 RpcBindingInqAuthInfoA( RPC_BINDING_HANDLE Binding
, unsigned char ** ServerPrincName
, unsigned long *AuthnLevel
,
974 unsigned long *AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE
*AuthIdentity
, unsigned long *AuthzSvc
)
976 FIXME("%p %p %p %p %p %p\n", Binding
, ServerPrincName
, AuthnLevel
,
977 AuthnSvc
, AuthIdentity
, AuthzSvc
);
978 return RPC_S_INVALID_BINDING
;
981 /***********************************************************************
982 * RpcBindingInqAuthInfoW (RPCRT4.@)
984 RPCRTAPI RPC_STATUS RPC_ENTRY
985 RpcBindingInqAuthInfoW( RPC_BINDING_HANDLE Binding
, unsigned short ** ServerPrincName
, unsigned long *AuthnLevel
,
986 unsigned long *AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE
*AuthIdentity
, unsigned long *AuthzSvc
)
988 FIXME("%p %p %p %p %p %p\n", Binding
, ServerPrincName
, AuthnLevel
,
989 AuthnSvc
, AuthIdentity
, AuthzSvc
);
990 return RPC_S_INVALID_BINDING
;
993 /***********************************************************************
994 * RpcBindingSetAuthInfoExA (RPCRT4.@)
996 RPCRTAPI RPC_STATUS RPC_ENTRY
997 RpcBindingSetAuthInfoExA( RPC_BINDING_HANDLE Binding
, unsigned char *ServerPrincName
,
998 unsigned long AuthnLevel
, unsigned long AuthnSvc
,
999 RPC_AUTH_IDENTITY_HANDLE AuthIdentity
, unsigned long AuthzSvr
,
1000 RPC_SECURITY_QOS
*SecurityQos
)
1002 FIXME("%p %s %lu %lu %p %lu %p\n", Binding
, debugstr_a((const char*)ServerPrincName
),
1003 AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
, SecurityQos
);
1007 /***********************************************************************
1008 * RpcBindingSetAuthInfoExW (RPCRT4.@)
1010 RPCRTAPI RPC_STATUS RPC_ENTRY
1011 RpcBindingSetAuthInfoExW( RPC_BINDING_HANDLE Binding
, unsigned short *ServerPrincName
, unsigned long AuthnLevel
,
1012 unsigned long AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE AuthIdentity
, unsigned long AuthzSvr
,
1013 RPC_SECURITY_QOS
*SecurityQos
)
1015 FIXME("%p %s %lu %lu %p %lu %p\n", Binding
, debugstr_w((const WCHAR
*)ServerPrincName
),
1016 AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
, SecurityQos
);
1020 /***********************************************************************
1021 * RpcBindingSetAuthInfoA (RPCRT4.@)
1023 RPCRTAPI RPC_STATUS RPC_ENTRY
1024 RpcBindingSetAuthInfoA( RPC_BINDING_HANDLE Binding
, unsigned char *ServerPrincName
, unsigned long AuthnLevel
,
1025 unsigned long AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE AuthIdentity
, unsigned long AuthzSvr
)
1027 FIXME("%p %s %lu %lu %p %lu\n", Binding
, debugstr_a((const char*)ServerPrincName
),
1028 AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
);
1032 /***********************************************************************
1033 * RpcBindingSetAuthInfoW (RPCRT4.@)
1035 RPCRTAPI RPC_STATUS RPC_ENTRY
1036 RpcBindingSetAuthInfoW( RPC_BINDING_HANDLE Binding
, unsigned short *ServerPrincName
, unsigned long AuthnLevel
,
1037 unsigned long AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE AuthIdentity
, unsigned long AuthzSvr
)
1039 FIXME("%p %s %lu %lu %p %lu\n", Binding
, debugstr_w((const WCHAR
*)ServerPrincName
),
1040 AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
);
1044 /***********************************************************************
1045 * RpcBindingSetOption (RPCRT4.@)
1047 RPC_STATUS WINAPI
RpcBindingSetOption(RPC_BINDING_HANDLE BindingHandle
, ULONG Option
, ULONG OptionValue
)
1049 FIXME("(%p, %ld, %ld): stub\n", BindingHandle
, Option
, OptionValue
);