4 * Copyright 2001 Ove Kåven, TransGaming Technologies
5 * Copyright 2003 Mike Hearn
6 * Copyright 2004 Filip Navara
7 * Copyright 2006 CodeWeavers
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
35 #include "wine/unicode.h"
40 #include "wine/debug.h"
42 #include "rpc_binding.h"
43 #include "rpc_message.h"
45 WINE_DEFAULT_DEBUG_CHANNEL(rpc
);
47 LPSTR
RPCRT4_strndupA(LPCSTR src
, INT slen
)
51 if (!src
) return NULL
;
52 if (slen
== -1) slen
= strlen(src
);
54 s
= HeapAlloc(GetProcessHeap(), 0, len
+1);
60 LPSTR
RPCRT4_strdupWtoA(LPWSTR src
)
64 if (!src
) return NULL
;
65 len
= WideCharToMultiByte(CP_ACP
, 0, src
, -1, NULL
, 0, NULL
, NULL
);
66 s
= HeapAlloc(GetProcessHeap(), 0, len
);
67 WideCharToMultiByte(CP_ACP
, 0, src
, -1, s
, len
, NULL
, NULL
);
71 LPWSTR
RPCRT4_strdupAtoW(LPSTR src
)
75 if (!src
) return NULL
;
76 len
= MultiByteToWideChar(CP_ACP
, 0, src
, -1, NULL
, 0);
77 s
= HeapAlloc(GetProcessHeap(), 0, len
*sizeof(WCHAR
));
78 MultiByteToWideChar(CP_ACP
, 0, src
, -1, s
, len
);
82 LPWSTR
RPCRT4_strndupW(LPWSTR src
, INT slen
)
86 if (!src
) return NULL
;
87 if (slen
== -1) slen
= strlenW(src
);
89 s
= HeapAlloc(GetProcessHeap(), 0, (len
+1)*sizeof(WCHAR
));
90 memcpy(s
, src
, len
*sizeof(WCHAR
));
95 void RPCRT4_strfree(LPSTR src
)
97 HeapFree(GetProcessHeap(), 0, src
);
100 static RPC_STATUS
RPCRT4_AllocBinding(RpcBinding
** Binding
, BOOL server
)
102 RpcBinding
* NewBinding
;
104 NewBinding
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(RpcBinding
));
105 NewBinding
->refs
= 1;
106 NewBinding
->server
= server
;
108 *Binding
= NewBinding
;
113 RPC_STATUS
RPCRT4_CreateBindingA(RpcBinding
** Binding
, BOOL server
, LPSTR Protseq
)
115 RpcBinding
* NewBinding
;
117 RPCRT4_AllocBinding(&NewBinding
, server
);
118 NewBinding
->Protseq
= RPCRT4_strdupA(Protseq
);
120 TRACE("binding: %p\n", NewBinding
);
121 *Binding
= NewBinding
;
126 RPC_STATUS
RPCRT4_CreateBindingW(RpcBinding
** Binding
, BOOL server
, LPWSTR Protseq
)
128 RpcBinding
* NewBinding
;
130 RPCRT4_AllocBinding(&NewBinding
, server
);
131 NewBinding
->Protseq
= RPCRT4_strdupWtoA(Protseq
);
133 TRACE("binding: %p\n", NewBinding
);
134 *Binding
= NewBinding
;
139 RPC_STATUS
RPCRT4_CompleteBindingA(RpcBinding
* Binding
, LPSTR NetworkAddr
, LPSTR Endpoint
, LPSTR NetworkOptions
)
141 TRACE("(RpcBinding == ^%p, NetworkAddr == %s, EndPoint == %s, NetworkOptions == %s)\n", Binding
,
142 debugstr_a(NetworkAddr
), debugstr_a(Endpoint
), debugstr_a(NetworkOptions
));
144 RPCRT4_strfree(Binding
->NetworkAddr
);
145 Binding
->NetworkAddr
= RPCRT4_strdupA(NetworkAddr
);
146 RPCRT4_strfree(Binding
->Endpoint
);
148 Binding
->Endpoint
= RPCRT4_strdupA(Endpoint
);
150 Binding
->Endpoint
= RPCRT4_strdupA("");
152 if (!Binding
->Endpoint
) ERR("out of memory?\n");
157 RPC_STATUS
RPCRT4_CompleteBindingW(RpcBinding
* Binding
, LPWSTR NetworkAddr
, LPWSTR Endpoint
, LPWSTR NetworkOptions
)
159 TRACE("(RpcBinding == ^%p, NetworkAddr == %s, EndPoint == %s, NetworkOptions == %s)\n", Binding
,
160 debugstr_w(NetworkAddr
), debugstr_w(Endpoint
), debugstr_w(NetworkOptions
));
162 RPCRT4_strfree(Binding
->NetworkAddr
);
163 Binding
->NetworkAddr
= RPCRT4_strdupWtoA(NetworkAddr
);
164 RPCRT4_strfree(Binding
->Endpoint
);
166 Binding
->Endpoint
= RPCRT4_strdupWtoA(Endpoint
);
168 Binding
->Endpoint
= RPCRT4_strdupA("");
170 if (!Binding
->Endpoint
) ERR("out of memory?\n");
175 RPC_STATUS
RPCRT4_ResolveBinding(RpcBinding
* Binding
, LPSTR Endpoint
)
177 TRACE("(RpcBinding == ^%p, EndPoint == \"%s\"\n", Binding
, Endpoint
);
179 RPCRT4_strfree(Binding
->Endpoint
);
180 Binding
->Endpoint
= RPCRT4_strdupA(Endpoint
);
185 RPC_STATUS
RPCRT4_SetBindingObject(RpcBinding
* Binding
, UUID
* ObjectUuid
)
187 TRACE("(*RpcBinding == ^%p, UUID == %s)\n", Binding
, debugstr_guid(ObjectUuid
));
188 if (ObjectUuid
) memcpy(&Binding
->ObjectUuid
, ObjectUuid
, sizeof(UUID
));
189 else UuidCreateNil(&Binding
->ObjectUuid
);
193 RPC_STATUS
RPCRT4_MakeBinding(RpcBinding
** Binding
, RpcConnection
* Connection
)
195 RpcBinding
* NewBinding
;
196 TRACE("(RpcBinding == ^%p, Connection == ^%p)\n", Binding
, Connection
);
198 RPCRT4_AllocBinding(&NewBinding
, Connection
->server
);
199 NewBinding
->Protseq
= RPCRT4_strdupA(rpcrt4_conn_get_name(Connection
));
200 NewBinding
->NetworkAddr
= RPCRT4_strdupA(Connection
->NetworkAddr
);
201 NewBinding
->Endpoint
= RPCRT4_strdupA(Connection
->Endpoint
);
202 NewBinding
->FromConn
= Connection
;
204 TRACE("binding: %p\n", NewBinding
);
205 *Binding
= NewBinding
;
210 RPC_STATUS
RPCRT4_ExportBinding(RpcBinding
** Binding
, RpcBinding
* OldBinding
)
212 InterlockedIncrement(&OldBinding
->refs
);
213 *Binding
= OldBinding
;
217 RPC_STATUS
RPCRT4_DestroyBinding(RpcBinding
* Binding
)
219 if (InterlockedDecrement(&Binding
->refs
))
222 TRACE("binding: %p\n", Binding
);
223 /* FIXME: release connections */
224 RPCRT4_strfree(Binding
->Endpoint
);
225 RPCRT4_strfree(Binding
->NetworkAddr
);
226 RPCRT4_strfree(Binding
->Protseq
);
227 HeapFree(GetProcessHeap(), 0, Binding
);
231 RPC_STATUS
RPCRT4_OpenBinding(RpcBinding
* Binding
, RpcConnection
** Connection
,
232 PRPC_SYNTAX_IDENTIFIER TransferSyntax
,
233 PRPC_SYNTAX_IDENTIFIER InterfaceId
)
235 RpcConnection
* NewConnection
;
238 TRACE("(Binding == ^%p)\n", Binding
);
240 if (!Binding
->server
) {
241 /* try to find a compatible connection from the connection pool */
242 NewConnection
= RPCRT4_GetIdleConnection(InterfaceId
, TransferSyntax
,
243 Binding
->Protseq
, Binding
->NetworkAddr
, Binding
->Endpoint
,
246 *Connection
= NewConnection
;
250 /* we already have a connection with acceptable binding, so use it */
251 if (Binding
->FromConn
) {
252 *Connection
= Binding
->FromConn
;
257 /* create a new connection */
258 RPCRT4_CreateConnection(&NewConnection
, Binding
->server
, Binding
->Protseq
,
259 Binding
->NetworkAddr
, Binding
->Endpoint
, NULL
,
260 Binding
->AuthInfo
, Binding
);
261 status
= RPCRT4_OpenConnection(NewConnection
);
262 if (status
!= RPC_S_OK
)
264 RPCRT4_DestroyConnection(NewConnection
);
268 /* we need to send a binding packet if we are client. */
269 if (!NewConnection
->server
) {
271 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(NewConnection
, hdr
, NULL
, 0);
281 RPCRT4_FreeHeader(hdr
);
282 if (status
!= RPC_S_OK
) {
283 RPCRT4_DestroyConnection(NewConnection
);
287 status
= RPCRT4_Receive(NewConnection
, &response_hdr
, &msg
);
288 if (status
!= RPC_S_OK
) {
289 ERR("receive failed\n");
290 RPCRT4_DestroyConnection(NewConnection
);
294 if (response_hdr
->common
.ptype
!= PKT_BIND_ACK
||
295 response_hdr
->bind_ack
.max_tsize
< RPC_MIN_PACKET_SIZE
) {
296 ERR("failed to bind for interface %s, %d.%d\n",
297 debugstr_guid(&InterfaceId
->SyntaxGUID
),
298 InterfaceId
->SyntaxVersion
.MajorVersion
,
299 InterfaceId
->SyntaxVersion
.MinorVersion
);
300 RPCRT4_FreeHeader(response_hdr
);
301 RPCRT4_DestroyConnection(NewConnection
);
302 return RPC_S_PROTOCOL_ERROR
;
305 /* FIXME: do more checks? */
307 NewConnection
->MaxTransmissionSize
= response_hdr
->bind_ack
.max_tsize
;
308 NewConnection
->ActiveInterface
= *InterfaceId
;
309 RPCRT4_FreeHeader(response_hdr
);
313 Binding
->FromConn
= NewConnection
;
314 *Connection
= NewConnection
;
319 RPC_STATUS
RPCRT4_CloseBinding(RpcBinding
* Binding
, RpcConnection
* Connection
)
321 TRACE("(Binding == ^%p)\n", Binding
);
322 if (!Connection
) return RPC_S_OK
;
323 if (Binding
->server
) {
324 /* don't destroy a connection that is cached in the binding */
325 if (Binding
->FromConn
== Connection
)
327 return RPCRT4_DestroyConnection(Connection
);
330 RPCRT4_ReleaseIdleConnection(Connection
);
335 /* utility functions for string composing and parsing */
336 static unsigned RPCRT4_strcopyA(LPSTR data
, LPCSTR src
)
338 unsigned len
= strlen(src
);
339 memcpy(data
, src
, len
*sizeof(CHAR
));
343 static unsigned RPCRT4_strcopyW(LPWSTR data
, LPCWSTR src
)
345 unsigned len
= strlenW(src
);
346 memcpy(data
, src
, len
*sizeof(WCHAR
));
350 static LPSTR
RPCRT4_strconcatA(LPSTR dst
, LPCSTR src
)
352 DWORD len
= strlen(dst
), slen
= strlen(src
);
353 LPSTR ndst
= HeapReAlloc(GetProcessHeap(), 0, dst
, (len
+slen
+2)*sizeof(CHAR
));
356 HeapFree(GetProcessHeap(), 0, dst
);
360 memcpy(ndst
+len
+1, src
, slen
+1);
364 static LPWSTR
RPCRT4_strconcatW(LPWSTR dst
, LPCWSTR src
)
366 DWORD len
= strlenW(dst
), slen
= strlenW(src
);
367 LPWSTR ndst
= HeapReAlloc(GetProcessHeap(), 0, dst
, (len
+slen
+2)*sizeof(WCHAR
));
370 HeapFree(GetProcessHeap(), 0, dst
);
374 memcpy(ndst
+len
+1, src
, (slen
+1)*sizeof(WCHAR
));
379 /***********************************************************************
380 * RpcStringBindingComposeA (RPCRT4.@)
382 RPC_STATUS WINAPI
RpcStringBindingComposeA(RPC_CSTR ObjUuid
, RPC_CSTR Protseq
,
383 RPC_CSTR NetworkAddr
, RPC_CSTR Endpoint
,
384 RPC_CSTR Options
, RPC_CSTR
*StringBinding
)
389 TRACE( "(%s,%s,%s,%s,%s,%p)\n",
390 debugstr_a( (char*)ObjUuid
), debugstr_a( (char*)Protseq
),
391 debugstr_a( (char*)NetworkAddr
), debugstr_a( (char*)Endpoint
),
392 debugstr_a( (char*)Options
), StringBinding
);
394 if (ObjUuid
&& *ObjUuid
) len
+= strlen((char*)ObjUuid
) + 1;
395 if (Protseq
&& *Protseq
) len
+= strlen((char*)Protseq
) + 1;
396 if (NetworkAddr
&& *NetworkAddr
) len
+= strlen((char*)NetworkAddr
);
397 if (Endpoint
&& *Endpoint
) len
+= strlen((char*)Endpoint
) + 2;
398 if (Options
&& *Options
) len
+= strlen((char*)Options
) + 2;
400 data
= HeapAlloc(GetProcessHeap(), 0, len
);
401 *StringBinding
= (unsigned char*)data
;
403 if (ObjUuid
&& *ObjUuid
) {
404 data
+= RPCRT4_strcopyA(data
, (char*)ObjUuid
);
407 if (Protseq
&& *Protseq
) {
408 data
+= RPCRT4_strcopyA(data
, (char*)Protseq
);
411 if (NetworkAddr
&& *NetworkAddr
)
412 data
+= RPCRT4_strcopyA(data
, (char*)NetworkAddr
);
414 if ((Endpoint
&& *Endpoint
) ||
415 (Options
&& *Options
)) {
417 if (Endpoint
&& *Endpoint
) {
418 data
+= RPCRT4_strcopyA(data
, (char*)Endpoint
);
419 if (Options
&& *Options
) *data
++ = ',';
421 if (Options
&& *Options
) {
422 data
+= RPCRT4_strcopyA(data
, (char*)Options
);
431 /***********************************************************************
432 * RpcStringBindingComposeW (RPCRT4.@)
434 RPC_STATUS WINAPI
RpcStringBindingComposeW( RPC_WSTR ObjUuid
, RPC_WSTR Protseq
,
435 RPC_WSTR NetworkAddr
, RPC_WSTR Endpoint
,
436 RPC_WSTR Options
, RPC_WSTR
* StringBinding
)
441 TRACE("(%s,%s,%s,%s,%s,%p)\n",
442 debugstr_w( ObjUuid
), debugstr_w( Protseq
),
443 debugstr_w( NetworkAddr
), debugstr_w( Endpoint
),
444 debugstr_w( Options
), StringBinding
);
446 if (ObjUuid
&& *ObjUuid
) len
+= strlenW(ObjUuid
) + 1;
447 if (Protseq
&& *Protseq
) len
+= strlenW(Protseq
) + 1;
448 if (NetworkAddr
&& *NetworkAddr
) len
+= strlenW(NetworkAddr
);
449 if (Endpoint
&& *Endpoint
) len
+= strlenW(Endpoint
) + 2;
450 if (Options
&& *Options
) len
+= strlenW(Options
) + 2;
452 data
= HeapAlloc(GetProcessHeap(), 0, len
*sizeof(WCHAR
));
453 *StringBinding
= data
;
455 if (ObjUuid
&& *ObjUuid
) {
456 data
+= RPCRT4_strcopyW(data
, ObjUuid
);
459 if (Protseq
&& *Protseq
) {
460 data
+= RPCRT4_strcopyW(data
, Protseq
);
463 if (NetworkAddr
&& *NetworkAddr
) {
464 data
+= RPCRT4_strcopyW(data
, NetworkAddr
);
466 if ((Endpoint
&& *Endpoint
) ||
467 (Options
&& *Options
)) {
469 if (Endpoint
&& *Endpoint
) {
470 data
+= RPCRT4_strcopyW(data
, Endpoint
);
471 if (Options
&& *Options
) *data
++ = ',';
473 if (Options
&& *Options
) {
474 data
+= RPCRT4_strcopyW(data
, Options
);
484 /***********************************************************************
485 * RpcStringBindingParseA (RPCRT4.@)
487 RPC_STATUS WINAPI
RpcStringBindingParseA( RPC_CSTR StringBinding
, RPC_CSTR
*ObjUuid
,
488 RPC_CSTR
*Protseq
, RPC_CSTR
*NetworkAddr
,
489 RPC_CSTR
*Endpoint
, RPC_CSTR
*Options
)
492 static const char ep_opt
[] = "endpoint=";
494 TRACE("(%s,%p,%p,%p,%p,%p)\n", debugstr_a((char*)StringBinding
),
495 ObjUuid
, Protseq
, NetworkAddr
, Endpoint
, Options
);
497 if (ObjUuid
) *ObjUuid
= NULL
;
498 if (Protseq
) *Protseq
= NULL
;
499 if (NetworkAddr
) *NetworkAddr
= NULL
;
500 if (Endpoint
) *Endpoint
= NULL
;
501 if (Options
) *Options
= NULL
;
503 data
= (char*) StringBinding
;
505 next
= strchr(data
, '@');
507 if (ObjUuid
) *ObjUuid
= (unsigned char*)RPCRT4_strndupA(data
, next
- data
);
511 next
= strchr(data
, ':');
513 if (Protseq
) *Protseq
= (unsigned char*)RPCRT4_strndupA(data
, next
- data
);
517 next
= strchr(data
, '[');
521 if (NetworkAddr
) *NetworkAddr
= (unsigned char*)RPCRT4_strndupA(data
, next
- data
);
523 close
= strchr(data
, ']');
524 if (!close
) goto fail
;
526 /* tokenize options */
527 while (data
< close
) {
528 next
= strchr(data
, ',');
529 if (!next
|| next
> close
) next
= close
;
530 /* FIXME: this is kind of inefficient */
531 opt
= RPCRT4_strndupA(data
, next
- data
);
535 next
= strchr(opt
, '=');
537 /* not an option, must be an endpoint */
538 if (*Endpoint
) goto fail
;
539 *Endpoint
= (unsigned char*) opt
;
541 if (strncmp(opt
, ep_opt
, strlen(ep_opt
)) == 0) {
542 /* endpoint option */
543 if (*Endpoint
) goto fail
;
544 *Endpoint
= (unsigned char*) RPCRT4_strdupA(next
+1);
545 HeapFree(GetProcessHeap(), 0, opt
);
549 /* FIXME: this is kind of inefficient */
550 *Options
= (unsigned char*) RPCRT4_strconcatA( (char*)*Options
, opt
);
551 HeapFree(GetProcessHeap(), 0, opt
);
553 *Options
= (unsigned char*) opt
;
559 if (*data
) goto fail
;
561 else if (NetworkAddr
)
562 *NetworkAddr
= (unsigned char*)RPCRT4_strdupA(data
);
567 if (ObjUuid
) RpcStringFreeA((unsigned char**)ObjUuid
);
568 if (Protseq
) RpcStringFreeA((unsigned char**)Protseq
);
569 if (NetworkAddr
) RpcStringFreeA((unsigned char**)NetworkAddr
);
570 if (Endpoint
) RpcStringFreeA((unsigned char**)Endpoint
);
571 if (Options
) RpcStringFreeA((unsigned char**)Options
);
572 return RPC_S_INVALID_STRING_BINDING
;
575 /***********************************************************************
576 * RpcStringBindingParseW (RPCRT4.@)
578 RPC_STATUS WINAPI
RpcStringBindingParseW( RPC_WSTR StringBinding
, RPC_WSTR
*ObjUuid
,
579 RPC_WSTR
*Protseq
, RPC_WSTR
*NetworkAddr
,
580 RPC_WSTR
*Endpoint
, RPC_WSTR
*Options
)
583 static const WCHAR ep_opt
[] = {'e','n','d','p','o','i','n','t','=',0};
585 TRACE("(%s,%p,%p,%p,%p,%p)\n", debugstr_w(StringBinding
),
586 ObjUuid
, Protseq
, NetworkAddr
, Endpoint
, Options
);
588 if (ObjUuid
) *ObjUuid
= NULL
;
589 if (Protseq
) *Protseq
= NULL
;
590 if (NetworkAddr
) *NetworkAddr
= NULL
;
591 if (Endpoint
) *Endpoint
= NULL
;
592 if (Options
) *Options
= NULL
;
594 data
= StringBinding
;
596 next
= strchrW(data
, '@');
598 if (ObjUuid
) *ObjUuid
= RPCRT4_strndupW(data
, next
- data
);
602 next
= strchrW(data
, ':');
604 if (Protseq
) *Protseq
= RPCRT4_strndupW(data
, next
- data
);
608 next
= strchrW(data
, '[');
612 if (NetworkAddr
) *NetworkAddr
= RPCRT4_strndupW(data
, next
- data
);
614 close
= strchrW(data
, ']');
615 if (!close
) goto fail
;
617 /* tokenize options */
618 while (data
< close
) {
619 next
= strchrW(data
, ',');
620 if (!next
|| next
> close
) next
= close
;
621 /* FIXME: this is kind of inefficient */
622 opt
= RPCRT4_strndupW(data
, next
- data
);
626 next
= strchrW(opt
, '=');
628 /* not an option, must be an endpoint */
629 if (*Endpoint
) goto fail
;
632 if (strncmpW(opt
, ep_opt
, strlenW(ep_opt
)) == 0) {
633 /* endpoint option */
634 if (*Endpoint
) goto fail
;
635 *Endpoint
= RPCRT4_strdupW(next
+1);
636 HeapFree(GetProcessHeap(), 0, opt
);
640 /* FIXME: this is kind of inefficient */
641 *Options
= RPCRT4_strconcatW(*Options
, opt
);
642 HeapFree(GetProcessHeap(), 0, opt
);
650 if (*data
) goto fail
;
651 } else if (NetworkAddr
)
652 *NetworkAddr
= RPCRT4_strdupW(data
);
657 if (ObjUuid
) RpcStringFreeW(ObjUuid
);
658 if (Protseq
) RpcStringFreeW(Protseq
);
659 if (NetworkAddr
) RpcStringFreeW(NetworkAddr
);
660 if (Endpoint
) RpcStringFreeW(Endpoint
);
661 if (Options
) RpcStringFreeW(Options
);
662 return RPC_S_INVALID_STRING_BINDING
;
665 /***********************************************************************
666 * RpcBindingFree (RPCRT4.@)
668 RPC_STATUS WINAPI
RpcBindingFree( RPC_BINDING_HANDLE
* Binding
)
671 TRACE("(%p) = %p\n", Binding
, *Binding
);
672 status
= RPCRT4_DestroyBinding(*Binding
);
673 if (status
== RPC_S_OK
) *Binding
= 0;
677 /***********************************************************************
678 * RpcBindingVectorFree (RPCRT4.@)
680 RPC_STATUS WINAPI
RpcBindingVectorFree( RPC_BINDING_VECTOR
** BindingVector
)
685 TRACE("(%p)\n", BindingVector
);
686 for (c
=0; c
<(*BindingVector
)->Count
; c
++) {
687 status
= RpcBindingFree(&(*BindingVector
)->BindingH
[c
]);
689 HeapFree(GetProcessHeap(), 0, *BindingVector
);
690 *BindingVector
= NULL
;
694 /***********************************************************************
695 * RpcBindingInqObject (RPCRT4.@)
697 RPC_STATUS WINAPI
RpcBindingInqObject( RPC_BINDING_HANDLE Binding
, UUID
* ObjectUuid
)
699 RpcBinding
* bind
= (RpcBinding
*)Binding
;
701 TRACE("(%p,%p) = %s\n", Binding
, ObjectUuid
, debugstr_guid(&bind
->ObjectUuid
));
702 memcpy(ObjectUuid
, &bind
->ObjectUuid
, sizeof(UUID
));
706 /***********************************************************************
707 * RpcBindingSetObject (RPCRT4.@)
709 RPC_STATUS WINAPI
RpcBindingSetObject( RPC_BINDING_HANDLE Binding
, UUID
* ObjectUuid
)
711 RpcBinding
* bind
= (RpcBinding
*)Binding
;
713 TRACE("(%p,%s)\n", Binding
, debugstr_guid(ObjectUuid
));
714 if (bind
->server
) return RPC_S_WRONG_KIND_OF_BINDING
;
715 return RPCRT4_SetBindingObject(Binding
, ObjectUuid
);
718 /***********************************************************************
719 * RpcBindingFromStringBindingA (RPCRT4.@)
721 RPC_STATUS WINAPI
RpcBindingFromStringBindingA( RPC_CSTR StringBinding
, RPC_BINDING_HANDLE
* Binding
)
724 RpcBinding
* bind
= NULL
;
725 RPC_CSTR ObjectUuid
, Protseq
, NetworkAddr
, Endpoint
, Options
;
728 TRACE("(%s,%p)\n", debugstr_a((char*)StringBinding
), Binding
);
730 ret
= RpcStringBindingParseA(StringBinding
, &ObjectUuid
, &Protseq
,
731 &NetworkAddr
, &Endpoint
, &Options
);
732 if (ret
!= RPC_S_OK
) return ret
;
734 ret
= UuidFromStringA(ObjectUuid
, &Uuid
);
737 ret
= RPCRT4_CreateBindingA(&bind
, FALSE
, (char*)Protseq
);
739 ret
= RPCRT4_SetBindingObject(bind
, &Uuid
);
741 ret
= RPCRT4_CompleteBindingA(bind
, (char*)NetworkAddr
, (char*)Endpoint
, (char*)Options
);
743 RpcStringFreeA((unsigned char**)&Options
);
744 RpcStringFreeA((unsigned char**)&Endpoint
);
745 RpcStringFreeA((unsigned char**)&NetworkAddr
);
746 RpcStringFreeA((unsigned char**)&Protseq
);
747 RpcStringFreeA((unsigned char**)&ObjectUuid
);
750 *Binding
= (RPC_BINDING_HANDLE
)bind
;
752 RPCRT4_DestroyBinding(bind
);
757 /***********************************************************************
758 * RpcBindingFromStringBindingW (RPCRT4.@)
760 RPC_STATUS WINAPI
RpcBindingFromStringBindingW( RPC_WSTR StringBinding
, RPC_BINDING_HANDLE
* Binding
)
763 RpcBinding
* bind
= NULL
;
764 RPC_WSTR ObjectUuid
, Protseq
, NetworkAddr
, Endpoint
, Options
;
767 TRACE("(%s,%p)\n", debugstr_w(StringBinding
), Binding
);
769 ret
= RpcStringBindingParseW(StringBinding
, &ObjectUuid
, &Protseq
,
770 &NetworkAddr
, &Endpoint
, &Options
);
771 if (ret
!= RPC_S_OK
) return ret
;
773 ret
= UuidFromStringW(ObjectUuid
, &Uuid
);
776 ret
= RPCRT4_CreateBindingW(&bind
, FALSE
, Protseq
);
778 ret
= RPCRT4_SetBindingObject(bind
, &Uuid
);
780 ret
= RPCRT4_CompleteBindingW(bind
, NetworkAddr
, Endpoint
, Options
);
782 RpcStringFreeW(&Options
);
783 RpcStringFreeW(&Endpoint
);
784 RpcStringFreeW(&NetworkAddr
);
785 RpcStringFreeW(&Protseq
);
786 RpcStringFreeW(&ObjectUuid
);
789 *Binding
= (RPC_BINDING_HANDLE
)bind
;
791 RPCRT4_DestroyBinding(bind
);
796 /***********************************************************************
797 * RpcBindingToStringBindingA (RPCRT4.@)
799 RPC_STATUS WINAPI
RpcBindingToStringBindingA( RPC_BINDING_HANDLE Binding
, RPC_CSTR
*StringBinding
)
802 RpcBinding
* bind
= (RpcBinding
*)Binding
;
805 TRACE("(%p,%p)\n", Binding
, StringBinding
);
807 ret
= UuidToStringA(&bind
->ObjectUuid
, (unsigned char**)&ObjectUuid
);
808 if (ret
!= RPC_S_OK
) return ret
;
810 ret
= RpcStringBindingComposeA((unsigned char*) ObjectUuid
, (unsigned char*)bind
->Protseq
, (unsigned char*) bind
->NetworkAddr
,
811 (unsigned char*) bind
->Endpoint
, NULL
, StringBinding
);
813 RpcStringFreeA((unsigned char**)&ObjectUuid
);
818 /***********************************************************************
819 * RpcBindingToStringBindingW (RPCRT4.@)
821 RPC_STATUS WINAPI
RpcBindingToStringBindingW( RPC_BINDING_HANDLE Binding
, RPC_WSTR
*StringBinding
)
824 unsigned char *str
= NULL
;
825 TRACE("(%p,%p)\n", Binding
, StringBinding
);
826 ret
= RpcBindingToStringBindingA(Binding
, &str
);
827 *StringBinding
= RPCRT4_strdupAtoW((char*)str
);
828 RpcStringFreeA((unsigned char**)&str
);
832 /***********************************************************************
833 * I_RpcBindingSetAsync (RPCRT4.@)
835 * Exists in win9x and winNT, but with different number of arguments
836 * (9x version has 3 arguments, NT has 2).
838 RPC_STATUS WINAPI
I_RpcBindingSetAsync( RPC_BINDING_HANDLE Binding
, RPC_BLOCKING_FN BlockingFn
)
840 RpcBinding
* bind
= (RpcBinding
*)Binding
;
842 TRACE( "(%p,%p): stub\n", Binding
, BlockingFn
);
844 bind
->BlockingFn
= BlockingFn
;
849 /***********************************************************************
850 * RpcBindingCopy (RPCRT4.@)
852 RPC_STATUS RPC_ENTRY
RpcBindingCopy(
853 RPC_BINDING_HANDLE SourceBinding
,
854 RPC_BINDING_HANDLE
* DestinationBinding
)
856 RpcBinding
*DestBinding
;
857 RpcBinding
*SrcBinding
= (RpcBinding
*)SourceBinding
;
860 TRACE("(%p, %p)\n", SourceBinding
, DestinationBinding
);
862 status
= RPCRT4_AllocBinding(&DestBinding
, SrcBinding
->server
);
863 if (status
!= RPC_S_OK
) return status
;
865 DestBinding
->ObjectUuid
= SrcBinding
->ObjectUuid
;
866 DestBinding
->BlockingFn
= SrcBinding
->BlockingFn
;
867 DestBinding
->Protseq
= RPCRT4_strndupA(SrcBinding
->Protseq
, -1);
868 DestBinding
->NetworkAddr
= RPCRT4_strndupA(SrcBinding
->NetworkAddr
, -1);
869 DestBinding
->Endpoint
= RPCRT4_strndupA(SrcBinding
->Endpoint
, -1);
871 if (SrcBinding
->AuthInfo
) RpcAuthInfo_AddRef(SrcBinding
->AuthInfo
);
872 DestBinding
->AuthInfo
= SrcBinding
->AuthInfo
;
874 *DestinationBinding
= DestBinding
;
878 /***********************************************************************
879 * RpcImpersonateClient (RPCRT4.@)
881 * Impersonates the client connected via a binding handle so that security
882 * checks are done in the context of the client.
885 * BindingHandle [I] Handle to the binding to the client.
889 * Failure: RPC_STATUS value.
893 * If BindingHandle is NULL then the function impersonates the client
894 * connected to the binding handle of the current thread.
896 RPC_STATUS WINAPI
RpcImpersonateClient(RPC_BINDING_HANDLE BindingHandle
)
898 FIXME("(%p): stub\n", BindingHandle
);
899 ImpersonateSelf(SecurityImpersonation
);
903 /***********************************************************************
904 * RpcRevertToSelfEx (RPCRT4.@)
906 * Stops impersonating the client connected to the binding handle so that security
907 * checks are no longer done in the context of the client.
910 * BindingHandle [I] Handle to the binding to the client.
914 * Failure: RPC_STATUS value.
918 * If BindingHandle is NULL then the function stops impersonating the client
919 * connected to the binding handle of the current thread.
921 RPC_STATUS WINAPI
RpcRevertToSelfEx(RPC_BINDING_HANDLE BindingHandle
)
923 FIXME("(%p): stub\n", BindingHandle
);
927 static RPC_STATUS
RpcAuthInfo_Create(unsigned long AuthnLevel
, unsigned long AuthnSvc
, CredHandle cred
, TimeStamp exp
, RpcAuthInfo
**ret
)
929 RpcAuthInfo
*AuthInfo
= HeapAlloc(GetProcessHeap(), 0, sizeof(*AuthInfo
));
931 return ERROR_OUTOFMEMORY
;
933 AuthInfo
->AuthnLevel
= AuthnLevel
;
934 AuthInfo
->AuthnSvc
= AuthnSvc
;
935 AuthInfo
->cred
= cred
;
941 ULONG
RpcAuthInfo_AddRef(RpcAuthInfo
*AuthInfo
)
943 return InterlockedIncrement(&AuthInfo
->refs
);
946 ULONG
RpcAuthInfo_Release(RpcAuthInfo
*AuthInfo
)
948 ULONG refs
= InterlockedDecrement(&AuthInfo
->refs
);
952 FreeCredentialsHandle(&AuthInfo
->cred
);
953 HeapFree(GetProcessHeap(), 0, AuthInfo
);
959 /***********************************************************************
960 * RpcRevertToSelf (RPCRT4.@)
962 RPC_STATUS WINAPI
RpcRevertToSelf(void)
969 /***********************************************************************
970 * RpcMgmtSetComTimeout (RPCRT4.@)
972 RPC_STATUS WINAPI
RpcMgmtSetComTimeout(RPC_BINDING_HANDLE BindingHandle
, unsigned int Timeout
)
974 FIXME("(%p, %d): stub\n", BindingHandle
, Timeout
);
978 /***********************************************************************
979 * RpcBindingInqAuthInfoExA (RPCRT4.@)
981 RPCRTAPI RPC_STATUS RPC_ENTRY
982 RpcBindingInqAuthInfoExA( RPC_BINDING_HANDLE Binding
, RPC_CSTR
*ServerPrincName
, unsigned long *AuthnLevel
,
983 unsigned long *AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE
*AuthIdentity
, unsigned long *AuthzSvc
,
984 unsigned long RpcQosVersion
, RPC_SECURITY_QOS
*SecurityQOS
)
986 FIXME("%p %p %p %p %p %p %lu %p\n", Binding
, ServerPrincName
, AuthnLevel
,
987 AuthnSvc
, AuthIdentity
, AuthzSvc
, RpcQosVersion
, SecurityQOS
);
988 return RPC_S_INVALID_BINDING
;
991 /***********************************************************************
992 * RpcBindingInqAuthInfoExW (RPCRT4.@)
994 RPCRTAPI RPC_STATUS RPC_ENTRY
995 RpcBindingInqAuthInfoExW( RPC_BINDING_HANDLE Binding
, RPC_WSTR
*ServerPrincName
, unsigned long *AuthnLevel
,
996 unsigned long *AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE
*AuthIdentity
, unsigned long *AuthzSvc
,
997 unsigned long RpcQosVersion
, RPC_SECURITY_QOS
*SecurityQOS
)
999 FIXME("%p %p %p %p %p %p %lu %p\n", Binding
, ServerPrincName
, AuthnLevel
,
1000 AuthnSvc
, AuthIdentity
, AuthzSvc
, RpcQosVersion
, SecurityQOS
);
1001 return RPC_S_INVALID_BINDING
;
1004 /***********************************************************************
1005 * RpcBindingInqAuthInfoA (RPCRT4.@)
1007 RPCRTAPI RPC_STATUS RPC_ENTRY
1008 RpcBindingInqAuthInfoA( RPC_BINDING_HANDLE Binding
, RPC_CSTR
*ServerPrincName
, unsigned long *AuthnLevel
,
1009 unsigned long *AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE
*AuthIdentity
, unsigned long *AuthzSvc
)
1011 FIXME("%p %p %p %p %p %p\n", Binding
, ServerPrincName
, AuthnLevel
,
1012 AuthnSvc
, AuthIdentity
, AuthzSvc
);
1013 return RPC_S_INVALID_BINDING
;
1016 /***********************************************************************
1017 * RpcBindingInqAuthInfoW (RPCRT4.@)
1019 RPCRTAPI RPC_STATUS RPC_ENTRY
1020 RpcBindingInqAuthInfoW( RPC_BINDING_HANDLE Binding
, RPC_WSTR
*ServerPrincName
, unsigned long *AuthnLevel
,
1021 unsigned long *AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE
*AuthIdentity
, unsigned long *AuthzSvc
)
1023 FIXME("%p %p %p %p %p %p\n", Binding
, ServerPrincName
, AuthnLevel
,
1024 AuthnSvc
, AuthIdentity
, AuthzSvc
);
1025 return RPC_S_INVALID_BINDING
;
1028 /***********************************************************************
1029 * RpcBindingSetAuthInfoExA (RPCRT4.@)
1031 RPCRTAPI RPC_STATUS RPC_ENTRY
1032 RpcBindingSetAuthInfoExA( RPC_BINDING_HANDLE Binding
, RPC_CSTR ServerPrincName
,
1033 unsigned long AuthnLevel
, unsigned long AuthnSvc
,
1034 RPC_AUTH_IDENTITY_HANDLE AuthIdentity
, unsigned long AuthzSvr
,
1035 RPC_SECURITY_QOS
*SecurityQos
)
1037 RpcBinding
* bind
= (RpcBinding
*)Binding
;
1041 ULONG package_count
;
1043 PSecPkgInfoA packages
;
1045 TRACE("%p %s %lu %lu %p %lu %p\n", Binding
, debugstr_a((const char*)ServerPrincName
),
1046 AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
, SecurityQos
);
1048 if (AuthnLevel
!= RPC_C_AUTHN_LEVEL_CONNECT
)
1050 FIXME("unsupported AuthnLevel %lu\n", AuthnLevel
);
1051 return RPC_S_UNKNOWN_AUTHN_LEVEL
;
1056 FIXME("unsupported AuthzSvr %lu\n", AuthzSvr
);
1057 return RPC_S_UNKNOWN_AUTHZ_SERVICE
;
1061 FIXME("SecurityQos ignored\n");
1063 r
= EnumerateSecurityPackagesA(&package_count
, &packages
);
1066 ERR("EnumerateSecurityPackagesA failed with error 0x%08lx\n", r
);
1067 return RPC_S_SEC_PKG_ERROR
;
1070 for (i
= 0; i
< package_count
; i
++)
1071 if (packages
[i
].wRPCID
== AuthnSvc
)
1074 if (i
== package_count
)
1076 FIXME("unsupported AuthnSvc %lu\n", AuthnSvc
);
1077 FreeContextBuffer(packages
);
1078 return RPC_S_UNKNOWN_AUTHN_SERVICE
;
1081 TRACE("found package %s for service %ld\n", packages
[i
].Name
, AuthnSvc
);
1082 r
= AcquireCredentialsHandleA((SEC_CHAR
*)ServerPrincName
, packages
[i
].Name
, SECPKG_CRED_OUTBOUND
, NULL
,
1083 AuthIdentity
, NULL
, NULL
, &cred
, &exp
);
1084 FreeContextBuffer(packages
);
1085 if (r
== ERROR_SUCCESS
)
1087 if (bind
->AuthInfo
) RpcAuthInfo_Release(bind
->AuthInfo
);
1088 bind
->AuthInfo
= NULL
;
1089 r
= RpcAuthInfo_Create(AuthnLevel
, AuthnSvc
, cred
, exp
, &bind
->AuthInfo
);
1091 FreeCredentialsHandle(&cred
);
1096 ERR("AcquireCredentialsHandleA failed with error 0x%08lx\n", r
);
1097 return RPC_S_SEC_PKG_ERROR
;
1101 /***********************************************************************
1102 * RpcBindingSetAuthInfoExW (RPCRT4.@)
1104 RPCRTAPI RPC_STATUS RPC_ENTRY
1105 RpcBindingSetAuthInfoExW( RPC_BINDING_HANDLE Binding
, RPC_WSTR ServerPrincName
, unsigned long AuthnLevel
,
1106 unsigned long AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE AuthIdentity
, unsigned long AuthzSvr
,
1107 RPC_SECURITY_QOS
*SecurityQos
)
1109 RpcBinding
* bind
= (RpcBinding
*)Binding
;
1113 ULONG package_count
;
1115 PSecPkgInfoW packages
;
1117 TRACE("%p %s %lu %lu %p %lu %p\n", Binding
, debugstr_w((const WCHAR
*)ServerPrincName
),
1118 AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
, SecurityQos
);
1120 if (AuthnLevel
!= RPC_C_AUTHN_LEVEL_CONNECT
)
1122 FIXME("unsupported AuthnLevel %lu\n", AuthnLevel
);
1123 return RPC_S_UNKNOWN_AUTHN_LEVEL
;
1128 FIXME("unsupported AuthzSvr %lu\n", AuthzSvr
);
1129 return RPC_S_UNKNOWN_AUTHZ_SERVICE
;
1133 FIXME("SecurityQos ignored\n");
1135 r
= EnumerateSecurityPackagesW(&package_count
, &packages
);
1138 ERR("EnumerateSecurityPackagesA failed with error 0x%08lx\n", r
);
1139 return RPC_S_SEC_PKG_ERROR
;
1142 for (i
= 0; i
< package_count
; i
++)
1143 if (packages
[i
].wRPCID
== AuthnSvc
)
1146 if (i
== package_count
)
1148 FIXME("unsupported AuthnSvc %lu\n", AuthnSvc
);
1149 FreeContextBuffer(packages
);
1150 return RPC_S_UNKNOWN_AUTHN_SERVICE
;
1153 TRACE("found package %s for service %ld\n", debugstr_w(packages
[i
].Name
), AuthnSvc
);
1154 r
= AcquireCredentialsHandleW((SEC_WCHAR
*)ServerPrincName
, packages
[i
].Name
, SECPKG_CRED_OUTBOUND
, NULL
,
1155 AuthIdentity
, NULL
, NULL
, &cred
, &exp
);
1156 FreeContextBuffer(packages
);
1157 if (r
== ERROR_SUCCESS
)
1159 if (bind
->AuthInfo
) RpcAuthInfo_Release(bind
->AuthInfo
);
1160 bind
->AuthInfo
= NULL
;
1161 r
= RpcAuthInfo_Create(AuthnLevel
, AuthnSvc
, cred
, exp
, &bind
->AuthInfo
);
1163 FreeCredentialsHandle(&cred
);
1168 ERR("AcquireCredentialsHandleA failed with error 0x%08lx\n", r
);
1169 return RPC_S_SEC_PKG_ERROR
;
1173 /***********************************************************************
1174 * RpcBindingSetAuthInfoA (RPCRT4.@)
1176 RPCRTAPI RPC_STATUS RPC_ENTRY
1177 RpcBindingSetAuthInfoA( RPC_BINDING_HANDLE Binding
, RPC_CSTR ServerPrincName
, unsigned long AuthnLevel
,
1178 unsigned long AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE AuthIdentity
, unsigned long AuthzSvr
)
1180 TRACE("%p %s %lu %lu %p %lu\n", Binding
, debugstr_a((const char*)ServerPrincName
),
1181 AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
);
1182 return RpcBindingSetAuthInfoExA(Binding
, ServerPrincName
, AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
, NULL
);
1185 /***********************************************************************
1186 * RpcBindingSetAuthInfoW (RPCRT4.@)
1188 RPCRTAPI RPC_STATUS RPC_ENTRY
1189 RpcBindingSetAuthInfoW( RPC_BINDING_HANDLE Binding
, RPC_WSTR ServerPrincName
, unsigned long AuthnLevel
,
1190 unsigned long AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE AuthIdentity
, unsigned long AuthzSvr
)
1192 TRACE("%p %s %lu %lu %p %lu\n", Binding
, debugstr_w((const WCHAR
*)ServerPrincName
),
1193 AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
);
1194 return RpcBindingSetAuthInfoExW(Binding
, ServerPrincName
, AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
, NULL
);
1197 /***********************************************************************
1198 * RpcBindingSetOption (RPCRT4.@)
1200 RPC_STATUS WINAPI
RpcBindingSetOption(RPC_BINDING_HANDLE BindingHandle
, ULONG Option
, ULONG OptionValue
)
1202 FIXME("(%p, %ld, %ld): stub\n", BindingHandle
, Option
, OptionValue
);